/* =====================================================================
   TEMI — l'hub ha una palette neutra; ogni mondo la riscrive a runtime.

   ui.js chiama applyTheme(w): scrive le variabili di w.theme su <html> e
   mette l'id del mondo su <body data-world>. Le regole marcate
   `[data-world="..."]` in fondo al file sono le decorazioni di quel mondo
   (texture, simboli, bordi) che una variabile da sola non può dare.
   ===================================================================== */
:root{
  --bg:#17131f; --bg-2:#1e1830; --panel:#241d34; --panel-2:#2c2440;
  --ink:#efeaf7; --muted:#a99fc4; --faint:#7a7092;
  --line:rgba(255,255,255,.08); --line-2:rgba(255,255,255,.14);
  /* DUE SIGNIFICATI, DUE COLORI — non mescolarli.
       oro   = Gemme. Ciò che costa Gemme, o che te ne frutta.
       verde = fatto. Il livello massimo, il cimelio in vetrina, il traguardo.
     Prima l'oro faceva entrambi i lavori, e un "Livello massimo" sembrava un
     premio da riscuotere. `--done` fa il testo, `--done-fill` le campiture:
     su fondo chiaro un verde leggibile è troppo cupo per riempire, e viceversa. */
  --gold:#e7b24c; --gold-fill:#e7b24c; --good:#6fcf97;
  --done:#6fcf97; --done-fill:#6fcf97;
  /* Sopra il ritratto c'è un velo scuro, in OGNI tema: il testo che ci sta
     sopra non può prendere il colore dall'inchiostro del mondo, o in un mondo
     chiaro diventa nero su nero. Questi non li riscrive nessun tema. */
  --on-veil:#f6f3ec; --on-veil-dim:rgba(246,243,236,.74);
  --accent:#58c7c7;                 /* ridefiniti per-mondo a runtime */
  --accent-2:#9b7bd6;               /* secondo colore: gradienti e bagliori */
  --texture:none;                   /* velo sul fondo, se il mondo ne ha uno */
  --font-display:'Zen Maru Gothic',system-ui,sans-serif;
  --font-body:'Zen Kaku Gothic New',system-ui,sans-serif;
  --font-num:'DM Mono',ui-monospace,monospace;
  --r:18px;
  --sh-1:0 2px 8px rgba(0,0,0,.22);
  --sh-2:0 10px 34px rgba(0,0,0,.34);
  /* le due ombre di ciò che galleggia: barra, dock, tendina, toast. Un mondo
     chiaro le riscrive — un'ombra nera al 50% su carta è una macchia, non un
     rilievo. */
  --sh-float:0 12px 34px rgba(0,0,0,.36);
  --sh-pop:0 18px 44px rgba(0,0,0,.5);
  --edge:inset 0 1px 0 rgba(255,255,255,.055);   /* filetto di luce in alto */
  --texture-blend:overlay;                       /* come la grana morde il fondo */
}
*{box-sizing:border-box}
html,body{margin:0}

/* ---------- Selezione del testo ----------
   È un gioco, non una pagina da leggere: i tap arrivano a raffica e tenere
   premuto ripete i livelli — su mobile il browser rispondeva selezionando
   parole a caso e aprendo il menu di copia. Spenta ovunque; riaccesa negli
   input e nei racconti (Ricordi e vignette), che sono testo da leggere.
   `-webkit-touch-callout` spegne anche il menu da pressione lunga di iOS. */
body{-webkit-user-select:none;user-select:none;-webkit-touch-callout:none}
input,textarea,.memp{-webkit-user-select:text;user-select:text;-webkit-touch-callout:default}

/* e niente pausa da doppio-tap-zoom sui comandi: i tap a raffica sono gameplay */
button{touch-action:manipulation}
body{
  background:
    radial-gradient(1100px 620px at 82% -14%, color-mix(in srgb, var(--accent) 16%, transparent), transparent 62%),
    radial-gradient(900px 520px at -12% 8%, color-mix(in srgb, var(--accent-2) 14%, transparent), transparent 58%),
    linear-gradient(180deg, var(--bg-2), var(--bg) 42%);
  background-attachment:fixed;
  color:var(--ink); font-family:var(--font-body);
  -webkit-font-smoothing:antialiased; line-height:1.5;
  /* il fondo lascia spazio alla barra delle sezioni, che e' fissa */
  padding:12px 16px calc(112px + env(safe-area-inset-bottom, 0px));
  min-height:100vh;
}
/* Velo di grana: il mondo lo accende con --texture, altrimenti non esiste. */
body::before{
  content:"";position:fixed;inset:0;z-index:0;pointer-events:none;
  background-image:var(--texture);opacity:.05;mix-blend-mode:var(--texture-blend);
}
.wrap{max-width:1120px;margin:0 auto;position:relative;z-index:1}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}

/* ---------- HUD ----------
   Due righe, appiccicate in alto come il dock delle sezioni lo è in basso.
   Sopra il titolo, che è anche il comando: cliccarlo apre la tendina dei mondi.
   Sotto i contatori, gli unici numeri che cambiano. La fila delle tab non
   esiste più — nome del mondo e conto degli obiettivi vivono nella tendina.

   Su una riga sola i tre blocchi si pestavano i piedi da mobile: i contatori
   non possono restringersi (dentro ci sono cifre), e il titolo finiva sotto.

   Lo sticky sta sul wrapper, non sulla barra: `.hud` clippa (le decorazioni
   dei mondi le disegnano dentro) e il menu aperto verrebbe tagliato. */
.hudwrap{position:sticky;top:12px;z-index:30;margin-bottom:20px}
.hud{
  display:flex;flex-direction:row;align-items:center;gap:12px;
  padding:9px 12px;border-radius:18px;
  border:1px solid var(--line-2);
  background:color-mix(in srgb, var(--panel) 76%, transparent);
  backdrop-filter:blur(16px) saturate(1.2);-webkit-backdrop-filter:blur(16px) saturate(1.2);
  box-shadow:var(--edge), var(--sh-float);
  overflow:hidden;
}
.hud > *{position:relative;z-index:1}
/* le due righe (titolo + contatori) stanno a sinistra; il logo a destra */
.hud-main{display:flex;flex-direction:column;gap:9px;min-width:0;flex:1 1 auto}
/* il logo del gioco: oggetto vero dell'header, in primo piano, a destra */
.hud-logo{flex:none;width:75px;height:75px;object-fit:contain;display:block}

/* Riga 1 — il titolo È il selettore dei mondi. Il sigillo prende i colori del
   mondo aperto: sai dove sei senza che il nome ti stia sempre addosso. */
.brand{
  align-self:flex-start;max-width:100%;
  display:flex;align-items:center;gap:9px;min-width:0;cursor:pointer;
  padding:3px 9px 3px 3px;border:1px solid transparent;border-radius:13px;
  background:transparent;color:inherit;font-family:var(--font-body);text-align:left;
  transition:background .14s, border-color .14s;
}
.brand:hover{background:color-mix(in srgb,var(--accent) 10%, transparent);border-color:var(--line)}
.brand[aria-expanded="true"]{background:color-mix(in srgb,var(--accent) 14%, transparent);border-color:var(--line-2)}
.brand .bt{
  min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  font-family:var(--font-display);font-weight:900;font-size:19px;letter-spacing:.2px;
  background:linear-gradient(100deg,var(--ink) 30%, var(--accent));-webkit-background-clip:text;background-clip:text;color:transparent;
}
.brand .chev{flex:none;font-size:10px;line-height:1;color:var(--muted);transition:transform .16s}
.brand[aria-expanded="true"] .chev{transform:rotate(180deg)}
.brand .ver{flex:none;font-family:var(--font-num);font-size:10px;color:var(--faint);letter-spacing:1px}
@media (max-width:720px){ .brand .ver{display:none} }
/* stretti: il titolo si accorcia, non sparisce */
@media (max-width:560px){ .brand .bt{font-size:16px} }
@media (max-width:400px){ .brand .bt{font-size:14px} }

/* Riga 2 — i due contatori hanno la stessa forma: la valuta del mondo e le
   Gemme si leggono con lo stesso colpo d'occhio, ma non hanno lo stesso colore.
   Da mobile si spartiscono la riga in parti uguali. */
.stats{display:flex;align-items:center;gap:8px}
.stat{
  display:flex;align-items:baseline;justify-content:center;gap:7px;white-space:nowrap;
  border:1px solid var(--line-2);border-radius:999px;padding:6px 14px;
  background:linear-gradient(180deg,var(--panel-2),var(--panel));
  box-shadow:var(--edge);
}
.stat[hidden]{display:none}
.stat .sym{align-self:center;font-size:14px;line-height:1}
.stat b{font-family:var(--font-num);font-weight:500;font-size:16px;color:var(--ink);letter-spacing:.3px}
.stat .rate{font-family:var(--font-num);font-size:11px;color:var(--faint)}
.stat .rate b{font-size:11px;color:var(--good)}
.stat.cur{border-color:color-mix(in srgb,var(--accent) 40%, var(--line-2))}
.stat.cur .sym{filter:drop-shadow(0 0 8px color-mix(in srgb,var(--accent) 70%, transparent))}
.stat.gem .sym{color:var(--gold);filter:drop-shadow(0 0 6px color-mix(in srgb,var(--gold) 60%, transparent))}
.stat.gem span:last-child{font-size:11px;color:var(--muted);letter-spacing:.5px}
/* Da mobile la riga è di chi produce: la valuta del mondo la occupa tutta, le
   Gemme si stringono attorno al loro numero — il simbolo ✦ le nomina già. */
@media (max-width:560px){
  .stats{gap:6px}
  .stat.cur{justify-content:flex-start;padding:6px 14px}
  .stat.gem{flex:none;padding:6px 12px}
  .stat.gem span:last-child{display:none}
}

/* Bacheca (__board) e Vignette (__cross): da mobile l'header si stringe. Lì i
   numeri — traguardi e Gemme — non sono la cosa da guardare (a differenza dei
   mondi, dove la valuta che sale è il cuore della schermata), e il logo vive già
   come sfondo: in header è ridondante. Via il logo, contatori più piccoli. */
@media (max-width:560px){
  body[data-world="__board"] .hud-logo,
  body[data-world="__cross"] .hud-logo{display:none}
  body[data-world="__board"] .hud,
  body[data-world="__cross"] .hud{padding:7px 12px}
  body[data-world="__board"] .stat,
  body[data-world="__cross"] .stat{padding:4px 11px}
  body[data-world="__board"] .stat .sym,
  body[data-world="__cross"] .stat .sym{font-size:12px}
  body[data-world="__board"] .stat b,
  body[data-world="__cross"] .stat b{font-size:13px}
}

/* DEBUG — tasti provvisori del playtest (vedi #debugBar in index.html e
   addGemme/addValuta in main.js). Stile volutamente sobrio, col bordo
   tratteggiato: si distingue a colpo d'occhio dai comandi veri del gioco. */
.debugbar{display:flex;gap:6px;flex-wrap:wrap}
.debugbar button{
  font-family:var(--font-num);font-size:11px;letter-spacing:.3px;
  color:var(--muted);cursor:pointer;
  padding:3px 10px;border-radius:999px;
  border:1px dashed var(--line-2);
  background:color-mix(in srgb,var(--panel) 60%, transparent);
  transition:color .14s, border-color .14s, background .14s;
}
.debugbar button:hover{color:var(--ink);border-color:var(--gold);
  background:color-mix(in srgb,var(--gold) 12%, transparent)}
.debugbar button:active{transform:translateY(1px)}

/* ---------- Tendina dei mondi ----------
   Scende dal titolo, allineata al suo bordo sinistro. */
.wmenu{
  position:absolute;top:calc(100% + 8px);left:0;z-index:31;
  min-width:min(280px, calc(100vw - 40px));padding:6px;
  border:1px solid var(--line-2);border-radius:16px;
  background:color-mix(in srgb, var(--panel) 92%, transparent);
  backdrop-filter:blur(18px) saturate(1.2);-webkit-backdrop-filter:blur(18px) saturate(1.2);
  box-shadow:var(--edge), var(--sh-pop);
  animation:menuIn .14s ease-out;
  /* con molti mondi la lista supera lo schermo: è ancorata all'header sticky,
     quindi scrollare la PAGINA non la raggiunge — deve scorrere da sé. Il
     tetto lascia fuori l'header (~top 12 + altezza + gap) e un margine sotto;
     overscroll-contain evita che il pollice, arrivato in fondo, trascini la
     pagina dietro. */
  max-height:calc(100vh - 128px);
  max-height:calc(100dvh - 128px);
  overflow-y:auto;overscroll-behavior:contain;
  /* la scrollbar di sistema stona col vetro: sottile, in tinta, pista invisibile
     (Firefox e standard; per WebKit/Blink le regole ::-webkit qui sotto) */
  scrollbar-width:thin;
  scrollbar-color:color-mix(in srgb,var(--accent) 42%, var(--line-2)) transparent;
}
/* WebKit/Blink: pollice sottile e arrotondato, staccato dai bordi dal bordo
   trasparente + background-clip; pista trasparente, con margine dagli angoli */
.wmenu::-webkit-scrollbar{width:9px}
.wmenu::-webkit-scrollbar-track{background:transparent;margin:8px 0}
.wmenu::-webkit-scrollbar-thumb{
  background:color-mix(in srgb,var(--accent) 40%, var(--line-2));
  border-radius:999px;border:3px solid transparent;background-clip:padding-box;
}
.wmenu::-webkit-scrollbar-thumb:hover{
  background:color-mix(in srgb,var(--accent) 62%, var(--line-2));background-clip:padding-box;
}
/* in sola-memoria l'header scende sotto la barra rossa (+40px): il menu con lui */
body.no-save .wmenu{max-height:calc(100dvh - 168px)}
.wmenu[hidden]{display:none}
@keyframes menuIn{from{opacity:0;transform:translateY(-6px)}}

