/* style.css — Tanuki no Sumika, identité visuelle "papier washi" */

@import url('https://fonts.googleapis.com/css2?family=Shippori+Mincho:wght@500;700;800&family=Zen+Kaku+Gothic+New:wght@400;500;700;900&display=swap');

:root{
  --washi:#EDE6D6;
  --washi-deep:#E1D7C0;
  --ink:#2B2620;
  --ink-soft:#5B5347;
  --torii:#B54B3A;
  --torii-deep:#8E3A2C;
  --moss:#6B7A54;
  --gold:#C9A227;
  --indigo:#2E3548;
  --indigo-deep:#151925;
}

*{box-sizing:border-box;}

html{overflow-x:hidden;}
body{
  margin:0;
  min-height:100vh;
  overflow-x:hidden;
  background:
    radial-gradient(circle at 20% 10%, #f3ede0 0%, transparent 50%),
    var(--washi-deep);
  font-family:'Zen Kaku Gothic New', sans-serif;
  color:var(--ink);
}

.app-shell{
  max-width:480px;
  margin:0 auto;
  min-height:100vh;
  background:var(--washi);
  display:flex;
  flex-direction:column;
}

[hidden]{display:none !important;}

/* ===== Login screen ===== */
.login-screen{
  flex:1;
  display:flex;
  flex-direction:column;
  align-items:center;
  justify-content:center;
  text-align:center;
  padding:40px 24px;
}
.login-kanji{
  font-family:'Shippori Mincho', serif;
  font-size:64px;
  color:var(--torii);
  opacity:.85;
  margin-bottom:8px;
}
.login-title{
  font-family:'Shippori Mincho', serif;
  font-size:28px;
  font-weight:800;
  margin:0 0 6px;
}
.login-sub{
  color:var(--ink-soft);
  font-size:14px;
  margin:0 0 32px;
  max-width:280px;}

/* ===== Buttons ===== */
.btn{
  font-family:'Shippori Mincho', serif;
  font-weight:700;
  font-size:14px;
  border:none;
  border-radius:12px;
  padding:13px 22px;
  cursor:pointer;
  letter-spacing:.02em;
  transition:transform .1s ease, opacity .15s ease;
}
.btn:active{transform:scale(.97);}
.btn:disabled{opacity:.4;cursor:not-allowed;}
.btn-primary{background:var(--torii); color:#fff;}
.btn-primary:hover:not(:disabled){background:var(--torii-deep);}
.btn-ghost{background:transparent; color:var(--ink-soft); border:1px solid rgba(43,38,32,.25);}
.btn-ghost:hover:not(:disabled){background:rgba(43,38,32,.06);}
/* Variante pour les cartes à fond sombre (yokai, missions en cours) : le
   .btn-ghost classique — texte brun sur bordure sombre à faible opacité —
   devenait quasi invisible sur ces fonds presque noirs. Texte clair et
   bordure claire à la place, même logique de "bouton discret". */
.btn-ghost-dark{
  background:rgba(255,255,255,.06);
  color:var(--washi);
  border:1px solid rgba(237,230,214,.35);
}
.btn-ghost-dark:hover:not(:disabled){background:rgba(255,255,255,.12);}
.btn-ghost-dark:disabled{opacity:.4;}
.btn-block{width:100%;}
.btn-small{font-size:11px;padding:8px 14px;border-radius:9px;}

/* ===== Top bar ===== */
.topbar{
  display:flex;
  flex-wrap:wrap;
  justify-content:space-between;
  align-items:center;
  gap:8px 10px;
  padding:calc(14px + env(safe-area-inset-top)) 18px 14px;
  border-bottom:1px solid rgba(43,38,32,.12);
  background:rgba(255,255,255,.4);
}
.player-tag{display:flex;align-items:center;gap:10px;min-width:0;}
.player-avatar{
  width:42px;height:42px;border-radius:50%;
  background:linear-gradient(135deg,#CBA46A,#8B6B3E);
  border:2px solid var(--gold);
  flex-shrink:0;
}
.player-name{
  font-family:'Shippori Mincho', serif;
  font-size:13px;font-weight:700;
}
.player-sub{font-size:10px;color:var(--ink-soft);}
/* Les 3 pastilles ne doivent JAMAIS se comprimer : avec de gros nombres
   (fin de partie, 5-6 chiffres), un simple flex les écrasait l'une contre
   l'autre car flex-shrink vaut 1 par défaut. flex-wrap sur .resources leur
   donne une porte de sortie propre (passer à la ligne) plutôt que de se
   tasser ou de déborder de l'écran. */
.resources{display:flex;flex-wrap:wrap;gap:6px 8px;justify-content:flex-end;}
.res-pill{
  display:flex;align-items:center;gap:5px;
  flex-shrink:0;white-space:nowrap;
  background:rgba(255,255,255,.6);
  border:1px solid rgba(43,38,32,.15);
  border-radius:20px;
  padding:5px 10px;
  font-size:11px;font-weight:700;
  font-variant-numeric:tabular-nums;
}
.res-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0;}
.logout-link{
  font-size:10px;color:var(--ink-soft);
  text-decoration:underline;
  background:none;border:none;cursor:pointer;
  padding:0;margin-top:2px;
}

/* ===== Main content ===== */
.app-main{flex:1;padding:16px 18px calc(96px + env(safe-area-inset-bottom));}

/* ===== Bâtiments du Repaire ===== */
.buildings-list{display:flex;flex-direction:column;gap:9px;}
.building-card{
  display:flex;align-items:center;gap:11px;
  background:rgba(255,255,255,.55);
  border:1px solid rgba(43,38,32,.12);
  border-radius:12px;
  padding:11px 12px;
}
.building-icon{
  width:44px;height:44px;border-radius:10px;
  background:rgba(43,38,32,.06);
  display:flex;align-items:center;justify-content:center;
  flex-shrink:0;
  padding:6px;
}
.building-info{flex:1;min-width:0;}
.building-name-row{display:flex;align-items:center;gap:7px;}
.building-name{font-family:'Shippori Mincho',serif;font-size:12px;font-weight:700;}
.building-level-badge{
  font-size:9px;font-weight:700;
  background:rgba(107,122,84,.18);color:var(--moss);
  padding:2px 7px;border-radius:8px;
}
.building-effect{font-size:10.5px;color:var(--ink-soft);margin-top:3px;}
.building-cost{font-size:9px;color:var(--ink-soft);margin-top:4px;}
.building-cost .insufficient{color:var(--torii-deep);font-weight:700;}
.building-action{
  flex-shrink:0;
  text-align:right;
  /* Empile timer/Accélérer/Récupérer verticalement plutôt que de les laisser
     s'aligner côte à côte par défaut (comportement inline des boutons) —
     Accélérer doit apparaître au-dessus de Récupérer, pas à sa gauche. */
  display:flex;
  flex-direction:column;
  align-items:flex-end;
  gap:6px;
}
.building-timer{font-size:10px;color:var(--torii-deep);font-weight:700;}
.building-max{font-size:10px;color:var(--gold);font-weight:700;}

/* Verrouillé (Sanctuaire, Dojo avant que leur prérequis soit rempli) :
   la carte reste lisible mais clairement en retrait — pas grisée au point
   de sembler désactivée par erreur, juste "pas encore à vous". */
.building-card.building-locked{opacity:.68;}
.building-card.building-locked .building-icon{background:rgba(43,38,32,.04);}
.building-locked-preview{font-style:italic;}
.building-locked-req{
  font-size:9px;font-weight:700;color:var(--ink-soft);
  max-width:110px;line-height:1.35;
}

/* Ligne de cible du Sanctuaire, dans sa carte */
.building-focus-row{
  display:block;width:100%;text-align:left;
  background:none;border:none;padding:5px 0 0;margin:0;
  font-size:10px;font-weight:700;color:var(--torii-deep);
  cursor:pointer;font-family:inherit;
}

/* Permis de double chantier actif : bandeau au-dessus de la liste des
   bâtiments, voir renderBuildings dans app.js. */
.double-chantier-banner{
  display:flex;align-items:center;gap:8px;
  background:rgba(181,75,58,.1);
  border:1px solid rgba(181,75,58,.25);
  border-radius:10px;
  padding:9px 12px;
  margin-bottom:10px;
  font-size:11px;font-weight:700;
  color:var(--torii-deep);
}
.building-focus-row:hover{text-decoration:underline;}

/* ===== Level up (fiche de résultat) ===== */
.result-levelup{
  font-size:11px;color:var(--moss);
  background:rgba(107,122,84,.12);
  border-radius:8px;padding:8px 10px;
  margin-top:-4px;margin-bottom:14px;
}

/* ===== Navigation par onglets ===== */
.bottomnav{
  position:fixed;
  bottom:0;
  left:50%;
  transform:translateX(-50%);
  width:100%;
  max-width:480px;
  display:flex;
  border-top:1px solid rgba(43,38,32,.15);
  background:rgba(237,230,214,.97);
  backdrop-filter:blur(6px);
  z-index:10;
  padding-bottom:env(safe-area-inset-bottom);
}
.nav-item{
  flex:1;
  /* Sans min-width:0, un item flex ne peut jamais rétrécir sous la largeur
     intrinsèque de son contenu (icône + libellé) — avec 6-7 onglets et des
     libellés comme "Missions"/"Boutique", la somme dépassait la largeur de
     la barre sur certains écrans Android, poussant "Arène" hors de l'écran
     sans qu'aucun scroll horizontal ne le révèle. */
  min-width:0;
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:3px;
  background:none;
  border:none;
  font-family:inherit;
  /* La barre du bas est l'élément le plus tapé du jeu et ne renvoyait rien au
     doigt, contrairement aux .btn. */
  transition:transform .1s ease;
  padding:9px 0 7px;
  font-size:10px;
  font-weight:700;
  color:var(--ink-soft);
  cursor:pointer;
  position:relative;
  min-height:52px;          /* cible tactile confortable */
  -webkit-tap-highlight-color:transparent;
}
.nav-item span{
  max-width:100%;
  overflow:hidden;
  text-overflow:ellipsis;
  white-space:nowrap;
}
.nav-item.active{color:var(--torii-deep);}
.nav-icon{font-size:16px;line-height:1;}

/* ===== Boutique ===== */
.shop-list{display:flex;flex-direction:column;gap:9px;}
.shop-item{
  display:flex;align-items:center;gap:11px;
  background:rgba(255,255,255,.55);
  border:1px solid rgba(43,38,32,.12);
  border-radius:12px;
  padding:11px 12px;
}
.shop-item-icon{
  width:44px;height:44px;border-radius:10px;
  background:rgba(43,38,32,.06);
  display:flex;align-items:center;justify-content:center;
  flex-shrink:0;
  padding:6px;
}
.shop-item-info{flex:1;min-width:0;}
.shop-item-name{font-family:'Shippori Mincho',serif;font-size:12px;font-weight:700;}
.shop-item-desc{font-size:10.5px;color:var(--ink-soft);margin-top:3px;line-height:1.4;}
.shop-item-owned{font-size:9px;color:var(--moss);font-weight:700;margin-top:3px;}
.shop-item-action{flex-shrink:0;text-align:right;}
.shop-item-cost{font-size:9px;color:var(--ink-soft);margin-bottom:5px;}
.shop-item-cost.insufficient{color:var(--torii-deep);font-weight:700;}

/* ===== Équipement (sur les cartes tanuki + sélecteur) ===== */
.tanuki-equip{
  margin-top:5px;
  font-size:8px;
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:2px;
}
.tanuki-equipped-tag{color:var(--ink-soft);}
.tanuki-equip-btn{
  font-size:8px;font-weight:700;
  color:var(--torii-deep);
  background:none;border:none;
  text-decoration:underline;
  cursor:pointer;
  padding:0;
}
.equip-pick-row{
  /* Centré et non aligné en haut : la coche fait 16 px et l'icône 26 px, donc
     en flex-start leurs centres se retrouvaient décalés de 4 px et la coche
     paraissait mal posée. */
  display:flex;align-items:center;gap:8px;
  /* Ces lignes sont insérées directement dans .equip-slot-block, qui n'a
     lui-même aucun padding (juste une bordure). Sans marge horizontale ici,
     le rond de sélection et le texte touchaient le bord du bloc. On reprend
     les 12px déjà utilisés par .equip-slot-empty juste à côté pour rester
     cohérent avec le reste de la carte. */
  padding:7px 12px;
  cursor:pointer;
  border-bottom:1px dashed rgba(43,38,32,.1);
  font-size:11px;
  transition:opacity .15s ease;
}
.equip-pick-row:last-child{border-bottom:none;}
/* Pendant l'aller-retour serveur : la ligne se fige visuellement pour montrer
   que le clic a bien été pris en compte. */
.equip-pick-row.equip-en-cours{opacity:.55;pointer-events:none;}
.equip-check{
  width:18px;height:18px;border-radius:50%;
  border:2px solid rgba(43,38,32,.25);
  flex-shrink:0;
  display:flex;align-items:center;justify-content:center;
  font-size:10px;font-weight:900;
  transition:background .12s ease, border-color .12s ease;
}
.equip-check.on{background:var(--gold);border-color:var(--gold);color:#fff;}
.equip-pick-name{flex:1;color:var(--ink);font-weight:700;}
.equip-pick-bonus{color:var(--ink-soft);font-weight:400;}
.equip-pick-warning{font-size:9px;color:var(--torii-deep);font-weight:400;margin-top:2px;}

/* ---------- Choix d'un accélérateur : cartes distinctes, pas une liste ---------- */
/* Les lignes réutilisaient .equip-pick-row (un simple séparateur pointillé,
   pensé pour cocher un objet dans une liste) sans aucune bordure ni case à
   cocher — deux choix côte à côte se distinguaient à peine l'un de l'autre. */
.accel-pick-row{
  display:flex;align-items:center;gap:10px;
  padding:11px 12px;
  margin-bottom:8px;
  border:1px solid rgba(43,38,32,.14);
  border-radius:11px;
  cursor:pointer;
  background:rgba(255,255,255,.5);
  transition:background .12s ease, border-color .12s ease;
  /* Ces lignes reprenaient auparavant .equip-pick-row, qui fixait la taille
     de police à 11px. En perdant cette classe pour leur propre style de
     carte, elles sont retombées sur la taille par défaut, plus grosse. */
  font-size:11px;
}
.accel-pick-row:last-child{margin-bottom:0;}
.accel-pick-row:hover{background:rgba(201,162,39,.12);border-color:var(--gold);}
.accel-pick-row:active{background:rgba(201,162,39,.2);}
.accel-pick-arrow{
  color:var(--ink-soft);font-size:14px;font-weight:700;
  flex-shrink:0;
}

/* ===== Hayashi (alliances) ===== */
.hayashi-intro{text-align:center;padding:20px 12px 6px;}
.hayashi-kanji{
  font-family:'Shippori Mincho',serif;
  font-size:48px;color:var(--torii);
  opacity:.85;line-height:1;
}
.hayashi-intro-title{
  font-family:'Shippori Mincho',serif;
  font-size:18px;font-weight:800;
  margin:8px 0 6px;
}
.hayashi-intro-text{
  font-size:12px;color:var(--ink-soft);
  line-height:1.6;margin:0;
}

.hayashi-input{
  width:100%;
  font-family:inherit;font-size:12px;
  padding:10px 12px;
  border:1px solid rgba(43,38,32,.2);
  border-radius:10px;
  background:rgba(255,255,255,.7);
  color:var(--ink);
}
.hayashi-input:focus{outline:2px solid var(--gold);outline-offset:-1px;}

.hayashi-create-card{
  background:rgba(255,255,255,.55);
  border:1px solid rgba(43,38,32,.12);
  border-radius:12px;
  padding:14px;
  display:flex;flex-direction:column;gap:9px;
}
.hayashi-create-cost{font-size:10px;color:var(--ink-soft);text-align:center;}

.hayashi-directory{display:flex;flex-direction:column;gap:8px;}
.hayashi-dir-row{
  display:flex;align-items:center;gap:10px;
  background:rgba(255,255,255,.55);
  border:1px solid rgba(43,38,32,.12);
  border-radius:11px;
  padding:10px 12px;
}
.hayashi-dir-info{flex:1;min-width:0;}
.hayashi-dir-name{font-family:'Shippori Mincho',serif;font-size:12px;font-weight:700;}
.hayashi-dir-meta{font-size:10px;color:var(--ink-soft);margin-top:2px;}

.hayashi-banner{
  background:linear-gradient(135deg, var(--torii-deep), var(--torii));
  border-radius:14px;
  padding:16px;
  color:var(--washi);
  position:relative;
  overflow:hidden;
}
.hayashi-banner::after{
  content:'囃';
  position:absolute;right:-8px;bottom:-22px;
  font-size:86px;
  font-family:'Shippori Mincho',serif;
  opacity:.15;
}
.hayashi-banner-name{font-family:'Shippori Mincho',serif;font-size:19px;font-weight:800;}
.hayashi-banner-level{font-size:11px;opacity:.9;margin-top:3px;}
.hayashi-bonus-row{display:flex;gap:6px;margin-top:10px;}

/* ---------- Bannières du Hayashi (personnalisation cosmétique, gratuite) ----------
   .hayashi-banner porte déjà le dégradé "torii" par défaut (ci-dessus) ; les
   variantes ne font que le remplacer selon la bannière choisie — le kanji
   ::after et la mise en page restent identiques dans tous les cas. */
.hayashi-banniere-or{ background:linear-gradient(135deg, #9A7A1E, var(--gold)); }
.hayashi-banniere-indigo{ background:linear-gradient(135deg, #1B2033, var(--indigo)); }
.hayashi-banniere-moss{ background:linear-gradient(135deg, #4E5A3E, var(--moss)); }
.hayashi-banniere-nuit{ background:linear-gradient(135deg, #14141C, #3A3550); }

.hayashi-banniere-picker{
  display:flex;gap:7px;margin-top:12px;
}
.banniere-swatch{
  width:22px;height:22px;border-radius:50%;
  border:2px solid rgba(255,255,255,.35);
  cursor:pointer;padding:0;
}
.banniere-swatch.active{border-color:var(--washi);box-shadow:0 0 0 2px rgba(0,0,0,.25);}
.banniere-swatch-torii{background:linear-gradient(135deg, var(--torii-deep), var(--torii));}
.banniere-swatch-or{background:linear-gradient(135deg, #9A7A1E, var(--gold));}
.banniere-swatch-indigo{background:linear-gradient(135deg, #1B2033, var(--indigo));}
.banniere-swatch-moss{background:linear-gradient(135deg, #4E5A3E, var(--moss));}
.banniere-swatch-nuit{background:linear-gradient(135deg, #14141C, #3A3550);}

.hayashi-treasury{
  background:rgba(255,255,255,.55);
  border:1px solid rgba(43,38,32,.12);
  border-radius:12px;
  padding:13px;
}
.treasury-progress-label{
  display:flex;justify-content:space-between;
  font-size:10px;font-weight:700;color:var(--ink-soft);
  margin-bottom:6px;
}
.treasury-track{
  height:8px;background:rgba(43,38,32,.12);
  border-radius:5px;overflow:hidden;margin-bottom:11px;
}
.treasury-fill{height:100%;background:var(--moss);border-radius:5px;transition:width .5s cubic-bezier(.22,1,.36,1);}
.treasury-actions{display:flex;flex-wrap:wrap;gap:8px;}
.treasury-actions .hayashi-input{flex:1 1 90px;min-width:0;}
.treasury-actions #contributeBtn{flex:1 1 100%;}

.hayashi-chat{
  background:rgba(255,255,255,.55);
  border:1px solid rgba(43,38,32,.12);
  border-radius:12px;
  padding:12px 10px 10px;
  display:flex;flex-direction:column;gap:10px;
}
.hayashi-chat-messages{
  display:flex;flex-direction:column;gap:12px;
  max-height:280px;overflow-y:auto;
  /* Sans ce overflow-x explicite, la spec CSS force "visible" à basculer en
     "auto" dès que overflow-y n'est pas "visible" — une barre horizontale
     apparaissait donc même sans aucun contenu trop large. Les messages
     s'enroulent déjà (white-space:pre-wrap + word-break sur .chat-msg-text,
     max-width:78% sur .chat-msg-body) : rien ne dépasse jamais réellement. */
  overflow-x:hidden;
  padding:2px 3px 2px 1px;
  /* Barre verticale fine et discrète plutôt que le rendu natif du
     navigateur (gris, épais, avec flèches) — Firefox. */
  scrollbar-width:thin;
  scrollbar-color:rgba(181,75,58,.35) transparent;
}
.hayashi-chat-messages::-webkit-scrollbar{ width:5px; }
.hayashi-chat-messages::-webkit-scrollbar-track{ background:transparent; }
.hayashi-chat-messages::-webkit-scrollbar-thumb{
  background:rgba(181,75,58,.35);
  border-radius:4px;
}
.hayashi-chat-messages::-webkit-scrollbar-thumb:hover{ background:rgba(181,75,58,.55); }
.hayashi-chat-empty{
  font-size:11px;color:var(--ink-soft);
  text-align:center;padding:18px 0;
}
.hayashi-chat-msg{display:flex;gap:7px;align-items:flex-start;}
.hayashi-chat-msg.own{flex-direction:row-reverse;}
.chat-msg-avatar{
  width:34px;height:34px;flex-shrink:0;
  border-radius:50%;
  background-size:cover;background-position:center 22%;
  background-color:rgba(43,38,32,.08);
  border:1px solid rgba(43,38,32,.1);
  display:flex;align-items:center;justify-content:center;
  font-size:13px;
}
.chat-msg-body{flex:1 1 auto;min-width:0;max-width:78%;}
.hayashi-chat-msg.own .chat-msg-body{margin-left:auto;display:flex;flex-direction:column;align-items:flex-end;}
.hayashi-chat-msg:not(.own) .chat-msg-body{margin-right:auto;}
.chat-msg-head{display:flex;align-items:center;gap:5px;font-size:9px;margin-bottom:3px;padding:0 2px;}
.hayashi-chat-msg.own .chat-msg-head{flex-direction:row-reverse;}
.chat-msg-name{font-weight:700;color:var(--torii-deep);}
.chat-msg-time{color:var(--ink-soft);}
.chat-msg-delete{
  width:17px;height:17px;flex-shrink:0;
  border-radius:50%;
  background:rgba(43,38,32,.08);
  border:none;color:var(--ink-soft);
  font-size:10px;line-height:1;
  cursor:pointer;
  display:flex;align-items:center;justify-content:center;
  opacity:.75;
}
.chat-msg-delete:hover,.chat-msg-delete:active{
  opacity:1;background:rgba(181,67,46,.18);color:var(--torii-deep);
}
.chat-msg-text{
  font-size:12px;line-height:1.45;
  background:rgba(255,255,255,.85);
  border:1px solid rgba(43,38,32,.08);
  border-radius:14px 14px 14px 4px;
  padding:8px 12px;
  display:inline-block;
  max-width:100%;
  word-break:break-word;
  white-space:pre-wrap;
}
.hayashi-chat-msg.own .chat-msg-text{
  background:rgba(201,162,39,.22);
  border-color:rgba(201,162,39,.35);
  border-radius:14px 14px 4px 14px;
}
/* Un message qui N'EST QU'une émote (voir HAYASHI_EMOTES côté client) perd
   sa bulle : à ce format-là, l'émote EST le message, la bulle de texte
   habituelle la ferait ressembler à un mot plutôt qu'à une réaction. */
.chat-msg-text-emote-solo{
  font-size:30px;line-height:1;
  background:none;border:none;
  padding:2px 4px;
}
.hayashi-emote-bar{
  display:flex;gap:2px;overflow-x:auto;
  padding:2px 0 6px;
  scrollbar-width:none;
}
.hayashi-emote-bar::-webkit-scrollbar{display:none;}
.hayashi-emote-btn{
  flex-shrink:0;
  font-size:18px;line-height:1;
  background:none;border:none;cursor:pointer;
  padding:4px 6px;border-radius:8px;
}
.hayashi-emote-btn:hover,.hayashi-emote-btn:active{background:rgba(43,38,32,.08);}
.hayashi-chat-input-row{display:flex;gap:6px;}
.hayashi-chat-input-row .hayashi-input{flex:1;}
.hayashi-chat-input-row button{flex-shrink:0;}

.hayashi-members{display:flex;flex-direction:column;gap:6px;}
.hayashi-member-row{
  display:flex;align-items:center;gap:9px;
  background:rgba(255,255,255,.5);
  border-radius:9px;
  padding:8px 11px;
  font-size:11px;
}
.member-role{font-size:13px;flex-shrink:0;}
.member-name{flex:1;font-weight:700;}
.member-contrib{color:var(--moss);font-weight:700;font-size:10px;}

/* ===== Raids ===== */
.raid-empty{
  background:rgba(255,255,255,.55);
  border:1px dashed rgba(43,38,32,.2);
  border-radius:12px;
  padding:14px;
  text-align:center;
}
.raid-empty p{font-size:11px;color:var(--ink-soft);margin:0 0 11px;}

.raid-card{
  background:var(--indigo-deep);
  border-radius:14px;
  padding:14px;
  color:var(--washi);
}
.raid-card.defeated{background:linear-gradient(135deg,#2d4030,#1a2620);}
/* Portrait du boss, en bandeau tout en haut de la carte : marges négatives
   pour "déborder" du padding de .raid-card et toucher ses bords, comme le
   fait déjà .yokai-art-stage pour la fiche d'un yokai classique. Deux
   calques plutôt qu'un seul : le flou (voile de contenu sensible) doit
   s'appliquer À L'IMAGE seulement, jamais à l'icône posée par-dessus — un
   filter CSS sur le conteneur aurait flouté ses enfants aussi. */
.raid-boss-portrait{
  position:relative;
  margin:-14px -14px 10px;
  /* Hauteur stable en clamp() plutôt que le duo aspect-ratio/max-height
     d'avant, qui entrait en conflit sur mobile : quand max-height rognait la
     hauteur voulue par aspect-ratio, la boîte réelle ne respectait plus le
     ratio 900:529, et background-size:cover rognait bien plus qu'attendu —
     les têtes de Yamata disparaissaient du cadre selon la largeur d'écran. */
  height:clamp(150px, 42vw, 200px);
  border-radius:14px 14px 0 0;
  overflow:hidden;
  background:var(--indigo-deep);
}
/* Fond : la même image, agrandie et floutée, pour combler l'espace autour
   d'une illustration qui n'a pas exactement les proportions du bandeau —
   même technique que .yokai-art-blur/.yokai-art pour la fiche d'un yokai
   classique. Toujours présent, y compris quand l'image nette est révélée :
   sans lui, une image plus large ou plus haute que le cadre laisserait des
   bandes du fond --indigo-deep uni de part et d'autre. */
.raid-boss-portrait-blur{
  position:absolute; inset:-20px;
  background-size:cover; background-position:center;
  filter:blur(18px) saturate(1.1);
  opacity:.6;
}
/* L'illustration nette, entière, JAMAIS rognée (contain plutôt que cover) :
   la tête de dragon la plus proche du bord ne disparaît plus jamais, quel
   que soit le ratio réel du bandeau selon l'écran. */
.raid-boss-portrait-img{
  position:absolute; inset:0;
  background-size:contain; background-position:center;
  background-repeat:no-repeat;
}
/* Contenu sensible : LES DEUX calques passent au flou (fond + image nette),
   l'illustration devient donc indiscernable dans son ensemble, pas
   seulement sur son pourtour — inset négatif et scale, même raisonnement que
   .raid-boss-portrait-blur ci-dessus, pour éviter une bordure transparente
   sur les bords du flou. */
.raid-boss-portrait-img.voile{
  inset:-20px;
  background-size:cover;
  filter:blur(18px) saturate(.8) brightness(.6);
  transform:scale(1.15);
}
.raid-boss-veil{
  position:absolute; inset:0;
  display:flex; align-items:center; justify-content:center;
  background:rgba(15,14,25,.28);
}
.raid-boss-veil-icon{ font-size:34px; filter:drop-shadow(0 2px 4px rgba(0,0,0,.5)); }
.raid-boss-name{
  font-family:'Shippori Mincho',serif;
  font-size:15px;font-weight:800;
  margin-bottom:8px;
}
.raid-hp-label{
  display:flex;justify-content:space-between;
  font-size:10px;color:#9aa4c4;font-weight:700;
  margin-bottom:5px;
}
.raid-hp-track{
  height:10px;background:rgba(255,255,255,.1);
  border-radius:6px;overflow:hidden;margin-bottom:12px;
}
.raid-hp-fill{
  height:100%;border-radius:6px;
  background:linear-gradient(90deg,#B5432E,#E8794A);
  /* Plus vif que les barres de progression : un dégât doit se sentir
     immédiat, pas glisser doucement. */
  transition:width .3s ease-out;
}
.raid-leaderboard{
  background:rgba(255,255,255,.05);
  border-radius:9px;
  padding:8px 10px;
  margin-bottom:12px;
}
.raid-lb-row{
  display:flex;align-items:center;gap:8px;
  font-size:10px;padding:3px 0;
}
.raid-lb-rank{
  width:16px;color:#E8C97A;font-weight:700;flex-shrink:0;
}
.raid-lb-name{flex:1;}
.raid-lb-dmg{color:#E8C97A;font-weight:700;}
.raid-note{
  font-size:11px;color:#9aa4c4;
  text-align:center;padding:6px 0;
}

/* ===== Sélecteur d'équipement (7 emplacements) ===== */
.equip-card{
  max-height:82vh;overflow-y:auto;text-align:left;
  /* Même traitement que la fiche d'illustration yokai : la barre de défilement
     par défaut du navigateur casse l'habillage washi. */
  scrollbar-width:none;
  -ms-overflow-style:none;
}
.equip-card::-webkit-scrollbar{display:none;}
.equip-header{
  display:flex;align-items:center;gap:11px;
  padding-bottom:12px;
  border-bottom:1px solid rgba(43,38,32,.12);
  margin-bottom:12px;
}
.equip-header-portrait{
  width:46px;height:46px;border-radius:10px;
  background-size:cover;background-position:center 22%;
  background-color:var(--washi-deep);
  flex-shrink:0;
}
.equip-header-name{font-family:'Shippori Mincho',serif;font-size:15px;font-weight:800;}
.equip-header-meta{font-size:10px;color:var(--ink-soft);margin-top:2px;}

.equip-slots{display:flex;flex-direction:column;gap:5px;}
.equip-slot-block{
  border:1px solid rgba(43,38,32,.12);
  border-radius:10px;
  background:rgba(255,255,255,.45);
  overflow:hidden;
}
.equip-slot-block.open{border-color:var(--gold);background:rgba(201,162,39,.08);}
.equip-slot-row{
  display:flex;align-items:center;gap:9px;
  padding:8px 10px;
  cursor:pointer;
}
.equip-slot-icon{font-size:16px;flex-shrink:0;width:22px;text-align:center;}
.equip-slot-main{flex:1;min-width:0;}
.equip-slot-title{
  font-family:'Shippori Mincho',serif;
  font-size:11px;font-weight:700;
}
/* Avec l'arrivée de la Vitesse, un objet peut porter quatre statistiques :
   « +12 For · +12 Rus · +10 Cha · +8 Vit » fait 36 caractères là où trois en
   faisaient 26. On autorise le retour à la ligne plutôt que de tronquer —
   masquer une statistique serait pire que d'occuper deux lignes. */
.equip-slot-current{
  font-size:10px;font-weight:700;margin-top:1px;
  line-height:1.35;overflow-wrap:anywhere;
}
.equip-slot-bonus{color:var(--ink-soft);font-weight:400;}
.equip-slot-vacant{font-size:10px;color:var(--ink-soft);margin-top:1px;}
.equip-slot-remove{
  font-size:12px;color:var(--torii-deep);
  background:none;border:none;cursor:pointer;
  padding:2px 5px;flex-shrink:0;
}
.equip-slot-empty{
  font-size:10px;color:var(--ink-soft);
  padding:6px 12px 9px;
}
.equip-legacy-note{
  font-size:10px;color:var(--torii-deep);
  background:rgba(181,75,58,.1);
  border-radius:8px;padding:8px 10px;
  margin-bottom:10px;
}

/* ===== Recrutement et rangs ===== */
.recruit-intro{
  font-size:10px;color:var(--ink-soft);
  line-height:1.5;margin-bottom:10px;
}
.recruit-list{display:flex;flex-direction:column;gap:7px;}
.recruit-row{
  display:flex;align-items:center;gap:10px;
  background:rgba(255,255,255,.5);
  border:1px solid rgba(43,38,32,.12);
  border-radius:11px;
  padding:9px 11px;
}
.recruit-row.ready{border-color:var(--gold);background:rgba(201,162,39,.1);}
.recruit-portrait{
  width:40px;height:40px;border-radius:9px;
  background-size:cover;background-position:center 22%;
  background-color:var(--washi-deep);
  flex-shrink:0;
}
.recruit-portrait.locked{filter:grayscale(1);opacity:.55;}
.recruit-info{flex:1;min-width:0;}
.recruit-name{font-family:'Shippori Mincho',serif;font-size:12px;font-weight:700;}
.recruit-meta{font-size:9px;color:var(--ink-soft);margin-top:1px;}
.recruit-frag-track{
  height:4px;background:rgba(43,38,32,.12);
  border-radius:3px;overflow:hidden;margin-top:5px;
}
.recruit-frag-fill{height:100%;background:var(--gold);border-radius:3px;transition:width .5s cubic-bezier(.22,1,.36,1);}
.recruit-frag-count{font-size:9px;color:var(--ink-soft);margin-top:2px;font-weight:700;}
.recruit-max{
  font-size:10px;font-weight:700;color:var(--gold);
  flex-shrink:0;
}
.recruit-meta.muted{
  opacity:.65;
  font-style:italic;
}

/* Fragments universels — voir convertToUniversalFragment (index.js) :
   5 fragments d'un tanuki déjà au rang max deviennent 1 fragment utilisable
   pour recruter ou monter en rang n'importe quel autre tanuki. */
.universal-frag-bar{
  display:flex;
  flex-wrap:wrap;
  align-items:center;
  gap:6px 10px;
  background:rgba(201,162,39,.12);
  border:1px solid rgba(201,162,39,.35);
  border-radius:11px;
  padding:9px 12px;
  margin-bottom:12px;
  font-size:12px;
  font-weight:700;
}
.universal-frag-icon{
  color:var(--gold);
  font-size:16px;
}
.universal-frag-hint{
  font-size:10px;
  font-weight:500;
  color:var(--ink-soft);
  width:100%;
}
.convert-universal-btn{
  flex-shrink:0;
}

/* ===== Récapitulatif de retour ===== */
.recap-absence{
  font-size:11.5px;color:var(--ink-soft);
  margin:2px 0 12px;
}
.recap-list{display:flex;flex-direction:column;gap:7px;text-align:left;}
.recap-row{
  display:flex;align-items:center;gap:9px;
  background:rgba(255,255,255,.45);
  border:1px solid rgba(43,38,32,.1);
  border-radius:10px;padding:9px 11px;
}
.recap-icon{font-size:16px;flex-shrink:0;line-height:1;}
.recap-text{font-size:12.5px;color:var(--ink);line-height:1.35;}

/* ===== Voies et traits passifs des tanukis ===== */
.voie-traits-section{
  border:1px solid rgba(43,38,32,.12);
  border-radius:11px;
  background:rgba(255,255,255,.4);
  padding:10px 11px;
  margin-bottom:10px;
}
.voie-traits-title{
  font-family:'Shippori Mincho',serif;
  font-size:11px;font-weight:700;color:var(--ink-soft);
  margin-bottom:5px;
}
.voie-badge{
  display:inline-flex;flex-direction:column;
  font-size:11px;font-weight:700;color:var(--torii-deep);
  background:rgba(181,75,58,.1);
  border-radius:8px;padding:6px 9px;
}
.voie-badge-desc{font-size:9px;font-weight:400;color:var(--ink-soft);margin-top:1px;}
.voie-locked{font-size:9.5px;color:var(--ink-soft);}
.voie-choice-intro{font-size:9.5px;color:var(--ink-soft);margin-bottom:5px;}
.voie-choice-row{display:flex;flex-wrap:wrap;gap:6px;}
.voie-choice-btn, .trait-choice-btn{
  display:flex;flex-direction:column;align-items:flex-start;
  text-align:left;line-height:1.3;
}
.trait-choice-desc{font-size:8.5px;font-weight:400;opacity:.75;margin-top:1px;}
.trait-chip-row{display:flex;flex-wrap:wrap;gap:6px;}
.trait-chip{
  display:inline-flex;flex-direction:column;
  font-size:10px;font-weight:700;color:var(--ink);
  background:rgba(201,162,39,.14);
  border:1px solid rgba(201,162,39,.35);
  border-radius:8px;padding:5px 8px;
}
.trait-chip-desc{font-size:8.5px;font-weight:400;color:var(--ink-soft);margin-top:1px;}
.voie-pending-dot{
  display:inline-block;width:7px;height:7px;border-radius:50%;
  background:var(--torii);margin-left:5px;vertical-align:middle;
  box-shadow:0 0 0 2px rgba(181,75,58,.25);
}

.rank-stars{
  font-size:9px;color:var(--gold);
  letter-spacing:-.5px;
}
.tanuki-rank{margin-top:1px;}
.tanuki-item-count{font-size:8px;color:var(--ink-soft);}

.result-fragment{
  font-size:11px;font-weight:700;
  color:#9A7A1E;
  background:rgba(201,162,39,.14);
  border-radius:8px;padding:8px 10px;
  margin-bottom:12px;
  display:flex;align-items:center;gap:7px;justify-content:center;
}

/* ===== Inventaire — grille v2 =====
   3 colonnes (au lieu de 4) : tuiles plus grandes, avec libellé de rareté,
   score et nom tronqué visibles directement — sans avoir à ouvrir la fiche
   détail pour un premier repère. */
.inventory-grid{
  display:grid;
  grid-template-columns:repeat(3, 1fr);
  gap:9px;
  margin-top:8px;
}

.inv-tile{
  position:relative;
  border-radius:12px;
  background:rgba(255,255,255,.72);
  border:2px solid var(--rarity, rgba(43,38,32,.12));
  padding:8px 6px 6px;
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:3px;
  cursor:pointer;
  transition:transform .1s ease, box-shadow .12s ease;
  min-height:96px;
}
.inv-tile:active{ transform:scale(.97); }
.inv-tile.selected{
  box-shadow:0 0 0 2px var(--gold);
  background:rgba(201,162,39,.14);
}
.inv-tile.equipped{
  opacity:.78;
}

/* léger fond teinté selon la rareté */
.inv-tile::before{
  content:"";
  position:absolute;inset:0;
  border-radius:10px;
  background:var(--rarity);
  opacity:.07;
  pointer-events:none;
}

.inv-tile-icon{
  width:34px;height:34px;
  display:flex;align-items:center;justify-content:center;
  margin-top:2px;
}
.inv-tile-icon svg,
.inv-tile-icon .item-icon{
  width:32px !important;
  height:32px !important;
}

.inv-tile-rarity{
  font-size:8.5px;
  font-weight:800;
  text-transform:uppercase;
  letter-spacing:.03em;
  color:var(--rarity);
  line-height:1;
}

.inv-tile-score{
  font-family:'Shippori Mincho',serif;
  font-size:13px;
  font-weight:800;
  color:var(--ink);
  line-height:1.1;
}

.inv-tile-name{
  font-size:9.5px;
  font-weight:600;
  color:var(--ink-soft);
  text-align:center;
  line-height:1.2;
  max-width:100%;
  overflow:hidden;
  text-overflow:ellipsis;
  white-space:nowrap;
  padding:0 2px;
}

/* Badge équipé */
.inv-tile-eq{
  position:absolute;
  top:5px;left:5px;
  min-width:16px;height:16px;
  border-radius:6px;
  background:var(--moss);
  color:#fff;
  font-size:9px;font-weight:800;
  display:flex;align-items:center;justify-content:center;
  padding:0 3px;
  line-height:1;
}

/* Check de sélection fusion */
.inv-tile-check{
  position:absolute;
  top:4px;right:4px;
  width:18px;height:18px;border-radius:50%;
  background:var(--gold);color:#fff;
  font-size:11px;font-weight:900;
  display:flex;align-items:center;justify-content:center;
  box-shadow:0 1px 3px rgba(43,38,32,.25);
}

/* Consommables : toujours visibles en haut de l'inventaire, indépendamment
   du filtre de rareté (qui ne s'applique qu'à l'équipement ci-dessous). */
.inv-consumables{margin-bottom:12px;}
.inv-consumables-title{
  font-size:9.5px;font-weight:700;color:var(--ink-soft);
  text-transform:uppercase;letter-spacing:.04em;
  margin-bottom:6px;
}
.inv-consumables-row{display:flex;flex-wrap:wrap;gap:6px;}
.inv-consumable-chip{
  display:flex;align-items:center;gap:6px;
  background:rgba(255,255,255,.55);
  border:1px solid rgba(43,38,32,.12);
  border-radius:20px;
  padding:4px 10px 4px 4px;
}
/* Seul le Permis de double chantier se clique directement depuis cette
   barre (voir wireConsumableChipClicks) — indice visuel pour le distinguer
   des autres puces, purement informatives. */
.inv-consumable-chip.usable{
  cursor:pointer;
  border-color:rgba(201,162,39,.45);
  transition:background .12s ease, border-color .12s ease;
}
.inv-consumable-chip.usable:hover{
  background:rgba(201,162,39,.14);
  border-color:var(--gold);
}
.inv-consumable-chip.usable:active{transform:scale(.97);}
.inv-consumable-name{font-size:10px;font-weight:600;color:var(--ink);}
.inv-consumable-qty{font-size:10px;font-weight:700;color:var(--torii-deep);}

.fusion-bar{
  background:rgba(255,255,255,.55);
  border:1px solid rgba(43,38,32,.12);
  border-radius:11px;
  padding:11px 12px;
  margin-bottom:11px;
}
.fusion-info{font-size:10px;color:var(--ink-soft);line-height:1.5;}
.fusion-info strong{color:var(--ink);}
.fusion-status{
  font-size:10px;font-weight:700;
  color:var(--torii-deep);
  margin:7px 0 8px;
}

/* ===== Objets sur les cartes tanuki ===== */
.tanuki-stats{
  display:flex;justify-content:center;gap:7px;flex-wrap:wrap;
  margin-top:4px;
}
/* Chaque statistique porte son initiale dans une pastille colorée : la
   couleur permet de la repérer d'un coup d'œil sans lire, l'initiale lève
   l'ambiguïté, et le title détaille l'effet pour qui veut savoir. */
.stat-pastille{
  display:inline-flex;align-items:center;gap:3px;
  font-size:10px;font-weight:800;color:var(--ink);
  cursor:help;
}
.stat-pastille i{
  display:inline-flex;align-items:center;justify-content:center;
  width:12px;height:12px;border-radius:3px;
  font-style:normal;font-size:8px;font-weight:800;
  color:#F7F2E6;
}
.tanuki-item{font-size:8px;font-weight:700;line-height:1.3;}
.tanuki-item.empty{color:var(--ink-soft);font-weight:400;}

/* ===== Objet trouvé (fiche de résultat) ===== */
.result-drop{
  border:2px solid var(--gold);
  border-radius:10px;
  padding:10px;
  margin-bottom:14px;
  background:rgba(255,255,255,.5);
  display:flex;align-items:center;gap:11px;text-align:left;
}
.result-drop-label{
  font-size:9px;text-transform:uppercase;
  letter-spacing:.1em;color:var(--ink-soft);
  font-weight:700;margin-bottom:3px;
}
.result-drop-name{font-family:'Shippori Mincho',serif;font-size:13px;font-weight:800;}
.result-drop-meta{font-size:10px;color:var(--ink-soft);margin-top:2px;}

/* ===== Section headers ===== */
.section-title{
  font-family:'Shippori Mincho', serif;
  font-size:15px;font-weight:700;
  margin:22px 0 10px;
  display:flex;align-items:center;gap:7px;
}
.section-title:first-child{margin-top:0;}
.section-title::before{
  content:'';
  width:3px;height:15px;
  background:var(--torii);
  display:inline-block;
}
.section-empty{
  font-size:12px;color:var(--ink-soft);
  background:rgba(255,255,255,.4);
  border:1px dashed rgba(43,38,32,.2);
  border-radius:10px;
  padding:14px;
  text-align:center;
}

/* ===== Tanuki roster ===== */
.roster-grid{
  display:grid;
  grid-template-columns:repeat(3,1fr);
  gap:9px;
}
.tanuki-card{
  background:rgba(255,255,255,.55);
  border:1px solid rgba(43,38,32,.12);
  border-radius:12px;
  padding:8px;
  text-align:center;
  position:relative;
}
.tanuki-portrait{
  width:100%;aspect-ratio:280/546;
  border-radius:9px;
  margin-bottom:6px;
  background-size:cover;
  background-position:center top;
  background-color:var(--washi-deep);
}
.tanuki-name{font-size:11px;font-weight:700;line-height:1.25;}
.tanuki-level{font-size:8px;font-weight:400;color:var(--ink-soft);}
.tanuki-power{
  display:inline-block;
  font-size:10px;font-weight:700;
  color:var(--torii-deep);
  background:rgba(201,162,39,.24);
  border-radius:7px;
  padding:1px 7px;
  margin-top:2px;
}
.tanuki-faction{font-size:9px;color:var(--ink-soft);margin-bottom:4px;}
.tanuki-status{
  font-size:8px;font-weight:700;
  padding:2px 6px;border-radius:8px;
  display:inline-block;
}
.status-idle{background:rgba(107,122,84,.18);color:var(--moss);}
.status-onMission{background:rgba(181,75,58,.15);color:var(--torii-deep);}
.status-resting{background:rgba(43,38,32,.1);color:var(--ink-soft);}
.tanuki-rest-timer{
  font-size:8px;
  color:var(--ink-soft);
  margin-top:3px;
}

/* ===== Active missions ===== */
.claim-all-bar{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:10px;
  background:rgba(107,122,84,.14);
  border:1px solid rgba(107,122,84,.35);
  border-radius:11px;
  padding:10px 12px;
  margin-bottom:10px;
  font-size:12px;
  font-weight:700;
  color:var(--ink);
}
.mission-active-card{
  background:var(--indigo-deep);
  color:var(--washi);
  border-radius:12px;
  padding:12px;
  margin-bottom:9px;
  display:flex;
  align-items:center;
  gap:10px;
}
.mission-active-left{
  display:flex;align-items:center;gap:10px;
  flex:1;min-width:0;
}
.mission-active-portrait{
  width:36px;height:36px;
  border-radius:8px;
  flex-shrink:0;
  background-size:cover;
  background-position:center 22%;
  background-color:var(--indigo);
}
.mission-active-name{font-family:'Shippori Mincho',serif;font-size:12px;font-weight:700;}
.mission-active-actions{
  display:flex;flex-direction:column;
  align-items:flex-end;gap:5px;
  flex-shrink:0;
}
.mission-active-timer{font-size:10px;color:#9aa4c4;margin-top:2px;}
.mission-active-timer.ready{color:#E8C97A;font-weight:700;}

/* ===== Yokai targets ===== */
.yokai-card{
  background:var(--indigo-deep);
  border-radius:12px;
  padding:11px 12px;
  margin-bottom:9px;
  color:var(--washi);
}
.yokai-head{
  display:flex;justify-content:space-between;align-items:center;
  gap:10px;
}
.yokai-head-left{display:flex;align-items:center;gap:10px;min-width:0;}
/* État fermé : le bouton se centre sur la carte entière (portrait + nom +
   étiquettes), pas seulement sur la première ligne — sinon il paraît décalé
   vers le haut dès que la rangée d'étiquettes s'ajoute en dessous. */
.yokai-card-row{display:flex;align-items:center;justify-content:space-between;gap:12px;}
.yokai-card-body{flex:1;min-width:0;}
.yokai-portrait{
  width:46px;height:46px;
  border-radius:9px;
  flex-shrink:0;
  background-size:cover;
  background-position:center 22%;
  background-color:var(--indigo);
  border:1px solid rgba(255,255,255,.12);
}
.yokai-name{font-family:'Shippori Mincho',serif;font-size:13px;font-weight:700;}
.yokai-power{font-size:10px;color:#8b93ab;margin-top:2px;}
.yokai-tags{display:flex;gap:5px;margin-top:6px;}
.tag{
  font-size:8px;font-weight:700;
  padding:2px 7px;border-radius:8px;
  background:rgba(255,255,255,.1);
}
.tag.gold{color:#E8C97A;}

/* ===== Squad selection ===== */
.squad-panel{
  margin-top:10px;
  border-top:1px solid rgba(255,255,255,.12);
  padding-top:10px;
}
.squad-pick-row{
  display:flex;align-items:center;gap:8px;
  padding:6px 0;
  cursor:pointer;
}
.squad-pick-row.disabled{opacity:.35;cursor:not-allowed;}
.squad-checkbox{
  width:16px;height:16px;border-radius:50%;
  border:2px solid rgba(255,255,255,.3);
  flex-shrink:0;
  display:flex;align-items:center;justify-content:center;
  font-size:9px;font-weight:900;
}
.squad-checkbox.on{background:var(--gold);border-color:var(--gold);color:var(--indigo-deep);}
.squad-pick-portrait{
  width:26px;height:26px;
  border-radius:50%;
  flex-shrink:0;
  background-size:cover;
  background-position:center 22%;
  background-color:var(--washi-deep);
  border:1px solid rgba(255,255,255,.15);
}
.squad-pick-name{font-size:11px;flex:1;}
.squad-pick-power{font-size:10px;color:#E8C97A;font-weight:700;}
.squad-compare{
  display:flex;justify-content:space-between;
  font-size:10px;color:#8b93ab;
  margin:8px 0;
}
.squad-actions{display:flex;gap:8px;margin-top:8px;}

/* Bonus de faction (à partir de 3 membres d'une même faction) — même palette
   que le reste du panneau d'escouade (fond dark, accent doré). */
.faction-bonus-summary{
  margin:8px 0;
  padding:8px 10px;
  background:rgba(255,255,255,.06);
  border:1px solid rgba(255,255,255,.12);
  border-radius:10px;
  font-size:11px;
}
.faction-bonus-title{
  font-weight:700;
  font-size:10px;
  color:#8b93ab;
  text-transform:uppercase;
  letter-spacing:.04em;
  margin-bottom:6px;
}
.faction-bonus{
  display:flex;
  justify-content:space-between;
  gap:8px;
  padding:3px 0;
}
.faction-bonus.active .faction-name{
  font-weight:700;
  color:var(--gold);
}
.faction-bonus.inactive{opacity:.55;}
.faction-effect{color:#8b93ab;text-align:right;}

/* ===== Result panel (after claim) ===== */
.result-overlay{
  position:fixed;inset:0;
  background:rgba(21,25,37,.75);
  display:flex;align-items:center;justify-content:center;
  padding:24px;
  z-index:50;
}
.result-card{
  background:var(--washi);
  border-radius:16px;
  padding:24px 20px;
  max-width:340px;
  width:100%;
  text-align:center;
}
.result-stamp{
  width:76px;height:76px;
  margin:0 auto 12px;
  border:3px solid var(--torii);
  border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  font-family:'Shippori Mincho',serif;
  font-size:12px;font-weight:800;color:var(--torii);
  transform:rotate(-8deg);
}
.result-stamp.outcome-defeat{
  border-color:var(--ink-soft);
  color:var(--ink-soft);
}
.result-injury{
  font-size:11px;
  color:var(--torii-deep);
  background:rgba(181,75,58,.1);
  border-radius:8px;
  padding:8px 10px;
  margin-top:-4px;
  margin-bottom:14px;
}
.result-title{font-family:'Shippori Mincho',serif;font-size:17px;font-weight:800;margin-bottom:4px;}
.result-loot{
  background:rgba(255,255,255,.6);
  border-radius:10px;
  padding:10px;
  margin:14px 0;
  text-align:left;
}
.result-loot-row{
  display:flex;justify-content:space-between;
  font-size:11px;font-weight:700;
  padding:4px 0;
}

.confirm-message{font-size:12px;color:var(--ink-soft);line-height:1.5;}
.confirm-actions{display:flex;gap:8px;margin-top:16px;}
/* min-width:0 : sans ça, un bouton garde sa largeur de contenu naturelle
   même avec flex:1, et un libellé long en un seul mot (ex. "Sélectionner")
   pousse tout le groupe hors du cadre au lieu de se laisser comprimer.
   overflow-wrap en filet de sécurité si même la version .btn-small déborde
   encore sur un très petit écran : le mot casse plutôt que de dépasser. */
.confirm-actions .btn{flex:1;min-width:0;overflow-wrap:break-word;}

.toast{
  position:fixed;
  bottom:20px;left:50%;
  transform:translateX(-50%);
  background:var(--ink);
  color:var(--washi);
  padding:10px 18px;
  border-radius:10px;
  font-size:12px;
  z-index:60;
}


/* ===================================================================
   AJOUTS — illustrations, pronostics, badges et confort de lecture
   Ce bloc est volontairement placé en fin de fichier : en CSS, à poids
   égal, c'est la dernière règle qui gagne. Vous pouvez donc l'ajuster
   sans toucher à tout ce qui précède.
   =================================================================== */

/* ---------- Illustrations vectorielles (icons.js) ---------- */
.icon-svg{width:100%;height:100%;display:block;}

.item-icon{
  width:34px;height:34px;
  flex-shrink:0;
  display:flex;align-items:center;justify-content:center;
  border-radius:9px;
  background:rgba(43,38,32,.07);
  padding:3px;
}
/* Les icônes sont dessinées sur une grille de 48 unités avec un trait de 1,6.
   Réduites dans une boîte de 26 px, ce trait tombe à 0,73 pixel réel :
   l'anticrénelage le délaye en gris pâle et le dessin paraît sale.
   On compense l'épaisseur à chaque taille pour viser ~1,2 px à l'écran.
   La règle CSS l'emporte sur l'attribut stroke-width du <svg>, mais PAS sur
   celui d'un <path> qui le redéfinit — les traits volontairement épais
   (le bâton, par exemple) gardent donc leur proportion. */
/* Valeurs recalculées depuis l'agrandissement de 15 % appliqué dans wrap()
   (icons.js) : il épaissit mécaniquement le trait d'autant. */
.item-icon .icon-svg{ stroke-width:1.9; }
.item-icon.sm .icon-svg{ stroke-width:2.4; }
.item-icon.lg .icon-svg{ stroke-width:1.5; }
/* Même correction pour les deux autres emplacements réduits (44 px de boîte,
   32 px de dessin). La révélation d'objet, elle, affiche l'icône à 52 px :
   le trait y fait déjà 1,7 px réel, elle n'a besoin de rien. */
.shop-item-icon .icon-svg,
.building-icon .icon-svg{ stroke-width:1.65; }
.item-icon.sm{width:26px;height:26px;padding:2px;border-radius:7px;}
.item-icon.lg{width:46px;height:46px;padding:5px;border-radius:11px;}
.item-icon.vacant{opacity:.45;}

/* Petites feuilles / flammes des coûts et du butin */
.res-ico{
  width:13px;height:13px;
  display:inline-block;vertical-align:-2px;
  margin-left:3px;
}
.res-ico.feuilles{color:var(--moss);}
.res-ico.essence{color:var(--indigo);}
.cost-chunk{white-space:nowrap;}
.cost-chunk + .cost-chunk{margin-left:8px;}

/* ---------- Barre du haut : compteurs de ressources ---------- */
.res-pill{gap:3px;transition:transform .18s ease;}
.res-pill .res-ico{width:14px;height:14px;margin:0 1px 0 0;}
@keyframes resBump{
  0%{transform:scale(1);}
  35%{transform:scale(1.18);}
  100%{transform:scale(1);}
}
.res-pill.bump{animation:resBump .45s ease;}

/* ---------- Écran de démarrage ---------- */
.boot-dots{display:flex;gap:7px;margin-top:18px;}
.boot-dots span{
  width:7px;height:7px;border-radius:50%;
  background:var(--torii);opacity:.35;
  animation:bootPulse 1.1s ease-in-out infinite;
}
.boot-dots span:nth-child(2){animation-delay:.16s;}
.boot-dots span:nth-child(3){animation-delay:.32s;}
@keyframes bootPulse{0%,100%{opacity:.25;}50%{opacity:.9;}}

/* ---------- Cartes tanuki : XP et emplacements ---------- */
.tanuki-xp-track{
  height:3px;background:rgba(43,38,32,.12);
  border-radius:2px;overflow:hidden;
  margin:5px 0 2px;
}
.tanuki-xp-fill{height:100%;background:var(--gold);border-radius:2px;transition:width .5s cubic-bezier(.22,1,.36,1);}
.tanuki-xp-label{
  font-size:7.5px;color:var(--ink-soft);
  text-align:right;
  margin-bottom:4px;
}

.tanuki-slot-dots{
  display:flex;justify-content:center;gap:3px;
  margin:5px 0 4px;
}
.slot-dot{
  width:6px;height:6px;border-radius:50%;
  border:1px solid rgba(43,38,32,.22);
  background:transparent;
}
.slot-dot.on{border-color:transparent;}

.tanuki-equip-btn{
  display:inline-flex;align-items:center;gap:4px;
  padding:3px 2px;font-size:9px;
}
.tanuki-item-count{
  font-size:8.5px;color:var(--ink-soft);
  background:rgba(43,38,32,.08);
  border-radius:6px;padding:1px 4px;
  text-decoration:none;
}

/* ---------- Bâtiments : aperçu du niveau suivant ---------- */
.building-next{
  font-size:9.5px;color:var(--moss);font-weight:700;
  margin-top:3px;
}

/* ---------- Boutique : ce qui manque pour acheter ---------- */
.shop-item-missing{
  font-size:9.5px;color:var(--torii-deep);font-weight:700;
  margin-top:4px;
}
.shop-item-limit{
  font-size:9px;color:var(--ink-soft);
  margin-top:3px;
}
.shop-item-limit.reached{color:var(--torii-deep);font-weight:700;}
.shop-item-cost{display:flex;justify-content:flex-end;align-items:center;}

/* Bouton de reset de boutique (Essence, coût exponentiel par objet) */
.shop-reset-btn{
  margin-top:5px;
  font-size:9px;font-weight:700;
  padding:5px 9px;border-radius:8px;
  border:1px solid rgba(201,162,39,.5);
  background:rgba(201,162,39,.14);color:var(--torii-deep);
  cursor:pointer;
}
.shop-reset-btn:disabled{opacity:.45;cursor:default;}

/* ---------- Packs cosmétiques (Boutique) ----------
   Trois vitrines à thème (cadre + titre + couleur de pseudo), rendues avec
   la structure .shop-item existante : seule la colonne d'aperçu diffère —
   une pastille .cadre-swatch portant le VRAI cadre, pas une icône. Le
   padding-top laisse la place au linteau du torii et aux oreilles du yokai
   qui débordent au-dessus de la pastille. */
.pack-preview{
  width:44px;flex-shrink:0;
  display:flex;align-items:center;justify-content:center;
  padding-top:10px;
}
/* Variante de .pack-preview pour un pack dont la pièce cadre est en fait un
   skin de clairière (glyphe + couleur, pas de padding-top : rien ne déborde
   au-dessus d'un médaillon rond, contrairement au torii ou au yokai). */
.pack-preview-skin{
  width:36px;height:36px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  font-size:16px;line-height:1;
  border:2px solid rgba(240,228,196,.55);
  color:#F0E4C4;
  padding-top:0;
}
.pack-worth{
  font-size:9.5px;color:var(--ink-soft);
  text-decoration:line-through;
  margin-top:3px;
}
.pack-eco{
  font-size:9px;font-weight:800;color:var(--moss);
  margin-top:1px;
}
.pack-partiel{
  font-size:9.5px;color:var(--torii-deep);
  margin-top:3px;
}
/* Rotation saisonnière : un badge discret sur le nom (même gabarit que les
   .tag déjà utilisés dans la bannière du Hayashi) et une ligne de compte à
   rebours qui ne s'affiche que tant que le pack reste achetable — voir
   buildPack. */
.pack-seasonal-tag{
  font-size:8px;font-weight:800;
  vertical-align:middle;
  margin-left:4px;
  background:rgba(139,92,167,.16);
  color:#7A5A96;
}
.pack-expiry{
  font-size:9px;color:var(--ink-soft);
  margin-top:2px;
}
/* Renvoi vers le profil, sous la liste des packs : les pièces s'achètent
   aussi à l'unité, mais depuis un autre écran — sans ce rappel, personne ne
   le devine. */
.shop-hint{
  font-size:10px;color:var(--ink-soft);
  margin:6px 2px 14px;
}

/* Marque commune aux quatre objets premium (rappels immédiats, garantie de
   fragment) : le losange rappelle qu'il s'agit d'Essence, sans dupliquer
   entièrement le style d'un bouton d'action normal. */
.premium-btn{
  border-color:rgba(139,92,167,.4) !important;
  color:#8B5CA7 !important;
}
.premium-btn:disabled{opacity:.45;}

/* ---------- Sélecteur d'équipement ---------- */
.equip-slot-block.filled{background:rgba(255,255,255,.62);}
.equip-slot-title{display:flex;align-items:center;gap:6px;}
.equip-upgrade-dot{
  width:6px;height:6px;border-radius:50%;
  background:var(--gold);
  box-shadow:0 0 0 2px rgba(201,162,39,.25);
}
.equip-delta{
  font-size:10px;font-weight:800;
  flex-shrink:0;align-self:center;
  padding:2px 6px;border-radius:7px;
}
.equip-delta.up{color:#4B6B3A;background:rgba(107,122,84,.18);}
.equip-delta.down{color:var(--ink-soft);background:rgba(43,38,32,.08);}

/* ---------- Inventaire : filtres de rareté ---------- */
.inv-filters{
  display:flex;gap:6px;flex-wrap:wrap;
  margin-bottom:10px;
}
.inv-chip{
  font-family:inherit;
  font-size:10px;font-weight:700;
  color:var(--ink-soft);
  background:rgba(255,255,255,.5);
  border:1px solid rgba(43,38,32,.15);
  border-radius:20px;
  padding:5px 11px;
  cursor:pointer;
  display:flex;align-items:center;gap:5px;
}
.inv-chip span{
  font-size:9px;opacity:.7;
  background:rgba(43,38,32,.09);
  border-radius:6px;padding:0 4px;
}
.inv-chip.on{
  color:var(--chip);
  border-color:var(--chip);
  background:color-mix(in srgb, var(--chip) 12%, transparent);
}
/* Rangée des filtres d'emplacement, sous celle des raretés : léger retrait
   pour la distinguer visuellement sans dupliquer .inv-chip. */
.inv-filters-slots{ margin-bottom:8px; }
.inv-toolbar{
  display:flex;align-items:center;justify-content:space-between;
  margin-bottom:6px;font-size:11px;
}
.inv-reserve-toggle{
  display:flex;align-items:center;gap:6px;
  font-weight:600;color:var(--ink-soft);cursor:pointer;
}
.inv-count{ color:var(--ink-soft);font-weight:700; }

/* ---------- Pronostic de combat ---------- */
.squad-hint{
  font-size:10px;color:#8b93ab;
  text-align:center;padding:8px 0 2px;
}
.squad-forecast{margin:4px 0 2px;}
.forecast-bar{
  display:flex;height:7px;border-radius:4px;overflow:hidden;
  background:rgba(255,255,255,.1);
}
.forecast-bar span{display:block;height:100%;transition:width .25s ease;}
.seg-victory{background:#7FA45C;}
.seg-close{background:#D9A441;}
.seg-defeat{background:#B5432E;}
.forecast-legend{
  display:flex;justify-content:space-between;
  font-size:9.5px;color:#9aa4c4;font-weight:700;
  margin-top:6px;
}
.forecast-legend span{display:flex;align-items:center;gap:4px;}
.forecast-legend i{
  width:7px;height:7px;border-radius:2px;display:inline-block;
}
.squad-compare strong{color:#E8C97A;}

/* Badge de difficulté sur les cartes de repaire */
.tag.risk-none{background:rgba(127,164,92,.22);color:#A8CE85;}
.tag.risk-low{background:rgba(127,164,92,.18);color:#9BC377;}
.tag.risk-mid{background:rgba(217,164,65,.2);color:#E8C97A;}
.tag.risk-high{background:rgba(181,67,46,.25);color:#F0A28C;}

/* ---------- Missions en cours ---------- */
.mission-active-squad{
  font-size:9.5px;color:#8b93ab;
  margin-top:3px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  max-width:170px;
}

/* ---------- Déroulé du combat ---------- */
.battle-log{
  text-align:left;
  border-top:1px solid rgba(43,38,32,.12);
  margin-top:4px;padding-top:10px;
}
.battle-log summary{
  font-size:11px;font-weight:700;
  color:var(--ink-soft);
  cursor:pointer;
  list-style:none;
  padding:2px 0;
}
.battle-log summary::-webkit-details-marker{display:none;}
.battle-log summary::after{content:" ▾";}
.battle-log[open] summary::after{content:" ▴";}
.battle-round{
  display:flex;align-items:center;gap:9px;
  font-size:11px;
  padding:5px 0;
  border-bottom:1px dashed rgba(43,38,32,.1);
  /* Les rounds entrent l'un après l'autre : un combat se lit dans son ordre,
     pas d'un bloc. Le décalage est porté par --i, posé au rendu.
     L'animation ne démarre qu'à l'ouverture du <details> : tant qu'il est
     replié le contenu n'est pas rendu, donc rien ne tourne pour rien.
     Plafonné à 10 crans pour qu'un combat long ne fasse pas attendre. */
  animation:battleRound .26s ease both;
  animation-delay:calc(min(var(--i,0), 10) * 55ms);
}
@keyframes battleRound{
  from{opacity:0;transform:translateX(-6px);}
  to{opacity:1;transform:translateX(0);}
}
.battle-round:last-child{border-bottom:none;}
.battle-round-no{
  width:18px;height:18px;flex-shrink:0;
  border-radius:50%;
  background:rgba(43,38,32,.09);
  display:flex;align-items:center;justify-content:center;
  font-size:9px;font-weight:800;color:var(--ink-soft);
}
.battle-round-name{flex:1;font-weight:700;}
.battle-round-dmg{color:var(--torii-deep);font-weight:700;font-size:10px;}
.battle-round.crit .battle-round-dmg{color:var(--gold);}
.battle-round.crit .battle-round-no{background:rgba(201,162,39,.25);color:#8A6A12;}

/* ---------- Pastilles de notification sur la navigation ---------- */
.nav-badge{
  position:absolute;
  top:4px;
  left:calc(50% + 6px);
  min-width:16px;height:16px;
  padding:0 4px;
  border-radius:9px;
  background:var(--torii);
  color:#fff;
  font-size:9px;font-weight:800;
  display:flex;align-items:center;justify-content:center;
  box-shadow:0 0 0 2px var(--washi);
}

/* ---------- Messages éphémères ---------- */
.toast{
  max-width:calc(100% - 36px);
  text-align:center;
  line-height:1.4;
  box-shadow:0 6px 20px rgba(21,25,37,.28);
}
.toast-success{background:#3F5233;}
.toast-error{background:var(--torii-deep);}

/* ---------- Accessibilité ---------- */
/* Un contour visible seulement au clavier : indispensable pour naviguer
   au Tab sans voir sauter le focus d'un bouton à l'autre. */
:focus-visible{
  outline:2px solid var(--gold);
  outline-offset:2px;
  border-radius:6px;
}
.tanuki-card,.building-card,.shop-item,.inv-tile{overflow-wrap:anywhere;}

/* Respecte le réglage système « réduire les animations » */
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{
    animation-duration:.01ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.01ms !important;
  }
}

/* ---------- Écrans très étroits ---------- */
@media (max-width:360px){
  .roster-grid{grid-template-columns:repeat(2,1fr);}
  .nav-item{font-size:9px;}
}

/* ===================================================================
   Révélation d'objet (ouverture de coffre, fusion)
   =================================================================== */

.reveal-card{
  --rarity:#8A8578;
  padding-top:18px;
}

/* La scène : une auréole qui tourne derrière l'objet, teintée par la rareté.
   Plus l'objet est rare, plus la couleur saute aux yeux. */
.reveal-stage{
  position:relative;
  width:118px;height:118px;
  margin:0 auto 14px;
  display:flex;align-items:center;justify-content:center;
}
.reveal-aura{
  position:absolute;inset:0;
  border-radius:50%;
  background:
    conic-gradient(from 0deg,
      color-mix(in srgb, var(--rarity) 55%, transparent),
      transparent 35%,
      color-mix(in srgb, var(--rarity) 55%, transparent) 60%,
      transparent 85%,
      color-mix(in srgb, var(--rarity) 55%, transparent));
  filter:blur(9px);
  opacity:.85;
  animation:revealSpin var(--reveal-tour,7s) linear infinite;
}
.reveal-stage.failed .reveal-aura{opacity:.3;animation-duration:16s;}
@keyframes revealSpin{to{transform:rotate(360deg);}}

.reveal-icon{
  position:relative;
  width:82px;height:82px;
  border-radius:50%;
  background:var(--washi);
  border:2px solid var(--rarity);
  display:flex;align-items:center;justify-content:center;
  padding:15px;
  animation:revealPop var(--reveal-duree,.42s) cubic-bezier(.2,1.5,.4,1) both;
}
@keyframes revealPop{
  from{transform:scale(.4) rotate(-14deg);opacity:0;}
  to{transform:scale(1) rotate(0);opacity:1;}
}

/* ---------- Intensité de la révélation selon la rareté ----------
   Un Légendaire ne doit pas s'ouvrir comme un Commun : la rareté se sent
   avant de se lire. Tout passe par des variables portées par la carte, si
   bien qu'un palier ne coûte qu'une ligne et que les règles de dessin
   ci-dessus n'ont pas à connaître les raretés.
   Progression volontairement contenue : au-delà, l'attente devient une taxe
   sur une action que le joueur répète des dizaines de fois. */
.reveal-card{--reveal-duree:.42s; --reveal-aura:.85; --reveal-tour:7s;}
.reveal-card[data-rarity="rare"]{--reveal-duree:.5s;  --reveal-aura:.9;  --reveal-tour:6s;}
.reveal-card[data-rarity="epique"]{--reveal-duree:.58s; --reveal-aura:.95; --reveal-tour:5s;}
.reveal-card[data-rarity="legendaire"]{--reveal-duree:.66s; --reveal-aura:1; --reveal-tour:4s;}
.reveal-card[data-rarity="mythique"]{--reveal-duree:.74s; --reveal-aura:1; --reveal-tour:3s;}

/* À partir d'Épique, un halo pulse derrière l'icône : c'est le signal qui
   distingue une bonne trouvaille d'une trouvaille ordinaire, d'un coup d'œil. */
.reveal-card[data-rarity="epique"] .reveal-icon,
.reveal-card[data-rarity="legendaire"] .reveal-icon,
.reveal-card[data-rarity="mythique"] .reveal-icon{
  box-shadow:0 0 0 0 color-mix(in srgb, var(--rarity) 60%, transparent);
  animation:revealPop var(--reveal-duree) cubic-bezier(.2,1.5,.4,1) both,
            revealHalo 1.9s ease-out .5s infinite;
}
@keyframes revealHalo{
  0%{box-shadow:0 0 0 0 color-mix(in srgb, var(--rarity) 55%, transparent);}
  70%{box-shadow:0 0 0 18px color-mix(in srgb, var(--rarity) 0%, transparent);}
  100%{box-shadow:0 0 0 0 color-mix(in srgb, var(--rarity) 0%, transparent);}
}

.reveal-stamp{
  position:absolute;
  right:-2px;bottom:2px;
  width:30px;height:30px;
  border-radius:50%;
  background:var(--rarity);
  color:#fff;
  font-family:'Shippori Mincho',serif;
  font-size:14px;font-weight:800;
  display:flex;align-items:center;justify-content:center;
  transform:rotate(-8deg);
  box-shadow:0 2px 6px rgba(21,25,37,.25);
}

.reveal-title{
  font-family:'Shippori Mincho',serif;
  font-size:16px;font-weight:800;
  margin-bottom:10px;
}
.reveal-rarity{
  display:inline-block;
  font-size:9.5px;font-weight:800;
  letter-spacing:.12em;text-transform:uppercase;
  color:var(--rarity);
  border:1px solid var(--rarity);
  border-radius:20px;
  padding:3px 11px;
  margin-bottom:7px;
}
.reveal-name{
  font-family:'Shippori Mincho',serif;
  font-size:16px;font-weight:800;
  color:var(--rarity);
  line-height:1.3;
}
.reveal-slot{
  font-size:10.5px;color:var(--ink-soft);
  margin-top:3px;
}

/* Les trois statistiques, celles à zéro restent visibles mais estompées :
   on voit tout de suite si l'objet est spécialisé ou polyvalent. */
.reveal-stats{
  display:flex;gap:6px;
  margin:14px 0 4px;
}
.reveal-stat{
  flex:1;
  background:rgba(255,255,255,.55);
  border:1px solid rgba(43,38,32,.12);
  border-radius:9px;
  padding:7px 4px;
  opacity:.45;
}
.reveal-stat.on{
  opacity:1;
  border-color:color-mix(in srgb, var(--rarity) 45%, transparent);
  background:color-mix(in srgb, var(--rarity) 9%, rgba(255,255,255,.55));
}
.reveal-stat span{
  display:block;
  font-size:9px;color:var(--ink-soft);
  font-weight:700;text-transform:uppercase;letter-spacing:.06em;
}
.reveal-stat strong{
  display:block;
  font-family:'Shippori Mincho',serif;
  font-size:15px;margin-top:2px;
}
.reveal-stat.on strong{color:var(--rarity);}

.reveal-note{
  font-size:11px;color:var(--ink-soft);
  line-height:1.5;margin-top:12px;
}
.reveal-verdict{
  font-size:11px;font-weight:700;
  border-radius:8px;padding:8px 10px;
  margin-top:10px;
}
.reveal-verdict.good{color:#4B6B3A;background:rgba(107,122,84,.16);}
.reveal-verdict.neutral{color:var(--ink-soft);background:rgba(43,38,32,.07);}
.reveal-verdict.bad{color:var(--torii-deep);background:rgba(181,75,58,.1);}

/* Les cartes de repaire portent désormais jusqu'à cinq étiquettes */
.yokai-tags{flex-wrap:wrap;row-gap:5px;}
.tag.frag{background:rgba(201,162,39,.2);color:#E8C97A;}

/* Avertissement anti-farm ("Fragments réduits") : rouge/corail — c'est un
   malus, pas juste une info secondaire, donc pas le même traitement que les
   autres étiquettes (dorées/vertes, plutôt positives). Même famille de
   couleur que --torii, mais éclaircie pour rester lisible sur le fond sombre
   de la carte (voir .tag.frag/.tag.weakness juste au-dessus pour le même
   principe : teinte translucide de la couleur + texte dans une version
   claire de cette même couleur, jamais de texte sombre sur ce fond-là). */
.tag.malus{background:rgba(181,75,58,.32);color:#F09A8C;}

/* Étiquette de faiblesse sur les cartes de repaire : même couleur que le
   badge de la fiche illustrée (.weak-badge), pour que l'information soit
   présentée de façon cohérente où qu'on la regarde dans le jeu. */
.tag.weakness{background:rgba(107,122,84,.22);color:#A8CE85;}

/* Étiquette de butin possible : la couleur suit la rareté la plus haute
   atteignable à cette puissance, pour donner un repère visuel immédiat sans
   avoir à lire le chiffre. */
.tag.drop{
  background:color-mix(in srgb, var(--drop-color, #8A8578) 22%, transparent);
  color:color-mix(in srgb, var(--drop-color, #8A8578) 75%, white);
}

/* ===================================================================
   Rendez-vous quotidien et Cache au trésor
   =================================================================== */

#repaireTop:empty{display:none;}
#repaireTop:not(:empty){margin-bottom:18px;}
#tab-repaire > .section-title:first-of-type{margin-top:0;}

/* ---------- Visite du jour ---------- */
.daily-card{
  background:linear-gradient(135deg, rgba(201,162,39,.16), rgba(255,255,255,.5));
  border:1px solid rgba(201,162,39,.4);
  border-radius:13px;
  padding:13px;
  margin-bottom:9px;
}
.daily-card.done{
  background:rgba(255,255,255,.5);
  border-color:rgba(43,38,32,.12);
}
.daily-head{
  display:flex;align-items:center;justify-content:space-between;gap:10px;
}
.daily-title{
  font-family:'Shippori Mincho',serif;
  font-size:13px;font-weight:800;
}
.daily-sub{font-size:10.5px;color:var(--ink-soft);margin-top:2px;}
.daily-done-mark{
  width:28px;height:28px;flex-shrink:0;
  border-radius:50%;
  background:rgba(107,122,84,.2);
  color:var(--moss);
  font-size:14px;font-weight:800;
  display:flex;align-items:center;justify-content:center;
}

/* Sept pastilles : voir la série se remplir donne envie de la tenir */
.streak-track{
  display:flex;gap:5px;
  margin:10px 0 0;
}
.streak-dot{
  flex:1;height:15px;
  border-radius:5px;
  background:rgba(43,38,32,.1);
  border:1px solid rgba(43,38,32,.12);
  display:flex;align-items:center;justify-content:center;
  font-size:9px;color:rgba(43,38,32,.3);
}
.streak-dot.done{
  background:var(--gold);
  border-color:var(--gold);
  color:#fff;
}
.streak-dot.current{
  border-color:var(--torii);
  border-width:2px;
  background:rgba(181,75,58,.12);
  color:var(--torii-deep);
}

.daily-loot{
  display:flex;gap:12px;align-items:center;
  font-size:11px;font-weight:700;
  margin-top:9px;
}
.daily-crate{color:#8B5CA7;}

/* ---------- Cache au trésor ---------- */
.cache-card{
  display:flex;align-items:center;gap:11px;
  background:rgba(255,255,255,.55);
  border:1px solid rgba(43,38,32,.12);
  border-radius:12px;
  padding:11px 12px;
}
.cache-main{flex:1;min-width:0;}
.cache-title{
  font-family:'Shippori Mincho',serif;
  font-size:12px;font-weight:700;
}
.cache-track{
  height:5px;background:rgba(43,38,32,.12);
  border-radius:3px;overflow:hidden;
  margin:6px 0 4px;
}
.cache-fill{
  height:100%;border-radius:3px;
  background:linear-gradient(90deg,#C9A227,#E8C97A);
  transition:width .4s ease;
}
.cache-sub{font-size:9.5px;color:var(--ink-soft);}

/* ===== Coups de maître ===== */
.squad-pick-crit{
  font-size:9.5px;font-weight:700;
  color:#9aa4c4;
  flex-shrink:0;
  min-width:30px;text-align:right;
}
.battle-round-dmg.plain{color:var(--ink-soft);font-weight:400;}
.battle-round.crit{background:rgba(201,162,39,.1);border-radius:6px;padding-left:5px;padding-right:5px;}

/* ===================================================================
   Carte du Repaire et classement
   =================================================================== */

.map-frame{
  position:relative; /* ancre les feuilles décoratives dans le cadre */
  border-radius:14px;
  overflow:hidden;
  border:1px solid rgba(43,38,32,.14);
  margin-bottom:9px;
  background:var(--washi-deep);
  box-shadow:inset 0 -14px 24px -18px rgba(43,38,32,.45);
}
.repaire-map{display:block;width:100%;height:auto;}

/* Chaque bâtiment est cliquable et le montre */
.carte-batiment{cursor:pointer;transition:transform .15s ease;transform-box:fill-box;}
.carte-batiment:active{opacity:.75;}
.carte-etiquette{pointer-events:none;}
.carte-batiment:focus-visible{outline:none;}
.carte-batiment:focus-visible rect:first-of-type{
  stroke:var(--gold);stroke-width:2;stroke-dasharray:4 3;
}
/* Le chantier respire, pour attirer l'œil sans clignoter */
@keyframes chantierPulse{0%,100%{opacity:1;}50%{opacity:.72;}}
.carte-batiment.en-chantier{animation:chantierPulse 2.4s ease-in-out infinite;}

/* ---------- Fin de chantier ----------
   La carte est redessinée d'un bloc : sans ça, l'échafaudage disparaîtrait
   entre deux images et le bâtiment changerait de niveau sans qu'on le voie.
   app.js repère la transition et redessine l'échafaudage une dernière fois,
   le temps qu'il s'efface pendant que le bâtiment se pose. */
.echafaudage-disparait{
  animation:echafaudageEfface .85s ease-out both;
  pointer-events:none;
}
@keyframes echafaudageEfface{
  0%{opacity:1;transform:translateY(0);}
  100%{opacity:0;transform:translateY(-7px);}
}
.carte-batiment.vient-d-etre-acheve{
  /* transform-box/origin : sans eux, l'origine d'un <g> SVG est celle du
     document, pas celle du groupe — le bâtiment partirait en diagonale au
     lieu de se poser sur lui-même. */
  transform-box:fill-box;
  transform-origin:center bottom;
  animation:batimentAcheve .8s cubic-bezier(.2,1.4,.4,1) .25s both;
}
@keyframes batimentAcheve{
  0%{transform:scale(1);}
  40%{transform:scale(1.07);}
  100%{transform:scale(1);}
}

/* ---------- Feuilles portées par le vent ----------
   Écho aux Feuilles magiques, la ressource de base : le décor rappelle
   l'économie du jeu. Purement décoratif, donc aria-hidden et sans capture
   de clic — la carte reste entièrement cliquable au travers. */
.feuilles-vent{
  position:absolute; inset:0;
  overflow:hidden; pointer-events:none;
  border-radius:inherit;
}
.feuille-vent{
  position:absolute; top:-12px;
  width:7px; height:9px;
  background:var(--gold, #C9A227);
  border-radius:0 60% 0 60%;
  opacity:0;
  /* transform et opacity seulement : le navigateur compose sans repeindre,
     ce qui tient sans effort sur un téléphone modeste. */
  animation:feuilleVent linear infinite;
}
@keyframes feuilleVent{
  0%{opacity:0; transform:translate3d(0,0,0) rotate(0deg);}
  10%{opacity:.55;}
  90%{opacity:.35;}
  100%{opacity:0; transform:translate3d(26px,230px,0) rotate(220deg);}
}
/* Décalages et durées volontairement dissemblables : des feuilles synchrones
   se verraient immédiatement comme une boucle. */
.feuille-vent.f0{left:12%; animation-duration:11s; animation-delay:0s;}
.feuille-vent.f1{left:31%; animation-duration:14s; animation-delay:-4s;}
.feuille-vent.f2{left:54%; animation-duration:9.5s; animation-delay:-7s;}
.feuille-vent.f3{left:73%; animation-duration:13s; animation-delay:-2s;}
.feuille-vent.f4{left:88%; animation-duration:12s; animation-delay:-9s;}

/* La règle globale de mouvement réduit ramène les durées à .01ms, ce qui
   ferait clignoter les feuilles au lieu de les calmer : on les retire. */
@media (prefers-reduced-motion: reduce){
  .feuilles-vent{display:none;}
  .carte-batiment.vient-d-etre-acheve{animation:none;}
}

/* Surlignage de la fiche visée depuis la carte */
@keyframes ficheHighlight{
  0%{background:rgba(201,162,39,.35);}
  100%{background:rgba(255,255,255,.55);}
}
.building-card.highlight{animation:ficheHighlight 1.6s ease-out;}

/* ---------- Classement ---------- */
.lb-card{
  display:flex;align-items:center;gap:11px;
  background:rgba(255,255,255,.55);
  border:1px solid rgba(43,38,32,.12);
  border-radius:12px;
  padding:11px 12px;
  margin-top:18px;
  margin-bottom:14px; /* la carte suivante (bannière du Hayashi, récompense
                          du jour...) venait se coller directement dessous */
}
.lb-card.lb-podium{
  border-color:var(--gold);
  background:linear-gradient(135deg, rgba(201,162,39,.14), rgba(255,255,255,.5));
}
.lb-rank-badge{
  width:40px;height:40px;flex-shrink:0;
  border-radius:11px;
  background:rgba(43,38,32,.07);
  display:flex;align-items:baseline;justify-content:center;gap:1px;
  font-family:'Shippori Mincho',serif;
  font-size:17px;font-weight:800;
  color:var(--ink);
}
.lb-podium .lb-rank-badge{background:rgba(201,162,39,.2);color:#9A7A1E;}
.lb-rank-badge span{font-size:9px;font-weight:700;}
.lb-card-main{flex:1;min-width:0;}
.lb-card-title{font-family:'Shippori Mincho',serif;font-size:12px;font-weight:700;}
.lb-card-sub{font-size:10px;color:var(--ink-soft);margin-top:2px;}

.lb-panel{
  max-height:84vh;overflow-y:auto;text-align:left;
  /* Reprend le traitement de .yokai-art-card : la barre de défilement grise
     par défaut du navigateur tranchait sur l'habillage papier washi — c'est
     elle qu'on voyait sur la fiche des Objectifs. */
  scrollbar-width:none;
  -ms-overflow-style:none;
  overscroll-behavior:contain;
}
.lb-panel::-webkit-scrollbar{display:none;}
.lb-tabs{display:flex;gap:5px;margin:4px 0 2px;}
.lb-tab{
  flex:1;
  font-family:inherit;font-size:10.5px;font-weight:700;
  padding:7px 6px;border-radius:8px;
  border:1px solid rgba(43,38,32,.15);
  background:transparent;color:var(--ink-soft);
  cursor:pointer;
}
.lb-tab.on{background:var(--torii);border-color:var(--torii);color:#fff;}

.raid-boss-list{display:flex;flex-direction:column;gap:8px;}
.raid-boss-opt{
  text-align:left;
  background:rgba(255,255,255,.55);
  border:1px solid rgba(43,38,32,.12);
  border-radius:11px;
  padding:10px 12px;
  cursor:pointer;
  font-family:inherit;
}
.raid-boss-opt:not(.locked):hover{border-color:var(--torii);}
.raid-boss-opt.locked{opacity:.5;cursor:default;}
.raid-boss-opt-name{font-family:'Shippori Mincho',serif;font-size:13px;font-weight:700;}
.raid-boss-opt-stats{font-size:10.5px;color:var(--ink-soft);margin-top:2px;}
.raid-boss-opt-lock{font-size:10px;color:var(--torii-deep);margin-top:4px;font-weight:700;}
.lb-explain{
  font-size:10px;color:var(--ink-soft);
  line-height:1.5;margin:6px 0 12px;
}
.lb-list{display:flex;flex-direction:column;gap:2px;}
.lb-row{
  display:flex;align-items:center;gap:10px;
  font-size:11.5px;
  padding:7px 9px;
  border-radius:8px;
}
.lb-row:nth-child(even){background:rgba(43,38,32,.04);}
.lb-row.top .lb-row-rank{color:var(--gold);}
.lb-row.moi{
  background:rgba(181,75,58,.12);
  border:1px solid rgba(181,75,58,.3);
  font-weight:700;
}
.lb-row.hors-top{margin-top:8px;}
.lb-row-rank{
  width:24px;flex-shrink:0;
  font-weight:800;color:var(--ink-soft);
  text-align:right;
}
/* Portrait + bloc identité (nom + titre actif) : même schéma que
   .ladder-portrait / .ladder-name-block dans le classement d'arène, pour
   une apparence cohérente entre les deux types de classement. */
.lb-row-portrait{
  width:36px;height:36px;border-radius:8px;flex-shrink:0;
  background-size:cover;background-position:center 22%;
  background-color:rgba(43,38,32,.08);
}
.lb-row-identite{flex:1;min-width:0;}
.lb-row-name{flex:1;min-width:0;display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;cursor:pointer;}
.lb-row-score{font-weight:700;color:var(--moss);flex-shrink:0;}
/* En-tête de colonnes : sans lui, le nombre à droite (337, 597…) ne disait
   pas de quoi il s'agissait — le texte d'explication parle de renommée,
   mais rien ne reliait explicitement le mot au chiffre. */
.lb-head{
  display:flex;justify-content:space-between;align-items:baseline;
  padding:0 9px 5px;
  font-size:9.5px;font-weight:700;
  text-transform:uppercase;letter-spacing:.06em;
  color:var(--ink-soft);
  border-bottom:1px solid rgba(43,38,32,.1);
  margin-bottom:3px;
}

/* Lucioles de la carte : un flottement lent, sans clignotement agressif */
@keyframes luciole{
  0%,100%{opacity:.15;transform:translateY(0);}
  50%{opacity:.9;transform:translateY(-6px);}
}
.luciole{animation:luciole 4.5s ease-in-out infinite;}
@media (prefers-reduced-motion: reduce){ .luciole{opacity:.5;} }

/* Le cadre suit désormais un ciel sombre en haut */
.map-frame{
  border-color:rgba(43,38,32,.2);
  box-shadow:0 2px 10px -4px rgba(43,38,32,.35);
}

/* ===== Fiche illustrée d'un repaire yokai ===== */
.yokai-portrait.art-link{position:relative;cursor:pointer;}
.art-loupe{
  position:absolute;right:2px;bottom:2px;
  width:15px;height:15px;
  border-radius:4px;
  background:rgba(21,25,37,.72);
  color:#E8C97A;
  font-size:9px;line-height:15px;text-align:center;
  pointer-events:none;
}
.yokai-portrait.art-link:active{opacity:.75;}

.yokai-art-card{
  padding:0;
  max-width:330px;
  max-height:88vh;
  overflow-y:auto;
  text-align:left;
  /* La barre de défilement grise par défaut coupait l'illustration en deux.
     On la masque : le dégradé sous l'image suffit à signaler qu'il y a
     davantage de contenu plus bas. */
  scrollbar-width:none;
  -ms-overflow-style:none;
  overscroll-behavior:contain;
}
.yokai-art-card::-webkit-scrollbar{display:none;}
/* La scène : hauteur FIXE, identique pour toutes les fiches. Elle était
   auparavant calculée en JavaScript d'après les proportions de chaque
   illustration — ce qui donnait une fiche courte pour une image large
   (Umibōzu) et une fiche haute pour une image verticale (Amanojaku), alors
   que ces cartes se suivent dans la même liste. Le fond flouté ci-dessous
   comblant déjà n'importe quel format, rien n'obligeait la boîte à épouser
   les proportions de l'image. */
.yokai-art-stage{
  position:relative;
  width:100%;
  /* Un cran au-dessus du 160–220 : moins de zoom forcé par le cover. */
  height:clamp(185px, 30vh, 255px);
  overflow:hidden;
  border-radius:16px 16px 0 0;
  background:var(--indigo-deep);
}
.yokai-art-blur{
  position:absolute;
  inset:-24px;
  background-size:cover;
  background-position:center top;
  filter:blur(20px) saturate(1.15);
  opacity:.55;
}
/* 100% auto = largeur du cadre, hauteur proportionnelle.
   Moins agressif que cover (qui grossit jusqu'à tout remplir).
   center top = la tête reste prioritaire si ça dépasse en bas. */
.yokai-art{
  position:absolute;
  inset:0;
  background-size:100% auto;
  background-position:center top;
  background-repeat:no-repeat;
}
.yokai-art-body{
  padding:16px 18px 14px;
  position:relative;
}
/* Fondu entre l'illustration et le texte, pour que la coupure ne soit pas nette */
.yokai-art-body::before{
  content:'';
  position:absolute;left:0;right:0;top:-34px;height:34px;
  background:linear-gradient(to bottom, transparent, var(--washi));
  pointer-events:none;
}
/* Le bouton reste accessible sans avoir à faire défiler toute l'illustration */
.yokai-art-foot{
  position:sticky;bottom:0;
  padding:0 18px 16px;
  background:linear-gradient(to bottom, transparent, var(--washi) 35%);
}

/* Détail des chances de fragment */
.frag-odds{
  background:rgba(201,162,39,.1);
  border:1px solid rgba(201,162,39,.35);
  border-radius:10px;
  padding:10px 12px;
  margin-top:12px;
}
.frag-odds-title{
  font-family:'Shippori Mincho',serif;
  font-size:11.5px;font-weight:700;
  color:#9A7A1E;
  margin-bottom:6px;
}
.frag-odds-row{
  display:flex;justify-content:space-between;
  font-size:11px;padding:2px 0;
}
.frag-odds-row strong{color:#9A7A1E;}
.frag-odds-note{
  font-size:10px;color:var(--ink-soft);
  line-height:1.5;margin-top:7px;
}
.yokai-art-name{
  font-family:'Shippori Mincho',serif;
  font-size:17px;font-weight:800;
}
.yokai-art-meta{font-size:11px;color:var(--ink-soft);margin-top:3px;}
.yokai-art-desc{
  font-size:12px;color:var(--ink-soft);
  line-height:1.6;margin:11px 0 0;
  font-style:italic;
}
.yokai-tags.art-tags{margin-top:12px;}
.yokai-tags.art-tags .tag{
  background:rgba(43,38,32,.09);
  color:var(--ink-soft);
  font-size:9.5px;padding:3px 9px;
}
.yokai-tags.art-tags .tag.frag{background:rgba(201,162,39,.2);color:#9A7A1E;}

/* ===== Faiblesses des yokai ===== */
.weak-badge{
  display:inline-flex;align-items:baseline;gap:7px;
  background:rgba(107,122,84,.16);
  border:1px solid rgba(107,122,84,.4);
  border-radius:20px;
  padding:4px 11px 4px 8px;
  margin-top:9px;
}
.weak-label{
  font-size:8.5px;font-weight:800;
  text-transform:uppercase;letter-spacing:.1em;
  color:var(--ink-soft);
}
.weak-value{
  font-family:'Shippori Mincho',serif;
  font-size:12px;font-weight:700;
  color:#4B6B3A;
}
/* Le gain de puissance apporté par la faiblesse, dans le sélecteur d'escouade */
.squad-pick-power.boost{color:#A8CE85;}
.pick-boost{
  font-size:8.5px;font-weight:800;
  color:#7FA45C;
  margin-left:3px;
}

/* ===================================================================
   Objectifs et accueil du nouveau joueur
   =================================================================== */

.obj-list{display:flex;flex-direction:column;gap:7px;text-align:left;}
.obj-row{
  display:flex;align-items:center;gap:10px;
  background:rgba(255,255,255,.5);
  border:1px solid rgba(43,38,32,.1);
  border-radius:11px;
  padding:9px 11px;
}
.obj-row.ready{border-color:var(--gold);background:rgba(201,162,39,.1);}
.obj-row.done{opacity:.6;}
.obj-main{flex:1;min-width:0;}
.obj-label{font-family:'Shippori Mincho',serif;font-size:12px;font-weight:700;}
.obj-desc{font-size:10px;color:var(--ink-soft);margin-top:1px;line-height:1.4;}
.obj-reward{margin-top:4px;font-size:10px;font-weight:700;color:var(--moss);}
.obj-done-tag{
  font-size:9.5px;font-weight:800;color:var(--moss);
  flex-shrink:0;white-space:nowrap;
}

/* ---------- Accueil du nouveau joueur ---------- */
.onboard-card{max-width:340px;}
.onboard-steps{
  display:flex;flex-direction:column;gap:12px;
  text-align:left;
  margin:16px 0 20px;
}
.onboard-step{
  display:flex;align-items:flex-start;gap:10px;
  font-size:12px;color:var(--ink-soft);
  line-height:1.5;
}
.onboard-step strong{color:var(--ink);}
.onboard-step-no{
  width:22px;height:22px;flex-shrink:0;
  border-radius:50%;
  background:var(--torii);
  color:#fff;
  font-family:'Shippori Mincho',serif;
  font-weight:800;font-size:11px;
  display:flex;align-items:center;justify-content:center;
  margin-top:1px;
}

/* ===================================================================
   Profil joueur (pseudo, avatar) et classement des Hayashi
   =================================================================== */

/* ---------- Barre du haut : nom + bouton d'édition ---------- */
.player-name-row{display:flex;align-items:center;gap:7px;}
.profile-edit-btn{
  /* Auparavant un glyphe de 10 px, gris clair et à 70 % d'opacité, sans fond :
     rien n'indiquait qu'on pouvait cliquer, et il se confondait avec le texte
     du pseudo juste à côté. Une pastille lui donne une surface tactile et le
     désigne comme un bouton. */
  background:rgba(43,38,32,.09);
  border:none; cursor:pointer;
  font-size:12px; color:var(--ink-soft);
  /* 24 px : en dessous, la cible devient difficile à toucher au pouce. */
  width:24px; height:24px; flex-shrink:0;
  border-radius:50%;
  display:inline-flex; align-items:center; justify-content:center;
  padding:0; line-height:1;
  transition:background .15s ease, color .15s ease, transform .1s ease;
}
.profile-edit-btn:hover{ background:rgba(181,75,58,.16); color:var(--torii-deep); }
.profile-edit-btn:active{ transform:scale(.9); }
.profile-edit-btn:focus-visible{ outline:2px solid var(--torii); outline-offset:2px; }

/* Titre actif, affiché sous le pseudo — petite majuscule dorée pour ne pas
   rivaliser avec le nom lui-même. */
.player-titre{
  display:block;
  font-size:8.5px;font-weight:700;
  color:var(--gold);
  text-transform:uppercase;letter-spacing:.04em;
  margin-top:1px;
}

/* ---------- Bannière de fiche, reprise sur TOUT le header (topbar) ----------
   Version révisée : la première mouture limitait le fond décoré au petit
   bloc avatar/nom (.player-tag) ; il s'étend maintenant sur toute la barre
   — avatar, ressources, cloche compris — comme sur une vraie bannière de
   fiche. Reprend les mêmes teintes/motifs/animations que les grandes
   bannières (.fiche-banniere.banniere-* plus bas dans ce fichier), condensés
   à un seul motif par bannière et un filet en box-shadow plutôt qu'un
   ::after séparé.

   Risque de clipping du cadre-* de l'avatar : .topbar porte overflow:hidden
   pour clipper proprement les motifs décoratifs (ents, flocons, etc.), et
   contient aussi l'avatar dont le cadre-* peut déborder jusqu'à -32% de sa
   propre taille (Torii) ou -30% (Brume/Yokai) — soit ~14-15px sur un avatar
   de 48px. Le padding-top actuel de .topbar (14px + safe-area) couvre
   presque tout ce débordement ; au pire 1-2px de la pointe d'un motif de
   cadre pourraient être rognés sur un écran sans encoche. Si ça se voit à
   l'usage, augmenter légèrement le padding-top de .topbar réglera ça. ---------- */
.topbar{
  position:relative;
  overflow:hidden;
  transition:background .25s ease, box-shadow .25s ease;
}
.topbar > *{
  position:relative;
  z-index:1;
}

/* ---- Torii ---- */
.topbar.banniere-torii{
  background:
    linear-gradient(135deg, rgba(181,75,58,.55), rgba(142,58,44,.75)),
    linear-gradient(145deg, #3A2A28, #2A1E1C);
  box-shadow:inset 0 -2px 0 rgba(201,162,39,.65);
  border-bottom-color:transparent;
}
.topbar.banniere-torii .player-name{ color:#FFF6E8; }
.topbar.banniere-torii .player-titre{ color:#F0DCC0; }
.topbar.banniere-torii .logout-link{ color:#D8B888; }
.topbar.banniere-torii .res-pill{ background:rgba(255,255,255,.12); border-color:rgba(240,228,196,.25); color:#F0E4C4; }
.topbar.banniere-torii .notif-bell{ color:#F0DCC0; }
.topbar.banniere-torii::after{
  content:"";
  position:absolute;
  right:2px; top:50%; transform:translateY(-50%);
  width:64px; height:56px;
  z-index:0; pointer-events:none;
  background-repeat:no-repeat; background-size:contain; background-position:center;
  background-image:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 80 70' fill='%23F0E4C4'%3E%3Crect x='6' y='8' width='68' height='5' rx='1'/%3E%3Crect x='12' y='16' width='56' height='3.5'/%3E%3Crect x='18' y='20' width='5' height='42'/%3E%3Crect x='57' y='20' width='5' height='42'/%3E%3Crect x='14' y='30' width='52' height='3'/%3E%3C/svg%3E");
  opacity:.14;
  animation:ficheToriiLueur 14s ease-in-out infinite;
}

/* ---- Vagues ---- */
.topbar.banniere-vague{
  background:
    radial-gradient(ellipse at 15% 90%, rgba(90,140,180,.28), transparent 55%),
    radial-gradient(ellipse at 85% 15%, rgba(110,160,200,.18), transparent 50%),
    linear-gradient(165deg, #243040 0%, #1A2435 55%, #151C28 100%);
  box-shadow:inset 0 -2px 0 rgba(126,176,200,.6);
  border-bottom-color:transparent;
}
.topbar.banniere-vague .player-name{ color:#E8F0F8; }
.topbar.banniere-vague .player-titre{ color:#C8E4F0; }
.topbar.banniere-vague .logout-link{ color:#A8C4D8; }
.topbar.banniere-vague .res-pill{ background:rgba(255,255,255,.12); border-color:rgba(200,224,240,.25); color:#E8F0F8; }
.topbar.banniere-vague .notif-bell{ color:#C8E4F0; }
.topbar.banniere-vague::before{
  content:"";
  position:absolute; inset:0;
  z-index:0; pointer-events:none;
  opacity:.16;
  background-image:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='48' height='24' viewBox='0 0 48 24'%3E%3Cpath d='M0 24a12 12 0 0 1 12-12 12 12 0 0 1 12 12 12 12 0 0 1 12-12 12 12 0 0 1 12 12' fill='none' stroke='%2398C4D8' stroke-width='1.15'/%3E%3C/svg%3E");
  background-size:48px 24px; background-repeat:repeat;
  animation:ficheVagueDerive 22s linear infinite;
}

/* ---- Bambou ---- */
.topbar.banniere-bambou{
  background: linear-gradient(145deg, #3A4A38, #2A3228);
  box-shadow:inset 0 -2px 0 rgba(143,168,106,.6);
  border-bottom-color:transparent;
}
.topbar.banniere-bambou .player-name,
.topbar.banniere-bambou .player-titre,
.topbar.banniere-bambou .logout-link,
.topbar.banniere-bambou .notif-bell{ color:#E4ECD8; }
.topbar.banniere-bambou .res-pill{ background:rgba(255,255,255,.12); border-color:rgba(200,216,168,.25); color:#E4ECD8; }
.topbar.banniere-bambou::after{
  content:"";
  position:absolute; right:0; top:0; bottom:0; width:26%;
  z-index:0; pointer-events:none;
  opacity:.22;
  background-repeat:no-repeat; background-size:contain; background-position:right center;
  background-image:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 90'%3E%3Cg fill='none' stroke='%23C8D8A8' stroke-width='2.2' stroke-linecap='round'%3E%3Cpath d='M28 90 V12'/%3E%3Cpath d='M28 28 h8'/%3E%3Cpath d='M28 48 h-7'/%3E%3Cpath d='M52 90 V8'/%3E%3Cpath d='M52 22 h-7'/%3E%3Cpath d='M52 42 h8'/%3E%3Cpath d='M76 90 V18'/%3E%3Cpath d='M76 34 h8'/%3E%3C/g%3E%3Cg fill='%23C8D8A8' opacity='.85'%3E%3Cellipse cx='38' cy='20' rx='9' ry='3.5' transform='rotate(-35 38 20)'/%3E%3Cellipse cx='20' cy='44' rx='8' ry='3' transform='rotate(28 20 44)'/%3E%3Cellipse cx='62' cy='30' rx='9' ry='3.5' transform='rotate(40 62 30)'/%3E%3C/g%3E%3C/svg%3E");
  transform-origin:bottom center;
  animation:ficheBambouSway 7s ease-in-out infinite;
}

/* ---- Lune ---- */
.topbar.banniere-lune{
  background: linear-gradient(160deg, #1A1E2E, #12141C);
  box-shadow:inset 0 -2px 0 rgba(138,155,184,.6);
  border-bottom-color:transparent;
}
.topbar.banniere-lune .player-name,
.topbar.banniere-lune .player-titre,
.topbar.banniere-lune .logout-link,
.topbar.banniere-lune .notif-bell{ color:#E8E4F0; }
.topbar.banniere-lune .res-pill{ background:rgba(255,255,255,.1); border-color:rgba(200,190,230,.25); color:#E8E4F0; }
.topbar.banniere-lune::before{
  content:"";
  position:absolute;
  inset:0;
  z-index:0; pointer-events:none;
  opacity:.9;
  /* Étoiles filantes — mêmes trajectoires que .fiche-banniere.banniere-lune,
     manquantes dans la première version compacte du topbar (::before était
     resté libre, seul ::after avait été utilisé pour la lune elle-même). */
  background:
    linear-gradient(122deg, transparent 0%, transparent 42%, rgba(240,228,196,.95) 46%, rgba(240,228,196,.35) 52%, transparent 58%) 72% 18% / 56px 2px no-repeat,
    linear-gradient(118deg, transparent 0%, transparent 40%, rgba(220,230,255,.9) 45%, rgba(220,230,255,.3) 55%, transparent 60%) 88% 38% / 42px 1.5px no-repeat;
  animation: ficheLuneFilantes 9s linear infinite;
}
.topbar.banniere-lune::after{
  content:"";
  position:absolute;
  right:6px; top:50%; transform:translateY(-50%);
  width:60px; height:52px;
  z-index:0; pointer-events:none;
  opacity:.3;
  background-repeat:no-repeat; background-size:contain; background-position:center;
  background-image:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 80 70'%3E%3Ccircle cx='52' cy='28' r='16' fill='%23F0E4C4' opacity='.9'/%3E%3Ccircle cx='58' cy='24' r='14' fill='%231A1E2E'/%3E%3Cg fill='%23F0E4C4'%3E%3Ccircle cx='12' cy='14' r='1.3'/%3E%3Ccircle cx='22' cy='8' r='.9'/%3E%3Ccircle cx='8' cy='32' r='1.1'/%3E%3Ccircle cx='18' cy='48' r='.8'/%3E%3C/g%3E%3C/svg%3E");
  animation:ficheLuneHalo 10s ease-in-out infinite;
}

/* ---- Sakura ---- */
.topbar.banniere-sakura{
  background: linear-gradient(145deg, #4A3540, #2E2430);
  box-shadow:inset 0 -2px 0 rgba(243,198,211,.6);
  border-bottom-color:transparent;
}
.topbar.banniere-sakura .player-name,
.topbar.banniere-sakura .player-titre,
.topbar.banniere-sakura .logout-link,
.topbar.banniere-sakura .notif-bell{ color:#F8E8EE; }
.topbar.banniere-sakura .res-pill{ background:rgba(255,255,255,.12); border-color:rgba(243,198,211,.3); color:#F8E8EE; }
.topbar.banniere-sakura::before{
  content:"";
  position:absolute; inset:0;
  z-index:0; pointer-events:none;
  opacity:.2;
  background-image:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='90' height='60' viewBox='0 0 120 80'%3E%3Cg fill='%23F3C6D3'%3E%3Cellipse cx='18' cy='16' rx='5' ry='3.2' transform='rotate(-20 18 16)'/%3E%3Cellipse cx='42' cy='10' rx='4' ry='2.6' transform='rotate(15 42 10)'/%3E%3Cellipse cx='68' cy='22' rx='5.5' ry='3.4' transform='rotate(-35 68 22)'/%3E%3Cellipse cx='95' cy='14' rx='4.2' ry='2.8' transform='rotate(25 95 14)'/%3E%3Cellipse cx='28' cy='48' rx='4.8' ry='3' transform='rotate(40 28 48)'/%3E%3C/g%3E%3C/svg%3E");
  background-size:90px 60px; background-repeat:repeat;
  animation:ficheSakuraTombe 10s linear infinite;
}

/* ---- Brume ---- */
.topbar.banniere-brume{
  background:
    radial-gradient(ellipse at 20% 80%, rgba(200,210,230,.22), transparent 50%),
    radial-gradient(ellipse at 75% 30%, rgba(180,190,210,.18), transparent 45%),
    linear-gradient(150deg, #3A4558 0%, #2A3040 55%, #222838 100%);
  background-size:120% 120%, 120% 120%, 100% 100%;
  box-shadow:inset 0 -2px 0 rgba(138,155,184,.55);
  border-bottom-color:transparent;
  animation:ficheBrumeDerive 14s ease-in-out infinite;
}
.topbar.banniere-brume .player-name,
.topbar.banniere-brume .player-titre,
.topbar.banniere-brume .logout-link,
.topbar.banniere-brume .notif-bell{ color:#E4E8F0; }
.topbar.banniere-brume .res-pill{ background:rgba(255,255,255,.1); border-color:rgba(180,190,210,.25); color:#E4E8F0; }

/* ---- Neige ---- */
.topbar.banniere-neige{
  background: linear-gradient(165deg, #2A3545 0%, #1A222E 55%, #141A24 100%);
  box-shadow:inset 0 -2px 0 rgba(138,160,184,.6);
  border-bottom-color:transparent;
}
.topbar.banniere-neige .player-name,
.topbar.banniere-neige .player-titre,
.topbar.banniere-neige .logout-link,
.topbar.banniere-neige .notif-bell{ color:#E8EEF4; }
.topbar.banniere-neige .res-pill{ background:rgba(255,255,255,.1); border-color:rgba(200,220,240,.25); color:#E8EEF4; }
.topbar.banniere-neige::after{
  content:"";
  position:absolute; inset:0;
  z-index:0; pointer-events:none;
  opacity:.5;
  background-image:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='36' height='36' viewBox='0 0 36 36'%3E%3Cg fill='%23E8F0F8' opacity='.9'%3E%3Ccircle cx='6' cy='8' r='1.1'/%3E%3Ccircle cx='20' cy='4' r='.9'/%3E%3Ccircle cx='30' cy='16' r='1.2'/%3E%3Ccircle cx='12' cy='24' r='1'/%3E%3Ccircle cx='26' cy='28' r='.8'/%3E%3C/g%3E%3C/svg%3E");
  background-size:36px 36px; background-repeat:repeat;
  animation:ficheNeigeTombe 11s linear infinite;
}

/* ---- Or ---- */
.topbar.banniere-or{
  background: linear-gradient(135deg, #6B5420 0%, #4A3A14 50%, #3A2E10 100%);
  box-shadow:inset 0 -2px 0 rgba(201,162,39,.8);
  border-bottom-color:transparent;
}
.topbar.banniere-or .player-name,
.topbar.banniere-or .player-titre,
.topbar.banniere-or .logout-link,
.topbar.banniere-or .notif-bell{ color:#F8ECC8; }
.topbar.banniere-or .res-pill{ background:rgba(255,255,255,.1); border-color:rgba(232,213,138,.3); color:#F8ECC8; }
.topbar.banniere-or::after{
  content:"";
  position:absolute; inset:0;
  z-index:0; pointer-events:none;
  opacity:.26;
  background-image:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='60' height='60' viewBox='0 0 60 60'%3E%3Cg fill='%23E8D58A'%3E%3Ccircle cx='10' cy='12' r='1.4'/%3E%3Ccircle cx='30' cy='8' r='1'/%3E%3Ccircle cx='48' cy='16' r='1.2'/%3E%3Ccircle cx='18' cy='32' r='.9'/%3E%3Ccircle cx='40' cy='28' r='1.3'/%3E%3C/g%3E%3C/svg%3E");
  background-size:60px 60px; background-repeat:repeat;
  animation:ficheOrScintille 5s ease-in-out infinite;
}

/* ---- Yokai ---- */
.topbar.banniere-yokai{
  background: linear-gradient(150deg, #2A1830 0%, #1A1020 55%, #120C18 100%);
  box-shadow:inset 0 -2px 0 rgba(180,80,120,.7);
  border-bottom-color:transparent;
}
.topbar.banniere-yokai .player-name,
.topbar.banniere-yokai .player-titre,
.topbar.banniere-yokai .logout-link,
.topbar.banniere-yokai .notif-bell{ color:#F0DCE8; }
.topbar.banniere-yokai .res-pill{ background:rgba(255,255,255,.1); border-color:rgba(180,80,120,.3); color:#F0DCE8; }
/* Face-à-face Tanuki/Yokai, repris de .fiche-banniere.banniere-yokai — la
   première version compacte n'était qu'un dégradé radial flou (pas de vraie
   illustration, d'où l'effet "blurred") et utilisait cadreYokaiAura, une
   animation de box-shadow en anneaux pensée pour un avatar rond, sans
   rapport avec le box-shadow en filet plat de cette barre — elle ne
   produisait donc aucun mouvement cohérent ici. ficheYokaiCourse (le
   même léger va-et-vient que sur la grande bannière) remplace ça. */
.topbar.banniere-yokai::after{
  content:"";
  position:absolute; right:4px; top:50%;
  width:90px; height:52px;
  z-index:0; pointer-events:none;
  opacity:.5;
  background-image:
    radial-gradient(ellipse at 62% 55%, rgba(180,92,130,.4), transparent 68%),
    url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 70' fill='none'%3E%3Cg%3E%3Cellipse cx='18' cy='17' rx='8' ry='11' fill='%23D9AE76'/%3E%3Cellipse cx='50' cy='17' rx='8' ry='11' fill='%23D9AE76'/%3E%3Cellipse cx='18' cy='18' rx='4' ry='6.5' fill='%23F0D4A8'/%3E%3Cellipse cx='50' cy='18' rx='4' ry='6.5' fill='%23F0D4A8'/%3E%3Cellipse cx='34' cy='41' rx='26' ry='23' fill='%23D9AE76'/%3E%3Cellipse cx='34' cy='37' rx='19' ry='17' fill='%23E8C48A'/%3E%3Cellipse cx='34' cy='40' rx='15' ry='9' fill='%232A2018' opacity='.9'/%3E%3Ccircle cx='27' cy='38' r='3.2' fill='%23FBEFD4'/%3E%3Ccircle cx='41' cy='38' r='3.2' fill='%23FBEFD4'/%3E%3Ccircle cx='27.4' cy='38' r='1.4' fill='%23200A16'/%3E%3Ccircle cx='41.4' cy='38' r='1.4' fill='%23200A16'/%3E%3Cellipse cx='34' cy='46' rx='3' ry='2' fill='%232A2018'/%3E%3C/g%3E%3Cg%3E%3Cpath d='M74 16 Q69 1 78 7' fill='none' stroke='%23B4507A' stroke-width='4' stroke-linecap='round'/%3E%3Cpath d='M100 16 Q105 1 96 7' fill='none' stroke='%23B4507A' stroke-width='4' stroke-linecap='round'/%3E%3Cellipse cx='87' cy='43' rx='22' ry='26' fill='%23B4507A'/%3E%3Ccircle cx='79' cy='36' r='3.4' fill='%23FBEFD4'/%3E%3Ccircle cx='95' cy='36' r='3.4' fill='%23FBEFD4'/%3E%3Ccircle cx='79.6' cy='36' r='1.5' fill='%23200A16'/%3E%3Ccircle cx='95.6' cy='36' r='1.5' fill='%23200A16'/%3E%3Cpath d='M76 49 Q87 56 98 49' fill='none' stroke='%23200A16' stroke-width='1.8' stroke-linecap='round'/%3E%3Cpath d='M79 49 L79.5 53.5 L82.5 49.5 Z' fill='%23FBEFD4'/%3E%3Cpath d='M95 49 L94.5 53.5 L91.5 49.5 Z' fill='%23FBEFD4'/%3E%3C/g%3E%3C/svg%3E");
  background-repeat:no-repeat, no-repeat;
  background-size:140% 140%, contain;
  background-position:center, center;
  filter: drop-shadow(0 2px 5px rgba(0,0,0,.4));
  transform: translate(6px, -50%);
  animation: ficheYokaiCourse 2.8s ease-in-out infinite;
}

/* ---- Forêt des Anciens (exclusif admin) ---- */
.topbar.banniere-ents{
  background:
    radial-gradient(ellipse at 15% 40%, rgba(107,122,84,.28), transparent 50%),
    radial-gradient(ellipse at 85% 60%, rgba(62,42,31,.3), transparent 45%),
    linear-gradient(145deg, #1A2218, #121810 45%, #0E140C);
  box-shadow:inset 0 -2px 0 rgba(143,168,106,.5);
  border-bottom-color:transparent;
}
.topbar.banniere-ents .player-name,
.topbar.banniere-ents .player-titre,
.topbar.banniere-ents .logout-link,
.topbar.banniere-ents .notif-bell{ color:#C8D8A8; }
.topbar.banniere-ents .player-name{ color:#F0F4E8; }
.topbar.banniere-ents .res-pill{ background:rgba(255,255,255,.1); border-color:rgba(200,216,168,.25); color:#E4ECD8; }
/* Ents plan lointain — gauche. background-position ancré en bas (pas
   "center") : sur PWA, padding-top grandit avec env(safe-area-inset-top)
   (encoche), le topbar devient bien plus haut qu'en desktop — un ancrage
   "center" faisait flotter l'arbre au milieu de cette hauteur variable au
   lieu de le garder planté au sol, quelle que soit la hauteur réelle du
   topbar. */
.topbar.banniere-ents::before{
  content:"";
  position:absolute;
  left:-10px; top:0; bottom:0;
  width:20%;
  z-index:0; pointer-events:none;
  opacity:.14;
  background-repeat:no-repeat; background-size:contain; background-position:left bottom;
  background-image:url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20110%2090'%3E%3Cg%20fill='%23C8D8A8'%3E%3Cpath%20d='M18%2090%20C16%2070%2015%2055%2017%2042%20C12%2038%208%2032%206%2026%20C10%2028%2014%2030%2018%2028%20C16%2020%2018%2012%2024%208%20C28%2014%2032%2018%2036%2016%20C34%2022%2032%2028%2034%2036%20C40%2034%2046%2036%2048%2042%20C44%2044%2040%2046%2036%2048%20C34%2060%2032%2075%2030%2090%20Z'/%3E%3Cpath%20d='M62%2090%20C60%2072%2058%2056%2060%2044%20C54%2040%2048%2034%2046%2026%20C50%2028%2056%2029%2060%2027%20C58%2018%2062%2010%2070%206%20C74%2012%2078%2016%2082%2014%20C80%2020%2078%2026%2080%2034%20C86%2032%2092%2035%2094%2042%20C88%2044%2084%2046%2078%2048%20C76%2062%2074%2076%2072%2090%20Z'/%3E%3C/g%3E%3C/svg%3E");
  transform-origin:bottom left;
  animation:ficheEntsSwayFar 16s ease-in-out infinite;
}
/* Ents plan proche — droite. Même correctif d'ancrage bas qu'à gauche. */
.topbar.banniere-ents::after{
  content:"";
  position:absolute;
  right:-8px; top:0; bottom:0;
  width:24%;
  z-index:0; pointer-events:none;
  opacity:.2;
  background-repeat:no-repeat; background-size:contain; background-position:right bottom;
  background-image:url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20150%2090'%3E%3Cg%20fill='%23C8D8A8'%3E%3Cpath%20d='M55%2090%20C52%2070%2050%2052%2053%2038%20C46%2034%2038%2028%2034%2020%20C40%2022%2046%2024%2052%2021%20C50%2012%2054%204%2064%201%20C70%207%2076%2011%2082%209%20C80%2016%2078%2022%2081%2030%20C90%2028%2098%2032%20102%2040%20C94%2042%2088%2044%2080%2046%20C78%2060%2076%2075%2074%2090%20Z'/%3E%3Cpath%20d='M48%2042%20C38%2040%2028%2042%2020%2048%20C24%2050%2030%2050%2036%2048%20C40%2052%2044%2054%2048%2052%20Z'%20opacity='.85'/%3E%3Cpath%20d='M88%2044%20C98%2040%20110%2042%20118%2048%20C112%2052%20104%2052%2096%2050%20C92%2054%2088%2054%2084%2052%20Z'%20opacity='.85'/%3E%3Cpath%20d='M120%2090%20C118%2074%20116%2060%20118%2048%20C112%2044%20106%2038%20104%2030%20C108%2032%20114%2033%20118%2031%20C116%2022%20120%2014%20128%2010%20C132%2016%20136%2020%20140%2018%20C138%2024%20136%2030%20138%2038%20C144%2036%20148%2040%20150%2046%20C144%2048%20140%2050%20134%2052%20C132%2064%20130%2078%20128%2090%20Z'/%3E%3C/g%3E%3C/svg%3E");
  transform-origin:bottom right;
  animation:ficheEntsSwayNear 11s ease-in-out infinite;
}

@media (prefers-reduced-motion:reduce){
  .topbar::before,
  .topbar::after,
  .topbar{ animation:none !important; }
}

/* Bouton "Titre" dans l'éditeur de profil, et l'écran de sélection */

.titre-pick-btn{
  width:100%;
  display:flex;align-items:center;justify-content:space-between;
  background:rgba(255,255,255,.55);
  border:1px solid rgba(43,38,32,.15);
  border-radius:10px;
  padding:9px 12px;
  font-family:inherit;font-size:12px;font-weight:700;color:var(--ink);
  cursor:pointer;
}
.titre-pick-empty{color:var(--ink-soft);font-weight:400;}
.titre-pick-arrow{color:var(--ink-soft);font-size:14px;}

.titre-panel{
  max-height:84vh;overflow-y:auto;text-align:left;
  /* Même traitement que .lb-panel : la barre de défilement grise par défaut
     du navigateur tranchait sur l'habillage papier washi. */
  scrollbar-width:none;
  -ms-overflow-style:none;
  overscroll-behavior:contain;
}
.titre-panel::-webkit-scrollbar{display:none;}
.titre-actif-row{
  display:flex;align-items:center;justify-content:space-between;
  font-size:11px;font-weight:700;color:var(--ink-soft);
  margin:8px 0 14px;
}
.titre-cat-title{
  font-size:9.5px;font-weight:700;color:var(--torii-deep);
  text-transform:uppercase;letter-spacing:.04em;
  margin:14px 0 6px;
}
.titre-cat-title:first-of-type{margin-top:0;}
.titre-list{display:flex;flex-direction:column;gap:5px;}
.titre-row{
  display:flex;align-items:center;justify-content:space-between;
  gap:10px;
  width:100%;
  background:rgba(255,255,255,.55);
  border:1px solid rgba(43,38,32,.12);
  border-radius:9px;
  padding:8px 12px;
  font-family:inherit;font-size:11.5px;font-weight:700;color:var(--ink);
  cursor:pointer;
  text-align:left;
}
.titre-row.actif{border-color:var(--gold);background:rgba(201,162,39,.14);}
.titre-row.locked{opacity:.6;cursor:default;}
/* Colonne titre + condition (style trophée) : le badge / cadenas reste à droite. */
.titre-row-text{
  display:flex;flex-direction:column;gap:2px;
  min-width:0;flex:1;
}
.titre-row-label{line-height:1.25;}
.titre-row-desc{
  font-size:10px;font-weight:500;line-height:1.35;
  color:var(--ink-soft);
}
.titre-row-badge{
  font-size:8.5px;font-weight:700;color:var(--gold);
  text-transform:uppercase;letter-spacing:.03em;
  flex-shrink:0;
}
.titre-row-lock{font-size:11px;opacity:.7;flex-shrink:0;}
.titre-buy-btn{
  font-size:9.5px;font-weight:700;
  padding:5px 10px;border-radius:8px;
  border:1px solid rgba(201,162,39,.5);
  background:rgba(201,162,39,.16);color:var(--torii-deep);
  cursor:pointer;flex-shrink:0;
}

/* ---------- Écran de sélection des cadres ---------- */
/* Variante de .titre-row avec une pastille d'aperçu en plus : un cadre ne se
   décrit pas par un simple libellé, il faut le voir pour juger s'il plaît. */
.cadre-row{
  display:flex;align-items:center;gap:10px;
  width:100%;
  background:rgba(255,255,255,.55);
  border:1px solid rgba(43,38,32,.12);
  border-radius:9px;
  padding:7px 12px;
  font-family:inherit;font-size:11.5px;font-weight:700;color:var(--ink);
  cursor:pointer;
}
.cadre-row.actif{border-color:var(--gold);background:rgba(201,162,39,.14);}
.cadre-row.locked{opacity:.75;cursor:default;}
.cadre-row-label{flex:1;text-align:left;}
/* Wrapper utilisé quand le label ET une description doivent partager la
   colonne flexible (voir ligneBanniere dans app.js) — .cadre-row-label garde
   sa règle flex:1 ci-dessus pour les appelants qui l'utilisent seul (cadres,
   thèmes de Forêt), sans wrapper. */
.cadre-row-text{flex:1;min-width:0;text-align:left;display:flex;flex-direction:column;gap:1px;}
.cadre-row-desc{
  display:block;
  font-size:9.5px;font-weight:400;
  color:var(--ink-soft);
  line-height:1.3;
}
.cadre-swatch{
  width:30px;height:30px;border-radius:50%;flex-shrink:0;
  background:linear-gradient(135deg,#CBA46A,#8B6B3E);
}
/* Pastille du sélecteur de skin de clairière : le vrai décor SVG
   (skinClairiereSvg dans app.js), pas un médaillon emoji — le disque a déjà
   sa propre bordure dans le SVG (voir ellipse fill=noeud), donc le conteneur
   reste neutre. overflow visible : le fil de la lanterne dépasse légèrement
   au-dessus du cadre de 36px pour ne pas être tronqué. */
.skin-clairiere-swatch{
  width:36px;height:36px;flex-shrink:0;
  display:flex;align-items:center;justify-content:center;
  overflow:visible;
}
/* Pastille du sélecteur de bannière de fiche : réutilise les mêmes fonds
   que .fiche-banniere.banniere-* en miniature, voir plus bas. */
.banniere-swatch-fiche{
  width:56px;height:28px;border-radius:6px;flex-shrink:0;
  border:1px solid rgba(43,38,32,.2);
  background:linear-gradient(145deg, #E8DFC8, #D4C8A8);
  position:relative;overflow:hidden;
  cursor:pointer;
}
.banniere-swatch-fiche:active{transform:scale(.94);}
.banniere-swatch-fiche.banniere-torii{ background:linear-gradient(135deg,#B54B3A,#8E3A2C); }
.banniere-swatch-fiche.banniere-vague{ background:linear-gradient(165deg,#243040,#151C28); }
.banniere-swatch-fiche.banniere-bambou{ background:linear-gradient(145deg,#3A4A38,#2A3228); }
.banniere-swatch-fiche.banniere-lune{ background:linear-gradient(160deg,#1A1E2E,#12141C); }
.banniere-swatch-fiche.banniere-sakura{ background:linear-gradient(145deg,#4A3540,#2E2430); }
.banniere-swatch-fiche.banniere-brume{ background:linear-gradient(150deg,#3A4558,#2A3040); }
.banniere-swatch-fiche.banniere-neige{ background:linear-gradient(160deg, #3A4A5C, #1E2835); }
.banniere-swatch-fiche.banniere-or{ background:linear-gradient(135deg,#9A7A1E,#C9A227); }
.banniere-swatch-fiche.banniere-yokai{ background:linear-gradient(150deg,#2A1830,#1A1020); }

/* Exclusif admin — Forêt des Anciens */
.banniere-swatch-fiche.banniere-ents{
  background:
    radial-gradient(ellipse at 30% 40%, rgba(107,122,84,.5), transparent 60%),
    linear-gradient(145deg, #1A2218, #0E140C);
}

/* ---------- Fiche joueur : carte publique en lecture seule (soi-même ou un
   autre joueur), ouverte depuis la topbar, la Forêt, le ladder ou un
   Hayashi (voir openFicheJoueur / afficherFicheJoueur dans app.js). ---------- */
.fiche-card{
  max-width:320px; text-align:left; padding:0;
  /* Même plafond que .profile-card : un titre + long historique de Hayashi
     pourrait dépasser un écran mobile en PWA. Coins arrondis conservés via
     overflow:hidden (la bannière doit rester rognée à border-radius), le
     défilement se fait donc sur le conteneur, pas sur la fiche elle-même. */
  max-height:84vh;overflow-y:auto;overflow-x:hidden;
  border-radius:16px;
  scrollbar-width:none;
  -ms-overflow-style:none;
  overscroll-behavior:contain;
}
.fiche-card::-webkit-scrollbar{display:none;}
.fiche-banniere{
  position:relative;
  overflow:hidden;
  padding:22px 16px 18px;
  background:linear-gradient(145deg, #E8DFC8, #D4C8A8);
  border-bottom:1px solid rgba(43,38,32,.12);
  display:flex; align-items:center; gap:12px;
  /* Empêche le décor (::before/::after) de déborder par-dessus l'avatar et
     le nom : ces deux-là restent au premier plan via z-index ci-dessous. */
  isolation:isolate;
}
.fiche-banniere .fiche-avatar-wrap,
.fiche-banniere .fiche-identite{
  position:relative;
  z-index:1;
}
/* Voile de lisibilité : le décor (torii, vagues…) ne doit jamais faire
   perdre le pseudo/titre, quelle que soit la bannière — texte légèrement
   ombré plutôt qu'un bandeau opaque qui casserait le fond derrière. */
.fiche-banniere .fiche-identite{
  padding:4px 8px 4px 0;
  border-radius:8px;
  text-shadow:0 1px 2px rgba(0,0,0,.75), 0 0 12px rgba(0,0,0,.35);
}
.fiche-banniere .fiche-nom{ font-weight:800; letter-spacing:.01em; }
.fiche-banniere .fiche-titre{
  opacity:.92;
  font-weight:700;
  text-shadow:0 1px 2px rgba(0,0,0,.8), 0 0 10px rgba(0,0,0,.4);
}
.fiche-avatar{
  width:56px; height:56px; border-radius:50%;
  background:linear-gradient(135deg,#CBA46A,#8B6B3E);
  border:2px solid var(--gold);
  flex-shrink:0;
  background-size:cover;
  /* center top : les JPG ~280×546 montraient le buste avec « center ».
     Uniquement sur la fiche ; les listes gardent center 14 %. */
  background-position:center top !important;
}
/* Décalage de position (pas de recadrage) : l'avatar lui-même est déplacé
   un peu vers la gauche dans la bannière, sans toucher au cadrage de
   l'image à l'intérieur du cercle. */
.fiche-avatar[style*="gardien-sumika-icon"]{
  transform:translateX(-8px);
}
.fiche-nom{
  font-family:'Shippori Mincho',serif;
  font-size:16px; font-weight:800;
  color:var(--ink);
}
.fiche-titre{
  font-size:11px; color:var(--ink-soft);
  margin-top:3px; font-weight:700;
}
.fiche-meta{ padding:12px 16px; }
.fiche-meta-row{
  display:flex; justify-content:space-between; gap:10px;
  font-size:12px; padding:6px 0;
  border-bottom:1px dashed rgba(43,38,32,.1);
}
.fiche-meta-row:last-child{ border-bottom:none; }
.fiche-meta-row span{ color:var(--ink-soft); }
.fiche-card .confirm-actions{ padding:0 16px 16px; }
/* Noms cliquables qui ouvrent une fiche (Forêt, ladder, Hayashi) : le style
   reste discret par défaut (le curseur suffit à signaler l'interactivité,
   pas besoin de souligner en permanence des dizaines de noms) et ne se
   souligne qu'au survol/focus. */
.fiche-link{ cursor:pointer; }
.fiche-link:hover, .fiche-link:focus-visible{
  color:var(--torii-deep);
  text-decoration:underline; text-underline-offset:2px;
}

/* ---------- Bannières de fiche (cosmétique acheté avec de l'Essence
   spirituelle, voir BANNIERES_FICHE_CLIENT dans app.js). "default" (Washi)
   est le fond neutre déjà posé sur .fiche-banniere ci-dessus, donc aucune
   règle supplémentaire n'est nécessaire pour lui. ---------- */
.fiche-banniere.banniere-torii{
  background:
    linear-gradient(135deg, rgba(181,75,58,.55), rgba(142,58,44,.75)),
    linear-gradient(145deg, #3A2A28, #2A1E1C);
  color:#F0E4C4;
}
/* Blanc cassé plein (pas le crème du fond, qui se fond dans le rouge) : le
   titre doré d'origine se faisait manger par le fond corail. */
.fiche-banniere.banniere-torii .fiche-nom{ color:#FFF6E8; }
.fiche-banniere.banniere-torii .fiche-titre{ color:#F0DCC0; opacity:1; }
/* .titre-halo-yokai force color: torii-deep !important → invisible sur fond rouge */
.fiche-banniere.banniere-torii .fiche-titre.titre-halo-yokai,
.fiche-banniere.banniere-torii .fiche-titre.titre-halo-torii,
.fiche-banniere.banniere-torii .fiche-titre.titre-halo-or,
.fiche-banniere.banniere-torii .fiche-titre.titre-halo-brume,
.fiche-banniere.banniere-torii .fiche-titre[class*="titre-halo-"]{
  color:#F0E4C4 !important;
  text-shadow:0 0 10px rgba(240,228,196,.55), 0 1px 3px rgba(0,0,0,.45) !important;
}

/* Portail en filigrane à droite, qui respire lentement (pulse d'opacité
   seul — aucun déplacement, pour ne rien imposer à un lecteur qui
   s'attarde sur la fiche). Plus petit, plus discret, plus à l'écart du
   texte que la première version — il ne doit rester qu'un détail. */
.fiche-banniere.banniere-torii::before{
  content:"";
  position:absolute;
  right:4px; top:50%;
  transform:translateY(-50%);
  width:72px; height:62px;
  z-index:0;
  pointer-events:none;
  background-repeat:no-repeat;
  background-size:contain;
  background-position:center;
  background-image:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 80 70' fill='%23F0E4C4'%3E%3Crect x='6' y='8' width='68' height='5' rx='1'/%3E%3Crect x='12' y='16' width='56' height='3.5'/%3E%3Crect x='18' y='20' width='5' height='42'/%3E%3Crect x='57' y='20' width='5' height='42'/%3E%3Crect x='14' y='30' width='52' height='3'/%3E%3C/svg%3E");
  opacity:.14;
  animation:ficheToriiLueur 14s ease-in-out infinite;
}
@keyframes ficheToriiLueur{
  0%, 100%{ opacity:.10; }
  50%{ opacity:.18; }
}
@keyframes ficheBambouSway {
  0%, 100% { transform: translateX(0) rotate(0deg); }
  50%      { transform: translateX(-3px) rotate(-0.6deg); }
}
@keyframes ficheOrScintille {
  0%, 100% { opacity: .22; background-position: 0 0; }
  50%      { opacity: .38; background-position: 12px -8px; }
}
@keyframes ficheBrumeDerive {
  0%   { background-position: 0% 40%, 100% 30%, 50% 60%; }
  50%  { background-position: 8% 45%, 92% 25%, 48% 55%; }
  100% { background-position: 0% 40%, 100% 30%, 50% 60%; }
}
@keyframes ficheLuneHalo {
  0%, 100% { opacity: .28; transform: translateY(-50%) scale(1); }
  50%      { opacity: .42; transform: translateY(-50%) scale(1.05); }
}
/* Filet or en bas, commun aux bannières premium (torii/vague) */
.fiche-banniere.banniere-torii::after,
.fiche-banniere.banniere-vague::after{
  content:"";
  position:absolute;
  left:0; right:0; bottom:0;
  height:3px;
  z-index:2;
  pointer-events:none;
}
.fiche-banniere.banniere-torii::after{
  background:linear-gradient(90deg,
    transparent 5%, #C9A227 25%, #E8D58A 50%, #C9A227 75%, transparent 95%);
}

.fiche-banniere.banniere-vague{
  background:
    radial-gradient(ellipse at 15% 90%, rgba(90,140,180,.28), transparent 55%),
    radial-gradient(ellipse at 85% 15%, rgba(110,160,200,.18), transparent 50%),
    linear-gradient(165deg, #243040 0%, #1A2435 55%, #151C28 100%);
  color:#E8F0F8;
}
.fiche-banniere.banniere-vague .fiche-nom,
.fiche-banniere.banniere-vague .fiche-titre{ color:#E8F0F8; }
.fiche-banniere.banniere-vague .fiche-titre.titre-halo-yokai,
.fiche-banniere.banniere-vague .fiche-titre.titre-halo-torii,
.fiche-banniere.banniere-vague .fiche-titre[class*="titre-halo-"]{
  color:#E8F0F8 !important;
  text-shadow:0 0 10px rgba(138,180,210,.55), 0 1px 3px rgba(0,0,0,.45) !important;
}

/* Seigaiha traditionnel (écailles imbriquées), plus dense et lisible. */
.fiche-banniere.banniere-vague::before{
  content:"";
  position:absolute;
  inset:0;
  z-index:0;
  pointer-events:none;
  opacity:.28;
  background-image:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='48' height='24' viewBox='0 0 48 24'%3E%3Cpath d='M0 24a12 12 0 0 1 12-12 12 12 0 0 1 12 12 12 12 0 0 1 12-12 12 12 0 0 1 12 12' fill='none' stroke='%2398C4D8' stroke-width='1.15'/%3E%3Cpath d='M0 24a8 8 0 0 1 8-8 8 8 0 0 1 8 8 8 8 0 0 1 8-8 8 8 0 0 1 8 8 8 8 0 0 1 8-8 8 8 0 0 1 8 8' fill='none' stroke='%237AA8C0' stroke-width='.85' opacity='.85'/%3E%3Cpath d='M-12 12a12 12 0 0 1 12-12 12 12 0 0 1 12 12 12 12 0 0 1 12-12 12 12 0 0 1 12 12 12 12 0 0 1 12-12 12 12 0 0 1 12 12' fill='none' stroke='%2398C4D8' stroke-width='1.15'/%3E%3Cpath d='M-8 12a8 8 0 0 1 8-8 8 8 0 0 1 8 8 8 8 0 0 1 8-8 8 8 0 0 1 8 8 8 8 0 0 1 8-8 8 8 0 0 1 8 8' fill='none' stroke='%237AA8C0' stroke-width='.85' opacity='.85'/%3E%3C/svg%3E");
  background-size:48px 24px;
  background-repeat:repeat;
  mask-image:linear-gradient(90deg, transparent 0%, #000 28%, #000 100%);
  -webkit-mask-image:linear-gradient(90deg, transparent 0%, #000 28%, #000 100%);
  animation:ficheVagueDerive 22s linear infinite;
}
@keyframes ficheVagueDerive{
  0%{ background-position:0 0; }
  100%{ background-position:48px 0; }
}
.fiche-banniere.banniere-vague::after{
  background:linear-gradient(90deg,
    transparent 5%, #7EB0C8 30%, #C8E4F0 50%, #7EB0C8 70%, transparent 95%);
  opacity:.9;
}

/* Coupe tout mouvement décoratif pour qui préfère moins d'animation —
   s'applique à toute bannière future, pas seulement torii/vague. */
@media (prefers-reduced-motion:reduce){
  .fiche-banniere::before,
  .fiche-banniere::after,
  .fiche-banniere *{
    animation:none !important;
  }
}

.fiche-banniere.banniere-bambou{
  background: linear-gradient(145deg, #3A4A38, #2A3228);
  color:#E4ECD8;
}
.fiche-banniere.banniere-bambou .fiche-nom,
.fiche-banniere.banniere-bambou .fiche-titre{ color:#E4ECD8; }
.fiche-banniere.banniere-bambou .fiche-titre[class*="titre-halo-"]{
  color:#E4ECD8 !important;
  text-shadow:0 0 8px rgba(180,200,140,.4), 0 1px 2px rgba(0,0,0,.35);
}
.fiche-banniere.banniere-bambou::before{
  content:"";
  position:absolute;
  right:0; top:0; bottom:0; width:55%;
  z-index:0; pointer-events:none; opacity:.22;
  background-image:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 90'%3E%3Cg fill='none' stroke='%23C8D8A8' stroke-width='2.2' stroke-linecap='round'%3E%3Cpath d='M28 90 V12'/%3E%3Cpath d='M28 28 h8'/%3E%3Cpath d='M28 48 h-7'/%3E%3Cpath d='M28 68 h8'/%3E%3Cpath d='M52 90 V8'/%3E%3Cpath d='M52 22 h-7'/%3E%3Cpath d='M52 42 h8'/%3E%3Cpath d='M52 62 h-7'/%3E%3Cpath d='M76 90 V18'/%3E%3Cpath d='M76 34 h8'/%3E%3Cpath d='M76 54 h-7'/%3E%3C/g%3E%3Cg fill='%23C8D8A8' opacity='.85'%3E%3Cellipse cx='38' cy='20' rx='9' ry='3.5' transform='rotate(-35 38 20)'/%3E%3Cellipse cx='20' cy='44' rx='8' ry='3' transform='rotate(28 20 44)'/%3E%3Cellipse cx='62' cy='30' rx='9' ry='3.5' transform='rotate(40 62 30)'/%3E%3Cellipse cx='86' cy='40' rx='8' ry='3' transform='rotate(-30 86 40)'/%3E%3C/g%3E%3C/svg%3E");
  background-size:contain; background-repeat:no-repeat; background-position:right center;
  transform-origin: bottom center;
  animation:ficheBambouSway 7s ease-in-out infinite;
}
.fiche-banniere.banniere-bambou::after{
  content:""; position:absolute; left:0; right:0; bottom:0; height:3px; z-index:2; pointer-events:none;
  background:linear-gradient(90deg, transparent 5%, #8FA86A 30%, #C8D8A8 50%, #8FA86A 70%, transparent 95%);
  opacity:.85;
}

.fiche-banniere.banniere-lune{
  background: linear-gradient(160deg, #1A1E2E, #12141C);
  color:#E8E4F0;
}
.fiche-banniere.banniere-lune .fiche-nom,
.fiche-banniere.banniere-lune .fiche-titre{ color:#E8E4F0; }
.fiche-banniere.banniere-lune .fiche-titre[class*="titre-halo-"]{
  color:#E8E4F0 !important;
  text-shadow:0 0 8px rgba(200,190,230,.45), 0 1px 2px rgba(0,0,0,.4);
}
.fiche-banniere.banniere-lune::before{
  content:"";
  position:absolute;
  right:6px; top:50%; transform:translateY(-50%);
  width:78px; height:68px;
  z-index:0; pointer-events:none; opacity:.35;
  background-image:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 80 70'%3E%3Ccircle cx='52' cy='28' r='16' fill='%23F0E4C4' opacity='.9'/%3E%3Ccircle cx='58' cy='24' r='14' fill='%231A1E2E'/%3E%3Cg fill='%23F0E4C4'%3E%3Ccircle cx='12' cy='14' r='1.3'/%3E%3Ccircle cx='22' cy='8' r='.9'/%3E%3Ccircle cx='8' cy='32' r='1.1'/%3E%3Ccircle cx='18' cy='48' r='.8'/%3E%3Ccircle cx='30' cy='58' r='1.2'/%3E%3Ccircle cx='42' cy='62' r='.7'/%3E%3Ccircle cx='68' cy='54' r='1'/%3E%3Ccircle cx='74' cy='42' r='.8'/%3E%3C/g%3E%3C/svg%3E");
  background-size:contain; background-repeat:no-repeat; background-position:center;
  animation:ficheLuneHalo 10s ease-in-out infinite;
}
.fiche-banniere.banniere-lune::after{
  content:"";
  position:absolute;
  inset:0;
  z-index:0;
  pointer-events:none;
  /* Filet doré-argent en bas */
  background:
    linear-gradient(90deg, transparent 5%, #8A9BB8 30%, #C8D4E8 50%, #8A9BB8 70%, transparent 95%) bottom / 100% 3px no-repeat,
    /* Étoile filante 1 */
    linear-gradient(122deg, transparent 0%, transparent 42%, rgba(240,228,196,.95) 46%, rgba(240,228,196,.35) 52%, transparent 58%) 72% 18% / 56px 2px no-repeat,
    /* Étoile filante 2 */
    linear-gradient(118deg, transparent 0%, transparent 40%, rgba(220,230,255,.9) 45%, rgba(220,230,255,.3) 55%, transparent 60%) 88% 38% / 42px 1.5px no-repeat;
  animation: ficheLuneFilantes 9s linear infinite;
  opacity:.9;
}
/* Les deux étoiles filent en même temps (0→42%), sur des trajectoires
   légèrement différentes, puis restent parquées hors-champ jusqu'au
   prochain cycle — plus naturel que l'ancien enchaînement l'une après
   l'autre. */
@keyframes ficheLuneFilantes {
  0%   { background-position: bottom, 130% -20%, 150% -8%; }
  42%  { background-position: bottom, -25% 92%, -18% 96%; }
  100% { background-position: bottom, -25% 92%, -18% 96%; }
}

.fiche-banniere.banniere-sakura{
  background: linear-gradient(145deg, #4A3540, #2E2430);
  color:#F8E8EE;
}
.fiche-banniere.banniere-sakura .fiche-nom,
.fiche-banniere.banniere-sakura .fiche-titre{ color:#F8E8EE; }
.fiche-banniere.banniere-sakura .fiche-titre[class*="titre-halo-"]{
  color:#F8E8EE !important;
  text-shadow:0 0 8px rgba(243,198,211,.5), 0 1px 2px rgba(0,0,0,.35);
}
.fiche-banniere.banniere-sakura::before{
  content:"";
  position:absolute; inset:0; z-index:0; pointer-events:none; opacity:.32;
  background-image:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='80' viewBox='0 0 120 80'%3E%3Cg fill='%23F3C6D3'%3E%3Cellipse cx='18' cy='16' rx='5' ry='3.2' transform='rotate(-20 18 16)'/%3E%3Cellipse cx='42' cy='10' rx='4' ry='2.6' transform='rotate(15 42 10)'/%3E%3Cellipse cx='68' cy='22' rx='5.5' ry='3.4' transform='rotate(-35 68 22)'/%3E%3Cellipse cx='95' cy='14' rx='4.2' ry='2.8' transform='rotate(25 95 14)'/%3E%3Cellipse cx='28' cy='48' rx='4.8' ry='3' transform='rotate(40 28 48)'/%3E%3Cellipse cx='55' cy='58' rx='5' ry='3.2' transform='rotate(-15 55 58)'/%3E%3Cellipse cx='82' cy='52' rx='4' ry='2.6' transform='rotate(30 82 52)'/%3E%3Cellipse cx='108' cy='42' rx='5' ry='3' transform='rotate(-40 108 42)'/%3E%3Cellipse cx='12' cy='68' rx='3.5' ry='2.2' transform='rotate(10 12 68)'/%3E%3C/g%3E%3C/svg%3E");
  background-size:120px 80px; background-repeat:repeat;
  animation:ficheSakuraTombe 10s linear infinite;
}
@keyframes ficheSakuraTombe {
  0%   { background-position: 0 0; }
  100% { background-position: -30px 80px; }
}
.fiche-banniere.banniere-sakura::after{
  content:""; position:absolute; left:0; right:0; bottom:0; height:3px; z-index:2; pointer-events:none;
  background:linear-gradient(90deg, transparent 5%, #E8A0B4 30%, #F3C6D3 50%, #E8A0B4 70%, transparent 95%);
  opacity:.85;
}

/* ---- Brume ---- */
.fiche-banniere.banniere-brume{
  background: linear-gradient(150deg, #3A4558 0%, #2A3040 55%, #222838 100%);
  color:#E4E8F0;
}
.fiche-banniere.banniere-brume .fiche-nom,
.fiche-banniere.banniere-brume .fiche-titre{ color:#E4E8F0; }
.fiche-banniere.banniere-brume .fiche-titre[class*="titre-halo-"]{
  color:#E4E8F0 !important;
  text-shadow:0 0 8px rgba(180,190,210,.45), 0 1px 2px rgba(0,0,0,.4);
}
.fiche-banniere.banniere-brume::before{
  content:"";
  position:absolute; inset:0; z-index:0; pointer-events:none;
  background:
    radial-gradient(ellipse at 20% 80%, rgba(200,210,230,.22), transparent 50%),
    radial-gradient(ellipse at 75% 30%, rgba(180,190,210,.18), transparent 45%),
    radial-gradient(ellipse at 50% 60%, rgba(220,225,235,.12), transparent 40%);
  background-size: 120% 120%, 120% 120%, 100% 100%;
  animation:ficheBrumeDerive 14s ease-in-out infinite;
}
.fiche-banniere.banniere-brume::after{
  content:""; position:absolute; left:0; right:0; bottom:0; height:3px; z-index:2; pointer-events:none;
  background:linear-gradient(90deg, transparent 5%, #8A9BB0 30%, #C0CAD8 50%, #8A9BB0 70%, transparent 95%);
  opacity:.75;
}

/* ---- Neige ---- */
@keyframes ficheNeigeTombe {
  0%   { background-position: 0 0, 20px -40px, 40px -80px; }
  100% { background-position: 0 120px, 20px 80px, 40px 40px; }
}

.fiche-banniere.banniere-neige{
  background: linear-gradient(165deg, #2A3545 0%, #1A222E 55%, #141A24 100%);
  color:#E8EEF4;
}
.fiche-banniere.banniere-neige .fiche-nom,
.fiche-banniere.banniere-neige .fiche-titre{ color:#E8EEF4; }
.fiche-banniere.banniere-neige .fiche-titre[class*="titre-halo-"]{
  color:#E8EEF4 !important;
  text-shadow:0 0 8px rgba(200,220,240,.45), 0 1px 2px rgba(0,0,0,.4);
}

/* 3 calques de flocons (tailles / vitesses différentes via background-size) */
.fiche-banniere.banniere-neige::before{
  content:"";
  position:absolute;
  inset:0;
  z-index:0;
  pointer-events:none;
  opacity:.7;
  background-image:
    /* gros flocons */
    url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='48' height='48' viewBox='0 0 48 48'%3E%3Cg fill='%23E8F0F8' opacity='.9'%3E%3Ccircle cx='8' cy='10' r='1.6'/%3E%3Ccircle cx='28' cy='6' r='1.2'/%3E%3Ccircle cx='40' cy='18' r='1.8'/%3E%3Ccircle cx='16' cy='30' r='1.4'/%3E%3Ccircle cx='36' cy='36' r='1.1'/%3E%3Ccircle cx='6' cy='40' r='1.3'/%3E%3C/g%3E%3C/svg%3E"),
    /* moyens */
    url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='36' height='36' viewBox='0 0 36 36'%3E%3Cg fill='%23D0DCE8' opacity='.75'%3E%3Ccircle cx='6' cy='8' r='1.1'/%3E%3Ccircle cx='20' cy='4' r='.9'/%3E%3Ccircle cx='30' cy='16' r='1.2'/%3E%3Ccircle cx='12' cy='24' r='1'/%3E%3Ccircle cx='26' cy='28' r='.8'/%3E%3C/g%3E%3C/svg%3E"),
    /* fins */
    url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cg fill='%23C0D0E0' opacity='.6'%3E%3Ccircle cx='4' cy='5' r='.7'/%3E%3Ccircle cx='14' cy='3' r='.5'/%3E%3Ccircle cx='20' cy='12' r='.8'/%3E%3Ccircle cx='8' cy='18' r='.6'/%3E%3C/g%3E%3C/svg%3E");
  background-size: 48px 48px, 36px 36px, 24px 24px;
  background-repeat: repeat;
  animation: ficheNeigeTombe 11s linear infinite;
}

.fiche-banniere.banniere-neige::after{
  content:"";
  position:absolute; left:0; right:0; bottom:0; height:3px;
  z-index:2; pointer-events:none;
  background:linear-gradient(90deg, transparent 5%, #8AA0B8 30%, #D0DCE8 50%, #8AA0B8 70%, transparent 95%);
  opacity:.85;
}

/* ---- Or ---- */
.fiche-banniere.banniere-or{
  background: linear-gradient(135deg, #6B5420 0%, #4A3A14 50%, #3A2E10 100%);
  color:#F8ECC8;
}
.fiche-banniere.banniere-or .fiche-nom,
.fiche-banniere.banniere-or .fiche-titre{ color:#F8ECC8; }
.fiche-banniere.banniere-or .fiche-titre[class*="titre-halo-"]{
  color:#F8ECC8 !important;
  text-shadow:0 0 10px rgba(201,162,39,.55), 0 1px 2px rgba(0,0,0,.45);
}
.fiche-banniere.banniere-or::before{
  content:"";
  position:absolute; inset:0; z-index:0; pointer-events:none; opacity:.28;
  background-image:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='60' height='60' viewBox='0 0 60 60'%3E%3Cg fill='%23E8D58A'%3E%3Ccircle cx='10' cy='12' r='1.4'/%3E%3Ccircle cx='30' cy='8' r='1'/%3E%3Ccircle cx='48' cy='16' r='1.2'/%3E%3Ccircle cx='18' cy='32' r='.9'/%3E%3Ccircle cx='40' cy='28' r='1.3'/%3E%3Ccircle cx='8' cy='48' r='1.1'/%3E%3Ccircle cx='28' cy='52' r='.8'/%3E%3Ccircle cx='52' cy='44' r='1.2'/%3E%3C/g%3E%3Cpath d='M0 30 Q15 22 30 30 T60 30' fill='none' stroke='%23C9A227' stroke-width='.7' opacity='.6'/%3E%3Cpath d='M0 45 Q15 37 30 45 T60 45' fill='none' stroke='%23C9A227' stroke-width='.55' opacity='.4'/%3E%3C/svg%3E");
  background-size:60px 60px; background-repeat:repeat;
  animation:ficheOrScintille 5s ease-in-out infinite;
}
.fiche-banniere.banniere-or::after{
  content:""; position:absolute; left:0; right:0; bottom:0; height:3px; z-index:2; pointer-events:none;
  background:linear-gradient(90deg, transparent 5%, #C9A227 25%, #E8D58A 50%, #C9A227 75%, transparent 95%);
  opacity:.95;
}

/* ---- Yokai ---- */
.fiche-banniere.banniere-yokai{
  background: linear-gradient(150deg, #2A1830 0%, #1A1020 55%, #120C18 100%);
  color:#F0DCE8;
}
.fiche-banniere.banniere-yokai .fiche-nom,
.fiche-banniere.banniere-yokai .fiche-titre{ color:#F0DCE8; }
.fiche-banniere.banniere-yokai .fiche-titre[class*="titre-halo-"]{
  color:#F0DCE8 !important;
  text-shadow:0 0 10px rgba(180,80,120,.5), 0 1px 2px rgba(0,0,0,.5);
}
/* Halo mauve derrière la scène pour donner de la profondeur */
.fiche-banniere.banniere-yokai::before{
  content:"";
  position:absolute;
  right:0; top:50%;
  width:120px; height:66px;
  z-index:0; pointer-events:none; opacity:.7;
  /* Face-à-face en gros plan : la tronche du Tanuki à gauche, celle du
     Yokai à droite — plus lisible en miniature (swatch de boutique) que
     l'ancienne scène de course en petits personnages entiers. */
  background-image:
    radial-gradient(ellipse at 62% 55%, rgba(180,92,130,.4), transparent 68%),
    url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 70' fill='none'%3E%3C!-- Tanuki (gauche) --%3E%3Cg%3E%3Cellipse cx='18' cy='17' rx='8' ry='11' fill='%23D9AE76'/%3E%3Cellipse cx='50' cy='17' rx='8' ry='11' fill='%23D9AE76'/%3E%3Cellipse cx='18' cy='18' rx='4' ry='6.5' fill='%23F0D4A8'/%3E%3Cellipse cx='50' cy='18' rx='4' ry='6.5' fill='%23F0D4A8'/%3E%3Cellipse cx='34' cy='41' rx='26' ry='23' fill='%23D9AE76'/%3E%3Cellipse cx='34' cy='37' rx='19' ry='17' fill='%23E8C48A'/%3E%3Cellipse cx='34' cy='40' rx='15' ry='9' fill='%232A2018' opacity='.9'/%3E%3Ccircle cx='27' cy='38' r='3.2' fill='%23FBEFD4'/%3E%3Ccircle cx='41' cy='38' r='3.2' fill='%23FBEFD4'/%3E%3Ccircle cx='27.4' cy='38' r='1.4' fill='%23200A16'/%3E%3Ccircle cx='41.4' cy='38' r='1.4' fill='%23200A16'/%3E%3Cellipse cx='34' cy='46' rx='3' ry='2' fill='%232A2018'/%3E%3C/g%3E%3C!-- Yokai (droite) --%3E%3Cg%3E%3Cpath d='M74 16 Q69 1 78 7' fill='none' stroke='%23B4507A' stroke-width='4' stroke-linecap='round'/%3E%3Cpath d='M100 16 Q105 1 96 7' fill='none' stroke='%23B4507A' stroke-width='4' stroke-linecap='round'/%3E%3Cellipse cx='87' cy='43' rx='22' ry='26' fill='%23B4507A'/%3E%3Ccircle cx='79' cy='36' r='3.4' fill='%23FBEFD4'/%3E%3Ccircle cx='95' cy='36' r='3.4' fill='%23FBEFD4'/%3E%3Ccircle cx='79.6' cy='36' r='1.5' fill='%23200A16'/%3E%3Ccircle cx='95.6' cy='36' r='1.5' fill='%23200A16'/%3E%3Cpath d='M76 49 Q87 56 98 49' fill='none' stroke='%23200A16' stroke-width='1.8' stroke-linecap='round'/%3E%3Cpath d='M79 49 L79.5 53.5 L82.5 49.5 Z' fill='%23FBEFD4'/%3E%3Cpath d='M95 49 L94.5 53.5 L91.5 49.5 Z' fill='%23FBEFD4'/%3E%3C/g%3E%3C/svg%3E");
  background-repeat:no-repeat, no-repeat;
  background-size:140% 140%, contain;
  background-position:center, center;
  filter: drop-shadow(0 2px 5px rgba(0,0,0,.4));
  transform: translate(6px, -50%);
  animation: ficheYokaiCourse 2.8s ease-in-out infinite;
}
@keyframes ficheYokaiCourse {
  0%   { transform: translate(6px, -50%); }
  50%  { transform: translate(-4px, -50%); }
  100% { transform: translate(6px, -50%); }
}
.fiche-banniere.banniere-yokai::after{
  content:""; position:absolute; left:0; right:0; bottom:0; height:3px; z-index:2; pointer-events:none;
  background:linear-gradient(90deg, transparent 5%, #8B3A5C 30%, #E8A0B8 50%, #8B3A5C 70%, transparent 95%);
  opacity:.9;
}

/* ---- Forêt des Anciens — exclusif admin (Gardien du Sumika) ----
   Ents organiques (v2) : troncs noueux, bras-branches écartés, couronnes
   irrégulières — la v1 (troncs verticaux stricts) ressemblait davantage à
   des lampadaires qu'à des arbres vivants. Toujours deux plans (gauche
   lointain/pâle, droite proche/marqué) avec balancement décalé pour la
   profondeur. Ligne du bas en box-shadow inset (au lieu du ::after dégradé
   des autres bannières) puisque les deux pseudo-éléments sont pris par les
   deux plans d'ents. */
.fiche-banniere.banniere-ents{
  background:
    radial-gradient(ellipse at 20% 30%, rgba(107,122,84,.25), transparent 55%),
    radial-gradient(ellipse at 80% 70%, rgba(62,42,31,.35), transparent 50%),
    linear-gradient(145deg, #1A2218, #121810 45%, #0E140C);
  color:#E4ECD8;
  box-shadow:inset 0 -3px 0 rgba(143,168,106,.55);
}
.fiche-banniere.banniere-ents .fiche-nom{ color:#F0F4E8; }
.fiche-banniere.banniere-ents .fiche-titre{ color:#C8D8A8; opacity:1; }
.fiche-banniere.banniere-ents .fiche-titre[class*="titre-halo-"]{
  color:#E4ECD8 !important;
  text-shadow:0 0 10px rgba(143,168,106,.45), 0 1px 3px rgba(0,0,0,.5) !important;
}
/* Plan lointain — gauche, deux ents noueux plus pâles */
.fiche-banniere.banniere-ents::before{
  content:"";
  position:absolute;
  left:-8px; top:0; bottom:0;
  width:50%;
  z-index:0;
  pointer-events:none;
  opacity:.15;
  background-repeat:no-repeat;
  background-size:contain;
  background-position:left center;
  background-image:url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20110%2090'%3E%3Cg%20fill='%23C8D8A8'%3E%3Cpath%20d='M18%2090%20C16%2070%2015%2055%2017%2042%20C12%2038%208%2032%206%2026%20C10%2028%2014%2030%2018%2028%20C16%2020%2018%2012%2024%208%20C28%2014%2032%2018%2036%2016%20C34%2022%2032%2028%2034%2036%20C40%2034%2046%2036%2048%2042%20C44%2044%2040%2046%2036%2048%20C34%2060%2032%2075%2030%2090%20Z'/%3E%3Cpath%20d='M62%2090%20C60%2072%2058%2056%2060%2044%20C54%2040%2048%2034%2046%2026%20C50%2028%2056%2029%2060%2027%20C58%2018%2062%2010%2070%206%20C74%2012%2078%2016%2082%2014%20C80%2020%2078%2026%2080%2034%20C86%2032%2092%2035%2094%2042%20C88%2044%2084%2046%2078%2048%20C76%2062%2074%2076%2072%2090%20Z'/%3E%3C/g%3E%3C/svg%3E");
  transform-origin:bottom left;
  animation:ficheEntsSwayFar 16s ease-in-out infinite;
}
/* Plan proche — droite, ent massif + bras écartés + deux ents plus petits */
.fiche-banniere.banniere-ents::after{
  content:"";
  position:absolute;
  right:-6px; top:0; bottom:0;
  width:60%;
  z-index:0;
  pointer-events:none;
  opacity:.24;
  background-repeat:no-repeat;
  background-size:contain;
  background-position:right center;
  background-image:url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20150%2090'%3E%3Cg%20fill='%23C8D8A8'%3E%3Cpath%20d='M55%2090%20C52%2070%2050%2052%2053%2038%20C46%2034%2038%2028%2034%2020%20C40%2022%2046%2024%2052%2021%20C50%2012%2054%204%2064%201%20C70%207%2076%2011%2082%209%20C80%2016%2078%2022%2081%2030%20C90%2028%2098%2032%20102%2040%20C94%2042%2088%2044%2080%2046%20C78%2060%2076%2075%2074%2090%20Z'/%3E%3Cpath%20d='M48%2042%20C38%2040%2028%2042%2020%2048%20C24%2050%2030%2050%2036%2048%20C40%2052%2044%2054%2048%2052%20Z'%20opacity='.85'/%3E%3Cpath%20d='M88%2044%20C98%2040%20110%2042%20118%2048%20C112%2052%20104%2052%2096%2050%20C92%2054%2088%2054%2084%2052%20Z'%20opacity='.85'/%3E%3Cpath%20d='M120%2090%20C118%2074%20116%2060%20118%2048%20C112%2044%20106%2038%20104%2030%20C108%2032%20114%2033%20118%2031%20C116%2022%20120%2014%20128%2010%20C132%2016%20136%2020%20140%2018%20C138%2024%20136%2030%20138%2038%20C144%2036%20148%2040%20150%2046%20C144%2048%20140%2050%20134%2052%20C132%2064%20130%2078%20128%2090%20Z'/%3E%3Cpath%20d='M22%2090%20C20%2076%2018%2062%2020%2050%20C14%2046%208%2040%206%2032%20C10%2034%2016%2035%2020%2033%20C18%2024%2022%2016%2030%2012%20C34%2018%2038%2022%2042%2020%20C40%2026%2038%2032%2040%2040%20C46%2038%2050%2042%2052%2048%20C46%2050%2040%2052%2034%2054%20C32%2066%2030%2078%2028%2090%20Z'%20opacity='.75'/%3E%3C/g%3E%3Cg%20fill='none'%20stroke='%23C8D8A8'%20stroke-width='1.5'%20stroke-linecap='round'%20opacity='.45'%3E%3Cpath%20d='M40%2090%20C48%2082%2056%2084%2064%2090'/%3E%3Cpath%20d='M70%2090%20C80%2080%2090%2082%20100%2090'/%3E%3Cpath%20d='M14%2090%20C22%2084%2028%2086%2034%2090'/%3E%3C/g%3E%3C/svg%3E");
  transform-origin:bottom right;
  animation:ficheEntsSwayNear 11s ease-in-out infinite;
}
@keyframes ficheEntsSwayFar{
  0%, 100%{ transform:translateX(0) rotate(0deg); }
  50%     { transform:translateX(3px) rotate(0.5deg); }
}
@keyframes ficheEntsSwayNear{
  0%, 100%{ transform:translateX(0) rotate(0deg); }
  50%     { transform:translateX(-4px) rotate(-0.8deg); }
}
/* Pas de bloc prefers-reduced-motion dédié : la règle globale
   ".fiche-banniere *{ animation:none !important; }" plus haut couvre déjà
   ::before/::after de banniere-ents comme toutes les autres bannières. */

/* ---------- Décors vivants des skins de clairière (skinClairiereSvg dans
   app.js). Chaque skin anime via classes CSS + keyframes plutôt que des
   <animate> SVG individuels — plus lisible à maintenir que 15 <animate>
   éparpillés dans le template, et le sélecteur .cf-skin-autre centralise en
   un seul endroit la version « sobre » montrée sur les repaires des autres
   joueurs (au lieu de ternaires moi/autre répétés dans chaque skin). ---------- */

@keyframes cfMousseOndule {
  0%, 100% { transform: rotate(-4deg); }
  50%      { transform: rotate(5deg); }
}
@keyframes cfMousseRespire {
  0%, 100% { opacity: .22; }
  50%      { opacity: .38; }
}

@keyframes cfLuneHalo {
  0%, 100% { opacity: .14; transform: scale(1); }
  50%      { opacity: .28; transform: scale(1.06); }
}
@keyframes cfLuneScintille {
  0%, 100% { opacity: .35; }
  40%      { opacity: 1; }
  60%      { opacity: .5; }
}
@keyframes cfLuneBrume {
  0%   { transform: translateX(-6px); opacity: .15; }
  50%  { transform: translateX(6px); opacity: .28; }
  100% { transform: translateX(-6px); opacity: .15; }
}

@keyframes cfLanterneBalancement {
  0%, 100% { transform: rotate(-6deg); }
  50%      { transform: rotate(7deg); }
}
@keyframes cfLanterneSol {
  0%, 100% { opacity: .28; }
  50%      { opacity: .48; }
}
.cf-skin-mousse .cf-fougere {
  transform-origin: bottom center;
  animation: cfMousseOndule 3.2s ease-in-out infinite;
}
.cf-skin-mousse .cf-fougere:nth-child(2) { animation-delay: -.8s; animation-duration: 3.8s; }
.cf-skin-mousse .cf-fougere:nth-child(3) { animation-delay: -1.4s; animation-duration: 2.9s; }
.cf-skin-mousse .cf-lueur { animation: cfMousseRespire 4s ease-in-out infinite; }

.cf-skin-lune .cf-halo { animation: cfLuneHalo 5s ease-in-out infinite; transform-origin: center; }
.cf-skin-lune .cf-etoile { animation: cfLuneScintille 2.4s ease-in-out infinite; }
.cf-skin-lune .cf-etoile:nth-child(2) { animation-delay: .6s; }
.cf-skin-lune .cf-etoile:nth-child(3) { animation-delay: 1.3s; }
.cf-skin-lune .cf-brume { animation: cfLuneBrume 8s ease-in-out infinite; }

.cf-skin-lanterne .cf-lanterne-corps {
  transform-origin: top center;
  animation: cfLanterneBalancement 2.8s ease-in-out infinite;
}
.cf-skin-lanterne .cf-lueur-sol { animation: cfLanterneSol 2s ease-in-out infinite; }

/* Version allégée sur les nœuds des autres : on cache les mini-lanternes
   satellites et on ralentit les mouvements de fond, plutôt que de
   dupliquer le SVG en JS. */
.cf-skin-autre .cf-lanterne-satellite { display: none; }
.cf-skin-autre .cf-fougere { animation-duration: 5s; }
.cf-skin-autre .cf-lanterne-corps { animation-duration: 4s; }

@media (prefers-reduced-motion: reduce) {
  .cf-skin-mousse *,
  .cf-skin-lune *,
  .cf-skin-lanterne * { animation: none !important; }
}

/* ---------- Cadres eux-mêmes, appliqués à n'importe quel avatar circulaire
   OU aux portraits rectangulaires d'arène (box-shadow suit le border-radius
   de l'élément porteur, quel qu'il soit) — cosmétique pur, jamais de
   changement de taille qui perturberait une mise en page existante.

   Refonte cosmétique v2 : les 4 cadres historiques n'étaient que des anneaux
   box-shadow, invisibles en 1 seconde dans un classement à côté du Sakura.
   Chacun porte désormais une vraie FORME en SVG via ::before/::after, sur le
   mécanisme exact du .cadre-sakura plus bas : aucun des 7 points d'affichage
   d'avatar n'a besoin de changer, cadreClass() suffit toujours. Différence
   volontaire avec Sakura : inset en POURCENTAGE et non en px, pour que le
   débordement (linteau du torii, oreilles du yokai) suive la taille du
   porteur — 26 px dans le chat, 48 px en Arène — au lieu d'écraser les
   petits avatars. pointer-events:none partout : le décor ne doit jamais
   intercepter un clic destiné à l'élément qu'il habille. ---------- */

/* Torii : la silhouette complète (kasagi incurvé, shimaki, nuki, piliers
   inclinés vers l'intérieur comme un vrai myōjin-torii) encadre l'avatar
   comme un portail. Statique : c'est l'entrée de gamme, identifiable par sa
   forme seule. */
.cadre-torii{
  position:relative;
  box-shadow:0 0 0 1.5px rgba(181,75,58,.55);
}
.cadre-torii::after{
  content:'';
  position:absolute;
  /* Asymétrique : le linteau (kasagi) recouvrait le cercle en haut avec un
     inset uniforme à -24%. Plus négatif en haut pousse le portail au-dessus
     de l'avatar ; moins négatif en bas garde les piliers proches du cercle. */
  top:-32%;
  right:-22%;
  bottom:-16%;
  left:-22%;
  background-image:url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20100%20100'%3E%3Cpath%20d='M2%205%20Q50%2013%2098%205%20L98%2011%20Q50%2019%202%2011%20Z'%20fill='%238E3A2C'/%3E%3Crect%20x='9'%20y='13.5'%20width='82'%20height='5'%20rx='1'%20fill='%23B54B3A'/%3E%3Crect%20x='47.4'%20y='18.5'%20width='5.2'%20height='3.2'%20fill='%23B54B3A'/%3E%3Crect%20x='4'%20y='21.5'%20width='92'%20height='3.6'%20rx='1'%20fill='%23B54B3A'/%3E%3Crect%20x='11'%20y='16'%20width='6.2'%20height='75'%20rx='2'%20fill='%23B54B3A'%20transform='rotate%282.4%2014.1%2053.5%29'/%3E%3Crect%20x='82.8'%20y='16'%20width='6.2'%20height='75'%20rx='2'%20fill='%23B54B3A'%20transform='rotate%28-2.4%2085.9%2053.5%29'/%3E%3Crect%20x='8'%20y='89'%20width='11.5'%20height='5.5'%20rx='1.5'%20fill='%238E3A2C'/%3E%3Crect%20x='80.5'%20y='89'%20width='11.5'%20height='5.5'%20rx='1.5'%20fill='%238E3A2C'/%3E%3C/svg%3E");
  background-size:contain;
  background-repeat:no-repeat;
  pointer-events:none;
}

/* Or : anneau épais + 8 points lumineux (4 étincelles, 4 perles) en orbite,
   avec un scintillement d'opacité par-dessus la rotation. */
.cadre-or{
  position:relative;
  box-shadow:0 0 0 3px var(--gold), 0 0 0 4.5px rgba(201,162,39,.3), 0 0 12px rgba(201,162,39,.55);
}
.cadre-or::after{
  content:'';
  position:absolute;
  inset:-16%;
  background-image:url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20100%20100'%3E%3Cg%20fill='%23FFE9A8'%3E%3Cpath%20d='M50%201%20L53.4%207%20L50%2013%20L46.6%207%20Z'/%3E%3Cpath%20d='M50%201%20L53.4%207%20L50%2013%20L46.6%207%20Z'%20transform='rotate%2890%2050%2050%29'/%3E%3Cpath%20d='M50%201%20L53.4%207%20L50%2013%20L46.6%207%20Z'%20transform='rotate%28180%2050%2050%29'/%3E%3Cpath%20d='M50%201%20L53.4%207%20L50%2013%20L46.6%207%20Z'%20transform='rotate%28270%2050%2050%29'/%3E%3C/g%3E%3Cg%20fill='%23FFF8E1'%3E%3Ccircle%20cx='50'%20cy='7'%20r='1.7'/%3E%3Ccircle%20cx='50'%20cy='7'%20r='1.7'%20transform='rotate%2890%2050%2050%29'/%3E%3Ccircle%20cx='50'%20cy='7'%20r='1.7'%20transform='rotate%28180%2050%2050%29'/%3E%3Ccircle%20cx='50'%20cy='7'%20r='1.7'%20transform='rotate%28270%2050%2050%29'/%3E%3C/g%3E%3Cg%20fill='%23E2BE4E'%3E%3Ccircle%20cx='50'%20cy='4.5'%20r='2'%20transform='rotate%2845%2050%2050%29'/%3E%3Ccircle%20cx='50'%20cy='4.5'%20r='2'%20transform='rotate%28135%2050%2050%29'/%3E%3Ccircle%20cx='50'%20cy='4.5'%20r='2'%20transform='rotate%28225%2050%2050%29'/%3E%3Ccircle%20cx='50'%20cy='4.5'%20r='2'%20transform='rotate%28315%2050%2050%29'/%3E%3C/g%3E%3C/svg%3E");
  background-size:contain;
  background-repeat:no-repeat;
  pointer-events:none;
  animation:cadreOrSpin 7s linear infinite, cadreOrScintille 2.4s ease-in-out infinite;
}
@keyframes cadreOrSpin{ to{ transform:rotate(360deg); } }
@keyframes cadreOrScintille{ 0%, 100%{ opacity:.8; } 50%{ opacity:1; } }

/* Forêt : anneau mousse + 6 feuilles en orbite lente autour de l'avatar.
   Même mécanisme que .cadre-sakura (::after unique, background SVG,
   rotation continue), mais un tempo bien plus lent (20s contre 14s) pour
   une sensation posée, végétale — pas un scintillement de vitrine. */
.cadre-foret{
  position:relative;
  box-shadow:0 0 0 2px rgba(107,122,84,.6), 0 0 8px rgba(107,122,84,.4);
}
.cadre-foret::after{
  content:'';
  position:absolute;
  inset:-8px;
  background-image:url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20100%20100'%3E%3Cg%20fill='%236B7A54'%3E%3Cpath%20d='M50%202%20C55%207%2055%2013%2050%2018%20C45%2013%2045%207%2050%202%20Z'/%3E%3Cpath%20d='M50%202%20C55%207%2055%2013%2050%2018%20C45%2013%2045%207%2050%202%20Z'%20transform='rotate%2860%2050%2050%29'/%3E%3Cpath%20d='M50%202%20C55%207%2055%2013%2050%2018%20C45%2013%2045%207%2050%202%20Z'%20transform='rotate%28120%2050%2050%29'/%3E%3Cpath%20d='M50%202%20C55%207%2055%2013%2050%2018%20C45%2013%2045%207%2050%202%20Z'%20transform='rotate%28180%2050%2050%29'/%3E%3Cpath%20d='M50%202%20C55%207%2055%2013%2050%2018%20C45%2013%2045%207%2050%202%20Z'%20transform='rotate%28240%2050%2050%29'/%3E%3Cpath%20d='M50%202%20C55%207%2055%2013%2050%2018%20C45%2013%2045%207%2050%202%20Z'%20transform='rotate%28300%2050%2050%29'/%3E%3C/g%3E%3Cg%20fill='%238FA377'%3E%3Cellipse%20cx='50'%20cy='4'%20rx='1.6'%20ry='2.4'/%3E%3Cellipse%20cx='50'%20cy='4'%20rx='1.6'%20ry='2.4'%20transform='rotate%2860%2050%2050%29'/%3E%3Cellipse%20cx='50'%20cy='4'%20rx='1.6'%20ry='2.4'%20transform='rotate%28120%2050%2050%29'/%3E%3Cellipse%20cx='50'%20cy='4'%20rx='1.6'%20ry='2.4'%20transform='rotate%28180%2050%2050%29'/%3E%3Cellipse%20cx='50'%20cy='4'%20rx='1.6'%20ry='2.4'%20transform='rotate%28240%2050%2050%29'/%3E%3Cellipse%20cx='50'%20cy='4'%20rx='1.6'%20ry='2.4'%20transform='rotate%28300%2050%2050%29'/%3E%3C/g%3E%3C/svg%3E");
  background-size:contain;
  background-repeat:no-repeat;
  pointer-events:none;
  animation:cadreForetSpin 20s linear infinite;
}
@keyframes cadreForetSpin{ to{ transform:rotate(360deg); } }

/* Brume : deux voiles de volutes qui tournent en sens inverse à des vitesses
   différentes, avec une respiration d'échelle. Les trois étapes des
   keyframes gardent la rotation régulière (0/180/360) pendant que l'échelle
   oscille — un seul transform, pas de conflit d'animations. Le blur CSS
   adoucit les arcs SVG en vraies nappes de brume. */
.cadre-brume{
  position:relative;
  box-shadow:0 0 0 2px #8A9BB8, 0 0 10px rgba(138,155,184,.5);
  animation:cadreBrumePulse 3s ease-in-out infinite;
}
.cadre-brume::before{
  content:'';
  position:absolute;
  inset:-30%;
  background-image:url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20100%20100'%3E%3Cg%20fill='none'%20stroke-linecap='round'%3E%3Cpath%20d='M6%2050%20A44%2044%200%200%201%2050%206'%20stroke='%23A8B8D4'%20stroke-width='9'%20opacity='.3'/%3E%3Cpath%20d='M94%2050%20A44%2044%200%200%201%2062%2092.3'%20stroke='%238A9BB8'%20stroke-width='10'%20opacity='.26'/%3E%3C/g%3E%3C/svg%3E");
  background-size:contain;
  background-repeat:no-repeat;
  pointer-events:none;
  filter:blur(.6px);
  animation:cadreBrumeContre 26s linear infinite;
}
.cadre-brume::after{
  content:'';
  position:absolute;
  inset:-20%;
  background-image:url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20100%20100'%3E%3Cg%20fill='none'%20stroke-linecap='round'%3E%3Cpath%20d='M50%205%20A45%2045%200%200%201%2095%2050'%20stroke='%23A8B8D4'%20stroke-width='7'%20opacity='.55'/%3E%3Cpath%20d='M11%2072.5%20A45%2045%200%200%201%2015%2028'%20stroke='%238A9BB8'%20stroke-width='6'%20opacity='.5'/%3E%3Cpath%20d='M65%2092.4%20A45%2045%200%200%201%2030%2091'%20stroke='%23C3CFE4'%20stroke-width='5'%20opacity='.45'/%3E%3C/g%3E%3C/svg%3E");
  background-size:contain;
  background-repeat:no-repeat;
  pointer-events:none;
  filter:blur(.5px);
  animation:cadreBrumeTourne 16s linear infinite;
}
@keyframes cadreBrumePulse{
  0%, 100%{ box-shadow:0 0 0 2px #8A9BB8, 0 0 6px rgba(138,155,184,.4); }
  50%{ box-shadow:0 0 0 2px #A8B8D4, 0 0 14px rgba(138,155,184,.75); }
}
@keyframes cadreBrumeTourne{
  0%{ transform:rotate(0deg) scale(1); }
  50%{ transform:rotate(180deg) scale(1.05); }
  100%{ transform:rotate(360deg) scale(1); }
}
@keyframes cadreBrumeContre{
  0%{ transform:rotate(0deg) scale(1.04); }
  50%{ transform:rotate(-180deg) scale(1); }
  100%{ transform:rotate(-360deg) scale(1.04); }
}

/* Yokai : oreilles de kitsune qui dépassent au-dessus de l'avatar (extérieur
   encre, intérieur rouge torii) + aura rouge qui pulse. Le frémissement des
   oreilles ne dure qu'une fraction du cycle : c'est la longue pause immobile
   qui rend le tressaillement vivant, pas le mouvement lui-même. */
.cadre-yokai{
  position:relative;
  box-shadow:0 0 0 2px var(--torii-deep), 0 0 0 3.5px rgba(43,38,32,.3), 0 0 12px rgba(181,75,58,.5);
  animation:cadreYokaiAura 3.2s ease-in-out infinite;
}
.cadre-yokai::after{
  content:'';
  position:absolute;
  inset:-30%;
  background-image:url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20100%20100'%3E%3Cpath%20d='M24%2035%20Q14%2020%2017.5%202.5%20Q30%209%2042.5%2020.5%20Q33%2027%2024%2035%20Z'%20fill='%232B2620'/%3E%3Cpath%20d='M76%2035%20Q86%2020%2082.5%202.5%20Q70%209%2057.5%2020.5%20Q67%2027%2076%2035%20Z'%20fill='%232B2620'/%3E%3Cpath%20d='M25.5%2030%20Q19.5%2019%2021%208%20Q29%2013%2037%2020%20Q31%2025%2025.5%2030%20Z'%20fill='%23B54B3A'/%3E%3Cpath%20d='M74.5%2030%20Q80.5%2019%2079%208%20Q71%2013%2063%2020%20Q69%2025%2074.5%2030%20Z'%20fill='%23B54B3A'/%3E%3C/svg%3E");
  background-size:contain;
  background-repeat:no-repeat;
  pointer-events:none;
  animation:cadreYokaiOreilles 5.5s ease-in-out infinite;
}
@keyframes cadreYokaiAura{
  0%, 100%{ box-shadow:0 0 0 2px var(--torii-deep), 0 0 0 3.5px rgba(43,38,32,.3), 0 0 8px rgba(181,75,58,.45); }
  50%{ box-shadow:0 0 0 2px var(--torii-deep), 0 0 0 3.5px rgba(43,38,32,.3), 0 0 16px rgba(181,75,58,.7); }
}
@keyframes cadreYokaiOreilles{
  0%, 86%, 100%{ transform:rotate(0deg); }
  90%{ transform:rotate(2deg); }
  95%{ transform:rotate(-1.4deg); }
}
/* ---------- Cadre "vitrine" : pétales de sakura en SVG, en orbite lente
   autour de l'avatar. ::after plutôt qu'un enfant HTML : aucune modification
   des 6 points d'affichage d'avatar n'est nécessaire, cadreClass() suffit
   déjà (même mécanisme que les cadres CSS purs ci-dessus). position:relative
   ici est nécessaire pour que le ::after se positionne par rapport à
   l'avatar lui-même, pas un ancêtre plus lointain. ---------- */
.cadre-sakura{
  position:relative;
  box-shadow:0 0 0 2px rgba(243,198,211,.7), 0 0 10px rgba(243,198,211,.5);
}
.cadre-sakura::after{
  content:'';
  position:absolute;
  inset:-8px;
  background-image:url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20100%20100'%3E%3Cg%20fill='%23F3C6D3'%3E%3Cellipse%20cx='50'%20cy='6'%20rx='5'%20ry='9'%20transform='rotate%280%2050%2050%29'/%3E%3Cellipse%20cx='50'%20cy='6'%20rx='5'%20ry='9'%20transform='rotate%2860%2050%2050%29'/%3E%3Cellipse%20cx='50'%20cy='6'%20rx='5'%20ry='9'%20transform='rotate%28120%2050%2050%29'/%3E%3Cellipse%20cx='50'%20cy='6'%20rx='5'%20ry='9'%20transform='rotate%28180%2050%2050%29'/%3E%3Cellipse%20cx='50'%20cy='6'%20rx='5'%20ry='9'%20transform='rotate%28240%2050%2050%29'/%3E%3Cellipse%20cx='50'%20cy='6'%20rx='5'%20ry='9'%20transform='rotate%28300%2050%2050%29'/%3E%3C/g%3E%3Cg%20fill='%23FBE4EA'%3E%3Ccircle%20cx='50'%20cy='6'%20r='2.2'%20transform='rotate%280%2050%2050%29'/%3E%3Ccircle%20cx='50'%20cy='6'%20r='2.2'%20transform='rotate%2860%2050%2050%29'/%3E%3Ccircle%20cx='50'%20cy='6'%20r='2.2'%20transform='rotate%28120%2050%2050%29'/%3E%3Ccircle%20cx='50'%20cy='6'%20r='2.2'%20transform='rotate%28180%2050%2050%29'/%3E%3Ccircle%20cx='50'%20cy='6'%20r='2.2'%20transform='rotate%28240%2050%2050%29'/%3E%3Ccircle%20cx='50'%20cy='6'%20r='2.2'%20transform='rotate%28300%2050%2050%29'/%3E%3C/g%3E%3C/svg%3E");
  background-size:contain;
  background-repeat:no-repeat;
  pointer-events:none;
  animation:cadreSakuraSpin 14s linear infinite;
}
@keyframes cadreSakuraSpin{ to{ transform:rotate(360deg); } }
@media (prefers-reduced-motion:reduce){
  .cadre-sakura::after{ animation:none; }
}
@media (prefers-reduced-motion:reduce){
  .cadre-brume, .cadre-brume::before, .cadre-brume::after,
  .cadre-or::after,
  .cadre-foret::after,
  .cadre-yokai, .cadre-yokai::after,
  .cadre-racines::before{ animation:none; }
}

/* Racines Entrelacées — v4 shape-agnostic : les deux grands tracés de
   "Racines" formaient un cercle quasi parfait dans le SVG (::after),
   inévitablement mal raccordé sur un porteur carré (.ladder-portrait,
   border-radius:9px) — visible en écart/gap dans les coins. Même principe
   que .cadre-aube v5 : l'anneau passe en box-shadow (suit nativement le
   border-radius du porteur, cercle ou carré), et seuls les éléments qui ne
   dépendent pas d'une géométrie circulaire restent en SVG — petites
   brindilles aux coins + amas de mousse, qui fonctionnaient déjà sans
   problème car ce sont de simples accents localisés, pas un anneau. */
.cadre-racines{
  position:relative;
  box-shadow:
    0 0 0 2px #5C4033,
    0 0 0 3.5px rgba(107,122,84,.35),
    0 0 8px rgba(107,122,84,.3);
}
.cadre-racines::after{
  content:'';
  position:absolute;
  top:-16%;
  right:-16%;
  bottom:-16%;
  left:-16%;
  background-image:url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20100%20100'%3E%3Cdefs%3E%3CradialGradient%20id='m1'%20cx='50%25'%20cy='50%25'%20r='50%25'%3E%3Cstop%20offset='0%25'%20stop-color='%23A8C07A'%20stop-opacity='.95'/%3E%3Cstop%20offset='55%25'%20stop-color='%236B7A54'%20stop-opacity='.85'/%3E%3Cstop%20offset='100%25'%20stop-color='%234E5A3E'%20stop-opacity='.3'/%3E%3C/radialGradient%3E%3CradialGradient%20id='m2'%20cx='50%25'%20cy='50%25'%20r='50%25'%3E%3Cstop%20offset='0%25'%20stop-color='%23B5D08A'%20stop-opacity='.9'/%3E%3Cstop%20offset='60%25'%20stop-color='%237A8F5C'%20stop-opacity='.75'/%3E%3Cstop%20offset='100%25'%20stop-color='%235A6B42'%20stop-opacity='.25'/%3E%3C/radialGradient%3E%3C/defs%3E%3C!-- Brindilles aux coins (accents localisés, pas un anneau) --%3E%3Cpath%20d='M18%2032%20C28%2026%2036%2034%2032%2042'%20fill='none'%20stroke='%233E2A1F'%20stroke-width='1.8'%20stroke-linecap='round'/%3E%3Cpath%20d='M82%2030%20C72%2024%2064%2032%2068%2040'%20fill='none'%20stroke='%234A3326'%20stroke-width='1.8'%20stroke-linecap='round'/%3E%3Cpath%20d='M22%2070%20C30%2078%2040%2074%2042%2066'%20fill='none'%20stroke='%233E2A1F'%20stroke-width='1.8'%20stroke-linecap='round'/%3E%3Cpath%20d='M78%2068%20C70%2076%2060%2072%2058%2064'%20fill='none'%20stroke='%234A3326'%20stroke-width='1.8'%20stroke-linecap='round'/%3E%3C!-- Amas de mousse (formes irrégulières) --%3E%3Cellipse%20cx='16'%20cy='40'%20rx='5.5'%20ry='4.2'%20fill='url(%23m1)'%20transform='rotate(-25%2016%2040)'%20opacity='.9'%3E%3Canimate%20attributeName='opacity'%20values='.65;.95;.65'%20dur='5s'%20repeatCount='indefinite'/%3E%3C/ellipse%3E%3Cellipse%20cx='19'%20cy='37'%20rx='3'%20ry='2.4'%20fill='url(%23m2)'%20transform='rotate(15%2019%2037)'%20opacity='.85'/%3E%3Ccircle%20cx='13'%20cy='42'%20r='1.6'%20fill='%238FA86A'%20opacity='.7'/%3E%3Ccircle%20cx='20'%20cy='43'%20r='1.2'%20fill='%23A8C07A'%20opacity='.65'/%3E%3Cellipse%20cx='84'%20cy='38'%20rx='5'%20ry='3.8'%20fill='url(%23m1)'%20transform='rotate(30%2084%2038)'%20opacity='.88'%3E%3Canimate%20attributeName='opacity'%20values='.6;.92;.6'%20dur='5.5s'%20repeatCount='indefinite'/%3E%3C/ellipse%3E%3Cellipse%20cx='81'%20cy='35'%20rx='2.8'%20ry='2.2'%20fill='url(%23m2)'%20transform='rotate(-10%2081%2035)'%20opacity='.8'/%3E%3Ccircle%20cx='87'%20cy='41'%20r='1.4'%20fill='%237A8F5C'%20opacity='.7'/%3E%3Cellipse%20cx='24'%20cy='74'%20rx='5.2'%20ry='4'%20fill='url(%23m1)'%20transform='rotate(20%2024%2074)'%20opacity='.9'%3E%3Canimate%20attributeName='opacity'%20values='.62;.95;.62'%20dur='4.8s'%20repeatCount='indefinite'/%3E%3C/ellipse%3E%3Cellipse%20cx='28'%20cy='71'%20rx='2.6'%20ry='2'%20fill='url(%23m2)'%20opacity='.8'/%3E%3Ccircle%20cx='21'%20cy='77'%20r='1.5'%20fill='%23A8C07A'%20opacity='.7'/%3E%3Ccircle%20cx='27'%20cy='78'%20r='1.1'%20fill='%236B7A54'%20opacity='.65'/%3E%3Cellipse%20cx='76'%20cy='72'%20rx='4.8'%20ry='3.6'%20fill='url(%23m1)'%20transform='rotate(-18%2076%2072)'%20opacity='.87'%3E%3Canimate%20attributeName='opacity'%20values='.58;.9;.58'%20dur='5.2s'%20repeatCount='indefinite'/%3E%3C/ellipse%3E%3Cellipse%20cx='73'%20cy='69'%20rx='2.5'%20ry='1.9'%20fill='url(%23m2)'%20opacity='.78'/%3E%3Ccircle%20cx='79'%20cy='75'%20r='1.3'%20fill='%238FA86A'%20opacity='.68'/%3E%3C!-- Petits amas haut / bas --%3E%3Cellipse%20cx='50'%20cy='8'%20rx='4'%20ry='2.8'%20fill='url(%23m2)'%20opacity='.75'%3E%3Canimate%20attributeName='opacity'%20values='.5;.8;.5'%20dur='6s'%20repeatCount='indefinite'/%3E%3C/ellipse%3E%3Ccircle%20cx='47'%20cy='10'%20r='1.2'%20fill='%236B7A54'%20opacity='.6'/%3E%3Ccircle%20cx='53'%20cy='9'%20r='1'%20fill='%23A8C07A'%20opacity='.55'/%3E%3Cellipse%20cx='50'%20cy='93'%20rx='4.5'%20ry='3'%20fill='url(%23m1)'%20opacity='.8'%3E%3Canimate%20attributeName='opacity'%20values='.55;.88;.55'%20dur='5.8s'%20repeatCount='indefinite'/%3E%3C/ellipse%3E%3Ccircle%20cx='46'%20cy='91'%20r='1.3'%20fill='%237A8F5C'%20opacity='.65'/%3E%3Ccircle%20cx='54'%20cy='92'%20r='1.1'%20fill='%23A8C07A'%20opacity='.6'/%3E%3C!-- Speckles de texture --%3E%3Ccircle%20cx='17'%20cy='44'%20r='.7'%20fill='%23C5D89A'%20opacity='.5'/%3E%3Ccircle%20cx='83'%20cy='42'%20r='.6'%20fill='%23C5D89A'%20opacity='.45'/%3E%3Ccircle%20cx='26'%20cy='76'%20r='.65'%20fill='%23B5D08A'%20opacity='.5'/%3E%3Ccircle%20cx='75'%20cy='74'%20r='.6'%20fill='%23C5D89A'%20opacity='.45'/%3E%3C/svg%3E");
  background-size:contain;
  background-repeat:no-repeat;
  pointer-events:none;
}
.cadre-racines::before{
  content:'';
  position:absolute;
  inset:-5%;
  border-radius:inherit; /* même correctif que .cadre-aube v5 : suit le carré du ladder ou le cercle de l'avatar, au lieu d'un cercle figé */
  box-shadow:0 0 9px 2px rgba(107,122,84,.25);
  animation:cadreRacinesLueur 5.5s ease-in-out infinite;
  pointer-events:none;
}
@keyframes cadreRacinesLueur{
  0%,100%{ opacity:.45; box-shadow:0 0 6px 1px rgba(107,122,84,.18); }
  50%    { opacity:1;   box-shadow:0 0 12px 3px rgba(143,168,106,.35); }
}
@media (prefers-reduced-motion:reduce){
  .cadre-racines::before{ animation:none; opacity:.7; }
}

/* Anneau de l'Aube — exclusif bêta-testeurs. v5 shape-agnostic : les v2-v4
   utilisaient un ::after avec un anneau SVG circulaire dessiné en dur, qui
   se déformait ou tranchait dès qu'il était posé sur un porteur non-rond —
   .ladder-portrait est un carré arrondi (border-radius:9px), pas un cercle
   comme .player-avatar/.fiche-avatar. Ici les anneaux passent en box-shadow
   (suivent nativement le border-radius du porteur, cercle ou carré), et la
   lueur (::before) utilise border-radius:inherit pour la même raison. Seuls
   les rayons restent un petit SVG, calés en haut en bandeau indépendant de
   la forme plutôt que centrés dans un cercle imaginaire. */
.cadre-aube{
  position:relative;
  box-shadow:
    0 0 0 2px #F07850,
    0 0 0 3.5px rgba(255,176,122,.55),
    0 0 0 5px rgba(212,160,64,.25);
}
/* Rayons d'aube — bandeau en haut, indépendant de la forme */
.cadre-aube::after{
  content:'';
  position:absolute;
  left:50%;
  top:-7px;
  width:28px;
  height:10px;
  transform:translateX(-50%);
  background-image:url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2028%2010'%3E%3Cg%20stroke='%23FFB07A'%20stroke-linecap='round'%3E%3Cline%20x1='14'%20y1='0'%20x2='14'%20y2='7'%20stroke-width='1.8'/%3E%3Cline%20x1='8'%20y1='1.5'%20x2='10'%20y2='7'%20stroke-width='1.4'/%3E%3Cline%20x1='20'%20y1='1.5'%20x2='18'%20y2='7'%20stroke-width='1.4'/%3E%3Cline%20x1='3'%20y1='3.5'%20x2='6'%20y2='8'%20stroke-width='1.2'/%3E%3Cline%20x1='25'%20y1='3.5'%20x2='22'%20y2='8'%20stroke-width='1.2'/%3E%3C/g%3E%3C/svg%3E");
  background-size:contain;
  background-repeat:no-repeat;
  background-position:center;
  pointer-events:none;
  opacity:.9;
}
/* Lueur chaude douce — suit aussi la forme via inset + parent radius */
.cadre-aube::before{
  content:'';
  position:absolute;
  inset:-2px;
  border-radius:inherit; /* clé : hérite cercle (avatar/fiche) ou carré (ladder) */
  box-shadow:0 0 8px 2px rgba(255,140,80,.35);
  pointer-events:none;
  animation:cadreAubeLueur 6s ease-in-out infinite;
}
@keyframes cadreAubeLueur{
  0%,100%{ opacity:.45; box-shadow:0 0 5px 1px rgba(255,140,80,.25); }
  50%    { opacity:1;   box-shadow:0 0 10px 2px rgba(255,140,80,.4); }
}
@media (prefers-reduced-motion:reduce){
  .cadre-aube::before{ animation:none; opacity:.7; }
}

/* ---------- Fiche d'édition du profil ---------- */
.profile-card{
  max-width:320px;text-align:left;
  /* La fiche s'est allongée (bannière de fiche en plus des réglages
     existants) au point de dépasser la hauteur d'un écran mobile en PWA :
     sans ce plafond + défilement, "Enregistrer" devenait inatteignable.
     Même traitement que .titre-panel / .equip-card : scrollbar masquée,
     l'habillage washi ne doit pas être coupé par la barre grise native. */
  max-height:84vh;overflow-y:auto;
  scrollbar-width:none;
  -ms-overflow-style:none;
  overscroll-behavior:contain;
}
.profile-card::-webkit-scrollbar{display:none;}
.profile-label{
  display:block;
  font-size:10.5px;font-weight:700;
  color:var(--ink-soft);
  margin-bottom:6px;
}
.avatar-grid{
  display:grid;
  grid-template-columns:repeat(4,1fr);
  gap:8px;
}
.avatar-pick{
  aspect-ratio:1;
  border-radius:11px;
  background-size:cover;
  background-position:center 22%;
  background-color:var(--washi-deep);
  border:2px solid rgba(43,38,32,.12);
  cursor:pointer;
  position:relative;
  display:flex;align-items:center;justify-content:center;
}
.avatar-pick.selected{border-color:var(--gold);}
.avatar-pick-check{
  width:20px;height:20px;
  border-radius:50%;
  background:var(--gold);
  color:#fff;
  font-size:11px;font-weight:900;
  display:flex;align-items:center;justify-content:center;
  box-shadow:0 2px 6px rgba(21,25,37,.3);
}

/* ---------- Avatars dans la liste des membres du Hayashi ---------- */
.member-avatar{
  width:36px;height:36px;flex-shrink:0;
  border-radius:50%;
  background-size:cover;
  background-position:center 22%;
  background-color:rgba(43,38,32,.08);
  display:flex;align-items:center;justify-content:center;
  font-size:14px;
}

/* ---------- Classement des Hayashi : détails par ligne ---------- */
/* Modificateur, pas une redéfinition de .lb-row-name : le classement joueur
   utilise déjà cette classe pour un nom sur une seule ligne (flex:1,
   ellipsis) et ne doit pas en hériter la disposition en colonne. */
.lb-row-name.has-sub{display:flex;flex-direction:column;gap:2px;white-space:normal;align-self:center;}
.lb-row-sub{font-size:9px;color:var(--ink-soft);font-weight:400;}

/* ===================================================================
   Gouvernance du Hayashi : coffre, rangs, demandes, réglages
   =================================================================== */

.hayashi-dir-name{display:flex;align-items:center;gap:6px;flex-wrap:wrap;}
.dir-approval-tag{
  font-size:8px;font-weight:700;
  color:var(--ink-soft);
  background:rgba(43,38,32,.08);
  border-radius:6px;padding:1px 6px;
}

.treasury-note{font-size:9.5px;color:var(--ink-soft);margin-top:7px;line-height:1.4;}

/* ---------- Coffre de l'alliance ---------- */
.hayashi-chest{
  background:linear-gradient(135deg, rgba(201,162,39,.14), rgba(255,255,255,.5));
  border:1px solid rgba(201,162,39,.35);
  border-radius:12px;
  padding:13px;
}
.chest-row{
  display:grid;
  grid-template-columns:70px 1fr auto;
  align-items:center;gap:8px;
  margin-bottom:8px;
  font-size:11px;font-weight:700;
}
.chest-row:last-of-type{margin-bottom:0;}
.chest-row-label{display:flex;align-items:center;gap:4px;color:var(--ink-soft);}
.chest-row-track{
  height:6px;background:rgba(43,38,32,.1);
  border-radius:4px;overflow:hidden;
}
.chest-row-fill{
  height:100%;border-radius:4px;
  background:linear-gradient(90deg,#C9A227,#E8C97A);
  transition:width .5s cubic-bezier(.22,1,.36,1);
}
.chest-row-fill.essence{background:linear-gradient(90deg,#2E3548,#4A5A7A);}
.chest-row-value{font-size:9.5px;color:var(--ink-soft);white-space:nowrap;font-weight:600;}
.chest-note{font-size:10px;color:var(--ink-soft);margin-top:6px;line-height:1.4;}

/* ---------- Demandes d'adhésion ---------- */
.hayashi-requests{display:flex;flex-direction:column;gap:7px;}
.hayashi-request-row{
  display:flex;align-items:center;gap:9px;
  background:rgba(255,255,255,.55);
  border:1px solid rgba(43,38,32,.12);
  border-radius:10px;
  padding:8px 10px;
}
.request-actions{display:flex;gap:6px;flex-shrink:0;}
.request-actions .btn{padding:6px 10px;}

/* ---------- Membres : rôle, menu contextuel ---------- */
.member-main{flex:1;min-width:0;}
.member-role-tag{
  font-size:8px;font-weight:800;
  color:#9A7A1E;
  background:rgba(201,162,39,.18);
  border-radius:6px;padding:1px 6px;
  margin-left:5px;
  vertical-align:middle;
}
/* Refonte sociale : le chef et les officiers ne se distinguaient que par le
   texte du tag ("Chef"/"Officier"), noyé dans les listes denses. La couleur
   or reste réservée au chef ; l'indigo — déjà la teinte "rôle" du jeu (voir
   .nom-indigo) — marque les officiers, y compris dans le chat (voir
   renderHayashiChat). */
.member-role-tag.role-officer{
  color:var(--indigo);
  background:rgba(46,53,72,.15);
}
.member-menu-wrap{position:relative;flex-shrink:0;}
.member-menu-btn{
  background:none;border:none;cursor:pointer;
  font-size:15px;color:var(--ink-soft);
  padding:2px 6px;
  letter-spacing:-1px;
}
.member-menu{
  position:absolute;right:0;top:100%;
  z-index:20;
  background:var(--washi);
  border:1px solid rgba(43,38,32,.15);
  border-radius:10px;
  box-shadow:0 6px 18px rgba(21,25,37,.18);
  overflow:hidden;
  min-width:180px;
}
.member-menu-item{
  display:block;width:100%;
  text-align:left;
  background:none;border:none;cursor:pointer;
  font-family:inherit;font-size:11.5px;
  padding:9px 12px;
  color:var(--ink);
  border-bottom:1px solid rgba(43,38,32,.08);
}
.member-menu-item:last-child{border-bottom:none;}
.member-menu-item:hover{background:rgba(43,38,32,.05);}
.member-menu-item.kick-btn{color:var(--torii-deep);}

/* ---------- Réglages (chef uniquement) ---------- */
.hayashi-settings{
  background:rgba(255,255,255,.5);
  border:1px solid rgba(43,38,32,.12);
  border-radius:12px;
  padding:12px;
}
.settings-row{display:flex;align-items:center;justify-content:space-between;gap:10px;}
.settings-row span{font-size:11.5px;font-weight:700;}
.settings-toggle{display:flex;gap:4px;}
.toggle-opt{
  font-family:inherit;font-size:10px;font-weight:700;
  padding:6px 10px;border-radius:8px;
  border:1px solid rgba(43,38,32,.15);
  background:transparent;color:var(--ink-soft);
  cursor:pointer;
}
.toggle-opt.on{background:var(--torii);border-color:var(--torii);color:#fff;}

/* ===================================================================
   Arène (PvP asynchrone)
   =================================================================== */

.arena-header{
  --league-color:#A8763E;
  display:flex;flex-wrap:wrap;align-items:center;gap:8px 10px;
  /* Teinte unie plutôt qu'un dégradé à 135° : celui-ci virait au blanc vers
     la droite, exactement là où se trouve le décompte de saison, qui semblait
     donc posé sur un autre fond que le badge de division à gauche.
     Mélange avec --washi et non avec du transparent : la couleur est ainsi
     réellement plate, sans dépendre de ce qu'il y a derrière. */
  background:color-mix(in srgb, var(--league-color) 13%, var(--washi));
  border:1px solid color-mix(in srgb, var(--league-color) 40%, transparent);
  border-radius:13px;
  padding:13px 14px;
  margin-bottom:16px;
}
.arena-league-badge{
  font-family:'Shippori Mincho',serif;
  font-size:13px;font-weight:800;
  color:var(--league-color);
  background:color-mix(in srgb, var(--league-color) 16%, transparent);
  border-radius:9px;
  padding:5px 11px;
}
.arena-trophies{font-size:14px;font-weight:800;flex:1;}
.arena-next-league{font-size:9.5px;color:var(--ink-soft);text-align:right;}

/* ---------- Ma défense ---------- */
.arena-defense-card{
  background:rgba(255,255,255,.5);
  border:1px solid rgba(43,38,32,.12);
  border-radius:12px;
  padding:12px;
  margin-bottom:18px;
}

/* Assauts restants (fenêtre glissante de 24 h) + recharge en Essence */
.arena-attacks-card{
  display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  background:rgba(255,255,255,.5);
  border:1px solid rgba(43,38,32,.12);
  border-radius:12px;
  padding:10px 12px;
  margin-bottom:12px;
}
.arena-attacks-count{font-size:13px;font-weight:800;color:var(--ink);}
.arena-attacks-count.empty{color:var(--torii-deep);}
.arena-attacks-timer{font-size:10px;color:var(--ink-soft);}
.arena-attacks-card .btn{margin-left:auto;}
.arena-defense-squad{display:flex;gap:7px;flex-wrap:wrap;}
.arena-defense-portrait{
  width:42px;height:42px;
  border-radius:9px;
  background-size:cover;background-position:center 22%;
  background-color:var(--washi-deep);
  border:1px solid rgba(43,38,32,.15);
}
.arena-shield-tag{
  font-size:10px;font-weight:700;
  color:#4A7BA7;
  background:rgba(74,123,167,.12);
  border-radius:8px;
  padding:5px 9px;
  margin-top:9px;
  display:inline-block;
}

/* ---------- Recherche d'adversaire ---------- */
.arena-search-card{
  background:rgba(255,255,255,.5);
  border:1px dashed rgba(43,38,32,.2);
  border-radius:12px;
  padding:16px;
  text-align:center;
  margin-bottom:18px;
}
.arena-search-hint{font-size:11px;color:var(--ink-soft);margin-bottom:10px;}

.arena-opponent-card{
  display:flex;align-items:center;gap:11px;
  background:rgba(255,255,255,.5);
  border:1px solid rgba(43,38,32,.12);
  border-radius:12px;
  padding:12px;
}
.arena-opponent-portrait{
  width:48px;height:48px;flex-shrink:0;
  border-radius:10px;
  background-size:cover;background-position:center 22%;
  background-color:var(--washi-deep);
}
/* Effet d'entrée : l'adversaire trouvé claque à l'écran plutôt que
   d'apparaître platement — glissade + flash de contour rouge torii qui
   s'efface, pour donner un vrai sentiment de confrontation qui démarre. */
.arena-opponent-enter{
  animation:areneAdversaireEntree .5s cubic-bezier(.2,1.4,.4,1) both;
}
@keyframes areneAdversaireEntree{
  0%{ transform:translateX(18px) scale(.85); opacity:0; box-shadow:0 0 0 3px rgba(181,75,58,.7); }
  60%{ box-shadow:0 0 0 3px rgba(181,75,58,.35); }
  100%{ transform:translateX(0) scale(1); opacity:1; box-shadow:0 0 0 0 rgba(181,75,58,0); }
}
@media (prefers-reduced-motion:reduce){ .arena-opponent-enter{ animation:none; } }

.arena-opponent-info{flex:1;min-width:0;}
.arena-opponent-name{font-family:'Shippori Mincho',serif;font-size:13px;font-weight:700;}
.arena-opponent-meta{font-size:10px;color:var(--ink-soft);margin-top:2px;}

/* ---------- Résultat d'un combat d'arène : impact commun + éclat de victoire ---------- */
/* Impact d'entrée sur la scène de révélation, commun aux deux issues — un
   anneau qui claque puis s'efface, pour marquer que le coup vient d'être
   porté avant même de lire "Victoire"/"Défaite". */
.arena-reveal-stage::before{
  content:'';
  position:absolute;inset:-6px;
  border-radius:50%;
  border:3px solid var(--rarity, var(--torii));
  opacity:0;
  animation:areneImpactAnneau .5s ease-out both;
}
.arena-reveal-stage.arena-victory::before{ border-color:#7FA45C; }
.arena-reveal-stage.arena-defeat::before{ border-color:var(--torii-deep); }
@keyframes areneImpactAnneau{
  0%{ transform:scale(.6); opacity:.9; }
  100%{ transform:scale(1.6); opacity:0; }
}
/* Victoire : quatre éclats dorés qui giclent en croix depuis le trophée —
   la même logique que .cadre-or (formes en losange), mais en éclatement
   ponctuel au lieu d'une orbite continue. */
.arena-reveal-stage.arena-victory .reveal-icon::after{
  content:'';
  position:absolute;inset:-40%;
  background-image:url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20100%20100'%3E%3Cg%20fill='%23FFE9A8'%3E%3Cpath%20d='M50%200%20L54%208%20L50%2016%20L46%208%20Z'/%3E%3Cpath%20d='M50%200%20L54%208%20L50%2016%20L46%208%20Z'%20transform='rotate%2890%2050%2050%29'/%3E%3Cpath%20d='M50%200%20L54%208%20L50%2016%20L46%208%20Z'%20transform='rotate%28180%2050%2050%29'/%3E%3Cpath%20d='M50%200%20L54%208%20L50%2016%20L46%208%20Z'%20transform='rotate%28270%2050%2050%29'/%3E%3C/g%3E%3C/svg%3E");
  background-size:contain;background-repeat:no-repeat;
  pointer-events:none;
  animation:areneEclatVictoire .7s ease-out .15s both;
}
@keyframes areneEclatVictoire{
  0%{ transform:scale(.3) rotate(0deg); opacity:0; }
  40%{ opacity:1; }
  100%{ transform:scale(1.5) rotate(35deg); opacity:0; }
}
/* Défaite : léger tremblement du blason, comme un coup encaissé — bref et
   discret, ça ne doit pas prolonger la déception. */
.arena-reveal-stage.arena-defeat .reveal-icon{
  animation:revealPop var(--reveal-duree,.42s) cubic-bezier(.2,1.5,.4,1) both,
            areneTremblementDefaite .35s ease-in-out .42s both;
}
@keyframes areneTremblementDefaite{
  0%,100%{ transform:translateX(0); }
  25%{ transform:translateX(-4px); }
  75%{ transform:translateX(4px); }
}
@media (prefers-reduced-motion:reduce){
  .arena-reveal-stage::before,
  .arena-reveal-stage.arena-victory .reveal-icon::after,
  .arena-reveal-stage.arena-defeat .reveal-icon{ animation:none; }
}

/* ---------- Historique ---------- */
.arena-log{display:flex;flex-direction:column;gap:4px;}
.arena-log-row{
  display:flex;justify-content:space-between;align-items:center;
  background:rgba(255,255,255,.4);
  border-radius:8px;
  padding:7px 10px;
  font-size:10.5px;
}
.arena-log-verb{color:var(--ink-soft);}
.arena-log-change{font-weight:800;}
.arena-log-row.win .arena-log-change{color:#4B6B3A;}
.arena-log-row.loss .arena-log-change{color:var(--torii-deep);}

/* ===================================================================
   Notifications
   =================================================================== */

.notif-bell{
  position:relative;
  background:rgba(255,255,255,.55);
  border:1px solid rgba(43,38,32,.15);
  border-radius:50%;
  width:36px;height:36px;
  padding:0;
  font-size:16px;
  line-height:1;
  cursor:pointer;
  display:flex;align-items:center;justify-content:center;
  flex-shrink:0;
  /* transform-origin en haut : une cloche pivote depuis son attache, pas
     depuis son centre — sinon elle glisse au lieu de sonner. */
  transform-origin:top center;
}
/* .icon-svg remplit tout son parent par défaut (width/height:100%) — bien
   trop grand pour ce bouton de 36px. Contraint à une taille comparable à
   l'emoji 🔔 voisin (font-size:16px).
   Petit ajustement vertical en plus : un SVG dessiné dans un viewBox et un
   émoji rendu par la police n'ont pas le même "centre optique" une fois
   tous deux centrés en flex dans une boîte identique — l'émoji cloche
   déborde légèrement vers le haut (le battant pend en dessous de son
   propre cadre), la goutte SVG se retrouvait visuellement plus basse.
   padding:0 et line-height:1 sur .notif-bell ci-dessus éliminent déjà une
   bonne partie de l'écart (le padding par défaut d'un <button> et un
   line-height hérité pouvaient légèrement décaler l'un par rapport à
   l'autre) ; ce -2px couvre le reste, propre au rendu SVG vs émoji. Réglage
   à l'œil, à raffiner si besoin (rendu emoji variable selon OS/police). */
#essenceTopbarBtn .icon-svg{ width:19px; height:19px; margin-top:-2px; }

/* Icônes Essence + Notifications. Sur mobile/PWA elles montent au niveau
   du nom (même rangée que .player-tag, via display:contents sur
   .topbar-right) ; sur desktop elles s'empilent au-dessus des pastilles
   de ressources (voir @media min-width:900px). */
.topbar-icons{
  display:flex;
  flex-direction:row;
  align-items:center;
  gap:6px;
  flex-shrink:0;
}

/* Mobile/PWA : display:contents fait remonter .topbar-icons et .resources
   comme enfants directs de .topbar. Ainsi les icônes se placent sur la
   première ligne (à droite du nom, là où le carré rouge indiquait la
   place voulue) et les pastilles de ressources passent en dessous
   (flex-basis:100% ci-dessous). Sur desktop, la media query rétablit un
   vrai flex column pour empiler icônes AU-DESSUS des ressources. */
.topbar-right{
  display:contents;
}
/* Force les pastilles sur leur propre ligne quand .topbar-right est en
   display:contents (mobile). Réinitialisé en desktop. */
.topbar > .resources,
.topbar-right > .resources{
  flex-basis:100%;
}

/* ---------- Retour tactile ----------
   .btn a déjà le sien ; ces deux-là n'étaient couverts par aucune règle
   alors que la navigation est l'élément le plus sollicité du jeu. */
.nav-item:active{transform:scale(.93);}
.notif-bell:active{transform:scale(.92);}

/* ---------- La cloche sonne ----------
   Rien n'attirait l'œil vers elle : le badge apparaissait en silence, dans un
   coin. Déclenchée depuis updateNotifBadge() uniquement quand le nombre de
   non-lues augmente — pas à la lecture, pas au premier chargement. */
@keyframes clocheSonne{
  0%,100%{transform:rotate(0);}
  12%{transform:rotate(14deg);}
  26%{transform:rotate(-12deg);}
  40%{transform:rotate(9deg);}
  54%{transform:rotate(-7deg);}
  68%{transform:rotate(4deg);}
  84%{transform:rotate(-2deg);}
}
.notif-bell.sonne{animation:clocheSonne .75s ease;}
@media (prefers-reduced-motion: reduce){
  .notif-bell.sonne{animation:none;}
}
.notif-badge{
  position:absolute;top:-3px;right:-3px;
  min-width:16px;height:16px;
  padding:0 4px;
  border-radius:8px;
  background:var(--torii);
  color:#fff;
  font-size:9px;font-weight:800;
  line-height:16px;text-align:center;
  box-shadow:0 0 0 2px var(--washi);
}

.notif-row{
  display:flex;align-items:flex-start;gap:10px;
  padding:10px 4px;
  border-bottom:1px solid rgba(43,38,32,.08);
  text-align:left;
}
.notif-row:last-child{border-bottom:none;}
.notif-row.unread{background:rgba(201,162,39,.08);border-radius:9px;}
.notif-icon{font-size:17px;flex-shrink:0;margin-top:1px;}
.notif-body{flex:1;min-width:0;}
.notif-title{font-family:'Shippori Mincho',serif;font-size:12px;font-weight:700;}
.notif-message{font-size:10.5px;color:var(--ink-soft);margin-top:2px;line-height:1.4;}
.notif-time{font-size:9px;color:var(--ink-soft);opacity:.7;margin-top:3px;}
.notif-dot{
  width:7px;height:7px;border-radius:50%;
  background:var(--torii);flex-shrink:0;margin-top:4px;
}

/* ===================================================================
   Connexion par email (inscription / connexion / mot de passe oublié)
   =================================================================== */

.login-divider{
  display:flex;align-items:center;gap:10px;
  width:100%;max-width:280px;
  margin:18px 0 14px;
  color:var(--ink-soft);
  font-size:10.5px;
}
.login-divider::before,.login-divider::after{
  content:'';flex:1;height:1px;
  background:rgba(43,38,32,.15);
}

.login-email-form{
  display:flex;flex-direction:column;gap:9px;
  width:100%;max-width:280px;
}
.login-email-form .hayashi-input{width:100%;}

.login-switch{
  margin-top:14px;
  font-size:11px;color:var(--ink-soft);
  display:flex;align-items:center;gap:6px;
}
.login-link-btn{
  background:none;border:none;
  color:var(--torii-deep);
  font-family:inherit;font-size:11px;font-weight:700;
  cursor:pointer;
  padding:2px 0;
  text-decoration:underline;
}
.login-forgot{margin-top:9px;color:var(--ink-soft);}
/* ===== Sélecteur de langue (fiche profil) ===== */
.lang-grid{display:flex;gap:8px;flex-wrap:wrap;}
.lang-pick{
  display:flex;align-items:center;gap:7px;
  font-family:inherit;font-size:12.5px;font-weight:700;
  color:var(--ink-soft);
  background:rgba(255,255,255,.5);
  border:1px solid rgba(43,38,32,.18);
  border-radius:10px;padding:8px 13px;cursor:pointer;
}
.lang-pick:hover{background:rgba(255,255,255,.75);}
.lang-pick.selected{
  color:var(--torii-deep);
  border-color:var(--torii);
  background:rgba(181,75,58,.1);
}
.lang-flag{font-size:15px;line-height:1;}
.login-legal{
  margin-top:22px;
  font-size:10.5px;line-height:1.6;
  color:var(--ink-soft);
  max-width:300px;
}
.login-legal a{color:var(--torii-deep);}

/* Lien "Informations légales" dans le sélecteur de profil (une fois
   connecté) — même sobriété que .login-legal, mais centré et sans le
   paragraphe explicatif (le contexte est différent : un joueur déjà inscrit
   qui cherche l'info, pas une obligation RGPD affichée avant collecte). */
.profile-legal-link{
  margin-top:14px;
  text-align:center;
  font-size:11px;
}
.profile-legal-link a{color:var(--ink-soft);text-decoration:underline;text-underline-offset:2px;}
.profile-legal-link a:hover{color:var(--torii-deep);}

/* Renoncement au droit de rétractation avant achat d'Essence — case NON
   pré-cochée par défaut (voir index.html), condition du renoncement exprès
   exigé par l'art. L221-28, 13° du code de la consommation. */
.essence-consent{
  display:flex;align-items:flex-start;gap:9px;
  margin:10px 0 14px;
  padding:10px 12px;
  background:rgba(255,255,255,.5);
  border:1px solid rgba(43,38,32,.14);
  border-radius:10px;
  font-size:12px;line-height:1.45;
  color:var(--ink-soft);
  cursor:pointer;
}
.essence-consent input[type="checkbox"]{
  margin:2px 0 0;flex-shrink:0;
  width:16px;height:16px;accent-color:var(--torii);
  cursor:pointer;
}
.essence-consent a{color:var(--torii-deep);font-weight:700;}

/* ===================================================================
   Bandeau de vérification d'email
   =================================================================== */

.verify-banner{
  display:flex;align-items:center;flex-wrap:wrap;gap:9px;
  background:rgba(201,162,39,.16);
  border-bottom:1px solid rgba(201,162,39,.4);
  padding:9px 14px;
  font-size:11px;font-weight:600;
  color:#8A6A12;
}
.verify-banner span{flex:1;min-width:180px;}
.verify-banner-btn{
  font-family:inherit;font-size:10.5px;font-weight:700;
  padding:6px 11px;border-radius:8px;
  border:1px solid #C9A227;
  background:#C9A227;color:#fff;
  cursor:pointer;
}
.verify-banner-btn.ghost{
  background:transparent;color:#8A6A12;
  border-color:rgba(138,106,18,.4);
}

/* ============================================================
   ===== Mise en page bureau (≥ 900 px) =====
   ============================================================
   Le jeu est conçu pour le téléphone : une colonne de 480 px, une barre
   d'onglets fixée en bas sous le pouce. Sur un écran d'ordinateur, cette
   colonne flottait au centre d'un vaste aplat beige.
   Rien du CSS mobile n'est modifié plus haut : tout tient dans cette
   requête média, donc l'affichage téléphone reste strictement identique. */
@media (min-width:900px){

  .app-shell{ max-width:1180px; }

  /* La barre d'onglets devient une colonne latérale. On passe par une
     grille plutôt que par du position:fixed avec un décalage calculé :
     la grille suit la largeur réelle du conteneur, donc rien ne sort de
     l'écran aux tailles intermédiaires (fenêtre réduite, tablette). */
  #appScreen{
    flex:1;
    display:grid;
    grid-template-columns:168px minmax(0,1fr);
    grid-template-rows:auto auto 1fr;
    grid-template-areas:
      "nav topbar"
      "nav banner"
      "nav main";
    min-height:100vh;
  }
  .topbar{ grid-area:topbar; }

  /* Desktop : rétablit un vrai conteneur (annule display:contents mobile)
     et empile les icônes AU-DESSUS des pastilles de ressources, alignées
     à droite. Les icônes restent côte à côte (row), pas empilées entre elles. */
  .topbar-right{
    display:flex;
    flex-direction:column;
    align-items:flex-end;
    gap:6px;
    flex-wrap:nowrap;
  }
  .topbar-icons{
    flex-direction:row;
  }
  .topbar > .resources,
  .topbar-right > .resources{
    flex-basis:auto;
  }
  .verify-banner{ grid-area:banner; }
  .app-main{ grid-area:main; padding:18px 22px 36px; }

  .bottomnav{
    grid-area:nav;
    position:sticky;
    top:0;
    align-self:start;
    left:auto;
    transform:none;
    width:auto;
    max-width:none;
    height:100vh;
    flex-direction:column;
    justify-content:flex-start;
    gap:2px;
    border-top:none;
    border-right:1px solid rgba(43,38,32,.15);
    padding:14px 9px;
    backdrop-filter:none;
  }
  /* Icône à côté du libellé, comme dans toute barre latérale */
  .nav-item{
    flex:0 0 auto;
    flex-direction:row;
    justify-content:flex-start;
    align-items:center;
    gap:10px;
    min-height:auto;
    padding:10px 11px;
    font-size:12px;
    border-radius:9px;
    text-align:left;
  }
  .nav-item:hover{ background:rgba(43,38,32,.05); }
  .nav-item.active{ background:rgba(181,75,58,.11); }
  .nav-icon{ font-size:16px; }
  /* La pastille se cale à droite du libellé au lieu d'être posée sur l'icône */
  .nav-badge{ position:static; margin-left:auto; }

  /* ===== Onglet Repaire : deux colonnes =====
     La carte du repaire est un SVG en largeur 100 % : étalée sur toute la
     zone de contenu, elle faisait à elle seule plus d'un écran de haut et
     repoussait bâtiments et classement hors de vue. Placée dans une colonne,
     elle retrouve une hauteur raisonnable — et la place gagnée à droite
     accueille ce qu'il fallait auparavant aller chercher en défilant. */
  #tab-repaire{
    display:grid;
    grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);
    grid-template-rows:auto auto 1fr;
    column-gap:20px;
    align-items:start;
  }
  #repaireTop{ grid-column:1; grid-row:1 / span 3; }
  #tab-repaire > .section-title{ grid-column:2; grid-row:1; margin-top:0; }
  #buildingsList{ grid-column:2; grid-row:2; }
  #leaderboardCard{ grid-column:2; grid-row:3; margin-top:14px; }

  /* ===== Onglet Tanukis : roster pleine largeur, puis deux colonnes ===== */
  #tab-tanukis{
    display:grid;
    grid-template-columns:minmax(0,1fr) minmax(0,1fr);
    column-gap:20px;
    align-items:start;
  }
  /* nth-child et non nth-of-type : « of-type » compte les div frères, or
     rosterGrid et recruitSection sont eux aussi des div — .section-title
     n'est jamais le 2e ni le 3e div, et les règles ne s'appliqueraient pas.
     grid-row explicite sur CHAQUE règle ci-dessous, pas seulement
     grid-column : sans ça, le placement automatique de la grille avance son
     curseur d'une ligne dès que "Recrutement" (colonne 1) doit sauter la
     ligne 3 pour rester dans sa colonne — et ne revient JAMAIS combler la
     colonne 2 restée libre à cette ligne (le placement "sparse", par
     défaut, ne recule jamais). "Inventaire" se retrouvait donc placé une
     ligne plus bas que "Recrutement" au lieu d'être aligné avec lui. */
  #tab-tanukis > .section-title:nth-child(1){ grid-column:1 / -1; grid-row:1; margin-top:0; }
  #rosterGrid{ grid-column:1 / -1; grid-row:2; grid-template-columns:repeat(4,1fr); }
  #tab-tanukis > .section-title:nth-child(3){ grid-column:1; grid-row:3; }
  #recruitSection{ grid-column:1; grid-row:4; }
  #tab-tanukis > .section-title:nth-child(5){ grid-column:2; grid-row:3; }
  #inventorySection{ grid-column:2; grid-row:4; }

  /* ===== Listes en plusieurs colonnes =====
     .buildings-list est volontairement ABSENTE d'ici : ses cartes sont des
     cartes horizontales (icône, texte, bouton sur une ligne) et elles vivent
     déjà dans la colonne de droite de l'onglet Repaire, soit environ 500 px.
     Les répartir sur deux colonnes de plus leur laissait ~240 px et cassait
     les libellés lettre par lettre (« Do rt oir »). */
  .shop-list{
    display:grid;
    grid-template-columns:repeat(2,minmax(0,1fr));
    gap:9px;
  }
  /* Les cartes yokai espacent avec margin-bottom : on l'annule au profit
     du gap de la grille, sinon l'écart vertical serait doublé. */
  #yokaiList{
    display:grid;
    grid-template-columns:repeat(2,minmax(0,1fr));
    gap:9px;
  }
  #yokaiList .yokai-card{ margin-bottom:0; }

  /* Les fiches modales gardent une largeur lisible : étirées sur 1180 px,
     leurs lignes de texte deviendraient interminables. */
  .result-card{ max-width:420px; }
  .yokai-art-card{ max-width:380px; }

  /* ===== Carte de raid : bandeau du boss ===== */
  /* Le clamp mobile (150-200px) plafonnait la hauteur bien avant que la
     largeur du bandeau n'ait fini de grandir : sur une carte proche de
     1000 px de large, l'image tenait dans une bande de 200 px à peine,
     minuscule et écrasée à côté. Hauteur revue à la hausse, réservée au
     desktop — rien n'est changé pour le mobile, qui gardait déjà un bon
     rendu. La largeur de .raid-card elle-même n'est pas touchée ici : c'est
     un autre sujet, à traiter séparément si besoin.*/
  .raid-boss-portrait{ height:clamp(200px, 30vw, 320px); }
}

/* ===================================================================
   Tutoriel guidé
   =================================================================== */
/* Le voile intercepte tous les clics : c'est LUI qui redirige ceux qui
   tombent sur la cible (voir tutorial.js). On ne fait donc jamais remonter
   l'élément visé par z-index, ce qui casserait dès qu'il se trouve dans un
   contexte d'empilement — la barre d'onglets en crée un. */
.tuto-voile{
  position:fixed; inset:0; z-index:9000;
  background:transparent;
}
/* L'assombrissement vient de l'ombre portée démesurée du projecteur : le
   « trou » est donc toujours exactement à la bonne place, sans avoir à
   composer quatre rectangles autour de la cible. */
.tuto-projecteur{
  position:fixed; z-index:9001;
  pointer-events:none;
  box-shadow:0 0 0 9999px rgba(20,16,12,.72);
  border:2px solid var(--torii);
  transition:opacity .18s ease;
}
.tuto-bulle{
  position:fixed; z-index:9002;
  max-width:min(330px, calc(100vw - 24px));
  background:var(--washi);
  border:1px solid rgba(43,38,32,.18);
  border-radius:14px;
  padding:14px 16px 12px;
  box-shadow:0 12px 34px -12px rgba(20,16,12,.6);
}
.tuto-bulle.centree{
  top:50%; left:50%;
  transform:translate(-50%,-50%);
}
.tuto-compte{
  font-size:9.5px; font-weight:800; letter-spacing:.07em; text-transform:uppercase;
  color:var(--ink-soft); margin-bottom:5px;
}
.tuto-titre{
  font-family:'Shippori Mincho',serif;
  font-size:16px; font-weight:700; color:var(--ink); margin-bottom:5px;
}
.tuto-texte{ font-size:12.5px; line-height:1.55; color:var(--ink-soft); }
.tuto-actions{
  display:flex; align-items:center; justify-content:space-between;
  gap:10px; margin-top:12px;
}
.tuto-passer{
  background:none; border:none; padding:0; cursor:pointer;
  font-family:inherit; font-size:10.5px; color:var(--ink-soft);
  text-decoration:underline; opacity:.75;
}
.tuto-passer:hover{ opacity:1; }
/* Secousse quand le joueur clique en dehors de la cible : lui signale que le
   clic a bien été reçu mais qu'il n'est pas au bon endroit, plutôt que de
   laisser croire à une interface figée. */
.tuto-bulle.secoue{ animation:tuto-secousse .32s ease; }
@keyframes tuto-secousse{
  0%,100%{ transform:translateX(0); }
  20%{ transform:translateX(-6px); } 40%{ transform:translateX(6px); }
  60%{ transform:translateX(-4px); } 80%{ transform:translateX(4px); }
}
.tuto-bulle.centree.secoue{ animation:tuto-secousse-c .32s ease; }
@keyframes tuto-secousse-c{
  0%,100%{ transform:translate(-50%,-50%); }
  20%{ transform:translate(calc(-50% - 6px),-50%); }
  40%{ transform:translate(calc(-50% + 6px),-50%); }
  60%{ transform:translate(calc(-50% - 4px),-50%); }
  80%{ transform:translate(calc(-50% + 4px),-50%); }
}
@media (prefers-reduced-motion: reduce){
  .tuto-bulle.secoue, .tuto-bulle.centree.secoue{ animation:none; }
}

/* ===== Objectifs du jour ===== */
.obj-section-title{
  font-family:'Shippori Mincho',serif;
  font-size:11px; font-weight:700; color:var(--ink-soft);
  text-transform:uppercase; letter-spacing:.06em;
  margin:12px 0 6px;
}
.obj-section-title:first-of-type{ margin-top:6px; }
/* Avancement chiffré à côté du libellé : sans lui, un objectif « trois
   missions » ne dit pas où l'on en est, et il faut compter de tête. */
.daily-progress{
  font-size:10px; font-weight:700; color:var(--ink-soft);
  background:rgba(43,38,32,.08);
  border-radius:20px; padding:1px 7px; margin-left:4px;
}
.daily-bonus-row{
  border-color:rgba(201,162,39,.45);
  background:rgba(201,162,39,.07);
}

/* ===== Conversion Feuilles -> Essence du coffre commun ===== */
.dist-conversion{
  margin-top:9px;
  font-size:10.5px;line-height:1.5;
  color:var(--ink-soft);
  background:rgba(43,38,32,.05);
  border-radius:8px;padding:7px 9px;
}
.dist-conversion.insuffisant{
  color:var(--torii-deep);
  background:rgba(181,75,58,.1);
}
.dist-conv-main{ font-size:11px; }
/* Le rappel du coût réel est volontairement plus discret que le chiffre du
   coffre : il informe sans transformer chaque don en reproche. */
.dist-conv-note{
  font-size:9.5px; line-height:1.45;
  opacity:.72; margin-top:4px;
}

/* ===== Options de fusion et Encens de l'oubli ===== */
.fusion-options{
  display:flex;flex-direction:column;gap:6px;
  margin:9px 0 10px;
  padding:9px 10px;
  background:rgba(255,255,255,.45);
  border:1px solid rgba(43,38,32,.12);
  border-radius:10px;
}
.fusion-opt{
  display:flex;align-items:center;gap:8px;
  font-size:11px;color:var(--ink);cursor:pointer;
}
.fusion-opt input{ accent-color:var(--torii); }
.fusion-opt-stock{ font-size:9.5px;font-weight:700;color:var(--ink-soft); }
.fusion-options select{ font-size:11px;padding:5px 8px; }
.fusion-options select:disabled{ opacity:.45; }
.encens-row{ margin-top:10px; }

/* ===== Sets d'équipement ===== */
.set-block{ margin-bottom:9px; }
.set-block:last-child{ margin-bottom:0; }
.set-head{
  display:flex;align-items:baseline;justify-content:space-between;
  margin-bottom:3px;
}
.set-name{ font-family:'Shippori Mincho',serif;font-size:12.5px;font-weight:700; }
.set-count{ font-size:10px;font-weight:700;color:var(--ink-soft); }
/* Les paliers non atteints restent VISIBLES mais atténués : ils annoncent au
   joueur ce qu'il gagnerait à compléter, au lieu de le laisser deviner. */
.set-tier{
  font-size:10px;line-height:1.5;color:var(--ink-soft);
  opacity:.45;padding-left:2px;
}
.set-tier.on{ opacity:1;color:var(--ink);font-weight:700; }
.set-tier-n{
  display:inline-block;min-width:15px;height:15px;line-height:15px;
  text-align:center;margin-right:6px;
  font-size:9px;font-weight:800;border-radius:50%;
  background:rgba(43,38,32,.1);color:var(--ink-soft);
}
.set-tier.on .set-tier-n{ background:var(--torii);color:#fff; }
/* Petite pastille "quel set ?" posée à côté du nom d'un objet, partout où on
   peut choisir/voir un objet (liste de sélection, ligne "déjà équipé",
   inventaire) — sans elle, rien ne distingue un objet de set d'un objet
   isolé tant qu'on n'a pas ouvert le détail du tanuki. */
.set-badge{
  display:inline-flex;align-items:center;
  font-size:8.5px;font-weight:800;line-height:1;
  padding:2.5px 5px;border-radius:6px;
  border:1px solid currentColor;
  background:rgba(255,255,255,.5);
  white-space:nowrap;
  flex-shrink:0;
}

/* ===== Classement d'arène ===== */
.ladder-card{
  background:rgba(255,255,255,.45);
  border:1px solid rgba(43,38,32,.12);
  border-radius:12px;padding:11px 12px;
}
/* Bandeau de position. Le rang est traité comme un CHIFFRE-OBJET, pas comme
   un mot dans une phrase : c'est l'information qu'on vient chercher, elle doit
   se lire sans lire. */
.ladder-banner{
  display:flex;align-items:center;gap:13px;
  padding:11px 13px;margin-bottom:10px;
  border-radius:11px;
  /* Teinte unie : le dégradé diagonal s'éteignait vers la droite, là où se
     trouve le compteur de trophées, qui paraissait alors détaché de la carte. */
  background:rgba(181,75,58,.10);
  border:1px solid rgba(181,75,58,.22);
}
.ladder-banner-rank{
  display:flex;align-items:baseline;
  color:var(--torii-deep);
  flex-shrink:0;
}
.ladder-banner-num{
  font-family:'Shippori Mincho',serif;
  font-size:30px;font-weight:800;line-height:1;
}
.ladder-banner-rank sup{ font-size:12px;font-weight:700;margin-left:1px; }
.ladder-banner-txt{ min-width:0; }
.ladder-banner-main{
  font-family:'Shippori Mincho',serif;
  font-size:12.5px;font-weight:700;color:var(--ink);
}
.ladder-banner-sub{
  font-size:10.5px;color:var(--ink-soft);margin-top:2px;line-height:1.4;
}
.ladder-banner-sub strong{ color:var(--torii-deep);font-weight:800; }
/* Au sommet, on passe sur l'or : le rouge torii sert à indiquer un objectif
   à atteindre, il n'a plus rien à signaler quand il n'y a plus personne. */
.ladder-banner.au-sommet{
  background:rgba(201,162,39,.13);
  border-color:rgba(201,162,39,.4);
}
.ladder-banner.au-sommet .ladder-banner-rank{ color:#A67C0F; }
.ladder-section-title{
  font-size:9.5px;font-weight:800;letter-spacing:.06em;text-transform:uppercase;
  color:var(--ink-soft);margin:9px 0 4px;
}
.ladder-row{
  display:flex;align-items:center;gap:9px;
  padding:6px 7px;border-radius:9px;
}
/* La ligne du joueur est mise en avant : c'est le repère qu'on cherche des
   yeux en ouvrant le classement. */
.ladder-row.moi{
  background:rgba(181,75,58,.1);
  border:1px solid rgba(181,75,58,.3);
}
.ladder-rank{
  min-width:24px;text-align:center;
  font-size:12px;font-weight:800;color:var(--ink-soft);
}
.ladder-portrait{
  width:40px;height:40px;border-radius:9px;flex-shrink:0;
  background-size:cover;background-position:center 22%;
}
.ladder-name-block{ flex:1;min-width:0; }
.ladder-name{
  display:block;font-size:12px;font-weight:700;color:var(--ink);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.ladder-trophies{ font-size:11px;font-weight:700;color:var(--moss);flex-shrink:0; }
.ladder-locked{ font-size:12px;color:var(--ink-soft);opacity:.5;padding:0 10px; }

/* Titre actif d'un AUTRE joueur, affiché sous son nom dans le classement
   d'arène, les voisins de la Forêt, et la liste des membres du Hayashi.
   Même teinte dorée que .player-titre (son propre titre dans l'en-tête),
   mais en display:block sous un nom déjà réduit, donc plus petit encore. */
.mini-titre-badge{
  display:block;
  font-size:8px;font-weight:700;
  color:var(--gold);
  text-transform:uppercase;letter-spacing:.03em;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  margin-top:1px;
}

/* ---------- Halos de titre (Sprint 2 cosmétique) ----------
   Réservés aux titres premium : un texte n'a pas de forme à cadrer comme un
   avatar, donc text-shadow/couleur plutôt que box-shadow. Classes GÉNÉRIQUES
   (pas préfixées par .mini-titre-badge) : réutilisées telles quelles sur
   .player-titre (son propre titre, topbar) et .titre-row-label (aperçu dans
   l'écran de sélection), qui n'ont pas la même classe parente. */
.titre-halo-torii{
  color:var(--torii) !important;
  text-shadow:0 0 6px rgba(181,75,58,.5);
}
.titre-halo-or{
  color:var(--gold) !important;
  text-shadow:0 0 8px rgba(201,162,39,.65);
}
.titre-halo-brume{
  color:#8A9BB8 !important;
  text-shadow:0 0 6px rgba(138,155,184,.6);
  animation:titreBrumePulse 3s ease-in-out infinite;
}
@keyframes titreBrumePulse{
  0%, 100%{ opacity:.85; }
  50%{ opacity:1; text-shadow:0 0 10px rgba(138,155,184,.85); }
}
.titre-halo-yokai{
  color:var(--torii-deep) !important;
  text-shadow:0 0 7px rgba(181,75,58,.55), 0 0 2px rgba(43,38,32,.6);
}
@media (prefers-reduced-motion:reduce){
  .titre-halo-brume{ animation:none; }
}

/* ---------- Couleurs de pseudo (Sprint 3 cosmétique) ----------
   Classes génériques, comme les halos de titre : réutilisées telles quelles
   sur .player-name (topbar), .ladder-name, .member-name, .chat-msg-name et
   .arena-opponent-name, qui n'ont pas de classe parente commune. */
/* Refonte cosmétique v2 : un léger halo (text-shadow) sur chaque couleur —
   la teinte seule se noyait dans les listes denses (ladder, membres). */
.nom-or{ color:var(--gold) !important; text-shadow:0 0 6px rgba(201,162,39,.55); }
.nom-torii{ color:var(--torii) !important; text-shadow:0 0 6px rgba(181,75,58,.5); }
.nom-indigo{ color:var(--indigo) !important; text-shadow:0 0 6px rgba(46,53,72,.5); }

/* Aurore : dégradé or/torii qui glisse à travers le pseudo — la couleur
   « prestige ». Repli en or plein d'abord : si background-clip:text n'est
   pas supporté, un texte transparent deviendrait invisible, d'où le
   @supports. Le motif du dégradé se répète tous les 33 % de l'image
   (background-size:300 %) : glisser la position de 0 % à 100 % déplace
   l'image d'exactement deux périodes, la boucle est donc invisible. */
.nom-aurore{
  color:var(--gold) !important;
  text-shadow:0 0 6px rgba(201,162,39,.45);
}
@supports ((-webkit-background-clip:text) or (background-clip:text)){
  .nom-aurore{
    background-image:linear-gradient(90deg,
      var(--gold) 0%, var(--torii) 16.5%, var(--gold) 33%,
      var(--torii) 49.5%, var(--gold) 66%,
      var(--torii) 82.5%, var(--gold) 100%);
    background-size:300% 100%;
    -webkit-background-clip:text;
    background-clip:text;
    -webkit-text-fill-color:transparent;
    color:transparent !important;
    text-shadow:none;
    animation:nomAuroreGlisse 6s linear infinite;
  }
}
@keyframes nomAuroreGlisse{
  from{ background-position:0% 0; }
  to{ background-position:100% 0; }
}
@media (prefers-reduced-motion:reduce){
  .nom-aurore{ animation:none; }
}

/* ---------- Zones de fin de saison ----------
   Un liseré à gauche plutôt qu'un fond coloré : la ligne « moi » a déjà le
   sien, et deux aplats superposés deviendraient illisibles. Le liseré se
   cumule sans conflit. */
/* ---------- Fin de saison, dans l'en-tête d'arène ----------
   Le décompte se noyait dans le fond : il porte l'échéance de toute la
   compétition, il doit se lire d'un coup d'œil. */
.arena-saison{
  display:flex; align-items:center; gap:7px;
  /* flex-basis:100% force TOUJOURS son propre passage à la ligne, quelle
     que soit la largeur d'écran, plutôt que de deviner si elle tient à côté
     du badge de ligue et des trophées (ce calcul dépendait de la largeur
     exacte de l'écran et ratait encore sur certains iPhones récents). Un
     petit filet visuel (bordure du dessus) sépare alors clairement ce
     second rang plutôt que de le laisser flotter. */
  flex:1 1 100%;
  justify-content:space-between;
  margin-top:6px;
  padding-top:8px;
  border-top:1px solid color-mix(in srgb, var(--league-color) 25%, transparent);
}
.arena-saison-label{
  font-size:10px; text-transform:uppercase; letter-spacing:.06em;
  color:var(--ink-soft); opacity:.75;
  white-space:nowrap;
}
.arena-saison-compte{
  font-family:'Shippori Mincho', serif;
  font-weight:700; font-size:13px;
  color:var(--ink);
  font-variant-numeric:tabular-nums; /* les chiffres ne dansent pas à chaque seconde */
  white-space:nowrap;
}
.arena-destin{
  position:relative;
  display:inline-flex; align-items:center; justify-content:center;
  width:22px; height:22px; flex-shrink:0;
  border-radius:7px;
  font-weight:800; font-size:13px; line-height:1;
  cursor:help;
}
.arena-destin:focus-visible{ outline:2px solid var(--torii); outline-offset:2px; }
/* Teinte discrète plutôt qu'aplat saturé + texte blanc : le vert plein
   tranchait avec la palette chaude de la page et attirait l'œil plus que le
   décompte lui-même. Même principe que .tag.weakness ailleurs dans le jeu —
   fond très translucide, symbole coloré. */
.destin-montee{ color:#4E5A3D; background:rgba(107,122,84,.20); }
.destin-descente{ color:var(--torii-deep); background:rgba(181,75,58,.18); }
.destin-stable{ color:var(--ink-soft); background:rgba(43,38,32,.09); }

/* Infobulle maison : l'attribut title met une à deux secondes à apparaître,
   ne se met pas en forme, et reste muet sur un <span> dans plusieurs
   navigateurs. Celle-ci s'affiche immédiatement, au survol comme au focus
   clavier. */
.arena-destin::after{
  content:attr(data-tip);
  position:absolute; top:calc(100% + 7px); right:0;
  z-index:20;
  background:var(--ink); color:var(--washi);
  font-family:-apple-system,'Segoe UI',Roboto,Arial,sans-serif;
  font-size:11px; font-weight:600; line-height:1.3;
  padding:6px 9px; border-radius:8px;
  white-space:nowrap;
  opacity:0; visibility:hidden;
  transform:translateY(-3px);
  transition:opacity .12s ease, transform .12s ease, visibility .12s;
  pointer-events:none;
  box-shadow:0 3px 10px -3px rgba(43,38,32,.5);
}
.arena-destin:hover::after,
.arena-destin:focus-visible::after{
  opacity:1; visibility:visible; transform:translateY(0);
}

/* ---------- Infobulle tactile réutilisable (.a-tip) ----------
   Même raisonnement que .arena-destin ci-dessus, généralisé : title ne
   s'affiche JAMAIS au toucher sur mobile (ni au survol, qui n'existe pas, ni
   au tap, sur la plupart des navigateurs), seulement à la souris. Tout
   élément avec data-tip + cette classe reçoit une bulle qui s'ouvre aussi
   sur simple tap, via .tip-open posée en JS (voir le gestionnaire délégué
   sur document dans app.js — un seul suffit pour tout le jeu, y compris le
   contenu redessiné après coup).
   Centrée au-dessus de l'élément plutôt qu'alignée à droite comme
   .arena-destin : ses usages sont dispersés dans des cartes de largeurs
   variées, un alignement fixe déborderait souvent. white-space:normal avec
   une largeur maximale, pas nowrap : certains textes (l'effet d'une
   statistique) sont des phrases complètes, pas des libellés courts. */
.a-tip{ position:relative; cursor:help; }
.a-tip::after{
  content:attr(data-tip);
  position:absolute; bottom:calc(100% + 7px); left:50%;
  z-index:30;
  background:var(--ink); color:var(--washi);
  font-family:-apple-system,'Segoe UI',Roboto,Arial,sans-serif;
  font-size:11px; font-weight:600; line-height:1.35;
  padding:7px 10px; border-radius:8px;
  white-space:normal; width:max-content; max-width:200px;
  text-align:center;
  opacity:0; visibility:hidden;
  transform:translate(-50%, 3px);
  transition:opacity .12s ease, transform .12s ease, visibility .12s;
  pointer-events:none;
  box-shadow:0 3px 10px -3px rgba(43,38,32,.5);
}
.a-tip:hover::after,
.a-tip:focus-visible::after,
.a-tip.tip-open::after{
  opacity:1; visibility:visible; transform:translate(-50%, 0);
}

.ladder-row.zone-montee{ box-shadow:inset 3px 0 0 var(--moss); }
.ladder-row.zone-descente{ box-shadow:inset 3px 0 0 var(--torii); }

/* ---------- Progression au classement depuis la veille ----------
   Volontairement discret : c'est une information secondaire, elle ne doit pas
   concurrencer le rang lui-même. */
.ladder-mouvement{
  display:inline-flex; align-items:center; gap:1px;
  font-size:9px; font-weight:700;
  margin-left:-4px; margin-right:2px;
  cursor:help;
}
.ladder-mouvement.monte{ color:var(--moss); }
.ladder-mouvement.descend{ color:var(--torii); }
.ladder-mouvement-n{ font-size:9px; opacity:.75; }

/* Gain attendu affiché sur le bouton : l'enjeu doit se lire avant le clic,
   sinon une victoire à 0 trophée passe pour un dysfonctionnement. */
.ladder-gain{ font-weight:800; opacity:.85; margin-left:2px; }
/* Un combat qui ne rapporte rien reste possible — on ne l'interdit pas, on le
   rend simplement visiblement sans intérêt. */
.ladder-attack-btn.sans-gain{ opacity:.55; }
.ladder-attack-btn.sans-gain .ladder-gain{ opacity:.7; }

/* Une seule ligne discrète quand tous les objectifs de départ sont accomplis :
   la section entière disparaît, mais l'accomplissement n'est pas effacé. */
.obj-all-done{
  font-size:10.5px;color:var(--ink-soft);
  text-align:center;margin-top:12px;opacity:.8;
}

/* Explique pourquoi la protection s'est allongée : sans ça, un bouclier qui
   passe de 15 min à 4 h paraîtrait arbitraire. */
.shield-streak{
  display:block;font-size:9.5px;font-weight:400;
  opacity:.75;margin-top:2px;
}

/* ===================================================================
   PvP — sélecteur Arène/Forêt et vue de la Forêt
   =================================================================== */

.pvp-switch{
  display:flex;gap:6px;margin-bottom:14px;
  background:rgba(43,38,32,.06);border-radius:10px;padding:3px;
}
.pvp-switch-btn{
  flex:1;border:none;background:none;cursor:pointer;font-family:inherit;
  padding:7px 10px;border-radius:8px;
  font-size:12px;font-weight:700;color:var(--ink-soft);
}
.pvp-switch-btn.active{
  background:var(--washi);color:var(--ink);
  box-shadow:0 1px 3px rgba(43,38,32,.16);
}

/* Position du repaire dans la Forêt */
.foret-header{
  display:flex;align-items:center;justify-content:space-between;gap:10px;
  background:rgba(255,255,255,.5);
  border:1px solid rgba(43,38,32,.12);
  border-radius:12px;padding:10px 12px;margin-bottom:12px;
}
.foret-pos{font-size:13px;color:var(--ink);}
.foret-pos-sub{font-size:10px;color:var(--ink-soft);margin-top:2px;}

/* Bouton d'aide contextuelle — un vrai panneau au clic plutôt qu'un simple
   title= (infobulle native), inutile sur mobile où il n'y a pas de survol. */
.foret-aide-btn{
  flex-shrink:0;
  width:26px;height:26px;border-radius:50%;
  background:rgba(181,75,58,.12);
  border:1px solid rgba(181,75,58,.35);
  color:var(--torii-deep);
  font-family:Georgia,serif;font-weight:800;font-size:14px;
  cursor:pointer;
  display:flex;align-items:center;justify-content:center;
}
.foret-aide-btn:hover{background:rgba(181,75,58,.2);}

/* Sections du panneau d'aide */
.aide-foret-section{
  margin-bottom:12px;padding-bottom:12px;
  border-bottom:1px solid rgba(43,38,32,.1);
}
.aide-foret-section:last-of-type{border-bottom:none;margin-bottom:4px;padding-bottom:0;}
.aide-foret-titre{font-size:13px;font-weight:800;color:var(--ink);margin-bottom:4px;}
.aide-foret-section p{font-size:12px;color:var(--ink-soft);line-height:1.5;margin:0 0 6px;}
.aide-foret-section p:last-child{margin-bottom:0;}
.aide-foret-section p.note{
  font-size:11px;font-style:italic;
  background:rgba(201,162,39,.1);border-radius:8px;padding:6px 8px;
}

/* Convoi d'évacuation */
.foret-convoi{
  display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  background:rgba(201,162,39,.12);
  border:1px solid rgba(201,162,39,.35);
  border-radius:12px;padding:10px 12px;margin-bottom:14px;
}
.foret-convoi-titre{font-size:12px;font-weight:800;color:var(--ink);}
.foret-convoi-detail{font-size:11px;color:var(--ink-soft);flex:1;min-width:140px;}
.foret-convoi-timer{font-size:10px;color:var(--ink-soft);font-weight:700;}

/* Opérations en route */
.foret-op{
  display:flex;align-items:center;gap:10px;
  background:rgba(255,255,255,.45);
  border:1px solid rgba(43,38,32,.1);
  border-radius:10px;padding:8px 10px;margin-bottom:6px;
}
.foret-op-type{font-size:16px;}
.foret-op-cible{font-size:12px;font-weight:700;}
.foret-op-sub{font-size:10px;color:var(--ink-soft);}

/* Liste des repaires voisins */
.foret-cible{
  display:flex;align-items:center;gap:10px;
  background:rgba(255,255,255,.5);
  border:1px solid rgba(43,38,32,.12);
  border-radius:11px;padding:9px 11px;margin-bottom:7px;
}
.foret-cible.voisin{border-left:3px solid var(--torii);}
.foret-cible-portrait{
  width:44px;height:44px;border-radius:10px;flex-shrink:0;
  background-size:cover;background-position:center 22%;
  background-color:rgba(43,38,32,.08);
}
.foret-cible-info{flex:1;min-width:0;}
.foret-cible-nom{font-size:12.5px;font-weight:700;overflow-wrap:anywhere;}
.foret-cible-sub{font-size:10px;color:var(--ink-soft);margin-top:2px;}
/* align-items:center est indispensable : sans lui, les enfants s'étirent en
   hauteur (stretch par défaut) et le texte de la pastille se cale en haut de
   sa boîte, alors que le bouton voisin centre le sien — d'où le décalage. */
.foret-cible-actions{display:flex;align-items:center;gap:5px;flex-shrink:0;}
.foret-protege{
  display:inline-flex;align-items:center;gap:3px;
  font-size:10px;font-weight:700;color:var(--ink-soft);
  white-space:nowrap;
}

/* Rapports d'espionnage et de raid */
.foret-rapport{
  background:rgba(255,255,255,.5);
  border:1px solid rgba(43,38,32,.12);
  border-left:3px solid rgba(43,38,32,.25);
  border-radius:10px;padding:9px 11px;margin-bottom:7px;
}
.foret-rapport.gagne{border-left-color:var(--moss);}
.foret-rapport.perdu{border-left-color:var(--torii-deep);}
.foret-rapport-titre{
  font-size:12px;font-weight:800;margin-bottom:5px;
  display:flex;justify-content:space-between;gap:8px;
}
.foret-rapport-niveau{font-size:10px;font-weight:700;color:var(--ink-soft);}
.foret-rapport-ligne{font-size:11px;color:var(--ink);margin-top:2px;}
.foret-approx{font-size:10px;color:var(--ink-soft);font-style:italic;}

/* Sélecteurs de tanukis PvP (classes utilisées aussi par l'arène) */
.squad-pick-list{max-height:280px;overflow-y:auto;}
.squad-pick-count{
  font-size:10px;color:var(--ink-soft);text-align:center;
  margin-top:7px;font-weight:700;
}

/* Bandeau d'attaque entrante : la seule alerte du jeu qui a une échéance.
   Animée volontairement — un compte à rebours statique se confond avec le
   reste du tableau de bord et se rate. */
.alerte-raid{
  position:relative;overflow:hidden;
  display:flex;align-items:center;gap:11px;
  background:rgba(181,75,58,.15);
  border:1px solid rgba(181,75,58,.45);
  border-radius:12px;padding:11px 13px;margin-bottom:11px;
  animation:alerteRaidEntree .35s ease-out;
}
.alerte-raid.critique{
  background:rgba(181,75,58,.24);
  border-color:var(--torii);
  animation:alerteRaidEntree .35s ease-out, alerteRaidPulse 1.1s ease-in-out infinite;
}
/* Balayage lumineux qui traverse le bandeau, discret mais perceptible en
   vision périphérique — c'est ce qui attire l'œil sans clignoter. */
.alerte-raid-pulse{
  position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(100deg, transparent 30%, rgba(255,255,255,.35) 50%, transparent 70%);
  transform:translateX(-100%);
  animation:alerteRaidBalayage 2.8s ease-in-out infinite;
}
.alerte-raid-portrait{
  width:34px;height:34px;border-radius:9px;flex-shrink:0;
  background-size:cover;background-position:center 22%;
  background-color:rgba(43,38,32,.08);
  position:relative;
}
.alerte-raid-corps{flex:1;min-width:0;position:relative;}
/* Pas de display:flex ici : le titre est une phrase continue
   (« Éclaireur de {nom} en approche ») avec un <span class="fiche-link">
   au milieu. En flex, chaque nœud texte et le span deviennent des items
   séparés qui se répartissent n'importe comment sur mobile — d'où
   « Éclaireur Aka / de ne / en approch e ». Flux inline normal +
   break-word (pas anywhere) pour ne couper qu'en dernier recours. */
.alerte-raid-titre{
  font-size:12.5px;font-weight:800;color:var(--ink);
  line-height:1.35;
  overflow-wrap:break-word;
  word-break:normal;
}
.alerte-raid-titre .fiche-link{
  cursor:pointer;
  display:inline;
  font-weight:800;
}
.alerte-raid-titre .fiche-link:hover{text-decoration:underline;}
/* Le mini-titre de l'attaquant réutilise .mini-titre-badge (voir plus haut),
   mais sur le fond corail de l'alerte plutôt que le fond washi habituel :
   la teinte or reste lisible, aucune redéfinition nécessaire ici. */
.alerte-raid-icone{
  font-size:15px;
  margin-right:6px;
  vertical-align:-1px;
}
.alerte-raid-compte{
  font-family:'Shippori Mincho',serif;
  font-size:19px;font-weight:800;color:var(--torii-deep);
  margin-top:2px;font-variant-numeric:tabular-nums;
}
.alerte-raid .btn{position:relative;flex-shrink:0;}

@keyframes alerteRaidEntree{
  from{opacity:0;transform:translateY(-8px);}
  to{opacity:1;transform:none;}
}
@keyframes alerteRaidPulse{
  0%,100%{box-shadow:0 0 0 0 rgba(181,75,58,.45);}
  50%{box-shadow:0 0 0 7px rgba(181,75,58,0);}
}
@keyframes alerteRaidBalayage{
  0%{transform:translateX(-100%);}
  55%,100%{transform:translateX(100%);}
}

/* Respect du réglage système : une animation qui pulse en permanence peut
   être pénible, voire déclencher des troubles. Le bandeau reste visible et
   parfaitement lisible, il cesse simplement de bouger. */
@media (prefers-reduced-motion: reduce){
  .alerte-raid,
  .alerte-raid.critique{animation:none;}
  .alerte-raid-pulse{display:none;}
}

/* Opération engagée : plus rappelable */
.foret-op-engagee{font-size:9.5px;font-weight:700;color:var(--ink-soft);flex-shrink:0;}

/* Protection de Jizō */
.foret-jizo{
  background:rgba(107,122,84,.14);
  border:1px solid rgba(107,122,84,.4);
  border-radius:12px;padding:10px 12px;margin-bottom:12px;
}
.foret-jizo-titre{font-size:12px;font-weight:800;color:var(--ink);}
.foret-jizo-texte{font-size:10.5px;color:var(--ink-soft);margin-top:3px;}

/* Carte de la Forêt — scène de nuit, même esprit que la carte du repaire */
.carte-foret-cadre{
  background:#3E4055;
  border:1px solid rgba(43,38,32,.2);
  border-radius:14px;padding:0;margin-bottom:12px;overflow:hidden;
  box-shadow:0 2px 10px -5px rgba(43,38,32,.5);
}
.carte-foret{display:block;width:100%;height:auto;}
.carte-foret-noeud, .cf-noeud{cursor:default;}
.cf-noeud.moi ellipse{filter:drop-shadow(0 0 5px rgba(110,143,82,.75));}
.carte-foret-legende{
  display:flex;justify-content:center;gap:13px;flex-wrap:wrap;
  font-size:9.5px;color:rgba(240,228,196,.7);
  padding:7px 8px 9px;background:rgba(0,0,0,.15);
}
.carte-foret-legende span{display:flex;align-items:center;gap:4px;}
.carte-foret-legende .pastille{width:8px;height:8px;border-radius:50%;display:inline-block;}
.carte-foret-legende .pastille.moi{background:#6E8F52;}
.carte-foret-legende .pastille.peuplee{background:#A85543;}
.carte-foret-legende .pastille.vide{background:#565469;}

/* Éclaireur repéré : avertissement, pas urgence. Ton ambre et pas de compte
   à rebours — rien n'est chronométré ici, mais une attaque peut suivre. */
.alerte-raid.espion{
  background:rgba(201,162,39,.16);
  border-color:rgba(201,162,39,.5);
  animation:alerteRaidEntree .35s ease-out;
}
.alerte-raid-sous{
  font-size:10.5px;color:var(--ink-soft);margin-top:3px;
}

/* --- Correctifs d'alignement et compléments PvP --- */

/* "Engagée" / "Rentre" étaient collés au texte au lieu d'être alignés à
   droite comme le bouton qu'ils remplacent. */
.foret-op{justify-content:space-between;}
.foret-op-info{flex:1;min-width:0;}
.foret-op-engagee{margin-left:auto;text-align:right;}

/* Convoi : minuteur et bouton de demi-tour côte à côte */
.foret-convoi-fin{
  display:flex;align-items:center;gap:8px;margin-left:auto;flex-shrink:0;
}

/* Âge d'un rapport d'espionnage — devient un avertissement au-delà de 30 min */
.foret-rapport-age{
  font-size:9.5px;color:var(--ink-soft);font-style:italic;margin-bottom:4px;
}
.foret-rapport-age.perime{color:var(--torii-deep);font-style:normal;font-weight:700;}

/* Le compte à rebours d'un éclaireur est plus discret que celui d'un raid :
   c'est une menace sur les informations, pas sur les ressources. */
.alerte-raid-compte.discret{
  font-size:13px;color:var(--ink-soft);font-family:inherit;
}

/* Note explicative sous la carte : trois numérotations coexistent (numéro de
   clairière, nombre de repaires, numéro d'emplacement), il faut dire
   lesquelles la carte montre et laquelle elle ne montre pas. */
.carte-foret-note{
  font-size:9.5px;line-height:1.45;
  color:rgba(240,228,196,.62);
  padding:0 12px 10px;background:rgba(0,0,0,.15);
  text-align:center;
}

/* Étiquette du thème de carte actif (lac, yuki…), sous la note explicative —
   n'apparaît que si le joueur a quitté le thème "Classique" gratuit. */
.carte-foret-theme-tag{
  text-align:center;
  font-size:10px;font-weight:700;
  color:rgba(240,228,196,.75);
  padding:4px 8px 8px;
  background:rgba(0,0,0,.12);
}

/* Nuit des lanternes (thème akari) : pulse quasi imperceptible sur la lueur
   au sol, 12s — jamais de balancement des lanternes elles-mêmes, c'est le
   rythme "jeu mobile cheap" qui a justement été écarté pour ce thème. */
@keyframes cfAkariLueur {
  0%, 100% { opacity: .24; }
  50%      { opacity: .34; }
}
.cf-akari-lueur {
  animation: cfAkariLueur 12s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) {
  .cf-akari-lueur { animation: none; opacity: .28; }
}

/* Bilan de chargement d'un convoi : ce qui part et ce qui reste exposé */
.evac-duree-label{
  font-size:9.5px;font-weight:700;color:var(--ink-soft);
  text-transform:uppercase;letter-spacing:.04em;
  margin:10px 0 4px;
}
.evac-bilan{
  background:rgba(201,162,39,.14);
  border:1px solid rgba(201,162,39,.4);
  border-radius:10px;padding:8px 10px;margin-top:9px;
}
.evac-bilan.complet{
  background:rgba(107,122,84,.16);border-color:rgba(107,122,84,.45);
}
.evac-bilan-ligne{font-size:11px;color:var(--ink);}
.evac-bilan-ligne.reste{color:var(--torii-deep);font-weight:700;margin-top:3px;}

/* Minuteurs de la Forêt en gras : ce sont les seules valeurs qui bougent,
   elles doivent se distinguer du texte descriptif autour. */
.foret-op-sub[data-compte-op],
.foret-convoi-timer{
  font-weight:800;color:var(--ink);
  font-variant-numeric:tabular-nums;
}

/* Saisie des quantités à envoyer */
.envoi-champs{display:flex;gap:9px;margin-top:10px;}
.envoi-champ{flex:1;display:flex;flex-direction:column;gap:3px;}
.envoi-champ span{font-size:10px;font-weight:700;color:var(--ink-soft);}
.envoi-champ small{font-weight:400;opacity:.8;}
.envoi-champ input{
  width:100%;padding:7px 9px;border-radius:8px;
  border:1px solid rgba(43,38,32,.2);background:rgba(255,255,255,.65);
  font-family:inherit;font-size:13px;font-weight:700;color:var(--ink);
}
.foret-envoi-btn{padding:6px 9px;}

/* Bandeau des opérations que l'on mène soi-même : informatif, pas alarmant.
   Ton neutre, pas d'animation — c'est un récapitulatif, pas une urgence. */
.alerte-raid.offensive{
  background:rgba(255,255,255,.5);
  border-color:rgba(43,38,32,.16);
  animation:none;
}
.alerte-raid.offensive .alerte-raid-sous{
  display:flex;gap:5px;align-items:center;
  font-variant-numeric:tabular-nums;
}

/* Convoi amical entrant : ton vert, aucune urgence, pas de bouton d'action.
   Il n'y a rien à faire d'autre que l'attendre. */
.alerte-raid.convoi{
  background:rgba(107,122,84,.15);
  border-color:rgba(107,122,84,.45);
  animation:alerteRaidEntree .35s ease-out;
}

/* ---------- Essence : grille de tuiles, dès le mobile ----------
   Contrairement à .shop-list générique (Coffres/Potions/Équipement, restée
   en 1 colonne car ses cartes portent plus d'infos — coût, limite, manque
   de ressources — qui se tasseraient mal à deux), les packs d'Essence
   utilisent une tuile VERTICALE dédiée (icône en haut, texte, bouton en
   dessous) plutôt que la ligne horizontale de .shop-item classique.
   Nécessaire : à deux colonnes, une ligne horizontale (icône+texte+bouton)
   n'a plus assez de largeur pour le texte, qui s'effondre à quelques pixels
   et se met à casser lettre par lettre (overflow-wrap:anywhere hérité de
   .shop-item). Une tuile verticale n'a pas ce problème, à aucune largeur. */
#shopEssenceList{
  display:grid;
  grid-template-columns:repeat(2,minmax(0,1fr));
  gap:9px;
}
.essence-tile{
  flex-direction:column;
  text-align:center;
  gap:7px;
  padding:14px 10px;
}
.essence-tile .pack-icon{
  width:52px;height:52px;
}
.essence-tile-name{
  font-family:'Shippori Mincho',serif;
  font-size:12px;
  font-weight:700;
}
.essence-tile-amount{
  font-size:10.5px;
  color:var(--ink-soft);
}
.essence-tile .buy-essence-btn{
  width:100%;
  margin-top:2px;
}

/* ---------- Tailles d'avatar responsives ----------
   Le mobile-first calait tout au plus étroit possible ; sur un écran plus
   large (desktop, PWA installée), l'app garde son max-width:480px mais peut
   se permettre des avatars plus lisibles. Un seul point de rupture à 400px :
   inutile de multiplier les paliers pour une largeur qui plafonne de toute
   façon à 480px. */
@media (min-width:400px){
  /* Décalés en conséquence de la hausse des tailles mobiles ci-dessus : ces
     valeurs restaient au même niveau, voire en dessous, du nouveau défaut
     mobile (ex. .ladder-portrait passait de 36px partout à 36px ici — plus
     aucun gain sur desktop). Même delta relatif qu'avant conservé. */
  .player-avatar{ width:48px; height:48px; }
  .fiche-avatar{ width:72px; height:72px; }
  .ladder-portrait{ width:44px; height:44px; }
  .member-avatar{ width:40px; height:40px; }
  .lb-row-portrait{ width:40px; height:40px; }
  .foret-cible-portrait{ width:46px; height:46px; }
  .alerte-raid-portrait{ width:40px; height:40px; }
}

/* ===== Onglet Admin ===== */
.admin-card{
  background:rgba(255,255,255,.55);
  border:1px solid rgba(43,38,32,.12);
  border-radius:12px;
  padding:14px;
  display:flex;
  flex-direction:column;
  gap:16px;
}
.admin-current-label{
  font-size:10px;font-weight:700;text-transform:uppercase;
  letter-spacing:.04em;color:var(--ink-soft);margin-bottom:6px;
}
.admin-current-title{
  font-family:'Shippori Mincho',serif;
  font-size:14px;font-weight:800;color:var(--torii-deep);
}
.admin-current-msg{
  font-size:12px;color:var(--ink);line-height:1.45;margin-top:4px;
  white-space:pre-wrap;
}
.admin-current-meta{
  font-size:10px;color:var(--ink-soft);margin-top:6px;
}
.admin-current-empty{
  font-size:12px;color:var(--ink-soft);font-style:italic;
}
.admin-label{
  display:block;font-size:11px;font-weight:700;
  color:var(--ink-soft);margin:10px 0 4px;
}
.admin-textarea{
  resize:vertical;min-height:90px;
}
.admin-actions{
  display:flex;gap:8px;margin-top:14px;flex-wrap:wrap;
}

/* ===== Bandeau d'annonce générale =====
   Absent du patch d'origine (qui renvoyait à un bandeau supposé déjà en
   place) : ce bloc-ci n'existait pas dans le code, donc dessiné depuis les
   mêmes teintes que .admin-card/.result-card plutôt que de deviner un style
   déjà écrit ailleurs. Généré dynamiquement par renderAnnouncementBanner()
   (voir app.js) en premier enfant de .app-main, pas présent dans
   index.html au départ.
   Accent doré à gauche façon parchemin scellé, plutôt qu'un bandeau plein
   généraliste — pour rester dans la palette washi du reste de l'appli. */
.announcement-banner{
  position:relative;
  background:linear-gradient(135deg, rgba(201,162,39,.14), rgba(201,162,39,.04));
  border:1px solid rgba(201,162,39,.35);
  border-left:3px solid var(--gold);
  border-radius:12px;
  padding:14px 38px 14px 16px;
  margin:0 0 16px;
  box-shadow:0 2px 10px rgba(43,38,32,.05);
}
.announcement-title{
  font-family:'Shippori Mincho',serif;
  font-size:14px;font-weight:800;color:var(--torii-deep);
  line-height:1.35;
  padding-right:6px;
}
.announcement-message{
  font-size:12px;color:var(--ink);line-height:1.6;margin-top:8px;
  white-space:pre-wrap;
}
.announcement-dismiss{
  position:absolute;top:10px;right:10px;
  width:24px;height:24px;
  display:flex;align-items:center;justify-content:center;
  font-size:12px;line-height:1;color:var(--ink-soft);
  background:rgba(255,255,255,.5);
  border:1px solid rgba(43,38,32,.12);
  border-radius:50%;
  cursor:pointer;
  transition:background .12s ease;
}
.announcement-dismiss:hover{background:rgba(255,255,255,.9);}
.announcement-dismiss:active{transform:scale(.92);}

/* ---- Icônes image des packs d'Essence (argent réel) ----
   Contrairement aux icônes SVG des autres objets de la boutique (qui
   utilisent le padding de .shop-item-icon pour respirer autour du trait),
   les images de packs sont des illustrations pleines : pas de padding,
   object-fit cover pour remplir le carré sans déformer. */
.shop-item-icon.pack-icon{padding:0;overflow:hidden;}
.shop-item-icon.pack-icon img{
  width:100%;height:100%;
  object-fit:cover;
  border-radius:10px;
  display:block;
}

/* ===== Pull-to-refresh ===== */
/* Fixé en haut, translaté hors écran par défaut (translateY:-100%) — la
   position réelle pendant le geste est pilotée en JS via --ptr-offset
   (voir initPullToRefresh dans app.js), 0 au repos, jusqu'à ~70px tiré. */
.ptr-indicator{
  position:fixed;
  top:calc(10px + env(safe-area-inset-top));
  left:50%;
  transform:translateX(-50%) translateY(calc(-100% - 10px + var(--ptr-offset, 0px)));
  z-index:20;
  width:36px;height:36px;
  border-radius:50%;
  background:rgba(237,230,214,.97);
  border:1px solid rgba(43,38,32,.15);
  box-shadow:0 4px 12px rgba(43,38,32,.18);
  display:flex;align-items:center;justify-content:center;
  transition:transform .15s ease;
  pointer-events:none;
}
/* Pas de transition pendant le drag lui-même (suivi 1:1 du doigt) — activée
   uniquement pour l'aller-retour au relâchement (voir la classe .settling
   posée/retirée en JS). */
.ptr-indicator.dragging{transition:none;}
.ptr-spinner{
  width:16px;height:16px;
  border-radius:50%;
  border:2px solid rgba(43,38,32,.2);
  border-top-color:var(--torii-deep);
  /* La rotation ne tourne QUE pendant le chargement effectif (classe
     .spinning posée juste avant location.reload) — au repos et pendant le
     tiré, l'icône reste fixe, c'est l'offset qui donne le retour visuel. */
}
.ptr-indicator.spinning .ptr-spinner{
  animation:ptr-spin .7s linear infinite;
}
@keyframes ptr-spin{ to{ transform:rotate(360deg); } }
@media (prefers-reduced-motion:reduce){
  .ptr-indicator.spinning .ptr-spinner{ animation:none; }
}
