/* ═══════════════════════════════════════════════════════════════════════
   FurinaBot — habillage inspiré de l'UI de Genshin Impact.
   Nuit bleutée constellée, texte crème (jamais blanc pur), or « parchemin »
   #d3bc8e pour les cadres, dégradés de rareté sur les cases d'inventaire
   (coin bas-droit arrondi, bandeau crème de niveau), boutons pilule ivoire.
   ═══════════════════════════════════════════════════════════════════════ */
@import url('https://fonts.googleapis.com/css2?family=Marcellus&family=Nunito+Sans:wght@400;600;700;800&display=swap');

:root {
    --night: #0d1019;
    --night-2: #131725;
    --panel: #1d2333;
    --panel-2: #232a3e;
    --panel-3: #2c3450;
    --edge: rgba(211, 188, 142, .18);
    --edge-soft: rgba(236, 229, 216, .10);

    --cream: #ece5d8;
    --cream-dim: #aaa494;
    --cream-faint: #6f6b60;
    --ink: #3b4255;          /* texte sombre sur les boutons ivoire */

    --gold: #d3bc8e;         /* or signature de l'UI du jeu */
    --gold-bright: #ffd780;
    --azur: #7fb2e5;         /* données réelles importées du compte Genshin */
    --azur-bright: #a9d0f5;
    --star: #ffcc32;
    --set-green: #5dbf8b;    /* nom de set, comme la teinte verte en jeu */

    --danger: #e06c68;
    --ok: #6fbf73;

    /* Paliers de qualité d'un artefact (cf. SCORE_TIERS dans utils/theme.py) :
       du plus banal au plus rare. Les mêmes couleurs servent au CV et au RV. */
    --t-gris: #9aa0a6;
    --t-violet: #a970ff;
    --t-jaune: #f1c40f;
    --t-bleu: #5dc8ff;
    --t-rouge: #ff3b30;

    /* Dégradés de rareté des cases d'inventaire */
    --g5: linear-gradient(160deg, #6e4a30 0%, #96613a 52%, #cf8f3e 100%);
    --g4: linear-gradient(160deg, #4c4470 0%, #71589e 52%, #a37ad1 100%);
    --g3: linear-gradient(160deg, #39537a 0%, #4a77a3 52%, #63a9c9 100%);
    /* Les deux raretés que seules les armes connaissent — aucun artéfact ne
       descend sous 3★. */
    --g2: linear-gradient(160deg, #3a5340 0%, #4d7150 52%, #6ba36a 100%);
    --g1: linear-gradient(160deg, #45474d 0%, #5c5f66 52%, #83868d 100%);

    --font-display: "Marcellus", "Times New Roman", serif;
    --font-body: "Nunito Sans", "Segoe UI", system-ui, sans-serif;
}

/* ══ Les deux espaces ══
   Le site couvre deux mondes qu'il ne faut jamais confondre : le JEU du bot,
   qu'on modifie, et le COMPTE Genshin, simple miroir de tirages réels. Chacun
   porte un accent, dont dérive tout le chrome (rail, titres, cadres) — de sorte
   qu'un coup d'œil périphérique suffit à savoir où l'on est.

   `--accent-rgb` double `--accent` : les fonds translucides ont besoin du
   triplet, et rgba() n'accepte pas une couleur hex en premier argument.

   L'or reste l'or partout où il dit la RARETÉ (5★, dégradés d'inventaire,
   pastilles de chance) : ça, c'est du vocabulaire Genshin, pas du repérage. */
.layout {
    --accent: var(--gold);
    --accent-bright: var(--gold-bright);
    --accent-rgb: 211, 188, 142;
    --edge: rgba(211, 188, 142, .18);
}
.layout[data-space="genshin"] {
    --accent: var(--azur);
    --accent-bright: var(--azur-bright);
    --accent-rgb: 127, 178, 229;
    --edge: rgba(127, 178, 229, .20);
}
/* Paramètres, admin d'aucun des deux mondes : accent éteint, pour que le neutre
   ne se fasse pas passer pour l'un des deux espaces. */
.layout[data-space="tools"] {
    --accent: var(--cream-dim);
    --accent-bright: var(--cream);
    --accent-rgb: 170, 164, 148;
    --edge: rgba(236, 229, 216, .14);
}

* { box-sizing: border-box; }

/* `hidden` doit gagner : plusieurs composants posent un `display` explicite
   (.cell, .empty…), qui prend le pas sur la feuille de l'agent utilisateur et
   laissait s'afficher des éléments que le JS croyait avoir masqués. */
[hidden] { display: none !important; }

body {
    margin: 0;
    background: var(--night);
    color: var(--cream);
    font-family: var(--font-body);
    font-size: 15px;
    line-height: 1.55;
    -webkit-font-smoothing: antialiased;
}

/* Voûte étoilée : nébuleuses douces + semis d'étoiles en tuile SVG. */
body::before {
    content: "";
    position: fixed;
    inset: 0;
    z-index: -1;
    background:
        radial-gradient(1000px 600px at 82% -12%, rgba(76, 100, 175, .20) 0%, transparent 65%),
        radial-gradient(800px 560px at -8% 100%, rgba(190, 150, 80, .07) 0%, transparent 60%),
        radial-gradient(600px 400px at 30% 20%, rgba(120, 90, 160, .07) 0%, transparent 60%),
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='280' height='280'%3E%3Cg fill='%23fffbe8'%3E%3Ccircle cx='24' cy='38' r='1' opacity='.20'/%3E%3Ccircle cx='120' cy='12' r='.7' opacity='.14'/%3E%3Ccircle cx='210' cy='64' r='1.2' opacity='.22'/%3E%3Ccircle cx='68' cy='120' r='.8' opacity='.12'/%3E%3Ccircle cx='170' cy='150' r='1' opacity='.16'/%3E%3Ccircle cx='250' cy='200' r='.7' opacity='.12'/%3E%3Ccircle cx='40' cy='220' r='1.1' opacity='.18'/%3E%3Ccircle cx='140' cy='250' r='.8' opacity='.13'/%3E%3Ccircle cx='232' cy='120' r='.6' opacity='.10'/%3E%3Ccircle cx='90' cy='180' r='.6' opacity='.10'/%3E%3C/g%3E%3C/svg%3E");
}

a { color: var(--gold); text-decoration: none; transition: color .14s; }
a:hover { color: var(--gold-bright); }

h1, h2, h3, .display { font-family: var(--font-display); font-weight: 400; }

/* ══ Rail de navigation (menu latéral du jeu) ══ */
.layout { display: flex; min-height: 100vh; }

.rail {
    width: 218px;
    flex-shrink: 0;
    background: linear-gradient(180deg, rgba(24, 28, 43, .92) 0%, rgba(16, 19, 30, .95) 100%);
    border-right: 1px solid var(--edge);
    padding: 26px 0 18px;
    position: sticky;
    top: 0;
    height: 100vh;
    display: flex;
    flex-direction: column;
    backdrop-filter: blur(4px);
}

.rail .brand {
    font-family: var(--font-display);
    text-align: center;
    font-size: 1.3rem;
    letter-spacing: .18em;
    color: var(--accent);
    padding-bottom: 18px;
    margin: 0 18px 16px;
    border-bottom: 1px solid var(--edge);
    position: relative;
}
/* Losange d'ornement centré sous le titre, motif récurrent de l'UI. */
.rail .brand::after {
    content: "";
    position: absolute;
    left: 50%; bottom: -4.5px;
    width: 8px; height: 8px;
    background: var(--night);
    border: 1px solid var(--accent);
    transform: translateX(-50%) rotate(45deg);
}
.rail .brand small {
    display: block;
    font-family: var(--font-body);
    font-size: .62rem;
    letter-spacing: .34em;
    color: var(--cream-faint);
    margin-top: 3px;
}

/* ══ Sélecteur d'espace ══
   Deux pavés côte à côte, en haut du rail : c'est le premier objet du regard, et
   le seul endroit d'où l'on change de monde. L'actif prend l'accent en fond
   plein — l'inactif reste éteint, sans même son propre accent, pour qu'aucune
   hésitation ne soit possible sur celui où l'on se trouve. */
.spaces {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 5px;
    padding: 0 12px 4px;
}
.spaces a {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    padding: 9px 4px 8px;
    border-radius: 7px;
    color: var(--cream-faint);
    font-size: .7rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: .1em;
    box-shadow: inset 0 0 0 1px var(--edge-soft);
    transition: background .14s, color .14s, box-shadow .14s;
}
.spaces a .gl { font-size: 1.05rem; line-height: 1; font-weight: 400; }
.spaces a:hover { color: var(--cream-dim); box-shadow: inset 0 0 0 1px var(--edge); }
.spaces a.on {
    background: rgba(var(--accent-rgb), .16);
    color: var(--accent-bright);
    box-shadow: inset 0 0 0 1px var(--accent);
}

.rail nav { display: flex; flex-direction: column; gap: 2px; padding: 6px 12px; }
.rail nav a {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 14px;
    border-radius: 6px;
    color: var(--cream-dim);
    font-size: .92rem;
    font-weight: 600;
    letter-spacing: .04em;
    transition: background .14s, color .14s;
}
/* Intitulé de section du rail (Jeu / Outils). */
.nav-group {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 6px 14px 4px;
    margin-top: 12px;
    font-size: .64rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: .2em;
    color: var(--cream-faint);
}
.nav-group:first-child { margin-top: 0; }
.nav-group::after {
    content: "";
    flex: 1;
    height: 1px;
    background: linear-gradient(90deg, var(--edge-soft), transparent);
}

.rail nav a svg { width: 17px; height: 17px; flex-shrink: 0; opacity: .8; }
.rail nav a:hover { background: rgba(236, 229, 216, .06); color: var(--cream); }
.rail nav a.active {
    background: linear-gradient(90deg, rgba(var(--accent-rgb), .16), rgba(var(--accent-rgb), .04));
    color: var(--accent-bright);
    box-shadow: inset 0 0 0 1px rgba(var(--accent-rgb), .30);
}
.rail nav a.active svg { opacity: 1; }


/* ══ Barre de ressources (haut droit, comme en jeu) ══ */
.content { flex: 1; min-width: 0; }

.resbar {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    gap: 9px;
    padding: 18px 34px 6px;
    flex-wrap: wrap;
}

/* Pastille de lieu, tout à gauche du bandeau : le rail dit où l'on peut aller,
   celle-ci dit où l'on EST. Elle nomme l'espace en toutes lettres — la couleur
   seule ne suffit pas, ni de loin ni pour qui la distingue mal. */
.dchip {
    display: flex;
    align-items: center;
    gap: 7px;
    margin-right: auto;
    padding: 4px 14px;
    border-radius: 999px;
    background: rgba(var(--accent-rgb), .12);
    box-shadow: inset 0 0 0 1px rgba(var(--accent-rgb), .40);
    color: var(--accent-bright);
    font-size: .72rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: .13em;
}
.dchip .gl { font-size: .9rem; font-weight: 400; }

/* Marque de provenance : posée sur une valeur qui vient de l'AUTRE espace.
   Toujours azur, quel que soit l'espace courant — c'est la donnée qu'elle
   qualifie, pas la page ; et une valeur importée ne se modifie pas d'ici. */
.prov {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 1px 9px;
    border-radius: 999px;
    background: rgba(127, 178, 229, .14);
    box-shadow: inset 0 0 0 1px rgba(127, 178, 229, .45);
    color: var(--azur-bright);
    font-size: .66rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: .1em;
    white-space: nowrap;
    vertical-align: middle;
}
.res {
    display: flex;
    align-items: center;
    gap: 7px;
    background: rgba(13, 16, 25, .78);
    border: 1px solid var(--edge);
    border-radius: 999px;
    padding: 4px 15px 4px 11px;
    font-size: .86rem;
    font-variant-numeric: tabular-nums;
    box-shadow: 0 2px 10px rgba(0, 0, 0, .3);
}
/* Icône de ressource : image d'objet quand il en existe une, emoji sinon. */
.res .ico { font-size: .92rem; }
.res img.ico { width: 20px; height: 20px; object-fit: contain; display: block; }
/* Tracé maison : il prend l'accent de l'espace, là où les icônes d'objets
   apportent leurs propres couleurs. */
.res svg.ico { width: 19px; height: 19px; display: block; color: var(--accent-bright); }
.res .val { font-weight: 800; letter-spacing: .02em; }

.account {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-left: 8px;
    font-size: .86rem;
    color: var(--cream-dim);
}
.avatar { width: 27px; height: 27px; border-radius: 50%; border: 1px solid var(--gold); display: block; }

/* Réglages, admin, déconnexion : trois pastilles discrètes, collées à l'identité. */
.acct-nav { display: flex; align-items: center; gap: 5px; margin-left: 4px; }
.acct-nav a {
    display: grid;
    place-items: center;
    width: 28px; height: 28px;
    border-radius: 50%;
    color: var(--cream-faint);
    font-size: .86rem;
    line-height: 1;
    box-shadow: inset 0 0 0 1px var(--edge-soft);
    transition: color .14s, box-shadow .14s;
}
.acct-nav a:hover { color: var(--cream); box-shadow: inset 0 0 0 1px var(--edge); }
.acct-nav a.on { color: var(--accent-bright); box-shadow: inset 0 0 0 1px var(--accent); }

main { padding: 8px 34px 60px; max-width: 1220px; }
/* Pages qui ont besoin d'air : l'inventaire (grille de 9 colonnes + panneau de détail)
   et la fiche d'artefact (3 colonnes). À 1220px les tuiles tombent sous les 90px. */
main.wide { max-width: 1680px; }

/* ══ Paliers de z-index ══
   Le reste de l'app ne dépasse pas 2 (.mat .pick). Au-dessus :
     50 — voile du tiroir de filtres (.fscrim)
     60 — tiroir lui-même (.fdrawer) */

/* ══ Titres ornementés ══ */
.page-title {
    display: flex;
    align-items: center;
    gap: 14px;
    margin: 10px 0 26px;
    font-size: 1.65rem;
    letter-spacing: .06em;
    color: var(--cream);
}
.page-title::before {
    content: "";
    width: 10px; height: 10px;
    border: 1px solid var(--accent);
    background: rgba(var(--accent-rgb), .25);
    transform: rotate(45deg);
    flex-shrink: 0;
}
.page-title::after {
    content: "";
    flex: 1;
    height: 1px;
    background: linear-gradient(90deg, var(--edge), transparent);
}
.page-title .count { color: var(--cream-faint); font-family: var(--font-body); font-size: 1rem; }

.section-title {
    display: flex;
    align-items: center;
    gap: 11px;
    margin: 36px 0 15px;
    font-size: 1.02rem;
    letter-spacing: .12em;
    color: var(--accent);
    text-transform: none;
}
.section-title::before {
    content: "";
    width: 7px; height: 7px;
    background: var(--accent);
    transform: rotate(45deg);
    flex-shrink: 0;
    opacity: .8;
}
/* Un contrôle placé dans un titre passe APRÈS le trait de séparation
   (::after est en flex:1 et remplit l'espace) : d'où l'order explicite. */
.section-title .seg, .page-title .seg { order: 9; flex-shrink: 0; }
.section-title::after {
    content: "";
    flex: 1;
    height: 1px;
    background: linear-gradient(90deg, var(--edge), transparent);
}
.section-title .faint { font-family: var(--font-body); font-size: .85rem; }

/* ══ Panneaux : double cadre + liseré doré ══ */
.panel {
    background: linear-gradient(165deg, var(--panel-2) 0%, var(--panel) 70%);
    border: 1px solid var(--edge);
    border-radius: 8px;
    padding: 20px;
    position: relative;
    box-shadow: 0 6px 24px rgba(0, 0, 0, .30);
}
.panel.accent::before {
    content: "";
    position: absolute;
    inset: 5px;
    border: 1px solid rgba(var(--accent-rgb), .16);
    border-radius: 5px;
    pointer-events: none;
}

.grid { display: grid; gap: 14px; }
.cols-2 { grid-template-columns: repeat(auto-fit, minmax(310px, 1fr)); }
.cols-3 { grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); }
.cols-4 { grid-template-columns: repeat(auto-fill, minmax(168px, 1fr)); }

/* ══ Tuile de statistique ══ */
.stat {
    background: linear-gradient(165deg, var(--panel-2) 0%, var(--panel) 70%);
    border: 1px solid var(--edge);
    border-radius: 8px;
    padding: 15px 18px;
    position: relative;
    overflow: hidden;
}
.stat::after {
    content: "";
    position: absolute;
    right: -22px; top: -22px;
    width: 58px; height: 58px;
    border: 1px solid rgba(211, 188, 142, .14);
    transform: rotate(45deg);
    pointer-events: none;
}
.stat .k {
    font-size: .7rem;
    text-transform: uppercase;
    letter-spacing: .15em;
    font-weight: 700;
    color: var(--cream-faint);
}
.stat .v {
    font-family: var(--font-display);
    font-size: 1.9rem;
    letter-spacing: .01em;
    font-variant-numeric: tabular-nums;
    margin-top: 4px;
    line-height: 1.12;
    color: var(--cream);
}
.stat .sub { font-size: .8rem; color: var(--cream-dim); margin-top: 3px; }
a.stat { display: block; transition: border-color .14s, transform .14s; }
a.stat:hover { border-color: var(--gold); transform: translateY(-2px); }

/* ══ Case d'inventaire (artefact / matériau / objet) ══
   Reprend la case du jeu : dégradé de rareté, art centré sur un halo,
   étoiles en bas de l'art, bandeau crème avec le niveau, coin bas-droit
   fortement arrondi. */
.cell {
    display: block;
    position: relative;
    background: linear-gradient(165deg, var(--panel-2) 0%, var(--panel) 70%);
    border: 1px solid var(--edge-soft);
    border-radius: 5px 5px 22px 5px;
    overflow: hidden;
    color: inherit;
    transition: transform .15s, box-shadow .15s, border-color .15s;
}
.cell:hover {
    transform: translateY(-3px);
    border-color: var(--gold);
    box-shadow: 0 0 0 1px rgba(211, 188, 142, .55), 0 10px 26px rgba(0, 0, 0, .5);
    color: inherit;
}

.cell-art {
    position: relative;
    height: 128px;
    display: flex;
    align-items: center;
    justify-content: center;
}
.r5 .cell-art { background: var(--g5); }
.r4 .cell-art { background: var(--g4); }
.r3 .cell-art { background: var(--g3); }
/* Halo lumineux derrière l'objet, comme la vitrine du jeu. */
.cell-art::before {
    content: "";
    position: absolute;
    inset: 0;
    background: radial-gradient(circle at 50% 42%, rgba(255, 236, 190, .30) 0%, transparent 58%);
    pointer-events: none;
}
.cell-art img {
    width: 82px;
    height: 82px;
    object-fit: contain;
    position: relative;
    filter: drop-shadow(0 4px 8px rgba(0, 0, 0, .45));
}
.cell-art img.ghost { filter: grayscale(1) brightness(2.1); opacity: .38; }
.cell-art .big { font-size: 2.6rem; line-height: 1; position: relative; filter: drop-shadow(0 4px 8px rgba(0,0,0,.45)); }
.cell-art img.big { width: 72%; height: 72%; object-fit: contain; }
/* Icône glissée dans une phrase, calée sur la hauteur du texte. */
.ico-inline { width: 1.15em; height: 1.15em; object-fit: contain; vertical-align: -.25em; }

.cell-stars {
    position: absolute;
    left: 7px; bottom: 3px;
    color: var(--star);
    font-size: .72rem;
    letter-spacing: .05em;
    text-shadow: 0 1px 2px rgba(0, 0, 0, .7);
}
.cell-score, .cell-qty {
    position: absolute;
    right: 6px; top: 6px;
    background: rgba(13, 16, 25, .78);
    color: var(--gold-bright);
    border-radius: 4px;
    padding: 1px 7px;
    font-size: .74rem;
    font-weight: 800;
    font-variant-numeric: tabular-nums;
}

/* Code couleur des paliers : le texte prend la teinte, le fond une trace de la même
   couleur pour rester lisible sur l'art de la pièce. */
.t-gris   { color: var(--t-gris);   border: 1px solid rgba(154, 160, 166, .45); }
.t-violet { color: var(--t-violet); border: 1px solid rgba(169, 112, 255, .5); }
.t-jaune  { color: var(--t-jaune);  border: 1px solid rgba(241, 196, 15, .5); }
.t-bleu   { color: var(--t-bleu);   border: 1px solid rgba(93, 200, 255, .55); }
.t-rouge  {
    color: var(--t-rouge);
    border: 1px solid rgba(255, 59, 48, .6);
    box-shadow: 0 0 10px rgba(255, 59, 48, .35);
}

/* Bandeau crème : niveau à gauche (comme le « +20 » du jeu). */
.cell-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    background: #e9e2d0;
    color: var(--ink);
    padding: 3px 10px;
    font-size: .8rem;
    font-weight: 800;
    font-variant-numeric: tabular-nums;
}
.cell-foot .foot-sub { font-weight: 700; font-size: .72rem; opacity: .75; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.cell-info { padding: 8px 11px 11px; }
.cell-name {
    font-size: .84rem;
    font-weight: 700;
    line-height: 1.3;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.cell-main { font-size: .76rem; color: var(--cream-dim); margin-top: 1px; }
.cell-set { font-size: .72rem; color: var(--set-green); margin-top: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ══ Fiche d'artefact (carte du jeu) ══ */
.acard {
    border: 1px solid var(--edge);
    border-radius: 8px 8px 26px 8px;
    overflow: hidden;
    box-shadow: 0 10px 34px rgba(0, 0, 0, .4);
}
.acard-head {
    position: relative;
    padding: 20px 155px 16px 22px;
    min-height: 158px;
}
.r5 .acard-head, .acard-head.r5 { background: var(--g5); }
.r4 .acard-head, .acard-head.r4 { background: var(--g4); }
.r3 .acard-head, .acard-head.r3 { background: var(--g3); }
.acard-head::before {
    content: "";
    position: absolute;
    inset: 0;
    background: radial-gradient(circle at 78% 45%, rgba(255, 236, 190, .30) 0%, transparent 55%);
    pointer-events: none;
}
.acard-head .art {
    position: absolute;
    right: 8px; top: 50%;
    transform: translateY(-50%);
    width: 140px; height: 140px;
    object-fit: contain;
    filter: drop-shadow(0 6px 14px rgba(0, 0, 0, .5));
}
.acard-head .art.ghost { filter: grayscale(1) brightness(2.1); opacity: .4; }
.acard-head .art-big { position: absolute; right: 30px; top: 50%; transform: translateY(-50%); font-size: 4.6rem; filter: drop-shadow(0 6px 14px rgba(0,0,0,.5)); }

.acard-name {
    margin: 0;
    font-family: var(--font-display);
    font-size: 1.35rem;
    letter-spacing: .02em;
    color: #fff8ea;
    text-shadow: 0 1px 3px rgba(0, 0, 0, .5);
}
.acard-slot {
    font-size: .74rem;
    text-transform: uppercase;
    letter-spacing: .14em;
    font-weight: 700;
    color: rgba(255, 248, 234, .75);
    margin-top: 2px;
}
.acard-maink { font-size: .78rem; color: rgba(255, 248, 234, .8); margin-top: 20px; }
.acard-mainv {
    font-family: var(--font-display);
    font-size: 1.9rem;
    line-height: 1.1;
    color: #fff8ea;
    text-shadow: 0 1px 3px rgba(0, 0, 0, .5);
}
.acard-stars { color: var(--star); font-size: .95rem; letter-spacing: .08em; margin-top: 8px; text-shadow: 0 1px 2px rgba(0,0,0,.6); }

.acard-body { background: linear-gradient(180deg, #1c2231 0%, #181d2a 100%); padding: 16px 20px 20px; }
.acard-lvl {
    display: inline-block;
    background: rgba(13, 16, 25, .82);
    color: var(--cream);
    border: 1px solid var(--edge);
    border-radius: 4px;
    padding: 2px 11px;
    font-size: .88rem;
    font-weight: 800;
    font-variant-numeric: tabular-nums;
    margin-bottom: 12px;
}

/* Bloc set : nom vert, bonus 2p/4p, provenance. */
.setblock { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--edge-soft); }
.setblock .setname { color: var(--set-green); font-weight: 800; font-size: .95rem; }
.setblock .bonus { display: flex; gap: 9px; font-size: .85rem; color: var(--cream-dim); margin-top: 6px; }
.setblock .bonus b { color: var(--set-green); font-weight: 800; flex-shrink: 0; }
.setblock .desc { font-size: .82rem; font-style: italic; color: var(--cream-faint); margin-top: 12px; line-height: 1.6; }
.domainline {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 13px;
    font-size: .82rem;
    color: var(--cream-dim);
    background: rgba(211, 188, 142, .07);
    border: 1px solid rgba(211, 188, 142, .18);
    border-radius: 6px;
    padding: 7px 12px;
}
.domainline .dot { color: var(--gold); }

.badge {
    display: inline-block;
    background: rgba(13, 16, 25, .72);
    border: 1px solid var(--edge);
    border-radius: 4px;
    padding: 2px 10px;
    font-size: .82rem;
    font-weight: 800;
    font-variant-numeric: tabular-nums;
}

.rule { height: 1px; background: var(--edge-soft); margin: 16px 0; }

/* ══ Sous-stats : puces ・ et losanges de rolls ══ */
.subs { list-style: none; padding: 0; margin: 0; }
.subs li {
    display: flex;
    align-items: baseline;
    gap: 9px;
    padding: 6px 0;
    font-size: .94rem;
    border-bottom: 1px solid rgba(236, 229, 216, .05);
}
.subs li:last-child { border-bottom: none; }
.subs li::before { content: "・"; color: var(--gold); }
.subs li.off { color: var(--cream-faint); }
.subs li.off::before { content: "🔒"; font-size: .68rem; }
.subs .val { font-weight: 800; margin-left: auto; font-variant-numeric: tabular-nums; }
.subs .rolls { color: rgba(211, 188, 142, .65); font-size: .62rem; letter-spacing: .18em; }

/* ══ Écran d'amélioration ══
   La mise en page vient désormais de .arti-page (shell à 3 colonnes) ; il ne
   reste ici que les éléments propres au renforcement. .enh-target est la cible
   des animations de fin d'amélioration, portée par la colonne centrale. */
.enh-target { position: sticky; top: 16px; }

.lvl-preview {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 14px;
    margin: 16px 0 12px;
    position: relative;
}

/* Animation jouée au retour d'une amélioration réussie. */
@keyframes enh-flash {
    0% { box-shadow: 0 6px 24px rgba(0, 0, 0, .30); }
    22% { box-shadow: 0 0 0 3px var(--gold-bright), 0 0 44px rgba(255, 215, 128, .55); }
    100% { box-shadow: 0 6px 24px rgba(0, 0, 0, .30); }
}
.enh-flash { animation: enh-flash 1.3s ease-out; }

@keyframes lvlup-float {
    0% { opacity: 0; transform: translate(-50%, 10px) scale(.7); }
    18% { opacity: 1; transform: translate(-50%, -8px) scale(1.12); }
    75% { opacity: 1; }
    100% { opacity: 0; transform: translate(-50%, -40px) scale(1); }
}
.lvlup-float {
    position: absolute;
    left: 50%;
    top: -16px;
    font-family: var(--font-display);
    font-size: 1.25rem;
    color: var(--gold-bright);
    text-shadow: 0 0 14px rgba(255, 215, 128, .8), 0 1px 3px rgba(0, 0, 0, .6);
    white-space: nowrap;
    pointer-events: none;
    animation: lvlup-float 2.2s ease-out forwards;
}

/* Sous-stat qui vient de gagner un roll : balayage doré + valeur qui scintille. */
@keyframes sub-up {
    0% { background: transparent; transform: translateX(0); }
    20% { background: rgba(255, 215, 128, .18); transform: translateX(5px); }
    70% { background: rgba(255, 215, 128, .10); }
    100% { background: transparent; transform: translateX(0); }
}
@keyframes sub-up-val {
    0%, 100% { color: inherit; text-shadow: none; }
    25% { color: var(--gold-bright); text-shadow: 0 0 12px rgba(255, 215, 128, .85); transform: scale(1.18); }
    70% { color: var(--gold-bright); }
}
.subs li.sub-up { animation: sub-up 2.2s ease-out .4s both; border-radius: 5px; }
.subs li.sub-up .val { animation: sub-up-val 2.2s ease-out .4s both; }

/* Sélection déjà au niveau max : les pièces restantes ne peuvent plus s'ajouter. */
.mat.locked { opacity: .4; cursor: not-allowed; }
.mat.locked:hover {
    transform: none;
    border-color: var(--edge-soft);
    box-shadow: none;
}
.lvl-preview .badge { font-size: 1.12rem; padding: 5px 16px; }
.lvl-preview .arrow { color: var(--gold); font-size: 1.15rem; }
.lvl-preview .lvl-to.up {
    border-color: var(--gold-bright);
    color: var(--gold-bright);
    box-shadow: 0 0 16px rgba(255, 215, 128, .28);
}

.enh-actions { display: flex; gap: 9px; flex-wrap: wrap; }

/* Sélection de matériaux : coche dorée par-dessus la case. */
.mat { cursor: pointer; user-select: none; position: relative; }
.mat .pick {
    position: absolute;
    inset: 0;
    display: none;
    align-items: center;
    justify-content: center;
    background: rgba(13, 16, 25, .55);
    color: var(--gold-bright);
    font-size: 2rem;
    font-weight: 800;
    z-index: 2;
    text-shadow: 0 2px 8px rgba(0, 0, 0, .8);
}
.mat.on { border-color: var(--gold-bright); box-shadow: 0 0 0 1px var(--gold-bright), 0 6px 20px rgba(0, 0, 0, .45); }
.mat.on .pick { display: flex; }
.mat.is-equipped .cell-art img { opacity: .8; }
.mat .warn { color: #e0b357; margin-top: 3px; font-size: .74rem; font-weight: 700; }

.mat-ctl { display: flex; align-items: center; gap: 6px; margin-top: 8px; }
.mat-ctl input { width: 100%; text-align: center; padding: 5px 4px; font-size: .86rem; }
.mat-ctl .step { padding: 4px 12px; font-size: .95rem; line-height: 1.1; border-radius: 6px; }

@media (max-width: 1150px) {
    .enh-target { position: static; }
}

/* ══ Personnages ══ */
.char-card {
    display: block;
    border: 1px solid var(--edge-soft);
    border-radius: 5px 5px 22px 5px;
    overflow: hidden;
    color: inherit;
    background: linear-gradient(165deg, var(--panel-2) 0%, var(--panel) 70%);
    transition: transform .15s, border-color .15s, box-shadow .15s;
}
.char-card:hover {
    transform: translateY(-3px);
    border-color: var(--gold);
    box-shadow: 0 0 0 1px rgba(211, 188, 142, .55), 0 10px 26px rgba(0, 0, 0, .5);
    color: inherit;
}
.char-head {
    position: relative;
    padding: 16px 16px 12px;
    display: flex;
    align-items: center;
    gap: 14px;
}
.char-head::before {
    content: "";
    position: absolute; inset: 0;
    background: radial-gradient(circle at 22% 45%, rgba(255, 236, 190, .25) 0%, transparent 55%);
    pointer-events: none;
}
.r5 .char-head { background: var(--g5); }
.r4 .char-head { background: var(--g4); }
/* Médaillon : initiale dans un losange, à défaut d'illustration. */
.char-mono {
    width: 52px; height: 52px;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: var(--font-display);
    font-size: 1.5rem;
    color: #fff8ea;
    background: rgba(13, 16, 25, .35);
    border: 1px solid rgba(255, 248, 234, .5);
    transform: rotate(45deg);
    border-radius: 8px;
    position: relative;
    text-shadow: 0 1px 3px rgba(0, 0, 0, .5);
}
.char-mono > span { transform: rotate(-45deg); }
.char-head .char-name {
    font-family: var(--font-display);
    font-size: 1.15rem;
    color: #fff8ea;
    text-shadow: 0 1px 3px rgba(0, 0, 0, .5);
    position: relative;
}
.char-head .char-stars { color: var(--star); font-size: .76rem; letter-spacing: .06em; text-shadow: 0 1px 2px rgba(0,0,0,.6); position: relative; }
.char-head .cons {
    margin-left: auto;
    position: relative;
    background: rgba(13, 16, 25, .6);
    color: var(--gold-bright);
    border-radius: 4px;
    padding: 2px 9px;
    font-size: .78rem;
    font-weight: 800;
}
.char-body { padding: 12px 16px 15px; }
.char-body .line { font-size: .84rem; color: var(--cream-dim); }
/* 5 losanges = 5 emplacements d'artefacts. */
.slot-pips { display: flex; gap: 7px; margin-top: 10px; }
.slot-pips i {
    width: 8px; height: 8px;
    transform: rotate(45deg);
    border: 1px solid var(--gold);
    background: transparent;
    opacity: .45;
}
.slot-pips i.on { background: var(--gold); opacity: 1; box-shadow: 0 0 6px rgba(211, 188, 142, .6); }

/* Slot d'équipement (page personnage) */
.equip-art {
    width: 76px; height: 76px;
    flex-shrink: 0;
    border-radius: 6px 6px 16px 6px;
    display: flex;
    align-items: center;
    justify-content: center;
    position: relative;
    overflow: hidden;
}
.equip-art.r5 { background: var(--g5); }
.equip-art.r4 { background: var(--g4); }
.equip-art.r3 { background: var(--g3); }
.equip-art.no-piece { background: rgba(13, 16, 25, .5); border: 1px dashed var(--edge); }
.equip-art img { width: 58px; height: 58px; object-fit: contain; filter: drop-shadow(0 3px 6px rgba(0,0,0,.45)); }
.equip-art img.ghost { filter: grayscale(1) brightness(2.1); opacity: .3; }

/* ══ Formulaires ══ */
.filters {
    display: flex;
    gap: 12px;
    flex-wrap: wrap;
    align-items: flex-end;
    background: rgba(19, 23, 37, .7);
    border: 1px solid var(--edge);
    border-radius: 8px;
    padding: 14px 16px;
    margin-bottom: 22px;
}
label {
    display: block;
    font-size: .68rem;
    text-transform: uppercase;
    letter-spacing: .13em;
    font-weight: 700;
    color: var(--cream-faint);
    margin-bottom: 5px;
}
select, input[type=number], input[type=text], input[type=email], input[type=password] {
    background: #141826;
    color: var(--cream);
    border: 1px solid var(--edge-soft);
    border-radius: 7px;
    padding: 8px 11px;
    font-size: .89rem;
    font-family: inherit;
    transition: border-color .14s;
}
select:focus, input:focus { outline: none; border-color: var(--gold); box-shadow: 0 0 0 2px rgba(211, 188, 142, .15); }

/* Boutons pilule ivoire, signature des menus du jeu. */
button, .btn {
    background: linear-gradient(180deg, #f3ecdd 0%, #e2dac6 100%);
    color: var(--ink);
    border: none;
    border-radius: 999px;
    padding: 9px 24px;
    font-size: .88rem;
    font-weight: 800;
    letter-spacing: .03em;
    font-family: inherit;
    cursor: pointer;
    display: inline-block;
    box-shadow: 0 2px 8px rgba(0, 0, 0, .35);
    transition: box-shadow .14s, transform .14s, filter .14s;
}
button:hover, .btn:hover {
    color: var(--ink);
    filter: brightness(1.04);
    box-shadow: 0 0 0 2px rgba(211, 188, 142, .5), 0 4px 14px rgba(0, 0, 0, .4);
    transform: translateY(-1px);
}
button.ghost, .btn.ghost {
    background: rgba(13, 16, 25, .5);
    color: var(--cream-dim);
    box-shadow: inset 0 0 0 1px var(--edge);
}
button.ghost:hover, .btn.ghost:hover { color: var(--cream); box-shadow: inset 0 0 0 1px var(--gold), 0 0 12px rgba(211, 188, 142, .18); }
button.danger {
    background: rgba(120, 40, 38, .35);
    color: #f0b3b1;
    box-shadow: inset 0 0 0 1px rgba(224, 108, 104, .5);
}
button.danger:hover { color: #ffd5d3; box-shadow: inset 0 0 0 1px var(--danger), 0 0 12px rgba(224, 108, 104, .25); }
button:disabled { opacity: .35; cursor: not-allowed; transform: none; }

form.inline { display: flex; gap: 10px; align-items: flex-end; flex-wrap: wrap; }

/* ══ Barre de progression dorée ══ */
.bar {
    background: rgba(13, 16, 25, .8);
    border: 1px solid var(--edge-soft);
    border-radius: 999px;
    height: 8px;
    overflow: hidden;
    margin-top: 7px;
}
.bar > span {
    display: block;
    height: 100%;
    border-radius: 999px;
    background: linear-gradient(90deg, #a8895a, var(--gold-bright));
    box-shadow: 0 0 8px rgba(255, 215, 128, .45);
    transition: width .3s ease;
}

/* ══ Alertes ══ */
.alert {
    padding: 11px 16px;
    border-radius: 7px;
    margin-bottom: 20px;
    font-size: .9rem;
    border: 1px solid;
}
.alert.ok { background: rgba(111, 191, 115, .09); border-color: rgba(111, 191, 115, .4); }
.alert.err { background: rgba(224, 108, 104, .09); border-color: rgba(224, 108, 104, .4); }

.empty {
    text-align: center;
    padding: 56px 20px;
    color: var(--cream-dim);
    background: rgba(19, 23, 37, .5);
    border: 1px dashed var(--edge);
    border-radius: 8px;
}

.muted { color: var(--cream-dim); }
.faint { color: var(--cream-faint); }
.small { font-size: .84rem; }
.gold { color: var(--gold-bright); }
.green { color: var(--set-green); }

code {
    background: #141826;
    border: 1px solid var(--edge-soft);
    padding: 1px 8px;
    border-radius: 5px;
    color: var(--gold-bright);
    font-size: .9em;
}

/* ══ Connexion ══ */
.login-page {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
}
.login-box { max-width: 440px; width: 100%; text-align: center; }
/* Emblème : étoile à quatre branches dans un losange, façon terminal Akasha du jeu. */
.login-box .mark {
    width: 74px; height: 74px;
    margin: 0 auto 22px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--gold);
    transform: rotate(45deg);
    border-radius: 12px;
    background: radial-gradient(circle, rgba(211, 188, 142, .14) 0%, transparent 70%);
    box-shadow: 0 0 30px rgba(211, 188, 142, .18);
}
.login-box .mark span {
    transform: rotate(-45deg);
    font-size: 2rem;
    color: var(--gold-bright);
    text-shadow: 0 0 14px rgba(255, 215, 128, .6);
}
.login-box h1 {
    font-family: var(--font-display);
    font-size: 2rem;
    letter-spacing: .22em;
    margin: 0 0 4px;
    color: var(--gold);
}
.login-box .tagline {
    font-size: .74rem;
    letter-spacing: .34em;
    text-transform: uppercase;
    color: var(--cream-faint);
    margin-bottom: 30px;
}
/* Code d'erreur des pages autonomes (404). Volontairement en creux : le chiffre
   situe l'incident, mais c'est le chemin de retour qui doit attirer l'oeil. */
.error-code {
    font-family: var(--font-display);
    font-size: 3.4rem;
    line-height: 1;
    letter-spacing: .1em;
    color: var(--cream-faint);
    opacity: .5;
    margin-bottom: 10px;
}
/* Champ étiqueté vertical. Le site n'avait jusqu'ici aucune saisie libre à
   mettre en page — que des cases, des listes et des nombres au fil du texte. */
.field {
    display: block;
    text-align: left;
    margin-bottom: 12px;
}
.field > span {
    display: block;
    font-size: .72rem;
    letter-spacing: .13em;
    text-transform: uppercase;
    color: var(--cream-faint);
    margin-bottom: 5px;
}
.field input {
    width: 100%;
    box-sizing: border-box;
}
.login-form button { width: 100%; margin-top: 4px; }

.btn-discord {
    background: linear-gradient(180deg, #6470f3 0%, #4a55cf 100%);
    color: #fff;
    padding: 12px 30px;
    font-size: .95rem;
    margin-top: 6px;
    box-shadow: 0 4px 16px rgba(88, 101, 242, .35);
}
.btn-discord:hover { color: #fff; box-shadow: 0 0 0 2px rgba(122, 132, 250, .6), 0 6px 20px rgba(88, 101, 242, .45); }

/* ══ Administration ══ */
.player-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 18px;
    flex-wrap: wrap;
    background: linear-gradient(165deg, var(--panel-2) 0%, var(--panel) 70%);
    border: 1px solid var(--edge-soft);
    border-radius: 8px;
    padding: 14px 18px;
    margin-bottom: 12px;
}
/* Les admins se repèrent d'un coup d'œil : cadre doré et fond chaud. */
.player-row.is-admin {
    border-color: var(--gold);
    background: linear-gradient(165deg, rgba(211, 188, 142, .10) 0%, var(--panel) 75%);
    box-shadow: 0 0 14px rgba(211, 188, 142, .10);
}
.player-row .who { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.player-row .pid {
    font-weight: 800;
    font-variant-numeric: tabular-nums;
    letter-spacing: .02em;
}
.admin-badge {
    background: rgba(211, 188, 142, .16);
    border: 1px solid var(--gold);
    color: var(--gold-bright);
    border-radius: 999px;
    padding: 1px 11px;
    font-size: .72rem;
    font-weight: 800;
    letter-spacing: .06em;
}

/* ══ Simulateur de voeux ══ */
.wish-layout {
    display: grid;
    grid-template-columns: 360px 1fr;
    gap: 20px;
    align-items: start;
}
.wish-results.busy { opacity: .5; }
.wish-results > * + * { margin-top: 14px; }

.stage-row {
    background: rgba(13, 16, 25, .4);
    border-radius: 8px;
    box-shadow: inset 0 0 0 1px var(--edge-soft);
    padding: 9px 11px;
    margin-bottom: 9px;
}
.stage-row .sr-top { display: flex; gap: 8px; align-items: center; }
.stage-row .sr-bot { display: flex; gap: 7px; align-items: center; margin-top: 7px; flex-wrap: wrap; }
.stage-row .st-name { flex: 1; min-width: 0; font-weight: 700; }
.stage-row .st-banner { flex: 1; min-width: 108px; }
.stage-row .st-start { width: 104px; }
.stage-row .st-count { width: 58px; text-align: center; }
.stage-row .st-range { white-space: nowrap; font-variant-numeric: tabular-nums; }
.stage-row .st-del { padding: 5px 11px; line-height: 1; }
/* Départ imposé : par une étape précédente du même nom, ou par la box. */
.stage-row .st-start:disabled { opacity: .45; cursor: not-allowed; }

/* Saisie de la cible : champ libre doublé d'une liste illustrée.
   Le champ RESTE libre — le référentiel a toujours un patch de retard sur le
   jeu, et un personnage qu'il ignore doit pouvoir se viser quand même. */
.stage-row .st-combo { position: relative; flex: 1; min-width: 0; display: flex; align-items: center; gap: 8px; }
.st-face {
    width: 30px;
    height: 30px;
    flex-shrink: 0;
    border-radius: 50%;
    overflow: hidden;
    background: var(--panel-2);
    box-shadow: inset 0 0 0 1px var(--edge);
}
.st-face img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Au-dessus du reste du plan : la liste déborde de sa ligne, et une étape
   suivante ne doit pas la recouvrir. */
.st-list {
    position: absolute;
    z-index: 30;
    top: calc(100% + 5px);
    left: 0;
    right: 0;
    max-height: 288px;
    overflow-y: auto;
    padding: 4px;
    background: var(--panel);
    border: 1px solid var(--edge);
    border-radius: 10px;
    box-shadow: 0 12px 28px rgba(0, 0, 0, .45);
}
.st-opt {
    display: flex;
    align-items: center;
    gap: 9px;
    width: 100%;
    padding: 5px 7px;
    border: 0;
    border-radius: 7px;
    background: none;
    color: var(--cream-dim);
    font: inherit;
    text-align: left;
    cursor: pointer;
}
.st-opt:hover { background: var(--panel-2); color: var(--cream); }
.st-opt img { width: 30px; height: 30px; flex-shrink: 0; border-radius: 50%; object-fit: cover; }
.st-opt.r5 img { background: var(--g5); }
.st-opt.r4 img { background: var(--g4); }
.st-opt > span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Palier déjà possédé : c'est la seule information qui distingue deux entrées
   par ailleurs identiques, elle prend donc la couleur d'accent. */
.st-opt em {
    flex-shrink: 0;
    font-style: normal;
    font-size: .76rem;
    font-weight: 800;
    color: var(--accent-bright);
    font-variant-numeric: tabular-nums;
}

.stage-row .st-boxlbl {
    display: flex;
    align-items: center;
    gap: 5px;
    white-space: nowrap;
    font-size: .8rem;
    color: var(--cream-dim);
    cursor: pointer;
}
.stage-row .st-boxlbl:has(:disabled) { opacity: .4; cursor: not-allowed; }
/* `display: flex` bat la règle [hidden] du navigateur : sans ça, masquer la
   case en JS n'aurait aucun effet. */
.stage-row .st-boxlbl[hidden] { display: none; }

/* Budget et déclencheur sur une seule ligne. */
.budget-row { display: flex; align-items: flex-end; gap: 10px; flex-wrap: wrap; }
.budget-row input[type=number] { width: 108px; }
.budget-row #status { padding-bottom: 9px; }

/* État de départ : une ligne par compteur de pity. */
.start-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 7px 10px;
    border-radius: 7px;
    background: rgba(13, 16, 25, .45);
    box-shadow: inset 0 0 0 1px var(--edge-soft);
    margin-bottom: 7px;
}
.start-row .sr-label { flex: 1; font-size: .84rem; font-weight: 700; white-space: nowrap; }
.start-row input[type=number] { width: 62px; text-align: center; padding: 5px 6px; }
.start-row .sr-fate { width: 52px; }
/* Compteurs repris du tracker : lisibles, mais visiblement hors de portée. */
#starts.locked .start-row { opacity: .62; }
#starts.locked input { cursor: not-allowed; }
.sr-check {
    display: flex;
    align-items: center;
    gap: 5px;
    margin: 0;
    text-transform: none;
    letter-spacing: .03em;
    font-size: .74rem;
    color: var(--cream-dim);
    white-space: nowrap;
    cursor: pointer;
}
.sr-check input { accent-color: var(--gold); }

/* ══ Tracker de voeux ══ */
/* Couleurs élémentaires, reprises de l'UI du jeu. */
.el-pyro   { --el: #ef7938; }
.el-hydro  { --el: #4cc2f1; }
.el-anemo  { --el: #6ecaa5; }
.el-electro{ --el: #b08fc4; }
.el-cryo   { --el: #99d9e8; }
.el-geo    { --el: #f2b723; }
.el-dendro { --el: #9bc93a; }

.wish-head { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; margin-bottom: 22px; }
.subnav { display: flex; gap: 4px; flex-wrap: wrap; }
.subnav a {
    padding: 6px 15px;
    border-radius: 999px;
    font-size: .82rem;
    font-weight: 700;
    color: var(--cream-dim);
    box-shadow: inset 0 0 0 1px var(--edge-soft);
}
.subnav a:hover { color: var(--cream); box-shadow: inset 0 0 0 1px var(--accent); }
.subnav a.on {
    background: rgba(var(--accent-rgb), .16);
    color: var(--accent-bright);
    box-shadow: inset 0 0 0 1px var(--accent);
}

/* Bandeau de totaux */
.totals {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    gap: 10px;
}
.totals > div {
    background: rgba(13, 16, 25, .45);
    box-shadow: inset 0 0 0 1px var(--edge-soft);
    border-radius: 8px;
    padding: 12px 15px;
}
.totals b {
    display: block;
    font-family: var(--font-display);
    font-size: 1.55rem;
    line-height: 1.1;
    font-variant-numeric: tabular-nums;
}
.totals span {
    font-size: .64rem;
    text-transform: uppercase;
    letter-spacing: .13em;
    color: var(--cream-faint);
}

/* Portrait : dégradé de rareté (l'élément n'est pas signalé, cf. _wish.html) */
.pf {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 62px; height: 62px;
    flex-shrink: 0;
    border-radius: 10px;
    overflow: hidden;
    box-shadow: inset 0 0 0 1px rgba(255, 248, 234, .18);
}
.pf.r5 { background: var(--g5); }
.pf.r4 { background: var(--g4); }
.pf.r3 { background: var(--g3); }
.pf img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pf i {
    font-family: var(--font-display);
    font-style: normal;
    font-size: 1.4rem;
    color: #fff8ea;
}
.pf.sm { width: 34px; height: 34px; border-radius: 8px; }
.pf.sm i { font-size: .9rem; }
.pf.xs { width: 26px; height: 26px; border-radius: 6px; }
.pf.xs i { font-size: .72rem; }

/* Carte de bannière */
.bstat { display: block; color: inherit; transition: transform .14s, box-shadow .14s; }
a.bstat:hover { color: inherit; transform: translateY(-2px); box-shadow: 0 0 0 1px var(--gold), 0 10px 26px rgba(0,0,0,.4); }
.bstat .bstat-head { display: flex; align-items: baseline; gap: 10px; }
.bstat .bstat-name { font-family: var(--font-display); font-size: 1.15rem; }
.bstat .bstat-head .faint { margin-left: auto; }
.bstat .bstat-pity { display: flex; align-items: baseline; gap: 8px; margin-top: 10px; }
.bstat .bstat-pity .v {
    font-family: var(--font-display);
    font-size: 2rem;
    line-height: 1;
    font-variant-numeric: tabular-nums;
    color: var(--gold-bright);
}
.bstat .bstat-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 8px;
    margin-top: 14px;
    text-align: center;
}
.bstat .bstat-grid b { display: block; font-size: 1.05rem; font-variant-numeric: tabular-nums; }
.bstat .bstat-grid span {
    font-size: .6rem;
    text-transform: uppercase;
    letter-spacing: .1em;
    color: var(--cream-faint);
}

/* Pastilles de 5★
   Grille et non flux libre : à largeur variable, les noms et les pity se
   décalaient d'une pastille à l'autre et il fallait relire chaque ligne. En
   colonnes fixes, le regard descend tout droit — le pity toujours au même
   endroit, le portrait toujours au même endroit. */
.fpills {
    display: grid;
    /* 248px : de quoi loger « Nocturne's Curtain Call » sans coupe. Au-delà,
       les noms plus longs cèdent à l'ellipse, le titre au survol les rend. */
    grid-template-columns: repeat(auto-fill, minmax(248px, 1fr));
    gap: 9px;
}
.fpill {
    display: flex;
    align-items: center;
    gap: 9px;
    min-width: 0;
    padding: 4px 10px 4px 4px;
    /* Concentrique avec le portrait : 8px de rayon + 4px de marge = 12px.
       En pastille pleinement arrondie, les angles de l'image mordaient la
       bordure au lieu de s'y loger. */
    border-radius: 12px;
    background: rgba(13, 16, 25, .5);
    box-shadow: inset 0 0 0 1px var(--edge-soft);
}
.fpill.won { box-shadow: inset 0 0 0 1px rgba(111, 191, 115, .55); }
.fpill.lost { box-shadow: inset 0 0 0 1px rgba(224, 108, 104, .55); }
/* Le nom cède la place en premier : le pity ne doit jamais être repoussé. */
.fpill .fp-name {
    flex: 1;
    min-width: 0;
    font-size: .82rem;
    font-weight: 700;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.fpill .fp-pity {
    flex-shrink: 0;
    min-width: 34px;
    text-align: center;
    font-size: .76rem;
    font-weight: 800;
    font-variant-numeric: tabular-nums;
    padding: 0 7px;
    border-radius: 999px;
}
/* Le pity se teinte par la chance : tôt = vert, pity dur = rouge. */
.fp-pity.vlucky { background: rgba(111, 191, 115, .22); color: #8fdc93; }
.fp-pity.lucky  { background: rgba(211, 188, 142, .22); color: var(--gold-bright); }
.fp-pity.meh    { background: rgba(224, 160, 90, .2); color: #e5b078; }
.fp-pity.bad    { background: rgba(224, 108, 104, .2); color: #f0b3b1; }

/* Collection */
.colgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 11px; }
.ccard {
    display: flex;
    align-items: center;
    gap: 11px;
    padding: 10px 12px;
    border-radius: 10px;
    color: inherit;
    background: linear-gradient(165deg, var(--panel-2) 0%, var(--panel) 70%);
    box-shadow: inset 0 0 0 1px var(--edge-soft);
    transition: transform .14s, box-shadow .14s;
}
.ccard:hover {
    color: inherit;
    transform: translateY(-2px);
    box-shadow: inset 0 0 0 1px var(--el, var(--gold)), 0 8px 20px rgba(0, 0, 0, .4);
}
.ccard .cc-body { min-width: 0; flex: 1; }
.ccard .cc-name {
    font-weight: 700;
    font-size: .88rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.ccard .cc-const { display: flex; align-items: baseline; gap: 7px; margin-top: 3px; flex-wrap: wrap; }
.ccard .cc-shown { font-family: var(--font-display); font-size: 1.15rem; line-height: 1; }
/* Mis en avant : l'information que le jeu ne donne pas. */
.ccard .cc-real {
    background: rgba(211, 188, 142, .2);
    color: var(--gold-bright);
    border-radius: 999px;
    padding: 1px 8px;
    font-size: .66rem;
    font-weight: 800;
    box-shadow: inset 0 0 0 1px var(--gold);
}
.ccard .cc-copies { font-size: .7rem; margin-top: 2px; }

/* ══ Facettes : des icônes qui se cumulent ══
   Éteintes au repos, allumées quand elles filtrent : l'état du filtre se lit sans
   rien déplier, et rien n'oblige à choisir une seule valeur. */
.facets { display: flex; flex-wrap: wrap; gap: 16px; margin-bottom: 12px; }
.facet-group {
    display: flex;
    gap: 4px;
    padding: 4px;
    border-radius: 999px;
    background: rgba(13, 16, 25, .45);
    box-shadow: inset 0 0 0 1px var(--edge-soft);
}
.facet {
    display: grid;
    place-items: center;
    width: 36px; height: 36px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: none;
    cursor: pointer;
    opacity: .42;
    transition: opacity .14s, background .14s, box-shadow .14s;
}
.facet img { width: 24px; height: 24px; object-fit: contain; display: block; }
.facet:hover { opacity: .8; background: rgba(236, 229, 216, .07); }
.facet.on {
    opacity: 1;
    background: rgba(var(--accent-rgb), .18);
    box-shadow: inset 0 0 0 1px var(--accent);
}
/* Une facette élémentaire allumée reprend la couleur de son élément. */
.facet.on[class*="el-"] {
    background: color-mix(in srgb, var(--el) 22%, transparent);
    box-shadow: inset 0 0 0 1px var(--el);
}
.facet-txt {
    width: auto;
    min-width: 42px;
    border-radius: 999px;
    color: var(--cream-dim);
    font-family: var(--font-body);
    font-size: .78rem;
    font-weight: 800;
}
.facet-txt.on { color: var(--accent-bright); }
.facet svg { width: 19px; height: 19px; }

/* Interrupteur à trois positions : deux valeurs qui s'excluent, et le neutre
   qui est l'absence des deux. Les moitiés se touchent pour se lire comme un
   seul contrôle — deux puces espacées se liraient comme deux cases à cocher,
   donc cumulables, ce qu'elles ne sont justement pas. */
.facet-group[data-switch] { gap: 0; }
.facet-group[data-switch] .facet-txt { padding: 0 14px; }

/* La recherche vit dans la même barre : un champ, pas un formulaire à part. */
.facet-search {
    align-self: stretch;
    min-width: 150px;
    padding: 0 16px;
    border-radius: 999px;
    font-size: .84rem;
}
#resetFilters { align-self: stretch; height: auto; }

/* ══ Roster : la vignette de personnage ══
   Reprend la tuile d'objet (.cell) — dégradé de rareté, halo, coin bas-droit
   arrondi, bandeau crème — mais le portrait couvre toute la vitrine au lieu d'y
   flotter : c'est ainsi que le jeu présente un personnage, et non un objet. */
.chgrid { align-items: start; }
.chcard .cell-art { height: 150px; }
.chcard .cell-art img {
    width: 100%; height: 100%;
    object-fit: cover;
    object-position: 50% 12%;   /* le buste, pas le menton */
    filter: none;
}
/* Fondu vers le bas : le bandeau crème doit accrocher le portrait, pas le trancher. */
.chcard .cell-art::after {
    content: "";
    position: absolute;
    inset: auto 0 0 0;
    height: 46%;
    background: linear-gradient(180deg, transparent, rgba(13, 16, 25, .55));
    pointer-events: none;
}
.chcard .cell-stars, .chcard .cell-qty { z-index: 1; }
/* Constellation : crème tant qu'elle n'est pas complète, or dès C6 — c'est le
   code du jeu, où seul le maximum se distingue. */
/* Classement Akasha, en vis-à-vis de la constellation : coin opposé, même
   gabarit. Plus le rang est haut, plus la pastille s'affirme. */
.top-chip {
    position: absolute;
    left: 6px; top: 6px;
    z-index: 1;
    background: rgba(13, 16, 25, .78);
    color: var(--cream-dim);
    border-radius: 4px;
    padding: 1px 6px;
    font-size: .62rem;
    font-weight: 800;
    letter-spacing: .02em;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
.top-chip.good { color: #8fdc93; box-shadow: 0 0 0 1px rgba(111, 191, 115, .5); }
.top-chip.elite {
    color: var(--gold-bright);
    box-shadow: 0 0 0 1px rgba(255, 215, 128, .6), 0 0 10px -2px rgba(255, 215, 128, .7);
}

.cons-badge { color: var(--cream); }
.cons-badge.maxed {
    color: var(--gold-bright);
    box-shadow: 0 0 0 1px rgba(255, 215, 128, .55), 0 0 10px -2px rgba(255, 215, 128, .7);
}

/* Intitulé d'un groupe de facettes, quand son sens ne va pas de soi. */
.facet-group.labeled { align-items: center; padding-left: 12px; }
.facet-label {
    font-size: .62rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: .13em;
    color: var(--cream-faint);
    margin-right: 4px;
    white-space: nowrap;
}
/* L'élément se lit sur le liseré au survol, jamais en pastille permanente. */
.chcard:hover { border-color: var(--el, var(--gold)); }
.chcard .cell-main { font-size: .72rem; margin-top: 2px; }

/* Les cinq emplacements, pièce par pièce. Le fond porte la rareté, le coin
   bas-droit le niveau : la même grammaire que les cases d'inventaire. */
.ch-slots { display: flex; gap: 5px; margin-top: 9px; }
.ch-slot {
    position: relative;
    width: 30px; height: 30px;
    flex-shrink: 0;
    border-radius: 5px 5px 9px 5px;
    overflow: hidden;
    box-shadow: inset 0 0 0 1px var(--edge-soft);
}
.ch-slot.r5 { background: var(--g5); }
.ch-slot.r4 { background: var(--g4); }
.ch-slot.r3 { background: var(--g3); }
.ch-slot img { width: 100%; height: 100%; object-fit: contain; display: block; }
.ch-slot.ch-void { background: rgba(13, 16, 25, .45); }
.ch-slot.ch-void img { opacity: .28; filter: grayscale(1) brightness(1.9); }
.ch-slot .ch-lvl {
    position: absolute;
    right: 0; bottom: 0;
    background: rgba(13, 16, 25, .82);
    color: var(--cream);
    font-style: normal;
    font-size: .52rem;
    font-weight: 800;
    line-height: 1;
    padding: 1px 3px;
    border-radius: 4px 0 0 0;
    font-variant-numeric: tabular-nums;
}

/* ══ Fiche de personnage ══
   Trois bandes empilées et pleine largeur — le bandeau, les cinq pièces, la
   barre de build — plutôt que deux colonnes inégales : c'est ce qui tient dans
   un écran sans défilement, et ce qui donne un rectangle plutôt qu'un escalier.

   Le bandeau prend l'illustration pour fond plutôt que de la ranger dans une
   vignette : le personnage occupe la moitié droite, les panneaux flottent sur
   la gauche, et le dégradé se teinte des couleurs de l'image (`--tint-a/b`,
   relevées par scripts/dl_splash.py). Sans teinte, la couleur de l'élément
   prend le relais ; sans élément, le fond du site. */
.hero {
    position: relative;
    overflow: hidden;
    min-height: clamp(300px, 40vh, 430px);
    border-radius: 8px 8px 22px 8px;
    border: 1px solid var(--edge-soft);
    background:
        radial-gradient(85% 115% at 76% 42%,
            color-mix(in srgb, var(--tint-a, var(--el, var(--panel-2))) 52%, transparent) 0%,
            transparent 68%),
        linear-gradient(102deg, var(--panel) 34%,
            color-mix(in srgb, var(--tint-b, var(--el, var(--panel-2))) 26%, var(--panel)) 100%);
}
/* L'onglet Progression n'a que la ligne d'identité à poser : le bandeau se
   réduit d'autant, sans quoi la saisie commencerait sous la ligne de flottaison. */
.hero.slim { min-height: 150px; }

.hero-art {
    position: absolute;
    inset: 0 0 0 auto;
    width: 64%;
    height: 100%;
    object-fit: cover;
    /* Le personnage est au centre de son illustration ; cadrer plus à GAUCHE le
       décale donc vers la droite, où il ne passe plus sous les panneaux. */
    object-position: 34% 26%;
    /* Fondu vers la gauche : l'illustration devient le fond des panneaux au lieu
       de s'arrêter net sur une arête verticale. */
    -webkit-mask-image: linear-gradient(90deg, transparent 0%, #000 46%);
    mask-image: linear-gradient(90deg, transparent 0%, #000 46%);
}
/* Faute de splash art, le portrait carré se cale sur le buste et reste petit :
   étiré sur 64 % de largeur, il ne serait plus qu'une tache. */
.hero-art.portrait { width: 34%; object-position: 50% 12%; }

.hero-body { position: relative; padding: 13px 15px; max-width: 61%; }
@media (max-width: 1100px) { .hero-body { max-width: none; } }

/* Ligne d'identité : ce que portait le bandeau crème de la vignette, à plat. */
.hero-id { display: flex; align-items: center; flex-wrap: wrap; gap: 9px; margin-bottom: 11px; }
.hero-lvl { font-family: var(--font-display); font-size: 1.15rem; line-height: 1; }
.hero-stars { color: var(--star); font-size: .78rem; letter-spacing: .04em; }
.hero-id .top-badge { position: static; }

/* Les panneaux posés sur l'illustration : assez opaques pour rester lisibles,
   assez transparents pour qu'on voie sur quoi ils flottent. */
.hero .panel {
    background: rgba(11, 14, 22, .58);
    -webkit-backdrop-filter: blur(7px);
    backdrop-filter: blur(7px);
    border-color: rgba(236, 229, 216, .09);
}

/* Attributs : une seule surface, et dedans rien que de la typographie —
   libellé discret au-dessus, valeur en grand dessous. Encadrer chaque stat en
   faisait huit petits objets à parcourir un par un ; à plat, la grille se lit
   d'un balayage. */
.hero .statbox { grid-template-columns: repeat(4, minmax(0, 1fr)); row-gap: 4px; column-gap: 18px; }
@media (max-width: 1500px) { .hero .statbox { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 1100px) { .hero .statbox { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 700px) { .hero .statbox { grid-template-columns: 1fr; } }
.hero .statline {
    display: block;
    background: none;
    border: 0;
    border-radius: 0;
    padding: 7px 0;
    margin: 0;
}
.hero .statline span {
    display: block;
    font-size: .72rem;
    line-height: 1.2;
    color: var(--cream-faint);
}
.hero .statline b {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 1px;
    font-size: 1.16rem;
    font-weight: 700;
}
/* Le Crit Value n'est pas une stat du jeu mais un jugement porté dessus : il se
   détache sous la grille, sur toute la largeur. */
.hero .statline.cv {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    margin-top: 6px;
    padding-top: 9px;
    border-top: 1px solid rgba(236, 229, 216, .1);
}

/* Anneau du taux CRIT : la seule stat bornée à 100 %, donc la seule qu'on
   puisse montrer comme une proportion plutôt que comme un nombre. */
.statring {
    width: 21px;
    height: 21px;
    flex-shrink: 0;
    border-radius: 50%;
    background: conic-gradient(var(--accent) calc(var(--pct, 0) * 1%),
                               rgba(236, 229, 216, .14) 0);
    -webkit-mask: radial-gradient(circle, transparent 54%, #000 56%);
    mask: radial-gradient(circle, transparent 54%, #000 56%);
}

/* Aptitudes couronnées : le bandeau s'ourle d'or, comme la vignette du roster. */
.hero.crown-1 { border-color: rgba(255, 215, 128, .32); }
.hero.crown-2 { border-color: rgba(255, 215, 128, .55); }
.hero.crown-3 {
    border-color: var(--gold-bright);
    box-shadow: 0 0 30px -8px rgba(255, 215, 128, .55);
}

/* Aptitudes couronnées : le portrait rayonne d'autant plus qu'il y en a. */
.chcard.crown-1 { box-shadow: 0 0 0 1px rgba(255, 215, 128, .35), 0 0 18px -4px rgba(255, 215, 128, .35); }
.chcard.crown-2 { box-shadow: 0 0 0 1px rgba(255, 215, 128, .55), 0 0 26px -3px rgba(255, 215, 128, .5); }
.chcard.crown-3 { box-shadow: 0 0 0 1px var(--gold-bright), 0 0 34px -2px rgba(255, 215, 128, .7); }
.chcard.crown-3 .cell-art::before { background: radial-gradient(circle at 50% 42%, rgba(255, 236, 190, .5) 0%, transparent 62%); }

/* Barre de build : source, photos et bouton de photo sur une seule ligne, en
   pied de page. Un panneau vertical pour ces trois contrôles mangeait la colonne
   de gauche et repoussait les artéfacts sous la ligne de flottaison. */
.buildbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px 16px;
    margin-top: 12px;
    padding: 9px 14px;
}
.buildbar .preset-chips { flex: 1; margin: 0; }
.buildbar .tr-check { margin: 0; white-space: nowrap; }
.buildbar form.inline { align-items: center; gap: 8px; }
.buildbar input[type="text"] { min-width: 150px; }

/* Le seul chiffre qu'Akasha apporte et qu'on ne peut pas saisir soi-même. */
.top-badge {
    position: absolute;
    left: 7px; top: 7px;
    z-index: 1;
    background: rgba(13, 16, 25, .82);
    color: var(--gold-bright);
    box-shadow: inset 0 0 0 1px var(--gold);
    border-radius: 4px;
    padding: 2px 8px;
    font-size: .7rem;
    font-weight: 800;
    letter-spacing: .06em;
}

/* Presets : une puce par configuration, la croix supprime. */
.preset-chips { display: flex; flex-wrap: wrap; gap: 6px; margin: 10px 0; }
.pchip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 3px 6px 3px 11px;
    border-radius: 999px;
    background: rgba(13, 16, 25, .5);
    box-shadow: inset 0 0 0 1px var(--edge-soft);
    font-size: .76rem;
    font-weight: 700;
}
.pchip.on { box-shadow: inset 0 0 0 1px var(--accent); color: var(--accent-bright); }
.pchip form { display: inline; }
.pchip-x {
    background: none;
    border: 0;
    padding: 0 3px;
    color: var(--cream-faint);
    cursor: pointer;
    font-size: .9rem;
    line-height: 1;
}
.pchip-x:hover { color: var(--danger); }

/* Carte d'arme */
.wpn { display: flex; gap: 12px; align-items: center; padding: 11px 13px; }
/* Le fond suit la rareté de l'arme, comme les cases d'inventaire. */
.wpn-icon { width: 72px; height: 72px; object-fit: contain; flex-shrink: 0; border-radius: 6px; background: var(--g3); }
.wpn-icon.r5 { background: var(--g5); }
.wpn-icon.r4 { background: var(--g4); }
.wpn-icon.ghost { opacity: .3; filter: grayscale(1); background: none; }
.wpn-body { min-width: 0; flex: 1; }
.wpn-name { font-family: var(--font-display); font-size: 1.1rem; line-height: 1.2; }
.wpn-stars { color: var(--star); font-size: .74rem; letter-spacing: .04em; }
.wpn-tags { display: flex; gap: 6px; margin-top: 5px; }
.tag {
    background: rgba(var(--accent-rgb), .16);
    box-shadow: inset 0 0 0 1px rgba(var(--accent-rgb), .4);
    color: var(--accent-bright);
    border-radius: 4px;
    padding: 1px 8px;
    font-size: .7rem;
    font-weight: 800;
}
.wpn-stats { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 7px; font-size: .78rem; color: var(--cream-dim); }
.wpn-stats b { color: var(--cream); font-variant-numeric: tabular-nums; }

/* Panneau d'attributs : une ligne par stat, valeur à droite — comme en jeu, mais
   sur plusieurs colonnes. Une colonne unique faisait une bande de 400 px de haut
   à côté d'une vitrine deux fois plus courte. */
.statbox {
    margin-top: 10px;
    padding: 4px 16px 10px;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    column-gap: 26px;
}
/* Le total et l'avertissement valent pour tout le panneau, pas pour une colonne. */
.statbox .statline.cv, .statbox .statnote, .statbox > .faint { grid-column: 1 / -1; }
.statline {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 7px 0;
    font-size: .84rem;
    border-bottom: 1px solid var(--edge-soft);
}
.statline:last-child { border-bottom: 0; }
.statline span { color: var(--cream-dim); }
.statline b { font-variant-numeric: tabular-nums; font-size: .95rem; }
.statline.cv b { color: var(--gold-bright); }
/* Le panneau calculé annonce ce qu'il ne compte pas : sans cette ligne, l'ATQ
   se lirait comme la valeur du jeu, arme comprise. */
.statnote { display: block; padding: 8px 0 4px; line-height: 1.35; }

/* Carte d'artéfact */
.artc {
    border-radius: 8px;
    padding: 10px 12px;
    background: linear-gradient(165deg, var(--panel-2) 0%, var(--panel) 70%);
    box-shadow: inset 0 0 0 1px var(--edge-soft);
}
.artc.r5 { box-shadow: inset 0 0 0 1px rgba(207, 143, 62, .5); }
.artc.empty-slot { opacity: .55; }
/* En-tête : la vitrine de l'icône à gauche, la stat principale à droite. */
.artc-head { display: flex; align-items: center; gap: 12px; }
/* La fiche de personnage réutilise cette carte sans vitrine : son icône reste
   une image simple, qu'il faut donc continuer de dimensionner. */
.artc-head > img { width: 46px; height: 46px; object-fit: contain; flex-shrink: 0; }
.artc-head > img.ghost { opacity: .35; filter: grayscale(1) brightness(1.9); }

/* Vitrine de l'icône : même grammaire que les cases d'inventaire du jeu —
   dégradé de rareté, halo, coin bas-droit arrondi. */
.artc-vis {
    position: relative;
    width: 78px; height: 78px;
    flex-shrink: 0;
    border-radius: 7px 7px 18px 7px;
    overflow: hidden;
    display: block;
}
.artc.r5 .artc-vis { background: var(--g5); }
.artc.r4 .artc-vis { background: var(--g4); }
.artc.r3 .artc-vis { background: var(--g3); }
.artc-vis::before {
    content: "";
    position: absolute;
    inset: 0;
    background: radial-gradient(circle at 50% 40%, rgba(255, 236, 190, .28) 0%, transparent 62%);
    pointer-events: none;
}
.artc-vis > img {
    position: relative;
    width: 100%; height: 100%;
    object-fit: contain;
    display: block;
    filter: drop-shadow(0 3px 6px rgba(0, 0, 0, .45));
}
.artc-vis > img.ghost { opacity: .3; filter: grayscale(1) brightness(1.9); }

/* Le niveau : incrusté sur la vitrine quand il y en a une, simple pastille
   dans la ligne de titre sinon (fiche de personnage). */
.artc-lvl {
    background: rgba(13, 16, 25, .82);
    border-radius: 4px;
    padding: 1px 6px;
    font-style: normal;
    font-size: .7rem;
    font-weight: 800;
    color: var(--gold-bright);
    font-variant-numeric: tabular-nums;
}
.artc-vis .artc-lvl { position: absolute; left: 3px; top: 3px; padding: 0 5px; font-size: .66rem; }

/* Tête du porteur : dire où est la pièce sans avoir à lire un nom. */
.artc-face {
    position: absolute;
    right: 2px; bottom: 2px;
    width: 26px; height: 26px;
    border-radius: 50%;
    overflow: hidden;
    background: #10131c;
    box-shadow: 0 0 0 1.5px var(--gold-bright), 0 2px 6px rgba(0, 0, 0, .5);
    display: flex;
    align-items: center;
    justify-content: center;
}
.artc-face img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 18%; }
.artc-face em {
    font-style: normal;
    font-size: .68rem;
    font-weight: 800;
    color: var(--gold-bright);
}

.artc-main { flex: 1; min-width: 0; }
.artc-main b {
    display: block;
    font-size: 1.35rem;
    line-height: 1.1;
    font-variant-numeric: tabular-nums;
    word-break: break-word;
}
.artc-main span {
    display: block;
    margin-top: 2px;
    font-size: .64rem;
    text-transform: uppercase;
    letter-spacing: .1em;
    color: var(--cream-faint);
}

/* Les quatre sous-stats en 2×2, jamais en liste : c'est la grille du jeu. */
.artc-subs { display: grid; grid-template-columns: 1fr 1fr; gap: 4px 12px; margin-top: 10px; }
/* Enfants DIRECTS seulement : une ligne de sous-stat peut contenir ses propres
   spans — les points de rolls de la fiche de personnage — et l'écartement d'une
   ligne n'a rien à faire à l'intérieur d'eux. */
.artc-subs > span {
    display: flex;
    justify-content: space-between;
    gap: 6px;
    font-size: .78rem;
    font-variant-numeric: tabular-nums;
}
.artc-subs i { font-style: normal; color: var(--cream-faint); }
.artc-set { margin-top: 7px; font-size: .7rem; color: var(--set-green); }

/* ══ Les cinq emplacements en rangée, sur la fiche de personnage ══
   Cinq colonnes égales, et des cartes qui se terminent toutes à la même hauteur :
   le bouton d'équipement se cale en bas quel que soit le nombre de sous-stats. */
.artrow { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 10px; margin-top: 14px; }
@media (max-width: 1240px) { .artrow { grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); } }

/* Carte centrée, par ordre d'importance : l'emplacement en icône, la stat
   principale en grand, les sous-stats en pastilles, le set en pied. */
.artrow .artc {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    padding: 13px 11px 11px;
}
.artc-top { position: relative; }
.artc-top img { display: block; width: 44px; height: 44px; object-fit: contain; }
.artc-top img.ghost { opacity: .3; filter: grayscale(1) brightness(1.9); }
.artc-top .artc-lvl { position: absolute; right: -14px; bottom: 0; font-size: .62rem; padding: 0 5px; }
.artc-val {
    margin-top: 7px;
    font-size: 1.5rem;
    line-height: 1.1;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}
.artc-name {
    margin-top: 1px;
    font-size: .64rem;
    text-transform: uppercase;
    letter-spacing: .1em;
    color: var(--cream-faint);
}
/* Sous-stats en pastilles, deux par deux : quatre lignes empilées feraient une
   carte deux fois plus haute pour la même information.

   `nowrap` n'est pas un détail : cinq cartes sur un écran de portable donnent des
   pastilles de 90 px, où « DGT 31.9 % » se coupait en deux étages et faisait
   grandir toute la rangée. Le texte reste donc d'un bloc, et c'est le contenu
   qu'on a raccourci pour qu'il tienne. */
.artrow .artc-subs { width: 100%; margin-top: 11px; gap: 5px 6px; }
/* Trois colonnes de largeur FIXE — nom, valeur, rolls — et non un simple flux :
   les quatre pastilles d'une carte se lisent alors comme un petit tableau, les
   noms sous les noms et les chiffres sous les chiffres. En flux, chaque pastille
   se recalait sur son propre contenu et rien ne s'alignait. */
.artrow .artc-subs .sub {
    display: grid;
    grid-template-columns: 2.4rem minmax(0, 1fr) 1.5rem;
    align-items: baseline;
    gap: 4px;
    min-width: 0;
    padding: 3px 6px;
    border-radius: 5px;
    background: rgba(13, 16, 25, .5);
    box-shadow: inset 0 0 0 1px var(--edge-soft);
    font-size: .69rem;
    text-align: right;
    white-space: nowrap;
}
.artrow .artc-subs .sub b { text-align: left; font-weight: 700; color: var(--cream-faint); }

/* Les rolls, dits en points : un par jet, teinté de sa qualité. Le compte se voit
   sans se lire — quatre points valent une pièce bien tombée — et le détail chiffré
   reste dans l'infobulle pour qui le cherche. */
/* Les points se tassent à droite de leur colonne : une ligne à six rolls et une
   à un seul finissent alors sur la même verticale. */
.rolls { display: flex; align-self: center; justify-content: flex-end; flex-shrink: 0; gap: 1.5px; }
.rolls span { width: 3px; height: 3px; border-radius: 50%; background: rgba(236, 229, 216, .3); }
.rolls .q80 { background: rgba(236, 229, 216, .48); }
.rolls .q90 { background: rgba(211, 188, 142, .8); }
.rolls .q100 { background: var(--gold-bright); }

.artrow .artc-foot { margin-top: 9px; justify-content: center; gap: 8px; }
.artrow .artc-actions { margin-top: auto; padding-top: 10px; width: 100%; }

/* ══ Filtre en panneau : trop de valeurs pour une rangée de chips ══ */
/* Le déclencheur vit dans la même pilule que les autres groupes : sans ce
   contenant il flottait nu dans la barre, en décalage avec tout le reste. */
.popfilter {
    position: relative;
    display: flex;
    padding: 4px;
    border-radius: 999px;
    background: rgba(13, 16, 25, .45);
    box-shadow: inset 0 0 0 1px var(--edge-soft);
}
.popfilter .pop-btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 0 14px;
    /* Ouvrir un menu n'est pas une valeur sélectionnée : le bouton reste lisible. */
    opacity: 1;
    color: var(--cream-dim);
}
.popfilter .pop-btn:hover { color: var(--cream); }
.popfilter.open .pop-btn { color: var(--cream); background: rgba(236, 229, 216, .07); }
.popfilter.active .pop-btn {
    background: rgba(211, 188, 142, .16);
    color: var(--gold-bright);
    box-shadow: inset 0 0 0 1px var(--gold);
}
.popfilter .pop-n {
    font-style: normal;
    font-size: .64rem;
    font-variant-numeric: tabular-nums;
}
.popfilter .pop-n:empty { display: none; }

.pop-panel {
    display: none;
    position: absolute;
    z-index: 40;
    top: calc(100% + 6px);
    left: 0;
    width: 290px;
    max-height: 340px;
    overflow: hidden;
    padding: 8px;
    border-radius: 10px;
    background: #171b28;
    box-shadow: inset 0 0 0 1px var(--edge), 0 16px 38px rgba(0, 0, 0, .55);
}
.popfilter.open .pop-panel { display: flex; flex-direction: column; }
.pop-panel .pop-q {
    width: 100%;
    margin-bottom: 7px;
    padding: 5px 11px;
    border-radius: 999px;
    font-size: .76rem;
    flex-shrink: 0;
}
.pop-list { display: block; overflow-y: auto; }
.pop-item {
    display: flex;
    align-items: center;
    gap: 9px;
    width: 100%;
    text-align: left;
    padding: 5px 9px;
    border-radius: 6px;
    background: none;
    box-shadow: none;
    color: var(--cream-dim);
    font-size: .76rem;
    font-weight: 600;
    letter-spacing: 0;
}
.pop-item span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pop-item i {
    font-style: normal;
    font-size: .68rem;
    color: var(--cream-faint);
    font-variant-numeric: tabular-nums;
}
.pop-item:hover { background: rgba(236, 229, 216, .07); color: var(--cream); box-shadow: none; transform: none; }
.pop-item[aria-pressed="true"] {
    background: rgba(211, 188, 142, .16);
    color: var(--gold-bright);
    box-shadow: inset 0 0 0 1px var(--gold);
}
.pop-item[aria-pressed="true"] i { color: var(--gold); }

/* ══ Coffre d'artéfacts réels ══ */
.artgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 11px; }
.artc-foot {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 12px;
    margin-top: 11px;
    padding-top: 10px;
    border-top: 1px solid var(--edge-soft);
}
/* Les deux scores se lisent d'un coup d'œil : pastilles arrondies, teinte du
   palier sur le texte et un fond discret de la même couleur — pas de cadre plein
   qui écraserait le reste de la carte. */
.artc-scores { display: flex; gap: 8px; flex-shrink: 0; }
.artc-scores b {
    display: inline-flex;
    align-items: baseline;
    gap: 4px;
    /* Les classes .t-* apportent un cadre carré : la pastille s'en passe. */
    border: 0;
    padding: 3px 11px;
    border-radius: 999px;
    background: currentColor;
    font-size: .74rem;
    font-variant-numeric: tabular-nums;
    line-height: 1.25;
}
/* Le fond hérite de la teinte via currentColor ; le texte la reprend en clair
   par-dessus, ce qui garde le contraste sur les cinq paliers. */
.artc-scores b > span { color: var(--panel); font-weight: 800; }
.artc-scores b > i { color: var(--panel); font-style: normal; opacity: .72; font-size: .66rem; }
.artc-actions { display: flex; align-items: center; gap: 8px; margin-top: 8px; }

/* ══ Menu d'équipement : boîte modale filtrable ══
   Comparer des artéfacts demande de voir leurs sous-stats côte à côte : une
   liste déroulante ne peut ni les afficher, ni se filtrer. */
.artc-actions .pick-open { width: 100%; padding: 5px 12px; font-size: .76rem; border-radius: 999px; }
.artc-actions .pick-open i { font-style: normal; margin-left: 6px; font-variant-numeric: tabular-nums; }

.pickdlg {
    width: min(920px, 94vw);
    max-height: 86vh;
    padding: 0;
    border: none;
    border-radius: 12px;
    background: linear-gradient(170deg, #1c2131 0%, #161a26 100%);
    color: var(--cream);
    box-shadow: inset 0 0 0 1px var(--edge), 0 30px 70px rgba(0, 0, 0, .6);
    overflow: hidden;
}
.pickdlg::backdrop { background: rgba(8, 10, 16, .72); backdrop-filter: blur(2px); }
.pickdlg > form { display: flex; flex-direction: column; max-height: 86vh; }

.pick-head {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 14px 16px;
    border-bottom: 1px solid var(--edge-soft);
}
.pick-head > div { flex: 1; display: flex; align-items: baseline; gap: 9px; }
.pick-head b { font-family: var(--font-display); font-size: 1.15rem; font-weight: 400; }
.pick-head .ghost { padding: 4px 12px; font-size: .76rem; border-radius: 999px; }
.pick-remove { color: #f0b3b1 !important; box-shadow: inset 0 0 0 1px rgba(224, 108, 104, .4) !important; }

.pick-filters {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    padding: 11px 16px;
    border-bottom: 1px solid var(--edge-soft);
    background: rgba(13, 16, 25, .35);
}
.pick-filters .pick-q {
    flex: 1;
    min-width: 170px;
    padding: 6px 12px;
    border-radius: 999px;
    font-size: .8rem;
}
.pick-chips { display: flex; gap: 4px; flex-wrap: wrap; }
.pick-chips .facet-txt { padding: 3px 11px; font-size: .72rem; }
.pick-toggle {
    display: flex;
    align-items: center;
    gap: 6px;
    margin: 0;
    text-transform: none;
    letter-spacing: .02em;
    font-size: .74rem;
    color: var(--cream-dim);
    cursor: pointer;
    white-space: nowrap;
}
.pick-toggle input { accent-color: var(--gold); }

.pick-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
    gap: 8px;
    padding: 14px 16px 18px;
    overflow-y: auto;
}
.pick-card {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    text-align: left;
    padding: 9px 11px;
    border-radius: 9px;
    background: linear-gradient(165deg, var(--panel-2) 0%, var(--panel) 70%);
    box-shadow: inset 0 0 0 1px var(--edge-soft);
    color: var(--cream);
    font-weight: 400;
    letter-spacing: 0;
    transition: box-shadow .14s, transform .14s;
}
.pick-card:hover { color: var(--cream); transform: translateY(-2px); box-shadow: inset 0 0 0 1px var(--gold), 0 8px 20px rgba(0, 0, 0, .4); }
.pick-card.on { box-shadow: inset 0 0 0 1px var(--gold-bright), 0 0 16px -4px rgba(255, 215, 128, .5); }
.pick-card.blocked { opacity: .42; cursor: not-allowed; }
.pick-card.blocked:hover { transform: none; box-shadow: inset 0 0 0 1px var(--edge-soft); }

.pick-card .pc-art {
    position: relative;
    width: 46px; height: 46px;
    flex-shrink: 0;
    border-radius: 6px 6px 12px 6px;
    overflow: hidden;
}
.pick-card.r5 .pc-art { background: var(--g5); }
.pick-card.r4 .pc-art { background: var(--g4); }
.pick-card.r3 .pc-art { background: var(--g3); }
.pick-card .pc-art img { width: 100%; height: 100%; object-fit: contain; display: block; }
.pick-card .pc-lvl {
    position: absolute;
    right: 0; bottom: 0;
    background: rgba(13, 16, 25, .82);
    font-style: normal;
    font-size: .56rem;
    font-weight: 800;
    padding: 1px 4px;
    border-radius: 4px 0 0 0;
}
.pick-card .pc-body { min-width: 0; flex: 1; display: block; }
.pick-card .pc-top { display: flex; align-items: center; gap: 8px; }
.pick-card .pc-top b { font-size: .84rem; font-weight: 800; }
.pick-card .pc-score {
    margin-left: auto;
    font-style: normal;
    font-size: .72rem;
    font-weight: 800;
    font-variant-numeric: tabular-nums;
}
.pick-card .pc-set {
    display: block;
    font-size: .7rem;
    color: var(--set-green);
    margin-top: 1px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.pick-card .pc-subs { display: flex; flex-wrap: wrap; gap: 3px 9px; margin-top: 5px; }
.pick-card .pc-subs em { font-style: normal; font-size: .67rem; color: var(--cream-faint); }
.pick-card .pc-subs b { color: var(--cream-dim); font-weight: 700; margin-left: 2px; }
.pick-card .pc-blocked {
    display: block;
    margin-top: 5px;
    font-size: .66rem;
    color: #e0b357;
}
.pick-none { padding: 30px 16px 36px; text-align: center; color: var(--cream-faint); font-size: .82rem; }
/* Pièce figée : lisible mais visiblement hors de portée. */
.artc.locked { box-shadow: inset 0 0 0 1px rgba(127, 178, 229, .45); }
.artc-lock { font-size: .8rem; margin-left: 4px; }


/* ══ Éditeur d'artéfact ══ */
.editor-cols { display: grid; grid-template-columns: minmax(0, 380px) minmax(0, 1fr); gap: 14px; align-items: start; }
@media (max-width: 1080px) { .editor-cols { grid-template-columns: 1fr; } }

/* Le scan est une porte d'entrée, pas une section : une seule ligne au-dessus du
   formulaire, qui ne prétend pas au même poids visuel que la saisie elle-même. */
.scanbox { margin-bottom: 14px; padding: 12px 14px; }
.scan-pick { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.scan-pick > label { margin: 0; white-space: nowrap; }
.scan-pick input[type=file] {
    flex: 1;
    min-width: 190px;
    color: var(--cream-dim);
    font-size: .82rem;
}
.scan-pick input[type=file]::file-selector-button {
    margin-right: 10px;
    padding: 6px 12px;
    border: 0;
    border-radius: 999px;
    background: rgba(var(--accent-rgb), .16);
    box-shadow: inset 0 0 0 1px rgba(var(--accent-rgb), .35);
    color: var(--accent-bright);
    font: inherit;
    font-size: .8rem;
    cursor: pointer;
}
.scan-pick > .small { flex-basis: 100%; }

/* Pendant la lecture, l'attente REMPLACE les contrôles : les laisser visibles
   invite à recliquer, et un second envoi doublerait le travail pour rien. */
.scanbox.busy .scan-pick { display: none; }
.scan-busy { display: flex; align-items: center; gap: 12px; }
.scan-thumb {
    width: 104px;
    height: 58px;
    object-fit: cover;
    border-radius: 6px;
    box-shadow: inset 0 0 0 1px var(--edge-soft);
    background: rgba(13, 16, 25, .45);
}
.scan-spin {
    width: 16px;
    height: 16px;
    flex-shrink: 0;
    border-radius: 50%;
    border: 2px solid rgba(var(--accent-rgb), .25);
    border-top-color: var(--accent-bright);
    animation: scan-spin .7s linear infinite;
}
@keyframes scan-spin { to { transform: rotate(360deg); } }
/* Un sablier qui tourne en boucle est exactement ce qui gêne les personnes
   sensibles au mouvement : le texte suffit à dire que ça travaille. */
@media (prefers-reduced-motion: reduce) {
    .scan-spin { animation: none; border-top-color: rgba(var(--accent-rgb), .25); }
}

/* ── Scan en série ──
   La zone de dépôt est la page : tant qu'aucune capture n'est lue, il n'y a
   rien d'autre à regarder, et elle doit dire les trois gestes possibles. */
.lot-drop {
    text-align: center;
    padding: 26px 18px;
    border: 1px dashed rgba(var(--accent-rgb), .35);
    transition: border-color .14s, background .14s;
}
.lot-drop.over {
    border-color: var(--accent-bright);
    background: rgba(var(--accent-rgb), .07);
}
.lot-drop-main { margin: 0 0 6px; font-size: .95rem; }
.lot-drop kbd {
    padding: 1px 6px;
    border-radius: 4px;
    background: rgba(13, 16, 25, .55);
    box-shadow: inset 0 0 0 1px var(--edge-soft);
    font-size: .78rem;
}
.lot-link { color: var(--accent-bright); cursor: pointer; text-decoration: underline; }
.lot-progress {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 9px;
    margin-top: 12px;
    font-size: .84rem;
    color: var(--cream-dim);
}

.lot-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 10px; margin-top: 14px; }
.lotcard { padding: 11px 13px; }
/* L'anomalie se voit au bord, pas au fond : une carte lue reste lisible même
   quand elle porte une réserve. */
.lotcard.warn { box-shadow: inset 3px 0 0 var(--gold-bright); }
.lotcard.bad { box-shadow: inset 3px 0 0 var(--danger); }
.lotcard-head { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.lotcard-head > b { flex: 1; min-width: 0; font-size: .92rem; }
.lotcard-drop {
    padding: 0 6px;
    border: 0;
    background: none;
    color: var(--cream-faint);
    font-size: .95rem;
    line-height: 1;
    cursor: pointer;
}
.lotcard-drop:hover { color: var(--danger); }
.lotcard-subs { margin: 8px 0 0; padding: 0; list-style: none; font-size: .8rem; }
.lotcard-subs li { display: flex; justify-content: space-between; gap: 10px; padding: 1px 0; }
.lotcard-subs i { color: var(--cream-faint); font-style: normal; }
.lotcard-note { margin-top: 7px; font-size: .76rem; color: var(--gold-bright); }
.lotcard.bad .lotcard-note { color: var(--danger); }

.ed-row { display: flex; align-items: center; gap: 9px; margin-bottom: 11px; flex-wrap: wrap; }
.ed-row > label { width: 100%; margin: 0 0 2px; }
.ed-row > select { flex: 1; min-width: 0; }
.ed-rarity { flex: 0 0 auto !important; width: 92px; color: var(--star); }
.ed-mainvalue {
    flex-shrink: 0;
    font-size: 1.05rem;
    font-weight: 800;
    font-variant-numeric: tabular-nums;
    color: var(--gold-bright);
}
/* Raccourcis vers les paliers : ce sont eux qui donnent un roll. */
.ed-steps { display: flex; gap: 3px; }
.ed-steps button {
    padding: 4px 10px;
    border: 0;
    border-radius: 5px;
    background: rgba(var(--accent-rgb), .12);
    box-shadow: inset 0 0 0 1px var(--edge-soft);
    color: var(--cream-dim);
    font-size: .76rem;
    font-weight: 800;
    cursor: pointer;
}
.ed-steps button:hover { color: var(--accent-bright); box-shadow: inset 0 0 0 1px var(--accent); }

.ed-piece { display: flex; align-items: center; gap: 11px; margin: 0 0 13px; }
.ed-piece img { width: 54px; height: 54px; object-fit: contain; border-radius: 6px; background: var(--g5); }
.ed-piece-name { font-family: var(--font-display); font-size: 1.02rem; line-height: 1.2; }

/* Une ligne de saisie : la sous-stat, son curseur, sa lecture. */
.subrow { padding: 11px 0; }
.subrow + .subrow { border-top: 1px solid var(--edge-soft); }
.sub-top { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.sub-top .sub-name { width: 200px; flex-shrink: 0; }
.sub-top .sub-input { width: 96px; flex-shrink: 0; text-align: right; font-variant-numeric: tabular-nums; }
/* Les quatre valeurs qu'un roll de plus donnerait, de la pire à la meilleure. */
.sub-next { display: flex; gap: 4px; margin-left: auto; flex-wrap: wrap; }
.sub-next i {
    font-style: normal;
    font-size: .68rem;
    font-variant-numeric: tabular-nums;
    padding: 1px 7px;
    border-radius: 4px;
    background: rgba(236, 229, 216, .06);
    color: var(--cream-faint);
}
.sub-next i:last-child { background: rgba(var(--accent-rgb), .16); color: var(--accent-bright); }
.subrow .sub-slider { display: block; width: 100%; margin: 9px 0 4px; accent-color: var(--accent); }
.subrow .sub-slider:disabled { opacity: .3; }
.sub-foot { display: flex; justify-content: space-between; gap: 10px; }
.sub-foot i {
    font-style: normal;
    font-size: .68rem;
    color: var(--cream-faint);
    font-variant-numeric: tabular-nums;
}

/* La saisie de progression ne prend pas toute la largeur de l'écran : au-delà,
   l'œil perd la ligne entre l'intitulé et son champ. */
.sheet-form { max-width: 860px; margin-top: 14px; }
.sheet-grid { display: flex; gap: 12px; align-items: flex-end; flex-wrap: wrap; }
.sheet-grid input[type=number] { width: 84px; }
/* Le jeu écrit « Niveau 20 / 40 » sous une rangée d'étoiles. On reprend la
   notation telle quelle : c'est la seule où 20/20 et 20/40 se distinguent sans
   réfléchir, là où un numéro de palier demandait une traduction de tête. */
.lvl-tiles { display: flex; gap: 12px; flex-wrap: wrap; }
.lvl-tile {
    flex: 1 1 210px;
    padding: 11px 14px 13px;
    border-radius: 8px;
    background: rgba(13, 16, 25, .45);
    box-shadow: inset 0 0 0 1px var(--edge-soft);
}
.lvl-tile-label {
    display: block;
    font-size: .62rem;
    text-transform: uppercase;
    letter-spacing: .12em;
    color: var(--cream-faint);
}
.asc-stars { display: flex; gap: 1px; margin: 5px 0 3px; }
.asc-star {
    padding: 0 1px;
    border: 0;
    background: none;
    cursor: pointer;
    font-size: 1.1rem;
    line-height: 1.2;
    color: var(--panel-3);
}
.asc-star::before { content: "\2726"; }
.asc-star.on { color: var(--star); }
.asc-star:hover { color: var(--gold-bright); }

.lvl-line { display: flex; align-items: baseline; gap: 5px; }
.lvl-word { font-size: .78rem; color: var(--cream-dim); }
/* Descendu par `.lvl-line` : `input[type=number]` compte un sélecteur d'attribut,
   donc la règle générale des champs bat une simple classe. Sans ce parent, le
   padding global s'appliquait et le corps du chiffre non — le champ se retrouvait
   trop étroit pour ses deux chiffres. */
.lvl-line .lvl-input {
    width: 2.2em;
    padding: 1px 4px;
    border: 0;
    border-bottom: 1px solid var(--edge);
    border-radius: 0;
    background: none;
    color: var(--cream);
    font-size: 1.3rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    text-align: center;
    -moz-appearance: textfield;
}
.lvl-input::-webkit-outer-spin-button,
.lvl-input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.lvl-line .lvl-input:focus {
    outline: 0;
    border-bottom-color: var(--accent-bright);
    box-shadow: none;
}
/* Le plafond est une conséquence du palier, pas une saisie : il se lit, il ne se
   touche pas — d'où l'absence de cadre et la teinte en retrait. */
.lvl-cap { font-size: 1.05rem; color: var(--cream-faint); font-variant-numeric: tabular-nums; }
.lvl-cap b { color: var(--cream-dim); }

.apti-line { padding: 7px 0; }
.apti-line .sr-label { flex: 1; min-width: 150px; font-size: .84rem; font-weight: 700; }

.sheet-facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 10px; }
.sheet-facts > div {
    background: rgba(13, 16, 25, .45);
    box-shadow: inset 0 0 0 1px var(--edge-soft);
    border-radius: 8px;
    padding: 10px 13px;
}
.sheet-facts b { display: block; font-size: 1.05rem; font-variant-numeric: tabular-nums; }
.sheet-facts span {
    font-size: .62rem;
    text-transform: uppercase;
    letter-spacing: .12em;
    color: var(--cream-faint);
}

/* Déclaration hors historique : 125 lignes, donc tout doit rester compact. */
.decl-table td { vertical-align: middle; }
.decl-table td.lbl { display: flex; align-items: center; gap: 9px; }
.decl-table .decl { padding: 4px 8px; font-size: .82rem; }
.decl-table .total { font-variant-numeric: tabular-nums; font-weight: 700; }
.decl-table tbody tr:hover { background: rgba(236, 229, 216, .04); }

/* Journal des tirages */
.wish-log td { white-space: nowrap; }
.wish-log td.lbl { display: flex; align-items: center; gap: 9px; }
.wish-log .rar.r5 { color: var(--gold-bright); font-weight: 800; }
.wish-log .rar.r4 { color: #c9a5e8; font-weight: 700; }
.wish-log .rar.r3 { color: var(--cream-dim); font-weight: 400; }
.wish-log tbody tr:hover { background: rgba(236, 229, 216, .04); }

.actchart { min-width: 620px; height: auto; }
.purple { color: #c9a5e8; }
.ok-text { color: #8fdc93; }
.bad-text { color: #f0b3b1; }

.track-row {
    background: rgba(13, 16, 25, .42);
    border-radius: 8px;
    box-shadow: inset 0 0 0 1px var(--edge-soft);
    padding: 12px 14px;
    margin-bottom: 11px;
}
.track-row .tr-head { display: flex; align-items: baseline; gap: 10px; }
.track-row .tr-label { font-weight: 800; font-size: .95rem; }
.track-row .tr-head .faint { margin-left: auto; }
.track-row .tr-fields { display: flex; gap: 12px; align-items: flex-end; flex-wrap: wrap; margin-top: 9px; }
.track-row .tr-fields input[type=number] { width: 82px; text-align: center; }
.tr-check {
    display: flex;
    align-items: center;
    gap: 6px;
    margin: 0 0 8px;
    text-transform: none;
    letter-spacing: .03em;
    font-size: .78rem;
    color: var(--cream-dim);
    cursor: pointer;
}
.tr-check input { accent-color: var(--gold); }
/* Le repère du soft pity se lit par-dessus la barre de progression. */
.tr-bar { position: relative; overflow: visible; margin-top: 11px; }
.tr-bar > span { border-radius: 999px 0 0 999px; }
.tr-bar .tr-soft {
    position: absolute;
    top: -3px; bottom: -3px;
    width: 2px;
    background: var(--gold-bright);
    opacity: .75;
    border-radius: 2px;
}
.track-row .tr-note { margin-top: 7px; }

.chartbox { color: var(--cream); }
.chart-scroll { overflow-x: auto; }
.chart { width: 100%; min-width: 520px; height: auto; display: block; margin-top: 6px; }
.legend { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 8px; }
.legend .lg { display: flex; align-items: center; gap: 5px; font-size: .74rem; color: var(--cream-dim); }
.legend .lg i { width: 10px; height: 3px; border-radius: 2px; display: block; }

.table-scroll { overflow-x: auto; }
.wish-table { width: 100%; border-collapse: collapse; margin-top: 8px; font-size: .86rem; }
.wish-table th, .wish-table td {
    padding: 6px 10px;
    text-align: right;
    font-variant-numeric: tabular-nums;
    border-bottom: 1px solid rgba(236, 229, 216, .06);
    white-space: nowrap;
}
.wish-table th {
    font-size: .66rem;
    text-transform: uppercase;
    letter-spacing: .12em;
    color: var(--cream-faint);
    font-weight: 800;
}
.wish-table th:first-child, .wish-table td.lbl { text-align: left; }
.wish-table td.lbl { display: flex; align-items: center; gap: 8px; font-weight: 700; }
.wish-table .dot { width: 9px; height: 9px; border-radius: 2px; display: block; flex-shrink: 0; }
.wish-table tbody tr:last-child td { border-bottom: none; }

@media (max-width: 1080px) {
    .wish-layout { grid-template-columns: 1fr; }
}

/* ══ Reconfiguration : frise des paliers d'Exégèse ══ */
.tiers { display: flex; gap: 8px; margin-top: 12px; }
.tier {
    flex: 1;
    text-align: center;
    padding: 7px 4px;
    border-radius: 6px;
    background: rgba(13, 16, 25, .5);
    box-shadow: inset 0 0 0 1px var(--edge-soft);
    font-size: .72rem;
    color: var(--cream-faint);
    line-height: 1.35;
}
.tier b { display: block; font-size: .95rem; font-variant-numeric: tabular-nums; }
.tier.done { color: var(--gold); box-shadow: inset 0 0 0 1px rgba(211, 188, 142, .45); }
.tier.next {
    color: var(--gold-bright);
    background: rgba(211, 188, 142, .14);
    box-shadow: inset 0 0 0 1px var(--gold), 0 0 14px rgba(255, 215, 128, .18);
}

/* Sélection des 2 sous-stats privilégiées. */
.pickstat {
    display: flex;
    align-items: baseline;
    gap: 10px;
    padding: 12px 15px;
    border-radius: 8px;
    background: linear-gradient(165deg, var(--panel-2) 0%, var(--panel) 70%);
    box-shadow: inset 0 0 0 1px var(--edge-soft);
    cursor: pointer;
    user-select: none;
    transition: box-shadow .14s, transform .14s;
}
.pickstat:hover { transform: translateY(-2px); box-shadow: inset 0 0 0 1px var(--gold); }
.pickstat .ps-name { font-weight: 600; }
.pickstat .ps-val { margin-left: auto; font-weight: 800; font-variant-numeric: tabular-nums; }
.pickstat .ps-rolls { letter-spacing: .14em; font-size: .6rem; }
.pickstat.on {
    background: linear-gradient(165deg, rgba(211, 188, 142, .18) 0%, var(--panel) 75%);
    box-shadow: inset 0 0 0 1px var(--gold-bright), 0 0 16px rgba(255, 215, 128, .16);
    color: var(--gold-bright);
}
.pickstat.locked { opacity: .4; cursor: not-allowed; }
.pickstat.locked:hover { transform: none; box-shadow: inset 0 0 0 1px var(--edge-soft); }

/* ══ Atelier d'artefacts : éditeur de rolls ══ */
.statline {
    background: rgba(13, 16, 25, .45);
    border: 1px solid var(--edge-soft);
    border-radius: 8px;
    padding: 12px 14px;
    margin-bottom: 10px;
}
.statline-head { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.statline-head .sl-name { flex: 1; min-width: 170px; }
.sl-active {
    display: flex;
    align-items: center;
    gap: 6px;
    margin: 0;
    text-transform: none;
    letter-spacing: .04em;
    font-size: .74rem;
    color: var(--cream-dim);
    cursor: pointer;
}
.sl-active input { accent-color: var(--gold); }
.statline .sl-value { margin-left: auto; font-variant-numeric: tabular-nums; }

.chips { display: flex; flex-wrap: wrap; gap: 6px; margin: 10px 0 0; }
.chips:empty { margin: 0; }
/* Jeton de roll : la teinte dit la qualité d'un coup d'œil (or = parfait). */
.chip {
    border-radius: 999px;
    padding: 2px 12px;
    font-size: .76rem;
    font-weight: 800;
    font-variant-numeric: tabular-nums;
    background: rgba(13, 16, 25, .6);
    color: var(--cream-dim);
    box-shadow: inset 0 0 0 1px var(--edge-soft);
    transition: filter .14s, box-shadow .14s;
}
.chip:hover { filter: brightness(1.15); box-shadow: inset 0 0 0 1px var(--danger); color: #f0b3b1; }
.chip.q100 { background: rgba(211, 188, 142, .22); color: var(--gold-bright); box-shadow: inset 0 0 0 1px var(--gold); }
.chip.q90 { background: rgba(211, 188, 142, .12); color: var(--gold); box-shadow: inset 0 0 0 1px rgba(211, 188, 142, .45); }
.chip.q80 { color: var(--cream); }

.sl-add { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 10px; }
.sl-add .step { padding: 3px 12px; font-size: .76rem; border-radius: 999px; }

/* ══ Responsive ══ */
@media (max-width: 780px) {
    .layout { flex-direction: column; }
    .rail {
        width: 100%;
        height: auto;
        position: static;
        padding: 14px 0 0;
    }
    .rail .brand { margin-bottom: 8px; }
    .rail nav { flex-direction: row; overflow-x: auto; padding: 6px 10px 10px; align-items: center; }
    .rail nav a { white-space: nowrap; padding: 8px 13px; }
    /* En rail horizontal, l'intitulé devient un simple séparateur vertical. */
    .nav-group {
        margin: 0 2px;
        padding: 0 8px 0 0;
        font-size: .58rem;
        border-right: 1px solid var(--edge-soft);
        align-self: stretch;
    }
    .nav-group::after { display: none; }
    .resbar { padding: 12px 16px 4px; justify-content: flex-start; }
    main { padding: 4px 16px 44px; }
    .acard-head { padding-right: 120px; }
    .acard-head .art { width: 104px; height: 104px; }
    .cols-4 { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); }
}

/* ── Tuiles compactes : Top 10 de l'Aperçu ───────────────────────────────────
   Format dense et carré, score en évidence : on doit repérer les bonnes pièces
   à la couleur, sans lire un seul chiffre. */
.seg {
    display: inline-flex;
    border: 1px solid var(--edge);
    border-radius: 8px;
    overflow: hidden;
    background: var(--panel);
}
.seg a {
    padding: 6px 13px;
    font-size: .82rem;
    color: var(--cream-dim);
    border-right: 1px solid var(--edge-soft);
}
.seg a:last-child { border-right: 0; }
.seg a:hover { background: var(--panel-2); color: var(--cream); }
.seg a.on { background: var(--gold); color: var(--ink); font-weight: 700; }

.tierbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 14px;
    margin-bottom: 16px;
}
.tierchip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 2px 10px 2px 8px;
    border-radius: 999px;
    background: var(--panel);
    font-size: .78rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}
.tierchip i {
    width: 8px; height: 8px;
    border-radius: 50%;
    background: currentColor;
}
.tierchip.empty { opacity: .3; }

/* Les 10 pièces sur une seule ligne ; en dessous de 1100px la ligne devient un
   scroller horizontal plutôt que de se casser en 3 rangées bancales. */
.toprow {
    display: grid;
    grid-template-columns: repeat(10, minmax(0, 1fr));
    gap: 10px;
}

.scell {
    display: block;
    background: var(--panel);
    border: 1px solid var(--edge-soft);
    border-radius: 9px;
    overflow: hidden;
    transition: transform .14s, border-color .14s;
}
.scell:hover { transform: translateY(-2px); border-color: var(--gold); }

.scell-art {
    position: relative;
    aspect-ratio: 1;
    display: grid;
    place-items: center;
}
.r5 .scell-art { background: var(--g5); }
.r4 .scell-art { background: var(--g4); }
.r3 .scell-art { background: var(--g3); }
.scell-art img { width: 76%; height: 76%; object-fit: contain; }
.scell-art img.ghost { filter: grayscale(1) brightness(2.1); opacity: .38; }

.scell-lvl {
    position: absolute;
    left: 5px; bottom: 4px;
    background: rgba(13, 16, 25, .8);
    color: var(--cream);
    border-radius: 4px;
    padding: 0 5px;
    font-size: .7rem;
    font-weight: 700;
}

/* Rang dans le Top 10, en médaillon façon numéro de classement. */
.scell-rank {
    position: absolute;
    left: 5px; top: 5px;
    width: 19px; height: 19px;
    display: grid;
    place-items: center;
    border-radius: 50%;
    background: rgba(13, 16, 25, .82);
    border: 1px solid var(--gold);
    color: var(--gold-bright);
    font-size: .68rem;
    font-weight: 800;
}

.scell-name, .scell-set {
    padding: 0 7px;
    font-size: .72rem;
    line-height: 1.25;
    /* Un nom trop long ne doit pas déformer la grille. */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.scell-name { margin-top: 6px; color: var(--cream); font-weight: 600; }
.scell-set { color: var(--set-green); }

.scell-score {
    display: block;
    margin: 5px 7px 7px;
    padding: 2px 0;
    border-radius: 5px;
    text-align: center;
    font-size: .88rem;
    font-weight: 800;
    font-variant-numeric: tabular-nums;
    background: rgba(13, 16, 25, .55);
}

@media (max-width: 1100px) {
    .toprow {
        grid-template-columns: none;
        grid-auto-flow: column;
        grid-auto-columns: 112px;
        overflow-x: auto;
        padding-bottom: 6px;
    }
}
@media (max-width: 720px) {
    .toprow { grid-auto-columns: 96px; }
}

/* Score de la fiche d'artefact, avec le lien de bascule CV ⇄ RV. */
.scoretoggle {
    display: inline-flex;
    align-items: baseline;
    gap: 7px;
    margin-left: 10px;
}
.scoretoggle b {
    font-size: 1.05rem;
    font-weight: 800;
    font-variant-numeric: tabular-nums;
    padding: 1px 9px;
    border-radius: 5px;
    background: rgba(13, 16, 25, .5);
}
.scoretoggle a { font-size: .72rem; letter-spacing: .08em; color: var(--cream-faint); }
.scoretoggle a:hover { color: var(--gold-bright); }

/* ══ Inventaire d'artefacts ══════════════════════════════════════════════════
   Reprend la logique de l'écran du jeu : la liste groupée par set à gauche,
   la pièce sélectionnée détaillée à droite, filtres dans un tiroir.

   La page occupe exactement la hauteur de l'écran et ne défile pas : seules la
   liste et le panneau défilent, chacun de son côté, pour que les boutons
   Filtres et Détails restent toujours à l'écran. */
.content.viewport { height: 100vh; display: flex; flex-direction: column; }
.content.viewport main {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    padding-bottom: 18px;
}
.content.viewport .page-title { margin: 6px 0 14px; }
.content.viewport .tierbar { flex-shrink: 0; }

.inv {
    flex: 1;
    min-height: 0;
    display: grid;
    grid-template-columns: minmax(0, 1fr) 360px;
    gap: 18px;
    align-items: stretch;
}
.inv-main {
    display: flex;
    flex-direction: column;
    min-height: 0;
    padding: 16px 16px 0;
}
/* min-height:0 sur l'enfant flex, sinon il refuse de rétrécir sous son contenu
   et c'est la page entière qui se met à défiler. */
.inv-scroll { flex: 1; min-height: 0; overflow-y: auto; padding-right: 4px; }

.inv-foot {
    flex-shrink: 0;
    margin: 0 -16px;
    padding: 12px 16px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 12px;
    border-top: 1px solid var(--edge);
}
/* Compteur de filtres actifs : sans lui, tiroir fermé, rien ne dit que la
   liste est filtrée. */
.inv-foot .n {
    display: inline-block;
    margin-left: 6px;
    min-width: 18px;
    padding: 0 5px;
    border-radius: 999px;
    background: var(--gold);
    color: var(--ink);
    font-size: .72rem;
    font-weight: 800;
}

/* ── Groupe de set, replié par <details> natif ── */
.inv-group { border-bottom: 1px solid var(--edge-soft); padding: 4px 0 12px; }
.inv-group:last-child { border-bottom: 0; }

.inv-group > summary {
    list-style: none;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 11px;
    padding: 9px 4px;
    border-radius: 6px;
}
.inv-group > summary::-webkit-details-marker { display: none; }
.inv-group > summary:hover { background: rgba(236, 229, 216, .04); }
.inv-group > summary .ico { width: 28px; height: 28px; object-fit: contain; }
.inv-group > summary .gname {
    font-family: var(--font-display);
    font-size: 1.02rem;
    letter-spacing: .04em;
    color: var(--set-green);
}
/* Le trait de remplissage pousse le chevron à droite. */
.inv-group > summary .badge { flex-shrink: 0; }
.inv-group > summary::after {
    content: "";
    flex: 1;
    height: 1px;
    background: linear-gradient(90deg, var(--edge), transparent);
    order: 8;
}
.inv-group > summary .chev {
    order: 9;
    color: var(--cream-faint);
    transition: transform .18s;
    flex-shrink: 0;
}
.inv-group[open] > summary .chev { transform: rotate(180deg); }

/* ── La grille : 9 colonnes, minmax(0,…) sinon les longs libellés
      de stat principale font déborder les colonnes. ── */
.inv-grid {
    display: grid;
    grid-template-columns: repeat(9, minmax(0, 1fr));
    gap: 8px;
    margin-top: 6px;
}

/* Tuile compacte : image, niveau, stat principale, et un liseré bas de la
   couleur du palier pour que le filtre par palier reste vérifiable à l'œil. */
.icell {
    display: block;
    border-radius: 5px 5px 16px 5px;
    overflow: hidden;
    background: var(--panel);
    border: 1px solid var(--edge-soft);
    border-bottom: 3px solid currentColor;
    color: var(--t-gris);
    transition: transform .14s, box-shadow .14s, border-color .14s;
}
.icell:hover { transform: translateY(-2px); border-top-color: var(--gold); }
.icell.sel {
    border-color: var(--gold-bright);
    box-shadow: 0 0 0 1px var(--gold-bright), 0 0 18px rgba(255, 215, 128, .22);
}

.icell-art {
    position: relative;
    aspect-ratio: 1;
    display: grid;
    place-items: center;
}
/* Les dégradés de rareté passent par des sélecteurs descendants : sans ces
   trois lignes, les tuiles seraient grises sans le moindre message d'erreur. */
.r5 .icell-art { background: var(--g5); }
.r4 .icell-art { background: var(--g4); }
.r3 .icell-art { background: var(--g3); }
.icell-art img { width: 78%; height: 78%; object-fit: contain; }
.icell-art img.ghost { filter: grayscale(1) brightness(2.1); opacity: .38; }

.icell-lvl {
    position: absolute;
    left: 4px; bottom: 4px;
    background: rgba(13, 16, 25, .8);
    color: var(--cream);
    border-radius: 4px;
    padding: 0 4px;
    font-size: .66rem;
    font-weight: 700;
}
.icell-main {
    padding: 4px 5px 5px;
    text-align: center;
    font-size: .66rem;
    color: var(--cream-dim);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.arti-panel-col { display: flex; flex-direction: column; min-height: 0; }
.arti-panel-scroll { flex: 1; min-height: 0; overflow-y: auto; padding-right: 4px; }
/* Le bouton Détails vit sous la fiche : si celle-ci est trop haute, c'est elle
   qui défile, pas le bouton qui disparaît. */
.panel-foot { flex-shrink: 0; padding-top: 12px; }
.panel-foot .btn { display: block; text-align: center; }

@media (max-width: 1500px) { .inv-grid { grid-template-columns: repeat(7, minmax(0, 1fr)); } }
@media (max-width: 1240px) {
    /* Écran trop étroit pour deux colonnes figées : on redonne la main au
       défilement normal de la page. */
    .content.viewport, .content.viewport main { height: auto; display: block; overflow: visible; }
    .inv { display: block; }
    .inv-main { margin-bottom: 18px; }
    .inv-scroll, .arti-panel-scroll { overflow: visible; }
    .inv-grid { grid-template-columns: repeat(6, minmax(0, 1fr)); }
}
@media (max-width: 780px) { .inv-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

/* ══ Tiroir de filtres ══
   En position fixed depuis le bord de l'écran (et non absolute dans la liste) :
   sinon il sort du champ dès que l'inventaire fait 30 groupes de haut. */
.fscrim {
    position: fixed;
    inset: 0;
    z-index: 50;
    background: rgba(8, 10, 17, .55);
    backdrop-filter: blur(2px);
    opacity: 0;
    pointer-events: none;
    transition: opacity .2s;
}
.fscrim.open { opacity: 1; pointer-events: auto; }

.fdrawer {
    position: fixed;
    left: 0; top: 0; bottom: 0;
    z-index: 60;
    width: 340px;
    max-width: 88vw;
    overflow-y: auto;
    padding: 20px 20px 30px;
    background: linear-gradient(165deg, var(--panel-2) 0%, var(--panel) 70%);
    border-right: 1px solid var(--gold);
    box-shadow: 14px 0 40px rgba(0, 0, 0, .55);
    transform: translateX(-101%);
    transition: transform .22s ease;
}
.fdrawer.open { transform: none; }

.fdrawer-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 6px;
}
.fdrawer-head h2 {
    margin: 0;
    font-size: 1.15rem;
    letter-spacing: .1em;
    color: var(--gold);
}
.fclose {
    background: none;
    border: 0;
    color: var(--cream-faint);
    font-size: 1.1rem;
    cursor: pointer;
    padding: 4px 8px;
}
.fclose:hover { color: var(--cream); }

.fgroup { margin-top: 18px; }
.fgroup h3 {
    margin: 0 0 8px;
    font-family: var(--font-body);
    font-size: .7rem;
    text-transform: uppercase;
    letter-spacing: .15em;
    font-weight: 700;
    color: var(--cream-faint);
}
.fchips { display: flex; flex-wrap: wrap; gap: 6px; }

.fchip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 10px;
    border-radius: 999px;
    border: 1px solid var(--edge-soft);
    background: rgba(13, 16, 25, .4);
    color: var(--cream-dim);
    font-size: .78rem;
    cursor: pointer;
    user-select: none;
    transition: border-color .13s, background .13s, color .13s;
}
.fchip:hover { border-color: var(--edge); color: var(--cream); }
.fchip.on {
    border-color: var(--gold);
    background: rgba(211, 188, 142, .16);
    color: var(--gold-bright);
    font-weight: 700;
}
.fchip .n { font-size: .68rem; opacity: .65; font-variant-numeric: tabular-nums; }
/* Les puces de palier gardent leur teinte (les classes .t-* posent déjà la couleur
   du texte et une bordure), on ne surcharge que l'état actif. */
.fchip.on[class*="t-"] { background: rgba(236, 229, 216, .08); }

.fdrawer-foot {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-top: 26px;
    padding-top: 16px;
    border-top: 1px solid var(--edge-soft);
}

/* ══ Écran d'une pièce : sous-menu / pièce / panneau ══════════════════════════
   La colonne de droite est la flexible : c'est elle qui accueille la grille de
   matériaux du renforcement. */
.arti-page {
    display: grid;
    grid-template-columns: 172px 330px minmax(0, 1fr);
    gap: 22px;
    align-items: start;
}

.arti-submenu {
    display: flex;
    flex-direction: column;
    gap: 4px;
    position: sticky;
    top: 16px;
}
/* Même vocabulaire que le rail de navigation, pour que ça se lise comme un menu. */
.arti-submenu a {
    padding: 11px 16px;
    border-radius: 6px;
    color: var(--cream-dim);
    font-weight: 600;
    font-size: .92rem;
    letter-spacing: .04em;
    transition: background .14s, color .14s;
}
.arti-submenu a:hover { background: rgba(236, 229, 216, .06); color: var(--cream); }
.arti-submenu a.on {
    background: linear-gradient(90deg, rgba(var(--accent-rgb), .16), rgba(var(--accent-rgb), .04));
    color: var(--accent-bright);
    box-shadow: inset 0 0 0 1px rgba(var(--accent-rgb), .30);
}

.arti-stage { position: sticky; top: 16px; text-align: center; }
.stage-halo {
    border-radius: 10px 10px 30px 10px;
    padding: 26px;
    position: relative;
    overflow: hidden;
}
.stage-halo::before {
    content: "";
    position: absolute;
    inset: 0;
    background: radial-gradient(circle at 50% 45%, rgba(255, 247, 224, .30), transparent 62%);
}
.stage-halo .art {
    position: relative;
    width: 190px; height: 190px;
    object-fit: contain;
    filter: drop-shadow(0 10px 22px rgba(0, 0, 0, .55));
}
.stage-halo .art.ghost { filter: grayscale(1) brightness(2.1); opacity: .42; }

.stage-name {
    margin: 14px 0 2px;
    font-size: 1.3rem;
    letter-spacing: .04em;
    color: var(--cream);
}
.stage-slot {
    font-size: .7rem;
    text-transform: uppercase;
    letter-spacing: .15em;
    color: var(--cream-faint);
}
.stage-main { margin-top: 6px; color: var(--gold-bright); font-weight: 700; }
.stage-stars { color: var(--star); letter-spacing: .08em; margin-top: 2px; }
.stage-lvl { margin-top: 10px; display: flex; justify-content: center; gap: 8px; }

/* Le renforcement réutilise la colonne centrale comme cible d'animation. */
.arti-stage.enh-target .lvl-preview { margin-top: 16px; }
.arti-stage.enh-target .subs { text-align: left; }

@media (max-width: 1150px) {
    .arti-page { grid-template-columns: 1fr; }
    .arti-submenu { flex-direction: row; position: static; }
    .arti-submenu a { flex: 1; text-align: center; }
    .arti-stage { position: static; }
}

/* Sous-titre à l'intérieur d'un groupe de filtres (ex. « Sens » sous le tri). */
.fsub {
    margin: 10px 0 6px;
    font-size: .68rem;
    text-transform: uppercase;
    letter-spacing: .14em;
    color: var(--cream-faint);
}

/* ══ Emplacements de matériaux (écran de renforcement) ══
   Comme en jeu : une rangée d'emplacements qui se remplit au fil de la sélection,
   et qui sert de bouton pour ouvrir le sélecteur de matériaux. */
.matslots {
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
    padding: 12px 14px;
    margin-bottom: 14px;
    border: 1px solid var(--edge);
    border-radius: 8px;
    background: rgba(13, 16, 25, .4);
    cursor: pointer;
    transition: border-color .14s, background .14s;
}
.matslots:hover, .matslots.open { border-color: var(--gold); background: rgba(211, 188, 142, .07); }
.matslots:focus-visible { outline: 2px solid var(--gold-bright); outline-offset: 2px; }

.matslots-row { display: flex; gap: 7px; flex-wrap: wrap; }
.matslot {
    width: 46px; height: 46px;
    border-radius: 5px 5px 14px 5px;
    border: 1px dashed var(--edge);
    background: rgba(236, 229, 216, .03);
    display: grid;
    place-items: center;
    overflow: hidden;
}
.matslot.filled { border-style: solid; border-color: var(--edge-soft); }
.matslot.filled.r5 { background: var(--g5); }
.matslot.filled.r4 { background: var(--g4); }
.matslot.filled.r3 { background: var(--g3); }
.matslot img { width: 82%; height: 82%; object-fit: contain; }
.matslot .big { font-size: 1.4rem; line-height: 1; }

.matslots-hint {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-left: auto;
    font-size: .82rem;
    color: var(--cream-dim);
}
.matslots-hint .chev { transition: transform .18s; }
.matslots.open .matslots-hint .chev { transform: rotate(180deg); }

/* Colonne de droite du shell : min-width:0 sinon une grille de matériaux large
   déborde au lieu de rétrécir. */
.arti-side { min-width: 0; }

/* Sélecteur de matériaux, déplié par un clic sur les emplacements. */
.matpicker { border-top: 1px solid var(--edge-soft); margin-top: 4px; }

/* ══ Râtelier d'armes ══
   La tuile est celle de l'inventaire d'artéfacts (.icell) : une arme n'a que
   deux chiffres, une carte large les étalait sans rien apprendre de plus. La
   vignette dit rareté, niveau, raffinement et porteur ; le reste est dans la
   fiche, à droite.
   Les deux degrés de rareté qu'aucun artéfact ne connaît — le jeu ne descend
   jamais sous 3★ côté pièces. */
.r2 .icell-art, .pick-card.r2 .pc-art { background: var(--g2); }
.r1 .icell-art, .pick-card.r1 .pc-art { background: var(--g1); }

/* Le liseré bas de .icell porte le palier côté artéfacts ; une arme n'en a pas,
   il reprend donc sa rareté — même information que le dégradé, mais lisible sur
   une grille entière d'un seul balayage. */
.wcell { color: var(--edge); cursor: pointer; padding: 0; text-align: inherit; font: inherit; }
.wcell.r5 { color: var(--gold); }
.wcell.r4 { color: #a37ad1; }
.wcell.r3 { color: #63a9c9; }
/* Arme figée : lisible mais visiblement hors de portée, comme les pièces. */
.wcell.locked { border-color: rgba(127, 178, 229, .45); }
.wcell .icell-main {
    font-family: var(--font-display);
    font-size: .72rem;
    color: var(--cream-dim);
}
/* Raffinement en haut à droite, symétrique du niveau : ce sont les deux nombres
   qu'on cherche sur une arme, et jamais au même endroit qu'autre chose. */
.icell-rf {
    position: absolute;
    right: 4px; top: 4px;
    background: rgba(13, 16, 25, .8);
    color: var(--gold-bright);
    border-radius: 4px;
    padding: 0 4px;
    font-size: .66rem;
    font-weight: 700;
}
.icell-lock { position: absolute; left: 4px; top: 3px; font-size: .68rem; }
/* Le porteur, en médaillon : reconnaître un visage va plus vite que lire un nom. */
.icell-face {
    position: absolute;
    right: 3px; bottom: 3px;
    width: 24px; height: 24px;
    border-radius: 50%;
    overflow: hidden;
    background: var(--panel-2);
    box-shadow: 0 0 0 1px var(--edge);
    display: grid;
    place-items: center;
}
.icell-face img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 18%; }
.icell-face em { font-size: .6rem; font-style: normal; font-weight: 800; color: var(--cream-dim); }

/* ── La fiche de l'arme choisie ── */
/* Sans la hauteur d'écran figée de l'inventaire du jeu, la fiche suit le
   défilement plutôt que de rester coincée en haut d'une grille de 40 armes. */
.wpn-inv { align-items: start; }
.wpn-inv .inv-main { padding: 16px; }
.wdet { position: sticky; top: 14px; padding: 16px; }
.wdet-head { display: flex; gap: 12px; align-items: center; }
.wdet-tags { display: flex; flex-wrap: wrap; gap: 6px; margin: 11px 0 4px; }
.wdet-passive { margin-top: 12px; }
.wdet-passive b { font-size: .82rem; color: var(--gold-bright); }
.wdet-passive p { margin: 4px 0 0; line-height: 1.45; }
/* Correction sur place : trois nombres et une coche, c'est toute la fiche. */
.wdet-edit { display: flex; align-items: center; gap: 8px; margin-top: 14px; }
.wdet-edit label {
    display: flex;
    align-items: center;
    gap: 4px;
    margin: 0;
    font-size: .7rem;
    color: var(--cream-faint);
}
.wdet-edit input { width: 56px; padding: 3px 6px; font-size: .8rem; text-align: center; }
.wdet-edit .step { padding: 3px 11px; font-size: .85rem; border-radius: 6px; }
.wdet-del { margin-top: 10px; }
.wdet-del .ghost { width: 100%; font-size: .76rem; color: var(--cream-faint); }
.wdet-del .ghost:hover { color: var(--danger); }
/* ── Formulaire d'ajout ──
   L'éditeur d'artéfact met sa colonne étroite à gauche (la pièce) et la large à
   droite (quatre sous-stats). Une arme inverse le besoin : son état tient en
   trois nombres, mais choisir parmi 247 modèles demande de la place. */
.wpn-editor { grid-template-columns: minmax(0, 1fr) minmax(0, 360px); }
@media (max-width: 1080px) { .wpn-editor { grid-template-columns: 1fr; } }
/* La grille défile pour elle-même : sans ça, la colonne d'état se retrouvait à
   un écran et demi au-dessus de la liste qu'on parcourt. */
.wpn-picker { max-height: 62vh; overflow-y: auto; padding-right: 4px; }
/* Le bouton de changement d'arme, dans le panneau du bandeau de la fiche perso. */
.wpn > .pick-open { align-self: center; padding: 5px 14px; font-size: .76rem; border-radius: 999px; }

/* ══ Plan de farm ══
   Les matériaux réclamés par l'état visé, en tuiles d'inventaire : la rareté se
   lit au dégradé, la quantité au coin, et l'icône dit l'objet plus vite que son
   nom — « Fragment d'agate agnidus » et « Morceau d'agate agnidus » ne se
   distinguent qu'à la troisième syllabe. */
.matgrid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(84px, 1fr));
    gap: 8px;
}
.matcell { color: var(--edge); cursor: default; }
.matcell.r5 { color: var(--gold); }
.matcell.r4 { color: #a37ad1; }
.matcell.r3 { color: #63a9c9; }
.matcell.r2 { color: #6ba36a; }
.matcell:hover { transform: none; }
/* La quantité, pas un niveau : elle peut valoir sept chiffres (la mora), d'où la
   pastille qui s'étire au lieu d'un carré de taille fixe. */
.matcell .icell-lvl { right: 4px; left: auto; font-variant-numeric: tabular-nums; }
.matcell .icell-main { font-size: .63rem; line-height: 1.25; white-space: normal; }
/* L'objectif, dans la même ligne que l'état courant : c'est le couple qui donne
   le plan, les séparer ferait lire deux réglages sans rapport. */
.wdet-goal { color: var(--gold-bright) !important; }
.wdet-goal input { width: 62px; }

/* ══ Bonus conditionnels ══
   La parenthèse dit ce qu'un effet CONDITIONNEL ajouterait — en écart réel, donc
   dans l'unité de la ligne. Plus petite et plus pâle que la valeur acquise :
   c'est un potentiel, il ne doit pas se lire comme un fait. */
.statplus {
    margin-left: 6px;
    font-style: normal;
    font-size: .78rem;
    font-weight: 700;
    color: var(--gold);
    opacity: .82;
    cursor: help;
}
.statline.cv .statplus { color: var(--gold-bright); }

/* Ce qu'aucune ligne d'attributs ne peut accueillir : bonus par type de dégâts,
   RÉS de l'ennemi, passifs d'arme. Replié par défaut — c'est de la lecture, pas
   un chiffre qu'on balaie. */
.bonusbox { margin-top: 14px; padding: 12px 16px; }
.bonusbox > summary {
    cursor: pointer;
    list-style: none;
    font-family: var(--font-display);
    font-size: .95rem;
}
.bonusbox > summary::-webkit-details-marker { display: none; }
.bonusbox > summary i { font-style: normal; margin-left: 6px; font-size: .8rem; }
.bonusbox > summary::after { content: " ▾"; color: var(--cream-faint); font-size: .7rem; }
.bonusbox[open] > summary::after { content: " ▴"; }
.bonusline { padding: 10px 0; border-bottom: 1px solid var(--edge-soft); }
.bonusline:last-child { border-bottom: 0; }
.bonusline b { font-size: .82rem; color: var(--gold-bright); }
.bonusline p { margin: 3px 0 0; font-size: .8rem; line-height: 1.45; color: var(--cream-dim); }

/* ══ Aperçu du compte ══
   Une vitrine, pas une liste : la page tient dans l'écran et ne défile jamais
   (cf. .content.viewport). Tout ce qui pourrait grandir est donc borné —
   l'illustration est recadrée, les noms sont tronqués, les deux colonnes
   masquent leur trop-plein plutôt que de pousser la page.

   Deux colonnes : l'identité à gauche, qui décrit ; le focus à droite, qui
   situe. Le classement mondial est la SEULE donnée comparative de la page,
   d'où sa taille — tout le reste est du contexte.

   Deux rangées aussi. La première se dimensionne sur son contenu : c'est donc
   la colonne d'identité, la plus haute des deux, qui fixe sa hauteur — et le
   focus s'y aligne au lieu de dicter la sienne. Tout le mou vertical tombe dans
   la seconde rangée, celle des tuiles, qui en remplit autant de lignes qu'elle
   peut. L'inverse (le focus en 1fr) le laissait s'étirer sur toute la page et
   ne laissait qu'une rangée de personnages. */
.apercu {
    flex: 1;
    min-height: 0;
    display: grid;
    grid-template-columns: 320px minmax(0, 1fr);
    grid-template-rows: minmax(0, auto) minmax(0, 1fr);
    gap: 18px;
    align-items: stretch;
}

/* ── Colonne d'identité ── */
.ap-side { display: flex; flex-direction: column; gap: 14px; min-height: 0; overflow: hidden; }

.ap-ident {
    position: relative;
    overflow: hidden;
    flex-shrink: 0;
    padding: 22px 18px 16px;
    text-align: center;
    background: var(--panel);
    border: 1px solid var(--edge);
    border-radius: 14px;
}
/* La carte de visite du joueur, en filigrane derrière l'avatar. Fondue vers le
   bas pour qu'elle reste un fond et ne dispute pas le nom. */
.ap-ident::before {
    content: "";
    position: absolute;
    inset: 0 0 auto;
    height: 104px;
    background-image: var(--card);
    background-size: cover;
    background-position: center;
    opacity: .2;
    -webkit-mask-image: linear-gradient(#000, transparent);
    mask-image: linear-gradient(#000, transparent);
}
.ap-ident > * { position: relative; }

.ap-avatar {
    width: 92px;
    height: 92px;
    margin: 0 auto 12px;
    border-radius: 50%;
    overflow: hidden;
    background: var(--panel-2);
    border: 2px solid var(--edge);
    color: var(--cream-faint);
    display: grid;
    place-items: center;
}
.ap-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
.ap-avatar svg { width: 46px; height: 46px; }

.ap-name {
    font-family: var(--font-display);
    font-size: 1.5rem;
    line-height: 1.2;
    color: var(--cream);
    overflow-wrap: anywhere;
}
/* La signature est libre : deux lignes au plus, sinon elle repousserait les
   compteurs hors de l'écran. */
.ap-sign {
    margin-top: 6px;
    font-size: .84rem;
    font-style: italic;
    color: var(--cream-dim);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.ap-badges { display: flex; justify-content: center; flex-wrap: wrap; gap: 6px; margin-top: 12px; }
.ap-badge {
    padding: 3px 11px;
    font-size: .78rem;
    font-weight: 700;
    color: var(--cream-dim);
    background: var(--panel-2);
    border-radius: 999px;
}
.ap-uid { margin-top: 10px; font-size: .78rem; color: var(--cream-faint); font-variant-numeric: tabular-nums; }

.ap-stats {
    flex-shrink: 0;
    list-style: none;
    margin: 0;
    padding: 2px 14px;
    background: var(--panel);
    border: 1px solid var(--edge);
    border-radius: 14px;
}
.ap-stats li {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 11px 0;
    border-bottom: 1px solid var(--edge-soft);
}
.ap-stats li:last-child { border-bottom: 0; }
.ap-stats svg { width: 18px; height: 18px; flex-shrink: 0; color: var(--accent); }
.ap-lbl { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--cream-dim); }
.ap-val { font-weight: 800; color: var(--cream); font-variant-numeric: tabular-nums; }

/* Derniers 5★ hors permanent. La pity qu'ils ont coûtée en dit plus que la date :
   c'est le prix payé, pas le moment. */
.ap-fives {
    list-style: none;
    margin: 0;
    padding: 6px 14px;
    background: var(--panel);
    border: 1px solid var(--edge);
    border-radius: 14px;
    min-height: 0;
    overflow: hidden;
}
.ap-fives li { display: flex; align-items: center; gap: 11px; padding: 9px 0; }
.ap-five-img {
    width: 38px;
    height: 38px;
    flex-shrink: 0;
    border-radius: 50%;
    overflow: hidden;
    background: var(--panel-2);
    box-shadow: inset 0 0 0 2px var(--el, var(--edge));
}
.ap-five-img img { width: 100%; height: 100%; object-fit: cover; display: block; }
.ap-five-txt { display: flex; flex-direction: column; min-width: 0; }
.ap-five-name {
    font-weight: 700;
    color: var(--cream);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.ap-five-pity { font-size: .78rem; color: var(--cream-faint); }

/* ── Colonne principale ── */
/* L'end-game garde sa hauteur propre, le focus prend le reste de la rangée —
   soit exactement de quoi finir à la même ligne que la colonne d'identité. */
.ap-main {
    display: grid;
    grid-template-rows: auto minmax(0, 1fr);
    gap: 14px;
    min-height: 0;
}

.ap-focus {
    position: relative;
    min-height: 0;
    display: grid;
    grid-template-columns: minmax(0, 300px) minmax(0, 1fr);
    gap: 24px;
    align-items: center;
    padding: 18px;
    background: var(--panel);
    border: 1px solid var(--edge);
    border-radius: 16px;
    overflow: hidden;
}
/* Halo à la couleur de l'élément : il signe le personnage sans colorer le texte. */
.ap-focus::after {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    background: radial-gradient(120% 100% at 12% 50%, rgba(0, 0, 0, 0) 40%, var(--el, transparent) 220%);
    opacity: .16;
}
.ap-splash {
    height: 100%;
    min-height: 0;
    border-radius: 12px;
    overflow: hidden;
    /* L'illustration se dissout vers la droite au lieu de s'arrêter net : le bord
       franc posait une seconde bordure en plein milieu du bloc, juste avant les
       chiffres. Le fondu laisse le regard glisser du portrait vers les stats.
       Pas de fond ici : un aplat resterait visible en rectangle sous le fondu. */
    -webkit-mask-image: linear-gradient(to right, #000 62%, transparent 100%);
    mask-image: linear-gradient(to right, #000 62%, transparent 100%);
}
/* Recadrée par le haut : les illustrations de bannière cadrent le visage en
   haut, un centrage classique le couperait. */
.ap-splash img { width: 100%; height: 100%; object-fit: cover; object-position: center top; display: block; }

/* Le bloc est le seul de la page à avoir de la place : sa hauteur est fixée par
   la colonne d'identité, son contenu en occupe moins. D'où des tailles plus
   généreuses qu'ailleurs — c'est là que doit tomber le regard. */
.ap-focus-head h2 {
    margin: 0;
    font-family: var(--font-display);
    font-size: 2.2rem;
    line-height: 1.15;
    color: var(--cream);
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}
.ap-cons {
    padding: 2px 11px;
    font-family: var(--font-body);
    font-size: .9rem;
    font-weight: 800;
    color: var(--accent-bright);
    background: rgba(var(--accent-rgb), .14);
    border-radius: 999px;
}
.ap-rank { margin: 14px 0 0; display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.ap-rank-n {
    font-size: 3rem;
    font-weight: 800;
    line-height: 1;
    color: var(--accent-bright);
    font-variant-numeric: tabular-nums;
}
.ap-rank-pct { font-size: 1.05rem; color: var(--cream-dim); }

.ap-sets { list-style: none; margin: 18px 0 0; padding: 0; }
.ap-sets li { display: flex; align-items: center; gap: 10px; padding: 6px 0; min-width: 0; font-size: .95rem; }
.ap-sets img { width: 26px; height: 26px; flex-shrink: 0; }
.ap-sets li > span {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--set-green);
}
.ap-sets em { font-style: normal; font-size: .84rem; color: var(--cream-faint); }
.ap-weapon > span { color: var(--cream-dim) !important; }

/* Le corps du focus : en-tête, panneau d'attributs, pièces. Chacun garde sa
   hauteur propre, seul le panneau se comprime — c'est le seul des trois dont on
   peut rogner l'interligne sans le rendre illisible. */
.ap-focus-body { display: grid; grid-template-rows: auto minmax(0, 1fr) auto; gap: 12px; min-width: 0; min-height: 0; }
.ap-focus-head { min-width: 0; }

/* Le panneau d'attributs : deux colonnes, libellé à gauche, valeur à droite.
   Pictogrammes maison (cf. la macro stat_icon) — les icônes de stats du jeu
   vivent dans un atlas de sprites qu'aucune API publique ne sert. */
.ap-panel {
    list-style: none;
    margin: 0;
    padding: 0;
    min-height: 0;
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-auto-rows: min-content;
    gap: 2px 20px;
    overflow: hidden;
}
.ap-panel li { display: flex; align-items: center; gap: 9px; min-width: 0; padding: 5px 0; }
.ap-pico { display: flex; flex-shrink: 0; color: var(--accent); opacity: .75; }
.ap-pico svg { width: 17px; height: 17px; }
.ap-plbl {
    flex: 1;
    min-width: 0;
    font-size: .92rem;
    color: var(--cream-dim);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.ap-panel b { font-size: .96rem; color: var(--cream); font-variant-numeric: tabular-nums; }

/* Les cinq pièces portées, dans l'ordre du jeu. Un emplacement vide garde sa
   case : la rangée dit aussi ce qui MANQUE. */
.ap-pieces { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 8px; }
.ap-pieces li {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    min-width: 0;
    padding: 10px 5px;
    background: var(--panel-2);
    border-radius: 10px;
}
.ap-pieces li.empty { opacity: .45; }
.ap-piece-img { position: relative; width: 54px; height: 54px; }
.ap-piece-img img { width: 100%; height: 100%; object-fit: contain; display: block; }
.ap-piece-img .ghost { opacity: .5; filter: grayscale(1); }
.ap-piece-lvl {
    position: absolute;
    right: -4px;
    bottom: -2px;
    padding: 0 4px;
    font-size: .64rem;
    font-style: normal;
    font-weight: 800;
    color: var(--ink);
    background: var(--cream);
    border-radius: 5px;
}
.ap-pieces b { font-size: .95rem; color: var(--cream); font-variant-numeric: tabular-nums; }
.ap-piece-lbl {
    max-width: 100%;
    font-size: .74rem;
    color: var(--cream-faint);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Les suivants au classement. Colonnes égales et noms tronqués : un
   « Neuvillette » ne doit pas pousser ses voisins hors de la rangée.

   Sur les deux colonnes : la rangée occupe la bande laissée libre sous la
   colonne d'identité, qui serait vide autrement. Le nombre de colonnes suit la
   largeur au lieu d'être figé — c'est la seule grille de la page dont on veut
   qu'elle en montre le plus possible. Les lignes se tassent en haut et le
   trop-plein est rogné : la page ne défile jamais. */
.ap-others {
    grid-column: 1 / -1;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
    align-content: start;
    gap: 10px;
    min-height: 0;
    overflow: hidden;
}
.ap-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 3px;
    min-width: 0;
    padding: 9px 5px;
    text-decoration: none;
    color: var(--cream-dim);
    background: var(--panel);
    border: 1px solid var(--edge);
    border-radius: 12px;
    transition: border-color .15s, transform .15s;
}
.ap-card:hover { border-color: var(--el, var(--accent)); transform: translateY(-2px); color: var(--cream); }
.ap-card-img {
    position: relative;
    width: 100%;
    max-width: 56px;
    aspect-ratio: 1;
    border-radius: 50%;
    overflow: visible;
    background: var(--panel-2);
    box-shadow: inset 0 0 0 2px var(--el, var(--edge));
}
.ap-card-img img { width: 100%; height: 100%; object-fit: cover; border-radius: 50%; display: block; }
.ap-card-cons {
    position: absolute;
    right: -3px;
    bottom: -3px;
    padding: 0 5px;
    font-size: .62rem;
    font-style: normal;
    font-weight: 800;
    color: var(--ink);
    background: var(--cream);
    border-radius: 6px;
}
.ap-card-name {
    max-width: 100%;
    font-size: .76rem;
    font-weight: 700;
    color: var(--cream);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.ap-card-top { font-size: .68rem; color: var(--accent-bright); font-variant-numeric: tabular-nums; }

.ap-endgame { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }
.ap-eg {
    display: flex;
    align-items: center;
    gap: 11px;
    min-width: 0;
    padding: 12px 16px;
    background: var(--panel);
    border: 1px solid var(--edge);
    border-radius: 14px;
}
.ap-eg svg { width: 22px; height: 22px; flex-shrink: 0; color: var(--accent); }
.ap-eg-txt { display: flex; flex-direction: column; min-width: 0; }
.ap-eg-lbl { font-size: .78rem; color: var(--cream-faint); }
.ap-eg-val {
    font-weight: 700;
    color: var(--cream);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Écrans courts : l'illustration est ce qui se comprime le mieux — un portrait
   plus bas reste lisible, une tuile de vitrine rognée ne l'est plus. */
@media (max-height: 820px) {
    .ap-focus-head h2 { font-size: 1.7rem; }
    .ap-rank-n { font-size: 2.2rem; }
    .ap-rank-pct { font-size: .95rem; }
    .ap-sets li { padding: 3px 0; font-size: .88rem; }
    .ap-sets img { width: 22px; height: 22px; }
    .ap-avatar { width: 74px; height: 74px; }
    .ap-stats li, .ap-fives li { padding: 8px 0; }
    .ap-card-img { max-width: 46px; }
    .ap-panel li { padding: 3px 0; }
    .ap-pieces li { padding: 6px 3px; }
    .ap-piece-img { width: 42px; height: 42px; }
}

/* Sous 1240px, .content.viewport rend la main au défilement normal (cf. plus
   haut) : la page redevient une colonne, et les blocs reprennent leur hauteur. */
@media (max-width: 1240px) {
    .apercu { display: block; }
    .ap-side { overflow: visible; margin-bottom: 14px; }
    .ap-side, .ap-main { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
    .ap-main { grid-template-columns: 1fr; grid-template-rows: none; }
    /* La page défile de nouveau : plus rien à rogner, la rangée se déroule. */
    .ap-others { margin-top: 14px; overflow: visible; }
    .ap-splash { height: 260px; }
}
@media (max-width: 780px) {
    .ap-others { grid-template-columns: repeat(4, minmax(0, 1fr)); }
    .ap-side { display: block; }
    .ap-endgame { grid-template-columns: 1fr; }
    .ap-focus { grid-template-columns: 1fr; }
}

/* ══ Onglet Progression ══
   Objectifs à gauche, coût à droite. C'est le même geste : on relève un
   « souhaité », on regarde ce que ça coûte. Empilés, la réponse passait sous la
   ligne de flottaison pendant que la moitié droite restait vide. */
.sheet-cols {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 14px;
    align-items: start;
    margin-top: 14px;
}
@media (max-width: 1080px) { .sheet-cols { grid-template-columns: 1fr; } }
/* La largeur de lecture ne vaut plus dans une colonne : c'est la grille qui borne. */
.sheet-cols .sheet-form { max-width: none; margin-top: 0; }
.sheet-mats .matgrid { margin-top: 4px; }
/* Le reliquat d'un plan tronqué : une tuile qui compte au lieu d'une liste qui
   déborde. Pas d'icône — c'est un nombre, pas un objet. */
.matmore { color: var(--edge); }
.matmore .icell-art { background: rgba(13, 16, 25, .5); }
.matmore .icell-art b { font-size: 1.05rem; color: var(--cream-dim); }

/* ══ Page « À farmer » ══
   Le cumul en tête — c'est la question qu'on se pose en ouvrant la page —, le
   détail par personnage ensuite, pour savoir à qui l'attribuer. */
.farm-total { margin-bottom: 20px; }
.farm-total .section-title .faint { margin-left: 10px; font-weight: 400; }

.farmgrid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(310px, 1fr));
    gap: 12px;
}
.farmcard {
    display: block;
    padding: 12px 14px 10px;
    border-radius: 10px;
    background: linear-gradient(165deg, var(--panel-2) 0%, var(--panel) 70%);
    box-shadow: inset 0 0 0 1px var(--edge-soft);
    color: inherit;
    text-decoration: none;
    transition: transform .14s, box-shadow .14s;
}
.farmcard:hover { transform: translateY(-2px); box-shadow: inset 0 0 0 1px var(--gold); }
.farmcard.r5 { box-shadow: inset 0 0 0 1px rgba(207, 143, 62, .45); }

.farmcard-head { display: flex; align-items: center; gap: 11px; margin-bottom: 10px; }
.farmcard-face {
    width: 46px; height: 46px;
    border-radius: 50%;
    object-fit: cover;
    object-position: 50% 18%;
    background: var(--g4);
    flex-shrink: 0;
}
.farmcard.r5 .farmcard-face { background: var(--g5); }
/* Une arme se regarde en entier : la rogner en médaillon n'en laisserait que le manche. */
.farmcard-face.wpn { border-radius: 8px; object-fit: contain; object-position: center; }
.farmcard-id { min-width: 0; }
.farmcard-id b { display: block; font-family: var(--font-display); font-size: 1.02rem; }
.farmcard-id span { display: block; margin-top: 1px; }
/* Résumé, donc tuiles plus petites que sur la fiche : on compte, on ne détaille pas. */
.farmcard .matgrid { grid-template-columns: repeat(auto-fill, minmax(62px, 1fr)); gap: 6px; }
.farmcard .icell-main { font-size: .58rem; }
.farmcard-foot {
    display: flex;
    justify-content: space-between;
    gap: 10px;
    margin-top: 10px;
    padding-top: 8px;
    border-top: 1px solid var(--edge-soft);
    font-variant-numeric: tabular-nums;
}