.wi{
  width:100%;display:grid;grid-template-columns:auto 1fr auto;align-items:center;
  column-gap:10px;cursor:pointer;text-align:left;
  padding:9px 11px;border:1px solid transparent;border-radius:11px;
  background:transparent;color:var(--muted);font-family:var(--font-body);
  transition:background .12s, color .12s, border-color .12s;
}
.wi .dot{width:8px;height:8px;border-radius:50%;background:var(--tab-c,var(--accent));box-shadow:0 0 8px var(--tab-c,var(--accent))}
.wi .wn{font-weight:700;font-size:13px;letter-spacing:.2px}
.wi .wt{grid-column:2;font-size:10.5px;color:var(--faint);line-height:1.35;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.wi .wk{font-family:var(--font-num);font-size:10.5px;color:var(--faint)}
.wi.locked .wk{color:var(--gold)}
.wi:hover{color:var(--ink);background:color-mix(in srgb,var(--tab-c) 12%, transparent)}
.wi.active{
  color:var(--ink);border-color:color-mix(in srgb,var(--tab-c) 40%, transparent);
  background:color-mix(in srgb,var(--tab-c) 15%, transparent);
}
.wi.locked{opacity:.66}
.wi.locked .dot{background:var(--faint);box-shadow:none}
/* gli Obiettivi non sono un mondo: una riga di stacco lo dice senza scriverlo */
.wsep{height:1px;margin:6px 8px;background:var(--line)}

/* il reset cancella la partita: rosso, così non lo si scambia per un mondo */
.wi.reset{--tab-c:#d9534f}
.wi.reset .wn,
.wi.reset .wk{color:#d9534f}
.wi.reset .dot{background:#d9534f;box-shadow:none;opacity:.75}

/* ---------- Testata di pagina (solo la Bacheca, che non ha un HUD proprio) ---------- */
.pagehead{margin:4px 2px 18px}
.pagehead h2{font-family:var(--font-display);font-weight:900;font-size:20px;margin:0 0 4px}
.pagehead p{margin:0;font-size:12.5px;color:var(--muted);max-width:52ch}

.board-hero{display:flex;justify-content:center;height:20px}
.board-hero img{max-width:100vw;position:fixed;z-index:-1}

/* ---------- Barra delle sezioni (fissa in basso) ---------- */
.sectionbar{
  position:fixed;left:50%;transform:translateX(-50%);bottom:16px;z-index:40;
  display:flex;justify-content:center;gap:4px;width:min(660px, calc(100% - 24px));
  padding:7px;border-radius:18px;
  background:color-mix(in srgb, var(--panel) 78%, transparent);
  backdrop-filter:blur(16px) saturate(1.2);-webkit-backdrop-filter:blur(16px) saturate(1.2);
  border:1px solid var(--line-2);
  box-shadow:var(--edge), var(--sh-float);
}
.sectionbar[hidden]{display:none}
.sbtn{
  flex:1 1 0;max-width:180px;min-width:0;cursor:pointer;position:relative;
  display:flex;flex-direction:column;align-items:center;gap:2px;
  padding:8px 6px;border:1px solid transparent;border-radius:12px;
  background:transparent;color:var(--faint);
  font-family:var(--font-body);transition:color .12s, background .12s, border-color .12s;
}
.sbtn:hover{color:var(--muted);background:color-mix(in srgb,var(--bg-2) 70%, transparent)}
.sbtn.active{
  color:var(--ink);border-color:color-mix(in srgb,var(--accent) 45%, var(--line-2));
  background:color-mix(in srgb,var(--accent) 16%, var(--panel));
}
.sbtn .sic{font-size:18px;line-height:1;filter:grayscale(1) opacity(.6);transition:filter .12s}
.sbtn.active .sic{filter:none}
.sbtn .slabel{font-size:11.5px;font-weight:700;letter-spacing:.2px;white-space:nowrap}
.sbtn .scnt{font-family:var(--font-num);font-size:10px;color:var(--faint)}
.sbtn.active .scnt{color:var(--accent)}
/* sezione completata: il contatore si accende, cosi' si vede a colpo d'occhio */
.sbtn .scnt.full{color:var(--done)}
/* su schermi stretti restano solo icona e contatore */
@media (max-width:520px){ .sbtn .slabel{display:none} }

/* ---------- Bacheca dei traguardi ---------- */
.faction-h .acnt-sec{margin-left:auto;font-family:var(--font-num);font-size:11px;color:var(--faint);text-transform:none;letter-spacing:0}

.achgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:12px}
.ach{
  display:flex;align-items:center;gap:12px;padding:13px 14px;
  border:1px solid var(--line);border-radius:14px;background:var(--panel);
  opacity:.9;transition:opacity .2s, border-color .2s;
}
.ach.done{
  opacity:1;border-color:color-mix(in srgb,var(--done-fill) 45%, var(--line));
  background:color-mix(in srgb,var(--done-fill) 8%, var(--panel));
  box-shadow:var(--edge), 0 6px 20px color-mix(in srgb,var(--done-fill) 14%, transparent);
}
.ach .aic{
  width:42px;height:42px;flex:none;border-radius:11px;display:grid;place-items:center;font-size:20px;
  background:var(--bg-2);border:1px solid var(--line);filter:grayscale(1) opacity(.5);transition:filter .3s;
}
.ach.done .aic{filter:none;box-shadow:0 0 0 2px color-mix(in srgb,var(--done-fill) 45%, transparent)}
.ach .abody{flex:1;min-width:0;display:flex;flex-direction:column;gap:5px}
.ach .an{font-weight:700;font-size:13.5px}
.ach .atick{color:var(--done)}
.ach .ad{font-size:11.5px;color:var(--muted)}
.ach .bar{height:5px;border-radius:999px;background:var(--bg-2);border:1px solid var(--line);overflow:hidden}
.ach .fill{height:100%;border-radius:999px;background:var(--faint)}
.ach.done .fill{background:var(--done-fill)}
.ach .acnt{font-family:var(--font-num);font-size:13px;color:var(--ink);flex:none;text-align:right}
.ach .acnt span{color:var(--faint);font-size:11px}

/* ---------- Campagna del mondo ---------- */
.camp{
  border:1px solid var(--line-2);border-radius:var(--r);padding:17px 19px;
  background:linear-gradient(180deg, color-mix(in srgb,var(--gold) 8%, var(--panel)), var(--panel));
  display:flex;flex-direction:column;gap:12px;
  box-shadow:var(--edge), var(--sh-1);
  position:relative;overflow:hidden;
}
.camp.locked{border-style:dashed;background:var(--panel);opacity:.8;box-shadow:none}
.camp .ch{display:flex;align-items:center;gap:12px}
.camp .ic{width:40px;height:40px;border-radius:10px;display:grid;place-items:center;font-size:20px;background:var(--bg-2);border:1px solid var(--line);flex:none}
.camp .cn{font-family:var(--font-display);font-weight:700;font-size:15px}
.camp .cd{font-size:11.5px;color:var(--muted);max-width:56ch}
.camp .creward{margin-left:auto;font-family:var(--font-num);font-size:13px;color:var(--gold);flex:none}
.camp .bar{height:10px;border-radius:999px;background:var(--bg-2);border:1px solid var(--line);overflow:hidden}
.camp .fill{
  height:100%;border-radius:999px;
  background:linear-gradient(90deg, color-mix(in srgb,var(--accent) 70%, var(--gold)), var(--gold));
  box-shadow:0 0 12px color-mix(in srgb,var(--gold) 50%, transparent);
  transition:width .2s linear;
}
.camp.locked .fill{background:var(--faint);box-shadow:none}
.camp .cfoot{display:flex;justify-content:space-between;align-items:center;gap:12px;font-size:11.5px;color:var(--muted)}
.camp .cfoot .num{font-family:var(--font-num);color:var(--faint)}

/* in attesa di roster o cimeli: il capitolo esiste ma non e' ancora cominciato */
.camp.waiting{border-style:dashed}
.camp.waiting .cfoot{flex-direction:column;align-items:flex-start;gap:6px}
.camp .reqs{display:flex;align-items:center;gap:6px;flex-wrap:wrap}
/* la locandina del capitolo: i protagonisti e i cimeli, sempre in vista */
.camp .ccast{margin-top:-4px}
.camp .cwait{color:var(--muted)}

/* piena: il premio va riscosso a mano, quindi la card deve chiamare */
.camp.ready{
  border-color:color-mix(in srgb,var(--gold) 60%, var(--line-2));
  box-shadow:0 0 0 1px color-mix(in srgb,var(--gold) 30%, transparent), 0 8px 30px rgba(231,178,76,.16);
}
.camp.ready .fill{animation:campglow 1.8s ease-in-out infinite}
@keyframes campglow{0%,100%{filter:brightness(1)}50%{filter:brightness(1.35)}}
.btn.claim{
  background:linear-gradient(180deg,color-mix(in srgb,var(--gold) 34%, var(--panel-2)),var(--panel-2));
  border-color:color-mix(in srgb,var(--gold) 55%, var(--line-2));
}
.btn.claim .cost{color:var(--gold)}

/* ---------- Cronaca: il capitolo in corso, e sotto il diario ---------- */
.chronicle{display:flex;flex-direction:column;gap:12px}
/* un capitolo chiuso non ha più niente da chiedere: si spegne e resta a memoria */
.camp.past{
  background:var(--panel);border-style:solid;
  border-color:color-mix(in srgb,var(--good) 22%, var(--line));
  opacity:.72;transition:opacity .2s;
}
.camp.past .cn{color:var(--accent)}
.camp.past:hover{opacity:1}
.camp.past .ic{filter:grayscale(1) opacity(.6)}
.camp.past .creward{color:var(--faint)}
.camp .cdone{color:var(--done);font-weight:700;font-size:11.5px}
/* le ondate infinite non sono un capitolo: non finiscono, si accumulano */
.camp.past.endless{border-color:color-mix(in srgb,var(--gold) 26%, var(--line))}
.camp.past.endless .cdone{color:var(--gold)}

/* c'è un premio che aspetta un click — un capitolo da riscuotere, un legame da
   stringere — e la sezione non è sott'occhio: il bottone chiama. Oro perché in
   entrambi i casi il premio sono le Gemme. */
.sbtn.alert{color:var(--ink)}
.sbtn.alert .sic{filter:none}
.sbtn.alert::after{
  content:"";position:absolute;top:5px;right:calc(50% - 20px);
  width:7px;height:7px;border-radius:50%;background:var(--gold);
  box-shadow:0 0 8px var(--gold);animation:starpulse 1.6s ease-in-out infinite;
}

/* ---------- Sections ---------- */
.sec{margin:24px 0 6px}
.sec-h{display:flex;align-items:center;gap:10px;margin:0 2px 12px}
.sec-h h3{font-family:var(--font-display);font-weight:700;font-size:14px;letter-spacing:.6px;margin:0;text-transform:uppercase;color:var(--ink)}
.sec-h .ln{flex:1;height:1px;background:linear-gradient(90deg, var(--line-2), transparent)}
.sec-h .cnt{font-family:var(--font-num);font-size:11px;color:var(--faint)}

.faction-h{display:flex;align-items:center;gap:8px;margin:18px 2px 10px;font-weight:700;font-size:12px;letter-spacing:1px;text-transform:uppercase;color:var(--fc)}
.faction-h .seal{width:7px;height:16px;border-radius:2px;background:var(--fc);box-shadow:0 0 10px var(--fc)}

/* ---------- Fazione richiudibile (<details> nativo) ---------- */
.fac{margin-bottom:6px}
.fac > summary{cursor:pointer;list-style:none;user-select:none;
  padding:6px 8px;border-radius:10px;transition:background .12s}
.fac > summary::-webkit-details-marker{display:none}
.fac > summary:hover{background:color-mix(in srgb,var(--fc) 10%, transparent)}
/* quanti ne hai su quanti ne esistono: il totale non mente mai */
.fac .facnt{margin-left:auto;font-family:var(--font-num);font-size:11px;
  color:var(--faint);letter-spacing:0;text-transform:none}
.fac .facnt.full{color:var(--good)}
.fac .chev{font-size:10px;color:var(--faint);transition:transform .18s ease}
.fac[open] > summary .chev{transform:rotate(180deg)}
/* chiusa: il sigillo resta acceso, cosi' la fazione si ritrova a colpo d'occhio */
.fac:not([open]) > summary{opacity:.72}

.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:12px}

/* sezione ancora tutta da scoprire: il vuoto va detto, non lasciato */
.veil{
  border:1px dashed var(--line-2);border-radius:var(--r);padding:30px 24px;
  text-align:center;color:var(--faint);font-size:12.5px;background:var(--panel);
}

/* ---------- Character card ---------- */
.card{
  border:1px solid var(--line);border-radius:14px;
  background:linear-gradient(180deg, var(--panel), color-mix(in srgb,var(--bg-2) 55%, var(--panel)));
  padding:14px;display:flex;flex-direction:column;gap:10px;position:relative;overflow:hidden;
  box-shadow:var(--edge);
  transition:border-color .15s, transform .12s, box-shadow .15s;
}
.card:hover{transform:translateY(-2px);border-color:color-mix(in srgb,var(--accent) 30%, var(--line-2));box-shadow:var(--edge), var(--sh-2)}
.card.locked{opacity:.6;filter:saturate(.8)}

/* ---------- Metà superiore: il ritratto ----------
   Sotto c'è sempre il gradiente del personaggio con la sua iniziale. Il file
   .webp, se esiste, lo copre; se non carica si toglie di mezzo da solo
   (`onerror`) e resta il gradiente. Le due forme hanno la stessa altezza,
   quindi la griglia resta regolare anche con due ritratti su cinquantacinque. */
.hero{
  position:relative;margin:-14px -14px 0;aspect-ratio:5/3;overflow:hidden;
  border-radius:13px 13px 0 0;display:flex;flex-direction:column;justify-content:flex-end;
  background:linear-gradient(150deg, hsl(var(--h),70%,72%), hsl(var(--h2),68%,58%));
}
.hero .hinit{
  position:absolute;inset:0;display:grid;place-items:center;
  font-family:var(--font-display);font-weight:900;font-size:76px;letter-spacing:-3px;
  color:rgba(0,0,0,.2);text-shadow:0 2px 0 rgba(255,255,255,.14);
}
.hero .hart{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center}
/* il velo: senza, il nome bianco sparisce sui ritratti chiari */
.hero .hveil{position:absolute;inset:0;background:linear-gradient(180deg, transparent 38%, rgba(6,9,14,.55) 68%, rgba(6,9,14,.92))}
.hero .hbody{position:relative;padding:10px 12px;display:flex;flex-direction:column;gap:1px}
.hero .nm{
  font-weight:700;font-size:15px;line-height:1.2;color:var(--on-veil);
  text-shadow:0 1px 8px rgba(0,0,0,.7);
  min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.hero .role,.hero .ttl{
  min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  text-shadow:0 1px 6px rgba(0,0,0,.7);
}
.hero .role{font-size:11px;color:var(--on-veil-dim)}
/* il titolo dell'evoluzione resta oro, ma quello VIVO: l'oro da testo è scelto
   per il pannello chiaro, e sul velo scuro sparirebbe */
.hero .ttl{font-size:11px;color:var(--gold-fill);font-weight:700}

/* La pillola delle stelle: sul ritratto, quindi ha un fondo suo — su un'immagine
   chiara l'oro sparirebbe. Le cinque stelle non vanno mai a capo.

   `grid` + `place-items:center` invece di lasciarle inline: i glifi ★ portano
   ascendente e discendente propri, e una scatola inline le appoggia sulla linea
   di base, non le centra sul padding. */
.hero .hstars{
  position:absolute;top:6px;right:6px;z-index:1;
  display:grid;place-items:center;white-space:nowrap;
  background:rgba(6,9,14,.62);border:1px solid var(--line-2);border-radius:8px;padding:4px 7px;
  backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);
}
/* `letter-spacing` spazia anche DOPO l'ultima stella: la scatola resta 1px più
   larga dei glifi e li spinge a sinistra. Il margine negativo se lo riprende. */
.hero .hstars .rankstars{
  display:block;margin:0 -1px 1px 0;line-height:1;
  text-shadow:0 1px 6px rgba(0,0,0,.7);
}
/* Il sigillo dei Ricordi: gemello della pastiglia delle stelle, angolo opposto.
   Sta dentro `.hero`, che è già `position:relative`, quindi nessuna delle tre
   zone di testo della card (abilità, produzione, bottone) si sposta di un pixel.
   Compare solo quando un Ricordo è stato trovato — vedi charCard(). */
.hero .hmem{
  position:absolute;top:6px;left:6px;z-index:1;
  display:flex;align-items:center;gap:4px;
  background:rgba(6,9,14,.62);border:1px solid var(--line-2);border-radius:8px;padding:4px 7px;
  backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);
  color:var(--gold-fill);font-size:12px;line-height:1;cursor:pointer;
  transition:border-color .15s, transform .15s;
}
.hero .hmem .seal{display:block;text-shadow:0 1px 6px rgba(0,0,0,.7)}
.hero .hmem b{font-family:var(--font-num);font-size:10px;color:var(--on-veil)}
.hero .hmem:hover{border-color:var(--gold-fill);transform:translateY(-1px)}

/* evoluto: una cornice d'oro dentro al ritratto. Sta sull'immagine, non sul
   pannello, quindi vuole l'oro vivo come le stelle. */
.hero.ranked{box-shadow:inset 0 0 0 2px var(--gold-fill)}
.card.locked .hero{filter:grayscale(1) brightness(.72)}

/* ---------- Il grado di stelle ----------
   Cinque gradi, una regola sola: `--tier` (0..5) arriva dalla card e il
   `calc()` dentro `color-mix` ne ricava l'intensità. Aggiungere una sesta
   stella non richiede una sesta riga di CSS.

   L'anello è un `::after`, non un bordo: `border-color` se lo contendono già
   il cel-shading del mondo ninja e lo stato `:hover`, e la card finirebbe a
   litigare con sé stessa a colpi di specificità. Sopra a tutto, senza eventi. */
.card.starred::after{
  content:"";position:absolute;inset:0;z-index:2;pointer-events:none;
  border-radius:inherit;
  box-shadow:inset 0 0 0 2px color-mix(in srgb, var(--gold-fill) calc(var(--tier) * 18%), transparent);
}
/* la pillola si accende con lui: il bordo dice il grado anche da lontano */
.card.starred .hstars{
  border-color:color-mix(in srgb, var(--gold-fill) calc(var(--tier) * 16%), var(--line-2));
}

/* L'ultimo gradino è l'unico che merita un trattamento suo: l'anello si
   riempie, un alone caldo entra dai bordi, e il nome smette di essere scritto
   per diventare inciso. */
.card.maxstar::after{
  box-shadow:
    inset 0 0 0 2px var(--gold-fill),
    inset 0 0 26px color-mix(in srgb, var(--gold-fill) 26%, transparent);
}
.card.maxstar .hstars{
  border-color:var(--gold-fill);
  background:rgba(6,9,14,.74);
}
.card.maxstar .nm{
  /* Il testo ritagliato non porta ombra: `text-shadow` disegnerebbe l'ombra di
     un testo trasparente, cioè una macchia. La leggibilità la dà il velo. */
  background:linear-gradient(100deg,
    var(--on-veil) 0 34%, var(--gold-fill) 44%, #fff4d2 50%, var(--gold-fill) 56%, var(--on-veil) 66% 100%);
  background-size:260% 100%;
  -webkit-background-clip:text;background-clip:text;color:transparent;
  text-shadow:none;
  animation:nameshine 5s linear infinite;
}
/* la luce passa sul nome una volta ogni cinque secondi: si nota, non distrae */
@keyframes nameshine{from{background-position:140% 0}to{background-position:-40% 0}}
/* avatar quadrato: resta solo nella vetrina dei mondi ancora chiusi */
.ava{
  position:relative;overflow:hidden;
  width:46px;height:46px;border-radius:12px;flex:none;display:grid;place-items:center;
  font-family:var(--font-display);font-weight:900;font-size:20px;color:#1a1620;
  background:linear-gradient(150deg, hsl(var(--h),70%,72%), hsl(var(--h2),68%,58%));
  box-shadow:0 4px 14px hsla(var(--h),60%,40%,.35), inset 0 1px 0 rgba(255,255,255,.35);
}
/* la miniatura copre l'iniziale; se il file manca, artFallback la toglie */
.ava .cart{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
.abil{font-size:11.5px;color:var(--muted);background:var(--bg-2);border:1px solid var(--line);border-radius:9px;padding:7px 9px;min-height:34px;display:flex;flex-direction:column;gap:6px}
.abil b{color:color-mix(in srgb,var(--accent) 70%, var(--ink))}
/* abilita' sbloccate dalle evoluzioni: separate da un filetto, non da un elenco puntato */
.abil .ab + .ab{border-top:1px solid var(--line);padding-top:6px}
/* ---------- Quanto produce, e di quanto è moltiplicato ----------
   Una riga sola: il numero prodotto a sinistra, il moltiplicatore totale in
   fondo a destra. La scomposizione ("da sé ×2.54 · dagli altri ×2.34") vive nel
   tooltip: è la risposta a una domanda che si fa di rado. */
.prod{display:flex;align-items:baseline;gap:5px;font-family:var(--font-num)}
.prod.none{font-size:11.5px;color:var(--faint)}
.prod b{font-size:15px;font-weight:500;color:var(--good);letter-spacing:.2px}
.prod .punit{font-size:11px;color:var(--faint)}

/* la pastiglia del totale: spinta a destra, si legge come un'etichetta cucita
   sul numero, non come un secondo numero in gara con lui */
.prod .pmul{
  margin-left:auto;align-self:center;cursor:help;
  font-size:11px;font-weight:500;color:var(--accent);letter-spacing:.2px;
  border:1px solid color-mix(in srgb,var(--accent) 32%, var(--line));
  background:color-mix(in srgb,var(--accent) 10%, transparent);
  border-radius:999px;padding:2px 8px;white-space:nowrap;
}
/* moltiplicatore fuori scala: una dicitura al posto del numero */
.prod .pmul.beyond{
  font-family:var(--font-body);font-size:10.5px;color:var(--gold);
  border-color:color-mix(in srgb,var(--gold) 38%, var(--line));
  background:color-mix(in srgb,var(--gold) 12%, transparent);
}
.btn{
  border:1px solid var(--line-2);border-radius:10px;padding:9px 12px;cursor:pointer;
  font-family:var(--font-body);font-weight:700;font-size:13px;color:var(--ink);
  background:var(--panel-2);display:flex;justify-content:space-between;gap:10px;align-items:center;
  box-shadow:var(--edge);
  transition:background .12s, border-color .12s, transform .08s;width:100%;
  /* si tiene premuto per salire di livello: il dito non deve selezionare il
     testo, né far comparire la lente o il doppio-tap zoom di iOS */
  touch-action:manipulation;user-select:none;-webkit-user-select:none;-webkit-touch-callout:none;
}
.btn:hover{border-color:var(--line-2);filter:brightness(1.12)}
.btn:active{transform:scale(.985)}
.btn .cost{font-family:var(--font-num);font-size:12px;color:var(--muted)}
.btn.affordable{border-color:color-mix(in srgb,var(--accent) 55%, var(--line-2));background:color-mix(in srgb,var(--accent) 18%, var(--panel-2))}
.btn.affordable .cost{color:var(--accent)}
.btn:disabled{opacity:.42;cursor:not-allowed;filter:none}
.btn.recruit{background:color-mix(in srgb,var(--accent) 20%, var(--panel-2))}
.btn.ascend{background:linear-gradient(180deg,color-mix(in srgb,var(--gold) 26%, var(--panel-2)),var(--panel-2));border-color:color-mix(in srgb,var(--gold) 45%, var(--line-2))}
.btn.ascend .cost{color:var(--gold)}
.btn.ascend.affordable{border-color:color-mix(in srgb,var(--gold) 70%, var(--line-2));background:color-mix(in srgb,var(--gold) 20%, var(--panel-2))}
.btn.star{background:linear-gradient(180deg,color-mix(in srgb,var(--gold) 14%, var(--panel-2)),var(--panel-2))}
.btn.star .cost{color:var(--gold)}
.btn.star.affordable{border-color:color-mix(in srgb,var(--gold) 70%, var(--line-2));background:color-mix(in srgb,var(--gold) 18%, var(--panel-2))}
.rankstars{color:var(--gold);font-size:11px;letter-spacing:1px;margin-left:6px;filter:drop-shadow(0 0 4px rgba(231,178,76,.5))}
/* una stella e' pronta da riscuotere: pulsa piano per farsi notare */
.rankstars.ready{animation:starpulse 1.6s ease-in-out infinite}
@keyframes starpulse{0%,100%{opacity:1}50%{opacity:.45}}

/* ---------- Upgrade / landmark ---------- */
.up{
  border:1px solid var(--line);border-radius:12px;
  background:linear-gradient(180deg, var(--panel), color-mix(in srgb,var(--bg-2) 55%, var(--panel)));
  padding:13px 14px;box-shadow:var(--edge);
  display:flex;flex-direction:column;gap:9px;transition:border-color .15s;
}
.up .uh{display:flex;align-items:center;gap:10px}
.up .ic{width:36px;height:36px;border-radius:9px;display:grid;place-items:center;font-size:18px;background:var(--bg-2);border:1px solid var(--line)}
.up .un{font-weight:700;font-size:14px}
.up .ud{font-size:11.5px;color:var(--muted)}
.up .ulv{font-family:var(--font-num);font-size:11px;color:var(--faint)}
.up .ulv b{color:var(--done);font-weight:500}
/* costruito ma migliorabile: accento del mondo. Al massimo: verde, è finito. */
.up.bought{border-color:color-mix(in srgb,var(--accent) 35%, var(--line));background:color-mix(in srgb,var(--accent) 7%, var(--panel))}
.up.maxed{border-color:color-mix(in srgb,var(--done-fill) 45%, var(--line));background:color-mix(in srgb,var(--done-fill) 8%, var(--panel))}
.up .ubar{height:4px;border-radius:999px;background:var(--bg-2);border:1px solid var(--line);overflow:hidden}
.up .ubar .fill{height:100%;border-radius:999px;background:var(--accent);transition:width .25s}
.up.maxed .ubar .fill{background:var(--done-fill)}
.up .ueff{display:flex;justify-content:space-between;gap:8px;font-family:var(--font-num);font-size:11px;color:var(--good)}
.up .ueff .unext{color:var(--faint)}
.up .done{font-size:12px;color:var(--done);font-weight:700;display:flex;align-items:center;gap:6px;justify-content:center;padding:6px}

/* ---------- Fusion ---------- */
.fus{
  border:1px dashed var(--line-2);border-radius:14px;background:
    linear-gradient(180deg, color-mix(in srgb,var(--gold) 6%, var(--panel)), var(--panel));
  padding:14px 16px;display:flex;flex-direction:column;gap:11px;
}
.fus.ready{border-style:solid;border-color:color-mix(in srgb,var(--gold) 60%, var(--line-2));box-shadow:0 0 0 1px color-mix(in srgb,var(--gold) 30%, transparent),0 8px 30px rgba(231,178,76,.12)}
.fus.done{border-style:solid;border-color:color-mix(in srgb,var(--done-fill) 45%, var(--line));background:color-mix(in srgb,var(--done-fill) 8%, var(--panel))}
.fus .fh{display:flex;align-items:center;gap:10px}
.fus .fname{font-family:var(--font-display);font-weight:700;font-size:15px}
.fus .freward{margin-left:auto;font-family:var(--font-num);font-size:12px;color:var(--gold)}
.fus .members{display:flex;gap:7px;flex-wrap:wrap}
.fus .fdesc{font-size:11.5px;color:var(--muted)}
.fus .fdone{color:var(--done);font-weight:700;text-align:center;font-size:12px;padding:6px}
.mchip{font-size:11.5px;padding:4px 9px;border-radius:8px;border:1px solid var(--line);background:var(--bg-2);color:var(--muted);display:flex;gap:6px;align-items:center}
.mchip.ok{color:var(--good);border-color:color-mix(in srgb,var(--good) 40%, var(--line))}
.mchip .mk{font-family:var(--font-num);font-size:10px;opacity:.85}
/* compagno non ancora reclutato: il nome e' la sorpresa, non lo si anticipa */
.mchip.unknown{color:var(--faint);border-style:dashed;letter-spacing:2px;font-weight:700}

/* avanzamento del legame: quanti sono, e quanto pesano */
.fus .fbar{height:6px;border-radius:999px;background:var(--bg-2);border:1px solid var(--line);overflow:hidden}
/* `--naruto` esiste solo nel tema ninja: senza fallback, negli altri mondi la
   barra dei legami era invisibile (background con var non definita). */
.fus .fbar .fill{height:100%;border-radius:999px;background:var(--naruto, var(--accent));transition:width .25s}
.fus.ready .fbar .fill{box-shadow:0 0 10px color-mix(in srgb,var(--gold) 60%, transparent)}
.fus .fprog{display:flex;justify-content:space-between;gap:10px;font-size:11px;color:var(--muted)}
.fus .fprog .num{font-family:var(--font-num);color:var(--faint)}
.fus .btn.fuse{background:linear-gradient(180deg,color-mix(in srgb,var(--gold) 34%, var(--panel-2)),var(--panel-2));border-color:color-mix(in srgb,var(--gold) 50%, var(--line-2))}

/* ---------- Collezione (vetrina / money sink) ---------- */
.shelf{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:12px}
.coll{border:1px solid var(--line);border-radius:14px;background:var(--panel);padding:14px 12px;display:flex;flex-direction:column;align-items:center;gap:8px;text-align:center;position:relative;box-shadow:var(--edge)}
.coll .citem{position:relative;width:60px;height:60px;border-radius:14px;display:grid;place-items:center;font-size:30px;background:var(--bg-2);border:1px solid var(--line);overflow:hidden;filter:grayscale(1) opacity(.35);transition:filter .3s, transform .2s}
/* la miniatura della vignetta copre l'icona; se il file manca, artFallback la
   toglie e l'icona sotto riappare */
.coll .citem .cart{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
.coll .cname{font-size:12px;font-weight:700;color:var(--muted);min-height:30px;display:flex;align-items:center}
.coll.owned{border-color:color-mix(in srgb,var(--done-fill) 45%, var(--line));background:color-mix(in srgb,var(--done-fill) 8%, var(--panel))}
.coll.owned .citem{filter:none;transform:translateY(-1px);box-shadow:0 0 0 2px color-mix(in srgb,var(--done-fill) 50%, transparent),0 6px 18px color-mix(in srgb,var(--done-fill) 22%, transparent)}
.coll.owned .cname{color:var(--ink)}
.coll .cown{font-size:11.5px;font-weight:700;color:var(--done)}
.btn.coll-buy{padding:8px 10px;font-size:12px;justify-content:center;width:100%}
.btn.coll-buy .cost{font-family:var(--font-num);font-size:11px}
.btn.coll-buy.affordable{border-color:color-mix(in srgb,var(--gold) 60%, var(--line-2));background:color-mix(in srgb,var(--gold) 16%, var(--panel-2))}
.btn.coll-buy.affordable .cost{color:var(--gold)}

/* ---------- Locked world panel ---------- */
.locked-panel{
  border:1px dashed var(--line-2);border-radius:var(--r);padding:30px;text-align:center;
  background:var(--panel);box-shadow:var(--edge);
}
.locked-panel h3{font-family:var(--font-display);font-size:19px;margin:0 0 6px}
.locked-panel p{color:var(--muted);font-size:13px;margin:0 auto 16px;max-width:46ch}
.locked-panel .roster{display:flex;gap:8px;justify-content:center;flex-wrap:wrap;margin-bottom:18px}
.locked-panel .roster .g{width:38px;height:38px;border-radius:10px;filter:grayscale(.4) brightness(.8)}
.locked-panel .hint{margin-top:12px;font-size:11.5px;color:var(--faint)}
.unlockbtn{
  font-family:var(--font-body);font-weight:700;font-size:14px;cursor:pointer;
  border:1px solid color-mix(in srgb,var(--gold) 50%, var(--line-2));border-radius:12px;
  padding:12px 22px;background:color-mix(in srgb,var(--gold) 16%, var(--panel-2));color:var(--ink);
  display:inline-flex;gap:10px;align-items:center;transition:transform .1s}
.unlockbtn:hover{transform:translateY(-1px)}
.unlockbtn:disabled{opacity:.5;cursor:not-allowed}
.unlockbtn .star{color:var(--gold)}

/* ---------- Toast ---------- */
/* Su mobile un annuncio stretto e centrato viene letto a metà: sta sopra la
   barra delle sezioni, largo quanto la pagina, e il testo va a capo invece di
   restare su una riga sola. */
.toast{
  position:fixed;left:50%;transform:translateX(-50%);bottom:96px;z-index:50;
  width:min(560px, calc(100vw - 24px));box-sizing:border-box;
  display:flex;align-items:center;gap:12px;
  background:var(--panel-2);border:1px solid var(--line-2);border-radius:12px;
  padding:14px 18px;font-size:13.5px;line-height:1.45;box-shadow:var(--sh-pop);
  opacity:0;pointer-events:none;transition:opacity .3s, transform .3s}
.toast.show{opacity:1;transform:translateX(-50%) translateY(0)}
.toast b{color:var(--accent)}
.toast .gm{color:var(--gold)}
.toast .tmsg{flex:1;min-width:0}

/* Un annuncio che porta da qualche parte si preme: la freccia lo dichiara.
   Gli altri restano trasparenti al tocco — non devono rubare tap alle card. */
.toast.go{
  cursor:pointer;
  border-color:color-mix(in srgb, var(--accent) 45%, var(--line-2));
  -webkit-tap-highlight-color:transparent;
}
.toast.go.show{pointer-events:auto}
.toast.go:active{transform:translateX(-50%) scale(.985)}
.toast .tgo{flex:none;color:var(--accent);font-size:20px;line-height:1;font-weight:700}

/* La riga raggiunta da un annuncio — una card, un obiettivo, un legame: un
   lampo, o dopo lo scroll non si saprebbe quale delle venti fosse quella di
   cui si parlava. */
.flash{animation:cardflash 1.6s ease-out}
@keyframes cardflash{
  0%,55%{box-shadow:0 0 0 2px var(--accent), var(--sh-pop)}
  100%{box-shadow:0 0 0 0 transparent}
}

.foot{margin:80px 0 0;text-align:center;color:var(--faint);font-size:11.5px}
.foot code{font-family:var(--font-num);background:var(--panel);padding:2px 6px;border-radius:6px;border:1px solid var(--line)}

/* Avviso di sola-memoria. Nascosto finché il boot non aggiunge `no-save` al body;
   allora la barra compare in cima e la testata sticky scende sotto di essa, così
   non la copre. Rosso pieno: non è un consiglio, è "stai perdendo i progressi". */
.savewarn{display:none;position:fixed;top:0;left:0;right:0;z-index:70;
  background:#b3261e;color:#fff;text-align:center;padding:9px 16px;
  font-size:12.5px;font-weight:500;line-height:1.4;box-shadow:0 2px 10px rgba(0,0,0,.28)}
.savewarn b{font-weight:800}
body.no-save .savewarn{display:block}
body.no-save .hudwrap{top:52px}

/* ---- il popup dei Ricordi ----------------------------------------------
   Sopra il toast (z-50) e il dock (z-40): mentre leggi un Ricordo, non c'è
   altro da cliccare. `[hidden]` va riaffermato, o il `display:grid` lo vince.
   Le scene disegnate arrivano alla spicciolata: quando il file manca,
   artFallback toglie l'<img> e resta l'icona dentro .memfig. */
.modal{
  position:fixed;inset:0;z-index:60;display:grid;place-items:center;padding:20px;
  background:rgba(6,9,14,.6);backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px);
}
.modal[hidden]{display:none}
.mbox{
  position:relative;width:min(520px,100%);max-height:80vh;overflow:auto;
  background:var(--panel);border:1px solid var(--line);border-radius:16px;
  padding:18px;box-shadow:var(--sh-pop);
}
.mx{
  position:absolute;top:10px;right:10px;width:28px;height:28px;border-radius:8px;
  border:1px solid var(--line);background:var(--panel-2);color:var(--muted);
  cursor:pointer;font-size:16px;line-height:1;
}
.mx:hover{color:var(--ink);border-color:var(--line-2)}
.mhead{margin:0 0 14px}
.mtitle{font-family:var(--font-display);font-weight:700;font-size:18px;color:var(--ink)}
.msub{font-size:11px;color:var(--faint)}
.mlist{display:flex;flex-direction:column;gap:20px}

/* Una scena a sé: immagine sopra (il formato 4:3 dei fotogrammi), testo sotto.
   Più cartolina che riga d'elenco — un Ricordo è un momento, non un dato. */
.mem{
  border:1px solid var(--line);border-radius:14px;overflow:hidden;
  background:var(--panel-2);box-shadow:var(--sh-1);
}
.memfig{
  position:relative;aspect-ratio:4/3;overflow:hidden;
  display:grid;place-items:center;
  background:linear-gradient(150deg, color-mix(in srgb,var(--accent) 22%, var(--bg-2)), var(--bg-2));
}
/* il segnaposto: sta sotto l'immagine e si scopre solo se il file manca */
.memicon{font-size:56px;opacity:.55;filter:saturate(.9)}
.memart{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
/* una velatura in basso, così il titolo qui sotto sembra nascere dalla scena */
.memfig::after{content:"";position:absolute;left:0;right:0;bottom:0;height:38%;
  background:linear-gradient(180deg, transparent, color-mix(in srgb,var(--panel-2) 78%, transparent))}
.memtx{padding:13px 16px 16px}
.memn{font-family:var(--font-display);font-weight:700;font-size:15px;color:var(--gold);margin-bottom:6px}
.memp{margin:0;font-size:12.5px;line-height:1.65;color:var(--muted)}

/* =====================================================================
   MONDO NINJA — quello che le variabili non sanno dire.

   Tre segni, tre significati:
     la spirale Uzumaki     filigrana dell'intestazione, il mondo stesso
     la targa della fascia  striscia di metallo sopra l'intestazione
     il calore sul bordo    un velo d'arancione in cima a ogni card
   ===================================================================== */
/* la targa: acciaio spazzolato, con i due fori del cordino. Corre lungo il
   bordo basso dell'HUD, dove una fascia ninja porterebbe la sua placca. */
body[data-world="ninja"] .hud{
  border-color:color-mix(in srgb,var(--accent) 22%, var(--line-2));
  padding-bottom:14px;
}
body[data-world="ninja"] .hud::before{
  content:"";position:absolute;left:0;right:0;bottom:0;height:6px;z-index:2;
  background:
    radial-gradient(circle at 22px 50%, #14181d 1.4px, transparent 1.8px),
    radial-gradient(circle at calc(100% - 22px) 50%, #14181d 1.4px, transparent 1.8px),
    linear-gradient(180deg,#9aa6b2, #5b6674 42%, #333c46);
  box-shadow:0 -1px 6px rgba(0,0,0,.5);
}
/* Il logo del gioco vive nell'header come oggetto vero (.hud-logo), non più come
   filigrana: prima qui c'era la spirale Uzumaki, ma valeva solo per il ninja. */

/* ---------------------------------------------------------------------
   CEL-SHADING — quello che una palette chiara, da sola, non ottiene.

   Un tema chiaro ottenuto solo scambiando le variabili resta un tema scuro
   schiarito: sfumature morbide, bagliori, bordi appena accennati. L'anime non
   ha niente di tutto questo. Tre regole, applicate ovunque:

     BORDO NETTO      2px d'inchiostro, non un filo bianco trasparente
     OMBRA SECCA      uno scalino sotto l'oggetto, zero sfocatura
     TINTA PIENA      il colore riempie, non tinge il fondo per trasparenza

   Il bordo scuro è anche ciò che tiene insieme la composizione: su carta, senza
   tratto, le card bianche su fondo bianco sparirebbero l'una nell'altra.
   --------------------------------------------------------------------- */
body[data-world="ninja"] .card,
body[data-world="ninja"] .up,
body[data-world="ninja"] .coll,
body[data-world="ninja"] .fus,
body[data-world="ninja"] .camp,
body[data-world="ninja"] .ach,
body[data-world="ninja"] .locked-panel{
  border-width:2px;
  border-color:color-mix(in srgb, var(--ink) 15%, transparent);
  background-image:none;                       /* niente veli: tinta piena */
}
body[data-world="ninja"] .card:hover{
  transform:translateY(-3px);
  border-color:var(--accent);
  box-shadow:0 6px 0 color-mix(in srgb, var(--ink) 12%, transparent);
}

/* Il bottone è un blocco di colore. Spento è carta; quando puoi permettertelo
   diventa arancione pieno con il testo bianco — non c'è nessuna ambiguità su
   cosa sia premibile, che è l'unica domanda che il giocatore fa a un bottone. */
body[data-world="ninja"] .btn{
  border-width:2px;border-color:color-mix(in srgb, var(--ink) 16%, transparent);
  background:var(--panel-2);box-shadow:0 2px 0 color-mix(in srgb, var(--ink) 14%, transparent);
  transition:transform .06s, box-shadow .06s, background .12s, border-color .12s;
}
body[data-world="ninja"] .btn:hover{filter:none;border-color:color-mix(in srgb, var(--ink) 30%, transparent)}
/* premuto: il blocco affonda nella carta, invece di rimpicciolirsi */
body[data-world="ninja"] .btn:active{transform:translateY(2px);box-shadow:none}
body[data-world="ninja"] .btn:disabled{box-shadow:none;transform:none}

/* Testo INCHIOSTRO sull'arancione, non bianco: il bianco su questo arancione
   tiene 2.6:1 ed è illeggibile. Ed è anche più fedele — nell'anime ogni
   campitura porta il suo tratto scuro, non una scritta bianca. */
body[data-world="ninja"] .btn.affordable{
  background:var(--accent);border-color:color-mix(in srgb, var(--accent) 55%, var(--ink));
  color:#1c1200;box-shadow:0 2px 0 color-mix(in srgb, var(--accent) 50%, var(--ink));
}
body[data-world="ninja"] .btn.affordable .cost{color:rgba(28,18,0,.72)}
/* i traguardi si pagano in Gemme: blocco d'oro VIVO, inchiostro sopra */
body[data-world="ninja"] .btn.star.affordable,
body[data-world="ninja"] .btn.ascend.affordable,
body[data-world="ninja"] .btn.claim,
body[data-world="ninja"] .btn.coll-buy.affordable{
  background:var(--gold-fill);border-color:color-mix(in srgb, var(--gold-fill) 50%, var(--ink));
  color:#1c1503;box-shadow:0 2px 0 color-mix(in srgb, var(--gold-fill) 45%, var(--ink));
}
body[data-world="ninja"] .btn.star.affordable .cost,
body[data-world="ninja"] .btn.ascend.affordable .cost,
body[data-world="ninja"] .btn.claim .cost,
body[data-world="ninja"] .btn.coll-buy.affordable .cost{color:rgba(28,21,3,.75)}

/* un legame pronto è un sigillo di carta: bordo pieno, nessun alone */
body[data-world="ninja"] .fus.ready,
body[data-world="ninja"] .camp.ready{
  border-style:solid;border-color:var(--gold-fill);
  box-shadow:0 3px 0 color-mix(in srgb, var(--gold-fill) 55%, var(--ink));
}

/* i pallini e i sigilli smettono di brillare: su carta un glow è una sbavatura */
body[data-world="ninja"] .wi .dot,
body[data-world="ninja"] .faction-h .seal,
body[data-world="ninja"] .sbtn.alert::after,
body[data-world="ninja"] .stat.cur .sym,
body[data-world="ninja"] .stat.gem .sym,
body[data-world="ninja"] .rankstars{box-shadow:none;filter:none}
/* il pallino "c'è un premio" dev'essere il colore vivo, non l'oro da testo */
body[data-world="ninja"] .sbtn.alert::after{background:var(--gold-fill)}
/* le stelline restano oro: si comprano con le Gemme. Il cimelio in vetrina e il
   traguardo conquistato NO — quelli sono fatti, e il fatto è verde. */
body[data-world="ninja"] .rankstars{color:var(--gold-fill)}

/* la barra e il dock poggiano sulla carta, non ci galleggiano sopra */
body[data-world="ninja"] .hud,
body[data-world="ninja"] .sectionbar{
  border-width:2px;border-color:color-mix(in srgb, var(--ink) 18%, transparent);
  background:color-mix(in srgb, var(--panel) 92%, transparent);
}
/* la sezione aperta è un blocco, non una velatura */
body[data-world="ninja"] .sbtn.active{
  border-color:var(--accent);
  background:color-mix(in srgb, var(--accent) 16%, var(--panel));
}

/* IL TWIST — il contratto di evocazione non firmato. Chi non è ancora nel
   roster è una pergamena in attesa: ritratto in seppia (inchiostro slavato)
   e HANKO rosso — il sigillo quadrato col kanji 忍 — stampato di traverso.
   Reclutare è firmare il contratto.
   Come sempre, il filtro non sta su .hero (scolorirebbe anche il nome):
   va sull'immagine, e il gradiente segnaposto si slava a mano. */
body[data-world="ninja"] .card.locked{opacity:.92;filter:saturate(1)}
body[data-world="ninja"] .card.locked .hero{
  filter:none;
  background:linear-gradient(150deg, #cfc4a8, #a89a78);   /* carta invecchiata */
}
body[data-world="ninja"] .card.locked .hero .hart{
  filter:sepia(.55) saturate(.5) contrast(.95) brightness(.9);
}
body[data-world="ninja"] .card.locked::after{
  content:"封";
  position:absolute;top:10px;right:10px;z-index:3;
  width:30px;height:30px;display:grid;place-items:center;
  font-family:var(--font-display);font-weight:900;font-size:19px;color:#fff;
  background:#c8342a;border-radius:4px;
  box-shadow:0 2px 0 rgba(22,24,29,.2);
  transform:rotate(6deg);
  pointer-events:none;
}

/* le barre si riempiono di CHAKRA: azzurro, il colore canonico, che sulla
   carta chiara spicca. Al livello massimo restano verde Foglia (done-fill):
   il chakra scorre, il compiuto mette radici. */
body[data-world="ninja"] .camp .fill,
body[data-world="ninja"] .ubar .fill,
body[data-world="ninja"] .fbar .fill{
  background:linear-gradient(90deg, #2f86c9, #57b0e8);
  box-shadow:0 0 8px rgba(47,134,201,.3);
}
body[data-world="ninja"] .camp.locked .fill{background:var(--faint);box-shadow:none}

/* la firma: la spirale Uzumaki in filigrana dietro le intestazioni di
   sezione — stava sull'HUD, torna al posto giusto */
body[data-world="ninja"] .sec-h{position:relative}
body[data-world="ninja"] .sec-h::before{
  content:"";position:absolute;left:-14px;top:50%;width:56px;height:56px;
  transform:translateY(-50%);pointer-events:none;opacity:.16;
  background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M50 50 m0 -5 a5 5 0 1 1 -10 0 a10 10 0 1 1 20 0 a15 15 0 1 1 -30 0 a20 20 0 1 1 40 0 a25 25 0 1 1 -50 0 a30 30 0 1 1 60 0' fill='none' stroke='%23e06f00' stroke-width='6' stroke-linecap='round'/%3E%3C/svg%3E") center/contain no-repeat;
}

/* il sigillo della fazione è una PENNELLATA a china: la maschera ritaglia la
   sagoma del tratto, il colore resta quello del villaggio (--fc) */
body[data-world="ninja"] .faction-h .seal{
  width:26px;height:14px;border-radius:0;
  background:var(--fc);
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 50'%3E%3Cpath d='M3 30 C20 18 45 14 97 20 C99 21 99 25 96 26 C60 34 30 40 6 36 C1 35 0 33 3 30 Z' fill='%23000'/%3E%3C/svg%3E") center/contain no-repeat;
          mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 50'%3E%3Cpath d='M3 30 C20 18 45 14 97 20 C99 21 99 25 96 26 C60 34 30 40 6 36 C1 35 0 33 3 30 Z' fill='%23000'/%3E%3C/svg%3E") center/contain no-repeat;
}

/* =====================================================================
   MONDO SPY×FAMILY — quello che le variabili non sanno dire.

   Tela VERDE VIVO del logo, card bianche sopra. I token in sxf.js sono tarati
   per le card (testo scuro su bianco); qui succedono le due cose che un fondo
   scuro con card chiare impone e che una palette da sola non può dare:

     1. la TELA — il body è l'unico punto che usa --bg/--bg-2 come fondo, e va
        ridipinto di verde vivo (i token restano chiari per le card);
     2. il TESTO SUL VERDE — le poche scritte che vivono direttamente sulla tela
        (intestazioni di sezione e fazione, contatori) vanno schiarite, o
        sparirebbero sul verde.
   Più la firma: la striscia verde→rosa del logo sotto l'header.
   ===================================================================== */
/* 1. la tela: verde vivo con un alone rosa (Anya) e uno chiaro, appena percettibili */
body[data-world="sxf"]{
  background:
    radial-gradient(1100px 620px at 84% -14%, color-mix(in srgb, var(--accent-2) 22%, transparent), transparent 60%),
    radial-gradient(820px 520px at -10% 6%, rgba(255,255,255,.14), transparent 58%),
    linear-gradient(180deg, #34935e, #2a8351 62%);
  background-attachment:fixed;
}
/* 2. il testo che vive sul verde: chiaro. Le card, che stanno su bianco, tengono
      il loro inchiostro scuro dai token. */
body[data-world="sxf"] .sec-h h3{color:#f6fbf8}
body[data-world="sxf"] .sec-h .cnt,
body[data-world="sxf"] .fac .facnt,
body[data-world="sxf"] .fac .chev{color:#d4ecdd}
body[data-world="sxf"] .fac .facnt.full{color:#bfeccb}
body[data-world="sxf"] .sec-h .ln{background:linear-gradient(90deg, rgba(255,255,255,.4), transparent)}

/* la firma: la striscia del titolo, verde→rosa, sul bordo basso dell'HUD */
body[data-world="sxf"] .hud{
  position:relative;
  border-color:color-mix(in srgb,var(--accent) 24%, var(--line-2));
  padding-bottom:12px;
}
body[data-world="sxf"] .hud::after{
  content:"";position:absolute;left:0;right:0;bottom:0;height:3px;z-index:2;
  background:linear-gradient(90deg,
    var(--accent) 0%,
    color-mix(in srgb, var(--accent) 50%, var(--accent-2)) 58%,
    var(--accent-2) 100%);
}
/* card e pannelli bianchi sul verde: un bordo scuro appena marcato li stacca */
body[data-world="sxf"] .card,
body[data-world="sxf"] .up,
body[data-world="sxf"] .coll,
body[data-world="sxf"] .fus,
body[data-world="sxf"] .camp,
body[data-world="sxf"] .ach,
body[data-world="sxf"] .locked-panel{
  border-color:color-mix(in srgb, var(--ink) 12%, transparent);
}
/* il seme della fazione e il pallino "premio" non hanno bisogno di alone */
body[data-world="sxf"] .faction-h .seal,
body[data-world="sxf"] .wi .dot{box-shadow:none}

/* IL TWIST — il dossier di WISE. Chi non è ancora reclutato è un fascicolo
   riservato: foto "fotocopiata" (contrasto alzato) e timbro CLASSIFICATO di
   traverso. Reclutare declassifica il dossier.

   Il timbro sta sulla CARD, non sul ritratto: `.card.locked .hero` porta un
   filter grayscale che scolorirebbe anche lo pseudo-elemento (i filtri valgono
   per i discendenti), e un timbro grigio non timbra niente. `margin-top` in
   percentuale si misura sulla LARGHEZZA, e il ritratto è alto 3/5 della
   larghezza: 26% lo pianta al centro della foto su ogni taglia di card. */
body[data-world="sxf"] .card.locked .hero{filter:grayscale(1) contrast(1.18) brightness(.88)}
body[data-world="sxf"] .card.locked::after{
  content:"CLASSIFICATO";
  position:absolute;left:50%;top:0;margin-top:26%;z-index:3;
  transform:translateX(-50%) rotate(-10deg);
  font-family:var(--font-num);font-size:13px;font-weight:700;letter-spacing:3px;
  color:rgba(161,45,61,.92);
  border:2px solid rgba(161,45,61,.8);border-radius:4px;
  outline:1px solid rgba(161,45,61,.4);outline-offset:2px;
  padding:3px 10px 2px;white-space:nowrap;
  pointer-events:none;
}

/* la firma: la NOCCIOLINA di Anya in filigrana bianca dietro le intestazioni —
   il cibo preferito della telepate, che è anche la valuta del mondo */
body[data-world="sxf"] .sec-h{position:relative}
body[data-world="sxf"] .sec-h::before{
  content:"";position:absolute;left:-10px;top:50%;width:34px;height:52px;
  transform:translateY(-50%) rotate(-18deg);pointer-events:none;opacity:.32;
  background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 60 100'%3E%3Cpath d='M30 2 C44 2 52 12 50 24 C49 32 44 36 44 42 C44 48 52 54 52 66 C52 84 42 96 30 96 C18 96 8 84 8 66 C8 54 16 48 16 42 C16 36 11 32 10 24 C8 12 16 2 30 2 Z' fill='%23ffffff'/%3E%3C/svg%3E") center/contain no-repeat;
}
/* il sigillo di fazione è una cartellina d'archivio, del colore della fazione */
body[data-world="sxf"] .faction-h .seal{
  width:18px;height:14px;border-radius:0;
  background:var(--fc);
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 36 28'%3E%3Cpath d='M2 4 h12 l4 5 h16 v17 a2 2 0 0 1 -2 2 h-28 a2 2 0 0 1 -2 -2 z' fill='%23000'/%3E%3C/svg%3E") center/contain no-repeat;
          mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 36 28'%3E%3Cpath d='M2 4 h12 l4 5 h16 v17 a2 2 0 0 1 -2 2 h-28 a2 2 0 0 1 -2 -2 z' fill='%23000'/%3E%3C/svg%3E") center/contain no-repeat;
}

/* =====================================================================
   MONDO DEATH NOTE — quello che le variabili non sanno dire.

   Copertina nera, pagine bianche, un solo colore vivo: il rosso. I token in
   dn.js sono tarati per le pagine (inchiostro su bianco); qui le tre cose che
   una palette da sola non può dare:
     1. la TELA — il body dipinto di nero puro, con un alone rosso in alto
        (le righe del quaderno le porta già --texture);
     2. il TESTO SUL NERO — intestazioni e contatori che vivono sulla tela;
     3. il LETTERING — il blackletter della copertina sui titoli di sezione,
        sul titolo del gioco e sui nomi delle card: ogni personaggio è un nome
        scritto sul quaderno.
   ===================================================================== */
body[data-world="dn"]{
  background:
    radial-gradient(900px 520px at 82% -12%, rgba(185,28,38,.28), transparent 62%),
    linear-gradient(180deg, #0a0a0a, #000 46%);
  background-attachment:fixed;
}
/* 2. il testo sulla copertina */
body[data-world="dn"] .sec-h .cnt,
body[data-world="dn"] .fac .facnt,
body[data-world="dn"] .fac .chev{color:#bdbdbd}
body[data-world="dn"] .fac .facnt.full{color:#e44f5c}
body[data-world="dn"] .sec-h .ln{background:linear-gradient(90deg, rgba(255,255,255,.38), transparent)}

/* 3. il lettering del quaderno. I titoli di sezione perdono il maiuscolo:
   il blackletter tutto maiuscolo è illeggibile per costruzione. */
body[data-world="dn"] .sec-h h3{
  font-family:'UnifrakturMaguntia', var(--font-display);
  font-weight:400;text-transform:none;letter-spacing:.5px;
  font-size:19px;color:#f5f5f5;
}
body[data-world="dn"] .hero .nm{
  font-family:'UnifrakturMaguntia', var(--font-display);
  font-weight:400;font-size:17px;letter-spacing:.5px;
}
body[data-world="dn"] .brand .bt{font-family:'UnifrakturMaguntia', var(--font-display);font-weight:400}

/* IL TWIST — chi non è ancora reclutato è un nome SCRITTO SUL QUADERNO:
   grafia gotica ROSSA su un ritratto che affonda nel buio. Reclutarlo è
   riprendersi il nome dalla pagina (il nome torna bianco).
   La card intera resta quasi piena: il segnale "manca" non è più il velo
   d'opacità globale ma il nome rosso sul ritratto spento.

   Il filtro NON sta su .hero: un filtro ingrigisce anche i discendenti, nome
   compreso. Va sui soli strati visivi — l'immagine del ritratto, e il
   gradiente del segnaposto che qui si spegne a mano. */
body[data-world="dn"] .card.locked{opacity:.85;filter:saturate(1)}
body[data-world="dn"] .card.locked .hero{
  filter:none;
  background:linear-gradient(150deg,#4a4a4a,#1c1c1c);
}
body[data-world="dn"] .card.locked .hero .hart{filter:grayscale(1) brightness(.45) contrast(1.06)}
body[data-world="dn"] .card.locked .nm{color:#d9505d;text-shadow:0 1px 8px rgba(0,0,0,.9)}

/* la firma: l'occhio dello shinigami in filigrana rossa dietro le
   intestazioni — il prezzo che si paga per vedere i nomi */
body[data-world="dn"] .sec-h{position:relative}
body[data-world="dn"] .sec-h::before{
  content:"";position:absolute;left:-12px;top:50%;width:62px;height:40px;
  transform:translateY(-50%);pointer-events:none;opacity:.3;
  background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 60'%3E%3Cg fill='none' stroke='%23b91c26' stroke-width='3'%3E%3Cpath d='M4 30 Q50 -6 96 30 Q50 66 4 30 Z'/%3E%3Ccircle cx='50' cy='30' r='14'/%3E%3Ccircle cx='50' cy='30' r='5' fill='%23b91c26' stroke='none'/%3E%3C/g%3E%3C/svg%3E") center/contain no-repeat;
}
/* il sigillo di fazione è la mela dello shinigami, del colore della fazione
   (in scala di grigi, tranne quella di Kira: rossa) */
body[data-world="dn"] .faction-h .seal{
  width:14px;height:16px;border-radius:0;box-shadow:none;
  background:var(--fc);
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 40 48'%3E%3Cpath d='M20 12 C10 4 1 10 1 22 C1 35 10 47 20 45 C30 47 39 35 39 22 C39 10 30 4 20 12 Z' fill='%23000'/%3E%3Cpath d='M21 10 C21 4 25 1 30 1 C30 7 26 10 21 10 Z' fill='%23000'/%3E%3C/svg%3E") center/contain no-repeat;
          mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 40 48'%3E%3Cpath d='M20 12 C10 4 1 10 1 22 C1 35 10 47 20 45 C30 47 39 35 39 22 C39 10 30 4 20 12 Z' fill='%23000'/%3E%3Cpath d='M21 10 C21 4 25 1 30 1 C30 7 26 10 21 10 Z' fill='%23000'/%3E%3C/svg%3E") center/contain no-repeat;
}

/* Pagine su copertina: OGNI card è un foglio bianco PIENO, non un velo.
   `background:` (non background-image) perché il gradiente di default è solo
   un'immagine: toglierlo lasciava le card trasparenti sul nero, e solo quelle
   con uno stato "fatto" (che portano un colore proprio) restavano leggibili. */
body[data-world="dn"] .card,
body[data-world="dn"] .up,
body[data-world="dn"] .coll,
body[data-world="dn"] .fus,
body[data-world="dn"] .camp,
body[data-world="dn"] .ach,
body[data-world="dn"] .locked-panel{
  border-width:2px;border-color:rgba(0,0,0,.55);
  background:var(--panel);
}
/* Le velature d'accento diventano GRIGIE: il rosso al 18% su bianco è un rosa
   pallido che con Death Note non c'entra. Il rosso resta dov'è testo puro
   (costi, contatori, ✓): grigio sotto, rosso sopra. */
/* spento: un blocco di carta grigia, chiaramente inerte */
body[data-world="dn"] .btn{background:#e7e7e4;border-color:rgba(0,0,0,.3)}
/* pagabile ADESSO: il bottone si accende — foglio bianco, bordo rosso netto
   (l'inset raddoppia il bordo senza spostare il layout). Niente classe fissa
   su .recruit: anche Recluta resta grigio finché gli Indizi non bastano. */
body[data-world="dn"] .btn.affordable{
  background:#fff;border-color:var(--accent);
  box-shadow:inset 0 0 0 1px var(--accent);
}

/* Due monete, due bottoni. Gli INDIZI comprano su carta: grigio, prezzo rosso
   (le regole qui sopra). Le GEMME comprano sul quaderno: il bottone pronto è
   NERO PIENO con le scritte d'oro — la copertina col suo lettering. Vale per
   stelle, evoluzioni, riscossioni della Cronaca e sblocco del mondo. */
body[data-world="dn"] .btn.star.affordable,
body[data-world="dn"] .btn.ascend.affordable,
body[data-world="dn"] .btn.claim,
body[data-world="dn"] .unlockbtn:not(:disabled){
  background:#0d0d0d;border-color:#0d0d0d;color:var(--gold-fill);
}
body[data-world="dn"] .btn.star.affordable .cost,
body[data-world="dn"] .btn.ascend.affordable .cost,
body[data-world="dn"] .btn.claim .cost{color:var(--gold-fill)}
body[data-world="dn"] .btn.star.affordable:hover,
body[data-world="dn"] .btn.ascend.affordable:hover,
body[data-world="dn"] .btn.claim:hover{filter:none;border-color:var(--gold-fill)}
/* i cimeli si comprano in Indizi: prezzo in rosso, non in oro */
body[data-world="dn"] .btn.coll-buy.affordable .cost{color:var(--accent)}
body[data-world="dn"] .prod .pmul{background:#efefec;border-color:rgba(0,0,0,.28)}
body[data-world="dn"] .sbtn.active{background:#e6e6e2;border-color:rgba(0,0,0,.5)}
body[data-world="dn"] .stat.cur{border-color:rgba(0,0,0,.45)}
body[data-world="dn"] .card:hover{border-color:var(--accent)}
/* la barra in alto e il dock in basso: strisce di carta piena sul nero */
body[data-world="dn"] .hud,
body[data-world="dn"] .sectionbar{
  background:rgba(255,255,255,.94);
  border-color:rgba(0,0,0,.4);
}

/* =====================================================================
   MONDO OSHI NO KO — quello che le variabili non sanno dire.

   Il buio della sala da concerto (la palette sta in onk.js). Qui i quattro
   twist da palco:
     1. il BOKEH — luci sfocate rosa/aqua/bianche che galleggiano in platea;
     2. le STELLE — sigilli delle fazioni e pallini del menu a forma di
        stella: in quest'opera la stella è l'anima, non un ornamento;
     3. le PENLIGHT — le barre di avanzamento brillano come glowstick;
     4. il DEBUTTO — chi non è reclutato è un teaser a palco spento; il
        riflettore (hover) e il reclutamento lo accendono.
   ===================================================================== */
/* 1. il bokeh: cerchi di luce fuori fuoco sopra il buio */
body[data-world="onk"]{
  background:
    radial-gradient(150px 150px at 15% 18%, rgba(240,86,142,.14), transparent 70%),
    radial-gradient(190px 190px at 79% 10%, rgba(88,199,232,.12), transparent 70%),
    radial-gradient(120px 120px at 58% 34%, rgba(255,255,255,.06), transparent 70%),
    radial-gradient(170px 170px at 28% 72%, rgba(240,86,142,.09), transparent 70%),
    radial-gradient(210px 210px at 88% 62%, rgba(88,199,232,.08), transparent 70%),
    radial-gradient(110px 110px at 45% 90%, rgba(255,255,255,.05), transparent 70%),
    linear-gradient(180deg, #161129, #0d0a1a 52%);
  background-attachment:fixed;
}

/* 2. le stelle: SEI punte sottili e allungate, come l'hoshigan negli occhi —
   uno sparkle, non un esagramma (il raggio interno è 0.2R: più è stretto,
   più le punte diventano aghi). Il clip-path taglia anche le ombre in
   scatola, quindi il bagliore va dato con drop-shadow, che si applica DOPO
   il ritaglio */
body[data-world="onk"] .faction-h .seal{
  width:17px;height:17px;border-radius:0;box-shadow:none;
  clip-path:polygon(50% 0%, 55% 41.3%, 93.3% 25%, 60% 50%, 93.3% 75%, 55% 58.7%, 50% 100%, 45% 58.7%, 6.7% 75%, 40% 50%, 6.7% 25%, 45% 41.3%);
  filter:drop-shadow(0 0 6px var(--fc));
}
body[data-world="onk"] .wi .dot{
  width:13px;height:13px;border-radius:0;box-shadow:none;
  clip-path:polygon(50% 0%, 55% 41.3%, 93.3% 25%, 60% 50%, 93.3% 75%, 55% 58.7%, 50% 100%, 45% 58.7%, 6.7% 75%, 40% 50%, 6.7% 25%, 45% 41.3%);
  filter:drop-shadow(0 0 6px var(--tab-c, var(--accent)));
}

/* 3. le penlight: le barre brillano del loro colore */
body[data-world="onk"] .camp .fill,
body[data-world="onk"] .ubar .fill,
body[data-world="onk"] .fbar .fill,
body[data-world="onk"] .ach .fill{
  box-shadow:0 0 9px color-mix(in srgb, var(--accent) 60%, transparent),
             0 0 3px color-mix(in srgb, var(--accent) 80%, transparent);
}
body[data-world="onk"] .up.maxed .ubar .fill,
body[data-world="onk"] .ach.done .fill{
  box-shadow:0 0 9px color-mix(in srgb, var(--done-fill) 60%, transparent);
}
body[data-world="onk"] .camp.locked .fill{box-shadow:none}

/* le stelle di grado brillano di luce bianca, non del vecchio alone dorato */
body[data-world="onk"] .rankstars{filter:drop-shadow(0 0 5px rgba(255,255,255,.55))}
/* il titolo dell'evoluzione è di Aqua: il nome resta bianco, il ruolo aqua */
body[data-world="onk"] .hero .ttl{color:var(--accent-2)}

/* 4a. il riflettore: un cono di luce dall'alto quando la card è sotto il mouse */
body[data-world="onk"] .card::before{
  content:"";position:absolute;inset:0;z-index:1;pointer-events:none;opacity:0;
  background:radial-gradient(120% 90% at 50% -20%, rgba(255,255,255,.15), transparent 55%);
  transition:opacity .25s;
}
body[data-world="onk"] .card:hover::before{opacity:1}

/* 4b. IL TWIST — il debutto. Chi non è reclutato è il teaser di un annuncio:
   il palco è spento e la figura si intuisce appena nel buio (coi ritratti
   segnaposto, l'iniziale è la sagoma). Reclutare accende le luci.
   Come in DN, il filtro non sta su .hero — ingrigirebbe anche il nome. */
body[data-world="onk"] .card.locked{opacity:.9;filter:saturate(1)}
body[data-world="onk"] .card.locked .hero{
  filter:none;
  background:linear-gradient(180deg, #241d40, #120e24);
}
body[data-world="onk"] .card.locked .hero .hart{filter:grayscale(.7) brightness(.28)}
body[data-world="onk"] .card.locked .hero .hinit{color:rgba(0,0,0,.72);text-shadow:none}
body[data-world="onk"] .card.locked .nm{color:rgba(241,236,250,.85)}
body[data-world="onk"] .card.locked .role{color:rgba(241,236,250,.45)}

/* la firma: lo sparkle dei gemelli in filigrana dietro le intestazioni —
   l'hoshigan grande rosa (Ruby) e quello piccolo aqua (Aqua), la stessa
   stella a sei punte sottili dei sigilli */
body[data-world="onk"] .sec-h{position:relative}
body[data-world="onk"] .sec-h::before{
  content:"";position:absolute;left:-12px;top:50%;width:58px;height:58px;
  transform:translateY(-50%);pointer-events:none;opacity:.38;
  background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M50 0 L55 41.3 L93.3 25 L60 50 L93.3 75 L55 58.7 L50 100 L45 58.7 L6.7 75 L40 50 L6.7 25 L45 41.3 Z' fill='%23f0568e'/%3E%3Cpath d='M50 0 L55 41.3 L93.3 25 L60 50 L93.3 75 L55 58.7 L50 100 L45 58.7 L6.7 75 L40 50 L6.7 25 L45 41.3 Z' transform='translate(63 -2) scale(.34)' fill='%2358c7e8'/%3E%3C/svg%3E") center/contain no-repeat;
}

/* =====================================================================
   MONDO CHAINSAW MAN — quello che le variabili non sanno dire.

   Nero e arancio, ruvido e strappato (la palette sta in csm.js). Qui:
     1. la TELA — catrame con due lame di luce, arancio e sangue;
     2. i DENTI DI SEGA — il bordo alto di ogni card è tagliato a denti,
        e gli angoli tondi spariscono: la motosega è passata di lì;
     3. il CANTIERE — il bottone pagabile è un blocco arancio PIENO con
        l'inchiostro nero sopra e una striscia di pericolo sul fondo.
   ===================================================================== */
body[data-world="csm"]{
  background:
    radial-gradient(620px 380px at 88% -8%, rgba(255, 0, 0, 0.28), transparent 62%),
    radial-gradient(900px 560px at -10% 16%, rgba(204, 36, 24, 0.575), transparent 62%),
    linear-gradient(180deg, #16100a, #0e0a08 56%);
  background-attachment:fixed;
}

/* 2. i denti di sega: DIECI punte alte 14px e sottili (~4% di base), separate
   da tratti piatti — i denti radi di una motosega vera, non uno zigzag
   continuo. Il clip-path sostituisce la sagoma (addio angoli tondi) e taglia
   anche le ombre: per un mondo ruvido è il prezzo giusto. */
body[data-world="csm"] .card,
body[data-world="csm"] .up,
body[data-world="csm"] .coll,
body[data-world="csm"] .fus{
  border-radius:0;
  clip-path:polygon(0% 14px, 3.5% 14px, 5% 0%, 6.5% 14px, 13.5% 14px, 15% 0%, 16.5% 14px, 23.5% 14px, 25% 0%, 26.5% 14px, 33.5% 14px, 35% 0%, 36.5% 14px, 43.5% 14px, 45% 0%, 46.5% 14px, 53.5% 14px, 55% 0%, 56.5% 14px, 63.5% 14px, 65% 0%, 66.5% 14px, 73.5% 14px, 75% 0%, 76.5% 14px, 83.5% 14px, 85% 0%, 86.5% 14px, 93.5% 14px, 95% 0%, 96.5% 14px, 100% 14px, 100% 100%, 0% 100%);
}
body[data-world="csm"] .hero{border-radius:0}

/* 3. il cantiere: chi si paga in Yen è un blocco arancio pieno, inchiostro
   nero sopra, striscia di pericolo sul fondo */
body[data-world="csm"] .btn.affordable{
  color:#140a02;
  border-color:#000;
  background:
    repeating-linear-gradient(-45deg, rgba(0,0,0,.8) 0 7px, transparent 7px 14px) left bottom/100% 5px no-repeat,
    var(--accent);
}
body[data-world="csm"] .btn.affordable .cost{color:rgba(20,10,2,.78)}
/* le Gemme restano oro: la spesa rara non veste da cantiere */
body[data-world="csm"] .btn.star.affordable,
body[data-world="csm"] .btn.ascend.affordable{
  color:var(--ink);
  background:linear-gradient(180deg, color-mix(in srgb, var(--gold) 30%, var(--panel-2)), var(--panel-2));
  border-color:color-mix(in srgb, var(--gold) 70%, var(--line-2));
}
body[data-world="csm"] .btn.star.affordable .cost,
body[data-world="csm"] .btn.ascend.affordable .cost{color:var(--gold)}

/* la firma: POCHITA in filigrana dietro le intestazioni — la sagoma arancio
   del cane-motosega sul catrame: corpo tondo, orecchie, lama dentata sul
   muso, l'anello del cordino per coda */
body[data-world="csm"] .sec-h{position:relative}
body[data-world="csm"] .sec-h::before{
  content:"";position:absolute;left:-14px;top:50%;width:66px;height:50px;
  transform:translateY(-50%);pointer-events:none;opacity:.22;
  background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 90'%3E%3Cg fill='%23f2600f'%3E%3Cellipse cx='70' cy='52' rx='30' ry='27'/%3E%3Cpath d='M52 20 L60 36 L44 38 Z'/%3E%3Cpath d='M84 18 L90 34 L74 34 Z'/%3E%3Cpath d='M6 44 a9 9 0 0 0 0 18 L44 62 L44 44 Z'/%3E%3Cpath d='M10 44 l6 -7 5 7 Z m14 0 l6 -7 5 7 Z m14 0 l6 -7 5 7 Z'/%3E%3Crect x='58' y='76' width='8' height='10' rx='4'/%3E%3Crect x='82' y='76' width='8' height='10' rx='4'/%3E%3C/g%3E%3Ccircle cx='104' cy='34' r='5' fill='none' stroke='%23f2600f' stroke-width='4'/%3E%3C/svg%3E") center/contain no-repeat;
}
/* il sigillo di fazione è una goccia di sangue, del colore della fazione */
body[data-world="csm"] .faction-h .seal{
  width:12px;height:16px;border-radius:0;box-shadow:none;
  background:var(--fc);
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 40 52'%3E%3Cpath d='M20 2 C20 2 36 26 36 36 A16 16 0 0 1 4 36 C4 26 20 2 20 2 Z' fill='%23000'/%3E%3C/svg%3E") center/contain no-repeat;
          mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 40 52'%3E%3Cpath d='M20 2 C20 2 36 26 36 36 A16 16 0 0 1 4 36 C4 26 20 2 20 2 Z' fill='%23000'/%3E%3C/svg%3E") center/contain no-repeat;
}

/* =====================================================================
   MONDO FRIEREN — quello che le variabili non sanno dire.

   Il grimorio (la palette — mattino lattiginoso, salvia, oro — sta in
   frieren.js). Qui i tre segni del libro:
     1. il SERIF ANTICO — IM Fell English sui titoli di sezione, sui nomi
        dei capitoli della Cronaca e sui titoli dei Ricordi: le pagine
        scritte del grimorio;
     2. il CERCHIO MAGICO — una filigrana dorata dietro ogni intestazione
        di sezione, come il sigillo inciso a inizio capitolo;
     3. le CORNICI DOPPIE — luoghi, cimeli, legami e cronaca incorniciati
        come tavole d'erbario: bordo esterno più un filetto interno.
   ===================================================================== */
/* 1. il serif antico. I titoli perdono il maiuscolo: un canone antico si
   legge nelle minuscole, e il maiuscoletto forzato lo sciupa. */
body[data-world="frieren"] .sec-h h3{
  font-family:'IM Fell English', var(--font-display);
  font-weight:400;text-transform:none;letter-spacing:.4px;font-size:19px;
}
body[data-world="frieren"] .brand .bt{font-family:'IM Fell English', var(--font-display);font-weight:400}
body[data-world="frieren"] .camp .cn,
body[data-world="frieren"] .memn{font-family:'IM Fell English', var(--font-display);font-weight:400;font-size:16px}

/* 2. il cerchio magico: un sigillo dorato in filigrana dietro l'intestazione.
   È un piccolo SVG inline (due cerchi, l'esagramma, il centro): una forma
   così non si disegna coi soli gradienti. */
body[data-world="frieren"] .sec-h{position:relative}
body[data-world="frieren"] .sec-h::before{
  content:"";position:absolute;left:-16px;top:50%;width:62px;height:62px;
  transform:translateY(-50%);pointer-events:none;opacity:.4;
  background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cg fill='none' stroke='%23c9a23c' stroke-width='1.6'%3E%3Ccircle cx='50' cy='50' r='46'/%3E%3Ccircle cx='50' cy='50' r='33'/%3E%3Cpolygon points='50,17 78.6,66.5 21.4,66.5'/%3E%3Cpolygon points='50,83 21.4,33.5 78.6,33.5'/%3E%3Ccircle cx='50' cy='50' r='7'/%3E%3C/g%3E%3C/svg%3E") center/contain no-repeat;
}

/* 3. le cornici doppie da erbario: bordo esterno + filetto interno dorato.
   Solo sulle card con padding pieno — sulla card personaggio il ritratto
   arriva ai bordi e coprirebbe il filetto in alto. */
body[data-world="frieren"] .up,
body[data-world="frieren"] .coll,
body[data-world="frieren"] .fus,
body[data-world="frieren"] .camp,
body[data-world="frieren"] .ach{
  box-shadow:var(--edge),
    inset 0 0 0 3px var(--panel),
    inset 0 0 0 4px color-mix(in srgb, var(--accent-2) 50%, var(--line));
}

/* 4. la magia è CELESTE (lo Zoltraak, il mana — i token done/good stanno nel
   tema): le barre di avanzamento si riempiono di mana, con un velo di luce */
body[data-world="frieren"] .camp .fill,
body[data-world="frieren"] .ubar .fill,
body[data-world="frieren"] .fbar .fill,
body[data-world="frieren"] .ach .fill{
  background:linear-gradient(90deg, #4aa8cf, #7cc4de);
  box-shadow:0 0 8px rgba(74,168,207,.35);
}
body[data-world="frieren"] .camp.locked .fill{background:var(--faint);box-shadow:none}

/* il sigillo di fazione è una piccola runa: un rombo che brilla appena */
body[data-world="frieren"] .faction-h .seal{
  width:11px;height:11px;border-radius:2px;transform:rotate(45deg);
  box-shadow:0 0 8px color-mix(in srgb, var(--fc) 50%, transparent);
}

/* il contatore del Mana nell'HUD ha il suo alone celeste */
body[data-world="frieren"] .stat.cur{border-color:color-mix(in srgb, #4aa8cf 45%, var(--line-2))}
body[data-world="frieren"] .stat.cur .sym{filter:drop-shadow(0 0 7px rgba(74,168,207,.7))}

/* =====================================================================
   MONDO DEMON SLAYER — quello che le variabili non sanno dire.

   La notte dell'era Taishō (la palette sta in ds.js). Qui i segni:
     1. la TELA — notte blu-verde con la luna e un alone di sangue;
     2. la FILIGRANA — l'orecchino hanafuda di Tanjiro dietro le
        intestazioni: la carta col sole nascente;
     3. i SIGILLI — il motivo ichimatsu (la scacchiera del kimono) come
        seme delle fazioni, nel loro colore;
     4. IL TWIST — chi non è reclutato è ancora AVVOLTO NELLA NOTTE: il
        ritratto affonda nel buio dietro il velo a scacchi del kimono.
        Reclutare è tirarlo fuori dalla notte.
   ===================================================================== */
body[data-world="ds"]{
  background:
    radial-gradient(280px 280px at 82% 6%, rgba(238,242,238,.10), transparent 70%),
    radial-gradient(900px 560px at -10% 12%, rgba(224,72,60,.16), transparent 60%),
    linear-gradient(180deg, #101a1c, #0b1013 52%);
  background-attachment:fixed;
}

/* 2. l'orecchino hanafuda, coi colori veri: cartiglio BIANCO avorio bordato
   di nero, il sole ROSSO in ALTO coi raggi che scendono, e la striscia
   CELESTE dell'orizzonte in basso. Sul buio della tela l'avorio fa da
   lanterna. */
body[data-world="ds"] .sec-h{position:relative}
body[data-world="ds"] .sec-h::before{
  content:"";position:absolute;left:-8px;top:50%;width:30px;height:52px;
  transform:translateY(-50%) rotate(-8deg);pointer-events:none;opacity:.32;
  background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 40 70'%3E%3Crect x='2' y='2' width='36' height='66' rx='4' fill='%23f4efe2' stroke='%23111111' stroke-width='3'/%3E%3Ccircle cx='20' cy='24' r='11' fill='%23cf3a2e'/%3E%3Cg stroke='%23cf3a2e' stroke-width='3' stroke-linecap='round'%3E%3Cpath d='M20 40 V50'/%3E%3Cpath d='M10 37 L5 47'/%3E%3Cpath d='M30 37 L35 47'/%3E%3C/g%3E%3Cpath d='M4 53 H36 V61 Q36 66 31 66 H9 Q4 66 4 61 Z' fill='%237fc0d8'/%3E%3C/svg%3E") center/contain no-repeat;
}

/* 3. il sigillo di fazione è l'ichimatsu: la scacchiera 2×2 del kimono, nel
   COLORE DELLA FAZIONE alternato al nero. Un conic-gradient a quadranti fa
   la scacchiera; il filetto chiaro tiene insieme la forma sulla tela scura. */
body[data-world="ds"] .faction-h .seal{
  width:14px;height:14px;border-radius:2px;box-shadow:none;
  background:conic-gradient(var(--fc) 0 90deg, #0a0d0d 90deg 180deg, var(--fc) 180deg 270deg, #0a0d0d 270deg);
  border:1px solid rgba(238,242,238,.28);
}

/* 4. IL TWIST — avvolti nella notte. Il ritratto affonda nel buio e sopra
   scende il velo a scacchi del kimono; il nome resta leggibile. Come sempre
   il filtro non sta su .hero (scolorirebbe anche il nome): va sull'immagine,
   e il gradiente segnaposto si spegne a mano. */
body[data-world="ds"] .card.locked{opacity:.9;filter:saturate(1)}
body[data-world="ds"] .card.locked .hero{
  filter:none;
  background:linear-gradient(180deg, #17262b, #0c1418);
}
body[data-world="ds"] .card.locked .hero .hart{filter:grayscale(.75) brightness(.35)}
body[data-world="ds"] .card.locked .hero::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:repeating-conic-gradient(rgba(8,14,12,.5) 0 90deg, transparent 0 180deg) 0 0/24px 24px;
}
body[data-world="ds"] .card.locked .hero .hinit{color:rgba(0,0,0,.7);text-shadow:none}
body[data-world="ds"] .card.locked .nm{position:relative;z-index:1;color:rgba(238,242,238,.88)}

/* =====================================================================
   MONDO ATTACK ON TITAN — quello che le variabili non sanno dire.

   La notte sopra le mura (la palette sta in aot.js). Qui i segni:
     1. la TELA — oliva militare con l'acciaio del cielo e il verde del
        mantello che salgono dai bordi;
     2. la FILIGRANA — le Ali della Libertà dietro le intestazioni: l'ala
        d'acciaio e l'ala bianca, incrociate;
     3. i SIGILLI — gli stemmi dei reggimenti sono scudi: il sigillo di
        fazione è uno scudo nel colore del corpo d'armata;
     4. IL TWIST — chi non è reclutato è MURATO: il ritratto sta dietro
        una parete di mattoni in ombra. Reclutare apre la breccia.
   ===================================================================== */
body[data-world="aot"]{
  background:
    radial-gradient(1000px 600px at 84% -10%, rgba(110,163,200,.16), transparent 62%),
    radial-gradient(800px 520px at -8% 14%, rgba(78,143,92,.14), transparent 60%),
    linear-gradient(180deg, #1b1d11, #15160e 52%);
  background-attachment:fixed;
}

/* 2. le Ali della Libertà: due ali incrociate, acciaio dietro e bianca davanti */
body[data-world="aot"] .sec-h{position:relative}
body[data-world="aot"] .sec-h::before{
  content:"";position:absolute;left:-14px;top:50%;width:64px;height:46px;
  transform:translateY(-50%);pointer-events:none;opacity:.34;
  background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 72'%3E%3Cpath d='M92 8 C70 10 50 20 38 34 C48 32 56 32 62 34 C50 40 40 48 34 58 C44 54 54 52 60 52 C52 58 46 64 42 70 C60 64 78 50 86 34 C90 24 92 14 92 8 Z' fill='%236ea3c8'/%3E%3Cpath d='M8 8 C30 10 50 20 62 34 C52 32 44 32 38 34 C50 40 60 48 66 58 C56 54 46 52 40 52 C48 58 54 64 58 70 C40 64 22 50 14 34 C10 24 8 14 8 8 Z' fill='%23e9e7da'/%3E%3C/svg%3E") center/contain no-repeat;
}

/* 3. il sigillo di fazione è uno scudo da reggimento, nel colore del corpo */
body[data-world="aot"] .faction-h .seal{
  width:13px;height:15px;border-radius:0;box-shadow:none;
  background:var(--fc);
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 40 48'%3E%3Cpath d='M20 2 L37 9 V22 C37 34 29 42 20 46 C11 42 3 34 3 22 V9 Z' fill='%23000'/%3E%3C/svg%3E") center/contain no-repeat;
          mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 40 48'%3E%3Cpath d='M20 2 L37 9 V22 C37 34 29 42 20 46 C11 42 3 34 3 22 V9 Z' fill='%23000'/%3E%3C/svg%3E") center/contain no-repeat;
}

/* 4. IL TWIST — murati. Il ritratto affonda nell'ombra dietro una parete di
   mattoni (due trame di giunti sopra una velatura di pietra); reclutare apre
   la breccia. Come sempre il filtro non sta su .hero: va sull'immagine, e il
   gradiente segnaposto si spegne a mano. */
body[data-world="aot"] .card.locked{opacity:.92;filter:saturate(1)}
body[data-world="aot"] .card.locked .hero{
  filter:none;
  background:linear-gradient(180deg, #2a2b20, #191a12);
}
body[data-world="aot"] .card.locked .hero .hart{filter:grayscale(.8) brightness(.4)}
body[data-world="aot"] .card.locked .hero::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:
    repeating-linear-gradient(0deg, rgba(10,10,6,.5) 0 2px, transparent 2px 14px),
    repeating-linear-gradient(90deg, rgba(10,10,6,.35) 0 2px, transparent 2px 26px),
    rgba(120,114,96,.22);
}
body[data-world="aot"] .card.locked .hero .hinit{color:rgba(0,0,0,.65);text-shadow:none}
body[data-world="aot"] .card.locked .nm{position:relative;z-index:1;color:rgba(240,239,228,.88)}

/* =====================================================================
   MONDO JUJUTSU KAISEN — quello che le variabili non sanno dire.

   Il buio del velo (la palette sta in jjk.js). Qui i segni:
     1. la TELA — blu-nero con il bagliore azzurro dell'Infinito e quello
        rosso delle maledizioni;
     2. la FILIGRANA — un torii vermiglio dietro le intestazioni: il
        santuario, e la soglia fra i due mondi;
     3. i SIGILLI — gli ofuda: il sigillo di fazione è un talismano di
        carta con la coda tagliata, nel colore della fazione;
     4. IL TWIST — chi non è reclutato sta DIETRO IL VELO: il ritratto è
        sfocato e oscurato dalla tenda che nasconde ai civili. Reclutare
        alza il velo.
   ===================================================================== */
body[data-world="jjk"]{
  background:
    radial-gradient(1000px 600px at 84% -10%, rgba(89,194,240,.16), transparent 62%),
    radial-gradient(800px 520px at -8% 14%, rgba(216,74,68,.13), transparent 60%),
    linear-gradient(180deg, #101625, #0a0d14 52%);
  background-attachment:fixed;
}

/* Lo stile del logo — la scritta JUJUTSU KAISEN è nera coi bordi gialli:
   i titoli di sezione la citano (lettere scure, contorno giallo), e le
   superfici COMPLETE (cimelio in vetrina, luogo al massimo, legame chiuso)
   diventano blocchi neri bordati di giallo. */
body[data-world="jjk"] .sec-h h3{
  color:#10131c;
  -webkit-text-stroke:1px #f5d442;
  paint-order:stroke fill;
  text-shadow:0 0 12px rgba(245,212,66,.22);
  letter-spacing:1.4px;
}
body[data-world="jjk"] .coll.owned,
body[data-world="jjk"] .up.maxed,
body[data-world="jjk"] .fus.done{
  background:#0b0e15;
  border-color:#f5d442;
}
body[data-world="jjk"] .coll.owned .citem{box-shadow:0 0 0 2px rgba(245,212,66,.55), 0 6px 18px rgba(245,212,66,.18)}
body[data-world="jjk"] .ach.done{border-color:color-mix(in srgb,#f5d442 55%, var(--line));background:#0b0e15}

/* 2. il torii: due colonne, doppio architrave, vermiglio sul buio */
body[data-world="jjk"] .sec-h{position:relative}
body[data-world="jjk"] .sec-h::before{
  content:"";position:absolute;left:-12px;top:50%;width:56px;height:50px;
  transform:translateY(-50%);pointer-events:none;opacity:.34;
  background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 90'%3E%3Cg fill='%23d84a44'%3E%3Cpath d='M2 12 Q50 2 98 12 L96 22 Q50 13 4 22 Z'/%3E%3Crect x='12' y='30' width='76' height='7'/%3E%3Crect x='22' y='22' width='9' height='66'/%3E%3Crect x='69' y='22' width='9' height='66'/%3E%3Crect x='46' y='12' width='8' height='18'/%3E%3C/g%3E%3C/svg%3E") center/contain no-repeat;
}

/* 3. l'ofuda: il talismano di carta con la coda a rondine, nel colore
   della fazione */
body[data-world="jjk"] .faction-h .seal{
  width:10px;height:17px;border-radius:0;box-shadow:none;
  background:var(--fc);
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 44'%3E%3Cpath d='M2 2 H22 V38 L12 32 L2 38 Z' fill='%23000'/%3E%3C/svg%3E") center/contain no-repeat;
          mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 44'%3E%3Cpath d='M2 2 H22 V38 L12 32 L2 38 Z' fill='%23000'/%3E%3C/svg%3E") center/contain no-repeat;
}

/* 4. IL TWIST — dietro il velo. Il ritratto affonda nel buio, SFOCATO: la
   sfocatura sta sul ritratto stesso (blur nel suo filter), non in un
   backdrop-filter sul velo — il backdrop non vede i fratelli già filtrati e,
   senza foto, sfocherebbe solo il testo. Il velo scurisce e basta. Come
   sempre il filtro non sta su .hero: va sull'immagine, e il gradiente
   segnaposto si spegne a mano. */
body[data-world="jjk"] .card.locked{opacity:.92;filter:saturate(1)}
body[data-world="jjk"] .card.locked .hero{
  filter:none;
  background:linear-gradient(180deg, #1a2338, #0e1320);
}
body[data-world="jjk"] .card.locked .hero .hart{filter:grayscale(.7) brightness(.45) blur(2.5px)}
body[data-world="jjk"] .card.locked .hero::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(180deg, rgba(10,13,20,.30), rgba(10,13,20,.55));
}
body[data-world="jjk"] .card.locked .hero .hinit{color:rgba(0,0,0,.68);text-shadow:none}
/* anche nome, ruolo e abilità stanno dietro il velo: sfocati quel tanto che
   li rende un mistero. Il tasto Recluta e il prezzo restano nitidi: l'azione
   non si nasconde mai. */
body[data-world="jjk"] .card.locked .nm,
body[data-world="jjk"] .card.locked .role{filter:blur(1.5px)}
body[data-world="jjk"] .card.locked .abil{filter:blur(2px)}

/* =====================================================================
   MONDO CYBERPUNK: EDGERUNNERS — quello che le variabili non sanno dire.

   Night City di notte (la palette sta in edge.js; le scanline le porta la
   texture). Qui i segni:
     1. la TELA — nero coi neon che salgono dai bordi, acido e magenta;
     2. la FILIGRANA — la Luna sopra lo skyline di Night City dietro le
        intestazioni: il sogno, appeso sopra la città;
     3. i SIGILLI — uno shard/chip coi pin, nel colore della fazione;
     4. IL TWIST — chi non è reclutato è in GLITCH da cyberpsicosi: statica
        sul ritratto e aberrazione cromatica sul nome. Reclutare stabilizza
        il segnale.
   ===================================================================== */
body[data-world="edge"]{
  background:
    radial-gradient(900px 560px at 86% -10%, rgba(246,230,72,.14), transparent 60%),
    radial-gradient(800px 520px at -8% 16%, rgba(225,63,174,.15), transparent 60%),
    linear-gradient(180deg, #141018, #0b0a0e 52%);
  background-attachment:fixed;
}

/* 2. la Luna sopra lo skyline: il cerchio pieno e i megablock sotto */
body[data-world="edge"] .sec-h{position:relative}
body[data-world="edge"] .sec-h::before{
  content:"";position:absolute;left:-12px;top:50%;width:58px;height:46px;
  transform:translateY(-50%);pointer-events:none;opacity:.32;
  background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 80'%3E%3Ccircle cx='64' cy='26' r='20' fill='%23f6e648'/%3E%3Cg fill='%23e13fae'%3E%3Crect x='4' y='44' width='12' height='36'/%3E%3Crect x='20' y='34' width='10' height='46'/%3E%3Crect x='34' y='50' width='12' height='30'/%3E%3Crect x='50' y='40' width='10' height='40'/%3E%3Crect x='64' y='54' width='12' height='26'/%3E%3Crect x='80' y='44' width='11' height='36'/%3E%3C/g%3E%3C/svg%3E") center/contain no-repeat;
}

/* 3. lo shard: il chip dati coi pin, nel colore della fazione */
body[data-world="edge"] .faction-h .seal{
  width:12px;height:16px;border-radius:0;box-shadow:none;
  background:var(--fc);
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 42'%3E%3Cpath d='M4 2 H26 V30 H4 Z M6 30 H10 V40 H6 Z M13 30 H17 V40 H13 Z M20 30 H24 V40 H20 Z' fill='%23000'/%3E%3C/svg%3E") center/contain no-repeat;
          mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 42'%3E%3Cpath d='M4 2 H26 V30 H4 Z M6 30 H10 V40 H6 Z M13 30 H17 V40 H13 Z M20 30 H24 V40 H20 Z' fill='%23000'/%3E%3C/svg%3E") center/contain no-repeat;
}

/* 4. IL TWIST — il glitch. Il ritratto perde il segnale (statica a righe
   sottili, bande magenta/ciano), e il nome si sdoppia in aberrazione
   cromatica. Come sempre il filtro non sta su .hero: va sull'immagine, e
   il gradiente segnaposto si spegne a mano. */
body[data-world="edge"] .card.locked{opacity:.92;filter:saturate(1)}
body[data-world="edge"] .card.locked .hero{
  filter:none;
  background:linear-gradient(180deg, #1c1626, #100c16);
}
body[data-world="edge"] .card.locked .hero .hart{filter:grayscale(.85) brightness(.45) contrast(1.1)}
body[data-world="edge"] .card.locked .hero::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:
    repeating-linear-gradient(0deg, rgba(246,230,72,.05) 0 1px, transparent 1px 3px),
    repeating-linear-gradient(0deg, transparent 0 22px, rgba(225,63,174,.12) 22px 24px, transparent 24px 47px, rgba(95,212,224,.10) 47px 49px);
}
body[data-world="edge"] .card.locked .nm{
  position:relative;z-index:1;color:rgba(242,242,244,.9);
  text-shadow:-1.5px 0 rgba(225,63,174,.8), 1.5px 0 rgba(95,212,224,.8);
}
body[data-world="edge"] .card.locked .hero .hinit{color:rgba(0,0,0,.68);text-shadow:none}

/* =====================================================================
   MONDO DANDADAN — quello che le variabili non sanno dire.

   La notte del paranormale (la palette sta in dd.js). Qui i segni:
     1. la TELA — nero-viola con l'aura verde acido e il magenta che
        salgono dai bordi, complementari e stridenti come le tavole;
     2. la FILIGRANA — l'occhio spiritico spalancato dietro le
        intestazioni, con le ciglia a raggiera;
     3. i SIGILLI — la spirale ipnotica, nel colore della fazione;
     4. IL TWIST — chi non è reclutato è in NEGATIVO fotografico: la
        manifestazione non è ancora stata sviluppata. Reclutare stampa
        la foto.
   ===================================================================== */
body[data-world="dd"]{
  background:
    radial-gradient(900px 560px at 86% -10%, rgba(125,232,74,.13), transparent 60%),
    radial-gradient(800px 520px at -8% 16%, rgba(232,69,200,.14), transparent 60%),
    linear-gradient(180deg, #170f20, #100a16 52%);
  background-attachment:fixed;
}

/* 2. l'occhio spiritico: mandorla, iride, e le ciglia a raggiera */
body[data-world="dd"] .sec-h{position:relative}
body[data-world="dd"] .sec-h::before{
  content:"";position:absolute;left:-12px;top:50%;width:60px;height:44px;
  transform:translateY(-50%);pointer-events:none;opacity:.32;
  background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 70'%3E%3Cg fill='none' stroke='%23e845c8' stroke-width='3'%3E%3Cpath d='M8 35 Q50 4 92 35 Q50 66 8 35 Z'/%3E%3Cpath d='M50 6 V0 M28 11 L24 4 M72 11 L76 4 M14 22 L7 17 M86 22 L93 17'/%3E%3C/g%3E%3Ccircle cx='50' cy='35' r='13' fill='none' stroke='%237de84a' stroke-width='3'/%3E%3Ccircle cx='50' cy='35' r='5' fill='%237de84a'/%3E%3C/svg%3E") center/contain no-repeat;
}

/* 3. la spirale ipnotica, nel colore della fazione */
body[data-world="dd"] .faction-h .seal{
  width:15px;height:15px;border-radius:0;box-shadow:none;
  background:var(--fc);
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M50 50 m0 -6 a6 6 0 1 1 -12 0 a12 12 0 1 1 24 0 a18 18 0 1 1 -36 0 a24 24 0 1 1 48 0 a30 30 0 1 1 -60 0 a36 36 0 1 1 72 0' fill='none' stroke='%23000' stroke-width='8' stroke-linecap='round'/%3E%3C/svg%3E") center/contain no-repeat;
          mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M50 50 m0 -6 a6 6 0 1 1 -12 0 a12 12 0 1 1 24 0 a18 18 0 1 1 -36 0 a24 24 0 1 1 48 0 a30 30 0 1 1 -60 0 a36 36 0 1 1 72 0' fill='none' stroke='%23000' stroke-width='8' stroke-linecap='round'/%3E%3C/svg%3E") center/contain no-repeat;
}

/* 4. IL TWIST — il negativo. Il ritratto è la foto non ancora sviluppata
   (colori invertiti, slavati); anche il gradiente segnaposto si rovescia
   in chiaro. Il velo scuro in basso tiene leggibile il nome. Come sempre
   il filtro non sta su .hero: va sull'immagine. */
body[data-world="dd"] .card.locked{opacity:.92;filter:saturate(1)}
body[data-world="dd"] .card.locked .hero{
  filter:none;
  background:linear-gradient(180deg, #cfc6dc, #9d92b4);   /* il negativo del buio */
}
body[data-world="dd"] .card.locked .hero .hart{filter:invert(.9) grayscale(.25) brightness(.85) contrast(1.05)}
body[data-world="dd"] .card.locked .hero .hinit{color:rgba(30,20,44,.4);text-shadow:none}
body[data-world="dd"] .card.locked .nm{color:rgba(243,238,248,.92)}

/* =====================================================================
   MONDO BOCCHI THE ROCK! — quello che le variabili non sanno dire.

   Il buio della sala prove (la palette sta in btr.js). Qui i segni:
     1. la TELA — nero caldo con il rosa di Bocchi e il blu di Ryo che
        salgono piano dai bordi, come luci di palco in attesa;
     2. la FILIGRANA — un plettro col cavo jack dietro le intestazioni;
     3. i SIGILLI — plettri, nel colore della fazione;
     4. IL TWIST — chi non è reclutato sta DENTRO LA BOCCHI-BOX: il
        ritratto è coperto dal cartone con il nastro adesivo. Reclutare
        convince a uscire dalla scatola.
   ===================================================================== */
body[data-world="btr"]{
  background:
    radial-gradient(900px 560px at 86% -10%, rgba(240,140,171,.14), transparent 60%),
    radial-gradient(800px 520px at -8% 16%, rgba(95,184,232,.11), transparent 60%),
    linear-gradient(180deg, #1b151b, #141014 52%);
  background-attachment:fixed;
}

/* 2. il plettro col jack: lo strumento minimo del mestiere */
body[data-world="btr"] .sec-h{position:relative}
body[data-world="btr"] .sec-h::before{
  content:"";position:absolute;left:-12px;top:50%;width:52px;height:48px;
  transform:translateY(-50%) rotate(-14deg);pointer-events:none;opacity:.32;
  background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 90'%3E%3Cpath d='M28 6 C46 0 66 4 70 18 C74 34 58 58 46 66 C34 58 14 40 16 24 C17 14 20 9 28 6 Z' fill='%23f08cab'/%3E%3Cpath d='M46 66 C50 76 58 82 70 82 C80 82 88 78 94 70' fill='none' stroke='%235fb8e8' stroke-width='5' stroke-linecap='round'/%3E%3Ccircle cx='96' cy='68' r='4' fill='%235fb8e8'/%3E%3C/svg%3E") center/contain no-repeat;
}

/* 3. il plettro di fazione */
body[data-world="btr"] .faction-h .seal{
  width:13px;height:15px;border-radius:0;box-shadow:none;
  background:var(--fc);
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 60 66'%3E%3Cpath d='M16 4 C28 0 44 2 48 12 C52 24 40 48 30 56 C20 48 6 32 8 18 C9 10 11 6 16 4 Z' fill='%23000'/%3E%3C/svg%3E") center/contain no-repeat;
          mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 60 66'%3E%3Cpath d='M16 4 C28 0 44 2 48 12 C52 24 40 48 30 56 C20 48 6 32 8 18 C9 10 11 6 16 4 Z' fill='%23000'/%3E%3C/svg%3E") center/contain no-repeat;
}

/* 4. IL TWIST — la Bocchi-box. Il ritratto è chiuso nel cartone: fondo
   cartone pieno, nastro adesivo in croce, e le fessure dei manici ai lati.
   Il nome resta leggibile sul velo. Reclutare apre la scatola. */
body[data-world="btr"] .card.locked{opacity:.94;filter:saturate(1)}
body[data-world="btr"] .card.locked .hero{
  filter:none;
  background:linear-gradient(180deg, #b9905f, #97744a);   /* il cartone */
}
body[data-world="btr"] .card.locked .hero .hart{filter:grayscale(1) brightness(.6);opacity:.12}
body[data-world="btr"] .card.locked .hero::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:
    /* il nastro adesivo: una banda verticale e una orizzontale, più chiare */
    linear-gradient(90deg, transparent 0 44%, rgba(222,198,150,.75) 44% 56%, transparent 56%),
    linear-gradient(180deg, transparent 0 34%, rgba(222,198,150,.6) 34% 46%, transparent 46%),
    /* le pieghe del cartone */
    repeating-linear-gradient(90deg, transparent 0 30px, rgba(90,64,38,.18) 30px 31px);
}
body[data-world="btr"] .card.locked .hero .hinit{color:rgba(90,64,38,.5);text-shadow:none}
body[data-world="btr"] .card.locked .nm{position:relative;z-index:1;color:rgba(246,240,243,.92)}

/* =====================================================================
   VIGNETTE CROSSOVER — la galleria delle cornici e il banco delle prove.
   Riusa .coll/.shelf (cimeli), .mchip (chip), .fac (fazioni): qui solo
   ciò che quelle classi non sanno dire.
   ===================================================================== */
.coll.xf{cursor:default}
.coll.xf.owned{cursor:pointer}
.coll.xf.owned:hover .citem{transform:translateY(-3px)}
.coll.xf.mystery .citem{filter:none;opacity:.75;background:color-mix(in srgb,var(--accent) 8%, var(--bg-2))}
.xriddle{font-size:12px;font-style:italic;line-height:1.45;color:var(--muted);display:flex;align-items:center;min-height:44px}

/* La vignetta su cui punta l'indizio: bordo dorato che pulsa piano, per
   ritrovarla nella galleria senza cercare. */
.coll.xf.hinted{border-color:color-mix(in srgb,var(--gold) 60%, var(--line));animation:xhintpulse 1.9s ease-in-out infinite}
@keyframes xhintpulse{
  0%,100%{box-shadow:var(--edge), 0 0 0 1px color-mix(in srgb,var(--gold) 30%, transparent)}
  50%{box-shadow:0 0 0 3px color-mix(in srgb,var(--gold) 45%, transparent), 0 8px 22px color-mix(in srgb,var(--gold) 24%, transparent)}
}
/* Il box indizio nel banco: dorato, discreto, premibile per saltare alla card. */
.xhintbox{display:flex;gap:11px;align-items:flex-start;cursor:pointer;
  padding:11px 13px;border-radius:12px;
  border:1px solid color-mix(in srgb,var(--gold) 42%, var(--line-2));
  background:color-mix(in srgb,var(--gold) 8%, var(--panel));
  transition:border-color .14s, background .14s}
.xhintbox:hover{border-color:color-mix(in srgb,var(--gold) 65%, var(--line-2));
  background:color-mix(in srgb,var(--gold) 13%, var(--panel))}
.xhintbox .xhi{font-size:18px;line-height:1.3;flex:none}
.xhintbox .xht{font-family:var(--font-num);font-size:10.5px;letter-spacing:.6px;text-transform:uppercase;
  font-weight:700;color:var(--gold)}
.xhintbox .xhd{font-size:12.5px;line-height:1.45;color:var(--ink);margin-top:2px}
.xhintbox .xhd b{color:color-mix(in srgb,var(--gold) 55%, var(--ink));font-weight:700}

/* ---- Layout a due colonne: galleria + banco delle prove ----
   Desktop: galleria a sinistra, banco appiccicato a destra sempre in vista.
   Mobile: impilano, col banco per primo (è prima nel DOM; su desktop la griglia
   lo rimanda a destra assegnandolo esplicitamente alla colonna 2). */
.xlayout{display:grid;grid-template-columns:1fr;gap:16px;align-items:start}
@media (min-width:860px){
  .xlayout{grid-template-columns:minmax(0,1fr) 340px}
  .xgallery{grid-column:1;grid-row:1}
  .xbench{grid-column:2;grid-row:1;min-width:0}
}

.xgallery{display:flex;flex-direction:column;gap:14px;min-width:0}
/* i due gruppi (Da scoprire / Scoperte) riusano .fac per il collasso nativo,
   dentro una scatola che li tiene distinti */
.xgroup{border:1px solid var(--line);border-radius:14px;padding:2px 12px 10px;margin-bottom:0;
  background:color-mix(in srgb,var(--panel) 90%, transparent)}
.xgroup > summary{margin:8px 2px}
.xgroup > .shelf{margin-top:4px}

.xbench-inner{display:flex;flex-direction:column;gap:11px}
.xbench .sec-h{margin:0 0 2px}
@media (min-width:860px){
  /* appiccicato sotto l'header sticky: gli slot e il tasto restano fissi, solo il
     roster scorre dentro. `top` insegue l'altezza dell'header (col tasto debug
     provvisorio è più alto; da ritoccare quando quello sparirà). */
  .xbench-inner{position:sticky;top:132px;max-height:calc(100vh - 152px)}
  .xrosters{flex:1 1 auto;min-height:0;overflow:auto;overscroll-behavior:contain}
}

.xfilter{display:flex;align-items:center;gap:8px;padding:0 12px;
  border:1px solid var(--line-2);border-radius:10px;background:var(--panel)}
.xfilter:focus-within{border-color:color-mix(in srgb,var(--accent) 50%, var(--line-2))}
.xfilter .xfi{flex:none;opacity:.55;font-size:13px}
.xfilter input{flex:1;min-width:0;border:0;background:transparent;color:var(--ink);
  font-family:var(--font-body);font-size:13px;padding:9px 0;outline:none}
.xfilter input::placeholder{color:var(--faint)}
.xnores{font-size:12px;color:var(--faint);text-align:center;padding:8px 0}

.xslots{display:flex;gap:10px;align-items:center;justify-content:center}
.xslot{flex:1 1 0;min-width:0;padding:10px 12px;border:1.5px dashed var(--line);border-radius:12px;
  text-align:center;font-weight:700;color:var(--faint);background:var(--panel);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.xslot.filled{border-style:solid;border-color:color-mix(in srgb,var(--accent) 55%, var(--line));color:var(--ink)}
.xvs{flex:none;font-weight:900;font-size:18px;color:var(--faint)}
.xtry{align-self:stretch;width:100%}
.xhint{text-align:center;font-size:12px;color:var(--muted)}

/* i nomi su due colonne: la lista verticale sprecava metà larghezza del banco */
.xroster{display:grid;grid-template-columns:1fr 1fr;gap:6px;padding:8px 2px}
.xroster .xchip{min-width:0;justify-content:center;text-align:center}
button.xchip{cursor:pointer;font:inherit;transition:transform .12s, border-color .12s}
button.xchip:hover{transform:translateY(-1px)}
button.xchip.sel{color:var(--ink);border-color:var(--accent);
  box-shadow:0 0 0 1.5px color-mix(in srgb,var(--accent) 60%, transparent)}
.xchip[hidden]{display:none}
.xros[hidden]{display:none}

/* ---- gli indizi a richiesta sulla cornice ----
   Ciò che un gradino ha svelato resta scritto sulla card; sotto, il bottone
   per il gradino successivo. Dorati come tutto ciò che sa di indizio. */
.xreveal{font-size:11.5px;line-height:1.4;color:var(--muted);
  padding:6px 9px;border-radius:9px;
  border:1px solid color-mix(in srgb,var(--gold) 30%, var(--line));
  background:color-mix(in srgb,var(--gold) 7%, transparent)}
.xreveal b{color:color-mix(in srgb,var(--gold) 55%, var(--ink));font-weight:700}
.xhbuy{display:flex;justify-content:space-between;align-items:center;gap:8px;
  border:1px solid color-mix(in srgb,var(--gold) 38%, var(--line-2));border-radius:10px;
  padding:7px 10px;cursor:pointer;width:100%;
  font-family:var(--font-body);font-weight:700;font-size:12px;color:var(--ink);
  background:color-mix(in srgb,var(--gold) 10%, var(--panel-2));
  transition:border-color .12s, background .12s}
.xhbuy:hover{border-color:color-mix(in srgb,var(--gold) 62%, var(--line-2));
  background:color-mix(in srgb,var(--gold) 16%, var(--panel-2))}
.xhbuy:disabled{opacity:.42;cursor:not-allowed}
.xhbuy .cost{font-family:var(--font-num);font-size:11.5px;color:var(--gold)}

/* =====================================================================
   LA COMPARSA FUGACE — la figurina cliccabile che attraversa il mondo.
   Vive su body (render() rifà #stage e se la porterebbe via); left/top
   glieli assegna spawnCameo(), qui solo la veste. Sotto il toast (z-50):
   un annuncio non va mai coperto da un gadget.
   ===================================================================== */
.cameo{
  position:fixed;z-index:45;transform:translateX(-50%);
  display:flex;flex-direction:column;align-items:center;gap:6px;
  background:none;border:none;cursor:pointer;padding:10px;
  -webkit-tap-highlight-color:transparent;
  animation:cameoin .35s cubic-bezier(.2,1.4,.4,1);
}
.cameo .cico{
  font-size:40px;line-height:1;
  filter:drop-shadow(0 0 14px color-mix(in srgb,var(--gold) 75%, transparent));
  animation:cameofloat 2.4s ease-in-out infinite;
  transition:transform .12s;
}
.cameo:hover .cico{transform:scale(1.14)}
.cameo:active .cico{transform:scale(.95)}
.cameo .clab{
  font-size:10.5px;font-weight:700;color:var(--ink);white-space:nowrap;
  max-width:46vw;overflow:hidden;text-overflow:ellipsis;
  background:var(--panel-2);border:1px solid color-mix(in srgb,var(--gold) 45%, var(--line-2));
  border-radius:999px;padding:3px 10px;box-shadow:var(--sh-pop);
}
@keyframes cameoin{from{opacity:0;transform:translateX(-50%) scale(.4)}to{opacity:1;transform:translateX(-50%) scale(1)}}
@keyframes cameofloat{0%,100%{transform:translateY(0)}50%{transform:translateY(-7px)}}

/* Il chip ⚡ nell'HUD mentre il bonus corre: il countdown lo scrive il tick. */
.stat .boostchip{
  font-family:var(--font-num);font-size:11px;font-weight:700;color:var(--gold);
  border:1px solid color-mix(in srgb,var(--gold) 45%, var(--line));border-radius:999px;
  padding:2px 8px;background:color-mix(in srgb,var(--gold) 12%, transparent);
  animation:boostpulse 1.4s ease-in-out infinite;
}
.stat .boostchip[hidden]{display:none}
@keyframes boostpulse{0%,100%{opacity:1}50%{opacity:.55}}

/* ---- Shaya, la Collezionista ----
   Stessa comparsa, ma non è di nessun mondo: palette viola/blu fissa (il suo
   colore, il suo occhio), aura più fredda e ampia, respiro più lento. Il ???
   al posto del nome è il mistero. */
.cameo.wanderer{--shaya-1:#8b6cff;--shaya-2:#4a74f0}
.cameo.wanderer .cico{
  filter:drop-shadow(0 0 16px var(--shaya-1)) drop-shadow(0 0 34px var(--shaya-2));
  animation:cameofloat 3.2s ease-in-out infinite, shayapulse 3.4s ease-in-out infinite;
}
/* Sfondo viola scuro FISSO, non legato a --panel-2: nei mondi "carta chiara"
   (Naruto, Death Note, Spy×Family, Frieren) la pastiglia diventava chiara e il
   testo lilla ci spariva dentro. Fissa, resta leggibile ovunque — ed è giusto
   così, Shaya non è di nessun mondo: la sua pastiglia non ne prende il colore. */
.cameo.wanderer .clab{
  color:#ece4ff;letter-spacing:2px;
  border-color:color-mix(in srgb,var(--shaya-1) 62%, #000);
  background:linear-gradient(180deg,#2a2352,#191430);
  box-shadow:0 0 16px color-mix(in srgb,var(--shaya-1) 45%, transparent), var(--sh-pop);
}
@keyframes shayapulse{0%,100%{opacity:.9;transform:scale(1)}50%{opacity:1;transform:scale(1.06)}}

/* Il banco di Shaya in cima alla galleria Crossover: un nastro viola, muto e
   incuriosente finché è mistero, premibile e dorato-viola una volta svelato. */
.xwander{
  display:flex;align-items:center;gap:13px;
  padding:13px 15px;border-radius:14px;
  border:1px solid color-mix(in srgb,#8b6cff 42%, var(--line));
  background:
    radial-gradient(120px 80px at 12% 30%, color-mix(in srgb,#8b6cff 18%, transparent), transparent 70%),
    linear-gradient(180deg, color-mix(in srgb,#4a74f0 10%, var(--panel)), var(--panel));
}
.xwander.revealed{cursor:pointer;border-color:color-mix(in srgb,#8b6cff 62%, var(--line-2));
  transition:border-color .14s, transform .1s}
.xwander.revealed:hover{transform:translateY(-1px);border-color:#a48cff}
.xwico{font-size:30px;line-height:1;flex:none;
  filter:drop-shadow(0 0 12px color-mix(in srgb,#8b6cff 60%, transparent))}
.xwbody{flex:1;min-width:0}
.xwname{font-family:var(--font-display);font-weight:700;font-size:14px;color:#d8ccff}
.xwsub{font-size:11.5px;color:var(--muted);margin-top:2px}
.xwsub b{color:#c9b8ff;font-weight:700}
.xwgo{flex:none;color:#a48cff;font-size:22px;font-weight:700;line-height:1}

/* =====================================================================
   IL RIEPILOGO DEL RITORNO — il modale del "bentornato".
   Riusa .modal/.mbox/.mhead dei Ricordi; qui solo le righe per mondo.
   `--wc` è l'accento del mondo della riga, assegnato inline.
   ===================================================================== */
.awaybox{width:min(460px,100%)}
.awaylist{display:flex;flex-direction:column;gap:8px}
.awayrow{
  display:flex;align-items:center;gap:11px;width:100%;text-align:left;cursor:pointer;
  font-family:var(--font-body);color:var(--ink);
  background:var(--panel-2);border:1px solid var(--line);border-radius:12px;padding:10px 13px;
  transition:border-color .12s, background .12s;
}
.awayrow:hover{border-color:color-mix(in srgb,var(--wc) 55%, var(--line-2));
  background:color-mix(in srgb,var(--wc) 7%, var(--panel-2))}
.awayrow .dot{flex:none;width:9px;height:9px;border-radius:50%;
  background:var(--wc);box-shadow:0 0 8px var(--wc)}
.awayrow .awmain{flex:1;min-width:0;display:flex;flex-direction:column;gap:4px}
.awayrow .awn{font-weight:700;font-size:13px}
.awaytags{display:flex;flex-wrap:wrap;gap:4px}
.awaytag{font-size:10.5px;color:var(--gold);border-radius:999px;padding:1px 8px;
  border:1px solid color-mix(in srgb,var(--gold) 35%, var(--line));
  background:color-mix(in srgb,var(--gold) 10%, transparent)}
.awayrow .awg{flex:none;font-family:var(--font-num);font-size:13px;color:var(--ink);white-space:nowrap}
.awayok{margin-top:14px;justify-content:center}

/* =====================================================================
   LA VETRINA DEI RICORDI (Bacheca) — una mensola di trofei che cresce.
   Tessere trovate (icona + titolo + personaggio, premibili per rileggerle)
   e sagome anonime per ciò che resta acceso nel mondo, senza dire quali.
   ===================================================================== */
.ricordi-sec{margin-top:26px}
.rworld{margin-top:6px}
.rgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:10px}

.rmem{
  display:flex;align-items:center;gap:11px;text-align:left;min-height:62px;
  border:1px solid var(--line);border-radius:12px;padding:11px 12px;
  background:var(--panel);box-shadow:var(--edge);
}
.rmem.found{
  cursor:pointer;font-family:inherit;
  border-color:color-mix(in srgb,var(--wc) 40%, var(--line));
  background:
    radial-gradient(90px 60px at 14% 18%, color-mix(in srgb,var(--wc) 13%, transparent), transparent 70%),
    var(--panel);
  transition:border-color .14s, transform .1s;
}
.rmem.found:hover{transform:translateY(-1px);border-color:color-mix(in srgb,var(--wc) 65%, var(--line-2))}
.rmem .rico{
  flex:none;width:38px;height:38px;border-radius:10px;display:grid;place-items:center;font-size:20px;
  background:var(--bg-2);border:1px solid var(--line);
  box-shadow:0 0 0 2px color-mix(in srgb,var(--wc) 22%, transparent);
}
.rmem .rbody{display:flex;flex-direction:column;gap:2px;min-width:0}
.rmem .rn{font-weight:700;font-size:12.5px;line-height:1.25;color:var(--ink);
  overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}
.rmem .rc{font-size:11px;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

/* la sagoma: un ricordo ancora spento in questo mondo. Anonima di proposito —
   dice che c'è, non di chi è. Niente hover, niente click. */
.rmem.ghost{
  justify-content:center;color:var(--faint);font-size:20px;
  border-style:dashed;filter:grayscale(1) opacity(.5);background:var(--bg-2);
}

/* ---- Le Stagioni (rilettura di un mondo) ----
   La card compare in fondo alla Cronaca chiusa: verde germoglio, per dire
   "ricomincia" senza gridare. Il fregio 🌿 marca i mondi già riletti. */
.camp.season{
  border-color:color-mix(in srgb,var(--good) 42%, var(--line));
  background:
    radial-gradient(160px 100px at 12% 20%, color-mix(in srgb,var(--good) 12%, transparent), transparent 70%),
    linear-gradient(180deg, color-mix(in srgb,var(--good) 7%, var(--panel)), var(--panel));
}
.seasonnote{
  font-size:12px;line-height:1.5;color:var(--muted);
  padding:10px 12px;border-radius:11px;
  border:1px solid color-mix(in srgb,var(--good) 26%, var(--line));
  background:color-mix(in srgb,var(--good) 6%, transparent);
}
.seasonnote b{color:var(--good);font-weight:700}
.btn.season-go{
  background:linear-gradient(180deg,color-mix(in srgb,var(--good) 24%, var(--panel-2)),var(--panel-2));
  border-color:color-mix(in srgb,var(--good) 48%, var(--line-2));
}
.btn.season-go:hover{border-color:color-mix(in srgb,var(--good) 70%, var(--line-2))}
.btn.season-go .cost{color:var(--good)}
/* il fregio: nell'intestazione della Cronaca e nel menu dei mondi */
.seasonchip{
  font-family:var(--font-num);font-size:10.5px;font-weight:700;color:var(--good);
  border:1px solid color-mix(in srgb,var(--good) 40%, var(--line));border-radius:999px;
  padding:2px 9px;background:color-mix(in srgb,var(--good) 10%, transparent);white-space:nowrap;
}
.wi .wk.season{color:var(--good)}

/* ---- Particelle (il "sugo" sui momenti grossi) ----
   <div> effimeri lanciati da fxBurst() (js/core/fx.js): sgorgano da un punto,
   volano verso --dx/--dy e si spengono. --pc è il colore, di solito l'accento
   del mondo. Sotto il modale (z-60) e la comparsa (z-45), sopra le card. */
.particle{
  position:fixed;z-index:48;border-radius:50%;
  background:var(--pc,#fff);box-shadow:0 0 7px var(--pc,#fff);
  pointer-events:none;transform:translate(-50%,-50%);
  animation:particle .72s cubic-bezier(.15,.6,.3,1) forwards;
}
@keyframes particle{
  0%{opacity:1;transform:translate(-50%,-50%) scale(1)}
  100%{opacity:0;transform:translate(calc(-50% + var(--dx)), calc(-50% + var(--dy))) scale(.2)}
}
/* chi chiede meno movimento non vuole cose che schizzano (fxBurst lo rispetta
   già saltando del tutto; questa è la cintura di sicurezza lato CSS) */
@media (prefers-reduced-motion: reduce){ .particle{display:none} }
