/* Les polices vivent sur le site, plus chez Google Fonts : charger une feuille
   de fonts.googleapis.com, c'etait envoyer l'adresse IP de chaque joueur a
   Google a chaque ouverture du jeu, sans qu'il l'ait accepte. Cinzel et
   Lancelot sont sous licence SIL OFL 1.1 (assets/polices/OFL-*.txt), qui
   permet de les servir soi-meme. Cinzel est une police VARIABLE : un fichier
   pour toutes les graisses, d'ou la plage 400 a 900. */
@font-face { font-family: 'Cinzel'; font-style: normal; font-weight: 400 900; font-display: swap;
    src: url('assets/polices/cinzel-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: 'Cinzel'; font-style: normal; font-weight: 400 900; font-display: swap;
    src: url('assets/polices/cinzel-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family: 'Lancelot'; font-style: normal; font-weight: 400; font-display: swap;
    src: url('assets/polices/lancelot-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: 'Lancelot'; font-style: normal; font-weight: 400; font-display: swap;
    src: url('assets/polices/lancelot-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF; }

:root {
    /* Palette "bois & or vieilli" : dérivée de l'illustration du village.
       Un seul accent (l'or) + vert/rouge désaturés pour les états. */
    --bg-color: #0f0d0a;
    --panel-bg: rgba(26, 21, 16, 0.96);
    --panel-border: #3b2f22;
    --line-soft: #2a2119;
    --surface: #191410;
    --surface-2: #221b14;
    --surface-3: #2a2219;
    --text-dark: #f2e9d8;
    --text-light: #f2e9d8;
    --muted: #9c9182;
    --accent: #d4a548;
    --gold-bright: #f0c674;
    --highlight: #ffaa00;
    --success: #74bd7a;
    --danger: #cf6a55;
    --progress-bg: rgba(0,0,0,0.6);
    --progress-fill: #d4a548;
    --radius: 12px;
    --radius-sm: 8px;
    --font-main: 'Lancelot', serif;
    --font-title: 'Cinzel', serif;
    --font-ui: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
}

body {
    margin: 0;
    padding: 0;
    background-color: var(--bg-color);
    background-image: radial-gradient(circle at center, #3d332b 0%, #1a1612 100%);
    color: var(--text-light);
    font-family: var(--font-main);
    display: flex;
    flex-direction: column;
    /* 100vh compte la barre du navigateur RETRACTEE : dans un onglet Safari
       ordinaire, la page est plus haute que ce qu'on voit et la barre
       d'onglets du bas se glisse dessous. 100dvh suit le viewport reel ;
       la ligne du dessus reste le repli des navigateurs qui l'ignorent. */
    height: 100vh;
    height: 100dvh;
    overflow: hidden;
}

h1, h2, h3, h4 {
    font-family: var(--font-title);
    margin-top: 0;
    text-shadow: 1px 1px 2px rgba(0,0,0,0.5);
}

#mobile-topbar-toggle {
    display: none;
}

/* Navigation mobile : masquée sur desktop, activée dans la media query */
#mobile-tabbar { display: none; }
.sheet-handle { display: none; }

#top-bar {
    background: linear-gradient(180deg, #221b14 0%, #16120d 100%);
    border-bottom: 1px solid var(--panel-border);
    padding: 0 14px;
    height: 62px;
    display: flex;
    align-items: center;
    flex-wrap: nowrap;
    box-sizing: border-box;
    width: 100%;
    gap: 14px;
    box-shadow: 0 2px 12px rgba(0,0,0,0.6);
    /* Les batiments de la scene sont aussi a 10 et viennent apres dans le
       document : a egalite, ils passaient devant le menu du bandeau. */
    position: relative;
    z-index: 60;
}

/* --- Blason joueur --- */
.hud-crest {
    display: flex;
    align-items: center;
    gap: 10px;
    padding-right: 14px;
    border-right: 1px solid var(--line-soft);
    flex-shrink: 0;
}
.crest-badge {
    width: 34px;
    height: 34px;
    border-radius: 9px;
    background: linear-gradient(160deg, #3b2f22, #241d15);
    border: 1px solid var(--panel-border);
    display: grid;
    place-items: center;
    font-size: 18px;
}
.crest-badge svg { width: 24px; height: 24px; }
.crest-txt { display: flex; flex-direction: column; line-height: 1.25; }
.crest-name {
    font-family: var(--font-title);
    font-size: 0.82rem;
    letter-spacing: 0.03em;
    max-width: 130px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.crest-sub { font-family: var(--font-ui); font-size: 0.68rem; color: var(--accent); }

/* --- Ressources --- */
.res-cluster {
    display: flex;
    align-items: center;
    gap: 8px;
    flex: 1;
    min-width: 0;
    overflow-x: auto;
    /* **Poser `overflow-x` emporte l'axe vertical avec lui.** Des qu'un axe
       cesse d'etre `visible`, l'autre ne peut plus l'etre : la specification
       le fait passer a `auto`. Cette ligne, ecrite pour laisser defiler les
       six tuiles sur un ecran etroit, rendait donc aussi le conteneur
       rogneur EN HAUTEUR -- et les tuiles remplissent sa hauteur au pixel
       pres.

       Le survol les souleve d'un pixel (`translateY(-1px)`), qui sortait
       aussitot du cadre : le bord dore de la tuile pointee etait coupe net
       sur le dessus, et de la seule tuile pointee, ce qui se lit comme un
       defaut d'alignement plutot que comme un rognage.

       On lui donne donc la place que le survol demande, et on la reprend en
       marge negative pour que le bandeau garde exactement sa hauteur. La
       regle : *un conteneur qui defile sur un axe rogne sur les deux ; tout
       ce qui deborde de ses enfants doit tenir dans sa marge interieure.* */
    padding-block: 3px;
    margin-block: -3px;
    scrollbar-width: none;
}
.res-cluster::-webkit-scrollbar { display: none; }
.res-chip {
    position: relative;
    flex: 0 0 auto;
    min-width: 0;
    display: grid;
    grid-template-columns: 22px 1fr;
    gap: 8px;
    align-items: center;
    padding: 6px 10px;
    background: var(--surface);
    border: 1px solid var(--line-soft);
    border-radius: var(--radius-sm);
    cursor: pointer;
    transition: border-color .15s, transform .15s;
}@media (hover: hover) and (pointer: fine) {
.res-chip:hover { border-color: var(--accent); transform: translateY(-1px); }
}
.res-chip.is-gold { border-color: rgba(212, 165, 72, 0.35); }
.res-chip.no-cap { cursor: default; }@media (hover: hover) and (pointer: fine) {
.res-chip.no-cap:hover { transform: none; border-color: var(--line-soft); }
}
.res-chip-icon {
    width: 22px;
    height: 22px;
    filter: drop-shadow(0 2px 3px rgba(0,0,0,0.7));
}
.ruby-icon { filter: drop-shadow(0 0 4px rgba(207, 85, 85, 0.5)); }
.res-chip-body { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
/* Valeur sur sa ligne, débit en dessous : les grands nombres ne sont jamais tronqués */
.res-chip-line { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 6px; min-width: 0; }

#top-bar .res-chip-line span[id^="res-"] {
    flex: 1 0 100%;
    font-family: var(--font-ui);
    font-size: 0.85rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    color: var(--text-light);
    line-height: 1.1;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.res-rate {
    font-family: var(--font-ui);
    font-size: 0.64rem;
    font-variant-numeric: tabular-nums;
    color: var(--success);
    white-space: nowrap;
}

/* --- Bouton Prestige --- */
.btn-prestige {
    flex-shrink: 0;
    height: 38px;
    padding: 0 14px;
    border-radius: 10px;
    cursor: pointer;
    background: linear-gradient(180deg, #4a3a22, #2c2114);
    border: 1px solid var(--accent);
    color: var(--gold-bright);
    font-family: var(--font-title);
    font-size: 0.78rem;
    letter-spacing: 0.04em;
    display: flex;
    align-items: center;
    gap: 6px;
    transition: border-color .15s, color .15s, opacity .15s;
}@media (hover: hover) and (pointer: fine) {
.btn-prestige:hover { border-color: var(--gold-bright); }
}
.btn-prestige.disabled { opacity: .45; }

/* --- Icônes d'action --- */
.hud-actions { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
.top-bar-icon-btn {
    position: relative;
    cursor: pointer;
    font-size: 1.05rem;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    flex-shrink: 0;
    padding: 0;
    margin: 0;
    color: inherit;
    font-family: inherit;
    line-height: 1;
    background: var(--surface);
    border: 1px solid var(--line-soft);
    border-radius: 10px;
    transition: transform 0.15s, border-color 0.15s;
    /* Pas d'attente de double-tap pour zoomer, pas de voile gris au doigt. */
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
    -webkit-appearance: none;
    appearance: none;
}
/* Un effet de survol sur un element tactile coute un appui : le premier pose le
   survol, le second seulement declenche l'action. On le reserve aux pointeurs. */
@media (hover: hover) and (pointer: fine) {
    .top-bar-icon-btn:hover {
        transform: translateY(-1px);
        border-color: var(--accent);
    }
}
/* Le doigt a droit au meme retour, immediat. */
.top-bar-icon-btn:active {
    transform: scale(0.94);
    border-color: var(--accent);
}
.top-bar-icon-btn:focus-visible {
    outline: 2px solid var(--gold-bright);
    outline-offset: 2px;
}
.hud-badge {
    position: absolute;
    top: -6px;
    right: -6px;
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    box-sizing: border-box;
    border-radius: 9px;
    background: var(--accent);
    color: #1a1208;
    font-family: var(--font-ui);
    font-size: 0.65rem;
    font-weight: 700;
    line-height: 18px;
    text-align: center;
    border: 2px solid #16120d;
}
.hud-badge-dot {
    position: absolute;
    bottom: -4px;
    right: -4px;
    width: 11px;
    height: 11px;
    border-radius: 50%;
    background: var(--success);
    border: 2px solid #16120d;
}
/* Les messages non lus du salon, sur l'icone de la guilde. En BAS a droite :
   le coin haut est deja pris par l'alerte d'invitation, et les deux nouvelles
   doivent pouvoir se voir en meme temps. */
.hud-badge-chat {
    top: auto; right: -6px; bottom: -6px;
    display: flex; align-items: center; justify-content: center;
    background: var(--danger); color: #fff;
}

/* Une pastille dans un onglet ne peut pas etre posee en absolu : `.tab-btn`
   n'est pas positionne, donc elle irait s'ancrer sur la fenetre entiere. Elle
   suit donc le texte. */
.tab-badge {
    display: none; align-items: center; justify-content: center;
    min-width: 16px; height: 16px; margin-left: 5px; padding: 0 4px;
    box-sizing: border-box; border-radius: 8px; vertical-align: -0.15em;
    background: var(--danger); color: #fff;
    font-family: var(--font-ui); font-size: 0.6rem; font-weight: 700; line-height: 1;
}
.tab-badge.on { display: inline-flex; }

/* --- Buffs actifs --- */
#active-buffs-container { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
.buff-chip {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 5px 9px;
    border-radius: 999px;
    background: var(--surface);
    border: 1px solid var(--line-soft);
    font-family: var(--font-ui);
    font-size: 0.68rem;
    white-space: nowrap;
}
.buff-chip.is-bonus { border-color: rgba(116, 189, 122, 0.4); }
.buff-chip.is-malus { border-color: rgba(207, 106, 85, 0.4); }
.buff-chip .buff-mult { font-weight: 700; }
.buff-chip.is-bonus .buff-mult { color: var(--success); }
.buff-chip.is-malus .buff-mult { color: var(--danger); }
/* Un contrat n'est ni un gain ni une perte : c'est un engagement qui court, et
   le chiffre qu'il porte est un effectif, pas un multiplicateur. */
.buff-chip.is-contrat { border-color: rgba(212, 165, 72, 0.45); }
.buff-chip.is-contrat .buff-mult { color: var(--accent); }
.buff-chip.is-contrat .buff-tip-effet { color: var(--accent); }
.buff-chip .buff-time { color: var(--muted); font-variant-numeric: tabular-nums; }

/* L'infobulle d'un buff. Le multiplicateur dit de combien, jamais sur quoi :
   « x0,6 » ne dit pas si ce sont les vivres ou la pierre. */
.buff-chip { position: relative; cursor: help; }
.buff-tip {
    position: absolute; top: calc(100% + 8px);
    /* Les buffs vivent a droite du bandeau : ancrer a droite evite que
       l'infobulle sorte de l'ecran. */
    right: 0; left: auto;
    width: 250px; max-width: calc(100vw - 24px);
    display: flex; flex-direction: column; gap: 4px;
    background: var(--panel-bg); border: 1px solid var(--panel-border);
    border-radius: var(--radius-sm); padding: 10px 12px;
    box-shadow: 0 8px 22px rgba(0,0,0,.55);
    font-family: var(--font-ui); white-space: normal; text-align: left;
    opacity: 0; visibility: hidden; transform: translateY(-4px);
    transition: opacity .14s ease, transform .14s ease;
    z-index: 200; pointer-events: none;
}
.buff-chip:hover .buff-tip,
.buff-chip:focus-visible .buff-tip,
.buff-chip.ouvert .buff-tip {
    opacity: 1; visibility: visible; transform: translateY(0);
}
.buff-tip-nom {
    font-family: var(--font-title); font-size: 0.82rem; color: var(--gold-bright);
}
.buff-tip-effet { font-size: 0.74rem; font-weight: 700; }
.buff-chip.is-bonus .buff-tip-effet { color: var(--success); }
.buff-chip.is-malus .buff-tip-effet { color: var(--danger); }
.buff-tip-desc { font-size: 0.73rem; color: var(--muted); line-height: 1.5; }
.buff-tip-fin {
    font-size: 0.69rem; color: var(--muted);
    border-top: 1px solid var(--line-soft); padding-top: 5px; margin-top: 1px;
}

/* Au doigt il n'y a pas de survol : la puce s'ouvre au toucher. */
@media (hover: none) {
    .buff-chip { cursor: pointer; }
    .buff-chip:hover .buff-tip { opacity: 0; visibility: hidden; }
    .buff-chip.ouvert .buff-tip { opacity: 1; visibility: visible; transform: translateY(0); }
}

main {
    flex: 1;
    display: flex;
    padding: 20px;
    gap: 20px;
    height: calc(100vh - 80px - 70px);
}

/* 2D MAP STYLING */
/* ============================================================================
   SCENE DU VILLAGE
   Le decor garde le cadrage et les couleurs qu'il a toujours eus. Ce qui
   s'ajoute est la vie : des villageois sur les sentiers, des fumees au-dessus
   des toits, un chantier sur le batiment en travaux. Tout ce qui bouge en
   continu est fait en CSS, aucune particule n'est creee ni detruite en boucle.
   Les positions restent en pourcentage : l'editeur de l'admin est inchange.
   ========================================================================= */
#village-map {
    flex: 3;
    position: relative;
    background: #0d0b08;
    border: 3px solid var(--panel-border);
    border-radius: 8px;
    box-shadow: inset 0 0 40px rgba(0,0,0,0.8), 3px 3px 10px rgba(0,0,0,0.5);
    overflow: hidden;
    aspect-ratio: 1 / 1;
    max-height: calc(100vh - 150px);
}

#vm-ground {
    position: absolute;
    inset: 0;
}

#vm-floor {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    user-select: none;
    -webkit-user-drag: none;
    transition: opacity 0.8s ease;
}

/* Le dessin ne remplit pas sa boite : il s'y inscrit. On lui donne donc un
   conteneur a sa taille exacte, pour que les echafaudages, les flammes et les
   fumees tombent sur le batiment et non a cote. */
.building-sprite {
    position: absolute;
    width: 150px;
    height: 150px;
    display: none;
    z-index: 10;
    transition: opacity 0.5s ease-in-out;
}

/* Le rendu calcule la taille de ce conteneur : le dessin s'inscrit dans la boite
   reglee par l'admin en gardant son rapport, et le conteneur epouse exactement
   le dessin. Les calques posés dedans tombent donc sur le batiment.
   aspect-ratio ne suffirait pas : quand c'est la hauteur qui borne, la largeur
   ne se reduit pas et le rapport est perdu. */
.bs-art {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    width: 100%;
    height: 100%;
    line-height: 0;
}

.building-sprite img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: contain;
    filter: drop-shadow(0 8px 15px rgba(0,0,0,0.6));
    transition: transform 0.3s, filter 0.3s;
    user-select: none;
    -webkit-user-drag: none;
}

.building-sprite.clickable img { cursor: pointer; }@media (hover: hover) and (pointer: fine) {
.building-sprite.clickable:hover img {
    transform: scale(1.08) translateY(-5px);
    filter: drop-shadow(0 15px 25px rgba(0,0,0,0.8));
}
}

#vm-weather {
    position: absolute;
    inset: 0;
    pointer-events: none;
    overflow: hidden;
}

/* --- Villageois -------------------------------------------------------------
   Le personnage occupe x 89..165 et y 35..213 dans une case de 256 px. On ancre
   donc l'echelle sur ses pieds : il reste plante au sol quelle que soit sa
   taille.

   **Rien ici ne s'anime autrement que par `transform`**, et c'est tout le
   sujet : la puce graphique joue seule une translation, alors qu'une position
   ou un fond qu'on fait defiler se recalcule et se repeint a chaque image. Le
   villageois se deplace par une animation posee sur `.vm-walker` (village.js),
   et son pas fait glisser une bande de trente images dans une fenetre de
   256 px -- la bande entiere derriere un cadre fixe, plutot qu'un fond qui
   defile. L'ombre est cuite dans les images de marche : un `drop-shadow`
   recalcule a chaque pas coutait plus cher que le personnage lui-meme. */
.vm-walker {
    position: absolute;
    left: 0; top: 0;
    pointer-events: none;
    z-index: 9;
    will-change: transform;
}

.vm-walker i {
    position: absolute;
    left: -127px;
    top: -213px;
    display: block;
    width: 256px;
    height: 256px;
    overflow: hidden;
    transform: scale(var(--walker-s, 0.15));
}
.vm-walker i::before {
    content: '';
    position: absolute;
    left: 0; top: 0;
    width: 7680px; height: 256px;
    background: var(--walk) no-repeat;
    animation: walkBande 1.3s steps(30) infinite;
    animation-delay: var(--walk-delay, 0s);
}
@keyframes walkBande {
    to { transform: translateX(-7680px); }
}

/* Le decor en pause quand personne ne le voit (village.js, majPause) : la
   feuille des batiments tiree par-dessus, une fenetre, la carte. Les
   animations s'arretent la ou elles sont et reprennent de la. */
#village-map.vm-pause *,
#village-map.vm-pause *::before,
#village-map.vm-pause *::after {
    animation-play-state: paused !important;
}

/* --- Ambiance des batiments -------------------------------------------------
   Trois particules fixes par source, decalees dans le temps : rien n'est cree
   ni detruit pendant que le jeu tourne. */
.vm-fx {
    position: absolute;
    width: 0;
    height: 0;
    pointer-events: none;
}

.vm-fx span {
    position: absolute;
    display: block;
    border-radius: 50%;
    will-change: transform, opacity;
}

.vm-fx-smoke span {
    width: 13px; height: 13px; margin: -7px 0 0 -7px;
    background: radial-gradient(circle, rgba(232,226,214,0.55), rgba(232,226,214,0) 70%);
    animation: vmSmoke 4.5s linear infinite;
}
@keyframes vmSmoke {
    0%   { transform: translate(0, 0) scale(0.35); opacity: 0; }
    18%  { opacity: 0.7; }
    100% { transform: translate(-15px, -46px) scale(2.2); opacity: 0; }
}

.vm-fx-dust span {
    width: 17px; height: 10px; margin: -5px 0 0 -9px; border-radius: 50%;
    background: radial-gradient(ellipse, rgba(216,198,162,0.5), rgba(216,198,162,0) 70%);
    animation: vmDust 5.2s linear infinite;
}
@keyframes vmDust {
    0%   { transform: translate(0, 0) scale(0.3); opacity: 0; }
    22%  { opacity: 0.55; }
    100% { transform: translate(9px, -21px) scale(1.8); opacity: 0; }
}

.vm-fx-sparks span {
    width: 3px; height: 3px; margin: -2px 0 0 -2px;
    background: #ffd28a;
    box-shadow: 0 0 6px 1px rgba(255,150,50,0.85);
    animation: vmSpark 1.8s ease-out infinite;
}
@keyframes vmSpark {
    0%   { transform: translate(0, 0) scale(1); opacity: 0; }
    12%  { opacity: 1; }
    100% { transform: translate(11px, -25px) scale(0.2); opacity: 0; }
}

/* --- Meteo ------------------------------------------------------------------
   Des degrades repetes qu'on fait defiler : pas une seule particule en DOM. */
/* La pluie et la neige sont des couches de motif qu'on fait glisser par
   `transform`, une couche par motif : chacune garde sa taille, son angle et sa
   vitesse d'origine. Elles faisaient defiler `background-position`, ce qui
   repeignait tout le village a chaque image, une heure sur cinq. Chaque couche
   deborde du cadre d'un peu plus que son pas, pour que le glissement ne
   decouvre jamais de bord. setWeather (village.js) pose les couches. */
#vm-weather > i {
    position: absolute;
    display: block;
    top: -230px; bottom: 0; left: -50px; right: -50px;
    will-change: transform;
    animation-timing-function: linear;
    animation-iteration-count: infinite;
}

#village-map.vm-rain #vm-weather { opacity: 0.75; }
/* Les couches sont dans l'ordre de la pile : la derniere est dessus, comme la
   premiere d'une liste de fonds. */
#village-map.vm-rain #vm-weather > i:nth-child(1) {
    background-image: repeating-linear-gradient(101deg, rgba(190,215,235,0) 0 11px, rgba(190,215,235,0.18) 11px 12px, rgba(190,215,235,0) 12px 23px);
    background-size: 170px 220px;
    animation-name: vmPluie2; animation-duration: 0.6s;
}
#village-map.vm-rain #vm-weather > i:nth-child(2) {
    background-image: repeating-linear-gradient(104deg, rgba(190,215,235,0) 0 6px, rgba(190,215,235,0.30) 6px 7px, rgba(190,215,235,0) 7px 13px);
    background-size: 110px 140px;
    animation-name: vmPluie1; animation-duration: 0.6s;
}
@keyframes vmPluie1 { to { transform: translate(-34px, 140px); } }
@keyframes vmPluie2 { to { transform: translate(-44px, 220px); } }

#village-map.vm-snow #vm-weather > i { animation-duration: 9s; }
#village-map.vm-snow #vm-weather > i:nth-child(1) {
    background-image: radial-gradient(circle at 8% 84%, rgba(255,255,255,0.5) 0 1.2px, rgba(255,255,255,0.1) 2.3px, transparent 3.4px);
    background-size: 200px 200px; animation-name: vmNeige5;
}
#village-map.vm-snow #vm-weather > i:nth-child(2) {
    background-image: radial-gradient(circle at 84% 58%, rgba(255,255,255,0.55) 0 0.9px, rgba(255,255,255,0.12) 1.7px, transparent 2.5px);
    background-size: 70px 70px; animation-name: vmNeige4;
}
#village-map.vm-snow #vm-weather > i:nth-child(3) {
    background-image: radial-gradient(circle at 41% 71%, rgba(255,255,255,0.6) 0 1.4px, rgba(255,255,255,0.14) 2.6px, transparent 3.8px);
    background-size: 160px 160px; animation-name: vmNeige3;
}
#village-map.vm-snow #vm-weather > i:nth-child(4) {
    background-image: radial-gradient(circle at 63% 34%, rgba(255,255,255,0.68) 0 1px, rgba(255,255,255,0.16) 2px, transparent 2.9px);
    background-size: 130px 130px; animation-name: vmNeige2;
}
#village-map.vm-snow #vm-weather > i:nth-child(5) {
    background-image: radial-gradient(circle at 18% 12%, rgba(255,255,255,0.72) 0 1.1px, rgba(255,255,255,0.18) 2.2px, transparent 3.2px);
    background-size: 90px 90px; animation-name: vmNeige1;
}
@keyframes vmNeige1 { to { transform: translate(22px, 90px); } }
@keyframes vmNeige2 { to { transform: translate(-26px, 130px); } }
@keyframes vmNeige3 { to { transform: translate(12px, 160px); } }
@keyframes vmNeige4 { to { transform: translate(-14px, 70px); } }
@keyframes vmNeige5 { to { transform: translate(30px, 200px); } }

#village-map.vm-fog #vm-weather {
    background:
        radial-gradient(ellipse 62% 28% at 28% 58%, rgba(226,232,238,0.5), transparent 72%),
        radial-gradient(ellipse 72% 22% at 74% 40%, rgba(222,230,238,0.42), transparent 72%),
        radial-gradient(ellipse 85% 32% at 50% 84%, rgba(226,232,238,0.46), transparent 72%),
        linear-gradient(180deg, rgba(220,228,236,0.16), rgba(220,228,236,0.3));
    animation: vmFog 34s ease-in-out infinite alternate;
}
@keyframes vmFog {
    from { transform: translate3d(-4%, 0, 0) scale(1.04); }
    to   { transform: translate3d(4%, -2%, 0) scale(1.12); }
}

/* --- Retours de jeu --------------------------------------------------------- */

/* Chantier : le marteau et la teinte d'origine. */
.construction-hammer {
    position: absolute;
    top: 30%;
    right: 25%;
    font-size: 36px;
    z-index: 100;
    animation: tapHammer 0.5s infinite alternate;
}
.building-upgrading {
    filter: grayscale(80%) sepia(50%) brightness(70%);
    pointer-events: none;
}

/* Un batiment endommage : il fume et brule vraiment, au lieu d'afficher 🔥. */
.building-sprite img.vm-ruined { filter: drop-shadow(0 10px 14px rgba(0,0,0,0.6)) grayscale(0.75) brightness(0.62); }

.vm-fire {
    position: absolute;
    left: 50%; top: 32%;
    width: 0; height: 0;
    pointer-events: none;
}
.vm-fire span {
    position: absolute;
    display: block;
    width: 16px; height: 22px;
    margin: -11px 0 0 -8px;
    border-radius: 50% 50% 46% 46%;
    background: radial-gradient(ellipse at 50% 80%, #ffd24a 0%, #ff8a2b 42%, rgba(200,50,10,0) 78%);
    filter: blur(0.4px);
    animation: vmFlame 1.1s ease-in-out infinite;
    will-change: transform, opacity;
}
.vm-fire span:nth-child(2) { margin-left: -20px; transform: scale(0.75); }
.vm-fire span:nth-child(3) { margin-left: 5px; transform: scale(0.85); }
@keyframes vmFlame {
    0%, 100% { transform: translateY(0) scaleY(1) scaleX(1); opacity: 0.92; }
    35%      { transform: translateY(-7px) scaleY(1.28) scaleX(0.85); opacity: 1; }
    70%      { transform: translateY(-3px) scaleY(0.92) scaleX(1.1); opacity: 0.8; }
}
.building-sprite.vm-levelup img { animation: vmLevelUp 0.9s cubic-bezier(.2,.9,.25,1); }
@keyframes vmLevelUp {
    0%   { transform: translateY(0) scale(1); filter: drop-shadow(0 10px 14px rgba(0,0,0,0.55)); }
    30%  { transform: translateY(-14px) scale(1.09); filter: drop-shadow(0 22px 20px rgba(0,0,0,0.6)) brightness(1.5); }
    60%  { transform: translateY(2px) scale(0.985); }
    100% { transform: translateY(0) scale(1); filter: drop-shadow(0 10px 14px rgba(0,0,0,0.55)); }
}

@media (prefers-reduced-motion: reduce) {
    .vm-walker i::before, .vm-fx span, #vm-weather, #vm-weather > i { animation: none !important; }
    .building-sprite.vm-levelup img { animation: none !important; }
    .vm-fire span { animation: none !important; }
}

@media (max-width: 900px) {
    #village-map { --walker-s: 0.13; }
}

#sprite-market { top: 8%; left: 5%; width: 30%; height: 30%; }
#sprite-lumbermill { top: 35%; left: 2%; width: 30%; height: 30%; }
#sprite-quarry { top: 60%; left: 10%; width: 28%; height: 28%; }
#sprite-academy { top: 15%; left: 25%; width: 32%; height: 32%; }
#sprite-farm { top: 15%; left: 55%; width: 30%; height: 30%; }
#sprite-goldmine { top: 5%; left: 70%; width: 28%; height: 28%; }
#sprite-ironmine { top: 35%; left: 70%; width: 28%; height: 28%; }
#sprite-guild { top: 45%; left: 20%; width: 30%; height: 30%; }
#sprite-barracks { top: 60%; left: 45%; width: 32%; height: 32%; }
#sprite-siegeworkshop { top: 50%; left: 70%; width: 30%; height: 30%; }

/* SIDEBAR PANELS */
#ui-panels {
    flex: 1;
    min-width: 300px;
    max-width: 400px;
    display: flex;
    flex-direction: column;
    gap: 20px;
    overflow-y: auto;
    padding-right: 10px; /* space for scrollbar */
    /* La barre des travaux est fixee en bas de l'ecran, PAR-DESSUS le panneau :
       sans cette marge, le bas de l'onglet le plus long (Population) restait
       cache dessous, defilement au maximum. Meme mesure que la feuille du
       telephone, qui reserve deja cette place. */
    padding-bottom: calc(var(--hauteur-travaux, 0px) + 10px);
}

/* Custom scrollbar for sidebar */
#ui-panels::-webkit-scrollbar { width: 8px; }
#ui-panels::-webkit-scrollbar-track { background: var(--bg-color); }
#ui-panels::-webkit-scrollbar-thumb { background: var(--panel-border); border-radius: 4px; }

#build-menu h2 {
    color: var(--accent);
    border-bottom: 2px solid var(--accent);
    padding-bottom: 5px;
    text-align: center;
    margin-bottom: 15px;
}

#build-menu, #construction-panel, #controls-panel {
    background-color: var(--panel-bg);
    color: var(--text-dark);
    border: 3px solid var(--panel-border);
    border-radius: 8px;
    padding: 15px;
    box-shadow: 3px 3px 10px rgba(0,0,0,0.5);
}

#buildings-container {
    display: flex;
    flex-direction: column;
    gap: 15px;
}

/* INPUTS & SELECTS */
input[type="number"], input[type="text"], input[type="password"] {
    background: rgba(255,255,255,0.7);
    border: 1px solid var(--panel-border);
    padding: 5px;
    font-family: 'Georgia', serif;
    border-radius: 3px;
    font-size: 1rem;
}

select {
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="%233a2512"><path d="M7 10l5 5 5-5z"/></svg>') no-repeat right 10px center;
    background-color: #f5eedc;
    color: #3a2512;
    border: 2px solid #8b5a2b;
    padding: 10px 35px 10px 10px;
    font-family: 'Cinzel', serif;
    font-size: 1rem;
    font-weight: bold;
    border-radius: 5px;
    cursor: pointer;
    box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
    transition: all 0.3s ease;
}@media (hover: hover) and (pointer: fine) {
select:hover {
    border-color: #5c3a21;
}
}
select:focus {
    outline: none;
    border-color: #d4af37;
    box-shadow: 0 0 8px rgba(212, 175, 55, 0.6), inset 0 0 5px rgba(0,0,0,0.2);
}
select option {
    background-color: #f5eedc;
    color: #3a2512;
    font-family: 'Georgia', serif;
    font-weight: bold;
}

/* Make building cards smaller for the sidebar */
.building-card {
    background: var(--surface);
    border: 1px solid var(--line-soft);
    border-radius: var(--radius);
    padding: 12px;
    margin-bottom: 10px;
}

.building-card.is-building { border-color: #4a3a22; }

.building-header {
    display: flex;
    align-items: center;
    gap: 10px;
}

.building-header h3 {
    font-size: 0.92rem;
    margin: 0;
    flex: 1;
    letter-spacing: 0.01em;
}

.building-level {
    background: rgba(212, 165, 72, 0.12);
    color: var(--gold-bright);
    padding: 3px 9px;
    border-radius: 999px;
    font-weight: 700;
    font-size: 0.7rem;
    font-family: var(--font-ui);
    border: 1px solid rgba(212, 165, 72, 0.35);
    white-space: nowrap;
}

/* La description textuelle est redondante avec la ligne de production : on la masque. */
.building-desc { display: none; }

.building-prod {
    margin-top: 8px;
    font-family: var(--font-ui);
    font-size: 0.78rem;
    color: var(--success);
    display: flex;
    align-items: center;
    gap: 5px;
    flex-wrap: wrap;
}
.building-prod .prod-bonus { color: var(--muted); }

.upgrade-costs {
    margin: 9px 0 0;
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    align-items: center;
}

.cost-item {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    background: var(--surface-2);
    border: 1px solid var(--line-soft);
    padding: 4px 8px;
    border-radius: 6px;
    font-family: var(--font-ui);
    font-size: 0.72rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    color: var(--text-light);
}

.cost-item.cost-time {
    margin-left: auto;
    background: transparent;
    border: 0;
    color: var(--muted);
    padding-right: 0;
}

.insufficient {
    color: var(--danger) !important;
    font-weight: 600;
}
.cost-item.insufficient { border-color: rgba(207, 106, 85, 0.35); }

.prod-full { color: var(--danger); font-weight: 700; }
.prod-idle { color: var(--highlight); }

.building-maxed {
    margin-top: 10px;
    padding: 8px 0;
    text-align: center;
    font-family: var(--font-ui);
    font-size: 0.78rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    color: var(--gold-bright);
    background: rgba(212, 165, 72, 0.08);
    border: 1px dashed rgba(212, 165, 72, 0.4);
    border-radius: var(--radius-sm);
}

.building-card.is-damaged { border-color: rgba(207, 106, 85, 0.55); }
.building-damaged-note {
    margin-top: 8px;
    font-family: var(--font-ui);
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--danger);
}
.btn-repair {
    background: linear-gradient(180deg, #b5583f, #8d3f2c);
    border-color: #d7836b;
    color: #fff;
}@media (hover: hover) and (pointer: fine) {
.btn-repair:hover:not(:disabled) { background: linear-gradient(180deg, #c76a50, #9c4a34); }
}

.btn-upgrade {
    width: 100%;
    background: linear-gradient(180deg, #d9ad51, #b5893a);
    color: #1c1408;
    border: 1px solid #eac57a;
    padding: 8px 6px;
    font-family: var(--font-ui);
    font-size: 0.82rem;
    font-weight: 700;
    cursor: pointer;
    border-radius: var(--radius-sm);
    transition: background 0.15s, transform 0.1s;
}@media (hover: hover) and (pointer: fine) {
.btn-upgrade:hover:not(:disabled) {
    background: linear-gradient(180deg, #e6bb63, #c2953f);
}
}

/* Bouton indisponible : lisible et explicite plutôt qu'un bloc gris muet */
.btn-upgrade:disabled {
    background: transparent;
    color: var(--muted);
    border: 1px solid var(--panel-border);
    cursor: not-allowed;
}

.btn-action-panel {
    background: var(--surface-2);
    color: var(--text-light);
    border-color: var(--panel-border);
    margin-top: 8px;
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.1), 0 2px 4px rgba(0,0,0,0.4);
    text-shadow: 0 1px 2px rgba(0,0,0,0.8);
}@media (hover: hover) and (pointer: fine) {
.btn-action-panel:hover:not(:disabled) {
    background: var(--surface-3);
    border-color: var(--accent);
}
}

/* Controls */
.sidebar-group {
    display: flex;
    flex-direction: column;
    gap: 20px;
}

#construction-panel h2, #guild-panel h2 {
    color: var(--accent);
    border-bottom: 2px solid var(--accent);
    padding-bottom: 5px;
    text-align: center;
    margin-bottom: 10px;
}

.active-construction-item {
    display: flex;
    align-items: center;
    gap: 10px;
    background: var(--surface);
    padding: 6px 12px;
    border: 1px solid var(--line-soft);
    border-radius: 999px;
    flex-shrink: 0;
    font-family: var(--font-ui);
    font-size: 0.74rem;
}

.ac-name {
    font-weight: 600;
    white-space: nowrap;
}

.progress-bar-container {
    width: 90px;
    height: 6px;
    background: #0c0a07;
    border-radius: 3px;
    overflow: hidden;
}

.construction-progress {
    height: 100%;
    background: linear-gradient(90deg, #8a6a2c, var(--gold-bright));
    width: 0%;
    border-radius: 3px;
    /* Pas de transition sur la largeur : la barre est reecrite dix fois par
       seconde, donc une transition de 0,1 s ne finissait jamais -- et animer
       `width` recalcule la mise en page de toute la page a chaque image.
       C'etait, a elle seule, un telephone occupe en continu. */
}

.construction-time {
    font-variant-numeric: tabular-nums;
    font-size: 0.72rem;
    color: var(--accent);
    white-space: nowrap;
}

#controls-panel { display: flex; flex-direction: column; }
/* Les boutons du menu Systeme sont styles par .sys-tuile, .sys-ligne et
   .sys-mini : des regles portees par un identifiant gagneraient sur eux. */

/* ANIMATIONS DE PRODUCTION */
.floating-text {
    position: absolute;
    color: #fff;
    font-size: 1.5rem;
    font-family: var(--font-title);
    font-weight: bold;
    text-shadow: 2px 2px 5px rgba(0,0,0,0.9), -1px -1px 2px rgba(0,0,0,0.5);
    pointer-events: none;
    z-index: 50;
    transform: translateX(-50%);
    animation: floatUp 2s ease-out forwards;
}

@keyframes floatUp {
    0% { transform: translate(-50%, 0) scale(0.5); opacity: 0; }
    15% { transform: translate(-50%, -15px) scale(1.2); opacity: 1; }
    80% { transform: translate(-50%, -50px) scale(1); opacity: 1; }
    100% { transform: translate(-50%, -60px) scale(0.8); opacity: 0; }
}

/* NOUVEAUX BÃ‚TIMENTS ET MODALES */

.clickable { cursor: pointer; }

#modal-overlay {
    position: fixed; top: 0; left: 0; right: 0; bottom: 0;
    background: rgba(0,0,0,0.8); z-index: 100;
}

.modal {
    position: fixed; top: 50%; left: 50%;
    transform: translate(-50%, -50%);
    background: var(--panel-bg);
    border: 2px solid var(--panel-border);
    border-radius: 12px; padding: 20px;
    width: 95%; max-width: 600px;
    max-height: 90vh;
    box-sizing: border-box;
    z-index: 101; color: var(--text-dark);
    box-shadow: 0 10px 40px rgba(0,0,0,0.9), inset 0 0 20px rgba(212,165,72,0.05);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    overflow: hidden;
}

.modal-content {
    max-height: calc(90vh - 100px);
    overflow-y: auto;
    padding-right: 5px;
}
.modal-content::-webkit-scrollbar { width: 8px; }
.modal-content::-webkit-scrollbar-track { background: rgba(0,0,0,0.1); border-radius: 4px; }
.modal-content::-webkit-scrollbar-thumb { background: var(--accent); border-radius: 4px; }

.custom-scrollbar::-webkit-scrollbar { width: 8px; height: 8px; }
.custom-scrollbar::-webkit-scrollbar-track { background: rgba(0,0,0,0.3); border-radius: 4px; border: 1px solid var(--panel-border); }
.custom-scrollbar::-webkit-scrollbar-thumb { background: var(--accent); border-radius: 4px; border: 1px solid var(--highlight); }

#chat-messages::-webkit-scrollbar { width: 8px; }
#chat-messages::-webkit-scrollbar-track { background: rgba(0,0,0,0.3); border-radius: 4px; border: 1px solid var(--panel-border); }
#chat-messages::-webkit-scrollbar-thumb { background: var(--accent); border-radius: 4px; border: 1px solid var(--highlight); }

.modal-close {
    position: absolute; top: 10px; right: 10px;
    background: var(--danger); color: white;
    border: none; border-radius: 50%;
    width: 30px; height: 30px;
    font-weight: bold; cursor: pointer;
}

.modal h1, .modal h2, .modal h3, .modal h4 { 
    color: var(--accent); 
    text-shadow: none; 
}
.modal h2 { text-align: center; border-bottom: 2px solid var(--accent); padding-bottom: 10px; margin-bottom: 20px; }

/* Academy Tech Tree (Modern Redesign) */
.tech-tier-header {
    background: linear-gradient(90deg, rgba(30,40,50,0) 0%, rgba(50,70,90,0.8) 50%, rgba(30,40,50,0) 100%);
    color: var(--accent);
    text-align: center;
    padding: 10px;
    margin: 25px 0 15px 0;
    font-family: 'Cinzel', serif;
    font-size: 1.4rem;
    font-weight: bold;
    border-top: 1px solid rgba(255,170,0,0.3);
    border-bottom: 1px solid rgba(255,170,0,0.3);
    text-shadow: 0 2px 4px rgba(0,0,0,0.8);
}

.tech-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 15px;
}

.tech-card {
    position: relative;
    background: linear-gradient(to bottom, rgba(40,50,60,0.9), rgba(20,30,40,0.95));
    border: 1px solid var(--panel-border);
    border-radius: 10px;
    padding: 15px;
    display: flex;
    flex-direction: column;
    align-items: center;
    transition: transform 0.2s, box-shadow 0.2s;
    box-shadow: inset 0 0 15px rgba(0,0,0,0.8), 0 4px 6px rgba(0,0,0,0.5);
    overflow: hidden;
}@media (hover: hover) and (pointer: fine) {
.tech-card:hover {
    transform: translateY(-2px);
    box-shadow: inset 0 0 15px rgba(0,0,0,0.8), 0 6px 12px rgba(0,0,0,0.6);
}
}

.tech-card.unlocked {
    border-color: #ffaa00;
    background: linear-gradient(to bottom, rgba(50,60,40,0.9), rgba(30,40,20,0.95));
    box-shadow: inset 0 0 20px rgba(255,170,0,0.1), 0 0 8px rgba(255,170,0,0.3);
}

.tech-card.locked {
    filter: grayscale(80%) brightness(0.6);
}

.tech-card.researching {
    border-color: var(--accent);
    animation: tech-pulse 2s infinite alternate;
}

@keyframes tech-pulse {
    0% { box-shadow: 0 0 5px rgba(0, 170, 255, 0.2); }
    100% { box-shadow: 0 0 15px rgba(0, 170, 255, 0.6); }
}

.tech-title {
    font-family: 'Cinzel', serif;
    font-size: 1.1rem;
    font-weight: bold;
    color: #fff;
    margin-bottom: 5px;
    text-align: center;
    text-shadow: 0 1px 3px rgba(0,0,0,0.8);
}

.tech-desc {
    font-size: 0.85rem;
    color: #bbb;
    text-align: center;
    margin-bottom: 15px;
    flex-grow: 1;
}

.tech-costs {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    justify-content: center;
    margin-bottom: 5px;
    width: 100%;
}

.tech-res-item {
    font-size: 0.95rem;
    font-weight: bold;
    display: flex;
    align-items: center;
    gap: 4px;
    text-shadow: 1px 1px 3px rgba(0,0,0,0.9);
}

.tech-time {
    font-size: 0.85rem;
    color: #aaccff;
    margin-bottom: 15px;
    font-style: italic;
    display: flex;
    align-items: center;
    gap: 5px;
    justify-content: center;
    width: 100%;
    text-shadow: 1px 1px 2px rgba(0,0,0,0.8);
}

.tech-btn {
    width: 100%;
    padding: 8px;
    font-size: 0.9rem;
    background: linear-gradient(180deg, #d9ad51, #b5893a);
    border: 1px solid #eac57a;
    border-radius: var(--radius-sm);
    color: #1c1408;
    font-weight: 700;
    cursor: pointer;
    font-family: var(--font-ui);
}

.tech-btn:disabled {
    background: transparent;
    border-color: var(--panel-border);
    color: var(--muted);
    cursor: not-allowed;
}

.tech-unlocked-badge {
    color: #ffaa00;
    font-weight: bold;
    font-size: 1rem;
    margin-top: auto;
    text-shadow: 0 1px 3px rgba(0,0,0,0.8);
}

.tech-lock-icon {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    font-size: 3rem;
    opacity: 0.5;
    pointer-events: none;
}

.tech-progress-container {
    width: 100%;
    height: 6px;
    background: rgba(0,0,0,0.6);
    border-radius: 3px;
    margin-top: 10px;
    overflow: hidden;
}

.tech-progress-bar {
    height: 100%;
    background: linear-gradient(90deg, #8a6a2c, var(--gold-bright));
    /* Reecrite chaque seconde : une transition d'une seconde tournait donc sans
       fin (voir .construction-progress). */
}

.market-controls {
    display: flex; gap: 10px; align-items: center; justify-content: center;
    background: rgba(0,0,0,0.2); padding: 20px; border-radius: 8px;
    margin-top: 15px;
}
.market-controls select, .market-controls input {
    padding: 8px; border-radius: 5px; border: 1px solid #777; background: #eee;
}

/* La boite des messages : showAlert et showConfirmModal. Elle portait encore
   l'habillage d'avant la refonte des fenetres -- degrade violet, titre centre en
   capitales geantes, texte en anglaise, bouton pleine largeur de 1,1 em -- et
   occupait un tiers d'ecran de telephone pour deux phrases. Elle reprend le
   gabarit des fenetres du jeu (.mil-modal) : titre a gauche avec la croix,
   texte en police de lecture, boutons en pied. */
.event-alert {
    position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%);
    width: min(400px, calc(100vw - 32px));
    max-height: calc(100vh - 48px);
    max-height: calc(100dvh - 48px);
    overflow-y: auto;
    box-sizing: border-box;
    /* Opaque, et le voile est son ombre : elle s'ouvre souvent PAR-DESSUS une
       autre fenetre (la Caserne, apres un assaut), que #modal-overlay ne couvre
       pas -- il vit sous les fenetres. Le fond translucide des modales laissait
       lire les boutons d'en dessous a travers le message. */
    background: #1a1510;
    border: 2px solid var(--panel-border);
    border-radius: var(--radius);
    box-shadow: 0 0 0 100vmax rgba(0,0,0,0.6), 0 18px 50px rgba(0,0,0,0.85), inset 0 0 20px rgba(212,165,72,0.05);
    padding: 14px 16px 16px;
    z-index: 10005;
    color: var(--text-light);
    font-family: var(--font-ui);
    text-align: left;
    animation: popInAlert 0.22s ease-out;
}
.alr-tete {
    display: flex; align-items: center; gap: 10px;
    padding-bottom: 10px; border-bottom: 1px solid var(--line-soft);
}
.alr-tete h3 {
    flex: 1; min-width: 0; margin: 0;
    font-family: var(--font-title); font-size: 1rem; font-weight: 700;
    color: var(--gold-bright); line-height: 1.3; text-wrap: balance;
}
.alr-corps {
    margin: 12px 0 16px;
    font-size: 0.86rem; line-height: 1.55; color: var(--text-light);
    overflow-wrap: anywhere;
}
.alr-corps b { color: var(--gold-bright); }
/* Une ligne a part dans le message : le bouclier leve, un bonus recu. */
.alr-note {
    display: flex; align-items: center; gap: 8px;
    margin-top: 10px; padding: 8px 10px;
    background: var(--surface-2); border: 1px solid var(--line-soft); border-radius: var(--radius-sm);
    font-size: 0.8rem; color: var(--muted);
}
.alr-note .mg-ic { width: 16px; height: 16px; flex-shrink: 0; }
.alr-pied { display: flex; gap: 8px; }
.alr-pied .btn-bar { flex: 1; min-width: 0; }
.btn-bar.alr-second { background: transparent; border-color: var(--panel-border); color: var(--text-light); }
@media (hover: hover) and (pointer: fine) {
    .btn-bar.alr-second:hover:not(:disabled) { background: var(--surface-2); border-color: var(--accent); }
}
@keyframes popInAlert {
    from { opacity: 0; transform: translate(-50%, -48%) scale(0.97); }
    to { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}

/* SIDEBAR TABS */
/* Onglets : contrôle segmenté unique (plus de pastilles de styles différents) */
.sidebar-tabs {
    display: flex;
    gap: 2px;
    margin-bottom: 12px;
    padding: 3px;
    background: var(--surface);
    border: 1px solid var(--line-soft);
    border-radius: 10px;
}
.tab-btn {
    flex: 1 1 0;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    padding: 8px 4px;
    background: transparent;
    border: 0;
    border-radius: 7px;
    color: var(--muted);
    cursor: pointer;
    font-family: var(--font-ui);
    font-size: 0.8rem;
    font-weight: 600;
    transition: color .15s, background .15s;
}@media (hover: hover) and (pointer: fine) {
.tab-btn:hover { color: var(--text-light); }
}
.tab-btn.active {
    background: var(--surface-3);
    color: var(--gold-bright);
    box-shadow: inset 0 0 0 1px var(--panel-border);
}
.tab-content { display: none; }
.tab-content.active { display: block; }
.market-tab { display: none; }
.market-tab.active { display: block; }

/* NOTIFICATION CLIGNOTANTE */
.map-event-icon {
    position: absolute;
    top: -15px;
    right: -15px;
    background: #e74c3c;
    border-radius: 50%;
    width: 25px;
    height: 25px;
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: 14px;
    animation: pulse 1.5s infinite;
    z-index: 5;
    cursor: pointer;
    box-shadow: 0 0 10px #e74c3c;
}

@keyframes blink {
    0% { opacity: 1; }
    50% { opacity: 0.2; }
    100% { opacity: 1; }
}

.market-notification {
    position: absolute;
    top: 25%;
    right: 25%;
    background-color: var(--danger);
    color: #fff;
    font-size: 14px;
    font-weight: bold;
    padding: 2px 8px;
    border-radius: 50%;
    border: 2px solid #c0392b;
    box-shadow: 0 0 10px #e74c3c;
    animation: pulseGlow 1s infinite alternate;
    z-index: 110;
}
@keyframes pulseGlow {
    0% { transform: scale(1); box-shadow: 0 0 5px #e74c3c; }
    100% { transform: scale(1.2); box-shadow: 0 0 15px #ff7675; }
}

/* ANIMATION CONSTRUCTION */

@keyframes tapHammer {
    0% { transform: rotate(0deg); }
    100% { transform: rotate(-45deg) translateY(5px); }
}


/* SCOREBOARD PREMIUM MODAL */
.scoreboard-table-premium { width: 100%; border-collapse: collapse; font-size: 1rem; }
.scoreboard-table-premium th, .scoreboard-table-premium td { padding: 12px 10px; text-align: center; border-bottom: 1px solid rgba(255, 170, 0, 0.2); }
.scoreboard-table-premium th { color: #ffaa00; font-family: 'Cinzel', serif; font-size: 1.1rem; text-transform: uppercase; letter-spacing: 1px; }
.scoreboard-table-premium tr { transition: background 0.3s; }
.scoreboard-table-premium tr:nth-child(even) { background: rgba(255, 255, 255, 0.03); }@media (hover: hover) and (pointer: fine) {
.scoreboard-table-premium tr:hover { background: rgba(255, 170, 0, 0.15); box-shadow: inset 0 0 10px rgba(255, 170, 0, 0.2); }
}
.scoreboard-table-premium td:nth-child(2) { text-align: left; font-weight: bold; color: #f5eedc; font-size: 1.1rem; }

.btn-tab-premium { background: rgba(0,0,0,0.5); border: 1px solid #555; color: #ccc; padding: 10px 20px; font-family: 'Cinzel', serif; font-weight: bold; font-size: 1.1rem; cursor: pointer; border-radius: 5px; transition: all 0.3s; }@media (hover: hover) and (pointer: fine) {
.btn-tab-premium:hover { background: rgba(255,170,0,0.2); color: #fff; border-color: #ffaa00; }
}
.btn-tab-premium.active { background: rgba(255,170,0,0.2); color: #ffaa00; border-color: #ffaa00; box-shadow: 0 0 10px rgba(255,170,0,0.4); text-shadow: 0 0 5px #ffaa00; }

/* SCOREBOARD */
.scoreboard-table { width: 100%; border-collapse: collapse; margin-top: 10px; font-size: 0.9rem; }
.scoreboard-table th, .scoreboard-table td { padding: 8px 5px; text-align: center; border-bottom: 1px solid var(--panel-border); }
.scoreboard-table th { color: gold; font-family: 'Cinzel', serif; }
.scoreboard-table tr:nth-child(even) { background: rgba(255,255,255,0.05); }@media (hover: hover) and (pointer: fine) {
.scoreboard-table tr:hover { background: rgba(255,255,255,0.1); }
}
.scoreboard-table td:nth-child(2) { text-align: left; font-weight: bold; }

/* BOTTOM TASKBAR */
#bottom-taskbar {
    position: fixed;
    bottom: 0;
    left: 0;
    width: 100%;
    box-sizing: border-box;
    height: 56px;
    background: linear-gradient(180deg, #1c1611, #14100c);
    border-top: 1px solid var(--panel-border);
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 0 16px;
    z-index: 50;
    box-shadow: 0 -6px 20px rgba(0,0,0,0.5);
    transform: translateY(100%);
    transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
#bottom-taskbar.visible { transform: translateY(0); }
#bottom-taskbar.collapsed { transform: translateY(100%); }
#taskbar-tab {
    position: absolute;
    top: -26px;
    left: 16px;
    background: var(--surface-2);
    color: var(--muted);
    border: 1px solid var(--panel-border);
    border-bottom: none;
    border-radius: 8px 8px 0 0;
    padding: 4px 12px;
    font-family: var(--font-ui);
    font-size: 0.7rem;
    font-weight: 600;
    cursor: pointer;
    z-index: 51;
    display: none;
}@media (hover: hover) and (pointer: fine) {
#taskbar-tab:hover { color: var(--gold-bright); border-color: var(--accent); background: var(--surface-3); }
}
#taskbar-tab.visible { display: block; }
#bottom-taskbar h3 {
    margin: 0;
    font-family: var(--font-ui);
    font-size: 0.66rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--muted);
    white-space: nowrap;
}
.taskbar-list { display: flex; gap: 8px; overflow-x: auto; flex: 1; align-items: center; }
.taskbar-list::-webkit-scrollbar { height: 6px; }
.taskbar-list::-webkit-scrollbar-thumb { background: var(--accent); border-radius: 3px; }

/* Tooltip pour l'académie */
.tooltip-container {
    position: relative;
    display: inline-block;
}
.tooltip-text {
    visibility: hidden;
    width: 250px;
    max-width: calc(100vw - 32px);
    box-sizing: border-box;
    background-color: var(--panel-bg);
    color: var(--text-dark);
    text-align: center;
    border-radius: 6px;
    padding: 10px;
    position: absolute;
    z-index: 102;
    top: 125%; /* Positionné en dessous de l'icône */
    left: 50%;
    margin-left: -125px;
    opacity: 0;
    transition: opacity 0.3s;
    font-size: 0.9rem;
    font-weight: normal;
    border: 2px solid var(--highlight);
    box-shadow: 0 5px 15px rgba(0,0,0,0.5);
    font-family: var(--font-main);
}
.tooltip-container:hover .tooltip-text {
    visibility: visible;
    opacity: 1;
}

@keyframes pulseRed { 0% { background-color: rgba(255,0,0,0.8); } 50% { background-color: rgba(200,0,0,1); } 100% { background-color: rgba(255,0,0,0.8); } }

@keyframes fireFlicker {
    0% { opacity: 1; transform: translateX(-50%) scale(1); }
    50% { opacity: 0.8; transform: translateX(-50%) scale(1.1); }
    100% { opacity: 1; transform: translateX(-50%) scale(1); }
}

/* ========================================================
   World Map (Isometric 3D)
======================================================== */

/* La scene : le viewport occupe tout le cadre, les commandes flottent par
   dessus. Elles sont hors du viewport pour ne pas subir son transform. */
.wm-shell {
    width: 100%;
    height: 100%;
    max-height: 100% !important;
    overflow: hidden !important;
    padding: 0 !important;
    display: flex;
    flex-direction: column;
    background: #0b131c;
}

.wm-head {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 12px 12px;
    padding: 10px 12px;
    background: rgba(0,0,0,0.75);
    border-bottom: 1px solid var(--line-soft, rgba(212,165,72,0.25));
    flex: 0 0 auto;
    /* Au-dessus des commandes de la carte (12) et de la fiche (15) : les
       listes deroulantes de l'en-tete descendent par-dessus la scene. */
    position: relative;
    z-index: 20;
}
.wm-head h2 {
    margin: 0;
    font-size: 1.05rem;
    white-space: nowrap;
}
/* Le meme bouton que partout ailleurs (mil-close) : c'est lui qui porte le
   style, on ne fait ici que le pousser au bout de la premiere rangee. Sans
   cela il flottait au milieu de l'en-tete, la recherche ne remplissant pas
   toute la largeur. */
.wm-close.modal-close {
    margin-left: auto;
    flex: 0 0 auto;
}

/* Ce qu'on cherche sans cesse ne doit pas dormir sous un volet : les filtres
   et la liste des camps tiennent dans l'en-tete, toujours sous les yeux. */
.wm-quick {
    display: flex;
    align-items: center;
    gap: 10px;
    flex: 1 1 100%;
    min-width: 0;
    order: 4;
}
.wm-quick-filters {
    display: flex;
    align-items: center;
    gap: 6px;
    flex: 1 1 auto;
    min-width: 0;
    overflow-x: auto;
    scrollbar-width: none;
    padding-bottom: 2px;
}
.wm-quick-filters::-webkit-scrollbar { display: none; }
.wm-quick .wm-chip { flex: 0 0 auto; }

.wm-camps-wrap { position: relative; flex: 0 0 auto; }
.wm-camps-btn {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 6px 11px; border-radius: 999px; cursor: pointer;
    background: rgba(212,165,72,0.14);
    border: 1px solid rgba(212,165,72,0.55);
    color: var(--gold-bright, #f0c674);
    font-family: var(--font-ui, inherit); font-size: 0.78rem; font-weight: 700;
    white-space: nowrap;
}
.wm-camps-btn:hover { background: rgba(212,165,72,0.24); }
.wm-camps-n {
    min-width: 1.35em; padding: 0 4px; border-radius: 999px;
    background: var(--gold-bright, #f0c674); color: #1a1208;
    font-size: 0.72rem; text-align: center;
}
.wm-camps-list {
    position: absolute;
    top: calc(100% + 6px); right: 0;
    width: min(380px, 86vw);
    max-height: 340px; overflow-y: auto;
    background: var(--surface, #16202c);
    border: 1px solid var(--line-soft, rgba(212,165,72,0.3));
    border-radius: 10px;
    box-shadow: 0 12px 28px rgba(0,0,0,0.6);
    z-index: 40;
}
.wm-camps-list[hidden] { display: none; }
.wm-camps-list .wm-camp-res {
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-start;
    gap: 2px;
    text-align: left;
}
.wm-camps-list .wm-camp-res > span { max-width: 100%; }
.wm-camps-list .wm-camp-res .wm-res-sub { white-space: normal; }
.wm-camp-res .mg-ic { width: 0.9rem; height: 0.9rem; vertical-align: -0.12em; }

/* Recherche : un joueur, ou un couple de coordonnees. */
.wm-search {
    position: relative;
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    align-items: center;
    gap: 6px;
    background: rgba(255,255,255,0.10);
    border: 1px solid rgba(212,165,72,0.55);
    border-radius: 10px;
    padding: 0 10px;
    max-width: 420px;
    box-shadow: inset 0 1px 3px rgba(0,0,0,0.45);
}
.wm-search:focus-within {
    border-color: var(--gold-bright, #f0c674);
    box-shadow: 0 0 0 3px rgba(240,198,116,0.22), inset 0 1px 3px rgba(0,0,0,0.45);
}
.wm-search-ico { opacity: 1; color: var(--gold-bright, #f0c674); font-size: 0.85rem; }
.wm-search input {
    flex: 1 1 auto;
    min-width: 0;
    background: transparent;
    border: 0;
    outline: none;
    color: #f2e9d6;
    font-family: var(--font-ui, inherit);
    font-size: 0.86rem;
    padding: 9px 0;
}
.wm-search input::placeholder { color: rgba(242,233,214,0.72); }
.wm-search-clear {
    background: none; border: 0; cursor: pointer;
    color: rgba(242,233,214,0.55); font-size: 0.8rem; padding: 2px 4px;
}
.wm-search-results {
    position: absolute;
    top: calc(100% + 6px);
    left: 0; right: 0;
    background: var(--surface, #16202c);
    border: 1px solid var(--line-soft, rgba(212,165,72,0.3));
    border-radius: 10px;
    box-shadow: 0 12px 30px rgba(0,0,0,0.6);
    max-height: 260px;
    overflow-y: auto;
    z-index: 40;
}
.wm-res {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    width: 100%;
    background: none;
    border: 0;
    border-bottom: 1px solid rgba(255,255,255,0.05);
    color: #f2e9d6;
    font-family: var(--font-ui, inherit);
    font-size: 0.84rem;
    padding: 9px 12px;
    cursor: pointer;
    text-align: left;
}
.wm-res:last-child { border-bottom: 0; }.wm-res:focus-visible { background: rgba(212,165,72,0.12); }
@media (hover: hover) and (pointer: fine) {
.wm-res:hover { background: rgba(212,165,72,0.12); }
}
.wm-res .wm-res-sub { color: rgba(242,233,214,0.5); font-size: 0.75rem; white-space: nowrap; }
.wm-res-empty { padding: 12px; color: rgba(242,233,214,0.5); font-size: 0.82rem; }

.wm-stage {
    position: relative;
    flex: 1 1 auto;
    min-height: 0;
    overflow: hidden;
}

#worldmap-viewport {
    position: absolute;
    inset: 0;
    overflow: hidden;
    cursor: grab;
    background: radial-gradient(circle at center, #1b2838, #0a0f16);
    user-select: none;
    touch-action: none;
}

#worldmap-container {
    width: 10000px;
    height: 10000px;
    position: absolute;
    top: 0; left: 0;
    transform-origin: 0 0;
}

#worldmap-grid {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-image: url('assets/map_terrain_seamless.png');
    background-size: 1600px 1600px;
    background-repeat: repeat;
    pointer-events: none;
}

/* ---- Le selecteur de village ----
   Masque tant qu'il n'y a qu'un village : on n'expose pas un choix qui n'en
   est pas un. */
.crest-village {
    display: inline-flex; align-items: center; gap: 5px;
    margin-top: 3px; padding: 2px 8px;
    background: rgba(0,0,0,0.35); border: 1px solid var(--panel-border, rgba(255,255,255,0.15));
    border-radius: 999px; cursor: pointer;
    font-family: var(--font-ui); font-size: 0.72rem; font-weight: 700;
    color: var(--gold-bright, #f0c674); white-space: nowrap;
}
/* display: inline-flex l'emporte sur la regle [hidden] du navigateur : sans
   cette ligne, le selecteur reste visible avec un seul village. */
.crest-village[hidden], .village-menu[hidden] { display: none; }
.crest-village:hover { background: rgba(0,0,0,0.55); border-color: var(--accent, #d4a548); }
.crest-village .mg-ic { width: 14px; height: 14px; }

.village-menu {
    position: absolute; top: 100%; left: 0; z-index: 400;
    min-width: 210px; margin-top: 6px; padding: 5px;
    /* Sur un ecran etroit, il ne doit jamais sortir de la fenetre. */
    max-width: calc(100vw - 24px); box-sizing: border-box;
    background: var(--panel-bg, #17110b); border: 1px solid var(--accent, #d4a548);
    border-radius: 8px; box-shadow: 0 10px 28px rgba(0,0,0,0.6);
}
.village-ligne { display: flex; align-items: center; border-radius: 6px; }
.village-ligne:hover { background: rgba(255,255,255,0.07); }
.village-ligne.actif { background: rgba(212,165,72,0.18); }
.village-ligne.actif .village-choix { color: var(--gold-bright, #f0c674); }

.village-choix {
    display: flex; align-items: center; gap: 7px; flex: 1 1 auto; min-width: 0;
    padding: 7px 4px 7px 9px; border: 0; border-radius: 6px; cursor: pointer;
    background: transparent; color: var(--text, #f2e9d6);
    font-family: var(--font-ui); font-size: 0.8rem; text-align: left;
}
.village-choix .mg-ic { width: 16px; height: 16px; flex: 0 0 auto; }
.village-choix .vn { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.village-choix .vc { flex: 0 0 auto; font-size: 0.72rem; opacity: 0.6; font-variant-numeric: tabular-nums; }

.village-renommer {
    flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
    width: 30px; height: 30px; margin-right: 4px;
    background: transparent; border: 0; border-radius: 6px; cursor: pointer;
    color: rgba(242,233,214,0.55);
}
.village-renommer:hover { background: rgba(255,255,255,0.1); color: var(--gold-bright, #f0c674); }
.village-renommer .mg-ic { width: 15px; height: 15px; }

/* Renommer se fait dans le menu : la ligne cede la place au champ. */
.village-edit { padding: 9px; display: flex; flex-direction: column; gap: 7px; }
.village-edit label {
    font-family: var(--font-ui); font-size: 0.7rem; letter-spacing: .04em;
    text-transform: uppercase; color: rgba(242,233,214,0.6);
}
.village-edit input {
    /* Sans border-box, les 100 % s'ajoutent a la marge interieure et a la
       bordure : le champ sortait du menu par la droite. */
    width: 100%; box-sizing: border-box; padding: 7px 9px; border-radius: 6px;
    background: rgba(0,0,0,0.45); border: 1px solid var(--panel-border, rgba(255,255,255,0.18));
    color: var(--text, #f2e9d6); font-family: var(--font-ui); font-size: 0.85rem;
}
.village-edit input:focus { outline: none; border-color: var(--accent, #d4a548); }
.village-edit-actions { display: flex; gap: 6px; justify-content: flex-end; }
.village-edit-actions button {
    padding: 6px 12px; border-radius: 6px; cursor: pointer;
    font-family: var(--font-ui); font-size: 0.78rem; font-weight: 700;
}
.ve-annuler { background: transparent; border: 1px solid var(--panel-border, rgba(255,255,255,0.18)); color: rgba(242,233,214,0.8); }
.ve-valider { background: var(--accent, #d4a548); border: 1px solid var(--accent, #d4a548); color: #17110b; }
.ve-valider:disabled { opacity: .6; cursor: default; }
.village-edit-aide { margin: 0; font-size: 0.7rem; opacity: 0.55; }

.hud-crest { position: relative; }

/* ---- Commandes flottantes ---- */
.wm-zoom {
    position: absolute;
    right: 12px;
    top: 12px;
    display: flex;
    flex-direction: column;
    gap: 6px;
    z-index: 12;
}
.wm-zoom button {
    width: 40px; height: 40px;
    display: flex; align-items: center; justify-content: center;
    background: rgba(12,18,26,0.88);
    border: 1px solid var(--line-soft, rgba(212,165,72,0.3));
    border-radius: 10px;
    color: var(--gold-bright, #f0c674);
    font-size: 1.05rem;
    cursor: pointer;
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
}@media (hover: hover) and (pointer: fine) {
.wm-zoom button:hover { background: rgba(212,165,72,0.18); }
}
.wm-zoom button:active { transform: scale(0.94); }

.wm-legend-wrap {
    position: absolute;
    left: 12px;
    top: 12px;
    z-index: 12;
    max-width: min(280px, calc(100% - 80px));
}
.wm-legend-btn {
    background: rgba(12,18,26,0.88);
    border: 1px solid var(--line-soft, rgba(212,165,72,0.3));
    border-radius: 10px;
    color: var(--gold-bright, #f0c674);
    font-family: var(--font-ui, inherit);
    font-size: 0.8rem;
    padding: 9px 12px;
    cursor: pointer;
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
}@media (hover: hover) and (pointer: fine) {
.wm-legend-btn:hover { background: rgba(212,165,72,0.18); }
}
.wm-legend {
    margin-top: 6px;
    background: rgba(12,18,26,0.94);
    border: 1px solid var(--line-soft, rgba(212,165,72,0.3));
    border-radius: 12px;
    padding: 12px;
    box-shadow: 0 14px 34px rgba(0,0,0,0.6);
    max-height: calc(100% - 60px);
    overflow-y: auto;
}
.wm-legend[hidden] { display: none; }
.wm-legend-title {
    font-family: var(--font-title, inherit);
    color: var(--accent, #d4a548);
    font-size: 0.74rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    margin: 0 0 6px;
}
.wm-legend-title + .wm-legend-title, .wm-filters + .wm-legend-title { margin-top: 12px; }
.wm-leg {
    display: flex;
    align-items: center;
    gap: 8px;
    color: #dcd3c2;
    font-size: 0.79rem;
    padding: 3px 0;
}
.wm-dot {
    width: 11px; height: 11px;
    border-radius: 50%;
    flex: 0 0 auto;
    display: inline-block;
}
.wm-dot.me   { background: #ffd700; box-shadow: 0 0 8px #ffd700; }
.wm-dot.ally { background: #74bd7a; box-shadow: 0 0 8px #74bd7a; }
.wm-dot.foe  { background: #cf6a55; box-shadow: 0 0 8px #cf6a55; }
.wm-dot.bot  { background: #9aa4ad; box-shadow: 0 0 8px #9aa4ad; }
.wm-dot.lord { background: #b06bff; box-shadow: 0 0 10px #b06bff; }
.wm-leg-ico { width: 11px; text-align: center; font-size: 0.8rem; }

.wm-filters { display: flex; flex-wrap: wrap; gap: 6px; }
.wm-chip {
    background: rgba(255,255,255,0.05);
    border: 1px solid rgba(255,255,255,0.12);
    border-radius: 999px;
    color: rgba(242,233,214,0.55);
    font-family: var(--font-ui, inherit);
    font-size: 0.75rem;
    padding: 5px 11px;
    cursor: pointer;
}
.wm-chip.on {
    background: rgba(212,165,72,0.18);
    border-color: var(--accent, #d4a548);
    color: var(--gold-bright, #f0c674);
}
/* ============================================================
   LA PASTILLE DE NIVEAU D'UN BARBARE

   Le niveau vivait dans le nom, en « (Niv. 3) ». C'est pourtant ce qui decide
   si l'on peut prendre ce camp : il se lit maintenant a la couleur autant qu'au
   chiffre, et la rampe va du vert tiede au rouge sombre -- **l'ordre des teintes
   porte l'information**, pas leur jolie difference.

   Le chiffre reste, et ce n'est pas une ceinture de plus : une rampe de couleur
   seule exclut qui ne les distingue pas, et rien dans le jeu n'apprend que le
   rouge vaut cinq.

   `font-variant-numeric: tabular-nums` et une largeur minimale : sans elles,
   une colonne de pastilles a des ronds de largeurs differentes.
   ============================================================ */
.wm-niv {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 17px;
    height: 17px;
    padding: 0 4px;
    margin-left: 6px;
    border-radius: 999px;
    border: 1px solid rgba(0,0,0,0.45);
    font-family: var(--font-ui, inherit);
    font-size: 0.66rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    line-height: 1;
    color: #17120a;
    vertical-align: middle;
    box-shadow: 0 1px 3px rgba(0,0,0,0.5);
}
.wm-niv-1 { background: #8fbf7a; }
.wm-niv-2 { background: #cbc46b; }
.wm-niv-3 { background: #e0a457; }
.wm-niv-4 { background: #d97b4a; }
.wm-niv-5 { background: #c2503c; color: #fdf2e6; }
.wm-niv-lord {
    background: linear-gradient(160deg, #b06bff, #6f34c9);
    color: #fdf2e6;
    border-color: rgba(0,0,0,0.55);
    box-shadow: 0 0 8px rgba(176,107,255,0.6);
}
.wm-niv-lord .mg-ic { width: 11px; height: 11px; }

/* La rangee de puces de niveau. Elle porte sa legende : une file de chiffres
   nus entre « Attaquables » et la liste des camps ne dirait pas de quoi elle
   parle. */
/* **Les puces de niveau vivent DANS la bande des autres filtres.**
   Deux essais rates avant celui-ci, et les deux venaient de la meme idee
   fausse -- leur donner une bande a elles :

   1. `flex-wrap: wrap` sans `flex-shrink: 0` : la rangee se faisait ecraser a
      la largeur d'UNE puce et les six tombaient en colonne ;
   2. une bande defilante a part : le bandeau de la carte passait a trois rangs
      sur telephone, et l'on ne voyait plus la carte.

   Ce sont des filtres comme les autres. Ils se parcourent donc dans le meme
   defilement, derriere un simple trait de separation -- une ligne, pas trois. */
.wm-quick-niveaux {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    flex: 0 0 auto;
}
.wm-quick-sep {
    flex: 0 0 auto;
    width: 1px; height: 18px;
    background: rgba(255,255,255,0.14);
    margin: 0 2px;
}

.wm-niv-l {
    color: rgba(242,233,214,0.45);
    font-family: var(--font-ui, inherit);
    font-size: 0.7rem;
    margin-right: 2px;
}
/* Une puce de niveau est ronde et porte sa teinte en sourdine tant qu'elle est
   eteinte : la rampe doit se lire AVANT d'avoir clique, sinon on ne sait pas ce
   qu'on demande. */
.wm-chip-niv {
    min-width: 26px;
    padding: 4px 7px;
    text-align: center;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}
.wm-chip-niv.wm-niv-1 { background: rgba(143,191,122,0.12); border-color: rgba(143,191,122,0.4); color: #a9d194; }
.wm-chip-niv.wm-niv-2 { background: rgba(203,196,107,0.12); border-color: rgba(203,196,107,0.4); color: #ded77f; }
.wm-chip-niv.wm-niv-3 { background: rgba(224,164,87,0.12); border-color: rgba(224,164,87,0.4); color: #eeb972; }
.wm-chip-niv.wm-niv-4 { background: rgba(217,123,74,0.12); border-color: rgba(217,123,74,0.4); color: #ee9463; }
.wm-chip-niv.wm-niv-5 { background: rgba(194,80,60,0.12); border-color: rgba(194,80,60,0.45); color: #e07a66; }
.wm-chip-niv.wm-niv-lord { background: rgba(176,107,255,0.12); border-color: rgba(176,107,255,0.45); color: #c79bff; box-shadow: none; }
.wm-chip-niv.wm-niv-lord .mg-ic { width: 13px; height: 13px; }
/* Allumee, la teinte passe au premier plan -- c'est le seul etat ou la carte
   ne montre que ce palier, donc il doit etre le plus visible de la barre. */
.wm-chip-niv.on.wm-niv-1 { background: #8fbf7a; border-color: #8fbf7a; color: #17120a; }
.wm-chip-niv.on.wm-niv-2 { background: #cbc46b; border-color: #cbc46b; color: #17120a; }
.wm-chip-niv.on.wm-niv-3 { background: #e0a457; border-color: #e0a457; color: #17120a; }
.wm-chip-niv.on.wm-niv-4 { background: #d97b4a; border-color: #d97b4a; color: #17120a; }
.wm-chip-niv.on.wm-niv-5 { background: #c2503c; border-color: #c2503c; color: #fdf2e6; }
.wm-chip-niv.on.wm-niv-lord {
    background: linear-gradient(160deg, #b06bff, #6f34c9);
    border-color: #b06bff; color: #fdf2e6;
    box-shadow: 0 0 8px rgba(176,107,255,0.55);
}

/* La rangee de puces du ralliement : meme habillage que celle de la carte, pour
   que le meme geste se reconnaisse aux deux endroits. */
.rall-niveaux {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 5px;
    margin: 2px 0 8px;
}

.wm-legend-hint {
    margin: 10px 0 0;
    color: rgba(242,233,214,0.45);
    font-size: 0.72rem;
    line-height: 1.4;
}

.wm-coords {
    position: absolute;
    left: 12px;
    bottom: 12px;
    z-index: 11;
    background: rgba(12,18,26,0.8);
    border: 1px solid rgba(255,255,255,0.1);
    border-radius: 8px;
    padding: 5px 10px;
    color: rgba(242,233,214,0.7);
    font-size: 0.74rem;
    font-variant-numeric: tabular-nums;
    pointer-events: none;
}

/* ---- Fiche du village selectionne ----
   Panneau lateral sur grand ecran, feuille par le bas sur telephone :
   les actions etaient jusqu'ici dans une infobulle au survol, donc
   inatteignables au doigt. */
.wm-card {
    position: absolute;
    right: 12px;
    bottom: 12px;
    width: 300px;
    max-height: calc(100% - 120px);
    overflow-y: auto;
    z-index: 15;
    background: linear-gradient(160deg, rgba(20,28,38,0.97), rgba(10,15,22,0.97));
    border: 1px solid var(--accent, #d4a548);
    border-radius: 14px;
    box-shadow: 0 16px 40px rgba(0,0,0,0.7);
    padding: 14px;
    animation: wmCardIn 0.16s ease-out;
}
.wm-card[hidden] { display: none; }

/* ---- Choisir une case (la merveille, d'abord) ----
   La fenetre de guilde vit a 10 000 : la carte ouverte depuis elle passerait
   dessous. Le temps du choix seulement, elle monte au-dessus. */
#modal-worldmap.wm-en-choix { z-index: 10050 !important; }
#modal-worldmap.wm-en-choix #worldmap-viewport { cursor: crosshair; }
#modal-worldmap.wm-en-choix .wm-card { display: none; }
.wm-choix {
    position: absolute;
    left: 50%;
    top: 12px;
    transform: translateX(-50%);
    width: min(440px, calc(100% - 24px));
    z-index: 16;
    background: linear-gradient(160deg, rgba(20,28,38,0.97), rgba(10,15,22,0.97));
    border: 1px solid var(--accent, #d4a548);
    border-radius: 14px;
    box-shadow: 0 16px 40px rgba(0,0,0,0.7);
    padding: 12px 14px;
    display: flex;
    flex-direction: column;
    gap: 6px;
    font-family: var(--font-ui);
}
.wm-choix[hidden] { display: none; }
.wm-choix-t { font-family: 'Cinzel', serif; color: var(--accent, #d4a548); font-size: 0.95rem; }
.wm-choix-s { color: rgba(242,233,214,0.8); font-size: 0.82rem; line-height: 1.4; font-variant-numeric: tabular-nums; }
.wm-choix-s.ok { color: #9be39b; }
.wm-choix-s.ko { color: #ff8a7a; }
.wm-choix-b { display: flex; gap: 8px; flex-wrap: wrap; }
.wm-choix-b .btn-res { flex: 1 1 140px; }
.wm-choix-b #wm-choix-non { background: transparent; border-color: var(--panel-border, rgba(255,255,255,0.2)); color: rgba(242,233,214,0.8); }
.wm-choix-marque { position: absolute; width: 0; height: 0; pointer-events: none; }
.wm-choix-sol {
    position: absolute;
    left: 0; top: 0;
    width: 100px; height: 50px;
    transform: translate(-50%, -50%);
    clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
    background: rgba(240,198,116,0.55);
    animation: wmChoixPouls 1.4s ease-in-out infinite;
}
.wm-choix-marque.libre .wm-choix-sol { background: rgba(110,220,110,0.6); }
.wm-choix-marque.refus .wm-choix-sol { background: rgba(255,90,70,0.6); }
.wm-choix-marque img {
    position: absolute;
    left: 0; top: 0;
    width: 120px;
    transform: translate(-50%, -75%);
    opacity: 0.8;
}
.wm-choix-marque.refus img { opacity: 0.35; }
@keyframes wmChoixPouls { 50% { opacity: 0.45; } }
@media (prefers-reduced-motion: reduce) { .wm-choix-sol { animation: none; } }
@keyframes wmCardIn {
    from { opacity: 0; transform: translateY(8px); }
    to   { opacity: 1; transform: translateY(0); }
}
.wm-card-head { display: flex; align-items: flex-start; gap: 8px; margin-bottom: 10px; }
.wm-card-title { flex: 1 1 auto; min-width: 0; }
.wm-card-title h3 {
    margin: 0;
    font-family: var(--font-title, inherit);
    font-size: 1rem;
    color: var(--gold-bright, #f0c674);
    word-break: break-word;
}
/* Le seigneur, sous le nom de son village. C'est un paragraphe, pas un titre :
   il porte donc la police d'interface et non l'anglaise des titres, qui se
   dechiffre au lieu de se lire. */
.wm-card-sub {
    display: flex;
    align-items: center;
    gap: 5px;
    margin-top: 3px;
    font-family: var(--font-ui);
    font-size: 0.78rem;
    color: var(--parchment-dim, #b8ab93);
}
.wm-card-sub svg { width: 13px; height: 13px; flex: 0 0 auto; opacity: 0.85; }

.wm-tag {
    display: inline-block;
    margin-top: 4px;
    font-size: 0.7rem;
    padding: 2px 8px;
    border-radius: 999px;
    border: 1px solid currentColor;
    opacity: 0.9;
}
.wm-tag.me   { color: #ffd700; }
.wm-tag.ally { color: #74bd7a; }
.wm-tag.foe  { color: #cf6a55; }
.wm-tag.bot  { color: #9aa4ad; }
.wm-tag.lord { color: #b06bff; }
.wm-card-close {
    background: none; border: 0; cursor: pointer;
    color: rgba(242,233,214,0.55); font-size: 0.9rem; padding: 2px 4px;
    flex: 0 0 auto;
}
.wm-card-stats {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8px;
    margin-bottom: 10px;
}
.wm-stat {
    background: rgba(255,255,255,0.04);
    border: 1px solid rgba(255,255,255,0.07);
    border-radius: 9px;
    padding: 7px 9px;
}
.wm-stat .k {
    display: block;
    font-size: 0.66rem;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: rgba(242,233,214,0.45);
}
.wm-stat .v {
    display: block;
    font-size: 0.85rem;
    color: #f2e9d6;
    font-variant-numeric: tabular-nums;
    margin-top: 2px;
}
.wm-note {
    border-radius: 9px;
    padding: 8px 10px;
    font-size: 0.76rem;
    line-height: 1.4;
    margin-bottom: 10px;
}
.wm-note.shield { background: rgba(30,70,140,0.35); border: 1px solid rgba(80,160,255,0.5); color: #bfe2ff; }
.wm-note.info   { background: rgba(255,255,255,0.05); border: 1px solid rgba(255,255,255,0.1); color: rgba(242,233,214,0.72); }
.wm-note.warn   { background: rgba(120,70,20,0.3); border: 1px solid rgba(214,158,74,0.45); color: #e8c58a; }
.wm-card-actions { display: flex; flex-direction: column; gap: 6px; }
.wm-act {
    width: 100%;
    border-radius: 9px;
    border: 1px solid var(--line-soft, rgba(212,165,72,0.3));
    background: rgba(255,255,255,0.05);
    color: #f2e9d6;
    font-family: var(--font-ui, inherit);
    font-size: 0.82rem;
    padding: 10px;
    cursor: pointer;
    text-align: center;
}@media (hover: hover) and (pointer: fine) {
.wm-act:hover { background: rgba(212,165,72,0.15); }
}
.wm-act.danger { background: rgba(207,106,85,0.2); border-color: rgba(207,106,85,0.6); color: #ffb9a8; }@media (hover: hover) and (pointer: fine) {
.wm-act.danger:hover { background: rgba(207,106,85,0.34); }
}
.wm-act.ghost { background: transparent; color: rgba(242,233,214,0.65); }

/* ---- Villages ---- */
.map-village {
    position: absolute;
    width: 120px;
    height: 120px;
    transform: translate(-50%, -75%);
    cursor: pointer;
    transition: transform 0.2s;
    z-index: 10;
}@media (hover: hover) and (pointer: fine) {
.map-village:hover {
    transform: translate(-50%, -75%) scale(1.1);
    z-index: 99999 !important;
}
}

.map-village.selected {
    transform: translate(-50%, -75%) scale(1.14);
    z-index: 99999 !important;
}
.map-village.selected .map-village-name {
    border-color: var(--gold-bright, #f0c674);
    box-shadow: 0 0 0 3px rgba(240,198,116,0.35);
}

.map-village-img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    filter: drop-shadow(0px 10px 5px rgba(0,0,0,0.8));
}

/* Tout ce qui surmonte un village -- couronne, pavois, coffre de ruines,
   tente du camp, plaque du nom -- tient dans une seule colonne, empilee du plus
   haut au plus proche. Plus aucune hauteur n'est ecrite a la main, donc plus
   aucun recouvrement quand un village porte plusieurs fanions.

   La colonne entiere grossit d'un bloc quand on dezoome (--wm-lbl, pose par
   updateMapTransform) : les etiquettes gardent ainsi une taille a peu pres
   constante a l'ecran au lieu de devenir illisibles. L'origine est en bas,
   donc elle grandit vers le haut, en s'ecartant du village. */
.map-village-tags {
    position: absolute;
    bottom: 100%;
    left: 50%;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 3px;
    transform: translateX(-50%) scale(var(--wm-lbl, 1));
    transform-origin: bottom center;
    pointer-events: none;
    z-index: 20;
}

.map-village-name {
    background: rgba(0, 0, 0, 0.8);
    color: #fff;
    padding: 4px 12px;
    border-radius: 10px;
    font-size: 17px;
    font-weight: bold;
    white-space: nowrap;
    pointer-events: none;
    z-index: 20;
    border: 1px solid rgba(255, 215, 0, 0.5);
    box-shadow: 0 2px 4px rgba(0,0,0,0.5);
    text-shadow: 0 1px 2px rgba(0,0,0,0.9);
    max-width: 260px;
    overflow: hidden;
    /* La plaque est une RANGEE, et c'est le nom seul qui se coupe.
       L'ellipse vivait sur la plaque entiere : la pastille de niveau, posee
       apres le nom, tombait donc hors du cadre des que le nom atteignait les
       260 px -- systematiquement pour le Seigneur de guerre, dont le libelle
       fait pres du double. Une pastille que le nom peut effacer ne sert a rien,
       puisque c'est elle qui decide si l'on peut prendre ce camp. */
    display: flex;
    align-items: center;
}
.map-village-name .wm-nom-l,
.map-village-name .wm-nom-c {
    overflow: hidden;
    text-overflow: ellipsis;
    min-width: 0;
}
.map-village-name .wm-niv { flex: 0 0 auto; }

/* Au loin, la plaque se resserre et ne garde que le pseudo : elle ne disparait
   plus -- c'est la colonne qui grossit pour rester lisible -- mais elle doit
   cesser de s'etaler, sinon deux villages voisins se recouvrent. */
.map-village-name .wm-nom-c { display: none; }
#worldmap-container.wm-far .map-village-name {
    padding: 2px 8px; border-radius: 8px; font-size: 15px; max-width: 150px;
}
#worldmap-container.wm-far .map-village-name .wm-nom-l { display: none; }
#worldmap-container.wm-far .map-village-name .wm-nom-c { display: inline; }

/* La couronne du Seigneur de guerre : il etait jusqu'ici impossible de le
   distinguer d'un village barbare ordinaire. */
.map-village.warlord .map-village-img {
    filter: drop-shadow(0px 10px 12px #b06bff) drop-shadow(0 0 20px rgba(176,107,255,0.7));
}
.map-village.warlord .map-village-name {
    border-color: #b06bff;
    color: #e5cfff;
    box-shadow: 0 0 14px rgba(176,107,255,0.6);
}
.map-crown {
    font-size: 30px;
    z-index: 26;
    pointer-events: none;
    filter: drop-shadow(0 0 8px rgba(176,107,255,0.95));
}

/* === Bouclier de Protection === */
@keyframes shieldPulse {
    0%   { box-shadow: 0 0 0px 0px rgba(80, 160, 255, 0), 0 0 18px 6px rgba(80, 160, 255, 0.5); }
    50%  { box-shadow: 0 0 0px 14px rgba(80, 160, 255, 0), 0 0 32px 14px rgba(120, 200, 255, 0.85); }
    100% { box-shadow: 0 0 0px 0px rgba(80, 160, 255, 0), 0 0 18px 6px rgba(80, 160, 255, 0.5); }
}
/* Le pavois flotte, il ne se deplace pas lateralement. Le `translateX(-50%)`
   qu'il portait ici est un reste de l'epoque ou chaque fanion etait pose en
   absolu a `left: 50%` : depuis qu'ils vivent dans la colonne
   `.map-village-tags`, c'est ELLE qui porte le recentrage, et le repeter sur
   l'enfant le decalait d'une demi-largeur vers la gauche -- le bouclier
   paraissait appartenir au village d'a cote. Une animation qui reecrit
   `transform` ecrase toute la propriete : elle ne doit donc contenir QUE ce
   qu'elle anime. */
@keyframes shieldIconFloat {
    0%   { transform: translateY(0px); }
    50%  { transform: translateY(-6px); }
    100% { transform: translateY(0px); }
}

.map-village.shielded {
    border-radius: 50%;
    animation: shieldPulse 2s ease-in-out infinite;
}

.map-village.shielded .map-village-img {
    filter: drop-shadow(0px 10px 5px rgba(0,0,0,0.8)) drop-shadow(0 0 12px rgba(80, 180, 255, 0.9));
}

.map-shield-icon {
    font-size: 28px;
    z-index: 25;
    pointer-events: none;
    animation: shieldIconFloat 2s ease-in-out infinite;
    filter: drop-shadow(0 0 6px rgba(80, 180, 255, 1));
    text-shadow: 0 0 10px rgba(80, 180, 255, 0.9);
}

/* Bandeau protection joueur */
#protection-banner {
    position: fixed;
    top: 100px;
    left: 20px;
    background: linear-gradient(135deg, rgba(20, 50, 100, 0.97), rgba(10, 30, 70, 0.97));
    border: 2px solid rgba(80, 160, 255, 0.8);
    border-radius: 12px;
    padding: 10px 22px;
    display: flex;
    align-items: center;
    gap: 12px;
    z-index: 9999;
    box-shadow: 0 0 20px rgba(80, 160, 255, 0.5), 0 4px 15px rgba(0,0,0,0.6);
    color: #cce8ff;
    font-size: 14px;
    font-weight: bold;
    pointer-events: auto;
    animation: shieldPulse 3s ease-in-out infinite;
}
#protection-banner .shield-emoji { font-size: 22px; }
#protection-banner .shield-timer { color: #80d4ff; font-size: 13px; font-weight: normal; }


/* Map Movements */
/* Les traces des colonnes (map.js, renderMovements). Le pointille -- dix
   pixels pleins, dix vides, qui avance de vingt pixels par seconde -- est une
   bande qui glisse dans un cadre fixe, tourne dans l'axe du trajet. Seul un
   `transform` s'anime : la puce graphique le joue sans que la page soit
   repeinte. La bande deborde de vingt pixels a gauche, pour que le glissement
   ne decouvre jamais le debut du trait. */
.map-movement-line {
  position: absolute;
  height: 4px;
  margin-top: -2px;
  transform-origin: 0 50%;
  overflow: hidden;
  opacity: 0.6;
  pointer-events: none;
}
.map-movement-line > i {
  position: absolute;
  top: 0; bottom: 0; left: -20px; right: 0;
  background: repeating-linear-gradient(90deg, var(--trait) 0 10px, transparent 10px 20px);
  animation: traitDePointilles 1s linear infinite;
  will-change: transform;
}
@keyframes traitDePointilles {
  to { transform: translateX(20px); }
}

.map-soldier {
  position: absolute;
  left: 0; top: 0;
  width: 60px;
  height: 60px;
  /* La position voyage en variables DANS le transform, posees une fois par
     seconde par animateSoldiers() : la transition d'une seconde lisse le trajet
     et la puce graphique la joue seule. Elle vivait dans `left`/`top`, que la
     boucle reecrivait a chaque image -- une mise en page de toute la carte
     soixante fois par seconde, et une transition relancee sans jamais finir.
     Chaque variante qui redefinit `transform` doit garder le premier
     translate, sinon la colonne retombe dans le coin de la carte. */
  transform: translate(var(--x, 0px), var(--y, 0px)) translate(-50%, -50%);
  pointer-events: none;
  /* La profondeur est posee par animateSoldiers() : sans cela le marcheur
     passait systematiquement sous les villages. */
  filter: drop-shadow(0px 4px 4px rgba(0,0,0,0.75));
  transition: transform 1s linear;
}

.map-soldier.return {
  filter: drop-shadow(0px 5px 5px rgba(0,0,0,0.8));
}


/* Le chevalier de la carte : une planche par allure, huit rangees de directions
   de 128 px, seize images par cycle. La rangee est posee en style en ligne
   (background-position-y), l'animation ne fait defiler que les colonnes. */
.map-soldier.animated {
    width: 128px;
    height: 128px;
    background-image: url('assets/marche.webp?v=2');
    background-repeat: no-repeat;
    /* La rangee -- donc la direction -- est posee par renderMovements() en
       variable CSS. Une variable descend aux pseudo-elements, une propriete de
       fond non, et la caravane porte sa planche sur un ::before. */
    background-position-y: var(--rang, 0px);
    /* Les pieds tombent sur le trajet, comme un village tombe sur sa case.
       L'origine posee sur les pieds rend le cadrage insensible a l'echelle. */
    transform-origin: 50% 97%;
    transform: translate(var(--x, 0px), var(--y, 0px)) translate(-50%, -97%) scale(0.62);
    animation: marche 1.12s steps(16) infinite;
}

/* Les villageois du village ont leur propre planche et leur propre cadence :
   trente images de 256 px par direction, un fichier par direction, et leur
   propre animation (`walkBande`, plus haut). Elles ont partage un nom une
   fois : renommer l'une en croyant toucher l'autre a fait glisser les
   villageois sans qu'ils bougent les jambes. */
@keyframes marche {
    from { background-position-x: 0px; }
    to   { background-position-x: -2048px; }
}

/* La caravane de commerce. Meme geometrie que le chevalier -- huit rangees de
   128 px, seize images sur une planche de 2048 -- donc la meme mecanique : la
   rangee en style en ligne, l'animation ne fait defiler que les colonnes.

   Trois ecarts, et chacun a sa raison. L'attelage TRESSAUTE au lieu de marcher :
   le maillage est unique et cuit, sans squelette ni roues separees, et a cette
   taille un rayon fait trois pixels -- des cahots sont la seule chose qui se
   lise. Il tressaute plus LENTEMENT qu'un homme ne marche. Et son origine tombe
   au centre de son empreinte au sol, pas aux pieds d'un homme : un chariot
   attele fait deux cases de long, donc l'ancrage aux « pieds » aurait plante
   la moitie de l'attelage sous le trajet. */
.map-soldier.caravane.animated {
    /* L'attelage vit dans un ::before, et ce n'est pas de l'elegance : le
       compte a rebours est un ENFANT de cet element. Une rotation posee ici lui
       serait transmise, et « 2 h 59 » s'afficherait de travers. */
    background-image: none;
    animation: none;
    transform-origin: 50% 70%;
    transform: translate(var(--x, 0px), var(--y, 0px)) translate(-50%, -70%) scale(0.62);
}

/* Le chariot lui-meme. La planche ne connait que huit caps, espaces de 45
   degres a l'ecran ; une route de village a village en prend n'importe lequel.
   L'ecart, jusqu'a 22,5 degres, ne se voyait pas sur un marcheur -- un homme
   n'a pas d'axe long -- mais un attelage dessine en travers de sa propre route
   doree se voit immediatement. `--cap` rend cet ecart, et le pivot est
   l'ancrage : le point meme qui est pose sur la ligne, donc le chariot tourne
   sans quitter sa route. */
.map-soldier.caravane.animated::before {
    content: "";
    position: absolute;
    inset: 0;
    background-image: url('assets/caravane.webp?v=1');
    background-repeat: no-repeat;
    background-position-y: var(--rang, 0px);
    animation: caravane 1.4s steps(16) infinite;
    transform-origin: 50% 70%;
    transform: rotate(var(--cap, 0deg));
}

@keyframes caravane {
    from { background-position-x: 0px; }
    to   { background-position-x: -2048px; }
}

.map-soldier-timer {
    position: absolute; top: -22px; left: 50%; transform: translateX(-50%);
    background: rgba(0,0,0,0.6); color: #fff;
    padding: 3px 7px; border-radius: 5px;
    font-family: var(--font-ui, sans-serif); font-size: 20px; font-weight: 700;
    pointer-events: none; white-space: nowrap; text-shadow: 1px 1px 2px #000;
    font-variant-numeric: tabular-nums;
}
#worldmap-container.wm-far .map-soldier-timer { display: none; }


/* Prestige Modal Redesign */
/* --- La Renaissance ---
   Meme grammaire que les autres fenetres du jeu : en-tete fige, corps qui
   defile, barre d'action en bas. Le seul ecart est une lueur doree en haut,
   parce que c'est le moment le plus solennel de la partie. */
.prestige-modal {
    max-width: 560px;
    background:
        radial-gradient(120% 70% at 50% 0%, rgba(212,165,72,0.10), transparent 70%),
        var(--panel-bg);
}
.prestige-modal .mil-head { border-bottom: 1px solid var(--line-soft); padding-bottom: 14px; }

/* Le palier : d'ou l'on part, ou l'on va, et ou l'on en est. */
.pr-step {
    display: flex; align-items: center; gap: 12px; margin-top: 14px;
    font-family: var(--font-ui);
}
.pr-lvl {
    flex: 0 0 auto; padding: 7px 14px; text-align: center;
    background: var(--surface); border: 1px solid var(--line-soft); border-radius: var(--radius-sm);
}
.pr-lvl .k { display: block; font-size: 0.56rem; text-transform: uppercase; letter-spacing: 0.09em; color: var(--muted); }
.pr-lvl .v { display: block; font-size: 1.3rem; font-weight: 700; line-height: 1.15; font-variant-numeric: tabular-nums; }
.pr-lvl.next { background: rgba(212,165,72,0.10); border-color: var(--accent); }
.pr-lvl.next .v { color: var(--gold-bright); }
.pr-arrow { color: var(--accent); font-size: 1.1rem; flex: 0 0 auto; }
.pr-state {
    margin-left: auto; text-align: right; font-size: 0.7rem; line-height: 1.35;
    color: var(--muted); max-width: 12em;
}
.pr-state.ready { color: var(--success); font-weight: 700; }

.pr-h {
    margin: 4px 0 9px; font-family: var(--font-ui);
    font-size: 0.62rem; text-transform: uppercase; letter-spacing: 0.1em;
    color: var(--muted); border: 0; text-align: left;
}
.pr-h + .pr-gains, .pr-h + .pr-reqs { margin-bottom: 16px; }

/* Une condition : ce qu'elle demande, ou l'on en est, et ce qui manque. */
.pr-reqs { display: flex; flex-direction: column; gap: 8px; font-family: var(--font-ui); }
.pr-req {
    background: var(--surface); border: 1px solid var(--line-soft);
    border-radius: var(--radius-sm); padding: 10px 12px;
}
.pr-req.ok { border-color: rgba(116,189,122,0.45); }
.pr-req-top {
    display: flex; align-items: baseline; gap: 8px; margin-bottom: 8px;
}
.pr-req-top .k { flex: 1; min-width: 0; font-size: 0.76rem; color: var(--text-light); }
.pr-req-top .k i { font-style: normal; margin-right: 6px; }
.pr-req-top .v { font-size: 0.78rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.pr-req.ok .pr-req-top .v { color: var(--success); }
.pr-req .store-bar { height: 8px; border-radius: 4px; }
.pr-req.ok .store-bar > i { background: linear-gradient(90deg, #4d7a51, var(--success)); }
.pr-miss { margin-top: 7px; font-size: 0.66rem; color: var(--danger); }
.pr-req.ok .pr-miss { color: var(--success); }

/* Le gain : la valeur d'aujourd'hui, celle d'apres. */
.pr-gains { display: flex; flex-direction: column; gap: 1px; font-family: var(--font-ui); }
.pr-gain {
    display: flex; align-items: baseline; gap: 8px;
    padding: 8px 2px; border-bottom: 1px solid var(--line-soft);
    font-size: 0.74rem;
}
.pr-gain:last-child { border-bottom: 0; }
.pr-gain .k { flex: 1; min-width: 0; color: var(--text-light); }
.pr-gain .k i { font-style: normal; margin-right: 7px; }
.pr-gain .from { color: var(--muted); font-variant-numeric: tabular-nums; }
.pr-gain .sep { color: var(--accent); }
.pr-gain .to { color: var(--gold-bright); font-weight: 700; font-variant-numeric: tabular-nums; }

.pr-hint { margin: 14px 0 4px; font-size: 0.68rem; color: var(--muted); font-family: var(--font-ui); }

.pr-bar .info b { color: var(--gold-bright); }

@media (max-width: 768px) {
    .pr-step { gap: 9px; flex-wrap: wrap; }
    .pr-lvl { padding: 6px 11px; }
    .pr-lvl .v { font-size: 1.15rem; }
    .pr-state { flex-basis: 100%; margin-left: 0; text-align: left; max-width: none; order: 4; }
    .pr-bar { flex-wrap: wrap; }
    .pr-bar .info { flex-basis: 100%; }
    .pr-bar .btn-bar { width: 100%; }
}

/* Le bouton de fermeture de la Renaissance reprend celui des autres modales. */


.storage-bar {
    width: 100%;
    height: 4px;
    border-radius: 2px;
    background: #0c0a07;
    box-shadow: inset 0 0 0 1px rgba(255,255,255,0.04);
    overflow: hidden;
}
/* Pas de transition sur `width` : la jauge suit la production a chaque tour,
   et une largeur animee sans fin recalcule la mise en page de toute la page. */
.storage-fill { height: 100%; width: 0%; border-radius: 2px; transition: background-color 0.3s; }
.wood-fill { background: #8B5A2B; }
.stone-fill { background: #8a8378; }
.iron-fill { background: #6d6a63; }
.food-fill { background: #c49a2e; }
.gold-fill { background: #d4a548; }
.storage-fill.full { background: var(--danger) !important; color: var(--danger); box-shadow: 0 0 8px rgba(207,106,85,.6); }

/* --- Quêtes journalières --- */
.quests-head {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    padding: 4px 0 14px;
    margin-bottom: 14px;
    border-bottom: 1px solid var(--line-soft);
}
.quests-ico { font-size: 1.4rem; line-height: 1.2; }
.quests-title { flex: 1; min-width: 0; }
.quests-title h2 {
    margin: 0;
    font-size: 1rem;
    color: var(--gold-bright);
    border: 0;
    padding: 0;
    text-align: left;
}
.quests-title p {
    margin: 4px 0 0;
    font-family: var(--font-ui);
    font-size: 0.7rem;
    color: var(--muted);
}
.streak-chip {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 5px 10px;
    border-radius: 999px;
    background: rgba(207, 106, 85, 0.12);
    border: 1px solid rgba(207, 106, 85, 0.35);
    color: #e9927c;
    font-family: var(--font-ui);
    font-size: 0.7rem;
    font-weight: 600;
    white-space: nowrap;
}
.modal-close.quests-close {
    position: static;
    flex-shrink: 0;
    width: 30px;
    height: 30px;
    border-radius: 8px;
    border: 1px solid var(--panel-border);
    background: transparent;
    color: var(--muted);
    font-size: 0.8rem;
    line-height: 1;
}@media (hover: hover) and (pointer: fine) {
.modal-close.quests-close:hover { color: var(--text-light); border-color: var(--accent); background: transparent; }
}

.quest-item {
    border: 1px solid var(--line-soft);
    border-radius: var(--radius);
    padding: 12px 14px;
    margin-bottom: 10px;
    background: var(--surface);
}
.quest-item { position: relative; overflow: hidden; }
.quest-item.q-done { border-color: rgba(116, 189, 122, 0.45); }
.quest-item.q-claimed { opacity: 0.5; }
.quest-progress-track {
    width: 100%;
    height: 6px;
    background: #0c0a07;
    border-radius: 3px;
    overflow: hidden;
    margin-top: 9px;
}
.quest-progress-fill {
    /* La barre ne change pas de largeur : elle se met a l'echelle depuis la
       gauche. `transform` passe par la carte graphique, `width` non. */
    height: 100%;
    width: 100%;
    border-radius: 3px;
    transform-origin: 0 50%;
    background: linear-gradient(90deg, #8a6a2c, var(--gold-bright));
}
.quest-item.q-done .quest-progress-fill { background: linear-gradient(90deg, #5d9f63, var(--success)); }
.quest-footer {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-top: 8px;
}
.quest-progress-label {
    font-family: var(--font-ui);
    font-size: 0.7rem;
    font-variant-numeric: tabular-nums;
    color: var(--muted);
}
.quest-done-label {
    font-family: var(--font-ui);
    font-size: 0.7rem;
    font-weight: 600;
    color: var(--success);
}
.btn-claim {
    height: 30px;
    padding: 0 14px;
    border-radius: 7px;
    border: 1px solid #eac57a;
    background: linear-gradient(180deg, #d9ad51, #b5893a);
    color: #1c1408;
    font-family: var(--font-ui);
    font-size: 0.72rem;
    font-weight: 700;
    cursor: pointer;
}@media (hover: hover) and (pointer: fine) {
.btn-claim:hover { background: linear-gradient(180deg, #e6bb63, #c2953f); }
}

.quests-bonus {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-top: 14px;
    padding: 12px 14px;
    border-radius: var(--radius);
    background: rgba(212, 165, 72, 0.07);
    border: 1px dashed rgba(212, 165, 72, 0.4);
    font-family: var(--font-ui);
}
.quests-bonus .txt { flex: 1; font-size: 0.76rem; }
.quests-bonus .txt b { color: var(--gold-bright); }
.quests-bonus .txt span { display: block; color: var(--muted); font-size: 0.7rem; margin-top: 2px; }
.quest-pips { display: flex; gap: 4px; }
.quest-pips i {
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: #0c0a07;
    border: 1px solid var(--panel-border);
}
.quest-pips i.on { background: var(--accent); border-color: var(--gold-bright); }

/* ---- Les quetes : une carte par difficulte, et deux onglets ---- */
.qtabs { display: flex; gap: 6px; margin: 2px 0 12px; flex: 0 0 auto; }
.qtab {
    flex: 1; position: relative; padding: 9px 10px; border-radius: 8px; cursor: pointer;
    background: var(--surface); border: 1px solid var(--line-soft); color: var(--muted);
    font-family: var(--font-ui); font-size: 0.78rem; font-weight: 700;
}
.qtab.active { color: var(--gold-bright); border-color: var(--accent); background: rgba(212,165,72,0.08); }
/* `hidden` ne gagne pas contre un `display` pose par une classe. */
.qtab-pt[hidden] { display: none; }
.qtab-pt {
    display: inline-block; width: 8px; height: 8px; margin-left: 4px; vertical-align: 1px;
    border-radius: 50%; background: var(--danger); box-shadow: 0 0 6px var(--danger);
}
.q-vide { text-align: center; color: var(--muted); font-family: var(--font-ui); }

/* La difficulte a sa couleur, du bronze au rouge : la bande de gauche, la
   pastille de l'icone et l'etiquette la lisent toutes ici. */
.quest-item { --qd: #b08a52; border-left: 3px solid var(--qd); }
.quest-item.q-d1 { --qd: #8fa7c4; }
.quest-item.q-d2 { --qd: #d06a4f; }
.q-tete { display: flex; align-items: center; gap: 11px; }
.q-ic {
    flex-shrink: 0; width: 38px; height: 38px; border-radius: 50%; display: grid; place-items: center;
    background: radial-gradient(circle at 35% 30%, rgba(255,255,255,0.14), rgba(0,0,0,0.25)), var(--surface-2);
    border: 2px solid var(--qd);
}
.q-ic .mg-ic { width: 22px; height: 22px; }
.q-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; font-family: var(--font-ui); }
.q-diff { font-size: 0.6rem; font-weight: 800; letter-spacing: 0.1em; text-transform: uppercase; color: var(--qd); }
.q-desc { font-size: 0.82rem; color: var(--text-light); line-height: 1.35; }
.quest-footer { gap: 8px; }
/* Les recompenses ont leur rang a elles, sous l'intitule : serrees a cote du
   bouton, elles s'empilaient une par ligne sur un telephone. */
.q-recompense { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 9px; padding-left: 49px; }
.q-chip {
    display: inline-flex; align-items: center; gap: 4px; padding: 2px 8px; border-radius: 999px;
    background: rgba(0,0,0,0.25); border: 1px solid var(--line-soft);
    font-family: var(--font-ui); font-size: 0.68rem; font-weight: 700; color: var(--text-light);
    font-variant-numeric: tabular-nums; white-space: nowrap;
}
.q-chip .mg-ic { width: 14px; height: 14px; }
.q-chip-temps { color: #9fc7e8; border-color: rgba(143,167,196,0.4); }
.q-chip-rubis { color: #ff9a9a; border-color: rgba(220,80,80,0.45); }
.q-changer {
    height: 28px; padding: 0 10px; border-radius: 7px; cursor: pointer;
    background: transparent; border: 1px solid var(--panel-border); color: var(--muted);
    font-family: var(--font-ui); font-size: 0.68rem; font-weight: 700;
    display: inline-flex; align-items: center; gap: 4px;
}
.q-changer .mg-ic { width: 15px; height: 15px; }
@media (hover: hover) and (pointer: fine) {
    .q-changer:hover { color: var(--text-light); border-color: var(--accent); }
}
.q-avis, .q-gains { margin-top: 8px; font-family: var(--font-ui); font-size: 0.7rem; line-height: 1.45; }
.q-avis { color: #e8b96a; }
.q-gains { color: var(--gold-bright); font-weight: 700; }
.q-gains .mg-ic { width: 14px; height: 14px; vertical-align: -2px; }
.q-tampon {
    position: absolute; right: 14px; top: 10px; pointer-events: none;
    padding: 3px 10px; border: 2px solid var(--success); border-radius: 6px;
    color: var(--success); font-family: var(--font-title); font-size: 0.8rem; font-weight: 700;
    letter-spacing: 0.08em; text-transform: uppercase; transform: rotate(-8deg);
    background: rgba(20,30,20,0.6);
}
.quests-bonus .q-coffre { font-size: 1.5rem; display: grid; place-items: center; }
.quests-bonus .q-coffre .mg-ic { width: 30px; height: 30px; }
.quests-bonus.ouvert { border-style: solid; border-color: rgba(212,165,72,0.55); }
.quests-bonus .txt .mg-ic { width: 13px; height: 13px; vertical-align: -2px; }

/* ---- Le calendrier : vingt-huit cases, une par jour de connexion ---- */
.cal-chapeau { margin: 0 0 12px; font-family: var(--font-ui); font-size: 0.8rem; color: var(--text-light); line-height: 1.5; }
.cal-chapeau b { color: var(--gold-bright); }
.cal-chapeau span { display: block; margin-top: 4px; font-size: 0.7rem; color: var(--muted); }
.cal-grille { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 6px; }
.cal-case {
    position: relative; min-width: 0; aspect-ratio: 0.8; padding: 5px 3px; border-radius: 8px;
    display: flex; flex-direction: column; align-items: center; justify-content: space-between;
    background: var(--surface); border: 1px solid var(--line-soft); color: var(--text-light);
    font-family: var(--font-ui); cursor: default; overflow: hidden;
}
.cal-case.semaine { border-color: rgba(212,165,72,0.55); background: linear-gradient(180deg, rgba(212,165,72,0.12), var(--surface)); }
.cal-jour { font-size: 0.56rem; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: 0.04em; white-space: nowrap; }
.cal-ic { display: grid; place-items: center; height: 28px; }
.cal-ic .mg-ic { width: 26px; height: 26px; }
.cal-qte { font-size: 0.58rem; font-weight: 700; line-height: 1.2; text-align: center; color: var(--text-light); font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.cal-case.ouverte { opacity: 0.55; }
.cal-case.ouverte .cal-ic, .cal-case.ouverte .cal-qte { opacity: 0.25; }
.cal-sceau {
    position: absolute; inset: 0; display: grid; place-items: center; pointer-events: none;
}
.cal-sceau .mg-ic {
    width: 30px; height: 30px; padding: 5px; border-radius: 50%;
    background: radial-gradient(circle at 34% 30%, #d9644c, #a3301f 55%, #561109);
    box-shadow: 0 2px 5px rgba(0,0,0,0.6); transform: rotate(-10deg);
}
.cal-case.prochaine {
    cursor: pointer; opacity: 1;
    border: 2px solid var(--gold-bright);
    background: linear-gradient(180deg, rgba(240,198,116,0.22), rgba(212,165,72,0.06));
    box-shadow: 0 0 14px rgba(240,198,116,0.35);
}
.cal-ouvrir {
    font-size: 0.56rem; font-weight: 800; text-transform: uppercase; letter-spacing: 0.06em;
    padding: 2px 6px; border-radius: 999px; background: var(--gold-bright); color: #1c1408;
}
.cal-case.prochaine .cal-qte { display: none; }
.cal-gains {
    margin-top: 12px; min-height: 1.4em; font-family: var(--font-ui); font-size: 0.78rem; color: var(--text-light);
    display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
}
.cal-gains b { color: var(--gold-bright); }
.cal-gains .mg-ic { width: 14px; height: 14px; vertical-align: -2px; }
.cal-eclat {
    position: absolute; left: 50%; top: 45%; width: 6px; height: 6px; margin: -3px;
    border-radius: 50%; background: #ffb3b3; box-shadow: 0 0 6px #ff5a5a; opacity: 0; pointer-events: none;
}
@media (max-width: 480px) {
    .cal-grille { grid-template-columns: repeat(4, minmax(0, 1fr)); }
    .cal-jour { font-size: 0.6rem; }
    .cal-qte { font-size: 0.62rem; }
}

/* ---- La mise en scene : a l'ouverture et au geste, jamais en boucle ---- */
.q-entree .quest-item { animation: qArrive 380ms ease-out backwards; animation-delay: calc(var(--i, 0) * 90ms); }
.q-entree .quest-progress-fill { animation: qRemplit 700ms cubic-bezier(.25,.8,.3,1) backwards; animation-delay: calc(250ms + var(--i, 0) * 90ms); }
@keyframes qArrive { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }
@keyframes qRemplit { from { transform: scaleX(0); } }
.quest-item.q-reclamee .q-tampon { animation: qTampon 420ms cubic-bezier(.2,1.4,.4,1) both; }
.quest-item.q-reclamee .q-gains { animation: qArrive 300ms 300ms ease-out backwards; }
@keyframes qTampon { from { opacity: 0; transform: scale(2.2) rotate(-20deg); } to { opacity: 1; transform: rotate(-8deg); } }
.quest-item.q-part { animation: qPart 260ms ease-in both; }
.quest-item.q-arrive { animation: qRetour 360ms cubic-bezier(.2,.9,.3,1.2) both; }
@keyframes qPart { to { opacity: 0; transform: scaleY(0.05); } }
@keyframes qRetour { from { opacity: 0; transform: scaleY(0.05); } to { opacity: 1; transform: none; } }
.quests-bonus.q-coffre-anime .q-coffre { animation: qCoffre 700ms cubic-bezier(.2,1.3,.4,1) both; }
@keyframes qCoffre {
    0% { transform: scale(1); }
    30% { transform: scale(1.45) rotate(-10deg); }
    55% { transform: scale(0.9) rotate(8deg); }
    100% { transform: scale(1) rotate(0); }
}
.cal-entree .cal-case { animation: qArrive 320ms ease-out backwards; animation-delay: calc(var(--i, 0) * 22ms); }
/* La case du jour respire deux fois a l'ouverture de l'onglet, puis se tient. */
.cal-entree .cal-case.prochaine { animation: qArrive 320ms ease-out backwards, calAppel 900ms ease-in-out 700ms 2; animation-delay: calc(var(--i, 0) * 22ms), 900ms; }
@keyframes calAppel { 50% { transform: scale(1.08); } }
.cal-case.cal-retourne { animation: calRetourne 600ms ease-in-out both; }
@keyframes calRetourne {
    0% { transform: scale(1); }
    25% { transform: scale(1.25); }
    50% { transform: scale(1.25) scaleX(0); }
    75% { transform: scale(1.25); }
    100% { transform: scale(1); }
}
.cal-case.cal-retourne .cal-eclat { animation: calEclat 700ms 250ms ease-out both; }
@keyframes calEclat {
    0% { opacity: 1; transform: rotate(var(--a)) translateX(4px) scale(1); }
    100% { opacity: 0; transform: rotate(var(--a)) translateX(46px) scale(0.3); }
}
.cal-case.cal-scelle .cal-sceau .mg-ic { animation: calSceau 420ms cubic-bezier(.2,1.4,.4,1) both; }
@keyframes calSceau { from { opacity: 0; transform: scale(2.2) rotate(-30deg); } to { opacity: 1; transform: rotate(-10deg); } }
.cal-gains.visible { animation: qArrive 300ms ease-out backwards; }

@media (prefers-reduced-motion: reduce) {
    .q-entree *, .cal-entree *, .quest-item.q-reclamee *, .quest-item.q-part, .quest-item.q-arrive,
    .quests-bonus.q-coffre-anime *, .cal-case.cal-retourne, .cal-case.cal-retourne *, .cal-case.cal-scelle *,
    .cal-gains.visible { animation: none !important; }
}
body.eco-energie :is(.q-entree *, .cal-entree *, .quest-item.q-reclamee *, .quest-item.q-part, .quest-item.q-arrive,
    .quests-bonus.q-coffre-anime *, .cal-case.cal-retourne, .cal-case.cal-retourne *, .cal-case.cal-scelle *,
    .cal-gains.visible) { animation: none !important; }

/* Le pourcentage de stockage n'apparaît qu'au survol : la barre suffit au coup d'œil.
   L'élément reste dans le DOM (lu par le JS de notifications de stockage plein). */
.storage-pct {
    position: absolute;
    right: 8px;
    top: 5px;
    font-family: var(--font-ui);
    font-size: 0.6rem;
    font-variant-numeric: tabular-nums;
    color: var(--muted);
    opacity: 0;
    transition: opacity .15s;
    pointer-events: none;
}@media (hover: hover) and (pointer: fine) {
.res-chip:hover .storage-pct { opacity: 1; }
}
/* =========================================================================
   RESPONSIVE MOBILE OVERHAUL
   ========================================================================= */
@media (max-width: 768px) {
    /* L'illustration du village reste visible : c'est le coeur du jeu.
       Elle occupe l'espace restant, le panneau devient une feuille glissante. */
    main {
        flex-direction: column;
        flex: 1;
        min-height: 0;
        height: auto;
        padding: 0;
        gap: 0;
    }

    #village-map {
        flex: 1;
        width: 100%;
        max-height: none;
        aspect-ratio: auto;
        border: 0;
        border-radius: 0;
        min-height: 0;
    }

    /* --- Top bar compacte : 2 lignes --- */
    #top-bar {
        height: auto;
        flex-wrap: wrap;
        align-items: center;
        padding: max(8px, env(safe-area-inset-top)) 10px 8px;
        gap: 7px;
    }

    .hud-crest { border-right: 0; padding-right: 0; flex: 1; min-width: 0; }
    .crest-badge { width: 28px; height: 28px; font-size: 15px; }
    .crest-name { font-size: 0.75rem; max-width: 40vw; }
    .crest-sub { font-size: 0.62rem; }

    .hud-actions { order: 2; gap: 5px; }
    .top-bar-icon-btn { width: 34px; height: 34px; font-size: 0.95rem; }

    #btn-prestige {
        order: 3;
        height: 32px;
        padding: 0 10px;
        font-size: 0.7rem;
    }
    .btn-prestige-label { display: none; }

    #active-buffs-container {
        order: 5;
        flex: 1 0 100%;
        display: flex;
        align-items: center;
        gap: 5px;
        overflow-x: auto;
        min-width: 0;
        scrollbar-width: none;
    }
    #active-buffs-container:empty { display: none; }
    #active-buffs-container::-webkit-scrollbar { display: none; }
    .buff-chip { font-size: 0.62rem; padding: 4px 8px; }

    .res-cluster {
        order: 6;
        flex: 1 0 100%;
        display: grid;
        grid-template-columns: repeat(3, 1fr);
        gap: 6px;
    }
    .res-chip {
        flex: none;
        min-width: 0;
        grid-template-columns: 18px 1fr;
        gap: 6px;
        padding: 5px 7px;
    }
    .res-chip.no-cap { flex: none; }
    .res-chip-icon { width: 18px; height: 18px; }
    #top-bar .res-chip-line span[id^="res-"] { font-size: 0.74rem; }
    .res-rate { font-size: 0.58rem; }
    .storage-pct { display: none; }

    /* Replier la barre : on ne garde que le blason et les actions */
    #mobile-topbar-toggle {
        display: flex;
        order: 7;
        width: 100%;
        justify-content: center;
        align-items: center;
        height: 16px;
        cursor: pointer;
        padding: 0;
        background: none;
        border: 0;
        color: inherit;
        touch-action: manipulation;
        -webkit-tap-highlight-color: transparent;
        -webkit-appearance: none;
        appearance: none;
    }
    #mobile-topbar-toggle .toggle-icon {
        color: var(--accent);
        font-size: 11px;
        transition: transform 0.3s;
    }
    #top-bar.collapsed .res-cluster,
    #top-bar.collapsed #active-buffs-container { display: none; }
    #top-bar.collapsed #mobile-topbar-toggle .toggle-icon { transform: rotate(180deg); }

    /* --- Panneau = feuille glissante, du bandeau a la barre d'onglets ---
       Elle tenait sur 48vh : une demi-hauteur fixe, meme quand on lit une
       liste. Or l'etat « montre-moi le village » existe deja -- l'onglet
       Village et la poignee font glisser la feuille hors de l'ecran. La
       demi-hauteur etait donc un TROISIEME etat dont personne n'a besoin,
       et il coutait 196 px de liste sur un telephone de 844.

       Elle s'accroche au bandeau MESURE (--hauteur-bandeau), jamais a un
       nombre en dur : le bandeau s'enroule sur deux ou trois lignes, porte
       les fioles de bonus par intermittence, se replie au chevron, et
       l'encoche du telephone s'y ajoute. Un nombre ecrit ici passerait un
       jour sous le bandeau sans que rien ne le dise. */
    #ui-panels {
        position: fixed;
        left: 0;
        right: 0;
        top: var(--hauteur-bandeau, 185px);
        bottom: calc(58px + env(safe-area-inset-bottom));
        z-index: 40;
        width: 100% !important;
        box-sizing: border-box;
        max-width: none;
        height: auto;
        margin: 0;
        /* La feuille ne defile pas : sa poignee et ses onglets restent en
           place, seul le corps de l'onglet courant defile. */
        gap: 0;
        padding: 0 10px calc(10px + var(--hauteur-travaux, 0px));
        overflow: hidden;
        background: linear-gradient(180deg, #1c1611, #120f0b);
        border-top: 1px solid var(--panel-border);
        border-radius: 18px 18px 0 0;
        box-shadow: 0 -12px 40px rgba(0,0,0,0.6);
        transform: translateY(0);
        transition: transform 0.28s cubic-bezier(0.4, 0, 0.2, 1);
    }
    body.village-view #ui-panels { transform: translateY(110%); }

    /* Seuls les enfants directs de la feuille : `.tab-content` sert aussi
       dans les fenetres, qui ont leur propre defilement. */
    #ui-panels > .tab-content.active {
        flex: 1;
        min-height: 0;
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
        overscroll-behavior-y: contain;
    }

    .sheet-handle {
        display: block;
        width: 44px;
        height: 4px;
        margin: 8px auto 4px;
        border-radius: 2px;
        background: var(--panel-border);
        cursor: pointer;
        flex-shrink: 0;
    }

    #build-menu, #construction-panel, #controls-panel { padding: 10px; }
    .sidebar-tabs { flex-wrap: nowrap; margin-bottom: 10px; flex-shrink: 0; }
    .tab-btn { padding: 7px 2px; font-size: 0.68rem; }

    .building-card { padding: 10px; }
    .building-header h3 { font-size: 0.86rem; }
    .cost-item { font-size: 0.68rem; padding: 3px 7px; }

    /* --- Travaux en cours : au pied de l'ecran, dans les deux vues ---
       Ils flottaient au-dessus de la feuille, c'est-a-dire POSES SUR
       L'ILLUSTRATION PEINTE : « Caserne (Nv. 13) - 2h 45m » se lisait sur
       des toits et des arbres. Ils tiennent maintenant la meme place que la
       feuille soit ouverte ou non, juste au-dessus de la barre d'onglets, et
       le degrade les detache de ce qui passe dessous -- la liste des
       batiments comme le village. La feuille leur reserve la place par son
       `padding-bottom`, donc aucune carte ne finit cachee dessous. */
    #bottom-taskbar {
        height: auto;
        padding: 10px 8px 6px;
        bottom: calc(58px + env(safe-area-inset-bottom));
        background: linear-gradient(180deg, rgba(18,15,11,0) 0, #120f0b 14px);
        border-top: 0;
        box-shadow: none;
        border-radius: 0;
        pointer-events: none;
        transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
    }
    /* Sans travaux, la barre doit disparaître : ancrée au-dessus de la feuille,
       translateY(100%) ne la sortait pas de l'écran et elle bloquait les onglets. */
    #bottom-taskbar:not(.visible) { display: none; }
    /* La liste doit rester défilable au doigt : seul le fond de la barre est transparent aux appuis.
       Le dégradé aux extrémités indique qu'il y a d'autres travaux à faire défiler. */
    .taskbar-list {
        pointer-events: auto;
        -webkit-overflow-scrolling: touch;
        overscroll-behavior-x: contain;
        -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 14px, #000 calc(100% - 14px), transparent 100%);
        mask-image: linear-gradient(90deg, transparent 0, #000 14px, #000 calc(100% - 14px), transparent 100%);
    }
    #bottom-taskbar h3 { display: none; }
    #no-construction-msg { display: none; }
    #taskbar-tab { display: none !important; }
    .taskbar-list { gap: 6px; padding-bottom: 0; }
    .active-construction-item {
        min-width: 0;
        flex: 0 0 auto;
        padding: 5px 10px;
        gap: 7px;
        border-radius: 999px;
        font-size: 0.7rem;
    }
    .active-construction-item .ac-name { font-size: 0.7rem; }
    .active-construction-item .progress-bar-container { width: 52px; height: 5px; }
    .active-construction-item .construction-time { font-size: 0.68rem; }

    /* --- Barre d'onglets fixe (zone du pouce) --- */
    #mobile-tabbar {
        display: grid;
        grid-template-columns: repeat(5, 1fr);
        position: fixed;
        left: 0;
        right: 0;
        bottom: 0;
        height: 58px;
        padding-bottom: env(safe-area-inset-bottom);
        z-index: 60;
        background: linear-gradient(180deg, #1c1611, #14100c);
        border-top: 1px solid var(--panel-border);
    }
    .mtab {
        position: relative;
        border: 0;
        background: transparent;
        color: var(--muted);
        cursor: pointer;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        gap: 3px;
        font-family: var(--font-ui);
        font-size: 0.6rem;
        padding: 0;
    }
    .mtab .i { font-size: 1.05rem; line-height: 1; }
    .mtab.active { color: var(--gold-bright); }
    .mtab.active::before {
        content: "";
        position: absolute;
        top: 0;
        left: 22%;
        right: 22%;
        height: 2px;
        background: var(--accent);
        border-radius: 0 0 2px 2px;
    }
    .mtab-badge {
        position: absolute;
        top: 5px;
        right: 50%;
        margin-right: -20px;
        min-width: 16px;
        height: 16px;
        padding: 0 4px;
        box-sizing: border-box;
        border-radius: 8px;
        background: var(--accent);
        color: #1a1208;
        font-size: 0.6rem;
        font-weight: 700;
        line-height: 16px;
        text-align: center;
    }

    .modal-content {
        width: auto !important;
        max-width: none !important;
        box-sizing: border-box;
        padding: 12px !important;
        margin: 0;
        max-height: calc(88vh - 60px) !important;
    }

    /* Bandeau de protection au-dessus de la barre d'onglets */
    #protection-banner {
        top: auto;
        bottom: calc(58px + 10px);
        left: 10px;
        right: 10px;
        padding: 8px 15px;
        font-size: 12px;
        flex-direction: column;
        align-items: flex-start;
        gap: 4px;
    }

    /* Classement : lisibilité sur petit écran */
    .leaderboard-tabs { flex-wrap: wrap; gap: 5px !important; }
    .btn-tab-premium { flex: 1 1 30%; font-size: 0.8rem; padding: 5px; }
    .btn-tab-premium img { width: 24px !important; }
    #modal-scoreboard { width: 100% !important; max-width: 100% !important; padding: 5px !important; }
    .scoreboard-table-premium { font-size: 0.8rem; }
    .scoreboard-table-premium th, .scoreboard-table-premium td { padding: 6px 4px; font-size: 0.8rem; }
    .scoreboard-table-premium td:nth-child(2) { font-size: 0.85rem; }
}

/* =========================================================================
   CASERNE
   ========================================================================= */
.mil-modal { padding: 0; display: flex; flex-direction: column; max-height: 90vh; }
.mil-head { padding: 16px 18px 0; flex-shrink: 0; }
.mil-head-top { display: flex; align-items: center; gap: 10px; }
.mil-head-top h2 {
    flex: 1; margin: 0; font-size: 1.05rem; color: var(--gold-bright);
    text-align: left; border: 0; padding: 0;
}
.help-dot {
    width: 22px; height: 22px; border-radius: 50%;
    background: var(--surface-2); border: 1px solid var(--panel-border); color: var(--muted);
    display: inline-flex; align-items: center; justify-content: center;
    font-family: var(--font-ui); font-size: 0.72rem; cursor: help;
}
.mil-head .tooltip-text {
    left: auto; right: 0; margin-left: 0;
    width: max-content; max-width: min(280px, calc(100vw - 80px));
    text-align: left;
}
.modal-close.mil-close {
    position: static; width: 30px; height: 30px; border-radius: 8px;
    border: 1px solid var(--panel-border); background: transparent; color: var(--muted);
    font-size: 0.8rem; line-height: 1; flex-shrink: 0;
}@media (hover: hover) and (pointer: fine) {
.modal-close.mil-close:hover { color: var(--text-light); border-color: var(--accent); background: transparent; }
}

.army-strip { display: flex; gap: 8px; margin-top: 14px; }
.army-strip .stat {
    flex: 1; min-width: 0; padding: 8px 10px;
    background: var(--surface); border: 1px solid var(--line-soft); border-radius: var(--radius-sm);
    font-family: var(--font-ui);
}
.army-strip .k { font-size: 0.6rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--muted); }
.army-strip .v { font-size: 0.9rem; font-weight: 700; margin-top: 2px; display: flex; align-items: baseline; gap: 4px; font-variant-numeric: tabular-nums; }
.army-strip .v small { font-size: 0.66rem; font-weight: 400; color: var(--muted); }
.cap-bar { height: 4px; border-radius: 2px; background: #0c0a07; margin-top: 6px; overflow: hidden; }
.cap-bar > i { display: block; height: 100%; width: 0%; background: linear-gradient(90deg, #8a6a2c, var(--accent)); transition: width .3s; }
.cap-bar.over > i { background: var(--danger); }

.barracks-tabs {
    display: flex; gap: 4px; margin-top: 14px; padding: 4px;
    background: var(--surface); border: 1px solid var(--line-soft); border-radius: 10px;
}
.barracks-tabs button {
    flex: 1 1 auto; min-width: 0; padding: 8px 4px; border: 0; border-radius: 7px; cursor: pointer;
    background: transparent; color: var(--muted);
    font-family: var(--font-ui); font-size: 0.74rem; font-weight: 600;
    display: flex; align-items: center; justify-content: center; gap: 5px;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}@media (hover: hover) and (pointer: fine) {
.barracks-tabs button:hover { color: var(--text-light); }
}
.barracks-tabs button.on { background: var(--surface-3); color: var(--gold-bright); box-shadow: inset 0 0 0 1px var(--panel-border); }
.seg-pill {
    min-width: 17px; height: 17px; padding: 0 4px; border-radius: 9px;
    background: var(--danger); color: #fff; font-size: 0.6rem; font-weight: 700;
    display: inline-grid; place-items: center;
}

.mil-body { flex: 1; overflow-y: auto; padding: 14px 18px 4px; text-align: left; max-height: none; }
.mil-note { font-size: 0.75rem; color: var(--muted); margin-bottom: 12px; font-family: var(--font-ui); }

/* --- Carte de troupe --- */
.troop-card {
    display: grid; grid-template-columns: 58px 1fr; gap: 12px;
    background: var(--surface); border: 1px solid var(--line-soft);
    border-radius: var(--radius); padding: 12px; margin-bottom: 10px;
}
.portrait {
    width: 58px; height: 58px; border-radius: 10px; overflow: hidden; position: relative;
    background: linear-gradient(160deg, var(--surface-3), #171310); border: 1px solid var(--panel-border);
    display: grid; place-items: center;
}
.portrait img { width: 100%; height: 100%; object-fit: cover; }
.portrait-emoji { font-size: 1.6rem; }
.portrait .owned {
    position: absolute; right: -1px; bottom: -1px;
    background: rgba(14,11,8,.92); border: 1px solid var(--panel-border);
    border-radius: 7px 0 9px 0; padding: 1px 6px;
    font-family: var(--font-ui); font-size: 0.64rem; font-weight: 700; color: var(--gold-bright);
}
.troop-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.troop-name { font-family: var(--font-title); font-size: 0.9rem; }
.weapon-tag {
    font-family: var(--font-ui); font-size: 0.58rem; font-weight: 700;
    letter-spacing: 0.04em; text-transform: uppercase;
    padding: 2px 7px; border-radius: 999px; border: 1px solid;
}
.weapon-tag.sword { color: #e0c08a; border-color: #6a5326; background: rgba(212,165,72,.1); }
.weapon-tag.axe { color: #d99a7a; border-color: #6b4030; background: rgba(207,106,85,.1); }
.weapon-tag.lance { color: #9dc0d6; border-color: #3c5568; background: rgba(122,167,199,.1); }
.weapon-tag.bow { color: #a9cf9f; border-color: #44603c; background: rgba(116,189,122,.1); }
.weapon-tag.none { color: var(--muted); border-color: var(--panel-border); }
.weapon-tag.lock { color: var(--danger); border-color: #6b3328; background: rgba(207,106,85,.12); }
.troop-card.locked { opacity: .62; }

.matchup { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 7px; font-family: var(--font-ui); font-size: 0.68rem; color: var(--muted); }
.matchup .good { color: var(--success); }
.matchup .bad { color: var(--danger); }

.troop-stats { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; align-items: center; }
.troop-stats .chip-pow { color: var(--gold-bright); border-color: rgba(212,165,72,.3); }

/* --- Sélecteur de quantité --- */
.qty-row { display: flex; align-items: center; gap: 8px; margin-top: 10px; flex-wrap: wrap; }
.stepper { display: flex; align-items: center; border: 1px solid var(--panel-border); border-radius: 8px; overflow: hidden; flex-shrink: 0; }
.stepper button {
    width: 32px; height: 32px; border: 0; background: var(--surface-2); color: var(--text-light);
    font-size: 1rem; line-height: 1; cursor: pointer;
}@media (hover: hover) and (pointer: fine) {
.stepper button:hover:not(:disabled) { background: var(--surface-3); color: var(--gold-bright); }
}
.stepper button:disabled { opacity: .4; cursor: not-allowed; }
.stepper input {
    width: 48px; height: 32px; border: 0;
    border-left: 1px solid var(--panel-border); border-right: 1px solid var(--panel-border);
    background: #0c0a07; color: var(--text-light); text-align: center;
    font-family: var(--font-ui); font-size: 0.82rem; font-variant-numeric: tabular-nums;
    -moz-appearance: textfield;
}
.stepper input::-webkit-outer-spin-button, .stepper input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.btn-max {
    height: 32px; padding: 0 10px; border-radius: 8px; cursor: pointer;
    background: transparent; border: 1px solid var(--panel-border); color: var(--muted);
    font-family: var(--font-ui); font-size: 0.68rem; font-weight: 600; white-space: nowrap;
}@media (hover: hover) and (pointer: fine) {
.btn-max:hover:not(:disabled) { color: var(--gold-bright); border-color: var(--accent); }
}
.btn-max:disabled { opacity: .45; cursor: not-allowed; }
.btn-troop {
    flex: 1; min-width: 120px; height: 32px; border-radius: 8px; cursor: pointer;
    background: linear-gradient(180deg, #d9ad51, #b5893a); border: 1px solid #eac57a;
    color: #1c1408; font-family: var(--font-ui); font-size: 0.74rem; font-weight: 700;
}@media (hover: hover) and (pointer: fine) {
.btn-troop:hover:not(:disabled) { background: linear-gradient(180deg, #e6bb63, #c2953f); }
}
.btn-troop:disabled { background: transparent; border-color: var(--panel-border); color: var(--muted); cursor: not-allowed; }
.total-line { margin-top: 7px; font-family: var(--font-ui); font-size: 0.68rem; color: var(--muted); font-variant-numeric: tabular-nums; }
.total-line b { color: var(--text-light); }

/* --- Guerre --- */
.war-field { margin-bottom: 14px; }
.war-label {
    display: flex; justify-content: space-between; align-items: center;
    font-family: var(--font-ui); font-size: 0.64rem; text-transform: uppercase;
    letter-spacing: 0.08em; color: var(--muted); margin-bottom: 6px;
}
.war-label .actions { text-transform: none; letter-spacing: 0; }
.war-label .actions button {
    background: none; border: 0; color: var(--accent); cursor: pointer;
    font-family: var(--font-ui); font-size: 0.7rem; padding: 0 4px;
}@media (hover: hover) and (pointer: fine) {
.war-label .actions button:hover { color: var(--gold-bright); text-decoration: underline; }
}
input.war-input {
    width: 100%; height: 40px; padding: 0 12px; border-radius: var(--radius-sm);
    background: #0c0a07; border: 1px solid var(--panel-border); color: var(--text-light);
    font-family: var(--font-ui); font-size: 0.82rem; box-sizing: border-box;
}
input.war-input:focus { outline: none; border-color: var(--accent); }
input.war-input::placeholder { color: var(--muted); }
.send-row {
    display: grid; grid-template-columns: 34px 1fr auto; gap: 10px; align-items: center;
    padding: 9px 10px; margin-bottom: 8px;
    background: var(--surface); border: 1px solid var(--line-soft); border-radius: var(--radius-sm);
}
.send-row .portrait { width: 34px; height: 34px; border-radius: 7px; }
.send-row .nm { font-family: var(--font-ui); font-size: 0.78rem; min-width: 0; }
.send-row .nm small { display: block; color: var(--muted); font-size: 0.66rem; margin-top: 2px; }
.war-summary {
    display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px;
    padding: 12px; margin-bottom: 14px; font-family: var(--font-ui);
    background: rgba(212,165,72,.06); border: 1px dashed rgba(212,165,72,.35); border-radius: var(--radius);
}
.war-summary .k { font-size: 0.58rem; text-transform: uppercase; letter-spacing: 0.07em; color: var(--muted); }
.war-summary .v { font-size: 0.88rem; font-weight: 700; margin-top: 3px; font-variant-numeric: tabular-nums; }
.war-summary .v.gold { color: var(--gold-bright); }

.tactic-note {
    display: flex; align-items: center; justify-content: center; gap: 8px; flex-wrap: wrap;
    padding: 10px; margin-bottom: 14px; border-radius: var(--radius);
    background: var(--surface); border: 1px solid var(--line-soft);
    font-family: var(--font-ui); font-size: 0.7rem; color: var(--muted); text-align: center;
}
.tactic-note b { color: var(--text-light); }

/* --- Infirmerie --- */
.heal-row {
    display: grid; grid-template-columns: 40px 1fr auto; gap: 12px; align-items: center;
    padding: 10px 12px; margin-bottom: 8px;
    background: var(--surface); border: 1px solid var(--line-soft); border-radius: var(--radius);
}
.heal-row .portrait { width: 40px; height: 40px; border-radius: 8px; filter: grayscale(.55); }
.heal-row .nm { font-family: var(--font-ui); font-size: 0.82rem; }
.heal-row .nm small { display: block; color: var(--muted); font-size: 0.68rem; margin-top: 3px; }

/* Les lits de l'infirmerie (1.26.6) : une case par soigneur. Le chirurgien du
   camp est gratuit ; chaque frere infirmier recrute ajoute un lit, et c'est sur le
   lit vide qu'on le recrute -- l'action vit la ou l'on voit le manque. */
.inf-lits { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 8px; margin: 8px 0 4px; }
.inf-lit {
    border: 1px solid var(--line-soft); border-radius: 10px; padding: 9px 10px 10px;
    background: var(--surface); font-family: var(--font-ui); font-size: .78rem;
    display: flex; flex-direction: column; gap: 5px; min-height: 86px; min-width: 0;
}
.inf-lit .qui { display: flex; align-items: center; gap: 6px; color: var(--muted); font-size: .68rem; text-transform: uppercase; letter-spacing: .06em; }
.inf-lit .qui .mg-ic { width: 15px; height: 15px; flex: none; }
.inf-lit .pat { display: flex; align-items: center; gap: 6px; font-size: .84rem; color: var(--text-light); }
.inf-lit .pat .mg-ic { width: 18px; height: 18px; flex: none; }
.inf-lit .bar { height: 6px; border-radius: 4px; background: rgba(0,0,0,.35); overflow: hidden; }
.inf-lit .bar i { display: block; height: 100%; background: linear-gradient(90deg, #7fbf7a, #b6e3a8); }
.inf-lit .t { color: var(--muted); font-size: .7rem; font-variant-numeric: tabular-nums; }
.inf-lit.libre { border-style: dashed; justify-content: center; }
.inf-lit.libre .pat { color: #a7d79b; }
.inf-lit.ferme { border-style: dashed; opacity: .55; justify-content: center; }
.inf-lit.recrue { border-style: dashed; border-color: rgba(212,175,55,.55); background: rgba(212,175,55,.06); }
.inf-lit.recrue .pat { color: var(--gold, #d4af37); }
.inf-lit.forme .bar i { background: linear-gradient(90deg, #c9a64a, #f0d68a); }
.inf-lit .prix { display: flex; flex-wrap: wrap; gap: 4px 8px; color: var(--muted); font-size: .7rem; }
.inf-lit .prix .mg-ic { width: 13px; height: 13px; }
.inf-lit .btn-troop { min-width: 0; padding: 0 10px; height: 30px; font-size: .75rem; margin-top: auto; }
.inf-lit .refus { color: #e59a8a; font-size: .68rem; }
.mil-sub-n.inf-n { color: #a7d79b; }
/* Le frere infirmier a un visage : un medaillon sur le lit qu'il tient, son
   portrait en pied sur le lit qu'on peut lui confier. Le portrait est en pied
   (360 x 800) : on le cadre sur la tete et les epaules. */
.inf-lit .qui .inf-av {
    width: 18px; height: 18px; flex: none; border-radius: 50%;
    object-fit: cover; object-position: 50% 6%; background: rgba(0,0,0,.35);
    border: 1px solid var(--line-soft);
}
.inf-frere { display: flex; align-items: center; gap: 8px; min-width: 0; }
.inf-frere img {
    width: 42px; height: 56px; flex: none; border-radius: 8px;
    object-fit: cover; object-position: 50% 4%;
    background: radial-gradient(circle at 50% 30%, rgba(212,175,55,.18), rgba(0,0,0,.3));
    border: 1px solid rgba(212,175,55,.35);
}
.inf-frere > div { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; min-width: 0; }
.inf-fiche {
    display: inline-flex; align-items: center; gap: 4px;
    font-family: var(--font-ui); font-size: 0.62rem; font-weight: 700;
    letter-spacing: 0.03em; text-transform: uppercase;
    padding: 3px 8px; border-radius: 999px; cursor: pointer;
    color: var(--gold-bright); background: rgba(212,165,72,.08);
    border: 1px solid var(--panel-border);
}
.inf-fiche .mg-ic { width: 13px; height: 13px; }
.inf-fiche b { color: var(--text-light); font-weight: 800; }
.inf-fiche:hover, .inf-fiche:focus-visible { background: rgba(212,165,72,.18); }
.ft-fiche-3d { margin: 8px 0 2px; font-size: .68rem; padding: 5px 12px; }
.inf-regles { font-family: var(--font-ui); font-size: .72rem; color: var(--muted); margin: 4px 0 8px; display: flex; flex-direction: column; gap: 2px; }
@media (max-width: 520px) {
    .inf-lit { min-height: 0; padding: 7px 9px 8px; gap: 4px; }
    .inf-lit .qui { font-size: .6rem; }
}

/* --- File d'attente --- */
.queue-item {
    display: flex; align-items: center; gap: 10px;
    padding: 8px 10px; margin-bottom: 6px;
    background: var(--surface); border: 1px solid var(--line-soft); border-radius: var(--radius-sm);
    font-family: var(--font-ui); font-size: 0.74rem;
}
.queue-item .q-name { flex: 1; min-width: 0; }
.queue-item .progress-bar-container { width: 70px; }
.queue-item .q-time { color: var(--accent); font-variant-numeric: tabular-nums; font-size: 0.7rem; white-space: nowrap; }
.btn-cancel {
    background: none; border: 0; color: var(--muted); cursor: pointer; font-size: 0.9rem; padding: 0 2px;
}@media (hover: hover) and (pointer: fine) {
.btn-cancel:hover { color: var(--danger); }
}

.mil-empty { text-align: center; color: var(--muted); font-family: var(--font-ui); font-size: 0.8rem; padding: 26px 0; }
.mil-sub { font-family: var(--font-title); font-size: 0.85rem; color: var(--gold-bright); margin: 16px 0 8px; }

/* --- Barre d'action --- */
.barracks-action-bar {
    display: flex; align-items: center; gap: 12px; flex-shrink: 0;
    padding: 12px 18px; border-top: 1px solid var(--line-soft);
    background: linear-gradient(180deg, rgba(28,22,17,.6), #16120d);
}
.barracks-action-bar .info { flex: 1; min-width: 0; font-family: var(--font-ui); font-size: 0.7rem; color: var(--muted); }
.barracks-action-bar .info b { display: block; color: var(--text-light); font-size: 0.82rem; margin-bottom: 2px; }
.btn-bar {
    height: 40px; padding: 0 20px; border-radius: var(--radius-sm); cursor: pointer; flex-shrink: 0;
    background: linear-gradient(180deg, #d9ad51, #b5893a); border: 1px solid #eac57a;
    color: #1c1408; font-family: var(--font-ui); font-size: 0.82rem; font-weight: 700;
}@media (hover: hover) and (pointer: fine) {
.btn-bar:hover:not(:disabled) { background: linear-gradient(180deg, #e6bb63, #c2953f); }
}
.btn-bar:disabled { background: transparent; border-color: var(--panel-border); color: var(--muted); cursor: not-allowed; }
.btn-bar.danger { background: linear-gradient(180deg, #b5583f, #8d3f2c); border-color: #d7836b; color: #fff; }@media (hover: hover) and (pointer: fine) {
.btn-bar.danger:hover:not(:disabled) { background: linear-gradient(180deg, #c76a50, #9c4a34); }
}

@media (max-width: 768px) {
    .mil-modal { max-height: 88vh; }
    .mil-head { padding: 14px 12px 0; }
    .mil-body { padding: 12px 12px 4px; }
    .barracks-action-bar { padding: 10px 12px; }
    .army-strip { gap: 6px; }
    .army-strip .stat { padding: 7px 8px; }
    .barracks-tabs { gap: 2px; padding: 3px; }
    .barracks-tabs button { font-size: 0.64rem; padding: 7px 3px; gap: 4px; }
    .troop-card { grid-template-columns: 48px 1fr; gap: 10px; padding: 10px; }
    .troop-card .portrait { width: 48px; height: 48px; }
    .btn-troop { min-width: 92px; }
}

@media (max-width: 360px) {
    .barracks-tabs button { font-size: 0.6rem; padding: 7px 2px; gap: 3px; }
    .army-strip .v { font-size: 0.82rem; }
}

/* ======================================================
   ACADÉMIE — arbre de technologies
   ====================================================== */
.aca-body { flex: 1; display: grid; grid-template-columns: 1fr 290px; min-height: 0; }
.aca-tree { overflow-y: auto; padding: 14px 16px 20px; text-align: left; }

.tech-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px 12px; align-items: start; }
.branch-head {
    display: flex; align-items: center; gap: 6px; padding: 7px 9px;
    background: var(--surface); border: 1px solid var(--line-soft); border-radius: 8px;
    font-family: var(--font-ui); font-size: 0.66rem; font-weight: 700;
    text-transform: uppercase; letter-spacing: 0.06em; white-space: nowrap; overflow: hidden;
}
.branch-head.eco { color: #a9cf9f; }
.branch-head.mil { color: #d99a7a; }
.branch-head.med { color: #9dc0d6; }
.branch-head.exp { color: #e0c08a; }

.tier-label {
    grid-column: 1 / -1; display: flex; align-items: center; gap: 10px; margin-top: 8px;
    font-family: var(--font-ui); font-size: 0.58rem; text-transform: uppercase;
    letter-spacing: 0.1em; color: var(--muted);
}
.tier-label::after { content: ""; flex: 1; height: 1px; background: var(--line-soft); }
.tier-cell { display: flex; flex-direction: column; gap: 9px; }

.tech-node {
    position: relative; display: block; width: 100%; text-align: left; cursor: pointer;
    background: var(--surface); border: 1px solid var(--line-soft); border-radius: 10px;
    padding: 9px 9px 10px; font-family: var(--font-ui); color: var(--text-light);
}
.tech-node .node-ico { width: 26px; height: 26px; object-fit: contain; display: block; margin-bottom: 5px; }
.tech-node .node-nm { display: block; font-size: 0.72rem; font-weight: 600; line-height: 1.2; }
.tech-node .node-ef { display: block; font-size: 0.62rem; color: var(--muted); margin-top: 3px; }
.tech-node .node-mark { position: absolute; top: 7px; right: 8px; font-size: 0.62rem; }
.tech-node .node-bar { height: 3px; border-radius: 2px; background: #0c0a07; margin-top: 6px; overflow: hidden; }
.tech-node .node-bar > i { display: block; height: 100%; background: linear-gradient(90deg, #8a6a2c, var(--accent)); }
.tech-node .node-time { display: block; font-size: 0.6rem; color: var(--accent); margin-top: 4px; font-variant-numeric: tabular-nums; }

.tech-node.done { border-color: #6a5326; background: rgba(212, 165, 72, 0.09); }
.tech-node.done .node-mark { color: var(--accent); }
.tech-node.available { border-color: var(--accent); box-shadow: 0 0 0 1px rgba(212,165,72,0.22), 0 4px 14px rgba(0,0,0,0.4); }
.tech-node.available .node-mark { color: var(--gold-bright); }
.tech-node.running { border-color: #3c5568; background: rgba(122, 167, 199, 0.08); }
.tech-node.locked { opacity: 0.5; }
.tech-node.sel { outline: 2px solid var(--gold-bright); outline-offset: 1px; }@media (hover: hover) and (pointer: fine) {
.tech-node:hover:not(.locked) { border-color: var(--accent); }
}
/* Amorce de liaison vers la technologie suivante de la branche. */
.tech-node.linked::after {
    content: ""; position: absolute; left: 50%; bottom: -10px; width: 2px; height: 10px;
    background: var(--line-soft); transform: translateX(-50%);
}
.tech-node.linked.done::after { background: var(--accent); }

/* --- panneau de détail --- */
.aca-side {
    position: relative; border-left: 1px solid var(--line-soft); background: var(--surface);
    padding: 16px 16px 14px; display: flex; flex-direction: column; gap: 10px;
    overflow-y: auto; text-align: left; font-family: var(--font-ui);
}
.aca-detail-close { display: none; }
.aca-hint { font-size: 0.74rem; color: var(--muted); margin: 0; }
.aca-detail-head { display: flex; gap: 10px; align-items: flex-start; }
.aca-detail-head img { width: 40px; height: 40px; object-fit: contain; flex-shrink: 0; }
.aca-detail-head h3 { margin: 0; font-size: 0.92rem; color: var(--gold-bright); font-family: var(--font-ui); }
.aca-detail-sub { font-size: 0.68rem; color: var(--muted); margin-top: 3px; }
.aca-rows .k-row {
    display: flex; justify-content: space-between; gap: 10px; font-size: 0.7rem;
    padding: 5px 0; border-bottom: 1px solid var(--line-soft);
}
.aca-rows .k { color: var(--muted); }
.aca-rows .v { color: var(--text-light); text-align: right; }
.aca-prereq { font-size: 0.68rem; color: var(--muted); line-height: 1.5; }
.aca-prereq b { color: var(--text-light); }
.aca-acquired {
    margin-top: auto; height: 40px; display: grid; place-items: center; border-radius: var(--radius-sm);
    background: rgba(212,165,72,0.12); border: 1px solid #6a5326; color: var(--gold-bright);
    font-size: 0.8rem; font-weight: 700;
}
.aca-acquired.running { background: rgba(122,167,199,0.1); border-color: #3c5568; color: #9dc0d6; }
.btn-res {
    margin-top: auto; height: 40px; border-radius: var(--radius-sm); cursor: pointer;
    background: linear-gradient(180deg, #d9ad51, #b5893a); border: 1px solid #eac57a;
    color: #1c1408; font-family: var(--font-ui); font-size: 0.82rem; font-weight: 700;
}@media (hover: hover) and (pointer: fine) {
.btn-res:hover:not(:disabled) { background: linear-gradient(180deg, #e6bb63, #c2953f); }
}
.btn-res:disabled { background: transparent; border-color: var(--panel-border); color: var(--muted); cursor: not-allowed; }

/* --- sélecteur de branche : mobile seulement --- */
.aca-branch-tabs { display: none; }
.seg-count { font-size: 0.58rem; color: var(--muted); font-variant-numeric: tabular-nums; }

@media (max-width: 768px) {
    .aca-body { grid-template-columns: 1fr; position: relative; }
    .aca-tree { padding: 12px 12px 20px; }
    .tech-grid { grid-template-columns: 1fr; gap: 9px; }
    .branch-head { display: none; }
    .tier-label { margin-top: 4px; }

    .aca-branch-tabs {
        display: flex; gap: 2px; margin-top: 10px; padding: 3px;
        background: var(--surface); border: 1px solid var(--line-soft); border-radius: 10px;
    }
    .aca-branch-tabs button {
        flex: 1 1 auto; min-width: 0; padding: 7px 3px; border: 0; border-radius: 7px; cursor: pointer;
        background: transparent; color: var(--muted); white-space: nowrap;
        font-family: var(--font-ui); font-size: 0.64rem; font-weight: 600;
        display: flex; align-items: center; justify-content: center; gap: 4px;
    }
    .aca-branch-tabs button.on { background: var(--surface-3); color: var(--gold-bright); box-shadow: inset 0 0 0 1px var(--panel-border); }

    /* Une seule branche à l'écran : le reste est retiré du flux. */
    .aca-tree[data-branch="eco"] .tier-cell:not([data-branch="eco"]),
    .aca-tree[data-branch="eco"] .tier-label:not(.has-eco),
    .aca-tree[data-branch="mil"] .tier-cell:not([data-branch="mil"]),
    .aca-tree[data-branch="mil"] .tier-label:not(.has-mil),
    .aca-tree[data-branch="med"] .tier-cell:not([data-branch="med"]),
    .aca-tree[data-branch="med"] .tier-label:not(.has-med),
    .aca-tree[data-branch="exp"] .tier-cell:not([data-branch="exp"]),
    .aca-tree[data-branch="exp"] .tier-label:not(.has-exp) { display: none; }

    /* Le détail devient une feuille basse, absente tant que rien n'est choisi. */
    .aca-side {
        position: absolute; left: 0; right: 0; bottom: 0; z-index: 5;
        border-left: 0; border-top: 1px solid var(--panel-border);
        border-radius: 14px 14px 0 0; background: var(--surface-2);
        box-shadow: 0 -10px 30px rgba(0,0,0,0.6); max-height: 62%;
        padding: 14px 16px 16px;
    }
    .aca-side:not(.open) { display: none; }
    .aca-detail-close {
        display: block; position: absolute; top: 10px; right: 12px;
        width: 26px; height: 26px; border-radius: 7px; cursor: pointer;
        background: transparent; border: 1px solid var(--panel-border); color: var(--muted); font-size: 0.7rem;
    }
    .aca-detail-head img { width: 34px; height: 34px; }
    .aca-detail-head h3 { font-size: 0.86rem; }
}

/* Barres de défilement des écrans refondus : discrètes, sur piste transparente,
   au lieu de celles du navigateur. */
.aca-tree, .aca-side, .mil-body, .lb-body, #player-dropdown, #battle-reports-list, #active-battles-list {
    scrollbar-width: thin;
    scrollbar-color: var(--line-soft) transparent;
}
.aca-tree::-webkit-scrollbar,
.aca-side::-webkit-scrollbar,
.mil-body::-webkit-scrollbar,
.lb-body::-webkit-scrollbar,
#player-dropdown::-webkit-scrollbar,
#battle-reports-list::-webkit-scrollbar,
#active-battles-list::-webkit-scrollbar { width: 8px; }
.aca-tree::-webkit-scrollbar-track,
.aca-side::-webkit-scrollbar-track,
.mil-body::-webkit-scrollbar-track,
.lb-body::-webkit-scrollbar-track,
#player-dropdown::-webkit-scrollbar-track,
#battle-reports-list::-webkit-scrollbar-track,
#active-battles-list::-webkit-scrollbar-track { background: transparent; }
.aca-tree::-webkit-scrollbar-thumb,
.aca-side::-webkit-scrollbar-thumb,
.mil-body::-webkit-scrollbar-thumb,
.lb-body::-webkit-scrollbar-thumb,
#player-dropdown::-webkit-scrollbar-thumb,
#battle-reports-list::-webkit-scrollbar-thumb,
#active-battles-list::-webkit-scrollbar-thumb {
    background: var(--line-soft); border-radius: 4px;
    border: 2px solid transparent; background-clip: padding-box;
}@media (hover: hover) and (pointer: fine) {
.aca-tree::-webkit-scrollbar-thumb:hover, .aca-side::-webkit-scrollbar-thumb:hover, .mil-body::-webkit-scrollbar-thumb:hover, .lb-body::-webkit-scrollbar-thumb:hover, #player-dropdown::-webkit-scrollbar-thumb:hover, #battle-reports-list::-webkit-scrollbar-thumb:hover, #active-battles-list::-webkit-scrollbar-thumb:hover { background: var(--accent); background-clip: padding-box; }
}

/* ======================================================
   CLASSEMENT
   ====================================================== */
.lb-tabs {
    display: flex; gap: 3px; margin-top: 12px; padding: 3px;
    background: var(--surface); border: 1px solid var(--line-soft); border-radius: 10px;
}
.lb-tabs button {
    flex: 1 1 auto; min-width: 0; padding: 7px 4px; border: 0; border-radius: 7px; cursor: pointer;
    background: transparent; color: var(--muted); white-space: nowrap;
    font-family: var(--font-ui); font-size: 0.68rem; font-weight: 600;
    display: flex; align-items: center; justify-content: center; gap: 5px;
}
.lb-tabs button.on { background: var(--surface-3); color: var(--gold-bright); box-shadow: inset 0 0 0 1px var(--panel-border); }@media (hover: hover) and (pointer: fine) {
.lb-tabs button:hover:not(.on) { color: var(--text-light); }
}

.lb-tools { display: flex; gap: 8px; margin-top: 10px; }
input.lb-search {
    flex: 1; min-width: 0; height: 34px; padding: 0 11px; border-radius: var(--radius-sm);
    background: #0c0a07; border: 1px solid var(--panel-border); color: var(--text-light);
    font-family: var(--font-ui); font-size: 0.76rem; box-sizing: border-box;
}
input.lb-search:focus { outline: none; border-color: var(--accent); }
input.lb-search::placeholder { color: var(--muted); }
.lb-near {
    height: 34px; padding: 0 11px; border-radius: var(--radius-sm); cursor: pointer; white-space: nowrap;
    background: transparent; border: 1px solid var(--panel-border); color: var(--muted);
    font-family: var(--font-ui); font-size: 0.7rem; font-weight: 600; flex-shrink: 0;
}
.lb-near.on { color: var(--gold-bright); border-color: var(--accent); }

.podium { display: grid; grid-template-columns: 1fr 1.15fr 1fr; gap: 8px; align-items: end; margin: 14px 0 2px; }
.podium .pod {
    background: var(--surface); border: 1px solid var(--line-soft); border-radius: 10px;
    padding: 10px 8px; text-align: center; cursor: pointer; font-family: var(--font-ui);
}@media (hover: hover) and (pointer: fine) {
.podium .pod:hover { border-color: var(--accent); }
}
.podium .pod.first { border-color: var(--accent); background: rgba(212,165,72,0.1); padding-top: 14px; }
.podium .medal { display: block; font-size: 1.1rem; }
.podium .nm { display: block; font-size: 0.74rem; font-weight: 700; color: var(--text-light); margin-top: 4px;
              overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.podium .sc { display: block; font-size: 0.66rem; color: var(--accent); margin-top: 2px; font-variant-numeric: tabular-nums; }

.lb-body { flex: 1; overflow-y: auto; padding: 10px 18px 14px; text-align: left; }
.lb-body .row {
    display: grid; grid-template-columns: 34px 1fr auto auto; gap: 10px; align-items: center;
    padding: 9px 10px; margin-bottom: 6px; cursor: pointer; font-family: var(--font-ui);
    background: var(--surface); border: 1px solid var(--line-soft); border-radius: var(--radius-sm);
}@media (hover: hover) and (pointer: fine) {
.lb-body .row:hover { border-color: var(--accent); }
}
.lb-body .row.me { border-color: var(--accent); background: rgba(212,165,72,0.1); }
.lb-body .rk { font-size: 0.8rem; font-weight: 700; color: var(--muted); text-align: center; font-variant-numeric: tabular-nums; }
.lb-body .rk.top { color: var(--gold-bright); }
.lb-body .row.me .rk { color: var(--gold-bright); }
.lb-body .nm { font-size: 0.8rem; font-weight: 600; color: var(--text-light); min-width: 0;
               overflow: hidden; text-overflow: ellipsis; }
.lb-body .nm em { color: var(--accent); font-style: normal; font-weight: 400; font-size: 0.72rem; }
.lb-body .nm small { display: block; color: var(--muted); font-size: 0.64rem; font-weight: 400; margin-top: 2px; }
.lb-body .val { font-size: 0.78rem; color: var(--accent); font-variant-numeric: tabular-nums; white-space: nowrap; }
.lb-body .atk {
    width: 28px; height: 28px; border-radius: 7px; cursor: pointer; flex-shrink: 0;
    background: transparent; border: 1px solid var(--panel-border); color: var(--muted); font-size: 0.72rem;
}@media (hover: hover) and (pointer: fine) {
.lb-body .atk:hover:not(:disabled) { color: #e08a70; border-color: #b5583f; }
}
.lb-body .atk:disabled { opacity: 0.25; cursor: not-allowed; }

.me-bar {
    flex-shrink: 0; display: flex; align-items: center; gap: 10px; padding: 10px 18px;
    background: var(--surface-3); border-top: 1px solid var(--panel-border);
    font-family: var(--font-ui); box-sizing: border-box;
}
.me-bar .rk { font-size: 1rem; font-weight: 700; color: var(--gold-bright); font-variant-numeric: tabular-nums; }
.me-bar .info { flex: 1; min-width: 0; font-size: 0.74rem; color: var(--text-light);
                overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.me-bar .info small { display: block; color: var(--muted); font-size: 0.64rem; margin-top: 2px; }
.me-bar .delta { font-size: 0.72rem; font-weight: 600; white-space: nowrap; }
.me-bar .delta.up { color: var(--success); }
.me-bar .delta.down { color: var(--danger); }
.me-bar .delta.flat { color: var(--muted); }

@media (max-width: 768px) {
    .lb-tabs button .lb-lbl { display: none; }
    .lb-tabs button { font-size: 0.9rem; padding: 8px 4px; }
    .lb-tools { margin-top: 8px; }
    .lb-near { padding: 0 9px; font-size: 0.66rem; }
    .lb-body { padding: 10px 12px 14px; }
    .lb-body .row { grid-template-columns: 28px 1fr auto auto; gap: 8px; padding: 8px 9px; }
    .me-bar { padding: 9px 12px; }
    .podium .nm { font-size: 0.68rem; }
}

/* --- Profil d'un seigneur, ouvert depuis le classement --- */
.profile-modal { padding: 0; display: block; overflow: hidden; }
.profile-modal .mil-head { padding: 16px 18px 0; }
.profile-modal h2 { margin: 0; font-size: 1.05rem; color: var(--gold-bright); font-family: var(--font-ui); flex: 1;
                    overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.profile-body { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; padding: 14px 18px 4px; text-align: left; }
.profile-card {
    background: var(--surface); border: 1px solid var(--line-soft);
    border-radius: var(--radius); padding: 12px 13px; font-family: var(--font-ui);
}
.profile-card h3 {
    margin: 0 0 8px; font-size: 0.72rem; font-family: var(--font-ui); color: var(--gold-bright);
    text-transform: uppercase; letter-spacing: 0.06em;
    display: flex; align-items: center; gap: 7px;
}
.profile-card h3 img { width: 18px; height: 18px; object-fit: contain; }
.profile-card .k-row {
    display: flex; justify-content: space-between; gap: 10px; align-items: baseline;
    font-size: 0.72rem; padding: 5px 0; border-bottom: 1px solid var(--line-soft);
}
.profile-card .k-row:last-child { border-bottom: 0; }
.profile-card .k { color: var(--muted); }
.profile-card .v { color: var(--text-light); font-variant-numeric: tabular-nums; text-align: right; }
.profile-card .v.good { color: var(--success); }
.profile-card .v.bad { color: var(--danger); }
.profile-action { padding: 10px 18px 16px; }
.profile-action .btn-bar { width: 100%; }

@media (max-width: 768px) {
    .profile-modal .mil-head { padding: 14px 12px 0; }
    .profile-body { grid-template-columns: 1fr; padding: 12px 12px 4px; }
    .profile-action { padding: 8px 12px 14px; }
}

/* --- Stockage (entrepôt et silo) --- */
.store-modal { padding: 0; display: block; overflow: hidden; }
.store-modal .mil-head { padding: 16px 18px 0; }
.store-modal h2 { margin: 0; font-size: 1.05rem; color: var(--gold-bright); font-family: var(--font-ui); flex: 1; }
.store-body { padding: 14px 18px 16px; text-align: left; font-family: var(--font-ui); max-height: none; }
.store-id { display: flex; align-items: center; gap: 14px; margin-bottom: 12px; }
.store-id img {
    width: 64px; height: 64px; object-fit: contain; padding: 8px; flex-shrink: 0;
    background: var(--surface); border: 1px solid var(--line-soft); border-radius: 10px;
}
.store-id .k { font-size: 0.6rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--muted); }
.store-id .v { font-size: 1.5rem; font-weight: 700; color: var(--gold-bright); margin-top: 2px; }

.store-gauge {
    background: var(--surface); border: 1px solid var(--line-soft);
    border-radius: var(--radius); padding: 12px 13px; margin-bottom: 10px;
}
.store-gauge-top {
    display: flex; justify-content: space-between; align-items: baseline; gap: 10px; margin-bottom: 9px;
    font-size: 0.64rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--muted);
}
.store-gauge-top .amt { color: var(--gold-bright); font-size: 0.78rem; text-transform: none;
                        letter-spacing: 0; font-weight: 700; font-variant-numeric: tabular-nums; }
.store-bar { height: 12px; border-radius: 6px; background: #0c0a07; overflow: hidden; }
.store-bar > i { display: block; height: 100%; width: 0%;
                 background: linear-gradient(90deg, #8a6a2c, var(--accent)); transition: width .4s; }
.store-bar > i.full { background: var(--danger); }

.store-rows { margin-bottom: 12px; }
.store-rows .k-row {
    display: flex; justify-content: space-between; gap: 10px; align-items: baseline;
    font-size: 0.72rem; padding: 7px 0; border-bottom: 1px solid var(--line-soft);
}
.store-rows .k { color: var(--muted); }
.store-rows .v { font-variant-numeric: tabular-nums; }

/* **Ce que la ressource produit, et pourquoi** (1.26.3). Un volet natif
   (`<details>`) : le total se lit replie, chaque bonus en le depliant. */
.pd { margin: 0 0 14px; border: 1px solid var(--panel-border); border-radius: var(--radius-sm);
    background: var(--surface-2); font-family: var(--font-ui); overflow: hidden; }
.pd > summary { list-style: none; cursor: pointer; display: grid; grid-template-columns: 1fr auto;
    align-items: baseline; gap: 2px 10px; padding: 12px 14px 10px; }
.pd > summary::-webkit-details-marker { display: none; }
.pd-tete .t { color: var(--muted); font-size: .76rem; text-transform: uppercase; letter-spacing: .06em; }
.pd-tete .v { color: var(--gold-bright); font-size: 1.3rem; font-weight: 700; font-variant-numeric: tabular-nums; text-align: right; }
.pd-sous { grid-column: 1 / -1; display: flex; flex-wrap: wrap; justify-content: space-between; gap: 2px 10px;
    color: var(--muted); font-size: .8rem; font-variant-numeric: tabular-nums; }
.pd .plus { color: var(--success); }
.pd .moins { color: var(--danger); }
.pd-solde { grid-column: 1 / -1; display: flex; justify-content: space-between; gap: 10px; margin-top: 4px;
    padding-top: 6px; border-top: 1px dashed var(--line-soft); font-size: .84rem; color: var(--text-light); }
.pd-solde b { font-variant-numeric: tabular-nums; }
.pd-ouvrir { grid-column: 1 / -1; display: flex; align-items: center; gap: 6px; margin-top: 6px;
    color: var(--accent); font-size: .78rem; }
.pd-ouvrir .mg-ic { width: 14px; height: 14px; }
.pd .pd-ouvrir-txt::after { content: 'Voir le détail des bonus'; }
.pd[open] .pd-ouvrir-txt::after { content: 'Replier'; }
.pd-l { display: grid; grid-template-columns: 22px minmax(0, 1fr) auto; gap: 8px; align-items: center;
    padding: 7px 14px; border-top: 1px solid var(--line-soft); font-size: .84rem; color: var(--text-light); }
.pd-l .i { display: flex; color: var(--accent); }
.pd-l .i .mg-ic { width: 18px; height: 18px; }
.pd-l .n small { display: block; color: var(--muted); font-size: .72rem; }
.pd-l .m { font-variant-numeric: tabular-nums; font-weight: 600; white-space: nowrap; }
.pd-l.tmp { background: rgba(116, 189, 122, .07); }
.pd-l.tmp-moins { background: rgba(207, 106, 85, .08); }
.pd-l.gris, .pd-l.gris .m { color: var(--muted); font-weight: 500; }
.pd-l.gris .i { color: var(--muted); opacity: .6; }
.pd-sep { padding: 8px 14px 4px; color: var(--muted); font-size: .7rem; text-transform: uppercase;
    letter-spacing: .06em; border-top: 1px solid var(--line-soft); }
.pd-pied { padding: 8px 14px 12px; color: var(--muted); font-size: .75rem; line-height: 1.45; border-top: 1px solid var(--line-soft); }

/* Avant de lancer une amelioration : ce que le batiment rendra apres. */
.prod-apres { margin: 2px 0 10px; padding: 9px 12px; border-radius: var(--radius-sm);
    background: rgba(116, 189, 122, .08); border: 1px solid rgba(116, 189, 122, .35);
    font-family: var(--font-ui); font-size: .84rem; color: var(--text-light); }
.prod-apres-l1 { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 2px 8px; align-items: baseline; }
.prod-apres .k { color: var(--muted); font-size: .72rem; text-transform: uppercase; letter-spacing: .05em; }
.prod-apres .chiffres { font-variant-numeric: tabular-nums; font-weight: 600; }
.prod-apres .fl { color: var(--muted); margin: 0 4px; }
.prod-apres .nouv { color: var(--success); }
.prod-apres-l2 { margin-top: 3px; color: var(--muted); font-size: .75rem; }
.prod-apres-l2 b { color: var(--success); font-variant-numeric: tabular-nums; }
.prod-detail-lien { margin-left: 6px; padding: 0; border: 0; background: none; color: var(--accent);
    font: inherit; text-decoration: underline; text-underline-offset: 2px; cursor: pointer; }

/* Le bonus du moment, sur la tuile qu'il touche, a cote du debit qu'il
   explique. En coin, il couvrait le stock ou le remplissage de l'entrepot. */
.res-bonus { align-self: center; padding: 0 4px; border-radius: 6px; white-space: nowrap;
    background: var(--success); color: #10220f; font: 700 9px/13px var(--font-ui); }
.res-bonus[hidden] { display: none; }
.res-bonus.moins { background: var(--danger); color: #2a0d07; }
.store-rows .v.good { color: var(--success); }
.store-rows .v.bad { color: var(--danger); }

.store-upgrade { border-top: 1px solid var(--line-soft); padding-top: 12px; }
.store-upgrade .chips { justify-content: flex-start; margin-bottom: 12px; }
.store-upgrade .btn-res { width: 100%; }
.btn-res.disabled { background: transparent; border-color: var(--panel-border); color: var(--muted); cursor: not-allowed; }

@media (max-width: 768px) {
    .store-modal .mil-head { padding: 14px 12px 0; }
    .store-body { padding: 12px 12px 14px; }
    .store-id img { width: 54px; height: 54px; }
}

/* --- Marché --- */
.mkt-tabs {
    display: flex; gap: 3px; margin-top: 12px; padding: 3px;
    background: var(--surface); border: 1px solid var(--line-soft); border-radius: 10px;
}
.mkt-tabs .market-tab-btn {
    flex: 1 1 auto; min-width: 0; padding: 8px 4px; border: 0; border-radius: 7px; cursor: pointer;
    background: transparent; color: var(--muted); white-space: nowrap;
    font-family: var(--font-ui); font-size: 0.72rem; font-weight: 600;
}
.mkt-tabs .market-tab-btn.active { background: var(--surface-3); color: var(--gold-bright); box-shadow: inset 0 0 0 1px var(--panel-border); }@media (hover: hover) and (pointer: fine) {
.mkt-tabs .market-tab-btn:hover:not(.active) { color: var(--text-light); }
}

/* **A quatre comptoirs, la barre ne tient plus sur un telephone.** Les libelles
   portent `white-space: nowrap`, donc ils ne se coupent pas : ils se serrent
   jusqu'a se toucher. Sous 480 px la barre passe donc sur deux rangs -- une
   barre qui defile cacherait un onglet, et un onglet cache n'existe pas. */
@media (max-width: 480px) {
    .mkt-tabs { flex-wrap: wrap; }
    .mkt-tabs .market-tab-btn { flex: 1 1 44%; font-size: 0.7rem; padding: 8px 6px; }
}

.mkt-trade, .mkt-form { display: flex; flex-direction: column; gap: 10px; }

/* Le formulaire d'une offre. Il respire plus que le reste des fenetres, et ce
   n'est pas de la coquetterie : c'est la seule saisie du jeu ou l'on compose
   DEUX montants en regard l'un de l'autre. Serres, les quatre champs se lisent
   comme une seule ligne de chiffres et on ne voit plus lequel va avec lequel. */
.mkt-form {
    background: var(--surface); border: 1px solid var(--line-soft);
    border-radius: var(--radius); padding: 16px; margin-bottom: 14px; gap: 14px;
}
/* `.mil-sub` porte une marge haute faite pour separer deux sections ; en tete
   d'un conteneur a `gap`, elle s'ajoute au gap et decolle le titre. */
.mkt-form .mil-sub { margin: 0; }

.mkt-swap { display: flex; align-items: stretch; gap: 12px; }
.mkt-swap > .mkt-select { flex: 1; min-width: 0; align-self: flex-end; }

/* Les deux cotes d'un troc sont deux panneaux, pas deux colonnes d'un meme
   bloc : c'est le fond qui dit ou finit « je cede » et ou commence « je
   demande ». */
.mkt-side {
    flex: 1; min-width: 0;
    background: var(--surface-2); border: 1px solid var(--panel-border);
    border-radius: var(--radius-sm); padding: 10px 11px 12px;
}
.mkt-side label {
    display: block; font-family: var(--font-ui);
    font-size: 0.64rem; text-transform: uppercase; letter-spacing: 0.09em;
    color: var(--muted); margin-bottom: 9px;
}
.mkt-pair { display: flex; gap: 8px; }
.mkt-pair .mkt-input { width: 84px; flex-shrink: 0; }
.mkt-pair .mkt-select { flex: 1; min-width: 0; }

/* La fleche se pose au milieu de la hauteur des deux panneaux, pas sur leur
   ligne de base : entre deux cartes, c'est le centre qui les relie. */
.mkt-swap > .mkt-arrow {
    align-self: center; padding: 0; flex-shrink: 0;
    display: flex; align-items: center; justify-content: center;
    width: 26px; height: 26px; border-radius: 50%;
    background: var(--surface-3); box-shadow: inset 0 0 0 1px var(--panel-border);
    font-size: 0.9rem;
}

/* Le taux se detache du formulaire par un filet : c'est une CONCLUSION, pas un
   champ de plus. */
.mkt-form .mkt-taux {
    justify-content: center; text-align: center;
    border-top: 1px solid var(--line-soft); padding-top: 12px; margin-top: 2px;
}
.mkt-form .btn-res { margin-top: 0; height: 42px; }

select.mkt-select, input.mkt-input {
    height: 38px; padding: 0 11px; border-radius: var(--radius-sm); box-sizing: border-box; width: 100%;
    background: #0c0a07; border: 1px solid var(--panel-border); color: var(--text-light);
    font-family: var(--font-ui); font-size: 0.78rem;
}
select.mkt-select {
    appearance: none; -webkit-appearance: none; cursor: pointer; padding-right: 26px;
    background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="%23d4a548"><path d="M7 10l5 5 5-5z"/></svg>');
    background-repeat: no-repeat; background-position: right 7px center;
}
select.mkt-select:focus, input.mkt-input:focus { outline: none; border-color: var(--accent); }
.choix-seigneur {
    display: flex; flex-direction: column; margin-top: 4px; max-height: 260px; overflow-y: auto;
    background: #0c0a07; border: 1px solid var(--panel-border); border-radius: var(--radius-sm);
}
.choix-ligne {
    min-height: 40px; padding: 8px 12px; text-align: left; background: none; border: 0;
    border-bottom: 1px solid var(--panel-border); color: var(--text-light);
    font-family: var(--font-ui); font-size: 0.82rem; cursor: pointer;
}
.choix-ligne:last-child { border-bottom: 0; }
/* Un `display` pose par une classe l'emporte sur l'attribut `hidden`. */
.choix-seigneur[hidden] { display: none; }
.choix-ligne:hover, .choix-ligne:focus-visible { background: rgba(212, 165, 72, 0.12); outline: none; }
input.mkt-input { text-align: center; font-variant-numeric: tabular-nums; }
input.mkt-input::placeholder { color: var(--muted); }

.mkt-actions { display: flex; gap: 8px; margin-bottom: 12px; }

/* ------------------------------------------------------------ la garde et le guet

   Une escorte se compose dans trois formulaires (poser une offre, en prendre
   une, se poster sur une route) : un seul bloc les habille tous les trois --
   trois listes de selecteurs qui divergeraient finiraient par se contredire. */
.mkt-garde {
    background: var(--surface-2); border: 1px solid var(--panel-border);
    border-radius: var(--radius-sm); padding: 10px 11px 11px;
}
.mkt-garde-tete {
    font-family: var(--font-ui); font-size: 0.64rem; text-transform: uppercase;
    letter-spacing: 0.09em; color: var(--muted); margin-bottom: 9px;
}
.mkt-garde-liste { display: flex; flex-direction: column; gap: 7px; margin-bottom: 8px; }
.mkt-garde-liste .mil-empty { margin: 0; }

.mkt-troupe { display: flex; align-items: center; gap: 10px; }
/* Le meme portrait que la Caserne, a la taille d'une ligne d'envoi. */
.mkt-troupe .portrait { width: 34px; height: 34px; border-radius: 7px; flex-shrink: 0; }
.mkt-t-nom {
    flex: 1; min-width: 0; font-family: var(--font-ui); font-size: 0.8rem;
    color: var(--text-light); display: flex; flex-direction: column; line-height: 1.25;
}
.mkt-t-nom small { font-size: 0.68rem; color: var(--muted); }
input.mkt-input.mkt-t-qte { width: 84px; flex-shrink: 0; height: 34px; }

/* Le chariot se clique sur la carte : il faut que cela se voie avant le clic,
   sinon le raccourci n'existe que pour qui le connait deja.

   **Et `.map-soldier` pose `pointer-events: none`.** Sans le lever ici, le
   curseur, la lueur au survol et le `onclick` etaient trois decorations : le
   clic traversait le chariot et n'atteignait jamais le raccourci. Le meme mode
   de panne que le `onclick` vers une fonction absente -- rien ne le dit, ni en
   lecture ni a l'usage. La carte se fait toujours glisser : le deplacement
   ecoute le cadre, et l'evenement remonte depuis le chariot. */
.map-soldier.mkt-guettable { cursor: pointer; pointer-events: auto; }
.map-soldier.mkt-guettable:hover { filter: brightness(1.25) drop-shadow(0 0 6px #c9a227); }
.mkt-actions .btn-max { flex: 1; height: 36px; }
.mkt-offers { max-height: 300px; overflow-y: auto; }
.mkt-offers { scrollbar-width: thin; scrollbar-color: var(--line-soft) transparent; }
.mkt-offers::-webkit-scrollbar { width: 8px; }
.mkt-offers::-webkit-scrollbar-track { background: transparent; }
.mkt-offers::-webkit-scrollbar-thumb { background: var(--line-soft); border-radius: 4px;
    border: 2px solid transparent; background-clip: padding-box; }

@media (max-width: 768px) {
    .mkt-swap { flex-direction: column; align-items: stretch; gap: 10px; }
    /* La fleche ne bascule que dans le FORMULAIRE, ou les deux cotes passent
       l'un sous l'autre. Dans une ligne du carnet, « 4 200 fer -> 9 800 or »
       reste sur une ligne : l'y faire pivoter donnait une fleche vers le bas
       au milieu d'une phrase horizontale. */
    .mkt-swap > .mkt-arrow { align-self: center; padding: 0; transform: rotate(90deg); }
    .mkt-pair .mkt-input { width: 88px; }
    .mkt-form { padding: 14px; gap: 12px; }
}

/* --- Le Marche Central, 1.22 ---
   Le bandeau du haut dit ce que le Marche permet : son niveau, ses chariots
   libres, la charge d'un attelage. Ce sont les trois chiffres dont depend
   toute decision prise dans cet ecran, donc ils sont au-dessus des onglets et
   non dans l'un d'eux. */
.mkt-bandeau {
    display: flex; gap: 8px; margin-bottom: 12px;
}
.mkt-b-case {
    flex: 1; min-width: 0; display: flex; flex-direction: column; align-items: center;
    gap: 2px; padding: 8px 6px; border-radius: 8px;
    background: var(--surface-3);
    box-shadow: inset 0 0 0 1px var(--panel-border);
}
.mkt-b-val { font-family: var(--font-ui); font-weight: 700; font-size: .92rem; color: var(--gold-bright); }
.mkt-b-lbl { font-family: var(--font-ui); font-size: .66rem; letter-spacing: .04em;
    text-transform: uppercase; color: var(--muted); text-align: center; }
.mkt-b-vide {
    flex: 1; padding: 10px; border-radius: 8px; text-align: center;
    font-family: var(--font-ui); font-size: .82rem; color: var(--muted);
    background: var(--surface-3);
    box-shadow: inset 0 0 0 1px var(--panel-border);
}

/* L'apercu d'un echange : ce qu'on donne, ce qu'on recoit. C'est une phrase,
   pas un titre -- donc la police de lecture. */
.mkt-taux {
    font-family: var(--font-ui); font-size: .82rem; color: var(--text-light);
    min-height: 1.2em; display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
}
.mkt-gris { color: var(--muted); }
.mkt-rouge { color: #e07a5f; }
.mkt-vert-t { color: #6fbf73; }
.btn-upgrade.mkt-vert { background: #27ae60; }
.mkt-note-sec { font-family: var(--font-ui); font-size: .76rem; color: var(--muted); }

/* Le compte du roi pour la journee.
   **Une jauge sans etiquette ne veut rien dire.** Vide, elle passait pour une
   panne ; pleine, on demande pourquoi. Ce n'est pas le sens du remplissage qui
   manquait, c'est la legende : on ne devine pas ce que mesure une barre nue
   posee entre un apercu et une phrase. */
.mkt-jauge-tete {
    display: flex; justify-content: space-between; align-items: baseline; gap: 10px;
    font-family: var(--font-ui); font-size: .68rem; letter-spacing: .04em;
    text-transform: uppercase; color: var(--muted); margin-bottom: 5px;
}
.mkt-jauge-tete #mkt-npc-compte {
    text-transform: none; letter-spacing: 0; font-weight: 700;
    color: var(--text-light); font-variant-numeric: tabular-nums;
}
.mkt-jauge {
    position: relative;
    height: 8px; border-radius: 4px; overflow: hidden;
    background: var(--line-soft); box-shadow: inset 0 0 0 1px var(--panel-border);
}
/* Et ce que l'echange en cours de saisie VA prendre, pose au bout de ce qui
   reste. C'est ce qui rend la barre utile au lieu de decorative : on voit d'un
   coup d'oeil si l'echange qu'on compose mange la journee entiere. */
.mkt-jauge-prise {
    position: absolute; top: 0; height: 100%; left: 0; width: 0;
    background: repeating-linear-gradient(135deg, #e07a5f 0 4px, #c4674f 4px 8px);
    transition: left .2s ease, width .2s ease;
}
/* La jauge porte CE QUI RESTE : pleine, le roi n'a rien pris. Elle vire au
   rouge quand il ne reste plus grand-chose -- c'est la seule chose qu'on ait
   besoin de lire sans lire. */
.mkt-jauge-in {
    height: 100%; width: 0%; border-radius: 3px;
    background: linear-gradient(90deg, #b5893a, #d4a548);
    transition: width .3s ease, background .3s ease;
}
.mkt-jauge-in.bas { background: linear-gradient(90deg, #a8533c, #e07a5f); }

/* Une ligne du carnet, ou une caravane sur les routes. */
.mkt-ligne {
    display: flex; align-items: center; justify-content: space-between; gap: 10px;
    padding: 10px 0; border-bottom: 1px solid var(--panel-border);
}
.mkt-ligne:last-child { border-bottom: none; }
.mkt-ligne-corps { min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.mkt-ligne-act { flex-shrink: 0; }
.mkt-qui { font-family: var(--font-ui); font-weight: 700; font-size: .82rem; color: var(--gold-bright); }
.mkt-troc { font-family: var(--font-ui); font-size: .86rem; color: var(--text-light);
    display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.mkt-troc .mkt-arrow { padding: 0; font-size: 1rem; }
.mkt-etat { font-family: var(--font-ui); font-size: .72rem; color: var(--muted); }
/* **`.mkt-etat` est declaree APRES `.mkt-rouge`**, a specificite egale : sans
   ces deux regles, la ligne qui explique un refus revenait au gris de la
   ligne ordinaire -- c'est-a-dire invisible, la ou elle doit sauter aux yeux. */
.mkt-etat.mkt-rouge { color: #e07a5f; }
.mkt-etat.mkt-vert-t { color: #6fbf73; }

/* Sortante ou entrante : un liseré a gauche suffit, et il dit le sens sans
   demander de lire. */
.mkt-caravane { border-left: 3px solid transparent; padding-left: 8px; }
.mkt-caravane.sortante { border-left-color: #c9a227; }
.mkt-caravane.entrante { border-left-color: #6fbf73; }

/* Les rubis d'un rapport : la seule ligne du compte rendu qui parle d'une
   ressource qu'on ne produit pas. */
.rap-rubis { color: #e0607a; font-weight: 700; }

/* La fiche du marche : un encadre pour la loi du haut, puis des PARAGRAPHES.
   `.ft-carte` est la carte d'une troupe -- s'en servir pour du texte courant
   transformait chaque phrase en boite, et la page tenait sur trois ecrans. */
.mkt-aide-p {
    font-family: var(--font-ui); font-size: .8rem; line-height: 1.55;
    color: var(--text-light); margin: 0 0 10px; text-align: left;
}
.mkt-aide-p:last-child { margin-bottom: 0; }

@media (max-width: 480px) {
    .mkt-bandeau { gap: 6px; }
    .mkt-b-val { font-size: .82rem; }
    .mkt-b-lbl { font-size: .6rem; }
    .mkt-ligne { flex-direction: column; align-items: stretch; gap: 8px; }
    .mkt-ligne-act .btn-upgrade { width: 100%; }
}


/* --- Guilde --- */
.guild-modal .mil-body { padding: 14px 18px 16px; }
.guild-card {
    background: var(--surface); border: 1px solid var(--line-soft);
    border-radius: var(--radius); padding: 13px; margin-bottom: 12px;
    font-family: var(--font-ui); text-align: left;
}
.guild-card .btn-res { width: 100%; margin-top: 10px; }
.guild-create { display: flex; gap: 10px; margin-top: 4px; }
.guild-field { flex: 1; min-width: 0; }
.guild-field.wide { flex: 2; }
.guild-field label {
    display: block; font-size: 0.62rem; text-transform: uppercase; letter-spacing: 0.08em;
    color: var(--muted); margin-bottom: 5px;
}
input.guild-tag { text-transform: uppercase; letter-spacing: 0.1em; }

.guild-scroll { max-height: 200px; overflow-y: auto; margin-top: 8px;
    scrollbar-width: thin; scrollbar-color: var(--line-soft) transparent; }
.guild-scroll.tall { max-height: 330px; }
.guild-scroll::-webkit-scrollbar { width: 8px; }
.guild-scroll::-webkit-scrollbar-track { background: transparent; }
.guild-scroll::-webkit-scrollbar-thumb { background: var(--line-soft); border-radius: 4px;
    border: 2px solid transparent; background-clip: padding-box; }

.guild-banner {
    display: flex; align-items: center; gap: 14px; padding-bottom: 12px; margin-bottom: 12px;
    border-bottom: 1px solid var(--line-soft); font-family: var(--font-ui); text-align: left;
}
.guild-banner img { width: 56px; height: 56px; object-fit: contain; border-radius: 10px; flex-shrink: 0; }
.guild-banner-id { flex: 1; min-width: 0; }
.guild-banner-id h3 { margin: 0; font-size: 1.05rem; color: var(--gold-bright); font-family: var(--font-ui);
                      overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.guild-banner-id p { margin: 4px 0 0; font-size: 0.74rem; color: var(--text-light); }
.guild-banner-id .muted { color: var(--muted); }
.btn-leave {
    height: 34px; padding: 0 14px; border-radius: var(--radius-sm); cursor: pointer; flex-shrink: 0;
    background: transparent; border: 1px solid #6b3328; color: var(--danger);
    font-family: var(--font-ui); font-size: 0.72rem; font-weight: 600;
}@media (hover: hover) and (pointer: fine) {
.btn-leave:hover { background: rgba(207,106,85,0.12); }
}

.guild-cols { display: grid; grid-template-columns: 1.35fr 1fr; gap: 12px; align-items: start; }
/* La colonne de gauche porte les membres ET le renfort. Tout empiler a droite
   laissait un trou sous une table d'un seul membre, et poussait « Envoyer un
   renfort » sous la ligne de flottaison : sur grand ecran il fallait faire
   defiler pour atteindre la premiere action de l'onglet. */
.guild-main { display: flex; flex-direction: column; gap: 12px; min-width: 0; }
/* Un membre simple ne voit pas la Salle d'audience : sans cela la colonne de
   droite restait vide et rendait le trou a l'autre bord. */
.guild-cols.sans-audience { grid-template-columns: 1fr; }
.guild-cols.sans-audience .guild-side { display: none; }
.guild-table { width: 100%; border-collapse: collapse; font-size: 0.74rem; color: var(--text-light); }
.guild-table th {
    text-align: left; padding: 7px 8px; font-size: 0.6rem; font-weight: 700;
    text-transform: uppercase; letter-spacing: 0.08em; color: var(--muted);
    border-bottom: 1px solid var(--line-soft);
}
.guild-table th.c, .guild-table td.c { text-align: center; }
.guild-table th.r, .guild-table td.r { text-align: right; }
.guild-table td { padding: 7px 8px; border-bottom: 1px solid var(--line-soft); }
.guild-table tr:last-child td { border-bottom: 0; }

.guild-locked-box { text-align: center; padding: 30px 16px; font-family: var(--font-ui); }
.guild-locked-box .lock { font-size: 1.8rem; }
.guild-locked-box h3 { margin: 10px 0 8px; color: var(--danger); font-family: var(--font-ui); font-size: 1rem; }
.guild-locked-box p { margin: 0; color: var(--muted); font-size: 0.8rem; line-height: 1.5; }
.guild-locked-box b { color: var(--gold-bright); }
/* Ou se trouvent des hommes qui ne sont pas au village : une precision, pas un
   titre -- elle se lit apres la ligne principale. */
.send-row .mil-ou { display: block; margin-top: 2px; opacity: .72; }

/* Le temps que mettra la colonne, sous le selecteur. Il ne parait que quand une
   cible ET des troupes sont choisies : avant, il n'y a rien a dire. */
.sup-duree {
    display: none; margin: 8px 0 0; padding: 8px 10px;
    border-radius: var(--radius-sm);
    background: var(--surface-2); border: 1px solid var(--line-soft);
    font-size: 0.76rem; line-height: 1.4; color: var(--text-light);
}
.sup-duree.on { display: block; }
.sup-duree b { color: var(--gold-bright); }
.sup-duree.hate { border-color: rgba(207,106,85,0.45); }
.sup-duree.hate b { color: #f0b7a5; }
.sup-duree .mg-ic { width: 1em; height: 1em; vertical-align: -0.15em; margin-right: 4px; }

/* Une colonne encore en chemin : ce qu'elle porte, dans combien de temps elle
   arrive, et de quoi la faire revenir. */
.sup-route {
    display: flex; align-items: center; gap: 8px;
    padding: 7px 10px; margin-bottom: 5px;
    border-radius: var(--radius-sm);
    background: var(--surface-2); border-left: 3px solid var(--accent);
    font-size: 0.78rem;
}
.sup-route .sr-quoi { flex: 1; min-width: 0; }
.sup-route .sr-t { white-space: nowrap; font-variant-numeric: tabular-nums; opacity: .9; }
.sup-route .mg-ic { width: 0.95em; height: 0.95em; vertical-align: -0.15em; }

/* La marche forcee : elle ne parait que quand elle s'applique vraiment, donc
   elle doit se voir. Le rouge de l'alerte, pas l'or d'une recompense -- ce qui
   presse le pas des hommes, c'est qu'un frere d'armes est en danger. */
.sup-hate {
    display: none; align-items: flex-start; gap: 8px;
    margin: 8px 0 0; padding: 9px 11px;
    border-radius: var(--radius-sm);
    background: rgba(120,40,30,0.28); border: 1px solid rgba(207,106,85,0.45);
    color: #f0b7a5; font-size: 0.76rem; line-height: 1.45;
}
.sup-hate.on { display: flex; }
.sup-hate b { color: #ffd9cb; }
.sup-hate .mg-ic { flex: 0 0 auto; width: 1.05em; height: 1.05em; margin: 2px 0 0; }
/* Les renseignements partages. La ligne est un BOUTON : on la deplie pour lire
   le rapport entier, et un bouton se tabule et s'annonce au lecteur d'ecran la
   ou un `div` cliquable ne fait ni l'un ni l'autre. */
.gi-row { margin-bottom: 5px; }
.gi-tete {
    display: flex; align-items: center; gap: 8px; width: 100%;
    padding: 7px 10px; border: 0;
    border-left: 3px solid var(--progress-fill, #8b3ff0);
    border-radius: var(--radius-sm);
    background: var(--surface-2); color: inherit;
    font: inherit; font-size: 0.78rem; text-align: left; cursor: pointer;
}
.gi-tete:hover { filter: brightness(1.12); }
.gi-tete .gi-quoi { flex: 1; min-width: 0; }
.gi-tete .gi-par { opacity: .7; }
.gi-tete .gi-n { opacity: .8; white-space: nowrap; }
/* L'age se lit AVANT les chiffres : c'est lui qui dit si le reste vaut encore
   quelque chose. Passe une heure, il vire a l'ambre -- pas au rouge : le
   renseignement n'est pas faux, il est seulement vieux. */
.gi-tete .gi-age { white-space: nowrap; opacity: .9; font-variant-numeric: tabular-nums; }
.gi-row.vieux .gi-tete { border-left-color: var(--accent); }
.gi-row.vieux .gi-age { color: #e8b48c; font-weight: 700; }
.gi-tete .mg-ic { width: 0.95em; height: 0.95em; vertical-align: -0.15em; }
.gi-corps { padding: 6px 0 2px; }
.gi-perime {
    margin: 0 0 8px; padding: 7px 10px;
    border-radius: var(--radius-sm);
    background: rgba(120,80,30,0.25); border: 1px solid rgba(207,150,85,0.4);
    color: #e8c9a5; font-size: 0.74rem; line-height: 1.45;
}
/* Le partage, en pied du compte rendu du registre. */
.esp-partage {
    display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
    margin-top: 9px; padding-top: 7px;
    border-top: 1px dashed rgba(255,255,255,0.12);
    font-size: 0.85em; color: #aaa;
}
.esp-partage.faite { color: #a9d9ad; }
.esp-partage .mg-ic { width: 1em; height: 1em; vertical-align: -0.15em; }

/* Les colonnes de la guilde : une ligne par assaut en vol. La teinte dit le
   sens -- ce qui part, et ce qui arrive sur un frere d'armes. */
.gc-row {
    display: flex; align-items: center; gap: 8px;
    padding: 7px 10px; margin-bottom: 5px;
    border-radius: var(--radius-sm);
    background: var(--surface-2);
    border-left: 3px solid var(--accent);
    font-size: 0.78rem;
}
.gc-row.entrante { border-left-color: var(--danger); }
/* Un renfort n'est ni un assaut sortant ni une menace : c'est le vert des
   colonnes amies, celui que la carte donne deja a `.map-soldier.support`. */
.gc-row.g-renfort { border-left-color: var(--success); }
/* Une chasse se distingue d'un pillage : la garnison du Seigneur est commune,
   donc s'y joindre est une decision, pas un doublon. */
.gc-row.g-seigneur { border-left-color: var(--gold-bright); }
.gc-row .gc-cible { opacity: .85; }
.gc-row .gc-quoi { flex: 1; min-width: 0; }
.gc-row .gc-n { opacity: .75; white-space: nowrap; }
.gc-row .gc-t { font-variant-numeric: tabular-nums; white-space: nowrap; opacity: .9; }
.gc-row .mg-ic { width: 0.95em; height: 0.95em; vertical-align: -0.15em; }
/* L'etat des secours se pose SOUS la ligne qu'il commente, pas a cote : c'est
   une conclusion, et une conclusion se lit apres. D'ou le retour a la ligne
   force -- `.gc-row` est un conteneur flex, un enfant en pleine largeur n'y
   passe a la ligne que si le conteneur l'autorise. */
.gc-row { flex-wrap: wrap; }
.gc-secours {
    flex: 0 0 100%;
    display: flex; align-items: flex-start; gap: 6px;
    margin-top: 5px; padding-top: 5px;
    border-top: 1px solid rgba(255,255,255,0.09);
    font-size: 0.73rem; line-height: 1.4;
}
.gc-secours.ok    { color: #a9d9ad; }
.gc-secours.tard  { color: #e8b48c; }
.gc-secours.vide  { color: #c9a6a0; }
.gc-secours b     { color: #fff; }
.gc-secours .mg-ic { flex: 0 0 auto; margin-top: 1px; }
.mil-retenues { margin-top: 6px; opacity: .85; }
/* La seconde ligne explique la porte suivante : elle doit se lire apres la
   premiere, pas en meme temps. */
.guild-locked-box .guild-locked-sub { margin-top: 10px; opacity: .78; font-size: 0.75rem; }

@media (max-width: 768px) {
    .guild-modal .mil-body { padding: 12px 12px 14px; }
    .guild-cols { grid-template-columns: 1fr; }
    .guild-create { flex-direction: column; gap: 8px; }
    .guild-banner img { width: 44px; height: 44px; }
    .guild-banner-id h3 { font-size: 0.92rem; }
    .guild-scroll.tall { max-height: 240px; }
}
.guild-table .muted { color: var(--muted); }
.guild-table .role-chief { color: var(--gold-bright); font-weight: 700; }
.guild-table .ok { color: var(--success); font-weight: 600; }
.guild-table .warn { color: var(--accent); font-weight: 600; }
.btn-row {
    height: 26px; padding: 0 10px; border-radius: 6px; cursor: pointer;
    background: transparent; border: 1px solid var(--panel-border); color: var(--muted);
    font-family: var(--font-ui); font-size: 0.66rem; font-weight: 600;
}@media (hover: hover) and (pointer: fine) {
.btn-row:hover { color: var(--text-light); border-color: var(--accent); }
}
.btn-row.danger { color: var(--danger); border-color: #6b3328; }@media (hover: hover) and (pointer: fine) {
.btn-row.danger:hover { background: rgba(207,106,85,0.12); color: #e08a70; }
}

/* ======================================================
   ÉCRAN D'ACCUEIL
   ====================================================== */
.auth-screen {
    position: fixed; inset: 0; z-index: 12000;
    display: flex; align-items: center; justify-content: center;
    overflow: hidden; background: #0d0a07; font-family: var(--font-ui);
}
.auth-bg { position: absolute; inset: 0; pointer-events: none; }

/* Le village dérive lentement : le décor respire sans distraire. */
.auth-sky {
    position: absolute; inset: -6%;
    background: url('assets/village_map.png') center/cover no-repeat;
    animation: authDrift 48s ease-in-out infinite alternate;
    will-change: transform;
}
@keyframes authDrift {
    from { transform: scale(1.06) translate3d(-1.2%, -0.8%, 0); }
    to   { transform: scale(1.14) translate3d(1.2%, 0.8%, 0); }
}

/* Deux bancs de brume à vitesses différentes, sans image. */
.auth-fog {
    position: absolute; left: -50%; width: 200%; height: 55%;
    background: radial-gradient(ellipse at 30% 50%, rgba(226, 214, 190, 0.10), rgba(226, 214, 190, 0) 60%),
                radial-gradient(ellipse at 70% 45%, rgba(226, 214, 190, 0.08), rgba(226, 214, 190, 0) 62%);
    filter: blur(6px); will-change: transform;
}
.fog-far  { bottom: 16%; opacity: 0.7; animation: authFog 73s linear infinite; }
.fog-near { bottom: -4%; opacity: 0.9; animation: authFog 47s linear infinite reverse; }
@keyframes authFog {
    from { transform: translate3d(-12%, 0, 0); }
    to   { transform: translate3d(12%, 0, 0); }
}

/* Braises : quelques points qui montent, générés par le script. */
.auth-embers { position: absolute; inset: 0; }
.auth-embers i {
    position: absolute; bottom: -10px; width: 3px; height: 3px; border-radius: 50%;
    background: var(--accent); box-shadow: 0 0 6px 1px rgba(212, 165, 72, 0.6);
    animation: authEmber linear infinite; will-change: transform, opacity;
}
@keyframes authEmber {
    0%   { transform: translate3d(0, 0, 0) scale(0.6); opacity: 0; }
    12%  { opacity: 0.9; }
    80%  { opacity: 0.55; }
    100% { transform: translate3d(var(--dx, 14px), -78vh, 0) scale(1.1); opacity: 0; }
}

.auth-vignette {
    position: absolute; inset: 0;
    background: radial-gradient(ellipse at 50% 42%, rgba(13,10,7,0.15) 0%, rgba(13,10,7,0.72) 58%, rgba(13,10,7,0.94) 100%);
}

.auth-stage {
    position: relative; z-index: 1; width: 100%; max-width: 400px;
    padding: 24px 18px calc(24px + env(safe-area-inset-bottom));
    max-height: 100vh; overflow-y: auto;
    scrollbar-width: thin; scrollbar-color: var(--line-soft) transparent;
}
.auth-brand { position: relative; text-align: center; margin-bottom: 18px; }
/* Le logo tombe sur la partie la plus claire du decor : un halo sombre le
   detache, sinon les lettres d'or s'y noient. */
.auth-brand::before {
    content: ''; position: absolute; inset: -34px -16px -18px;
    background: radial-gradient(ellipse at 50% 46%, rgba(9,7,4,0.84) 0%, rgba(9,7,4,0.58) 34%,
                                rgba(9,7,4,0.22) 58%, transparent 74%);
    pointer-events: none;
}
.auth-brand > * { position: relative; }
.auth-crest {
    display: block; width: 104px; height: 104px; margin: 0 auto;
    filter: drop-shadow(0 6px 18px rgba(0,0,0,0.85));
}
/* Le titre est grave, pas ecrit : deux mots d'or separes par un filet et une
   etoile, comme sur une enseigne. */
.auth-brand h1 {
    margin: 10px 0 0; font-family: var(--font-title, var(--font-ui));
    font-size: 1.72rem; font-weight: 700; line-height: 1.1;
    display: flex; flex-direction: column; align-items: center; gap: 2px;
    color: var(--gold-bright);
    filter: drop-shadow(0 1px 0 rgba(26,18,8,0.95)) drop-shadow(0 4px 16px rgba(0,0,0,0.95));
}
/* Le degrade est porte par chaque mot, pas par le bloc : sur deux lignes, le
   haut du bloc virait au creme et le mot du dessus se perdait sur le decor. */
.bd-med, .bd-game {
    letter-spacing: 0.16em; text-indent: 0.16em;
    background: linear-gradient(180deg, #f7dc9a 0%, #dcab4e 52%, #a4712b 100%);
    -webkit-background-clip: text; background-clip: text;
    color: transparent; -webkit-text-fill-color: transparent;
}
.bd-game { font-size: 1.24em; letter-spacing: 0.24em; text-indent: 0.24em; }
.bd-rule {
    display: flex; align-items: center; gap: 9px; width: 78%;
    margin: 3px 0; text-indent: 0;
}
.bd-rule i {
    flex: 1; height: 1px; background: linear-gradient(90deg, transparent, var(--accent), transparent);
}
.bd-dot { width: 11px; height: 11px; flex-shrink: 0; }
.auth-brand p { margin: 7px 0 0; font-size: 0.76rem; color: #c9bda6; text-shadow: 0 2px 8px rgba(0,0,0,0.9); }

.auth-card {
    background: rgba(26, 21, 16, 0.92); border: 1px solid var(--panel-border);
    border-radius: var(--radius); padding: 16px;
    box-shadow: 0 18px 50px rgba(0,0,0,0.75);
    backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
}
.auth-tabs {
    display: flex; gap: 3px; padding: 3px; margin-bottom: 14px;
    background: var(--surface); border: 1px solid var(--line-soft); border-radius: 10px;
}
.auth-tabs button {
    flex: 1; padding: 8px 4px; border: 0; border-radius: 7px; cursor: pointer;
    background: transparent; color: var(--muted);
    font-family: var(--font-ui); font-size: 0.74rem; font-weight: 600;
}
.auth-tabs button.on { background: var(--surface-3); color: var(--gold-bright); box-shadow: inset 0 0 0 1px var(--panel-border); }

.auth-field { display: block; margin-bottom: 11px; text-align: left; }
.auth-field > span:not(.auth-mdp) {
    display: block; font-size: 0.62rem; text-transform: uppercase; letter-spacing: 0.08em;
    color: var(--muted); margin-bottom: 5px;
}
.auth-field input {
    width: 100%; height: 40px; padding: 0 12px; box-sizing: border-box; border-radius: var(--radius-sm);
    background: #0c0a07; border: 1px solid var(--panel-border); color: var(--text-light);
    font-family: var(--font-ui); font-size: 0.82rem;
}
.auth-field input:focus { outline: none; border-color: var(--accent); }
.auth-field input::placeholder { color: #6b6152; }
/* Voir ce qu'on tape. Un mot de passe refuse ne dit pas quelle lettre a
   glisse -- une majuscule verrouillee, un accent, une touche voisine --, et
   le retaper a l'aveugle ne fait que repeter la meme faute. */
.auth-mdp { position: relative; display: block; }
.auth-mdp input { padding-right: 84px; }
.auth-voir {
    position: absolute; right: 4px; top: 50%; transform: translateY(-50%);
    height: 32px; padding: 0 10px; border-radius: var(--radius-sm);
    background: transparent; border: 1px solid transparent; color: var(--muted);
    font-family: var(--font-ui); font-size: 0.7rem; cursor: pointer;
}
.auth-voir:hover, .auth-voir:focus-visible { color: var(--text-light); border-color: var(--panel-border); outline: none; }
/* La ligne sous la confirmation : vide tant qu'on tape le debut, puis verte
   ou rouge. Les mots portent le verdict, la couleur ne fait que l'appuyer. */
.auth-accord { display: block; min-height: 0; margin-top: 5px; font-family: var(--font-ui); font-size: 0.7rem; color: var(--muted); }
.auth-accord:empty { display: none; }
.auth-accord.ok { color: var(--success); }
.auth-accord.non { color: var(--danger); }
.auth-submit { width: 100%; margin-top: 4px; }
.auth-error {
    margin: 11px 0 0; padding: 9px 11px; border-radius: var(--radius-sm);
    background: rgba(207,106,85,0.12); border: 1px solid #6b3328;
    color: var(--danger); font-size: 0.74rem; text-align: left;
}
.auth-hint { margin: 11px 0 0; font-size: 0.68rem; color: var(--muted); line-height: 1.5; text-align: left; }
.auth-version { margin: 14px 0 0; text-align: center; font-size: 0.64rem; color: #6b6152; }

@media (max-width: 768px) {
    .auth-stage { padding: 20px 14px calc(20px + env(safe-area-inset-bottom)); }
    .auth-brand h1 { font-size: 1.44rem; }
    .auth-crest { width: 86px; height: 86px; }
}

/* Décor immobile pour qui demande moins d'animations. */
@media (prefers-reduced-motion: reduce) {
    .auth-sky, .auth-fog, .auth-embers i { animation: none; }
    .auth-sky { transform: scale(1.08); }
}

/* --- Vérification de l'adresse e-mail --- */
.verify-head { text-align: center; margin-bottom: 14px; }
.verify-icon { font-size: 1.7rem; display: block; }
.verify-head h2 { margin: 8px 0 0; font-size: 1.05rem; color: var(--gold-bright); font-family: var(--font-ui); }
.verify-head p { margin: 7px 0 0; font-size: 0.74rem; color: var(--muted); line-height: 1.5; }
.verify-head b { color: var(--text-light); }
input.verify-code {
    text-align: center; font-size: 1.4rem; letter-spacing: 0.42em; font-weight: 700;
    font-variant-numeric: tabular-nums; height: 52px; padding-left: 0.42em;
}
.auth-ok {
    margin: 11px 0 0; padding: 9px 11px; border-radius: var(--radius-sm);
    background: rgba(116,189,122,0.12); border: 1px solid #3d6640;
    color: var(--success); font-size: 0.74rem; text-align: left;
}
.verify-actions { display: flex; justify-content: space-between; gap: 10px; margin-top: 12px; }

/* Le « Mot de passe oublié ? » sous le bouton de connexion : une sortie de
   secours, pas une action de meme rang -- elle se range a droite, en lien. */
.auth-aside { display: flex; justify-content: flex-end; margin-top: 10px; }

/* Le « Revenir a la connexion » tient le bord droit meme quand le bouton de
   renvoi n'est pas encore la : sans cela il glisse a gauche au premier envoi,
   et le seul bouton de sortie du volet change de place sous le doigt. */
#auth-forgot-section .verify-actions > :last-child { margin-left: auto; }

/* Le second temps du volet est une etape, pas la suite du premier : sans cet
   ecart, le champ du code se colle au bouton d'envoi et les deux se lisent
   comme une seule saisie. */
#forgot-step2 { margin-top: 14px; }

/* Les trois volets des Parametres du compte. Ils tenaient en champs bruts
   styles a la main, et chaque refus du serveur partait dans un `alert()` :
   les memes `.auth-field` que l'ecran de connexion, et la phrase du serveur
   posee sous le bouton, la ou l'on vient de cliquer. */
.btn-link {
    background: none; border: 0; padding: 0; cursor: pointer;
    color: var(--accent); font-family: var(--font-ui); font-size: 0.72rem; font-weight: 600;
}@media (hover: hover) and (pointer: fine) {
.btn-link:hover:not(:disabled) { color: var(--gold-bright); text-decoration: underline; }
}
.btn-link:disabled { color: var(--muted); cursor: not-allowed; text-decoration: none; }

.verify-banner {
    position: fixed; left: 50%; transform: translateX(-50%); z-index: 9500;
    top: calc(8px + env(safe-area-inset-top));
    display: flex; align-items: center; gap: 10px; max-width: calc(100vw - 24px);
    padding: 8px 10px 8px 14px; box-sizing: border-box;
    background: var(--surface-2); border: 1px solid var(--accent); border-radius: 999px;
    box-shadow: 0 8px 24px rgba(0,0,0,0.6); font-family: var(--font-ui);
}
.verify-banner .vb-icon { flex-shrink: 0; }
.verify-banner .vb-text { font-size: 0.74rem; color: var(--text-light); min-width: 0;
                          overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.verify-banner .vb-text b { color: var(--accent); font-weight: 600; }
.verify-banner .btn-bar { height: 30px; padding: 0 14px; font-size: 0.72rem; }

@media (max-width: 768px) {
    .verify-banner { top: auto; bottom: calc(66px + env(safe-area-inset-bottom)); padding: 7px 8px 7px 12px; }
    .verify-banner .vb-text { font-size: 0.68rem; }
}

/* ======================================================
   MENU SYSTÈME
   ====================================================== */
.sys-panel { font-family: var(--font-ui); }

/* En tete : qui, quelle version, quel serveur -- visible sans defiler. */
.sys-identity {
    background: var(--surface); border: 1px solid var(--line-soft);
    border-radius: var(--radius); padding: 12px 14px;
}
.sys-identity .v {
    font-size: 1.1rem; font-weight: 700; color: var(--gold-bright);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sys-meta {
    display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; margin-top: 5px;
    font-size: 0.72rem; color: var(--muted);
}
.sys-version b { color: var(--accent); }
.sys-status { color: var(--success); font-weight: 600; }

.sys-titre {
    font-size: 0.62rem; text-transform: uppercase; letter-spacing: 0.1em;
    color: var(--muted); margin: 14px 2px 7px;
}

/* Ce qu'on ouvre : deux colonnes de tuiles. */
.sys-grille { display: grid; grid-template-columns: 1fr 1fr; gap: 7px; }
.sys-tuile {
    position: relative; display: flex; align-items: center; gap: 8px; min-width: 0;
    min-height: 42px; padding: 0 11px; cursor: pointer;
    background: var(--surface); border: 1px solid var(--line-soft); border-radius: var(--radius-sm);
    color: var(--text-light); font-family: var(--font-ui); font-size: 0.76rem; font-weight: 600;
    text-align: left;
}
.sys-tuile > span:first-of-type { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Sans sondage, Premiers pas resterait seul sur sa rangee : il la prend. */
#btn-premiers-pas:has(+ #btn-sondage[hidden]) { grid-column: 1 / -1; }

/* Les reglages : un nom fixe, l'etat a droite. */
.sys-liste {
    background: var(--surface); border: 1px solid var(--line-soft);
    border-radius: var(--radius-sm); overflow: hidden;
}
.sys-ligne {
    display: flex; align-items: center; gap: 9px; width: 100%; min-height: 42px;
    padding: 0 12px; box-sizing: border-box; cursor: pointer;
    background: none; border: 0; border-top: 1px solid var(--line-soft);
    color: var(--text-light); font-family: var(--font-ui); font-size: 0.76rem; font-weight: 600;
    text-align: left;
}
.sys-ligne:first-child { border-top: 0; }
.sys-ligne > span { flex: 1; min-width: 0; }
.sys-ligne em { font-style: normal; font-weight: 500; font-size: 0.7rem; color: var(--muted); }
.sys-ligne.on em { color: var(--success); }
.sys-chevron { color: var(--muted); font-size: 1.1rem; font-weight: 400; }
.sys-inter {
    position: relative; flex-shrink: 0; width: 36px; height: 20px; box-sizing: border-box;
    border-radius: 999px; background: #2b231b; border: 1px solid #4a3a28;
}
.sys-inter::after {
    content: ""; position: absolute; top: 2px; left: 2px; width: 14px; height: 14px;
    border-radius: 50%; background: #8a7a64; transition: transform 0.15s, background 0.15s;
}
.sys-ligne.on .sys-inter { background: rgba(116,189,122,0.25); border-color: #3d6640; }
.sys-ligne.on .sys-inter::after { transform: translateX(16px); background: var(--success); }

@media (hover: hover) and (pointer: fine) {
.sys-tuile:hover { border-color: var(--accent); color: var(--gold-bright); }
.sys-ligne:hover { background: rgba(255,255,255,0.03); color: var(--gold-bright); }
}
.sys-tuile:focus-visible, .sys-ligne:focus-visible, .sys-mini:focus-visible {
    outline: 2px solid var(--accent); outline-offset: -2px;
}

/* En bas, discrets : l'administration et la sortie. */
.sys-bas {
    display: flex; gap: 7px; margin-top: 18px; padding-top: 14px;
    border-top: 1px solid var(--line-soft);
}
.sys-mini {
    position: relative; flex: 1; display: flex; align-items: center; justify-content: center; gap: 7px;
    min-height: 36px; padding: 0 10px; cursor: pointer;
    background: none; border: 1px solid var(--line-soft); border-radius: var(--radius-sm);
    font-family: var(--font-ui); font-size: 0.72rem; font-weight: 600;
}
.sys-mini.admin { color: #d99a7a; }
.sys-mini.danger { color: var(--danger); }
@media (hover: hover) and (pointer: fine) {
.sys-mini:hover { border-color: #6b3328; background: rgba(207,106,85,0.08); }
}
.sys-badge {
    position: absolute; top: 6px; right: 8px; width: 8px; height: 8px; border-radius: 50%;
    background: var(--danger); box-shadow: 0 0 8px var(--danger);
}

/* --- Panneau admin : zone dangereuse --- */
.danger-box {
    background: rgba(207,106,85,0.06); border: 1px solid #6b3328;
    border-radius: var(--radius); padding: 16px; font-family: var(--font-ui); text-align: left;
}
.danger-head { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.danger-icon { font-size: 1.2rem; }
.danger-head h3 { margin: 0; font-size: 1rem; color: var(--danger); font-family: var(--font-ui); }
.danger-lead { font-size: 0.78rem; color: var(--text-light); line-height: 1.55; margin: 0 0 12px; }
.danger-lead b { color: var(--danger); }
.danger-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-bottom: 14px; }
.danger-sub {
    font-size: 0.62rem; text-transform: uppercase; letter-spacing: 0.08em;
    color: var(--muted); margin-bottom: 6px;
}
.danger-cols ul { margin: 0; padding-left: 18px; }
.danger-cols li { font-size: 0.72rem; color: var(--text-light); line-height: 1.6; }
.danger-field { display: block; margin-bottom: 12px; }
.danger-field span { display: block; font-size: 0.72rem; color: var(--muted); margin-bottom: 6px; }
.danger-field b { color: var(--danger); letter-spacing: 0.06em; }
#btn-reset-season { width: 100%; }
.danger-result {
    margin: 12px 0 0; padding: 10px 12px; border-radius: var(--radius-sm);
    font-size: 0.74rem; line-height: 1.6;
}
.danger-result.ok { background: rgba(116,189,122,0.12); border: 1px solid #3d6640; color: var(--success); }
.danger-result.err { background: rgba(207,106,85,0.12); border: 1px solid #6b3328; color: var(--danger); }

/* --- Annonce de nouvelle saison --- */
.season-notice {
    position: fixed; inset: 0; z-index: 13000; display: flex; align-items: center; justify-content: center;
    background: rgba(9, 7, 5, 0.88); padding: 18px; font-family: var(--font-ui);
}
.season-card {
    max-width: 420px; width: 100%; text-align: center;
    background: var(--surface-2); border: 1px solid var(--accent); border-radius: var(--radius);
    padding: 22px 20px; box-shadow: 0 20px 60px rgba(0,0,0,0.8);
    max-height: 90vh; overflow-y: auto;
}
.season-crest { font-size: 2rem; display: block; }
.season-card h2 { margin: 8px 0 0; font-size: 1.25rem; color: var(--gold-bright); font-family: var(--font-ui); }
.season-lead { margin: 10px 0 0; font-size: 0.8rem; color: var(--text-light); line-height: 1.6; }
.season-list {
    margin: 14px 0 0; padding: 12px 14px 12px 30px; text-align: left;
    background: var(--surface); border: 1px solid var(--line-soft); border-radius: var(--radius-sm);
}
.season-list li { font-size: 0.74rem; color: var(--text-light); line-height: 1.7; }
.season-fair { margin: 12px 0 16px; font-size: 0.72rem; color: var(--muted); font-style: italic; }
.season-card .btn-res { width: 100%; }

@media (max-width: 768px) {
    .danger-cols { grid-template-columns: 1fr; gap: 10px; }
}

/* ============================================================================
   LA HORDE — chasse au Seigneur de guerre, rangs, renforts, salon, Panthéon.
   ========================================================================= */

.guild-tabs { margin: 10px 0 12px; }
.guild-tab { display: block; }

/* --- La carte du Seigneur de guerre --- */
.warlord-card {
    background: var(--surface-2);
    border: 1px solid #6b3328;
    border-left: 3px solid var(--danger);
    border-radius: var(--radius);
    padding: 14px 16px;
    margin-bottom: 12px;
}
.wl-head { display: flex; align-items: center; gap: 12px; }
.wl-crest { font-size: 1.7rem; line-height: 1; }
.wl-id h3 {
    margin: 0; font-family: var(--font-ui); font-size: 1.05rem;
    color: var(--gold-bright); letter-spacing: 0.2px;
}
.wl-id p { margin: 2px 0 0; }

/* La jauge dit d'un coup d'oeil ce qu'il reste a faire, et donc s'il vaut
   la peine de partir maintenant. */
.wl-gauge {
    height: 10px; margin: 12px 0 6px;
    background: rgba(0,0,0,0.45);
    border: 1px solid var(--line-soft);
    border-radius: 6px; overflow: hidden;
}
.wl-gauge i {
    display: block; height: 100%;
    background: linear-gradient(90deg, #8d3f2c, #cf6a55);
}
.wl-stat { margin: 0 0 8px; font-family: var(--font-ui); font-size: 0.82rem; color: var(--text-light); }

.wl-garrison { display: flex; flex-wrap: wrap; gap: 6px; margin: 10px 0 12px; }
.wl-chip {
    font-family: var(--font-ui); font-size: 0.72rem;
    background: var(--surface-3); border: 1px solid var(--line-soft);
    border-radius: 999px; padding: 3px 9px; color: var(--text-light);
}

.wl-inbound {
    display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
    padding: 7px 10px; border-bottom: 1px solid var(--line-soft);
    font-family: var(--font-ui); font-size: 0.78rem;
}
.wl-inbound:last-child { border-bottom: 0; }
.wl-inbound.mine { background: rgba(212,165,72,0.08); border-radius: var(--radius-sm); }
.wl-inbound .n { font-weight: 600; color: var(--gold-bright); }
.wl-inbound .u { color: var(--text-light); }
.wl-inbound .t { margin-left: auto; color: var(--text-dim); }

/* --- Le rappel dans le HUD : fixe, muet, il s'en va avec lui --- */
#warlord-bar {
    position: fixed;
    left: 50%; transform: translateX(-50%);
    bottom: 64px;
    /* Sous le voile des modales (100) : a 900 il passait par-dessus tout,
       y compris le panneau d'administration. */
    z-index: 90;
    display: flex; align-items: center; gap: 10px;
    max-width: min(560px, calc(100vw - 24px));
    padding: 7px 14px;
    background: var(--surface-2);
    border: 1px solid #6b3328;
    border-left: 3px solid var(--danger);
    border-radius: 999px;
    box-shadow: 0 6px 18px rgba(0,0,0,0.55);
    font-family: var(--font-ui); font-size: 0.78rem;
    color: var(--text-light);
    cursor: pointer;
}@media (hover: hover) and (pointer: fine) {
#warlord-bar:hover { border-color: var(--accent); }
}
.wb-icon { font-size: 1rem; }
.wb-name { font-weight: 600; color: var(--gold-bright); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.wb-gauge {
    flex: 1; min-width: 60px; height: 7px;
    background: rgba(0,0,0,0.45); border: 1px solid var(--line-soft);
    border-radius: 5px; overflow: hidden;
}
.wb-gauge i { display: block; height: 100%; background: linear-gradient(90deg, #8d3f2c, #cf6a55); }
.wb-pct, .wb-time { color: var(--text-dim); white-space: nowrap; }

/* --- Membres : gloire, grades, actions du chef --- */
.glory { color: var(--gold-bright); font-variant-numeric: tabular-nums; }
.role-officer { color: #7fa8d4; font-weight: 600; }
.guild-table .small { display: block; font-size: 0.68rem; }
.guild-row-actions { display: flex; gap: 4px; justify-content: flex-end; flex-wrap: wrap; }

/* --- Renforts --- */
.sup-troops { display: flex; flex-direction: column; gap: 6px; margin: 8px 0 10px; }
.sup-garrison {
    display: flex; align-items: center; gap: 10px;
    padding: 7px 10px; border-bottom: 1px solid var(--line-soft);
    font-family: var(--font-ui); font-size: 0.78rem;
}
.sup-garrison:last-child { border-bottom: 0; }
.sup-garrison .n { color: var(--text-light); }
.sup-garrison .u { color: var(--text-dim); margin-left: auto; }

/* --- Le salon de la guilde --- */
.chat-card { display: flex; flex-direction: column; }
.guild-chat-log {
    height: 300px; max-height: 45vh; overflow-y: auto;
    background: rgba(0,0,0,0.28);
    border: 1px solid var(--line-soft); border-radius: var(--radius-sm);
    padding: 8px 10px; margin: 8px 0;
}
/* Le salon n'a plus de mise en page a lui : il affiche les memes `.chat-msg`
   que la place publique, par la meme fonction. Les regles `.gc-line`, `.gc-who`,
   `.gc-txt` et `.gc-at` qui vivaient ici sont parties avec -- une regle morte
   qu'on laisse derriere soi est un correctif qu'on ira poser au mauvais
   endroit.

   Le cadre, lui, reste propre au salon : il est plus court que celui de la
   place, qui occupe une fenetre entiere. */
.guild-chat-send { display: flex; gap: 8px; }.guild-chat-send { display: flex; gap: 8px; }
.guild-chat-send input { flex: 1; }

/* --- Le Panthéon --- */
.pan-row {
    display: flex; gap: 12px; align-items: flex-start;
    padding: 10px 4px; border-bottom: 1px solid var(--line-soft);
}
.pan-row:last-child { border-bottom: 0; }
.pan-season {
    font-family: var(--font-ui); font-size: 0.72rem; font-weight: 700;
    color: var(--accent); background: var(--surface-3);
    border: 1px solid var(--line-soft); border-radius: 999px;
    padding: 3px 10px; white-space: nowrap;
}
.pan-body { display: flex; flex-direction: column; gap: 2px; font-family: var(--font-ui); font-size: 0.8rem; }
.pan-body b { color: var(--gold-bright); }

.btn-row .ico { display: none; }

@media (max-width: 900px) {
    #warlord-bar { bottom: 78px; font-size: 0.72rem; padding: 6px 11px; gap: 7px; }
    .wb-pct { display: none; }
    .guild-chat-log { height: 240px; }

    /* Trois libelles d'action ne tiennent pas dans 390 px : on garde les icones,
       et la colonne Armee cede la place — elle est deja lisible ailleurs. */
    .guild-row-actions .lbl { display: none; }
    .btn-row .ico { display: inline; }
    .guild-row-actions .btn-row { padding: 4px 8px; min-width: 32px; }
    /* Cette regle vise la table des membres, ou la troisieme colonne est
       l'Armee. Le ralliement s'en exclut : sa troisieme colonne est la PART du
       butin, c'est-a-dire la seule information pour laquelle on ouvre cet
       onglet. Une table qui herite d'une autre herite aussi de ses raccourcis. */
    .guild-table:not(.rall-table) th:nth-child(3),
    .guild-table:not(.rall-table) td:nth-child(3) { display: none; }
    .guild-scroll { overflow-x: auto; }
}

/* Le rappel du Seigneur de guerre s'efface pendant qu'une fenetre est ouverte :
   il n'a rien a dire par-dessus ce que le joueur est en train de faire. */
body.modal-open #warlord-bar { display: none !important; }

/* ===================== FENÊTRE NOUVEAUTÉS =====================
   La fenêtre s'ouvrait sur un mur de notes de version. Elle s'ouvre
   maintenant sur ce qu'est le jeu ; les notes suivent, et l'historique
   reste replié tant que personne ne le demande. */

/* --- Une fenetre en colonne ------------------------------------------------
   Une fenetre qui pose un pied sous sa zone defilante doit se repartir en
   colonne, sinon elle devine la hauteur de cette zone par un calcul en dur — et
   le calcul se trompe. La regle mobile « .modal-content { max-height:
   calc(88vh - 60px) !important } » poussait ainsi le contenu des Nouveautes a
   556 px dans une fenetre plafonnee a 630 px : les 74 px restants ne suffisaient
   ni au titre ni au bouton, et overflow:hidden coupait « J'ai compris » en
   entier sur telephone.

   En colonne, l'entete et le pied prennent ce qu'il leur faut et le contenu
   prend ce qui reste, quelle que soit la hauteur de l'ecran.

   Attention : la classe ne suffit pas, il faut que le script pose display:flex.
   Ne l'utiliser que sur une fenetre dont le script est versionne par ?v= —
   admin.js, servi par l'API sans parametre de cache, s'est deja fait prendre. */
.modal-colonne { flex-direction: column; }
.modal-colonne > .modal-content {
    /* min-height:0 sans quoi un enfant flexible refuse de descendre sous la
       hauteur de son contenu et deborde quand meme. Le !important ne repond
       qu'a celui de la regle mobile. */
    flex: 1 1 auto; min-height: 0; max-height: none !important;
}
.modal-colonne > .modal-close,
.modal-colonne > h2,
.modal-colonne > .btn-upgrade { flex: 0 0 auto; }

/* L'entete des Nouveautes : titre a gauche, croix a droite, comme la Caserne et
   les Quetes. La croix etait posee avant le titre et, mil-close etant en
   position statique, elle atterrissait en haut a gauche — seule fenetre du jeu
   dans ce cas. */
#modal-changelog > .cl-head {
    display: flex; align-items: center; gap: 10px; flex: 0 0 auto;
    border-bottom: 2px solid var(--accent);
    padding-bottom: 10px; margin-bottom: 20px;
}
#modal-changelog > .cl-head > h2 {
    flex: 1; min-width: 0; margin: 0; text-align: left;
    border-bottom: 0; padding-bottom: 0;
}

.cl-body { padding-right: 4px; }

.cl-h {
    font-family: var(--font-ui); font-size: 0.68rem; font-weight: 700;
    text-transform: uppercase; letter-spacing: 0.1em; color: var(--accent);
    margin: 22px 0 0; text-shadow: none;
}
.cl-body > .cl-h:first-child { margin-top: 0; }
.cl-sub {
    font-family: var(--font-ui); font-size: 0.76rem; color: var(--muted);
    margin: 4px 0 12px;
}

/* --- le résumé du jeu --- */

.cl-guide {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(215px, 1fr));
    gap: 8px; margin-bottom: 4px;
}
.cl-card {
    background: var(--surface-2); border: 1px solid var(--line-soft);
    border-radius: var(--radius-sm); padding: 9px 11px;
    display: flex; gap: 9px; align-items: flex-start;
}
.cl-card > .ic { font-size: 1.05rem; line-height: 1.25; flex: 0 0 auto; }
.cl-card > .tx { min-width: 0; }
.cl-card .t {
    font-family: var(--font-ui); font-size: 0.78rem; font-weight: 700;
    color: var(--gold-bright); margin-bottom: 2px;
}
.cl-card .d {
    font-family: var(--font-ui); font-size: 0.72rem; line-height: 1.4;
    color: var(--text-dark); opacity: 0.85;
}

/* --- les notes de version --- */

.cl-ver { margin-top: 12px; }
.cl-ver-head {
    display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
    border-bottom: 1px solid var(--line-soft); padding-bottom: 5px;
}
.cl-ver-head .n {
    font-family: var(--font-title); font-size: 1rem; color: var(--gold-bright);
}
.cl-ver-head .d {
    font-family: var(--font-ui); font-size: 0.66rem; text-transform: uppercase;
    letter-spacing: 0.08em; color: var(--muted);
}
.cl-new-tag {
    font-family: var(--font-ui); font-size: 0.6rem; font-weight: 700;
    text-transform: uppercase; letter-spacing: 0.08em;
    background: var(--accent); color: #1a1510;
    padding: 2px 7px; border-radius: 9px;
}
.cl-notes {
    font-family: var(--font-ui); font-size: 0.79rem; line-height: 1.5;
    color: var(--text-dark); margin: 8px 0 0; padding-left: 18px;
}
.cl-notes li { margin-bottom: 5px; }

/* --- l'appel a l'action d'une note de version ---
   Une seule version en porte un a la fois. Il doit se voir sans hurler : la
   note se lit d'abord, le bouton se prend ensuite. */
.cl-appel {
    display: block; width: 100%; margin: 12px 0 2px; padding: 11px 14px;
    cursor: pointer; text-align: center;
    font-family: var(--font-ui); font-size: 0.8rem; font-weight: 700;
    color: #1a1510; background: var(--accent);
    border: 1px solid var(--accent); border-radius: var(--radius-sm);
    box-shadow: 0 2px 10px rgba(0,0,0,0.35);
}
@media (hover: hover) and (pointer: fine) {
    .cl-appel:hover { filter: brightness(1.08); }
}
.cl-appel:active { transform: translateY(1px); }
/* Deja actives : le bouton reste, pour le test, mais cesse de reclamer. */
.cl-appel.fait {
    color: var(--success); background: rgba(116,189,122,0.1);
    border-color: #3d6640; box-shadow: none; font-weight: 600;
}

/* --- l'historique replié --- */

.cl-history { margin: 18px 0 4px; }
.cl-history > summary {
    cursor: pointer; list-style: none;
    font-family: var(--font-ui); font-size: 0.75rem; font-weight: 600;
    color: var(--muted); padding: 9px 12px;
    background: var(--surface); border: 1px solid var(--line-soft);
    border-radius: var(--radius-sm);
}
.cl-history > summary::-webkit-details-marker { display: none; }
.cl-history > summary::before { content: '▸ '; color: var(--accent); }
.cl-history[open] > summary::before { content: '▾ '; }@media (hover: hover) and (pointer: fine) {
.cl-history > summary:hover { color: var(--text-light); }
}

.cl-old { border-bottom: 1px solid var(--line-soft); }
.cl-old > summary {
    cursor: pointer; list-style: none; padding: 8px 4px;
    font-family: var(--font-ui); font-size: 0.75rem; color: var(--text-dark);
    display: flex; align-items: baseline; gap: 8px;
}
.cl-old > summary::-webkit-details-marker { display: none; }@media (hover: hover) and (pointer: fine) {
.cl-old > summary:hover { color: var(--gold-bright); }
}
.cl-old > summary .v { font-weight: 700; }
.cl-old > summary .d {
    font-size: 0.64rem; text-transform: uppercase; letter-spacing: 0.06em;
    color: var(--muted);
}
.cl-old .cl-notes { font-size: 0.74rem; margin-bottom: 10px; }

@media (max-width: 600px) {
    .cl-guide { grid-template-columns: 1fr; }
    .cl-card .d { font-size: 0.74rem; }
}

}

/* ===================== GUILDE : CORRECTIFS 1.14.2 ===================== */

/* La colonne de droite tient ses cartes ensemble : sans elle, la troisieme
   carte de la grille repassait sous le tableau des membres, tout en bas. */
.guild-side { display: flex; flex-direction: column; gap: 12px; min-width: 0; }

.guild-banner-acts { display: flex; gap: 8px; align-items: center; flex-shrink: 0; }
.btn-recruit {
    height: 34px; padding: 0 14px; border-radius: var(--radius-sm); cursor: pointer;
    background: linear-gradient(180deg, #d9ad51, #b5893a); border: 1px solid #eac57a;
    color: #1c1408; font-family: var(--font-ui); font-size: 0.76rem; font-weight: 700;
    white-space: nowrap;
}@media (hover: hover) and (pointer: fine) {
.btn-recruit:hover { background: linear-gradient(180deg, #e6bb63, #c2953f); }
}

/* La carte qu'on vient d'atteindre depuis la banniere se signale une fois. */
@keyframes guild-flash {
    0%, 100% { box-shadow: 0 0 0 0 rgba(212,165,72,0); }
    35%      { box-shadow: 0 0 0 3px rgba(212,165,72,0.55); }
}
.guild-card.flash { animation: guild-flash 1.1s ease-out 2; }

/* --- le salon : le champ prend la place, le bouton prend la sienne --- */
.guild-chat-send { display: flex; gap: 8px; align-items: stretch; }
.guild-chat-send .chat-input {
    flex: 1 1 auto; min-width: 0; height: 40px; text-align: left; padding: 0 12px;
}
/* .guild-card .btn-res passe tous les boutons a 100 % : ici, non. */
.guild-card .btn-res.btn-send {
    width: auto; flex: 0 0 auto; margin-top: 0; padding: 0 22px;
}

/* --- les renforts adoptent le pas-a-pas de la caserne --- */
.sup-troops .send-row { margin-bottom: 6px; }
.sup-troops .send-row .portrait-fallback {
    width: 34px; height: 34px; border-radius: 7px; display: grid; place-items: center;
    background: var(--surface-2); border: 1px solid var(--line-soft); font-size: 1rem;
}
.sup-actions { display: flex; gap: 6px; margin-top: 2px; }
.sup-actions .btn-max { flex: 1; }
.sup-total {
    margin-top: 8px; font-family: var(--font-ui); font-size: 0.7rem;
    color: var(--muted); font-variant-numeric: tabular-nums;
}
.sup-total b { color: var(--gold-bright); }

/* Deux boutons a cote du nom, sur 390 px, ecrasaient le nom de la guilde :
   la banniere passe sur deux rangs et les actions prennent la largeur. */
@media (max-width: 600px) {
    .guild-banner { flex-wrap: wrap; }
    .guild-banner-acts { flex: 1 0 100%; justify-content: stretch; }
    .guild-banner-acts > button { flex: 1; }
    .guild-chat-send .btn-res.btn-send { padding: 0 14px; }
}

/* Le classement garde sa hauteur pendant qu'il se recharge : la liste
   precedente reste affichee, et l'attente ne se signale qu'au-dela d'un
   quart de seconde, quand elle devient perceptible. */
.lb-body { min-height: 180px; }
.lb-body.lb-busy { opacity: 0.5; pointer-events: none; }

/* Un renfort et un emissaire se distinguent d'un assaut au premier coup d'oeil. */
.map-soldier.support { filter: drop-shadow(0 0 7px rgba(116,189,122,0.9)) drop-shadow(0 5px 5px rgba(0,0,0,0.8)); }
.map-soldier.diplo   { filter: drop-shadow(0 0 7px rgba(212,165,72,0.95)) drop-shadow(0 5px 5px rgba(0,0,0,0.8)); }
.map-soldier.fonde   { filter: drop-shadow(0 0 7px rgba(201,178,122,0.9)) drop-shadow(0 5px 5px rgba(0,0,0,0.8)); }


/* Un batiment qui attend une recherche : visible, mais clairement ferme. */
.building-card.is-locked { opacity: 0.72; }
.building-locked {
    display: flex; align-items: center; gap: 7px;
    margin: 8px 0; padding: 7px 10px; border-radius: 6px;
    background: rgba(0,0,0,0.3); border: 1px dashed rgba(214,158,74,0.45);
    font-family: var(--font-ui); font-size: 0.78rem; color: #e8c58a;
}
.building-locked .mg-ic { width: 15px; height: 15px; flex: 0 0 auto; }

/* ---- La Residence : fonder un village ---- */
.res-fonder {
    margin-top: 14px; padding: 12px;
    background: rgba(0,0,0,0.25); border: 1px solid var(--panel-border, rgba(255,255,255,0.12));
    border-radius: 8px;
}
.res-fonder h4 {
    margin: 0 0 8px; display: flex; align-items: center; gap: 7px;
    font-family: var(--font-title, serif); font-size: 1rem; color: var(--gold-bright, #f0c674);
}
.res-fonder h4 .mg-ic { width: 18px; height: 18px; }
.res-spot {
    display: flex; align-items: center; gap: 9px; width: 100%;
    margin-top: 7px; padding: 9px 11px; cursor: pointer;
    background: rgba(255,255,255,0.04); border: 1px solid var(--panel-border, rgba(255,255,255,0.14));
    border-radius: 7px; color: var(--text, #f2e9d6);
    font-family: var(--font-ui); text-align: left;
}
.res-spot:hover { background: rgba(212,165,72,0.16); border-color: var(--accent, #d4a548); }
.res-spot .mg-ic { width: 17px; height: 17px; flex: 0 0 auto; }
.res-spot .rs-c { font-weight: 700; font-variant-numeric: tabular-nums; }
.res-spot .rs-d { margin-left: auto; font-size: 0.76rem; opacity: 0.65; }

/* Le colon n'a pas de portrait peint : son symbole tient la place. */
.portrait .portrait-emoji .mg-ic { width: 46px; height: 46px; }

/* ===================== PANNEAU ADMIN : LETTRE AUX JOUEURS ===================== */

.mail-card {
    background: var(--surface); border: 1px solid var(--line-soft);
    border-radius: var(--radius); padding: 16px 18px; text-align: left;
    font-family: var(--font-ui);
}
.mail-lead { margin: 0 0 16px; font-size: 0.8rem; color: var(--muted); line-height: 1.6; }
.mail-warn {
    margin-bottom: 14px; padding: 10px 12px; border-radius: var(--radius-sm);
    background: rgba(207,106,85,0.12); border: 1px solid #6b3328;
    color: var(--danger); font-size: 0.78rem; line-height: 1.5;
}

.mail-field { margin-bottom: 14px; }
.mail-field > label {
    display: block; margin-bottom: 6px;
    font-size: 0.66rem; font-weight: 700; text-transform: uppercase;
    letter-spacing: 0.09em; color: var(--accent);
}
.mail-opt { text-transform: none; letter-spacing: 0; font-weight: 400; color: var(--muted); }
.mail-field input.mkt-input, .mail-field select.mkt-input { width: 100%; text-align: left; }
/* La regle .mkt-input ne vise que input et select : un textarea repartirait
   du blanc du navigateur. On lui redonne la meme peau. */
textarea.mail-textarea {
    width: 100%; min-height: 84px; resize: vertical; padding: 10px 12px; line-height: 1.5;
    text-align: left; box-sizing: border-box;
    background: #0c0a07; border: 1px solid var(--panel-border); border-radius: var(--radius-sm);
    color: var(--text-light); font-family: var(--font-ui); font-size: 0.82rem;
}
textarea.mail-textarea:focus { outline: none; border-color: var(--accent); }
textarea.mail-textarea::placeholder { color: var(--muted); }

.mail-target { display: flex; gap: 16px; flex-wrap: wrap; }
.mail-radio {
    display: flex; align-items: center; gap: 7px; cursor: pointer;
    font-size: 0.82rem; color: var(--text-light);
}
.mail-radio input { accent-color: var(--accent); }
.mail-radio b { color: var(--gold-bright); }
.mail-note { margin: 8px 0 0; font-size: 0.72rem; color: var(--muted); line-height: 1.5; }

.mail-actions { display: flex; gap: 8px; margin-top: 4px; }
.mail-actions .btn-upgrade { flex: 1; }

.mail-result {
    margin: 14px 0 0; padding: 10px 12px; border-radius: var(--radius-sm);
    font-size: 0.8rem; line-height: 1.5;
    background: var(--surface-2); border: 1px solid var(--line-soft); color: var(--text-light);
}
.mail-result.ok { border-color: var(--success); color: var(--success); }
.mail-result.ko { border-color: #6b3328; color: var(--danger); }

.mail-sub {
    margin: 16px 0 8px; font-size: 0.7rem; text-transform: uppercase;
    letter-spacing: 0.08em; color: var(--muted);
}
.mail-sub b { color: var(--gold-bright); text-transform: none; letter-spacing: 0; }
.mail-preview {
    width: 100%; height: 520px; border: 1px solid var(--panel-border);
    border-radius: var(--radius-sm); background: #14100b;
}

/* La liste des desabonnes : une trace, pas un tableau de bord. Elle reste
   discrete sous le formulaire, et se lit d'un coup d'oeil. */
.mail-desab {
    margin-top: 18px; padding-top: 14px;
    border-top: 1px solid var(--panel-border);
}
.mail-desab .mail-sub { display: flex; align-items: center; gap: 10px; margin-top: 0; }
.mail-desab-refresh {
    margin-left: auto; background: none; border: 1px solid var(--panel-border);
    color: var(--muted); border-radius: var(--radius-sm); padding: 4px 10px;
    font-size: 0.68rem; font-family: inherit; cursor: pointer;
    text-transform: none; letter-spacing: 0;
}
.mail-desab-refresh:hover { color: var(--gold-bright); border-color: var(--gold); }
.mail-desab-list { margin-top: 10px; }
.mail-desab-row {
    display: grid; grid-template-columns: 1fr 1.4fr auto; gap: 10px;
    align-items: center; padding: 7px 10px; font-size: 0.78rem;
    border-bottom: 1px solid var(--panel-border);
}
.mail-desab-row:last-child { border-bottom: 0; }
.mail-desab-nom { color: var(--text); font-weight: 600; }
.mail-desab-mail {
    color: var(--muted); font-size: 0.72rem;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.mail-desab-date { color: var(--muted); font-size: 0.72rem; white-space: nowrap; }

/* Sur telephone, l'adresse passe sous le pseudo plutot que d'etre tronquee. */
@media (max-width: 600px) {
    .mail-desab-row { grid-template-columns: 1fr auto; }
    .mail-desab-mail { grid-column: 1 / -1; white-space: normal; word-break: break-all; }
}

@media (max-width: 600px) {
    .mail-actions { flex-direction: column; }
    .mail-preview { height: 420px; }
}

/* C'est une case a cocher, pas un intitule de champ : elle ne doit pas heriter
   des capitales de .mail-field > label. */
.mail-check {
    display: flex; align-items: flex-start; gap: 8px; margin: 12px 0 0;
    cursor: pointer; line-height: 1.45;
    font-size: 0.8rem; font-weight: 400; color: var(--text-light);
    text-transform: none; letter-spacing: 0;
}
.mail-check input { accent-color: var(--accent); margin-top: 2px; flex-shrink: 0; }
.mail-check b { color: var(--gold-bright); }

/* ===================== CORRECTIFS 1.14.6 ===================== */

/* iOS compte 100vh avec la barre d'adresse repliee : une modale a 90vh
   depasse alors l'ecran visible et son bas devient inatteignable. */
@supports (height: 100dvh) {
    .modal { max-height: 90dvh; }
    .modal-content { max-height: calc(90dvh - 100px); }
    .mil-modal { max-height: 90dvh; }
}

/* Le panneau d'administration a trois etages : l'en-tete et les onglets
   restent en place, SEUL LE CORPS DEFILE. Le panneau entier defilait : sur
   telephone le titre et les onglets partaient avec le contenu, et le seul
   bouton « Fermer » attendait sous la derniere ligne du plus long des onglets.

   admin.js est servi par l'API et ouvre la fenetre en `display: block` dans
   ses versions passees : le selecteur d'attribut rend la colonne flex quoi que
   le script ait pose, sans quoi les etages s'effondreraient en silence. */
#modal-admin[style*="block"],
#modal-admin[style*="flex"] { display: flex !important; }
#modal-admin {
    flex-direction: column;
    width: 95%; max-width: 860px;
    height: 88vh; max-height: 88vh;
    padding: 0;
    overflow: hidden;
}
@supports (height: 100dvh) {
    #modal-admin { height: 88dvh; max-height: 88dvh; }
}
.adm-tete {
    display: flex; align-items: center; gap: 10px;
    padding: 14px 16px 10px; flex-shrink: 0;
}
.adm-tete h2 {
    flex: 1; min-width: 0; margin: 0; padding: 0; border: 0;
    font-size: 1.05rem; color: var(--gold-bright); text-align: left;
    display: flex; align-items: center; gap: 8px;
}
.adm-en-ligne {
    display: inline-flex; align-items: center; gap: 6px;
    font-size: 0.72rem; color: var(--success); white-space: nowrap;
}
.adm-en-ligne::before, .adm-point {
    content: ''; width: 7px; height: 7px; border-radius: 50%;
    background: var(--success); box-shadow: 0 0 5px rgba(116,189,122,0.6); flex-shrink: 0;
}
#modal-admin > .adm-corps {
    flex: 1 1 auto; min-height: 0;
    max-height: none !important;
    overflow-y: auto !important;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    padding: 14px 16px calc(18px + env(safe-area-inset-bottom)) !important;
}

/* Sur telephone, le panneau prend tout l'ecran visible. 100dvh suit la zone
   reellement vue, la ou une modale centree par top:50% se calait sur le
   viewport de mise en page d'iOS -- plus grand que ce que l'on voit quand la
   barre d'adresse est affichee -- et poussait son bas hors de l'ecran. */
@media (max-width: 700px) {
    #modal-admin {
        top: 0; left: 0; transform: none;
        width: 100%; max-width: none;
        height: 100vh; max-height: 100vh;
        border-radius: 0; border-width: 0;
        backdrop-filter: none; -webkit-backdrop-filter: none;
    }
    .adm-tete { padding: max(12px, env(safe-area-inset-top)) 12px 8px; }
    #modal-admin > .adm-corps { padding: 12px 12px calc(18px + env(safe-area-inset-bottom)) !important; }
}
@supports (height: 100dvh) {
    @media (max-width: 700px) {
        #modal-admin { height: 100dvh; max-height: 100dvh; }
    }
}

/* Le bandeau du Seigneur de guerre se referme jusqu'au suivant. */
.wb-close {
    flex: 0 0 auto; width: 20px; height: 20px; margin-left: 2px;
    display: grid; place-items: center;
    background: transparent; border: 0; border-radius: 50%;
    color: var(--muted); font-family: var(--font-ui); font-size: 0.8rem;
    line-height: 1; cursor: pointer;
}@media (hover: hover) and (pointer: fine) {
.wb-close:hover { background: rgba(255,255,255,0.08); color: var(--text-light); }
}

/* ===================== MESSAGES BREFS =====================
   Un refus de recrutement ou un renfort parti n'ont pas besoin d'une fenetre
   qui recouvre le jeu et demande un clic. Ils passent en bas de l'ecran et
   s'effacent seuls. Au-dessus des modales : un message declenche depuis une
   modale doit rester lisible. */

#toasts {
    position: fixed; left: 50%; transform: translateX(-50%);
    bottom: 84px; z-index: 12000;
    display: flex; flex-direction: column-reverse; align-items: center; gap: 8px;
    width: min(440px, calc(100vw - 24px));
    pointer-events: none;
}

.toast {
    width: 100%; box-sizing: border-box;
    display: flex; align-items: flex-start; gap: 9px;
    padding: 11px 13px;
    background: var(--surface-2); border: 1px solid var(--panel-border);
    border-left: 3px solid var(--accent);
    border-radius: var(--radius-sm);
    box-shadow: 0 8px 24px rgba(0,0,0,0.6);
    font-family: var(--font-ui); font-size: 0.8rem; line-height: 1.45;
    color: var(--text-light);
    pointer-events: auto; cursor: pointer;
    animation: toast-in .18s ease-out;
}
.toast.out { animation: toast-out .22s ease-in forwards; }
.toast > .ic { flex: 0 0 auto; font-size: 0.95rem; line-height: 1.4; }
.toast > .tx { min-width: 0; }
.toast.ko { border-left-color: var(--danger); }
.toast.ok { border-left-color: var(--success); }
.toast b { color: var(--gold-bright); }

@keyframes toast-in  { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@keyframes toast-out { to { opacity: 0; transform: translateY(8px); } }

@media (max-width: 900px) {
    /* Au-dessus de la barre d'onglets du pouce, et de la zone sure iOS. */
    #toasts { bottom: calc(86px + env(safe-area-inset-bottom)); }
}
@media (prefers-reduced-motion: reduce) {
    .toast, .toast.out { animation: none; }
}

/* ===================== LE TCHAT =====================
   Une conversation, pas un journal d'evenements : les messages d'un meme
   auteur se regroupent, les siens se distinguent, et la date change de jour
   quand il le faut. */

.chat-pane { display: none; flex-direction: column; min-height: 0; }
.support-tab-content.chat-pane[style*="flex"] { display: flex; }

/* Le corps de la messagerie. En mode tchat il ne defile plus lui-meme : sinon
   on se retrouvait avec deux ascenseurs et il fallait faire defiler la fenetre
   entiere pour atteindre le champ de saisie. Seul le journal defile. */
.msg-body {
    background: rgba(0,0,0,0.4);
    padding: 10px;
    border-radius: 8px;
    text-align: left;
    max-height: 50vh;
    overflow-y: auto;
}
.msg-body.chat-mode {
    display: flex;
    flex-direction: column;
    min-height: 0;
    height: min(60vh, calc(90vh - 190px));
    max-height: none;
    overflow: hidden;
}
.msg-body.chat-mode .chat-pane { flex: 1 1 auto; min-height: 0; }
.msg-body.chat-mode .chat-log { flex: 1 1 auto; min-height: 0; max-height: none; }
.msg-body.chat-mode .chat-compose,
.msg-body.chat-mode .chat-foot,
.msg-body.chat-mode .chat-hint { flex: 0 0 auto; }

.chat-head {
    display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
    padding-bottom: 8px; margin-bottom: 8px;
    border-bottom: 1px solid var(--line-soft);
    font-family: var(--font-ui);
}
.chat-scope { font-size: 0.8rem; font-weight: 700; color: var(--gold-bright); }
.chat-hint { font-size: 0.72rem; color: var(--muted); }

.chat-log {
    flex: 1 1 auto; min-height: 240px; max-height: 46vh; overflow-y: auto;
    overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
    background: rgba(0,0,0,0.28);
    border: 1px solid var(--line-soft); border-radius: var(--radius-sm);
    padding: 10px 12px;
    font-family: var(--font-ui);
}

.chat-day {
    display: flex; align-items: center; gap: 10px;
    margin: 12px 0 8px;
    font-size: 0.64rem; text-transform: uppercase; letter-spacing: 0.1em;
    color: var(--muted);
}
.chat-day::before, .chat-day::after {
    content: ''; flex: 1; height: 1px; background: var(--line-soft);
}
.chat-log > .chat-day:first-child { margin-top: 0; }

.chat-msg { margin-bottom: 8px; }
.chat-msg.grouped { margin-top: -5px; }
.chat-msg-head {
    display: flex; align-items: baseline; gap: 7px; margin-bottom: 2px;
}
.chat-who {
    font: inherit; font-size: 0.78rem; font-weight: 700; color: var(--accent);
    background: none; border: 0; padding: 0; cursor: pointer;
}
.chat-who:hover { text-decoration: underline; }
.chat-msg.mine .chat-who { color: var(--gold-bright); }
.chat-who.admin::after {
    content: 'admin'; margin-left: 5px; padding: 1px 5px; border-radius: 4px;
    background: var(--surface-3); border: 1px solid var(--panel-border);
    color: var(--muted); font-size: 0.58rem; font-weight: 700;
    text-transform: uppercase; letter-spacing: 0.06em; vertical-align: middle;
}
.chat-at { font-size: 0.64rem; color: var(--text-dim, var(--muted)); font-variant-numeric: tabular-nums; }
.chat-body {
    font-size: 0.82rem; line-height: 1.5; color: var(--text-light);
    word-break: break-word; white-space: pre-wrap;
    padding: 6px 10px; border-radius: 8px;
    background: var(--surface); border: 1px solid var(--line-soft);
    border-left: 2px solid transparent;
}
.chat-msg.mine .chat-body { border-left-color: var(--accent); background: var(--surface-2); }
/* Le heraut : une annonce, pas une bulle. Le liseré doré et la police de
   titre le detachent des seigneurs sans crier plus fort qu'eux. */
.chat-heraut-nom {
    display: inline-flex; align-items: center; gap: 5px;
    font-family: var(--font-title, inherit); font-size: 0.76rem; font-weight: 700;
    color: var(--gold-bright, #f0c674); letter-spacing: 0.03em;
}
.chat-heraut-nom svg { width: 15px; height: 15px; }
.chat-heraut .chat-body {
    border-left: 2px solid var(--gold-bright, #f0c674);
    background: linear-gradient(90deg, rgba(240, 198, 116, 0.10), transparent 70%), var(--surface);
}

/* Le lien du heraut vers la carte : un vrai bouton, pas un `title` -- il se
   lit au doigt. `white-space: pre-wrap` du corps garderait sinon les sauts de
   ligne du gabarit, d'ou `normal` ici. */
.chat-heraut-carte {
    display: flex; align-items: center; gap: 6px; margin-top: 6px;
    white-space: normal; cursor: pointer;
    padding: 4px 10px; border-radius: 999px; font: inherit; font-size: 0.76rem; font-weight: 600;
    color: var(--gold-bright, #f0c674); background: rgba(240, 198, 116, 0.10);
    border: 1px solid rgba(240, 198, 116, 0.35);
}
.chat-heraut-carte:hover { background: rgba(240, 198, 116, 0.18); }
.chat-heraut-carte svg { width: 14px; height: 14px; }

/* `.chat-mod` est declaree une seule fois, plus bas, avec les actions du tchat.
   Elle l'etait ici aussi : deux definitions du meme nom, c'est la derniere
   chargee qui gagne, et c'est exactement ainsi qu'un correctif se perd. */

.chat-empty {
    text-align: center; color: var(--muted); font-size: 0.8rem;
    padding: 28px 12px; line-height: 1.6;
}

.chat-jump {
    align-self: center; margin-top: -14px; margin-bottom: 6px; position: relative; z-index: 2;
    padding: 5px 14px; border-radius: 999px; cursor: pointer;
    background: var(--accent); border: 0; color: #1c1408;
    font-family: var(--font-ui); font-size: 0.7rem; font-weight: 700;
    box-shadow: 0 4px 12px rgba(0,0,0,0.5);
}

.chat-compose { display: flex; gap: 8px; align-items: flex-end; margin-top: 10px; }
.chat-compose textarea {
    flex: 1 1 auto; min-width: 0; box-sizing: border-box;
    min-height: 40px; max-height: 120px; resize: none; overflow-y: auto;
    padding: 10px 12px; line-height: 1.4;
    background: #0c0a07; border: 1px solid var(--panel-border);
    border-radius: var(--radius-sm); color: var(--text-light);
    font-family: var(--font-ui); font-size: 0.82rem;
}
.chat-compose textarea:focus { outline: none; border-color: var(--accent); }
.chat-compose textarea::placeholder { color: var(--muted); }

.chat-send {
    flex: 0 0 auto; width: 44px; height: 40px; border-radius: var(--radius-sm);
    background: linear-gradient(180deg, #d9ad51, #b5893a); border: 1px solid #eac57a;
    color: #1c1408; font-size: 1.05rem; cursor: pointer;
}@media (hover: hover) and (pointer: fine) {
.chat-send:hover:not(:disabled) { background: linear-gradient(180deg, #e6bb63, #c2953f); }
}
.chat-send:disabled { background: transparent; border-color: var(--panel-border); color: var(--muted); cursor: not-allowed; }

.chat-foot {
    display: flex; justify-content: space-between; gap: 10px; margin-top: 6px;
    font-family: var(--font-ui); font-size: 0.66rem; color: var(--muted);
}
.chat-count { font-variant-numeric: tabular-nums; }
.chat-count.near { color: var(--danger); }

@media (max-width: 600px) {
    .chat-log { max-height: 38vh; min-height: 180px; }
    .chat-keys { display: none; }
}

/* Les onglets de la messagerie reprennent le bandeau segmente du jeu au lieu
   de deux gros boutons bleus qui juraient avec tout le reste.

   **Deux marges se contredisaient, et les deux se voyaient.** `.msg-tabs`
   remettait a zero le `margin-top: 14px` de `.barracks-tabs` : le bandeau
   venait donc toucher le bouton de fermeture, `.mil-head` n'ayant aucune
   marge basse. Et `.mil-head` porte `padding: 16px 18px 0`, une marge faite
   pour une fenetre qui n'en a pas d'elle-meme (la Caserne) -- ici elle
   s'ajoute aux 20 px de `.modal`, donc le titre partait 18 px plus a droite
   que le bandeau et que le corps, tous deux poses sur le bord de la fenetre.

   La regle : *une marge interieure ecrite pour un cadre ne se transporte pas
   telle quelle dans un cadre qui en a deja une.* On la retire ici plutot que
   de decaler les deux autres, parce que c'est le titre qui est de trop. */
#modal-player-tickets .mil-head { padding: 0; }
.msg-tabs { margin: 14px 0 12px; }
.msg-tabs .tab-btn {
    flex: 1 1 auto; min-width: 0; padding: 8px 6px; border: 0; border-radius: 7px;
    cursor: pointer; background: transparent; color: var(--muted);
    font-family: var(--font-ui); font-size: 0.76rem; font-weight: 600;
    display: inline-flex; align-items: center; justify-content: center; gap: 6px;
    white-space: nowrap;
}@media (hover: hover) and (pointer: fine) {
.msg-tabs .tab-btn:hover { color: var(--text-light); }
}
.msg-tabs .tab-btn.on {
    background: var(--surface-3); color: var(--gold-bright);
    box-shadow: inset 0 0 0 1px var(--panel-border);
}
.seg-dot {
    width: 7px; height: 7px; border-radius: 50%;
    background: var(--danger); flex: 0 0 auto;
}
.chat-hint {
    margin: 0 0 8px; padding-bottom: 8px;
    border-bottom: 1px solid var(--line-soft);
    font-family: var(--font-ui); font-size: 0.72rem; color: var(--muted);
}

/* ========================================================
   Carte du monde — telephone
   La fiche devient une feuille par le bas, les commandes se resserrent.
======================================================== */
#modal-worldmap > .modal-content {
    max-height: 100% !important;
    padding: 0 !important;
    overflow: hidden !important;
    width: 100% !important;
    max-width: none !important;
}

@media (max-width: 768px) {
    .wm-head {
        flex-wrap: wrap;
        padding: 10px;
        gap: 8px;
    }
    .wm-head h2 { font-size: 0.95rem; }
    .wm-search { order: 3; flex-basis: 100%; max-width: none; }
    .wm-head h2 { flex: 1 1 auto; }
    .wm-quick { flex-wrap: nowrap; gap: 8px; }
    .wm-quick .wm-chip, .wm-camps-btn { padding: 7px 12px; font-size: 0.76rem; }
    /* **Le bouton des camps se reduit a son icone.** Ecrit en toutes lettres il
       prend la moitie de la ligne, et la bande des filtres -- qui porte
       desormais les cinq filtres ET les six niveaux -- n'avait plus que cent
       soixante pixels pour defiler : on y voyait « Joueurs » et la moitie de
       « Barbares ». L'icone et le compteur disent la meme chose, et le libelle
       reste dans l'`aria-label` pour qui ne voit pas le dessin. */
    .wm-camps-btn { padding: 7px 10px; gap: 4px; }
    .wm-camps-btn .wm-camps-txt { display: none; }
    /* La bande de puces defile ; sans ce fondu elle parait simplement coupee. */
    .wm-quick-filters {
        -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 20px), transparent);
        mask-image: linear-gradient(to right, #000 calc(100% - 20px), transparent);
    }
    .wm-camps-wrap { position: static; }
    .wm-camps-list { left: 10px; right: 10px; width: auto; max-height: 52vh; }

    .wm-zoom { right: 8px; top: 8px; }
    .wm-zoom button { width: 44px; height: 44px; }
    .wm-legend-wrap { left: 8px; top: 8px; max-width: calc(100% - 70px); }
    .wm-coords { left: 8px; bottom: 8px; font-size: 0.7rem; }

    .wm-card {
        left: 0; right: 0; bottom: 0;
        width: auto;
        max-height: 62%;
        border-radius: 16px 16px 0 0;
        border-left: 0; border-right: 0; border-bottom: 0;
        padding: 14px 14px calc(14px + env(safe-area-inset-bottom, 0px));
        box-shadow: 0 -12px 34px rgba(0,0,0,0.75);
        animation: wmSheetIn 0.18s ease-out;
    }
    @keyframes wmSheetIn {
        from { transform: translateY(100%); }
        to   { transform: translateY(0); }
    }
    /* La fiche couvre l'indicateur de position : on le releve. */
    body.wm-card-open .wm-coords { display: none; }
    .wm-act { padding: 12px; font-size: 0.86rem; }
}


/* ========================================================
   Ecrans tactiles : un appui doit suffire
   Un effet :hover pose sur un element cliquable coute un appui sur
   telephone -- le premier applique le survol, le second seulement
   declenche l'action. Toutes les regles de survol du fichier sont
   desormais conditionnees a un vrai pointeur ; ici on rend au doigt
   ce que le survol lui donnait, et un retour immediat a l'appui.
======================================================== */

/* Ni attente de double-tap pour zoomer, ni voile gris au contact. */
button,
a,
[onclick],
input,
select,
textarea,
summary,
.btn-upgrade,
.btn-bar,
.tab-btn,
.mtab,
.res-chip,
.modal-close {
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
}

@media (hover: none) {
    /* Ce que le survol revelait doit rester lisible au doigt. */
    .res-chip .storage-pct { opacity: 1; }
    .chat-mod button { opacity: 1; }

    /* Un appui se voit, puisqu'il n'y a plus de survol pour le faire. */
    button:active,
    [onclick]:active,
    .btn-upgrade:active,
    .btn-bar:active,
    .tab-btn:active,
    .mtab:active,
    .res-chip:active,
    .modal-close:active {
        filter: brightness(1.18);
    }
}

/* ========================================================
   Écran d'attente au démarrage
   Le serveur redémarre à chaque publication ; le jeu patiente ici
   au lieu d'afficher un village vide dont il ne se relevait pas.
======================================================== */
#boot-overlay {
    position: fixed;
    inset: 0;
    z-index: 20000;
    display: none;
    align-items: center;
    justify-content: center;
    background: rgba(8, 12, 18, 0.92);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
    padding: 24px;
}
.boot-card {
    text-align: center;
    max-width: 340px;
    background: var(--surface, #16202c);
    border: 1px solid var(--line-soft, rgba(212,165,72,0.3));
    border-radius: 14px;
    padding: 26px 22px;
    box-shadow: 0 18px 44px rgba(0,0,0,0.7);
}
.boot-card h3 {
    margin: 14px 0 6px;
    font-family: var(--font-title, inherit);
    font-size: 1.05rem;
    color: var(--gold-bright, #f0c674);
}
.boot-card p {
    margin: 0;
    font-size: 0.84rem;
    line-height: 1.5;
    color: rgba(242,233,214,0.7);
}
.boot-spin {
    width: 34px;
    height: 34px;
    margin: 0 auto;
    border-radius: 50%;
    border: 3px solid rgba(212,165,72,0.25);
    border-top-color: var(--accent, #d4a548);
    animation: bootSpin 0.9s linear infinite;
}
@keyframes bootSpin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
    .boot-spin { animation-duration: 2.4s; }
}
#boot-retry {
    margin-top: 16px;
    padding: 10px 18px;
    border-radius: 9px;
    border: 1px solid var(--accent, #d4a548);
    background: rgba(212,165,72,0.16);
    color: var(--gold-bright, #f0c674);
    font-family: var(--font-ui, inherit);
    font-size: 0.84rem;
    cursor: pointer;
    touch-action: manipulation;
}

/* ===================== LES EVENEMENTS =====================
   Meme grammaire que les autres fenetres : en-tete fige, corps qui defile,
   barre d'action. Un evenement peut porter trois options, chacune avec son
   cout et sa consequence annoncee -- l'ancienne boite a deux boutons ne
   savait pas les montrer. */

.ev-modal { max-width: 520px; }
.ev-modal .mil-head { border-bottom: 1px solid var(--line-soft); padding-bottom: 12px; }
/* La couleur de la cire suit la rarete : le cachet du titre, celui qui se
   brise a l'ouverture, le reflet et la lueur la lisent tous ici. */
.ev-modal {
    --cire: #a3301f; --cire-clair: #d9644c; --cire-sombre: #561109;
    --eclat: rgba(255,226,170,0.22);
}
.ev-modal.ev-r-rare { --cire: #2f5f93; --cire-clair: #6a9bd0; --cire-sombre: #142c4a; --eclat: rgba(60,115,185,0.32); }
.ev-modal.ev-r-epic { --cire: #6d3e93; --cire-clair: #a67acb; --cire-sombre: #311748; --eclat: rgba(125,60,175,0.34); }
.ev-modal.ev-r-legendary {
    --cire: #b8862f; --cire-clair: #f0cf7c; --cire-sombre: #5e3f0b; --eclat: rgba(214,150,30,0.45);
    border-color: #c99a3e;
}

/* Le parchemin lui-meme. Le message d'un evenement arrive par messager : il
   s'ecrit a l'encre sur du papier, pas sur le bois sombre des autres
   fenetres -- c'est ce qui le distingue d'un ecran de gestion au premier
   coup d'oeil. Les jetons de couleur sont redefinis pour la fenetre seule :
   le titre, la croix, les options et la barre du bas les lisent deja, et
   suivent sans une regle de plus. */
.ev-modal {
    --panel-border: #b3925c; --line-soft: rgba(110,78,36,0.26);
    --surface: rgba(255,249,234,0.55); --surface-2: rgba(255,248,228,0.9);
    --text-light: #3a2814; --text-dark: #3a2814; --muted: #6e5a3e;
    --gold-bright: #7a2e14; --accent: #9a6b22; --danger: #a8402a; --success: #3f7d45;
    color: var(--text-light);
    border: 1px solid #6e4e24;
    background:
        /* les deux rouleaux, en haut et en bas */
        linear-gradient(180deg, #5e3f1c 0, #b88d52 3px, #e0bd84 5px, #8a6233 9px, rgba(90,60,25,0.3) 11px, transparent 16px) top / 100% 16px no-repeat,
        linear-gradient(0deg, #5e3f1c 0, #b88d52 3px, #e0bd84 5px, #8a6233 9px, rgba(90,60,25,0.3) 11px, transparent 16px) bottom / 100% 16px no-repeat,
        /* deux taches d'age et la fibre du papier */
        radial-gradient(circle at 12% 78%, rgba(150,100,40,0.13), transparent 26%),
        radial-gradient(circle at 88% 22%, rgba(150,100,40,0.1), transparent 22%),
        repeating-linear-gradient(0deg, rgba(120,90,40,0.035) 0 2px, transparent 2px 5px),
        radial-gradient(ellipse at 50% 40%, #f7ecd3 0%, #ecdab4 58%, #d6bc8a 100%);
    box-shadow: 0 14px 44px rgba(0,0,0,0.85), inset 0 0 60px rgba(120,80,30,0.38);
    backdrop-filter: none; -webkit-backdrop-filter: none;
}
.ev-modal .mil-head { padding-top: 22px; }
.ev-modal .ev-bar { background: transparent; padding-bottom: 20px; }
.ev-modal .ev-rarity.rare { color: #2f5f93; border-color: rgba(47,95,147,0.5); }
.ev-modal .ev-rarity.epic { color: #6d3e93; border-color: rgba(109,62,147,0.5); }
.ev-modal .ev-opt.good { border-color: rgba(63,125,69,0.55); }
.ev-modal .ev-opt.bad { border-color: rgba(168,64,42,0.55); }
.ev-modal .ev-opt-label { color: #2c1d0c; }
.ev-icon {
    flex-shrink: 0; width: 38px; height: 38px; border-radius: 50%;
    display: grid; place-items: center; line-height: 1;
    background: radial-gradient(circle at 34% 30%, var(--cire-clair), var(--cire) 55%, var(--cire-sombre));
    box-shadow: inset 0 0 0 3px rgba(0,0,0,0.2), inset 0 2px 3px rgba(255,255,255,0.22), 0 2px 5px rgba(0,0,0,0.5);
}
.ev-icon .mg-ic.big { width: 22px; height: 22px; vertical-align: 0; }

.ev-rarity {
    flex-shrink: 0; padding: 3px 9px; border-radius: 999px;
    font-family: var(--font-ui); font-size: 0.58rem; font-weight: 700;
    text-transform: uppercase; letter-spacing: 0.09em;
    background: var(--surface-2); border: 1px solid var(--line-soft); color: var(--muted);
}
.ev-rarity.rare { color: #7fa9d8; border-color: rgba(127,169,216,0.45); }
.ev-rarity.epic { color: #b98ad8; border-color: rgba(185,138,216,0.45); }
.ev-rarity.legendary {
    color: #1c1408; border-color: #eac57a;
    background: linear-gradient(180deg, #e6bb63, #c2953f);
}

.ev-meta {
    display: flex; justify-content: space-between; gap: 10px; margin-top: 9px;
    font-family: var(--font-ui); font-size: 0.66rem; color: var(--muted);
}
.ev-timer { font-variant-numeric: tabular-nums; }

.ev-body { font-family: var(--font-ui); }
.ev-desc {
    margin: 0 0 14px; font-size: 0.82rem; line-height: 1.6;
    color: var(--text-light);
}

.ev-options { display: flex; flex-direction: column; gap: 8px; }
.ev-opt {
    width: 100%; text-align: left; cursor: pointer;
    display: flex; flex-direction: column; gap: 4px;
    padding: 11px 13px; border-radius: var(--radius-sm);
    background: var(--surface); border: 1px solid var(--panel-border);
    color: var(--text-light); font-family: var(--font-ui);
}
.ev-opt.good { border-color: rgba(116,189,122,0.45); }
.ev-opt.bad { border-color: rgba(207,106,85,0.45); }
@media (hover: hover) and (pointer: fine) {
    .ev-opt:hover:not(:disabled) { background: var(--surface-2); border-color: var(--accent); }
}
.ev-opt:disabled, .ev-opt.ko { cursor: not-allowed; opacity: 0.55; }
.ev-opt-top { display: flex; align-items: baseline; gap: 10px; }
.ev-opt-label { flex: 1; min-width: 0; font-size: 0.8rem; font-weight: 700; }
.ev-opt-detail { font-size: 0.7rem; color: var(--muted); line-height: 1.45; }
.ev-cost { display: inline-flex; gap: 8px; flex-shrink: 0; font-size: 0.74rem; font-variant-numeric: tabular-nums; }
.ev-cost .insufficient { color: var(--danger); }
.ev-cost img { width: 13px; height: 13px; vertical-align: -2px; }

.ev-outcome-head {
    font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.09em;
    color: var(--gold-bright); margin-bottom: 10px;
}
/* Le bilan : une carte par consequence, qui arrivent l'une apres l'autre. */
.ev-cartes { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.ev-cartes li {
    padding: 8px 12px; border-radius: var(--radius-sm);
    background: var(--surface); border: 1px solid var(--line-soft); border-left: 3px solid var(--accent);
    font-size: 0.8rem; line-height: 1.5; color: var(--text-light);
}

/* Le tirage au sort : le de roule, puis le verdict tombe comme un tampon. */
.ev-sort { display: flex; flex-direction: column; align-items: center; gap: 8px; margin: 2px 0 14px; }
.ev-de { display: grid; place-items: center; width: 58px; height: 58px; }
.ev-de .mg-ic { width: 52px; height: 52px; }
.ev-sort-verdict {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 4px 12px; border-radius: 999px; border: 1px solid;
    font-size: 0.72rem; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
}
.ev-sort.gagne .ev-sort-verdict { color: #2f6b36; border-color: rgba(63,125,69,0.55); background: rgba(63,125,69,0.12); }
.ev-sort.perdu .ev-sort-verdict { color: #8f3420; border-color: rgba(168,64,42,0.55); background: rgba(168,64,42,0.1); }

/* ---- La mise en scene : seulement transform et opacity, une fois par
   evenement, jamais en boucle. Le JavaScript ne pose les classes qui
   l'animent que hors mode economie et hors mouvement reduit ; les regles
   tout en bas de ce bloc sont le filet. */

/* Le parchemin se deroule depuis le haut. `scale` et non `transform` :
   `transform` porte deja le centrage de la fenetre. */
.ev-modal.ev-entree { transform-origin: 50% 0; animation: evDeroule 420ms cubic-bezier(.2,.9,.3,1.12) both; }
@keyframes evDeroule {
    from { scale: 1 0.06; opacity: 0.3; }
    to   { scale: 1 1;    opacity: 1; }
}

/* Le contenu se pose une fois le cachet brise. */
.ev-modal .mil-head-top { --i: 0; }
.ev-modal .ev-meta { --i: 1; }
.ev-modal .ev-desc { --i: 2; }
.ev-modal .ev-bar { --i: 6; }
.ev-modal.ev-entree :is(.mil-head-top, .ev-meta, .ev-desc, .ev-opt, .ev-bar) {
    /* `backwards` et non `both` : une fois posee, une option grisee doit
       retrouver sa propre opacite, pas garder celle de l'animation. */
    animation: evApparait 380ms ease-out backwards;
    animation-delay: calc(600ms + var(--i, 0) * 70ms);
}
@keyframes evApparait {
    from { opacity: 0; transform: translateY(8px); }
    to   { opacity: 1; transform: none; }
}

/* Le cachet, qui se brise en deux le long d'une fente. */
.ev-cachet {
    display: none; position: absolute; left: 50%; top: 40%; z-index: 5;
    width: 92px; height: 92px; margin: -46px 0 0 -46px; pointer-events: none;
}
.ev-modal.ev-entree .ev-cachet { display: block; animation: evCachet 1100ms ease-out both; }
.ev-cachet-m {
    position: absolute; inset: 0; border-radius: 50%; display: grid; place-items: center;
    background: radial-gradient(circle at 34% 30%, var(--cire-clair), var(--cire) 55%, var(--cire-sombre));
    box-shadow: inset 0 0 0 5px rgba(0,0,0,0.2), inset 0 0 0 9px rgba(255,255,255,0.07), 0 6px 16px rgba(0,0,0,0.6);
}
.ev-cachet-m .mg-ic { width: 46px; height: 46px; }
.ev-cachet-g { clip-path: polygon(0 0, 54% 0, 44% 38%, 57% 62%, 46% 100%, 0 100%); }
.ev-cachet-d { clip-path: polygon(54% 0, 100% 0, 100% 100%, 46% 100%, 57% 62%, 44% 38%); }
.ev-modal.ev-entree .ev-cachet-g { animation: evCachetG 1100ms ease-in both; }
.ev-modal.ev-entree .ev-cachet-d { animation: evCachetD 1100ms ease-in both; }
@keyframes evCachet {
    0%   { opacity: 0; transform: scale(1.6); }
    20%  { opacity: 1; transform: scale(0.92); }
    30%, 100% { opacity: 1; transform: scale(1); }
}
@keyframes evCachetG {
    0%, 50% { opacity: 1; transform: none; }
    100%    { opacity: 0; transform: translate(-74px, 56px) rotate(-30deg); }
}
@keyframes evCachetD {
    0%, 50% { opacity: 1; transform: none; }
    100%    { opacity: 0; transform: translate(74px, 62px) rotate(26deg); }
}
/* Les eclats d'or d'un legendaire, poses par le JavaScript avec leur angle. */
.ev-eclat {
    position: absolute; left: 50%; top: 50%; width: 7px; height: 7px; margin: -3.5px;
    border-radius: 50%; background: #ffe9a8; box-shadow: 0 0 8px #f6c95a; opacity: 0;
}
.ev-modal.ev-entree .ev-eclat { animation: evEclat 700ms 540ms ease-out both; }
@keyframes evEclat {
    0%   { opacity: 1; transform: rotate(var(--a)) translateX(10px) scale(1); }
    100% { opacity: 0; transform: rotate(var(--a)) translateX(var(--d)) scale(0.3); }
}

/* Un reflet traverse l'en-tete des que l'evenement sort de l'ordinaire. */
.ev-modal .mil-head { position: relative; overflow: hidden; }
.ev-modal .mil-head::after {
    content: ''; position: absolute; inset: 0; pointer-events: none; opacity: 0;
    background: linear-gradient(105deg, transparent 35%, var(--eclat) 50%, transparent 65%);
}
.ev-modal.ev-entree:is(.ev-r-rare, .ev-r-epic, .ev-r-legendary) .mil-head::after {
    animation: evReflet 900ms 750ms ease-in-out both;
}
@keyframes evReflet {
    from { opacity: 1; transform: translateX(-110%); }
    to   { opacity: 1; transform: translateX(110%); }
}
/* Et une lueur de cire monte sur tout le cadre pour l'epique et le legendaire ;
   le legendaire la garde, a peine. */
.ev-modal::after {
    content: ''; position: absolute; inset: 0; border-radius: inherit; pointer-events: none; opacity: 0;
    box-shadow: inset 0 0 46px var(--eclat), inset 0 0 0 1px var(--cire-clair);
}
.ev-modal.ev-r-legendary::after { opacity: 0.4; }
.ev-modal.ev-entree:is(.ev-r-epic, .ev-r-legendary)::after { animation: evLueur 1400ms 500ms ease-out both; }
@keyframes evLueur {
    0%   { opacity: 0; }
    35%  { opacity: 1; }
    100% { opacity: 0.4; }
}
.ev-modal.ev-entree.ev-r-epic::after { animation-name: evLueurEpique; }
@keyframes evLueurEpique {
    0%   { opacity: 0; }
    35%  { opacity: 1; }
    100% { opacity: 0; }
}

/* Le bilan : le de, le tampon, puis les cartes. */
.ev-outcome.ev-anime .ev-outcome-head { animation: evApparait 300ms ease-out both; }
.ev-outcome.ev-anime .ev-cartes li {
    animation: evCarte 360ms ease-out both;
    animation-delay: calc(var(--retard, 150ms) + var(--i, 0) * 130ms);
}
.ev-outcome.ev-anime.ev-roule { --retard: 1350ms; }
.ev-outcome.ev-anime.ev-roule .ev-de { animation: evDe 1000ms cubic-bezier(.3,.6,.4,1) both; }
.ev-outcome.ev-anime.ev-roule .ev-sort-verdict { animation: evTampon 420ms 1000ms cubic-bezier(.2,1.4,.4,1) both; }
@keyframes evCarte {
    from { opacity: 0; transform: translateX(-14px); }
    to   { opacity: 1; transform: none; }
}
@keyframes evDe {
    0%   { transform: translateY(-30px) rotate(0deg); }
    30%  { transform: translateY(0) rotate(300deg); }
    45%  { transform: translateY(-14px) rotate(430deg); }
    60%  { transform: translateY(0) rotate(540deg); }
    72%  { transform: translateY(-5px) rotate(620deg); }
    84%, 100% { transform: translateY(0) rotate(720deg); }
}
@keyframes evTampon {
    from { opacity: 0; transform: scale(1.8) rotate(-8deg); }
    to   { opacity: 1; transform: none; }
}

/* Les ressources gagnees volent jusqu'au bandeau (ou en tombent). */
.ev-vol {
    position: fixed; left: 0; top: 0; width: 24px; height: 24px; margin: -12px 0 0 -12px;
    z-index: 10200; pointer-events: none; opacity: 0;
    filter: drop-shadow(0 2px 3px rgba(0,0,0,0.7));
}
.ev-vol-n {
    position: fixed; z-index: 10200; pointer-events: none; white-space: nowrap;
    font-family: var(--font-ui); font-size: 0.82rem; font-weight: 800;
    color: #9fe0a5; text-shadow: 0 1px 3px #000, 0 0 2px #000; opacity: 0;
}
.ev-vol-n.perte { color: #f0907a; }

/* Le filet : rien ne bouge en mode economie ni avec le mouvement reduit. */
@media (prefers-reduced-motion: reduce) {
    .ev-modal.ev-entree, .ev-modal.ev-entree *, .ev-modal.ev-entree::after,
    .ev-modal.ev-entree .mil-head::after, .ev-outcome.ev-anime * { animation: none !important; }
    .ev-modal.ev-entree .ev-cachet { display: none; }
}
body.eco-energie .ev-modal.ev-entree, body.eco-energie .ev-modal.ev-entree *,
body.eco-energie .ev-modal.ev-entree::after, body.eco-energie .ev-modal.ev-entree .mil-head::after,
body.eco-energie .ev-outcome.ev-anime * { animation: none !important; }
body.eco-energie .ev-modal.ev-entree .ev-cachet { display: none; }

/* La pastille : un evenement laisse de cote reste joignable, il ne disparait pas. */
.ev-badge {
    position: fixed; right: 14px; bottom: 96px; z-index: 90;
    display: none; align-items: center; gap: 6px;
    padding: 9px 13px; border-radius: 999px; cursor: pointer;
    background: linear-gradient(180deg, #d9ad51, #b5893a); border: 1px solid #eac57a;
    color: #1c1408; font-family: var(--font-ui); font-size: 0.78rem; font-weight: 700;
    box-shadow: 0 6px 18px rgba(0,0,0,0.55);
}
.ev-badge-ic { font-size: 0.85rem; }

@media (max-width: 768px) {
    .ev-badge { bottom: 132px; right: 10px; }
    .ev-opt-top { flex-wrap: wrap; }
}

/* --- La chronique --- */
.chr-body { font-family: var(--font-ui); padding-bottom: 16px; }
.chr-vide { text-align: center; color: var(--muted); font-size: 0.8rem; padding: 30px 12px; line-height: 1.7; }
.chr-entry {
    background: var(--surface); border: 1px solid var(--line-soft);
    border-left: 2px solid var(--line-soft);
    border-radius: var(--radius-sm); padding: 10px 12px; margin-bottom: 8px;
}
.chr-entry.rare { border-left-color: #7fa9d8; }
.chr-entry.epic { border-left-color: #b98ad8; }
.chr-entry.legendary { border-left-color: var(--accent); }
.chr-head { display: flex; align-items: baseline; gap: 8px; }
.chr-ic { flex-shrink: 0; }
.chr-title { flex: 1; min-width: 0; font-size: 0.8rem; font-weight: 700; color: var(--text-light); }
.chr-when { flex-shrink: 0; font-size: 0.62rem; color: var(--muted); font-variant-numeric: tabular-nums; }
.chr-choice { margin-top: 5px; font-size: 0.72rem; color: var(--gold-bright); }
.chr-choice.auto { color: var(--muted); font-style: italic; }
.chr-lines { margin: 6px 0 0; padding-left: 17px; }
.chr-lines li { font-size: 0.72rem; line-height: 1.6; color: var(--muted); }
.ev-queue.portee { color: var(--gold-bright); font-weight: 700; }

/* --- Iconographie --- */
.mg-ic { width: 1em; height: 1em; vertical-align: -0.15em; flex-shrink: 0; }
.mg-ic.big { width: 1.35em; height: 1.35em; vertical-align: -0.25em; }

/* Le camp de passage : une tente et le temps qu'il lui reste, pour qu'on ne le
   confonde pas avec un camp barbare installe pour la saison. */
.map-camp {
    display: flex; align-items: center; gap: 4px;
    padding: 2px 7px 2px 5px; border-radius: 999px;
    background: rgba(24,18,12,0.92); border: 1px solid var(--accent);
    font-family: var(--font-ui); font-size: 0.6rem; font-weight: 700;
    color: var(--gold-bright); white-space: nowrap; pointer-events: none;
    box-shadow: 0 3px 10px rgba(0,0,0,0.6);
}
.map-camp .mg-ic { width: 0.95rem; height: 0.95rem; }
.map-camp-t { font-variant-numeric: tabular-nums; }

/* Des ruines : la garnison est tombee, les coffres sont encore la. Le village
   s'eteint -- plus de halo, plus de couleur -- et porte le coffre de ce qui
   reste, pour qu'on voie de loin qu'il y a encore a prendre. */
.map-ruine {
    display: flex; align-items: center; gap: 4px;
    padding: 2px 7px 2px 5px; border-radius: 999px;
    background: rgba(24,18,12,0.92); border: 1px solid rgba(214,158,74,0.7);
    font-family: var(--font-ui); font-size: 0.6rem; font-weight: 700;
    color: #e8c58a; white-space: nowrap; pointer-events: none;
    box-shadow: 0 3px 10px rgba(0,0,0,0.6);
}
.map-ruine .mg-ic { width: 0.95rem; height: 0.95rem; }
.map-village.ruine .map-village-img {
    filter: grayscale(100%) brightness(0.45) contrast(1.15) !important;
    opacity: 0.85;
}
.map-village.ruine .map-village-name {
    color: #9a8f7d;
    border-color: rgba(120,110,95,0.7);
    text-decoration: line-through;
    text-decoration-color: rgba(160,60,40,0.7);
}

/* Les icones dessinees ont besoin d'un peu plus de place que du texte pour
   rester lisibles a cote d'un libelle de 0,74 rem. */
/* En dessous de 18 px les details du dessin se perdent : on fixe une taille
   plancher plutot que de suivre la taille du texte, qui est petite dans ces
   listes. */
.pr-gain .mg-ic, .pr-req-top .mg-ic { width: 19px; height: 19px; margin-right: 5px; vertical-align: -5px; }
.ev-opt .mg-ic { width: 18px; height: 18px; }
.chr-ic .mg-ic { width: 1.25rem; height: 1.25rem; }
.ev-queue .mg-ic { width: 1.05em; height: 1.05em; vertical-align: -0.2em; }
.mil-head-top h2 .mg-ic { vertical-align: -0.22em; margin-right: 2px; }

/* --- Les icones dessinees la ou un emoji tenait la place ---------------------
   Un emoji suivait la taille du texte ; un SVG a besoin qu'on la lui donne,
   surtout dans les pastilles ou le texte descend sous 0,7 rem. */

.sys-status { display: inline-flex; align-items: center; gap: 6px; }
.sys-dot {
    width: 8px; height: 8px; border-radius: 50%; background: var(--success);
    box-shadow: 0 0 6px rgba(116,189,122,0.75); flex-shrink: 0;
}

.podium .medal .mg-ic { width: 1.3rem; height: 1.3rem; }
.podium .pod-rk { font-family: var(--font-title); font-size: 1.1rem; line-height: 1; }
.podium .pod-rk.argent { color: #c9cdd4; }
.podium .pod-rk.bronze { color: #c08552; }
.lb-body .row .rk .mg-ic { width: 1.05rem; height: 1.05rem; vertical-align: -0.18em; }
.lb-body .row .atk .mg-ic { width: 1.05rem; height: 1.05rem; }
.lb-ico .mg-ic { width: 1.05rem; height: 1.05rem; }

.top-bar-icon-btn .mg-ic { width: 1.2rem; height: 1.2rem; }
.crest-sub .mg-ic { width: 0.82rem; height: 0.82rem; vertical-align: -0.14em; }
.btn-prestige .mg-ic { width: 1em; height: 1em; vertical-align: -0.18em; }
.mtab .i .mg-ic { width: 1.2rem; height: 1.2rem; }
#taskbar-tab .mg-ic { width: 1em; height: 1em; vertical-align: -0.18em; }

.quests-ico .mg-ic, .season-crest .mg-ic, .verify-icon .mg-ic,
.wl-crest .mg-ic, .guild-locked-box .lock .mg-ic { width: 1em; height: 1em; }
.streak-chip .mg-ic { width: 0.95em; height: 0.95em; vertical-align: -0.16em; }
.wb-icon .mg-ic, .vb-icon .mg-ic { width: 1.15rem; height: 1.15rem; }
.danger-icon .mg-ic { width: 1.3rem; height: 1.3rem; }
.portrait-emoji .mg-ic { width: 1.7rem; height: 1.7rem; }
#protection-banner .shield-emoji .mg-ic { width: 22px; height: 22px; }
.wm-search-ico .mg-ic { width: 1rem; height: 1rem; }
.construction-hammer .mg-ic { width: 36px; height: 36px; }
.buff-ico .mg-ic { width: 1.05em; height: 1.05em; vertical-align: -0.2em; }

/* Titres, onglets et boutons : l'icone precede le mot et ne le domine pas. */
.mil-head-top h2 .mg-ic, .modal h2 .mg-ic, .modal h3 .mg-ic, .mil-sub .mg-ic,
.tab-btn .mg-ic, .btn-bar .mg-ic, .btn-upgrade .mg-ic,
.btn-recruit .mg-ic, .btn-leave .mg-ic, .wm-act .mg-ic, .wm-legend-btn .mg-ic,
.wm-note .mg-ic, .aca-detail-sub .mg-ic, .branch-head .mg-ic, .aca-seg .mg-ic {
    width: 1.05em; height: 1.05em; vertical-align: -0.2em; margin-right: 3px;
}
#wm-home .mg-ic { width: 1.1em; height: 1.1em; margin: 0; }

/* Listes et pastilles chiffrees : un plancher, sinon le dessin se perd. */
.wm-leg-ico .mg-ic { width: 15px; height: 15px; }
.mil-sub .mg-ic { width: 16px; height: 16px; vertical-align: -3px; }
.sys-tuile .mg-ic, .sys-ligne .mg-ic, .sys-mini .mg-ic { width: 17px; height: 17px; flex-shrink: 0; }
.node-mark .mg-ic { width: 15px; height: 15px; }
#aca-branch-tabs button .mg-ic { width: 15px; height: 15px; vertical-align: -3px; }
.branch-head .mg-ic { width: 16px; height: 16px; vertical-align: -3px; margin-right: 4px; }
.cost-item .mg-ic, .chip-pow .mg-ic, .q-name .mg-ic, .ac-name .mg-ic,
.queue-item .mg-ic, .mil-kpi .mg-ic, .v.num .mg-ic, .aca-acquired .mg-ic,
.k-row .mg-ic, .aca-mark .mg-ic, .prod-idle .mg-ic, .building-damaged-note .mg-ic {
    width: 16px; height: 16px; vertical-align: -3px;
}
#battle-reports-container .mg-ic { width: 18px; height: 18px; vertical-align: -4px; }
.quest-done-label .mg-ic { width: 15px; height: 15px; vertical-align: -3px; }

/* Le bandeau de liaison perdue : discret, en bas, il n'attrape aucun clic. */
#liaison-perdue {
    position: fixed; left: 50%; bottom: calc(62px + env(safe-area-inset-bottom));
    transform: translateX(-50%); z-index: 4000; pointer-events: none;
    display: flex; align-items: center; gap: 9px;
    max-width: calc(100vw - 28px); padding: 9px 15px;
    background: rgba(26,21,16,0.96); border: 1px solid #6b3328; border-radius: 999px;
    color: #e5d9c0; font-family: var(--font-ui); font-size: 0.72rem;
    box-shadow: 0 10px 28px rgba(0,0,0,0.6);
    animation: liaisonEntre 0.25s ease-out;
}
#liaison-perdue .mg-ic { width: 17px; height: 17px; flex-shrink: 0; }
@keyframes liaisonEntre { from { opacity: 0; transform: translate(-50%, 8px); } }
@media (max-width: 768px) { #liaison-perdue { bottom: calc(76px + env(safe-area-inset-bottom)); } }
.toast .ic .mg-ic { width: 16px; height: 16px; vertical-align: -3px; }

/* --- Le releve economique du panneau admin ---------------------------------- */
.eco-intro, .eco-assiette { font-size: 0.78rem; color: var(--muted); line-height: 1.5; margin: 0 0 12px; }
.eco-assiette b, .eco-sans { color: var(--text-light); }
.eco-h {
    margin: 18px 0 7px; font-family: var(--font-title); font-size: 0.86rem;
    color: var(--accent); border-bottom: 1px solid var(--line-soft); padding-bottom: 5px;
}
.eco-t {
    width: 100%; border-collapse: collapse; font-family: var(--font-ui);
    font-size: 0.74rem; font-variant-numeric: tabular-nums;
}
.eco-t th {
    text-align: right; padding: 4px 8px; color: var(--muted);
    font-size: 0.64rem; text-transform: uppercase; letter-spacing: 0.06em; font-weight: 600;
}
.eco-t td { text-align: right; padding: 5px 8px; border-top: 1px solid var(--line-soft); }
.eco-t .eco-k { text-align: left; color: var(--text-light); font-weight: 600; }
.eco-t .eco-med { color: var(--gold-bright); font-weight: 700; }
.eco-t .eco-gain { color: var(--success); }
/* Au-dela d'une journee de production pour un seul niveau, la courbe decroche. */
.eco-t .eco-mur { color: var(--danger); font-weight: 700; }
.eco-murs th:first-child, .eco-murs td:first-child { min-width: 130px; }
.eco-sans { font-size: 0.74rem; margin: 0 0 6px; }
.eco-rech { margin: 0; padding-left: 18px; font-size: 0.74rem; color: var(--muted); line-height: 1.7; }
.eco-rech b { color: var(--accent); }
.eco-vide { font-size: 0.78rem; color: var(--muted); font-style: italic; }
/* Une recherche sans fin affiche son rang plutot qu'une coche. */
.aca-rang {
    font-family: var(--font-ui); font-size: 0.62rem; font-weight: 700;
    color: var(--accent); background: var(--surface-3); border: 1px solid var(--line-soft);
    border-radius: 999px; padding: 1px 7px; vertical-align: 2px;
}
.node-rang { color: var(--gold-bright); font-family: var(--font-title); font-size: 0.8rem; }


/* --- Comment conquerir : la seule explication des regles a l'interieur du
   jeu. Elle s'ouvre par-dessus la Chapelle et la laisse ouverte derriere. --- */
.conq-modal { z-index: 1200; }
.help-dot-btn {
    border: 1px solid var(--panel-border, rgba(255,255,255,0.18));
    background: transparent; cursor: pointer; font-family: var(--font-ui);
}
.help-dot-btn:hover { border-color: var(--accent, #d4a548); color: var(--gold-bright, #f0c674); }

/* `body` est en Lancelot -- une anglaise medievale, faite pour un titre de trois
   mots. Tout ce qui ne pose pas sa police en herite, et ces deux fenetres sont
   les seules du jeu ou l'on lit des paragraphes entiers : les regles s'y
   dechiffraient au lieu de se lire. Les titres gardent le Cinzel. */
.conq-body { display: flex; flex-direction: column; gap: 16px; font-family: var(--font-ui); }
.conq-intro { margin: 0; font-size: 0.92rem; color: rgba(242,233,214,0.75); }

.conq-bloc {
    border: 1px solid var(--line-soft, rgba(212,165,72,0.22));
    border-radius: 8px; padding: 12px 14px;
    background: rgba(0,0,0,0.22);
}
.conq-bloc h4 {
    margin: 0 0 8px; font-family: var(--font-title, Cinzel, serif);
    font-size: 0.95rem; color: var(--gold-bright, #f0c674);
}
.conq-bloc p { margin: 0 0 8px; font-size: 0.88rem; line-height: 1.55; }
.conq-bloc p:last-child { margin-bottom: 0; }
.conq-note { font-size: 0.82rem !important; color: rgba(242,233,214,0.62); }

/* La jauge : trois crans qui montrent une prise en deux assauts. */
.conq-jauge { display: flex; flex-direction: column; gap: 6px; margin: 10px 0; }
.cj { display: grid; grid-template-columns: 8.5rem 1fr 2.4rem; align-items: center; gap: 8px; }
.cj-l { font-size: 0.78rem; color: rgba(242,233,214,0.7); }
.cj-b { height: 8px; border-radius: 3px; background: rgba(212,165,72,0.15); overflow: hidden; }
.cj-b i { display: block; height: 100%; background: var(--accent, #d4a548); }
.cj-v { font-size: 0.78rem; text-align: right; font-variant-numeric: tabular-nums; color: rgba(242,233,214,0.7); }
.cj.bas .cj-b i { background: #c0563c; }
.cj.bas .cj-v { color: #e08066; }

.conq-etapes { margin: 0; padding-left: 1.2rem; display: flex; flex-direction: column; gap: 6px; }
.conq-etapes li { font-size: 0.88rem; line-height: 1.5; }

.conq-garde {
    border-left: 2px solid var(--accent, #d4a548);
    padding: 2px 0 2px 10px; margin-bottom: 8px;
    font-size: 0.86rem; line-height: 1.5; color: rgba(242,233,214,0.85);
}
.conq-liste { margin: 0; padding-left: 1.2rem; display: flex; flex-direction: column; gap: 5px; }
.conq-liste li { font-size: 0.88rem; line-height: 1.5; }

@media (max-width: 560px) {
    .cj { grid-template-columns: 7rem 1fr 2.2rem; }
    .cj-l { font-size: 0.74rem; }
}

/* Le reglage des annonces, dans l'onglet Email du compte. Il est separe de la
   modification d'adresse : ce sont deux gestes differents. */

/* ==========================================================================
   PANNEAU D'ADMINISTRATION — Joueurs, Tickets, editeur de ressources.
   Configuration et Zone dangereuse gardent leur mise en forme d'origine.
   ========================================================================== */

/* Tout le panneau passe a la police d'interface. Le corps du jeu est en
   Lancelot -- une romane d'affichage, avec des chiffres en style ancien : a
   cette taille et avec cette densite de nombres, elle etait illisible. Le
   titre garde la police de titrage, lui. */
#modal-admin { font-family: var(--font-ui); }
#modal-admin h2 { font-family: var(--font-title); }
/* Chiffres alignes sur la ligne de base et de largeur fixe : une colonne de
   ressources se compare d'un joueur a l'autre. */
#modal-admin .adm-j-res,
#modal-admin .adm-j-id,
#modal-admin .adm-compte,
#modal-admin .adm-t-pied,
#modal-admin .mail-desab-row,
#modal-admin .admres-avant,
#modal-admin .admres-ecart,
#modal-admin input {
    font-variant-numeric: lining-nums tabular-nums;
    font-feature-settings: "lnum" 1, "tnum" 1;
}

/* Des puces qui passent a la ligne, jamais une barre qui defile : sur un
   telephone, la barre soulignee cachait quatre onglets sur sept derriere son
   bord droit, sans ascenseur ni degrade pour le dire. Un onglet cache n'existe
   pas. Les libelles raccourcissent sous 600 px pour tenir en deux rangs. */
.adm-tabs {
    display: flex; flex-wrap: wrap; gap: 5px;
    padding: 0 16px 10px; margin: 0;
    border-bottom: 1px solid var(--panel-border);
    flex-shrink: 0;
}
.adm-tab {
    background: var(--surface); border: 1px solid var(--line-soft); color: var(--muted);
    border-radius: var(--radius-sm);
    font-family: inherit; font-size: 0.75rem; padding: 6px 10px; cursor: pointer;
    white-space: nowrap; display: inline-flex; align-items: center; gap: 6px;
}
.adm-tab .mg-ic { width: 14px; height: 14px; }
.adm-tab:hover { color: var(--text-light); border-color: var(--panel-border); }
.adm-tab.on { color: var(--gold-bright); background: var(--surface-3); border-color: var(--accent); }
.adm-tab.peril.on { color: var(--danger); border-color: var(--danger); }
.adm-court { display: none; }
@media (max-width: 600px) {
    .adm-tabs { padding: 0 12px 8px; gap: 4px; }
    .adm-tab { font-size: 0.7rem; padding: 6px 8px; }
    .adm-long { display: none; }
    .adm-court { display: inline; }
}
.adm-pastille {
    background: var(--danger); color: #1c1408; font-size: 0.62rem; font-weight: 700;
    border-radius: 9px; padding: 1px 6px; line-height: 1.5;
}

/* Barre d'outils commune aux deux listes. */
.adm-barre { display: flex; gap: 9px; align-items: center; margin-bottom: 13px; flex-wrap: wrap; }
.adm-champ { flex: 1; min-width: 160px; }
.adm-champ input {
    width: 100%; box-sizing: border-box; background: var(--surface);
    border: 1px solid var(--panel-border); color: var(--text-light);
    border-radius: var(--radius-sm); padding: 9px 11px;
    font-family: inherit; font-size: 0.82rem;
}
.adm-champ input:focus { outline: 0; border-color: var(--accent); }
.adm-champ input::placeholder { color: #6b6152; }
.adm-puce { display: flex; gap: 4px; flex-wrap: wrap; }
.adm-puce button {
    background: var(--surface); border: 1px solid var(--panel-border);
    color: var(--muted); border-radius: var(--radius-sm); padding: 8px 11px;
    font-family: inherit; font-size: 0.74rem; cursor: pointer; white-space: nowrap;
}
.adm-puce button.on { background: var(--surface-3); color: var(--gold-bright); border-color: var(--accent); }
.adm-compte { font-size: 0.73rem; color: var(--muted); margin-left: auto; }
.adm-liste { display: flex; flex-direction: column; gap: 7px; }
.adm-vide { font-size: 0.8rem; color: var(--muted); text-align: center; padding: 22px 0; }

/* Boutons du panneau : sobres, l'or reserve a l'action principale. */
.b-adm {
    border: 1px solid var(--panel-border); background: var(--surface-2);
    color: var(--text-light); border-radius: var(--radius-sm); padding: 7px 12px;
    font-family: inherit; font-size: 0.75rem; cursor: pointer; white-space: nowrap;
}
.b-adm:hover { border-color: var(--accent); color: var(--gold-bright); }
.b-adm.or {
    background: linear-gradient(to bottom, #d9ad51, #b98c33);
    color: #1c1408; border-color: #8f6a22; font-weight: 700;
}
.b-adm.or:hover { color: #1c1408; }
.b-adm.peril:hover { border-color: var(--danger); color: var(--danger); }
.b-adm.mini { padding: 5px 9px; font-size: 0.7rem; }
.b-adm:disabled { opacity: 0.45; cursor: default; }
.b-adm:disabled:hover { border-color: var(--panel-border); color: var(--text-light); }

/* --- Joueurs : une fiche chacun ------------------------------------------ */
.adm-j {
    display: grid; grid-template-columns: auto 1fr auto; gap: 13px; align-items: center;
    background: var(--surface); border: 1px solid var(--line-soft);
    border-radius: var(--radius-sm); padding: 10px 12px;
}
.adm-j:hover { border-color: var(--panel-border); }
.adm-j-blason {
    width: 38px; height: 38px; border-radius: 50%; background: var(--surface-3);
    border: 1px solid var(--panel-border); display: flex; align-items: center;
    justify-content: center; font-family: var(--font-title); font-size: 0.88rem;
    color: var(--accent); flex: 0 0 auto;
}
.adm-j.chef .adm-j-blason { border-color: var(--accent); color: var(--gold-bright); }
.adm-j-corps { min-width: 0; }
.adm-j-nom { display: flex; align-items: center; gap: 7px; font-size: 0.88rem; font-weight: 600; flex-wrap: wrap; }
.adm-j-id { font-size: 0.68rem; color: var(--muted); font-weight: 400; }
.adm-etiq {
    font-size: 0.6rem; text-transform: uppercase; letter-spacing: 0.06em;
    padding: 2px 6px; border-radius: 4px; border: 1px solid;
}
.adm-etiq.chef { color: var(--gold-bright); border-color: var(--accent); background: rgba(212,165,72,.1); }
.adm-etiq.bot { color: var(--muted); border-color: var(--panel-border); }
/* Les cinq ressources en colonnes de largeur fixe : l'oeil compare d'un joueur
   a l'autre sans avoir a relire les icones. */
.adm-j-res { display: flex; gap: 13px; margin-top: 4px; font-size: 0.74rem; color: var(--muted); }
.adm-j-res span { display: flex; align-items: center; gap: 4px; min-width: 62px; }
.adm-j-vide { font-size: 0.74rem; color: var(--muted); font-style: italic; margin-top: 4px; }
.adm-j-actes { display: flex; gap: 5px; flex: 0 0 auto; }

/* La presence : en ligne (le registre du flux), sinon la derniere fois que
   le joueur avait le jeu ouvert. On ne montre que le vert ; l'absence se dit
   en toutes lettres, avec sa date. */
.adm-j-vu { display: flex; align-items: center; gap: 6px; margin-top: 3px; font-size: 0.72rem; color: var(--muted); }
.adm-j-vu.on { color: var(--success); }
.adm-j-vu.loin { color: #8a6f5a; }
.adm-j-vu .adm-point { display: inline-block; }

/* L'onglet Configuration reprend les pieces du reste du panneau. */
.adm-sec {
    background: var(--surface); border: 1px solid var(--line-soft);
    border-radius: var(--radius-sm); padding: 14px; margin-bottom: 12px;
    display: flex; flex-direction: column; align-items: flex-start; gap: 10px;
}
.adm-sec h3 { margin: 0; font-family: var(--font-title); font-size: 0.95rem; color: var(--gold-bright); }
.adm-note { margin: 0; font-size: 0.78rem; line-height: 1.5; color: var(--muted); }
.adm-grille { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 10px; width: 100%; }
.adm-lab { display: flex; flex-direction: column; gap: 5px; font-size: 0.74rem; color: var(--muted); }
.adm-lab input {
    background: var(--surface-2); border: 1px solid var(--panel-border); color: var(--text-light);
    border-radius: var(--radius-sm); padding: 8px 10px; font-family: inherit; font-size: 0.86rem;
}
.adm-lab input:focus { outline: 0; border-color: var(--accent); }

/* --- Tickets : le message d'abord ---------------------------------------- */
.adm-t {
    display: grid; grid-template-columns: 3px 1fr auto; gap: 0 13px; align-items: center;
    background: var(--surface); border: 1px solid var(--line-soft);
    border-radius: var(--radius-sm); overflow: hidden;
}
.adm-t-bande { align-self: stretch; }
.adm-t.critique .adm-t-bande { background: var(--danger); }
.adm-t.mineur .adm-t-bande { background: var(--highlight); }
.adm-t.idee .adm-t-bande { background: var(--success); }
.adm-t.clos { opacity: 0.45; }
.adm-t-corps { padding: 10px 0; min-width: 0; }
.adm-t-tete { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 3px; }
.adm-t-sujet { font-size: 0.86rem; font-weight: 600; }
.adm-t-genre {
    font-size: 0.6rem; text-transform: uppercase; letter-spacing: 0.06em;
    padding: 2px 6px; border-radius: 4px; border: 1px solid;
}
.adm-t.critique .adm-t-genre { color: var(--danger); border-color: var(--danger); background: rgba(207,106,85,.1); }
.adm-t.mineur .adm-t-genre { color: var(--highlight); border-color: #6b5320; background: rgba(255,170,0,.08); }
.adm-t.idee .adm-t-genre { color: var(--success); border-color: #3f5f42; background: rgba(116,189,122,.08); }
.adm-neuf {
    background: var(--danger); color: #1c1408; font-size: 0.58rem; font-weight: 700;
    text-transform: uppercase; letter-spacing: 0.05em; padding: 2px 6px; border-radius: 4px;
}
/* Deux lignes : assez pour juger l'urgence, pas assez pour noyer la liste. */
.adm-t-extrait {
    font-size: 0.77rem; color: var(--muted); line-height: 1.5;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.adm-t-pied { font-size: 0.69rem; color: var(--muted); margin-top: 5px; }
.adm-t-actes { display: flex; gap: 5px; padding-right: 12px; flex: 0 0 auto; }
.adm-t-resolu { font-size: 0.72rem; color: var(--success); padding-right: 12px; white-space: nowrap; }

/* --- L'editeur de ressources --------------------------------------------- */
#modal-adm-res { font-family: var(--font-ui); }
#modal-adm-res .admres-avant, #modal-adm-res .admres-ecart, #modal-adm-res input {
    font-variant-numeric: lining-nums tabular-nums;
    font-feature-settings: "lnum" 1, "tnum" 1;
}
.admres-tete { border-bottom: 1px solid var(--panel-border); padding-bottom: 11px; margin-bottom: 12px; }
.admres-tete h3 { margin: 0; font-family: var(--font-title); font-size: 0.98rem; color: var(--gold-bright); }
.admres-tete p { margin: 4px 0 0; font-size: 0.74rem; color: var(--muted); }
.admres-note { margin: 0 0 8px; font-size: 0.73rem; color: var(--muted); }
.admres-ligne {
    display: grid; grid-template-columns: 26px 1fr 96px 68px; gap: 10px;
    align-items: center; padding: 8px 0; border-bottom: 1px solid var(--line-soft);
}
.admres-ligne:last-child { border-bottom: 0; }
.admres-ico { text-align: center; line-height: 1; }
.admres-quoi { display: flex; flex-direction: column; min-width: 0; }
.admres-nom { font-size: 0.82rem; }
.admres-avant { font-size: 0.69rem; color: var(--muted); }
.admres-ligne input {
    width: 100%; box-sizing: border-box; background: var(--surface);
    border: 1px solid var(--panel-border); color: var(--text-light);
    border-radius: var(--radius-sm); padding: 7px 9px;
    font-family: inherit; font-size: 0.82rem; text-align: right;
}
.admres-ligne input:focus { outline: 0; border-color: var(--accent); }
/* L'ecart se lit avant de valider : c'est lui qui rattrape la faute de frappe. */
.admres-ecart { font-size: 0.72rem; text-align: right; white-space: nowrap; }
.admres-ecart.plus { color: var(--success); }
.admres-ecart.moins { color: var(--danger); }
.admres-ecart.rien { color: #8a7f6b; }
.admres-pied {
    display: flex; gap: 8px; justify-content: flex-end;
    margin-top: 14px; padding-top: 13px; border-top: 1px solid var(--panel-border);
}

/* Sur telephone, les actions passent sous la fiche plutot que de la comprimer. */
@media (max-width: 640px) {
    .adm-j { grid-template-columns: auto 1fr; }
    .adm-j-actes {
        grid-column: 1 / -1; justify-content: flex-end;
        border-top: 1px solid var(--line-soft); padding-top: 9px;
    }
    .adm-j-res { flex-wrap: wrap; gap: 7px 12px; }
    .adm-t { grid-template-columns: 3px 1fr; }
    .adm-t-actes, .adm-t-resolu { grid-column: 2; padding: 0 12px 10px; justify-content: flex-end; }
    .adm-compte { margin-left: 0; width: 100%; }
    .admres-ligne { grid-template-columns: 24px 1fr 84px 60px; gap: 7px; }
}

/* ==========================================================================
   MESSAGERIE — la liste des tickets et le formulaire d'ecriture.
   Le formulaire vivait dans une fenetre a part, tout en styles en ligne.
   ========================================================================== */

.tk-intro { margin: 0 0 14px; font-size: 0.82rem; color: var(--muted); line-height: 1.55; text-align: left; }
.tk-champ { margin-bottom: 13px; text-align: left; }
.tk-champ label {
    display: block; margin-bottom: 5px; font-size: 0.76rem;
    color: var(--gold-bright); letter-spacing: 0.02em;
}
.tk-opt { color: var(--muted); font-weight: 400; }
/* « input[type="text"] » est plus specifique qu'une simple classe : sans le
   nom de la balise, le champ retombait sur le fond clair global. */
input.tk-saisie, select.tk-saisie, textarea.tk-saisie, .tk-saisie {
    width: 100%; box-sizing: border-box; background: var(--surface);
    border: 1px solid var(--panel-border); color: var(--text-light);
    border-radius: var(--radius-sm); padding: 9px 11px;
    font-family: var(--font-ui); font-size: 0.84rem;
}
input.tk-saisie:focus, select.tk-saisie:focus, textarea.tk-saisie:focus { outline: 0; border-color: var(--accent); }
.tk-saisie::placeholder { color: #6b6152; }
.tk-zone { resize: vertical; min-height: 110px; line-height: 1.55; }
.tk-image { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.tk-image label { margin: 0; cursor: pointer; color: var(--text-light); }
.tk-image-nom { font-size: 0.75rem; color: var(--muted); }
.tk-envoi { width: 100%; padding: 11px; font-size: 0.85rem; margin-top: 4px; }
.tk-erreur { margin: 10px 0 0; font-size: 0.8rem; color: var(--danger); text-align: center; }

/* La liste. Une bande de couleur dit le genre sans qu'on ait a lire. */
.tk-carte {
    display: grid; grid-template-columns: 3px 1fr; gap: 0 12px; align-items: center;
    background: var(--surface); border: 1px solid var(--line-soft);
    border-radius: var(--radius-sm); overflow: hidden; margin-bottom: 7px;
    cursor: pointer; text-align: left;
}
.tk-carte:hover { border-color: var(--panel-border); }
.tk-bande { align-self: stretch; }
.tk-carte.critique .tk-bande { background: var(--danger); }
.tk-carte.mineur .tk-bande { background: var(--highlight); }
.tk-carte.idee .tk-bande { background: var(--success); }
.tk-carte.autre .tk-bande { background: var(--muted); }
.tk-carte.clos { opacity: 0.5; }
.tk-corps { padding: 10px 12px 10px 0; min-width: 0; }
.tk-tete { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.tk-sujet { font-size: 0.87rem; font-weight: 600; }
.tk-neuf {
    background: var(--danger); color: #1c1408; font-size: 0.58rem; font-weight: 700;
    text-transform: uppercase; letter-spacing: 0.05em; padding: 2px 6px; border-radius: 4px;
}
.tk-meta { display: flex; align-items: center; gap: 10px; margin-top: 4px; font-size: 0.72rem; flex-wrap: wrap; }
.tk-genre { color: var(--muted); }
.tk-etat.ouvert { color: var(--highlight); }
.tk-etat.clos { color: var(--success); }
.tk-date { color: var(--muted); margin-left: auto; }
.tk-nouveau { width: 100%; margin-bottom: 10px; padding: 10px; }

/* L'en-tete du formulaire : il dit ou l'on est, et comment revenir. */
.tk-form-tete {
    display: flex; align-items: center; gap: 10px; margin-bottom: 14px;
    padding-bottom: 10px; border-bottom: 1px solid var(--panel-border);
}
.tk-form-tete span {
    flex: 1; text-align: left; font-family: var(--font-title);
    font-size: 0.9rem; color: var(--gold-bright);
}

/* Une liste vide propose l'action plutot que de constater le vide. */
.tk-vide { text-align: center; padding: 26px 16px; }
.tk-vide p { margin: 0 0 6px; font-size: 0.86rem; }
.tk-vide-sous { color: var(--muted); font-size: 0.78rem !important; margin-bottom: 16px !important; }

/* --- Le jeu en veille -------------------------------------------------------
   Ecran eteint, application quittee, onglet en fond : dix braises, deux nappes
   de brume, la pluie et les villageois continuaient de se composer a soixante
   images par seconde devant personne. Sur un telephone, c'est de la chaleur et
   de la batterie pour rien.

   On suspend plutot que de masquer : une animation reprend la ou elle s'est
   arretee, sans saut visible au retour. */
body.jeu-en-veille *,
body.jeu-en-veille *::before,
body.jeu-en-veille *::after {
    animation-play-state: paused !important;
}

/* --- L'economie d'energie ---------------------------------------------------
   Le decor tient dans une vingtaine d'animations sans fin : braises, brume,
   pluie, derive du ciel, villageois et chevalier. Une vingtaine de mouvements a
   soixante images par seconde, que le joueur regarde ou non.

   Ce qui s'arrete ici ne dit rien du jeu, il fait joli. Les barres de
   progression, les compteurs et les retours d'action continuent : eux portent
   une information.

   Ce qui n'a de sens qu'en mouvement disparait — une braise figee en l'air ou
   une pluie arretee en traits obliques est plus etrange qu'absente. Le reste
   se fige simplement. */
body.eco-energie .auth-embers,
body.eco-energie #village-map.vm-rain #vm-weather,
body.eco-energie #village-map.vm-snow #vm-weather {
    display: none !important;
}

body.eco-energie .auth-sky,
body.eco-energie .fog-far,
body.eco-energie .fog-near,
body.eco-energie .vm-walker i::before,
body.eco-energie .map-soldier.animated,
body.eco-energie .map-soldier.caravane.animated::before {
    animation: none !important;
}


/* ===================== RÉACTIONS DU TCHAT =====================
   La barre reste discrète tant que personne n'a rien posé : un bouton « + »
   presque effacé, qui se révèle au survol du message. Une conversation ne doit
   pas se transformer en rangée de boutons. */
.rc-barre {
    display: flex; flex-wrap: wrap; align-items: center; gap: 4px;
    margin-top: 4px; position: relative;
}
/* La barre n'existe QUE s'il y a quelque chose dedans. Elle portait auparavant
   un « + » en absolu dans une boîte de hauteur nulle — une économie de place
   qui coûtait deux pannes : dans le salon de guilde le bouton tombait sur
   l'horodatage, et il fallait survoler pour le voir, ce qui n'existe pas au
   doigt. Le bouton a rejoint les actions du message, avec « répondre » et
   « supprimer », où il se voit sans rien recouvrir. */

.rc-chip, .rc-opt {
    font: inherit; line-height: 1;
    background: var(--surface-2); color: var(--text-light);
    border: 1px solid var(--line-soft); border-radius: 999px;
    padding: 2px 7px; cursor: pointer;
}
.rc-chip { display: inline-flex; align-items: center; gap: 4px; font-size: .95em; }
.rc-chip:hover, .rc-opt:hover { border-color: var(--accent); }

/* Celle qu'on a posée soi-même se distingue : sans cela on ne sait plus si le
   prochain clic ajoute ou retire. */
.rc-chip.mienne { border-color: var(--accent); background: rgba(212, 165, 72, 0.16); }
.rc-n { font-size: .8em; color: var(--muted); font-variant-numeric: tabular-nums; }
.rc-chip.mienne .rc-n { color: var(--accent); }


/* Hors connexion : ce qui a été posé reste lisible, mais rien ne ressemble à
   un bouton — on ne fait pas miroiter une action impossible. */
.rc-chip.fige { cursor: default; opacity: .75; }

/* Le choix se pose au-dessus du fil, pas dedans : l'insérer dans le flux
   décalerait tous les messages en dessous à chaque ouverture. */
.rc-choix {
    /* Fixe, et non absolu : le fil des messages défile, donc il rogne ce qui
       dépasse de lui. En absolu, le sélecteur du dernier message se faisait
       couper en deux. Sa place est calculée par placerLeChoix(). */
    position: fixed; top: 0; left: 0; z-index: 10050;
    display: flex; gap: 2px; padding: 4px;
    background: var(--panel-bg); border: 1px solid var(--panel-border);
    border-radius: var(--radius-sm); box-shadow: 0 6px 18px rgba(0,0,0,.5);
}
.rc-choix[hidden] { display: none; }

/* Qui a réagi : une bulle posée dans <body>, comme le sélecteur. */
.rc-qui {
    position: fixed; top: 0; left: 0; z-index: 10060;
    max-width: min(280px, calc(100vw - 16px));
    padding: 6px 10px; font-family: var(--font-ui, sans-serif); font-size: .8rem; line-height: 1.4;
    color: var(--text-light); background: var(--panel-bg); border: 1px solid var(--panel-border);
    border-radius: var(--radius-sm); box-shadow: 0 6px 18px rgba(0,0,0,.5);
    pointer-events: none;
}
.rc-qui[hidden] { display: none; }
.rc-qui b { color: var(--gold-bright, #f0c674); font-weight: 600; }
.rc-qui-e { font-size: 1.05em; }
.rc-chip { -webkit-touch-callout: none; user-select: none; }
.rc-opt { border-color: transparent; background: transparent; font-size: 1.15em; padding: 3px 5px; }

/* =============== RÉPONDRE, CITER, NOMMER ===============
   Les deux tchats partagent ces règles comme ils partagent le code : ce qui
   distingue la place publique du salon de guilde, c'est la mise en page de la
   ligne, pas la façon de répondre à quelqu'un. */

/* Les actions d'un message. Elles sont TOUJOURS là, y compris pour qui ne
   modère rien : c'est par là qu'on répond et qu'on réagit. Discrètes au repos,
   franches au survol — et jamais totalement invisibles, parce qu'une action
   qu'il faut deviner n'existe pas. */
.chat-mod { display: inline-flex; gap: 3px; margin-left: auto; align-items: center; }
.chat-mod button {
    background: transparent; border: 1px solid transparent; border-radius: 6px;
    color: var(--muted); cursor: pointer; line-height: 1;
    font-size: 0.8rem; padding: 2px 5px; opacity: .55;
    transition: opacity .15s ease, color .15s ease, border-color .15s ease;
}
.chat-msg:hover .chat-mod button,
.chat-msg:focus-within .chat-mod button { opacity: 1; }
.chat-mod button:hover { color: var(--accent); border-color: var(--accent); }
/* Le symbole du silence est le seul emoji en couleur au milieu de trois glyphes
   gris : il tirait l'oeil comme une alerte, alors que c'est l'action la plus
   rare des quatre. On le decolore pour qu'il tienne son rang. */
.chat-act-mute { filter: grayscale(1); }
.chat-mod button.chat-act-mute:hover { filter: none; }
/* Au doigt il n'y a pas de survol : les actions restent lisibles. */
@media (hover: none) { .chat-mod button { opacity: .8; } }

/* La citation posée au-dessus d'une réponse. Un filet à gauche, comme une
   citation de courrier — et elle se clique pour remonter au message d'origine. */
.chat-cite {
    display: flex; gap: 6px; align-items: baseline;
    margin: 0 0 3px; padding: 2px 8px;
    border-left: 3px solid var(--accent);
    background: rgba(255,255,255,0.035);
    border-radius: 0 6px 6px 0;
    font-family: var(--font-ui); font-size: 0.72rem; line-height: 1.4;
    cursor: pointer; max-width: 100%;
}
.chat-cite:hover { background: rgba(212,165,72,0.12); }
.chat-cite.manquant { border-left-color: var(--line-soft); color: var(--muted); cursor: default; }
.chat-cite.manquant:hover { background: rgba(255,255,255,0.035); }
.chat-cite-qui { font-weight: 700; color: var(--accent); white-space: nowrap; }
.chat-cite-txt {
    flex: 1; min-width: 0;
    color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* Le message qu'on vient de rejoindre depuis une citation. Il s'éteint seul :
   un surlignage qui reste finirait par désigner n'importe quoi. */
@keyframes chatVise {
    from { background: rgba(212,165,72,0.30); }
    to   { background: transparent; }
}
.chat-vise { animation: chatVise 1.8s ease-out 1; border-radius: 8px; }

/* Un nom cité dans un message. Le sien se distingue du nom d'un autre : dans un
   fil qui défile, une mention perdue au milieu d'un paragraphe se rate. */
.chat-mention { color: var(--accent); font-weight: 600; }
.chat-mention.moi {
    background: rgba(212,165,72,0.20); border-radius: 4px; padding: 0 3px;
    color: var(--gold-bright);
}
/* Et la ligne entière se signale, pour qu'on la voie sans lire. */
.chat-msg.me-nomme .chat-body { box-shadow: inset 3px 0 0 var(--accent); }

/* « Vous répondez à… », au-dessus du champ de saisie. */
.chat-reponse {
    display: flex; align-items: baseline; gap: 7px;
    margin: 0 0 6px; padding: 5px 8px;
    background: var(--surface-2); border: 1px solid var(--line-soft);
    border-left: 3px solid var(--accent); border-radius: 0 8px 8px 0;
    font-family: var(--font-ui); font-size: 0.74rem;
}
.chat-reponse[hidden] { display: none; }
.chat-rep-fleche { color: var(--accent); }
.chat-rep-qui { font-weight: 700; color: var(--accent); white-space: nowrap; }
.chat-rep-txt {
    flex: 1; color: var(--muted);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.chat-rep-x {
    background: transparent; border: 0; color: var(--muted);
    cursor: pointer; font-size: 0.9rem; line-height: 1; padding: 0 2px;
}
.chat-rep-x:hover { color: var(--danger); }

/* =========================================================================
   Les notifications : une seule fenetre
   -------------------------------------------------------------------------
   L'activation, l'essai et le choix des categories vivaient dans deux boutons
   du menu Systeme, qui en compte huit. Une seule affaire merite une seule
   entree.
   ========================================================================= */

.nt-body { font-family: var(--font-ui); display: flex; flex-direction: column; gap: 12px; }

.nt-ligne { display: flex; align-items: flex-start; gap: 10px; }
.nt-texte { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.nt-texte b { font-size: 0.86rem; }
.nt-texte small { font-size: 0.74rem; color: var(--muted); line-height: 1.4; }

/* La pastille dit l'etat avant qu'on ait lu la phrase. */
.nt-pastille {
    flex: 0 0 auto; width: 10px; height: 10px; margin-top: 5px; border-radius: 50%;
    background: var(--danger); box-shadow: 0 0 8px var(--danger);
}
.nt-pastille.on { background: var(--success); box-shadow: 0 0 8px var(--success); }

/* `.btn-res` porte `margin-top: auto` et fait 40 px la ou `.btn-max` en fait
   32 : les deux pieges deja rencontres sur les boutons du ralliement. */
.nt-boutons { display: flex; gap: 8px; margin-top: 12px; }
.nt-boutons .btn-res, .nt-boutons .btn-max { flex: 1; height: 40px; margin-top: 0; }
.nt-appareil { margin: 10px 0 0; }
/* Le journal des envois. Un SVG ne suit pas la taille du texte comme un emoji :
   a 0,75 rem de corps, sans plancher, l'icone tombait a onze pixels. */
.nt-journal { margin: 6px 0 0; display: flex; align-items: center; gap: 6px; }
.nt-journal .mg-ic { width: 15px; height: 15px; flex: 0 0 auto; opacity: .8; }
.nt-journal:empty { display: none; }

.nt-liste { display: flex; flex-direction: column; gap: 2px; margin-top: 8px; }

/* Une ligne par categorie. Toute la ligne est cliquable : viser un interrupteur
   de 38 px au pouce, sur une liste de huit, ne marche pas. */
.nt-cat {
    display: flex; align-items: center; gap: 12px;
    padding: 10px 2px; cursor: pointer;
    border-bottom: 1px solid var(--line-soft);
}
.nt-cat:last-child { border-bottom: 0; }
.nt-cat .nt-nom { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.nt-cat .nt-nom b { font-size: 0.8rem; font-weight: 600; }
.nt-cat .nt-nom small { font-size: 0.72rem; color: var(--muted); line-height: 1.4; }

/* Celles qu'on ne coupe pas. Elles restent visibles, et disent pourquoi : les
   retirer de la liste ferait croire qu'elles n'existent pas. */
.nt-cat.verrou { cursor: default; }
.nt-cat.verrou .nt-nom b { color: var(--gold-bright); }
.nt-cat .nt-toujours {
    flex: 0 0 auto; font-size: 0.66rem; font-weight: 700; letter-spacing: 0.06em;
    text-transform: uppercase; color: var(--muted);
    border: 1px solid var(--line-soft); border-radius: 999px; padding: 4px 9px;
}

/* L'interrupteur. Le jeu n'en avait aucun : il est dessine ici, dans sa palette. */
.nt-bascule {
    flex: 0 0 auto; position: relative; width: 38px; height: 22px; border-radius: 999px;
    background: var(--surface-2); border: 1px solid var(--line-soft);
    transition: background .18s ease, border-color .18s ease;
}
.nt-bascule::after {
    content: ''; position: absolute; top: 2px; left: 2px;
    width: 16px; height: 16px; border-radius: 50%;
    background: var(--muted); transition: transform .18s ease, background .18s ease;
}
.nt-cat.on .nt-bascule { background: rgba(116,189,122,0.22); border-color: #3d6640; }
.nt-cat.on .nt-bascule::after { transform: translateX(16px); background: var(--success); }
@media (hover: hover) and (pointer: fine) {
    .nt-cat:not(.verrou):hover .nt-bascule { border-color: var(--accent); }
}

@media (max-width: 768px) {
    .nt-boutons { flex-direction: column; }
    /* En colonne, `flex: 1` repartit la HAUTEUR et ecrase les boutons a quinze
       pixels : il faut une base fixe. */
    .nt-boutons .btn-res, .nt-boutons .btn-max { flex: 0 0 40px; width: 100%; }
}

/* =========================================================================
   Les ralliements de guilde
   ========================================================================= */

.rall-volets { margin-bottom: 10px; }

/* Le corps du ralliement NE porte PAS `guild-scroll` : cette classe plafonne a
   200 px, ce qui ecrasait tout le panneau dans une lucarne, sur mobile comme sur
   grand ecran. C'est `.mil-body` qui defile, sur 90vh -- le panneau se deroule
   donc sur toute la hauteur de la fenetre, comme les autres onglets. */
.rall-corps { font-family: var(--font-ui); text-align: left; }

/* Sur grand ecran la fenetre est large : sans bride, le champ de saisie part a
   l'autre bout de la ligne et la quantite se lit a trente centimetres du nom de
   l'unite. */
.rall-form, .rall-fonder, .rall-decision > .rall-boutons { max-width: 560px; }
/* La ligne de saisie se lit d'un seul coup d'oeil : le nom, le champ, le
   plafond. Etiree sur toute la largeur d'une fenetre de bureau, la quantite se
   lisait a trente centimetres du nom de l'unite. */
.rall-part { max-width: 340px; }

.rall-vide {
    background: var(--surface); border: 1px dashed var(--line-soft);
    border-radius: var(--radius); padding: 18px 14px; margin-bottom: 12px;
    text-align: center; font-size: 0.85rem; line-height: 1.5;
}
.rall-vide p { margin: 8px 0 0; opacity: .8; font-size: 0.8rem; }
.rall-vide .mg-ic { width: 1.2em; height: 1.2em; vertical-align: -0.2em; }

.rall-tete h3 { margin: 0 0 6px; font-size: 0.98rem; }
.rall-tete .mg-ic { width: 1em; height: 1em; vertical-align: -0.15em; }
.rall-mot { margin: 0 0 8px; font-style: italic; opacity: .9; font-size: 0.82rem; }
.rall-somme { margin: 0; font-size: 0.82rem; }

.rall-l { display: block; margin: 8px 0 3px; font-size: 0.75rem; opacity: .8; }
.rall-fonder .rall-action { margin-top: 10px; }

/* L'avertissement du camp visible de tous. `.wm-note` est dessinee pour la
   fiche etroite de la carte : 8 px de marge interieure y suffisent parce que le
   texte y tient sur une ligne. Ici il en fait trois, et le jaune se collait aux
   bords de son cadre. On lui donne de l'air, et on sort l'oeil du flux du texte
   pour que la seconde ligne ne vienne pas se ranger sous lui. */
.rall-avis {
    display: flex; align-items: flex-start; gap: 9px;
    padding: 11px 13px; margin: 12px 0 0; line-height: 1.5;
}
.rall-avis .mg-ic { flex: 0 0 auto; margin: 2px 0 0; }

/* Ce que la saisie designe vraiment, sous le champ. Une cible se tape a la main
   aussi bien qu'elle se choisit : sans ce retour, on ne savait qu'au refus du
   serveur qu'on avait vise a cote. */
.rall-apercu {
    min-height: 1.1em; margin: 5px 0 0;
    font-size: 0.74rem; line-height: 1.4; color: var(--muted);
}
.rall-apercu.ok { color: var(--text-light); }
.rall-apercu.ko { color: var(--danger); }
.rall-apercu b { color: var(--gold-bright); }
.rall-apercu.ko b { color: inherit; }

/* La part se lit AVANT de s'engager, et bouge pendant qu'on compose sa
   colonne : c'est la meilleure explication de la regle du partage. */
.rall-part {
    display: flex; flex-direction: column; gap: 4px;
    background: var(--surface-2); border-radius: var(--radius-sm);
    padding: 8px 10px; margin: 8px 0;
    font-size: 0.8rem;
}
.rall-part > div { display: flex; justify-content: space-between; align-items: baseline; }
.rall-part .k { opacity: .8; }
.rall-part .v { font-weight: 700; font-variant-numeric: tabular-nums; }
.rall-part .gold { color: var(--gold-bright); }

/* Les boutons du ralliement sont ceux du jeu -- `btn-res` pour l'action,
   `btn-max` pour le retrait -- et non des classes inventees, qui retombaient sur
   le bouton blanc du navigateur au milieu d'une interface sombre.
   
   Deux choses a neutraliser pour les mettre cote a cote ou l'un sous l'autre :
   `.btn-res` porte `margin-top: auto`, qui le pousse vers le bas des qu'il a de
   la place au-dessus, et les deux n'ont pas la meme hauteur d'origine -- 40 px
   contre 32. C'est ce qui les desalignait. */
.rall-action { width: 100%; height: 40px; margin-top: 8px; }

.rall-table { width: 100%; font-size: 0.78rem; }
.rall-table th { font-weight: 600; opacity: .7; padding-bottom: 4px; }
.rall-table td { padding: 4px 0; }
.rall-table .r { text-align: right; }
.rall-table .gold { color: var(--gold-bright); }
.rall-table tr.rall-moi td { background: rgba(255, 215, 0, 0.07); }
.rall-table tr.rall-muet td { opacity: .45; }

.rall-progres {
    height: 9px; border-radius: 5px; overflow: hidden;
    background: var(--surface-2); border: 1px solid var(--line-soft);
    margin-bottom: 7px;
}
.rall-progres > div { height: 100%; background: var(--accent); transition: width .4s ease; }
.rall-compteur { margin: 0 0 4px; font-size: 0.82rem; font-weight: 600; }

.rall-assaut { border-color: var(--danger); }
.rall-compte {
    font-size: 1.05rem; font-weight: 700; text-align: center;
    color: var(--danger); font-variant-numeric: tabular-nums;
}
.rall-compte .mg-ic { width: 1em; height: 1em; vertical-align: -0.15em; }

.rall-boutons { display: flex; gap: 8px; margin-top: 8px; align-items: center; }
.rall-boutons .btn-max, .rall-boutons .btn-res { flex: 1; height: 40px; margin-top: 0; }
.rall-boutons .btn-res .mg-ic { width: 1em; height: 1em; vertical-align: -0.15em; }
.rall-decision p { margin: 8px 0 0; font-size: 0.75rem; }

/* Les chroniques gardent les defaites : un camp brise est une chronique aussi,
   et c'est celle dont on apprend. */
.rall-chronique {
    padding: 8px 10px; margin-bottom: 6px;
    border-radius: var(--radius-sm); background: var(--surface-2);
    border-left: 3px solid var(--line-soft);
    font-size: 0.79rem;
}
.rall-chronique.ok { border-left-color: var(--accent); }
.rall-chronique.ko { border-left-color: var(--danger); }
.rall-chronique .rc-t { font-weight: 600; display: flex; justify-content: space-between; gap: 8px; }
.rall-chronique .rc-s { opacity: .8; margin-top: 2px; }
.rall-chronique .rc-m { margin-top: 3px; }
.rall-chronique .gold { color: var(--gold-bright); }

/* Le bouton qui ouvre le rapport complet. Discret : la chronique se parcourt,
   le detail se demande. Il ne parait que sur les lignes ou l'on etait. */
/* Un avertissement qui coute quelque chose au joueur : il doit se voir sans
   crier. Ambre, comme le reste des mises en garde du jeu. */
.rall-avert {
    margin-top: 8px;
    padding: 6px 10px;
    font-family: var(--font-ui);
    font-size: .82rem;
    line-height: 1.35;
    color: #ffc27a;
    background: rgba(255, 170, 68, .08);
    border-left: 3px solid #ffaa44;
    border-radius: 2px;
}

.rall-chronique .rc-detail {
    margin-top: 6px;
    padding: 3px 10px;
    font-family: var(--font-ui);
    font-size: .78rem;
    color: var(--gold-bright);
    background: rgba(0, 0, 0, .25);
    border: 1px solid var(--gold);
    border-radius: 3px;
    cursor: pointer;
}
.rall-chronique .rc-detail:hover {
    background: rgba(197, 160, 89, .15);
    border-color: var(--gold-bright);
}

/* Le camp sur la carte : ni gris comme un barbare, ni vert comme un allie.
   Une menace en train de se former doit se voir. */
.map-village.ralliement .map-village-img { animation: rall-pulse 2.4s ease-in-out infinite; }
@keyframes rall-pulse {
    0%, 100% { filter: drop-shadow(0px 10px 14px #ff9500); }
    50%      { filter: drop-shadow(0px 10px 20px #ffc266); }
}
.map-ralliement {
    display: flex; align-items: center; gap: 3px;
    background: rgba(40, 20, 0, 0.85);
    border: 1px solid rgba(255, 149, 0, 0.8);
    border-radius: 4px; padding: 1px 4px;
    color: #ffb347; font-size: 10px; white-space: nowrap;
}
.map-ralliement .mg-ic { width: 11px; height: 11px; }

@media (max-width: 600px) {
    /* **Six onglets passent sur deux rangs, ils ne defilent plus.** La barre
       defilait sans ascenseur visible : avec l'onglet de la merveille, les deux
       derniers -- Merveille et Pantheon -- tombaient derriere le bord droit
       d'un telephone, sans rien pour le dire. *Un onglet cache n'existe pas*,
       la lecon du panneau d'administration. */
    .guild-tabs { flex-wrap: wrap; }
    .guild-tabs .tab-btn { flex: 1 1 30%; white-space: nowrap; }
    .rall-table { font-size: 0.72rem; }
    /* Deux boutons cote a cote sur 390 px : « Donner le signal » passait sur
       deux lignes dans une hauteur de 40 px. Ils s'empilent -- et `flex: 1`
       doit ceder, sinon il repartit la HAUTEUR au lieu de la largeur et les
       ecrase a quinze pixels. */
    .rall-boutons { flex-direction: column; }
    .rall-boutons .btn-max, .rall-boutons .btn-res { flex: 0 0 40px; width: 100%; }
}

/* =========================================================================
   L'aide des guildes
   ========================================================================= */

/* Elle s'ouvre par-dessus la fenetre de guilde, qui est deja a 10000. */
#modal-guildes-aide { z-index: 10001; }

.conq-bloc h4 .mg-ic { width: 1em; height: 1em; vertical-align: -0.15em; margin-right: 4px; }

/* Les captures de l'aide. Elles vivent dans le depot et non dans le message
   d'une lettre : ici on peut servir du JPEG ordinaire, sans se soucier
   d'Outlook. `loading="lazy"` compte : la fenetre s'ouvre par-dessus le jeu, et
   rien ne doit se telecharger avant qu'on la deroule jusqu'a l'image. */
.ga-fig { margin: 10px 0 0; }
.ga-fig img {
    display: block; width: 100%; max-width: 480px; height: auto;
    border-radius: var(--radius-sm); border: 1px solid var(--line-soft);
}
.ga-fig figcaption {
    margin-top: 5px; font-size: 0.72rem; color: var(--muted); line-height: 1.4;
}

.ga-liste { margin: 0; padding-left: 1.1rem; display: flex; flex-direction: column; gap: 9px; }
.ga-liste li { font-size: 0.87rem; line-height: 1.5; }
.ga-liste .ga-t {
    font-size: 0.72rem; color: var(--muted);
    border: 1px solid var(--line-soft); border-radius: 4px;
    padding: 1px 6px; margin-left: 6px; white-space: nowrap;
}

.ga-table { width: 100%; border-collapse: collapse; font-size: 0.85rem; }
.ga-table th {
    text-align: left; vertical-align: top; white-space: nowrap;
    color: var(--gold-bright); font-weight: 700;
    padding: 7px 12px 7px 0; border-bottom: 1px solid var(--line-soft);
}
.ga-table td { padding: 7px 0; line-height: 1.5; border-bottom: 1px solid var(--line-soft); }
.ga-table tr:last-child th, .ga-table tr:last-child td { border-bottom: 0; }

/* Le bloc du ralliement porte la couleur de l'accent : c'est la nouveaute, et
   c'est aussi le seul endroit de la fenetre ou l'on prend un risque. */
.conq-bloc.ga-neuf { border-color: var(--accent); }
.ga-badge {
    font-size: 0.62rem; text-transform: uppercase; letter-spacing: .08em;
    background: var(--accent); color: #1c1408;
    border-radius: 4px; padding: 2px 6px; margin-left: 7px; vertical-align: 2px;
}
.conq-note.ga-danger {
    color: rgba(242,233,214,0.78) !important;
    border-left: 3px solid var(--danger);
    padding: 7px 0 7px 10px; margin-bottom: 8px;
}

.conq-fin {
    margin: 4px 0 0; font-size: 0.86rem; font-style: italic;
    color: rgba(242,233,214,0.6); text-align: center;
}

@media (max-width: 600px) {
    .ga-table th { white-space: normal; padding-right: 8px; }
    .ga-liste .ga-t { display: inline-block; margin: 3px 0 0 0; }
}

/* Ce que le triangle a fait, dans le rapport de bataille. C'est la seule ligne
   qui explique une defaite au lieu de la constater : elle se detache donc du
   reste, sans crier. */
.rap-contre {
    margin-top: 8px; padding: 8px 10px;
    background: rgba(212,165,72,0.06); border-left: 3px solid var(--accent);
    border-radius: 0 6px 6px 0;
    font-family: var(--font-ui); font-size: 0.8em; line-height: 1.45;
}
.rap-contre .mg-ic { width: 14px; height: 14px; vertical-align: -2px; margin-right: 4px; }
/* Ce que l'ennemi a rencontre, quand on l'a vu : c'est un complement, pas la
   lecon -- il passe donc au second plan. */
.rap-contre-eux { color: var(--muted); margin-top: 4px; }

/* La part du butin dans un rapport de ralliement. `.gold` n'existe qu'a
   l'interieur du panneau du ralliement : employee ici, elle serait sans style. */
.rap-part { color: var(--gold-bright); font-weight: 700; font-variant-numeric: tabular-nums; }

/* Ce que l'armee rassemblee porte comme armes. A sept contre un, c'est
   l'information qui decide ce qu'on apporte -- et la seule qu'on puisse
   connaitre, puisque celle d'en face est sous le brouillard. */
.rall-compo .rc-avis { font-size: 0.76rem; line-height: 1.45; margin: 0 0 10px; }
.rc-arme {
    display: grid; grid-template-columns: 8.5rem 1fr 3rem;
    align-items: center; gap: 8px; margin-bottom: 5px; font-size: 0.78rem;
}
.rc-arme.vide { opacity: .45; }
.rc-arme .rc-n { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rc-arme .rc-n .mg-ic { width: 1em; height: 1em; vertical-align: -0.15em; margin-right: 3px; }
.rc-arme .rc-jauge {
    height: 8px; border-radius: 3px; background: rgba(212,165,72,0.12); overflow: hidden;
}
.rc-arme .rc-jauge i { display: block; height: 100%; background: var(--accent); transition: width .3s ease; }
/* Une couleur par arme : on lit le desequilibre sans lire les nombres. */
.rc-arme .rc-jauge i.a-Sword { background: #d4a548; }
.rc-arme .rc-jauge i.a-Axe   { background: #cf6a55; }
.rc-arme .rc-jauge i.a-Lance { background: #7aa7c7; }
.rc-arme .rc-jauge i.a-Autre { background: var(--muted); }
.rc-arme .rc-p { text-align: right; font-variant-numeric: tabular-nums; color: var(--muted); }
.rall-compo .rc-manque { font-size: 0.74rem; color: var(--muted); margin: 8px 0 0; }
@media (max-width: 480px) {
    .rc-arme { grid-template-columns: 6.5rem 1fr 2.8rem; font-size: 0.72rem; }
}

/* =======================================================================
   La fiche des troupes (caserne et atelier de siege)
   -----------------------------------------------------------------------
   C'est une page qu'on lit, pas une page ou l'on clique : elle pose donc sa
   police d'interface, comme les deux fenetres d'aide -- le defaut du jeu est
   une anglaise medievale faite pour un titre de trois mots.
   ======================================================================= */
.ft-loi, .ft-carte { font-family: var(--font-ui); text-align: left; }

.ft-loi {
    background: var(--surface); border: 1px solid var(--line-soft);
    border-radius: var(--radius); padding: 12px 14px; margin-bottom: 12px;
}
.ft-loi h4 {
    font-family: var(--font-title); font-size: 0.9rem; color: var(--gold-bright);
    margin: 0 0 8px; display: flex; align-items: center; gap: 7px;
}
.ft-loi h4 .mg-ic { width: 18px; height: 18px; }
/* Le film des veterans, dans l'aide de la Caserne (16:10, comme les films des notes). */
.ft-film { margin: 4px 0 10px; }
.ft-film video, .ft-film img { display: block; width: 100%; height: auto; aspect-ratio: 16 / 10; border-radius: 10px;
    border: 1px solid var(--line-soft); background: #0d0a07; }
.ft-loi p { font-size: 0.78rem; line-height: 1.5; margin: 0 0 8px; color: var(--text-light); }
.ft-loi p:last-child { margin-bottom: 0; }
.ft-loi .mil-note { margin-bottom: 8px; line-height: 1.45; }

.ft-carte {
    background: var(--surface); border: 1px solid var(--line-soft);
    border-radius: var(--radius); padding: 12px; margin-bottom: 10px;
}
.ft-tete { display: grid; grid-template-columns: 58px 1fr auto; gap: 12px; align-items: center; }
.ft-id { min-width: 0; display: flex; flex-direction: column; gap: 5px; align-items: flex-start; }
.ft-id h4 { font-family: var(--font-title); font-size: 0.95rem; margin: 0; color: var(--text-light); }
.ft-puissance { text-align: right; }
.ft-puissance .k {
    display: block; font-size: 0.56rem; font-weight: 700; letter-spacing: 0.06em;
    text-transform: uppercase; color: var(--muted);
}
.ft-puissance .v { display: block; font-size: 1.05rem; font-weight: 700; color: var(--gold-bright); }

/* Ce qu'elle contre et ce qui la contre : deux lignes cote a cote tant que la
   place le permet, l'une sous l'autre des qu'elle manque. */
.ft-tri {
    display: flex; flex-wrap: wrap; gap: 6px 14px; margin-top: 10px;
    padding-top: 10px; border-top: 1px solid var(--line-soft); font-size: 0.72rem;
}
.ft-tri .mg-ic { width: 14px; height: 14px; vertical-align: -2px; margin-right: 4px; }
.ft-fort { color: var(--success); }
.ft-faible { color: var(--danger); }
.ft-neutre { color: var(--muted); }

.ft-chiffres { margin-top: 10px; display: flex; flex-direction: column; gap: 4px; }
.ft-l { display: flex; align-items: center; justify-content: space-between; gap: 10px; font-size: 0.73rem; }
.ft-l .k { color: var(--muted); }
.ft-l .v { color: var(--text-light); display: flex; flex-wrap: wrap; gap: 5px; justify-content: flex-end; }

/* Les particularites : une liste, parce que ce sont des phrases et non des
   chiffres, et qu'on les parcourt de l'oeil. */
.ft-traits {
    list-style: none; margin: 10px 0 0; padding: 10px 0 0;
    border-top: 1px solid var(--line-soft);
    display: flex; flex-direction: column; gap: 7px;
}
.ft-traits li { font-size: 0.72rem; line-height: 1.45; color: var(--muted); }
.ft-traits li b { color: var(--text-light); }
.ft-traits li .mg-ic { width: 15px; height: 15px; vertical-align: -3px; margin-right: 5px; }

@media (max-width: 480px) {
    /* `.portrait` est fixe a 58 px : retrecir la colonne sans retrecir la
       vignette la faisait deborder sous le nom de l'unite. Les deux bougent
       ensemble, ou aucune. */
    .ft-tete { grid-template-columns: 48px 1fr auto; gap: 9px; }
    .ft-tete .portrait { width: 48px; height: 48px; }
    .ft-puissance .v { font-size: 0.92rem; }
    .ft-loi p, .ft-tri, .ft-l, .ft-traits li { font-size: 0.7rem; }
}

/* =======================================================================
   Les notes de version : le resume, et le detail en images
   -----------------------------------------------------------------------
   L'ecran deroulait toutes les notes de toutes les versions non lues. Le
   resume tient en un coup d'oeil, et ce qui l'interesse s'ouvre a la demande.
   ======================================================================= */
.cl-resume { list-style: none; margin: 8px 0 0; padding: 0; display: flex; flex-direction: column; gap: 7px; }
.cl-resume li {
    position: relative; padding-left: 16px; font-size: 0.84rem; line-height: 1.45;
    font-family: var(--font-ui); color: var(--text-light);
}
/* Un losange plutot qu'une puce : le resume n'est pas une liste de plus, c'est
   la table des matieres de la version. */
.cl-resume li::before {
    content: ''; position: absolute; left: 2px; top: .55em;
    width: 6px; height: 6px; background: var(--accent); transform: rotate(45deg);
}

.cl-plus {
    margin-top: 12px; width: 100%; padding: 9px 12px;
    background: rgba(212,165,72,.07); border: 1px solid var(--panel-border); border-radius: var(--radius-sm);
    color: var(--gold-bright); font-family: var(--font-ui); font-size: .78rem; font-weight: 600;
    cursor: pointer; display: flex; align-items: center; justify-content: center; gap: 7px;
}
.cl-plus .mg-ic { width: 15px; height: 15px; }
@media (hover: hover) and (pointer: fine) {
    .cl-plus:hover { background: rgba(212,165,72,.14); border-color: var(--accent); }
}
.cl-repliees { margin-top: 10px; }

/* --- La page du detail --- */
/* ===== La grande annonce d'une mise a jour =====
   Plein ecran, au-dessus des notes de version (10000) et sous le detail en
   images (10002), qui s'ouvre par-dessus elle. N'anime que transform et
   opacity ; rien du tout avec le mouvement reduit. */
#maj-annonce {
    position: fixed; inset: 0; z-index: 10001;
    overflow-y: auto; overscroll-behavior: contain;
    background: radial-gradient(ellipse at 50% 30%, #2a1f12 0%, #0d0906 62%, #050302 100%);
    font-family: var(--font-ui); color: var(--text-light);
    padding: max(18px, env(safe-area-inset-top)) 16px max(24px, env(safe-area-inset-bottom));
}
#maj-annonce.mja-joue { animation: mja-entre .5s ease-out both; }
#maj-annonce.mja-sort { animation: mja-sort .26s ease-in both; }
@keyframes mja-entre { from { opacity: 0; } to { opacity: 1; } }
@keyframes mja-sort { to { opacity: 0; } }

.mja-rayons {
    position: fixed; left: 50%; top: 32%; width: 170vmax; height: 170vmax;
    margin: -85vmax 0 0 -85vmax; pointer-events: none; opacity: 0;
    background: repeating-conic-gradient(from 0deg, rgba(240,198,116,.10) 0deg 5deg, rgba(240,198,116,0) 5deg 15deg);
    -webkit-mask-image: radial-gradient(circle, #000 0%, rgba(0,0,0,.6) 25%, transparent 55%);
            mask-image: radial-gradient(circle, #000 0%, rgba(0,0,0,.6) 25%, transparent 55%);
}
.mja-joue .mja-rayons { animation: mja-fondu 1.6s ease-out .2s both, mja-tourne 90s linear infinite; }
@keyframes mja-fondu { from { opacity: 0; } to { opacity: 1; } }
@keyframes mja-tourne { to { transform: rotate(360deg); } }

.mja-etincelles { position: fixed; inset: 0; pointer-events: none; overflow: hidden; }
.mja-etincelles i {
    position: absolute; left: var(--x); bottom: -12px; width: 5px; height: 5px; border-radius: 50%;
    background: #ffd98a; box-shadow: 0 0 8px 2px rgba(255,200,100,.7); opacity: 0;
    transform: scale(var(--s));
}
.mja-joue .mja-etincelles i { animation: mja-monte var(--t) linear var(--d) infinite; }
@keyframes mja-monte {
    0%   { transform: translate(0, 0) scale(var(--s)); opacity: 0; }
    12%  { opacity: .9; }
    100% { transform: translate(30px, -105vh) scale(var(--s)); opacity: 0; }
}

.mja-cadre {
    position: relative; max-width: 860px; margin: 0 auto;
    display: flex; flex-direction: column; align-items: center; text-align: center; gap: 14px;
}
.mja-croix {
    position: absolute; top: 0; right: 0; width: 40px; height: 40px; border-radius: 50%;
    border: 1px solid rgba(240,198,116,.45); background: rgba(0,0,0,.45); color: var(--text-light);
    font-size: 1.05rem; cursor: pointer; z-index: 2;
}
.mja-croix:hover { border-color: var(--gold-bright); color: var(--gold-bright); }
.mja-blason { width: 84px; height: 84px; margin-top: 6px; filter: drop-shadow(0 0 18px rgba(255,200,100,.65)); }
.mja-blason .mg-ic { width: 100%; height: 100%; }
.mja-etiq {
    font-size: .78rem; font-weight: 700; letter-spacing: .22em; text-transform: uppercase; color: var(--accent);
    padding: 5px 14px; border: 1px solid rgba(212,165,72,.5); border-radius: 999px; background: rgba(212,165,72,.08);
}
.mja-titre {
    margin: 0; padding: 0 6px;
    font-family: var(--font-title); font-weight: 700; line-height: 1.12; text-wrap: balance;
    font-size: clamp(1.9rem, 6.4vw, 3.3rem); color: var(--gold-bright);
    filter: drop-shadow(0 2px 0 #3a2508) drop-shadow(0 0 18px rgba(240,198,116,.35));
}
/* Le reflet qui passe sur les lettres, une fois : le degrade est rogne au
   texte. Il anime background-position -- une peinture, pas le compositeur --,
   mais une seule fois et une seconde et demie : c'est un evenement, pas un
   battement. */
.mja-titre span {
    background: linear-gradient(100deg, #f0c674 0%, #f0c674 42%, #fff7dd 50%, #f0c674 58%, #f0c674 100%) 100% 0 / 260% 100% no-repeat;
    -webkit-background-clip: text; background-clip: text; color: transparent;
}
.mja-joue .mja-titre span { animation: mja-reflet 1.5s ease-in-out 1.6s both; }
@keyframes mja-reflet { from { background-position: 100% 0; } to { background-position: 0% 0; } }
.mja-sous { margin: 0; max-width: 620px; font-size: 1rem; line-height: 1.5; color: #e2d5bb; text-wrap: balance; }
.mja-scene { width: 100%; display: flex; flex-direction: column; align-items: center; gap: 14px; }
.mja-film {
    margin: 4px 0 0; width: 100%; max-width: 640px; aspect-ratio: 16 / 10;
    border-radius: 14px; overflow: hidden; border: 2px solid rgba(240,198,116,.7);
    background: #1a140d url('assets/merveille/etage5.webp') center 60% / 40% no-repeat;
    box-shadow: 0 0 0 6px rgba(0,0,0,.35), 0 18px 50px rgba(0,0,0,.7), 0 0 40px rgba(240,198,116,.18);
}
.mja-film img, .mja-film video { display: block; width: 100%; height: 100%; object-fit: cover; }
.mja-cartes { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; width: 100%; margin-top: 4px; }
.mja-carte {
    text-align: left; padding: 12px 14px; border-radius: 12px; min-width: 0;
    border: 1.5px solid var(--c); background: rgba(0,0,0,.42);
    box-shadow: inset 0 0 22px color-mix(in srgb, var(--c) 12%, transparent);
}
.mja-carte-h { display: flex; align-items: center; gap: 8px; color: var(--c); font-family: var(--font-title); font-weight: 700; font-size: 1.02rem; line-height: 1.2; }
.mja-carte-h .mg-ic, .mja-carte-h img { width: 22px; height: 22px; flex: none; }
.mja-carte p { margin: 7px 0 0; font-size: .85rem; line-height: 1.45; color: #d8cbb0; }
.mja-ou { margin: 2px 0 0; font-size: .92rem; color: var(--text-light); }
.mja-ou b { color: var(--gold-bright); }
.mja-actions {
    display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; margin: 0; width: 100%;
    /* Le bouton qui mene aux notes reste a l'ecran : sur un portable, les
       cartes suffisent a le pousser sous le pli. */
    position: sticky; bottom: 0; z-index: 3; padding: 26px 0 4px;
    /* Opaque des le haut des boutons : a demi transparent, le texte qui
       defile dessous se lisait a travers eux. */
    background: linear-gradient(180deg, rgba(10,7,4,0) 0, #0a0704 18px);
}
.mja-btn {
    display: inline-flex; align-items: center; gap: 8px; min-height: 46px; padding: 10px 20px;
    border-radius: 10px; border: 1px solid rgba(240,198,116,.5); background: rgba(0,0,0,.4);
    color: var(--text-light); font: 600 .95rem var(--font-ui); cursor: pointer;
}
.mja-btn .mg-ic { width: 18px; height: 18px; }
.mja-btn:hover { border-color: var(--gold-bright); }
.mja-btn-or {
    background: linear-gradient(180deg, #f0c674, #b98a35); color: #241703; border-color: #f7d996;
    font-weight: 700; box-shadow: 0 6px 20px rgba(240,198,116,.3);
}
.mja-btn-or:hover { filter: brightness(1.08); }

/* L'entree en scene : chaque piece arrive a son tour. */
.mja-joue .mja-blason { animation: mja-blason 1s cubic-bezier(.2,1.4,.4,1) .15s both; }
.mja-joue .mja-etiq   { animation: mja-monte-un .6s ease-out .75s both; }
.mja-joue .mja-titre  { animation: mja-titre .8s cubic-bezier(.2,1.2,.4,1) .9s both; }
.mja-joue .mja-sous   { animation: mja-monte-un .6s ease-out 1.25s both; }
.mja-joue .mja-film   { animation: mja-film .8s cubic-bezier(.2,1.1,.4,1) 1.45s both; }
.mja-joue .mja-carte  { animation: mja-monte-un .55s ease-out calc(1.85s + var(--i) * .12s) both; }
.mja-joue .mja-ou, .mja-joue .mja-actions { animation: mja-monte-un .5s ease-out 2.4s both; }
@keyframes mja-blason { 0% { opacity: 0; transform: scale(.2) rotate(-20deg); } 70% { opacity: 1; transform: scale(1.15) rotate(3deg); } 100% { opacity: 1; transform: none; } }
@keyframes mja-titre  { from { opacity: 0; transform: scale(1.25); } to { opacity: 1; transform: none; } }
@keyframes mja-film   { from { opacity: 0; transform: translateY(24px) scale(.92); } to { opacity: 1; transform: none; } }
@keyframes mja-monte-un { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }

/* Le bouton qui la remontre, dans les notes de version. */
.cl-plus.cl-annonce { margin-right: 6px; }

/* Sur un ecran large, les cartes se rangent a cote du film : empilees, elles
   tombaient sous le pli d'un portable de 800 px. */
@media (min-width: 980px) {
    .mja-cadre { max-width: 1000px; }
    .mja-scene { display: grid; grid-template-columns: minmax(0, 1.75fr) minmax(0, 1fr); align-items: center; gap: 16px; }
    .mja-film { max-width: none; margin: 0; }
    .mja-cartes { grid-template-columns: 1fr; gap: 9px; margin: 0; }
    .mja-carte { padding: 10px 14px; }
    .mja-carte p { margin-top: 4px; }
}
@media (min-width: 701px) and (max-height: 860px) {
    .mja-blason { width: 58px; height: 58px; margin-top: 0; }
    .mja-cadre { gap: 10px; }
    .mja-titre { font-size: clamp(1.9rem, 5vw, 2.8rem); }
}
@media (max-width: 700px) {
    .mja-cartes { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 9px; }
    .mja-carte { padding: 10px 11px; }
    .mja-carte-h { font-size: .9rem; }
    .mja-carte p { font-size: .78rem; }
    .mja-sous { font-size: .9rem; }
    .mja-blason { width: 64px; height: 64px; }
    .mja-cadre { gap: 11px; }
    /* Cote a cote : empiles, les deux boutons epingles mangeaient le quart de
       l'ecran par-dessus les cartes. */
    .mja-actions { flex-wrap: nowrap; gap: 8px; padding-top: 20px; }
    .mja-btn { flex: 1 1 0; min-width: 0; justify-content: center; text-align: center; padding: 8px 10px; font-size: .86rem; line-height: 1.2; }
}
@media (prefers-reduced-motion: reduce) {
    #maj-annonce *, #maj-annonce { animation: none !important; }
    .mja-rayons { opacity: 1; }
    .mja-etincelles { display: none; }
}

.majd-sous { margin: 6px 0 0; font-family: var(--font-ui); font-size: .78rem; color: var(--muted); line-height: 1.45; }
/* Des paragraphes entiers : elle pose sa police, comme les deux fenetres qui se
   lisent. Le defaut du jeu est une anglaise faite pour un titre de trois mots. */
.majd-corps { font-family: var(--font-ui); }
.majd-sec { margin-bottom: 22px; }
.majd-sec:last-child { margin-bottom: 4px; }
.majd-sec h4 {
    font-family: var(--font-title); font-size: .95rem; color: var(--gold-bright);
    margin: 0 0 8px; display: flex; align-items: center; gap: 7px;
}
.majd-sec h4 .mg-ic { width: 18px; height: 18px; flex: none; }
.majd-sec p { font-size: .82rem; line-height: 1.55; margin: 0 0 8px; color: var(--text-light); }

.majd-fig { margin: 12px 0 0; }
.majd-fig img, .majd-fig video {
    display: block; width: 100%; max-width: 480px; height: auto; margin: 0 auto;
    border: 1px solid var(--panel-border); border-radius: var(--radius-sm);
    background: var(--surface);
}
.majd-fig figcaption {
    margin-top: 7px; text-align: center;
    font-size: .72rem; color: var(--muted); font-style: italic; line-height: 1.4;
}

@media (max-width: 480px) {
    .cl-resume li { font-size: .78rem; }
    .majd-sec p { font-size: .78rem; }
    .majd-sec h4 { font-size: .88rem; }
}

/* =======================================================================
   Le voile de mise a jour
   -----------------------------------------------------------------------
   Une bascule de version coupait net : la page disparaissait, l'ecran blanc
   du navigateur s'installait une seconde, et le jeu revenait. Ce voile occupe
   les deux bouts -- pose avant le rechargement, repose des la premiere ligne
   de la page suivante -- de sorte que le joueur ne voie jamais le trou.

   Son `z-index` passe devant tout, y compris les fenetres a 10001 : pendant
   une mise a jour, plus rien d'autre ne compte.
   ======================================================================= */
#maj-voile {
    position: fixed; inset: 0; z-index: 99999;
    display: grid; place-items: center;
    background: radial-gradient(circle at 50% 40%, #1a1510 0%, #0b0907 70%);
    font-family: var(--font-ui);
    animation: majParait .25s ease both;
}
@keyframes majParait { from { opacity: 0; } to { opacity: 1; } }

.maj-boite { text-align: center; padding: 0 24px; max-width: 420px; }
.maj-blason .mg-ic { width: 72px; height: 72px; color: var(--gold-bright); animation: majSouffle 2.4s ease-in-out infinite; }
@keyframes majSouffle { 0%, 100% { opacity: .55; transform: scale(.97); } 50% { opacity: 1; transform: scale(1); } }

.maj-boite h2 {
    font-family: var(--font-title); font-size: 1.15rem; color: var(--gold-bright);
    margin: 14px 0 8px; letter-spacing: .02em;
}
.maj-boite p { font-size: .82rem; line-height: 1.5; color: var(--muted); margin: 0 0 18px; }

/* Une barre qui va et vient : on ne sait pas combien de temps cela prendra, et
   une barre qui pretendrait le savoir mentirait. */
.maj-barre { height: 3px; border-radius: 2px; background: rgba(212,165,72,.14); overflow: hidden; }
.maj-barre i {
    display: block; width: 38%; height: 100%; border-radius: 2px;
    background: linear-gradient(90deg, transparent, var(--accent), transparent);
    animation: majVaEtVient 1.5s ease-in-out infinite;
}
@keyframes majVaEtVient {
    0% { transform: translateX(-100%); }
    100% { transform: translateX(320%); }
}

/* L'API qui redemarre, elle, ne justifie pas un voile : le jeu continue de
   tourner, simplement contre une version d'hier. Un bandeau discret suffit, et
   il s'efface tout seul quand le serveur a rattrape. */
#maj-bandeau {
    position: fixed; left: 50%; transform: translateX(-50%);
    bottom: calc(14px + env(safe-area-inset-bottom, 0px)); z-index: 9998;
    display: flex; align-items: center; gap: 8px;
    padding: 8px 14px; border-radius: 999px;
    background: rgba(14,11,8,.94); border: 1px solid var(--panel-border);
    box-shadow: 0 6px 20px rgba(0,0,0,.5);
    font-family: var(--font-ui); font-size: .74rem; color: var(--muted);
    animation: majParait .3s ease both;
}
#maj-bandeau .mg-ic { width: 15px; height: 15px; color: var(--gold-bright); animation: majSouffle 2.4s ease-in-out infinite; }

@media (max-width: 480px) {
    .maj-blason .mg-ic { width: 58px; height: 58px; }
    .maj-boite h2 { font-size: 1rem; }
    /* La barre de navigation mobile est posee en bas : le bandeau se glisse
       au-dessus d'elle plutot que dessous. */
    #maj-bandeau { bottom: calc(76px + env(safe-area-inset-bottom, 0px)); font-size: .7rem; }
}

/* ------------------------------------------------------------- en ligne

   Une pastille verte sur qui a le jeu ouvert, dans le tchat et sur la carte.

   **On ne montre que le vert, jamais le gris.** Le serveur repond a partir du
   registre du flux : une oreille ouverte veut dire une page chargee. L'absence
   de pastille peut donc vouloir dire « parti », mais aussi « onglet en veille »
   ou « l'API vient de redemarrer ». Un point gris affirmerait une absence qu'on
   ne sait pas etablir ; rien du tout n'affirme rien.

   Elle est posee AVANT le pseudo et jamais dedans : le bandeau de reponse relit
   le nom par le `textContent` de `.chat-who`, et tout ce qu'on glisserait dans
   ce bouton s'y retrouverait. */
.en-ligne {
    display: inline-block;
    width: 7px;
    height: 7px;
    flex: 0 0 auto;
    border-radius: 50%;
    background: var(--success);
    /* Le halo fait tout le travail sur la carte : a cette taille, un disque plat
       se perd dans la plaque du nom, qui est deja claire. */
    box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.55), 0 0 5px var(--success);
    vertical-align: middle;
    animation: enLigneBattement 2.4s ease-in-out infinite;
}

/* Un battement lent, sur l'opacite seule : `transform` est deja porte par la
   colonne des fanions de la carte, et une animation qui reecrit `transform`
   ecrase toute la propriete -- c'est ce qui avait decale le pavois d'une
   demi-largeur. Ici il n'y a rien a ecraser, et rien a casser. */
@keyframes enLigneBattement {
    0%, 100% { opacity: 1; }
    50%      { opacity: 0.45; }
}

/* Sur la carte, la plaque du nom est une boite serree : la pastille prend sa
   place dans le flux plutot que de chevaucher la premiere lettre. */
.map-village-name .en-ligne { margin-right: 4px; }

/* Dans le tchat, l'en-tete est une rangee flex : un `margin-right` suffirait,
   mais le `gap` de la rangee s'en charge deja. On ne pose que l'alignement. */
.chat-msg-head .en-ligne { align-self: center; }

/* =========================================================================
   Les barres de defilement
   ========================================================================= */

/* Le jeu habillait ses barres par une liste de selecteurs, allongee a chaque
   ecran nouveau -- et vingt surfaces defilaient encore avec la barre blanche du
   navigateur au milieu d'une interface sombre : la fiche de la carte, les
   panneaux lateraux, les zones de saisie, l'administration.
   
   Une regle globale remplace la liste. Les proprietes de barre n'ont d'effet que
   sur ce qui defile, donc `*` ne coute rien ailleurs ; et sa specificite etant
   nulle, toutes les regles existantes continuent de primer la ou elles existent.
   
   `scrollbar-color` sert Firefox, `::-webkit-scrollbar` sert Chrome et Safari :
   il faut les deux, sinon la barre reste nue sur la moitie des navigateurs. */
* {
    scrollbar-width: thin;
    scrollbar-color: var(--line-soft) transparent;
/* =============================================================
   LES TOURNOIS DU ROYAUME
   ============================================================= */

/* Le bandeau du heraut. Il vit au-dessus du jeu, comme celui du Seigneur de
   guerre, et ne recouvre jamais la barre d'onglets du telephone : il se pose
   au-dessus d'elle par `bottom`, pas par un z-index qui l'enjamberait. */
.trn-bandeau {
    position: fixed;
    /* **`left: 50%` seul ecrasait le bandeau sur la moitie de l'ecran.** Un
       element `fixed` sans largeur se retrecit au contenu, mais la place dont
       il dispose part de son `left` : a 50 %, il ne restait que 50vw, et le
       `max-width` ne pouvait pas l'elargir -- un maximum ne fait que rogner.
       « Le Tir au trebuchet » tombait donc a un mot par ligne. Deux bords et
       une marge automatique centrent aussi bien, en laissant toute la largeur. */
    left: 12px;
    right: 12px;
    margin-inline: auto;
    width: fit-content;
    /* Il se pose AU-DESSUS des travaux en cours, jamais dessus : les deux
       flottent au meme endroit, et la hauteur des travaux est deja mesuree
       pour la feuille du telephone. */
    bottom: calc(14px + var(--hauteur-travaux, 0px));
    z-index: 55;
    display: flex;
    align-items: center;
    gap: 10px;
    max-width: min(520px, calc(100vw - 24px));
    box-sizing: border-box;
    padding: 9px 12px;
    border-radius: 12px;
    border: 1px solid var(--panel-border);
    background: linear-gradient(180deg, #221b14, #16120d);
    box-shadow: 0 8px 28px rgba(0,0,0,0.6);
    font-family: var(--font-ui);
    cursor: pointer;
}
.trn-bandeau.trn-ouvert { border-color: var(--accent); }
.trn-bandeau .mg-ic { width: 20px; height: 20px; color: var(--gold-bright); }
.trn-bandeau-txt { display: flex; flex-direction: column; min-width: 0; flex: 1; }
/* Un nom d'epreuve plus long que la place se coupe ; il ne s'empile pas en
   colonne d'un mot. Le `min-width: 0` du parent est ce qui rend l'ellipse
   possible -- sans lui, un enfant flex refuse de retrecir sous son contenu. */
.trn-bandeau-txt b {
    font-size: 0.82rem;
    color: var(--text-light);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.trn-bandeau-quand { font-size: 0.7rem; color: var(--muted); white-space: nowrap; }
.trn-bandeau.trn-ouvert .trn-bandeau-quand { color: var(--gold-bright); }
.trn-bandeau-btn {
    flex: 0 0 auto;
    border: 1px solid var(--panel-border);
    background: var(--surface-3);
    color: var(--gold-bright);
    font-family: var(--font-ui);
    font-size: 0.72rem;
    padding: 6px 11px;
    border-radius: 8px;
    cursor: pointer;
}

/* La fenetre. C'est une fenetre qui se LIT autant qu'elle s'utilise : elle pose
   sa police, faute de quoi elle heriterait du Lancelot du `body`, qui est une
   anglaise faite pour un titre de trois mots. */
#trn-corps { font-family: var(--font-ui); }
.trn-tete { display: flex; align-items: center; gap: 12px; margin-bottom: 4px; }
.trn-tete h3 { margin: 0; font-size: 1.05rem; }
.trn-tete-ico .mg-ic { width: 32px; height: 32px; color: var(--gold-bright); }
.trn-devise { margin: 2px 0 0; font-size: 0.8rem; color: var(--muted); font-style: italic; }
.trn-quand { margin: 6px 0 12px; font-size: 0.85rem; color: var(--gold-bright); }
.trn-regle { font-size: 0.85rem; line-height: 1.5; color: var(--text-light); }
.trn-mise {
    font-size: 0.82rem; line-height: 1.55; color: var(--muted);
    border-left: 2px solid var(--panel-border);
    padding: 8px 0 8px 12px; margin: 0 0 14px;
}
.trn-mise b { color: var(--text-light); }
.trn-avert { font-size: 0.74rem; color: var(--muted); text-align: center; margin: 8px 0 0; }
.trn-vide { font-size: 0.85rem; color: var(--muted); font-style: italic; text-align: center; padding: 18px 0; }
.trn-sous { margin: 22px 0 8px; font-size: 0.9rem; }

/* Le panneau de renvoi : une partie jouee dont le score n'est pas parti. */
.trn-renvoi { display: flex; flex-direction: column; gap: 12px; align-items: center;
              text-align: center; padding: 18px 12px; }
.trn-renvoi-t { font-family: var(--font-ui); font-weight: 700; font-size: 1.02rem;
                color: var(--danger); margin: 0; }
.trn-renvoi-d { font-family: var(--font-ui); font-size: 0.86rem; line-height: 1.5;
                color: var(--muted); margin: 0; max-width: 34ch; }
.trn-renvoi .btn-bar { width: 100%; max-width: 280px; }
.trn-sous small { color: var(--muted); font-weight: normal; }

.trn-resultat {
    display: flex; flex-direction: column; align-items: center; gap: 4px;
    padding: 16px; border-radius: 10px;
    background: var(--surface-2); border: 1px solid var(--panel-border);
}
.trn-res-score { font-size: 2rem; font-family: var(--font-title); color: var(--gold-bright); }
.trn-res-score small { font-size: 0.9rem; color: var(--muted); }
.trn-res-txt { font-size: 0.8rem; color: var(--muted); text-align: center; }

.trn-table { width: 100%; border-collapse: collapse; font-size: 0.82rem; }
.trn-table th { text-align: left; color: var(--muted); font-weight: 600; padding: 6px 8px; font-size: 0.72rem; }
.trn-table td { padding: 7px 8px; border-top: 1px solid var(--panel-border); }
.trn-table td:first-child { color: var(--muted); width: 2ch; }
.trn-table td:last-child { text-align: right; white-space: nowrap; }
.trn-table tr.trn-moi td { background: rgba(212,175,55,0.08); color: var(--gold-bright); }
.trn-vous { color: var(--muted); font-size: 0.74rem; }

/* --- Le trebuchet ---
   La poutre fait toute la largeur et se tape n'importe ou : viser un bouton de
   quarante pixels au pouce EN REGARDANT AILLEURS serait un second jeu
   d'adresse, qu'on n'a pas voulu ajouter au premier. */
.trb-tete { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 14px; }
.trb-tir { font-size: 0.82rem; color: var(--muted); }
.trb-tir b { color: var(--text-light); }
.trb-score { font-size: 0.95rem; color: var(--gold-bright); font-family: var(--font-title); }

.trb-poutre {
    position: relative;
    height: 56px;
    border-radius: 10px;
    border: 1px solid var(--panel-border);
    background: linear-gradient(180deg, #1a1611, #100d09);
    overflow: hidden;
    cursor: pointer;
    /* Le doigt ne doit ni faire defiler la page ni zoomer pendant qu'on vise. */
    touch-action: none;
    -webkit-tap-highlight-color: transparent;
    transition: box-shadow 0.15s, border-color 0.15s;
}
.trb-zone {
    position: absolute; top: 0; bottom: 0;
    background: linear-gradient(180deg, rgba(212,175,55,0.32), rgba(212,175,55,0.14));
    border-left: 1px solid rgba(212,175,55,0.7);
    border-right: 1px solid rgba(212,175,55,0.7);
}
.trb-boulet {
    position: absolute; top: 50%; left: 0;
    width: 16px; height: 16px; margin: -8px 0 0 -8px;
    border-radius: 50%;
    background: radial-gradient(circle at 35% 30%, #efe3c8, #8d7a55 70%, #4a3f2c);
    box-shadow: 0 0 10px rgba(239,227,200,0.35);
}
.trb-poutre.trb-plein { box-shadow: inset 0 0 0 2px var(--gold-bright), 0 0 22px rgba(212,175,55,0.45); }
.trb-poutre.trb-frole { box-shadow: inset 0 0 0 2px rgba(212,175,55,0.45); }
.trb-poutre.trb-rate  { box-shadow: inset 0 0 0 2px rgba(207,106,85,0.6); }

.trb-tirer { width: 100%; margin-top: 14px; font-size: 1rem; padding: 14px; touch-action: manipulation; }
.trb-aide { font-size: 0.74rem; color: var(--muted); text-align: center; margin: 10px 0 0; }

/* -------------------------------------------------------------
   L'ENIGME DU HERAUT
   ------------------------------------------------------------- */

.enq { font-family: var(--font-ui); }
.enq-tete {
    display: flex; justify-content: space-between; align-items: baseline;
    font-size: 0.78rem; color: var(--muted); margin-bottom: 8px;
}
.enq-n b { color: var(--gold-bright); }
/* Le palier du haut se voit tant qu'il court, et s'eteint quand il est passe :
   c'est la seule facon de faire sentir qu'on joue contre la montre. */
.enq-vif { color: var(--gold-bright); transition: color 0.3s, opacity 0.3s; }
.enq-vif.enq-vif-passe { color: var(--muted); opacity: 0.55; }

.enq-sable { height: 5px; border-radius: 3px; background: var(--surface-3); overflow: hidden; }
.enq-sable-fill {
    height: 100%; width: 100%;
    background: linear-gradient(90deg, var(--accent), var(--gold-bright));
}

/* La question est un PARAGRAPHE, donc elle pose sa police : le defaut du jeu
   est une anglaise faite pour un titre de trois mots. */
.enq-q {
    font-family: var(--font-ui); font-size: 1.02rem; line-height: 1.45;
    margin: 16px 0 14px; color: var(--text-light);
}
.enq-choix { display: flex; flex-direction: column; gap: 8px; }
.enq-opt {
    font-family: var(--font-ui); font-size: 0.92rem; text-align: left;
    padding: 13px 14px; border-radius: 10px;
    border: 1px solid var(--panel-border); background: var(--surface-3);
    color: var(--text-light); cursor: pointer;
    /* Quarante-quatre pixels au moins : c'est la taille d'un pouce. */
    min-height: 44px;
    transition: border-color 0.15s, background 0.15s;
}
.enq-opt:hover:not(:disabled) { border-color: var(--accent); }
.enq-opt:disabled { opacity: 0.5; cursor: default; }
/* **Pris, pas « juste ».** Le client ignore la bonne reponse -- c'est ce qui
   rend l'epreuve difficile a tricher --, donc il n'a rien a annoncer ici. */
.enq-opt.enq-pris { opacity: 1; border-color: var(--gold-bright); background: var(--surface-2); }

.enq-corr { list-style: none; padding: 0; margin: 10px 0 0; font-family: var(--font-ui); }
.enq-corr li {
    display: flex; flex-direction: column; gap: 2px;
    padding: 9px 11px; margin-bottom: 6px; border-radius: 8px;
    border-left: 3px solid var(--line-soft); background: var(--surface-3);
}
.enq-corr li.enq-ok { border-left-color: #6f9c5a; }
.enq-corr li.enq-ko { border-left-color: #cf6a55; }
.enq-cq { font-size: 0.8rem; color: var(--muted); }
.enq-cr { font-size: 0.86rem; color: var(--text-light); }

/* -------------------------------------------------------------
   LA MELEE : le dernier debout
   ------------------------------------------------------------- */

.mel { font-family: var(--font-ui); text-align: center; }
.mel-tete {
    display: flex; justify-content: space-between;
    font-size: 0.78rem; color: var(--muted); margin-bottom: 8px;
}
.mel-tete b { color: var(--gold-bright); }
.mel-phase { font-size: 0.82rem; color: var(--muted); margin: 0 0 4px; }
.mel-compte { font-size: 2rem; color: var(--gold-bright); margin: 0 0 6px; }
.mel-debout { font-size: 0.86rem; color: var(--text-light); margin: 6px 0 14px; }
.mel-aide { font-size: 0.74rem; color: var(--muted); margin: 12px 0 0; }
.mel-sorti {
    font-size: 0.86rem; color: var(--muted); margin: 18px 0 0;
    padding: 12px; border-radius: 10px; background: var(--surface-3);
}

/* La lice dressee : une explication, un bouton, une ligne fine. `.mel-aide`
   n'avait jamais de bouton apres elle -- il faut donc lui rendre l'air que
   `.mel-debout` porte dans la vue de l'appel. */
.mel .btn-bar { margin-top: 14px; }
.mel-fine { font-size: 0.7rem; color: var(--muted); margin: 10px 0 0; opacity: 0.85; }

.mel-sable { height: 6px; border-radius: 3px; background: var(--surface-3); overflow: hidden; }
.mel-sable-fill { height: 100%; width: 0%; background: var(--gold-bright); }

/* L'ordre tient TOUTE la place : c'est le seul mot a lire, et il faut le lire
   en un dixieme de seconde. */
.mel-ordre {
    font-family: var(--font-ui); font-weight: 700; letter-spacing: 0.06em;
    font-size: 1.7rem; line-height: 1.15;
    margin: 22px 0; padding: 18px 10px; border-radius: 12px;
    border: 1px solid var(--panel-border); background: var(--surface-3);
    color: var(--text-light);
    /* La hauteur ne bouge pas d'une phase a l'autre : un cadre qui grandit au
       moment ou l'ordre parait deplace les boutons sous le pouce. */
    min-height: 92px; display: flex; align-items: center; justify-content: center;
}
.mel-ordre.mel-attente { font-size: 1rem; font-weight: 400; color: var(--muted); letter-spacing: 0; }
.mel-ordre.mel-frapper { color: #e8b04b; border-color: #e8b04b; }
.mel-ordre.mel-parer { color: #7fa8d8; border-color: #7fa8d8; }
/* « Ne bougez pas » se distingue des deux autres au premier coup d'oeil :
   c'est le seul ordre ou le bon geste est de n'en faire aucun. */
.mel-ordre.mel-immobile { color: #cf6a55; border-color: #cf6a55; }
.mel-ordre.mel-fin { font-size: 1.15rem; color: var(--gold-bright); border-color: var(--accent); }

.mel-gestes { display: flex; gap: 10px; }
.mel-btn {
    flex: 1; font-family: var(--font-ui); font-size: 1rem; font-weight: 700;
    padding: 18px 10px; border-radius: 12px; cursor: pointer;
    border: 1px solid var(--panel-border); background: var(--surface-3);
    color: var(--text-light);
    /* Une cible de pouce, et pas de delai de 300 ms sur telephone. */
    min-height: 62px; touch-action: manipulation;
}
.mel-btn:disabled { opacity: 0.4; cursor: default; }
.mel-b-frapper:not(:disabled) { border-color: #e8b04b; color: #e8b04b; }
.mel-b-parer:not(:disabled) { border-color: #7fa8d8; color: #7fa8d8; }
.mel-btn.mel-pris { background: var(--surface-2); opacity: 1; }

@media (max-width: 768px) {
    /* Au-dessus de la barre d'onglets du pouce, jamais dessous -- et au-dessus
       des travaux en cours, qui flottent eux aussi juste la. */
    .trn-bandeau {
        bottom: calc(66px + env(safe-area-inset-bottom) + var(--hauteur-travaux, 0px));
    }
    .trb-poutre { height: 68px; }
}


}
*::-webkit-scrollbar { width: 8px; height: 8px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
    background: var(--line-soft);
    border-radius: 4px;
    border: 2px solid transparent;
    background-clip: padding-box;
}
@media (hover: hover) and (pointer: fine) {
    *::-webkit-scrollbar-thumb:hover { background: var(--accent); background-clip: padding-box; }
}
/* Le formulaire des tournois, dans l'administration. Une colonne sur telephone,
   deux sur un ecran large : ce sont quatre champs qu'on lit de haut en bas. */
.trn-adm-form {
    display: grid;
    grid-template-columns: 1fr;
    gap: 10px;
    margin: 14px 0 18px;
    font-family: var(--font-ui);
    font-size: 0.82rem;
}
.trn-adm-form label { display: flex; flex-direction: column; gap: 4px; color: var(--muted); }
.trn-adm-form input, .trn-adm-form select {
    background: var(--surface-2);
    border: 1px solid var(--panel-border);
    color: var(--text-light);
    border-radius: 7px;
    padding: 8px 10px;
    font-family: var(--font-ui);
    font-size: 0.85rem;
}
/* L'apercu de l'heure du serveur. Il n'est pas decoratif : c'est lui qui rend
   l'ecart de fuseau VISIBLE, la ou un paragraphe d'avertissement se lit sans
   se voir. */
.trn-adm-apercu { font-size: 0.74rem; color: var(--gold-bright); min-height: 1em; }
.trn-adm-apercu.trn-adm-passe { color: var(--danger); }
.trn-adm-form label small { color: var(--muted); font-weight: normal; }

@media (min-width: 700px) { .trn-adm-form { grid-template-columns: 1fr 1fr; } }

/* Le coin entre deux barres, qui restait blanc lui aussi. */
*::-webkit-scrollbar-corner { background: transparent; }

/* ============================================================
   L'ESPION
   ============================================================ */

/* Le titre de la section des espions, dans l'onglet Recruter. Le compte et le
   resume vivent sur la meme ligne que le titre : c'est ce qu'on vient y lire,
   et une ligne de plus pour deux nombres serait du remplissage.
   **La mise en page tient sur sa propre classe, jamais sur `.mil-sub`** : neuf
   autres titres la portent, et passer un bloc en conteneur flex a `gap` fait
   de chaque noeud de texte un element -- c'est ainsi que `.mkt-taux` s'est
   retrouve a ecrire « 196 , dans 8 min . ». */
.mil-sub-esp { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.mil-sub-n {
    margin-left: auto;
    font-family: var(--font-ui);
    font-variant-numeric: tabular-nums; font-weight: 700;
    color: #c9a2ff;
}
.mil-sub-r {
    flex-basis: 100%;
    font-family: var(--font-ui); font-weight: 400;
    color: var(--muted, #aaa); font-size: 0.78rem;
}

/* La colonne de l'espion sur la carte : un violet franc, qu'aucune autre
   colonne ne porte. Elle n'est servie qu'a son maitre, donc elle n'a pas a se
   distinguer d'une couleur ennemie -- elle a a se distinguer des siennes. */
.map-soldier.espion { filter: drop-shadow(0 0 7px rgba(139, 63, 240, 0.85)); }

/* Et il a sa propre planche : un homme encapuchonne, pas le chevalier de la
   colonne d'assaut. Meme geometrie que `marche.webp` -- huit rangees de 128 px,
   seize images, la rangee en variable CSS -- donc il suffit de changer l'image
   de fond : la cadence, l'ancrage aux pieds et l'echelle restent ceux du
   chevalier, et l'espion marche exactement a la meme taille que les colonnes
   qui l'entourent.

   Il est volontairement SOMBRE : ce qui detache sa silhouette du vert de la
   carte, c'est le contre-jour cuit dans la planche et le halo violet ci-dessus,
   pas la luminosite -- un espion qu'on eclaircirait pour le rendre lisible
   cesserait de ressembler a un espion. */
.map-soldier.espion.animated { background-image: url('assets/espion_marche.webp?v=1'); }

/* Et la plaque qui la nomme : une couleur ne se lit pas toute seule.

   Elle se pose AU-DESSUS du compte a rebours, qui est lui-meme a `top: -22px` :
   les deux sont en absolu sur la meme vignette, et sans ce decalage la plaque
   tombait pile derriere l'horloge. Le meme defaut que les fanions de la carte,
   poses un a un a des hauteurs ecrites a la main. */
.map-soldier-tag {
    position: absolute; top: -50px; left: 50%;
    transform: translateX(-50%);
    display: inline-flex; align-items: center; gap: 5px;
    padding: 3px 9px; border-radius: 999px;
    background: rgba(24, 10, 44, 0.92);
    border: 1px solid #8b3ff0;
    box-shadow: 0 0 10px rgba(139, 63, 240, 0.55);
    color: #dcc4ff;
    font-family: var(--font-ui); font-size: 17px; font-weight: 700;
    white-space: nowrap; pointer-events: none;
}
.map-soldier-tag .mg-ic { width: 16px; height: 16px; }
/* Au loin, le compte a rebours disparait ; la plaque le suit, sinon elle
   descendrait toute seule sur une vignette de trois pixels. */
#worldmap-container.wm-far .map-soldier-tag { display: none; }

.wm-act-n {
    margin-left: auto; padding: 1px 7px; border-radius: 999px;
    background: rgba(139, 63, 240, 0.22); border: 1px solid rgba(139, 63, 240, 0.6);
    color: #dcc4ff; font-variant-numeric: tabular-nums; font-weight: 700;
}
.wm-act[disabled] { opacity: 0.45; cursor: not-allowed; }

/* La phrase qui dit OU former un espion. Elle vivait dans un `title` sur le
   bouton grise -- *une info-bulle survolee n'existe pas au doigt*, et c'est
   justement au doigt qu'on lit une carte. Elle se pose donc sous le bouton,
   et le bouton qui y mene en est un vrai : on sait exactement ou aller. */
.wm-act-aide {
    margin: -2px 0 0; padding: 0 2px;
    font-family: var(--font-ui); font-size: 0.72rem; line-height: 1.45;
    color: var(--muted, #9d9079);
}
.wm-act-lien {
    border: 0; background: none; padding: 0; cursor: pointer;
    font-family: var(--font-ui); font-size: inherit; font-weight: 700;
    color: var(--gold-bright, #e8c877); text-decoration: underline;
}@media (hover: hover) and (pointer: fine) {
.wm-act-lien:hover { color: #fff; }
}

/* La regle qui dit contre qui une victoire compte, sous la ligne des
   victoires de la Renaissance. C'est une precision, pas une condition de
   plus : elle se lit en retrait et en plus petit. */
.prestige-exigence {
    margin: 4px 0 0; padding-left: 4px;
    font-family: var(--font-ui); font-size: 0.72rem; line-height: 1.45;
    color: var(--muted, #9d9079);
}
.prestige-exigence .mg-ic { width: 13px; height: 13px; vertical-align: -0.12em; }

/* ============================================================
   LA DISETTE ET LES DESERTEURS
============================================================ */

/* Le fanion d'une bande sur la carte. Meme forme que celui d'un ralliement --
   ils vivent dans la meme colonne `.map-village-tags` --, mais en vert d'eau :
   ce ne sont pas des ennemis, ce sont des hommes a prendre. */
.map-deserteurs {
    display: flex; align-items: center; gap: 3px;
    background: rgba(8, 34, 32, 0.85);
    border: 1px solid rgba(95, 208, 192, 0.8);
    border-radius: 4px; padding: 1px 4px;
    color: #7fe3d4; font-size: 10px; white-space: nowrap;
}
.map-deserteurs .mg-ic { width: 11px; height: 11px; }
.wm-tag.deserteurs { color: #7fe3d4; }

/* Un refus se lit, donc il se voit. `.wm-act-aide` est grise par defaut --
   c'est une indication ; un motif de refus n'en est pas une. */
.wm-act-aide.wm-act-ko { color: var(--danger, #cf6a55); }

/* Le bandeau de disette du village. Il se pose au-dessus de la liste des
   troupes, la ou l'on decide -- pas dans un coin du bandeau de ressources, ou
   le taux en rouge dit deja qu'il manque du grain sans dire quoi faire. */
.mil-disette {
    margin: 0 0 12px; padding: 10px 12px; border-radius: 8px;
    background: rgba(70, 26, 18, 0.55);
    border: 1px solid rgba(207, 106, 85, 0.7);
    font-family: var(--font-ui); font-size: 0.8rem; line-height: 1.5;
    color: #f0c9bd;
}
.mil-disette b { color: #ffd9cd; }
.mil-disette .mg-ic { width: 1rem; height: 1rem; vertical-align: -0.15em; }

/* L'avertissement du recrutement : il n'empeche rien, il previent. D'ou le
   jaune et non le rouge -- former une armee qu'on nourrira au pillage est un
   choix, pas une faute. */
.mil-avert {
    margin: 8px 0 0; padding: 8px 10px; border-radius: 6px;
    background: rgba(70, 58, 14, 0.5);
    border: 1px solid rgba(214, 178, 74, 0.6);
    font-family: var(--font-ui); font-size: 0.76rem; line-height: 1.45;
    color: #e8d79a;
}

/* Le bouton de conge, dans « Mon armee ». Discret : ce n'est pas le geste
   qu'on vient faire dans cet onglet, c'est celui dont on a besoin le jour ou
   les greniers se vident. */
/* `.send-row` est une grille a TROIS colonnes : un quatrieme enfant tombe a la
   ligne, colonne de gauche, et le bouton se retrouvait sous le portrait au lieu
   d'etre au bout de sa ligne. Le compteur et le bouton partagent donc la
   troisieme cellule. */
.send-bout { display: flex; flex-direction: column; align-items: flex-end; gap: 6px; }

.mil-conge {
    padding: 3px 9px; border-radius: 5px;
    background: transparent; border: 1px solid rgba(207, 106, 85, 0.55);
    color: #cf9c8f; font-family: var(--font-ui); font-size: 0.7rem;
    cursor: pointer; white-space: nowrap;
}
.mil-conge:hover { background: rgba(207, 106, 85, 0.18); color: #f0c9bd; }

/* La fenetre du conge. Elle remplace un `prompt()` : une boite native ne se
   style pas, et elle ne savait dire ni qui partait ni ce que le grenier y
   gagnait. Le bouton porte le nombre -- c'est lui qu'on relit avant de
   cliquer, et c'est la seule confirmation. */
#modal-conge .mil-body { display: flex; flex-direction: column; gap: 14px; padding-bottom: 16px; font-family: var(--font-ui); }
.cg-tete { display: flex; align-items: center; gap: 12px; }
.cg-tete .portrait { flex-shrink: 0; }
.cg-qui { min-width: 0; }
.cg-nom { font-family: var(--font-title, inherit); font-size: 1.05rem; color: var(--text-light, #fff); }
.cg-sous { font-size: 0.78rem; color: var(--muted); margin-top: 2px; }
.cg-choix { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.cg-choix .stepper input { width: 72px; }
.cg-effet {
    display: flex; flex-direction: column; gap: 6px;
    padding: 10px 12px; border-radius: 8px;
    background: rgba(255, 255, 255, 0.035); border: 1px solid var(--panel-border);
    font-size: 0.82rem; line-height: 1.4;
}
.cg-effet .mg-ic { vertical-align: -0.2em; }
.cg-solde { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; color: var(--muted); font-variant-numeric: tabular-nums; }
.cg-solde b { font-size: 0.95rem; }
/* Le « avant -> apres » se lit d'un bloc : il passe a la ligne entier, jamais
   coupe entre la fleche et le second chiffre. */
.cg-valeurs { display: inline-flex; align-items: baseline; gap: 8px; white-space: nowrap; }
/* Le stepper rogne (`overflow: hidden`) : l'anneau de focus du navigateur n'en
   laissait que deux traits blancs. On le dessine a l'interieur. */
#conge-n:focus { outline: none; box-shadow: inset 0 0 0 1px var(--accent); }
.cg-pos { color: var(--success); }
.cg-neg { color: var(--danger); }
.cg-fleche { color: var(--muted); }
.cg-note { margin: 0; font-size: 0.75rem; line-height: 1.45; color: var(--muted); }
.cg-actions { display: flex; justify-content: flex-end; gap: 8px; flex-wrap: wrap; }
.cg-annuler, .cg-ok {
    padding: 8px 16px; border-radius: 7px; cursor: pointer;
    font-family: var(--font-ui); font-size: 0.85rem;
}
.cg-annuler { background: transparent; border: 1px solid var(--panel-border); color: var(--muted); }
.cg-annuler:hover { color: var(--text-light, #fff); border-color: var(--accent); }
.cg-ok {
    background: rgba(207, 106, 85, 0.16); border: 1px solid rgba(207, 106, 85, 0.7);
    color: #f0c9bd; font-weight: 600;
}
.cg-ok:hover:not(:disabled) { background: rgba(207, 106, 85, 0.3); color: #fff; }
.cg-ok:disabled { opacity: .5; cursor: not-allowed; }

/* =======================================================================
   La Horde : le chef d'un camp, ce qu'il avait en tete, et l'aide
   -----------------------------------------------------------------------
   Trois caracteres, trois couleurs -- et le nom toujours ecrit a cote de la
   couleur : une teinte seule exclut qui ne les distingue pas, et rien dans
   le jeu n'apprend que l'ambre veut dire « prudent ».
   ======================================================================= */
:root {
    --horde-prudent: #8fb3d9;
    --horde-pillard: #d9b25f;
    --horde-rancunier: #e07a5f;
}

/* La fiche du chef, sur la carte. */
.wm-chef {
    display: flex; flex-direction: column; gap: 5px;
    padding: 9px 11px; border-radius: 8px;
    background: rgba(255,255,255,0.04);
    border: 1px solid rgba(255,255,255,0.1);
    border-left: 3px solid var(--chef, var(--accent));
    font-size: 0.8rem; line-height: 1.4;
    margin-bottom: 10px;
}
.wm-chef-prudent   { --chef: var(--horde-prudent); }
.wm-chef-pillard   { --chef: var(--horde-pillard); }
.wm-chef-rancunier { --chef: var(--horde-rancunier); }
.wm-chef-tete { display: flex; align-items: center; gap: 7px; color: var(--chef); font-family: var(--font-title); font-size: 0.88rem; }
.wm-chef-tete .mg-ic { width: 17px; height: 17px; flex-shrink: 0; }
.wm-chef-tete > span { flex: 1; min-width: 0; }
.wm-chef-tete b { font-weight: 700; }
.wm-chef-aide {
    width: 22px; height: 22px; border-radius: 50%; flex-shrink: 0;
    border: 1px solid rgba(255,255,255,0.22); background: transparent;
    color: rgba(242,233,214,0.8); font-size: 0.75rem; cursor: pointer; line-height: 1;
}
.wm-chef-aide:hover { border-color: var(--chef); color: #fff; }
.wm-chef-devise { color: rgba(242,233,214,0.78); }
.wm-chef-rancune { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 8px; color: #f0c2b4; }
.wm-chef-rancune small { flex-basis: 100%; color: rgba(242,233,214,0.55); font-size: 0.72rem; }
.wm-chef-rancune.calme { color: rgba(242,233,214,0.6); }

/* Les crans de rancune : pleins et vides, lisibles sans la couleur. */
.hr-pips { display: inline-flex; gap: 3px; vertical-align: middle; }
.hr-pip {
    width: 9px; height: 9px; border-radius: 50%;
    border: 1px solid rgba(224,122,95,0.7); background: transparent;
}
.hr-pip.on { background: var(--horde-rancunier); border-color: var(--horde-rancunier); box-shadow: 0 0 5px rgba(224,122,95,0.55); }

/* « Ce que le chef avait en tete », sous un rapport de defense. */
.hr-bloc {
    margin-top: 9px; padding: 10px 12px; border-radius: 8px;
    background: linear-gradient(180deg, rgba(90,40,30,0.28), rgba(40,25,20,0.2));
    border: 1px solid rgba(224,122,95,0.28);
    font-family: var(--font-ui); font-size: 0.84rem; line-height: 1.45;
}
.hr-tete { display: flex; align-items: center; justify-content: space-between; gap: 8px; flex-wrap: wrap; margin-bottom: 6px; }
.hr-titre { font-family: var(--font-title); color: #f2d7c9; font-size: 0.92rem; display: inline-flex; align-items: center; gap: 6px; }
.hr-titre .mg-ic { width: 16px; height: 16px; }
.hr-badge {
    font-size: 0.7rem; letter-spacing: 0.04em; text-transform: uppercase;
    padding: 2px 8px; border-radius: 999px; border: 1px solid currentColor;
}
.hr-prudent { color: var(--horde-prudent); }
.hr-pillard { color: var(--horde-pillard); }
.hr-rancunier { color: var(--horde-rancunier); }
.hr-lignes { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 5px; }
.hr-lignes li { display: grid; grid-template-columns: 18px 1fr; gap: 8px; align-items: start; color: rgba(242,233,214,0.86); }
.hr-lignes li > .mg-ic { width: 16px; height: 16px; margin-top: 2px; opacity: 0.85; }
.hr-lignes b { color: #fff; }
.hr-lien {
    margin-top: 8px; padding: 0; background: none; border: none; cursor: pointer;
    color: var(--gold, #d4a548); font-family: var(--font-ui); font-size: 0.8rem; text-align: left;
}
.hr-lien:hover { text-decoration: underline; }

/* La fenetre d'aide « La Horde ». */
#modal-horde .mil-body { font-family: var(--font-ui); font-size: 0.88rem; line-height: 1.55; color: rgba(242,233,214,0.88); }
.hd-intro { margin: 0 0 4px; }
.hd-h {
    display: flex; align-items: center; gap: 8px;
    margin: 18px 0 8px; font-family: var(--font-title); font-size: 0.98rem; color: var(--gold-bright, #f0c96b);
}
.hd-h .mg-ic { width: 18px; height: 18px; }
.hd-etapes { margin: 0; padding-left: 20px; display: flex; flex-direction: column; gap: 6px; }
.hd-cartes { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 10px; }
.hd-carte {
    display: flex; flex-direction: column; gap: 6px; min-width: 0;
    padding: 11px 12px; border-radius: 9px;
    background: rgba(255,255,255,0.035);
    border: 1px solid rgba(255,255,255,0.09);
    border-top: 3px solid var(--chef, var(--accent));
}
.hd-prudent { --chef: var(--horde-prudent); }
.hd-pillard { --chef: var(--horde-pillard); }
.hd-rancunier { --chef: var(--horde-rancunier); }
.hd-carte-tete { display: flex; align-items: center; gap: 7px; color: var(--chef); font-family: var(--font-title); font-size: 0.95rem; }
.hd-carte-tete .mg-ic { width: 18px; height: 18px; }
.hd-devise { margin: 0; font-style: italic; color: rgba(242,233,214,0.75); font-size: 0.82rem; }
.hd-traits { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 3px; font-size: 0.78rem; }
/* L'intitule AU-DESSUS de la valeur : cote a cote, sur trois colonnes, les
   deux se coupaient chacun en deux lignes et ne se lisaient plus ensemble. */
.hd-traits li { display: flex; flex-direction: column; gap: 1px; border-bottom: 1px dashed rgba(255,255,255,0.07); padding-bottom: 4px; }
.hd-traits li span { color: rgba(242,233,214,0.55); font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.04em; }
.hd-traits li b { color: #f2e9d8; font-weight: 600; }
.hd-parade { margin: 2px 0 0; font-size: 0.8rem; color: rgba(242,233,214,0.85); }
.hd-parade .mg-ic { width: 14px; height: 14px; vertical-align: -0.2em; }
.hd-paliers { display: flex; flex-wrap: wrap; gap: 6px; margin: 4px 0; }
.hd-palier {
    display: inline-flex; flex-direction: column; align-items: center; min-width: 52px;
    padding: 5px 8px; border-radius: 7px; background: rgba(255,255,255,0.04); border: 1px solid rgba(255,255,255,0.1);
    font-variant-numeric: tabular-nums; font-size: 0.95rem; color: #fff;
}
.hd-palier b { font-size: 0.66rem; font-weight: 500; color: rgba(242,233,214,0.55); text-transform: uppercase; letter-spacing: 0.05em; }
.hd-palier b::before { content: "Palier "; }
.hd-note { margin: 4px 0 0; font-size: 0.78rem; color: rgba(242,233,214,0.6); }
.hd-garde { margin: 0; padding-left: 20px; display: flex; flex-direction: column; gap: 4px; }
/* `.conq-body` est une colonne flex a `gap` de 16 px : chaque titre y etait
   detache de sa section par un vide aussi grand qu'entre deux sections. Ici
   les titres tiennent ce qu'ils annoncent, donc le flux redevient un bloc et
   ce sont les marges qui rythment. */
#modal-horde .conq-body { display: block; }
#modal-horde .mil-body p { margin: 0 0 8px; }
#modal-horde .mil-body .hd-h { margin: 18px 0 8px; }
#modal-horde .mil-body ol, #modal-horde .mil-body ul { margin-top: 0; }

/* =========================================================================
   Premiers pas (tuto.js) : un projecteur, une bulle.

   **Le voile est l'ombre du cercle**, pas un calque : `pointer-events: none`
   partout, donc le jeu reste cliquable -- le guide montre, il n'enferme pas.
   Le cercle glisse d'une cible a l'autre par `transform` ; ses seules
   animations continues (le pouls et la fleche des etapes d'action) ne
   touchent que `transform` et `opacity`, la regle de « La batterie du
   telephone ».
   ========================================================================= */
#pp-cercle {
    position: fixed; left: 0; top: 0; z-index: 9400;
    width: 0; height: 0;
    border-radius: 12px;
    border: 2px solid var(--gold-bright);
    box-shadow: 0 0 0 200vmax rgba(8, 6, 4, 0.62), 0 0 18px rgba(240, 198, 116, 0.55);
    pointer-events: none;
    transition: transform 0.45s cubic-bezier(.2,.8,.2,1), width 0.45s cubic-bezier(.2,.8,.2,1),
                height 0.45s cubic-bezier(.2,.8,.2,1), opacity 0.25s, border-color 0.3s;
}
/* Une etape sans cible : le voile reste, le trou se referme au centre. */
#pp-cercle.seul {
    width: 0; height: 0; border-color: transparent;
    transform: translate(50vw, 50vh);
    box-shadow: 0 0 0 200vmax rgba(8, 6, 4, 0.62);
}
#pp-cercle.pp-action::after {
    content: ''; position: absolute; inset: -3px;
    border: 2px solid var(--gold-bright); border-radius: 14px;
    animation: ppPouls 1.6s ease-out infinite;
}
/* La fleche qui dit « ici » sur une etape ou il faut agir. */
#pp-cercle.pp-action::before {
    content: ''; position: absolute; left: 50%; top: -26px;
    width: 0; height: 0; margin-left: -9px;
    border-left: 9px solid transparent; border-right: 9px solid transparent;
    border-top: 12px solid var(--gold-bright);
    filter: drop-shadow(0 2px 3px rgba(0,0,0,0.6));
    animation: ppFleche 0.9s ease-in-out infinite alternate;
}
#pp-cercle.pp-reussi { border-color: var(--success); }
#pp-cercle.pp-reussi::after, #pp-cercle.pp-reussi::before { animation: none; opacity: 0; }
@keyframes ppPouls {
    from { transform: scale(1); opacity: 0.9; }
    to   { transform: scale(1.18); opacity: 0; }
}
@keyframes ppFleche {
    from { transform: translateY(-4px); }
    to   { transform: translateY(4px); }
}

#pp-bulle {
    position: fixed; left: 0; top: 0; z-index: 9500;
    box-sizing: border-box;
    background: #1a1510;
    border: 2px solid var(--panel-border);
    border-radius: var(--radius);
    box-shadow: 0 16px 44px rgba(0,0,0,0.8), inset 0 0 20px rgba(212,165,72,0.05);
    padding: 12px 14px 14px;
    color: var(--text-light);
    font-family: var(--font-ui);
    transition: transform 0.45s cubic-bezier(.2,.8,.2,1), opacity 0.25s;
}
#pp-bulle.pp-action { border-color: var(--accent); }
/* L'entree joue sur `scale`, la propriete a part : `transform` porte deja la
   position, et une animation qui le reecrirait la ferait sauter en haut a
   gauche le temps de l'animation. */
#pp-bulle.pp-entre { animation: ppEntre 0.32s ease-out; }
@keyframes ppEntre {
    from { opacity: 0; scale: 0.94; }
    to   { opacity: 1; scale: 1; }
}
#pp-cercle.pp-cache, #pp-bulle.pp-cache { opacity: 0; visibility: hidden; }

.pp-tete { display: flex; align-items: center; gap: 8px; }
.pp-ico { color: var(--gold-bright); display: inline-flex; }
.pp-ico .mg-ic { width: 18px; height: 18px; }
.pp-quand {
    flex: 1; font-size: 0.68rem; letter-spacing: 0.06em; text-transform: uppercase;
    color: var(--muted); font-variant-numeric: tabular-nums;
}
.pp-barre { height: 3px; margin: 8px 0 10px; background: var(--line-soft); border-radius: 2px; overflow: hidden; }
.pp-barre i {
    display: block; height: 100%; background: var(--accent);
    transform-origin: left; transition: transform 0.45s ease;
}
#pp-bulle h3 {
    margin: 0 0 6px; font-family: var(--font-title); font-size: 1rem;
    color: var(--gold-bright); line-height: 1.3; text-wrap: balance;
}
.pp-avous {
    display: inline-block; vertical-align: 2px; margin-right: 4px;
    font-family: var(--font-ui); font-size: 0.6rem; font-weight: 700; letter-spacing: 0.08em;
    text-transform: uppercase; color: #1c1408; background: var(--gold-bright);
    border-radius: 4px; padding: 2px 6px;
}
.pp-texte { font-size: 0.84rem; line-height: 1.55; }
.pp-texte b { color: var(--gold-bright); }
.pp-attente {
    margin-top: 10px; padding: 8px 10px; border-radius: var(--radius-sm);
    background: var(--surface-2); border: 1px solid var(--line-soft);
    font-size: 0.78rem; color: var(--muted); font-variant-numeric: tabular-nums;
}
.pp-attente b { color: var(--text-light); }
.pp-bravo {
    display: flex; align-items: center; gap: 8px; margin-top: 10px;
    color: var(--success); font-weight: 700; font-size: 0.9rem;
    animation: ppBravo 0.4s cubic-bezier(.2,1.4,.4,1);
}
.pp-bravo .mg-ic { width: 18px; height: 18px; }
.pp-bravo[hidden], .pp-attente[hidden] { display: none; }
@keyframes ppBravo {
    from { transform: scale(0.6); opacity: 0; }
    to   { transform: scale(1); opacity: 1; }
}
.pp-pied { display: flex; align-items: center; justify-content: flex-end; gap: 10px; margin-top: 12px; }
.pp-pied .btn-bar { height: 36px; }
.pp-lien {
    background: none; border: 0; padding: 6px 2px; cursor: pointer;
    font-family: inherit; font-size: 0.76rem; color: var(--muted);
    text-decoration: underline; text-underline-offset: 3px;
}
.pp-lien:first-child { margin-right: auto; }
.pp-lien:hover { color: var(--text-light); }

/* Le voile retire : une etape longue repliee n'assombrit plus rien. */
#pp-cercle.pp-hors { opacity: 0; visibility: hidden; }

/* **La pastille d'une etape longue.** Rassembler une armee prend des heures :
   le guide se tient dans un coin, sous le bandeau, avec le seul chiffre qui
   compte. Elle se cache des qu'une fenetre s'ouvre -- sur telephone les
   fenetres prennent tout l'ecran, et elle tomberait sur leur croix. */
#pp-bulle.pp-pilule {
    left: auto; right: 12px;
    top: calc(var(--hauteur-bandeau, 80px) + 8px);
    width: auto; max-width: calc(100vw - 24px);
    padding: 0; display: flex; align-items: stretch;
    border-color: var(--accent); border-radius: 999px;
    transform: none;
}
.pp-pil-corps {
    display: flex; align-items: center; gap: 8px;
    background: none; border: 0; cursor: pointer;
    padding: 7px 4px 7px 12px; color: var(--text-light);
    font-family: var(--font-ui); font-size: 0.8rem; font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
.pp-pil-corps b { color: var(--gold-bright); }
.pp-pil-x {
    background: none; border: 0; cursor: pointer; color: var(--muted);
    padding: 0 12px 0 8px; font-size: 0.8rem;
}
.pp-pil-x:hover { color: var(--text-light); }

/* Le menu des guides. */
.pp-choix-liste { display: flex; flex-direction: column; gap: 8px; margin-top: 4px; }
.pp-choix {
    display: grid; grid-template-columns: 1fr auto; gap: 2px 10px; align-items: baseline;
    text-align: left; cursor: pointer;
    background: var(--surface-2); border: 1px solid var(--line-soft); border-radius: var(--radius-sm);
    padding: 10px 12px; color: var(--text-light); font-family: var(--font-ui);
}
.pp-choix:hover { border-color: var(--accent); }
.pp-choix b { font-family: var(--font-title); color: var(--gold-bright); font-size: 0.92rem; }
.pp-choix span { grid-column: 1; font-size: 0.78rem; color: var(--muted); }
.pp-choix em {
    grid-column: 2; grid-row: 1 / span 2; align-self: center;
    font-style: normal; font-size: 0.7rem; color: var(--muted);
    max-width: 118px; text-align: right; justify-self: end;
    display: inline-flex; align-items: center; gap: 4px;
}
.pp-choix em .mg-ic { width: 14px; height: 14px; color: var(--success); }

@media (prefers-reduced-motion: reduce) {
    #pp-cercle, #pp-bulle { transition: none; }
    #pp-cercle.pp-action::after, #pp-cercle.pp-action::before,
    #pp-bulle.pp-entre, .pp-bravo { animation: none; }
}

/* ============================================================================
   LA MERVEILLE DE GUILDE — sur la carte et dans la fenetre de guilde.
   ========================================================================= */

/* Plus large qu'un village : c'est un chantier de deux cases, et il doit se
   reconnaitre de loin. Les six images partagent un meme cadre (360 x 277), donc
   la boite garde ce rapport et le chantier pousse sur place. */
.map-village.merveille { width: 200px; height: 154px; }
.map-merveille {
    display: flex; align-items: center; gap: 3px;
    background: rgba(40, 30, 10, 0.85);
    border: 1px solid rgba(240, 198, 116, 0.85);
    border-radius: 4px; padding: 1px 4px;
    color: #f0c674; font-size: 10px; white-space: nowrap;
}
.map-merveille .mg-ic { width: 11px; height: 11px; }
/* La premiere couronnee de la saison : la seule victoire qui se lise sur le
   terrain, donc la seule plaque qui change de couleur. */
.map-merveille.premiere { background: rgba(70, 40, 90, 0.92); border-color: #e8c86a; color: #ffe08a; }

/* La duree d'un chantier deja reduite par la merveille : la pastille dit
   pourquoi il est plus court que la veille. */
.merv-gain { color: #8fd18f; font-size: 0.75em; font-weight: 600; }
.merv-gains li.fait { color: #8fd18f; }
.merv-gains li.fait b { color: inherit; }
.merv-moi { font-family: var(--font-ui); font-size: 0.82rem; line-height: 1.45; margin: 4px 0 8px; padding: 8px 10px; border-radius: 6px; border: 1px solid; }
.merv-moi.ok { background: rgba(120, 200, 120, 0.08); border-color: rgba(120, 200, 120, 0.35); }
.merv-moi.attente { background: rgba(240, 198, 116, 0.08); border-color: rgba(240, 198, 116, 0.35); }
.merv-victoire { font-family: var(--font-ui); font-size: 0.82rem; line-height: 1.45; margin: 0; }
.merv-victoire .mg-ic, .pan-merveille .mg-ic { width: 15px; height: 15px; vertical-align: -3px; color: #f0c674; }
/* Le siege : ce qui marche sur elle, ce qui vient la tenir. */
.merv-siege.alerte { border-color: rgba(224, 106, 85, 0.65); background: linear-gradient(180deg, rgba(90, 24, 16, 0.35), rgba(0, 0, 0, 0)); }
.merv-menace, .merv-secours { font-family: var(--font-ui); font-size: 0.85rem; margin: 6px 0; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.merv-menace { color: #ffcfc4; }
.merv-menace .mg-ic { color: #e06a55; }
.merv-secours { color: #bfe6bf; }
.merv-phase.repit { background: rgba(143, 179, 217, 0.1); border-color: rgba(143, 179, 217, 0.4); margin-top: 8px; }
.merv-compte { margin-left: auto; font-family: var(--font-ui); font-size: 0.8rem; color: var(--muted); }
.merv-troupes-ligne { display: block; color: var(--muted); font-size: 0.75rem; margin-top: 2px; }
/* Les volets repliables : la garnison et l'escorte ne se deplient que pour
   qui en a l'usage, sinon l'onglet s'allonge de deux formulaires. */
.merv-volet { margin-top: 10px; border: 1px solid rgba(212, 165, 72, 0.25); border-radius: 8px; padding: 0 12px; }
.merv-volet[open] { padding-bottom: 10px; }
.merv-volet summary { cursor: pointer; padding: 10px 0; font-family: var(--font-ui); font-size: 0.85rem; font-weight: 600; color: var(--gold-bright, #f0c674); list-style: none; display: flex; align-items: center; gap: 6px; }
.merv-volet summary::-webkit-details-marker { display: none; }
.merv-volet summary::after { content: '▸'; margin-left: auto; color: var(--muted); transition: transform .15s; }
.merv-volet[open] summary::after { transform: rotate(90deg); }
.merv-troupes { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 8px; margin: 8px 0; }
.merv-troupe { display: flex; align-items: center; gap: 10px; padding: 6px 8px; border-radius: 8px; background: rgba(255, 255, 255, 0.03); border: 1px solid rgba(255, 255, 255, 0.06); min-width: 0; }
.merv-troupe .portrait { width: 40px; height: 40px; flex: 0 0 40px; }
.merv-troupe .portrait img { width: 100%; height: 100%; object-fit: contain; }
.merv-troupe-nom { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; font-family: var(--font-ui); font-size: 0.8rem; }
.merv-troupe-nom small { color: var(--muted); }
.merv-troupe input { width: 84px; flex: 0 0 84px; }
/* Le rappel est un retrait, pas l'action de l'onglet : il ne prend pas l'or. */
.merv-rappel { background: transparent; color: var(--ink2, #cdbf9f); border: 1px solid rgba(255, 255, 255, 0.18); border-radius: 8px;
    padding: 7px 12px; font-family: var(--font-ui); font-size: 0.82rem; cursor: pointer; }
.merv-rappel:hover { border-color: rgba(240, 198, 116, 0.5); color: var(--gold-bright, #f0c674); }
.merv-film { padding: 0; overflow: hidden; }
.merv-film img { display: block; width: 100%; height: auto; }
.pan-merveille { font-family: var(--font-ui); font-size: 0.78rem; color: #f0c674; }
.wm-tag.merveille { color: #f0c674; }

.merv-corps { display: flex; flex-direction: column; gap: 12px; }
.merv-intro, .merv-tete { display: flex; flex-wrap: wrap; gap: 16px; align-items: center; }
.merv-img { width: 240px; max-width: 100%; height: auto; flex: 0 0 auto; }
.merv-intro-texte, .merv-tete-texte { flex: 1 1 260px; min-width: 0; }
.merv-p { font-family: var(--font-ui); font-size: 0.85rem; line-height: 1.5; margin: 0 0 8px; }
.merv-etages { font-family: var(--font-ui); font-size: 0.8rem; margin: 6px 0 12px 18px; padding: 0; }
.merv-etages li { margin: 2px 0; }
.merv-etages span { color: var(--muted); }
.merv-aide { font-family: var(--font-ui); font-size: 0.78rem; color: var(--muted); margin: 6px 0 0; }
.merv-aide.ko { color: var(--danger, #cf6a55); }
.merv-aide.ok { color: var(--success, #7fc47f); }
/* Le choix de l'emplacement : des cases proposees, la carte, ou les coordonnees. */
.merv-place { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }
.merv-place-t { font-family: 'Cinzel', serif; color: var(--gold-bright, #f0c674); font-size: 0.95rem; }
.merv-place .merv-aide { margin: 0; }
.merv-sugg-liste { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 8px; }
.merv-sugg {
    display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
    text-align: left; cursor: pointer;
    padding: 9px 11px; border-radius: 10px;
    background: rgba(255,255,255,0.04);
    border: 1px solid var(--panel-border, rgba(255,255,255,0.14));
    color: inherit; font-family: var(--font-ui); font-size: 0.82rem;
}
.merv-sugg:hover { border-color: var(--accent, #d4a548); }
.merv-sugg small { color: var(--muted); font-size: 0.74rem; font-variant-numeric: tabular-nums; }
.merv-sugg-carte b { color: var(--gold-bright, #f0c674); }
.merv-place-xy { display: flex; gap: 10px; flex-wrap: wrap; }
.merv-place-xy label { display: flex; align-items: center; gap: 6px; font-family: var(--font-ui); font-size: 0.85rem; color: var(--muted); }
.merv-place-xy input { width: 90px; flex: 0 0 90px; font-variant-numeric: tabular-nums; }
.merv-volet > summary { cursor: pointer; list-style: none; margin-top: 0; }
.merv-volet > summary::-webkit-details-marker { display: none; }
.merv-volet > summary::after { content: ' ▾'; color: var(--muted); }
.merv-volet[open] > summary::after { content: ' ▴'; }

.merv-etage { font-size: 1.8rem; font-weight: 700; color: var(--gold-bright, #f0c674); line-height: 1.1; margin: 4px 0 8px; }
.merv-etage small { font-family: var(--font-ui); font-size: 0.78rem; font-weight: 400; color: var(--muted); }
.merv-phase { font-family: var(--font-ui); font-size: 0.85rem; line-height: 1.45; padding: 8px 10px; border-radius: 6px;
              background: rgba(240, 198, 116, 0.08); border: 1px solid rgba(240, 198, 116, 0.25); }
.merv-phase small { display: block; color: var(--muted); margin-top: 3px; }
.merv-phase .mg-ic { width: 16px; height: 16px; vertical-align: -3px; }
.merv-phase.achevee { background: rgba(120, 200, 120, 0.1); border-color: rgba(120, 200, 120, 0.35); }

/* Une seule grille pour toutes les lignes : chaque ligne en etait une, et la
   colonne des chiffres, plus ou moins large selon le montant, decalait le
   depart de chaque barre. Des barres qu'on compare doivent partir du meme
   bord. */
.merv-quota { display: grid; grid-template-columns: 7.5rem 1fr auto; gap: 8px 10px; align-items: center;
              font-family: var(--font-ui); font-size: 0.8rem; }
.merv-res { display: contents; }
.merv-res-nom { white-space: nowrap; }
.merv-res-n { white-space: nowrap; font-variant-numeric: tabular-nums; text-align: right; }
.merv-res-n small { color: var(--muted); }
.merv-barre { display: flex; height: 10px; border-radius: 5px; overflow: hidden;
              background: rgba(255, 255, 255, 0.08); }
.merv-barre i { display: block; height: 100%; }
.merv-barre i.stock { background: linear-gradient(90deg, #b98a3a, #f0c674); }
/* Ce qui roule encore : hachure, comme la part que prendra un echange dans la
   jauge du marchand du roi. On voit ce qui manquera une fois tout arrive. */
.merv-barre i.route { background: repeating-linear-gradient(45deg, rgba(240,198,116,0.55) 0 4px, rgba(240,198,116,0.15) 4px 8px); }
.merv-res.ok .merv-barre i.stock { background: linear-gradient(90deg, #5a9a52, #8fd17f); }
@media (max-width: 480px) {
    .merv-quota { display: flex; flex-direction: column; align-items: stretch; gap: 10px; }
    .merv-res { display: grid; grid-template-columns: 1fr auto; gap: 4px 10px; align-items: center; }
    .merv-res .merv-barre { grid-column: 1 / -1; order: 3; }
}

.merv-convoi { font-family: var(--font-ui); font-size: 0.82rem; padding: 6px 8px; margin-bottom: 8px;
               border-radius: 6px; background: rgba(255, 255, 255, 0.05); }
.merv-champs { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 8px; }
.merv-champ { display: flex; flex-direction: column; gap: 4px; font-family: var(--font-ui); font-size: 0.78rem; min-width: 0; }
.merv-champ small { color: var(--muted); }
.merv-champ .mkt-input { width: 100%; box-sizing: border-box; }
.merv-boutons { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.merv-boutons .btn-res { flex: 1 1 160px; }
.merv-table tr.moi td { color: var(--gold-bright, #f0c674); }
.merv-reserve { display: block; margin-top: 2px; font-size: .78em; color: var(--text-muted, #a89a80); }
.merv-reserve img, .merv-reserve svg { width: 13px; height: 13px; vertical-align: -2px; }

/* Le ralliement nomme le village de chaque engagement : un engagement se prend
   par village, et chaque appareil garde son propre village actif. */
.rall-village { display: block; color: var(--muted); font-size: 0.74rem; }
.rall-ailleurs {
    display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
    margin: 0 0 10px; padding: 8px 10px; border-radius: 8px;
    background: rgba(255,255,255,0.04); border: 1px solid var(--panel-border, rgba(255,255,255,0.14));
    font-family: var(--font-ui); font-size: 0.82rem; line-height: 1.4;
}
.rall-ailleurs > span { flex: 1 1 200px; min-width: 0; }

/* =======================================================================
   La fiche d'un soldat (1.25.15)
   Le bouton vit dans la ligne du nom : il ne prend pas de place a lui, et il
   se voit au doigt -- une info-bulle n'existe pas sur un telephone.
   ======================================================================= */
.troop-fiche {
    margin-left: auto; display: inline-flex; align-items: center; gap: 4px;
    font-family: var(--font-ui); font-size: 0.62rem; font-weight: 700;
    letter-spacing: 0.03em; text-transform: uppercase;
    padding: 3px 8px; border-radius: 999px; cursor: pointer;
    color: var(--gold-bright); background: rgba(212,165,72,.08);
    border: 1px solid var(--panel-border);
}
.troop-fiche .mg-ic { width: 13px; height: 13px; }
.troop-fiche b { color: var(--text-light); font-weight: 800; }
.troop-fiche:hover, .troop-fiche:focus-visible { background: rgba(212,165,72,.18); }

/* La scene. Un cadre de hauteur FIXE : le modele s'y ajuste, et la fiche ne
   saute pas quand il arrive. `touch-action: none` laisse le doigt tourner le
   modele au lieu de faire defiler la fenetre -- le defilement reste possible
   partout ailleurs dans la fiche. */
.sd-scene {
    position: relative; height: min(46vh, 360px); margin-bottom: 8px;
    border-radius: var(--radius); border: 1px solid var(--line-soft); overflow: hidden;
    background: radial-gradient(ellipse at 50% 85%, rgba(212,165,72,.16), transparent 62%),
                radial-gradient(ellipse at 50% 30%, var(--surface), rgba(0,0,0,.25));
    display: flex; align-items: center; justify-content: center;
}
.sd-scene.sd-3d { touch-action: none; cursor: grab; }
.sd-scene.sd-3d:active { cursor: grabbing; }
.sd-scene canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.sd-portrait { max-height: 92%; max-width: 92%; object-fit: contain; }
.sd-portrait-ic .mg-ic { width: 72px; height: 72px; }
.sd-charge {
    position: absolute; inset: 0; display: flex; flex-direction: column;
    align-items: center; justify-content: center; gap: 8px;
    font-family: var(--font-ui); font-size: 0.72rem; color: var(--muted);
}
.sd-charge .sd-portrait { max-height: 78%; opacity: .45; filter: grayscale(.4); }
.sd-aide {
    margin: 0 0 10px; font-family: var(--font-ui); font-size: 0.7rem; color: var(--muted);
    display: flex; align-items: center; gap: 5px;
}
.sd-aide .mg-ic { width: 13px; height: 13px; }

/* La force d'un camp de la Horde, sur sa fiche : le mot porte le sens, la
   couleur ne fait que le souligner. */
.wm-stat .wm-force-faible { color: #8fc58a; }
.wm-stat .wm-force-redoutable { color: #e07a5f; font-weight: 700; }

/* iOS zoome sur tout champ dont le texte fait moins de 16 px des qu'il prend
   le focus, et ne dezoome jamais seul. On ne bloque pas le pincement
   (`maximum-scale=1` le couperait sur Android) : on donne aux champs la taille
   qui ne declenche rien. Le garde `-webkit-touch-callout` borne la regle a iOS,
   le seul a zoomer -- Android et l'ordinateur gardent leur mise en page. */
@media (pointer: coarse) {
    @supports (-webkit-touch-callout: none) {
        input, select, textarea { font-size: max(16px, 1em) !important; }
    }
}

/* iOS 26 floute une bande sous la barre d'etat, par-dessus la page, et elle
   deborde de quelques pixels : le pseudo, premiere ligne du bandeau, y tombait.
   On descend le bandeau hors de cette bande, sur l'application installee
   seulement -- dans Safari, la barre du navigateur est au-dessus et rien ne
   floute la page. La feuille lit la hauteur MESUREE du bandeau, elle suit. */
@media (max-width: 768px) and (display-mode: standalone) {
    @supports (-webkit-touch-callout: none) {
        #top-bar { padding-top: max(22px, calc(env(safe-area-inset-top) + 14px)); }
    }
}

/* =====================================================================
   Le sondage du royaume
   ===================================================================== */
/* Un `display` pose par une classe l'emporte sur l'attribut `hidden` : sans
   cette ligne, le bouton et sa pastille ne partiraient jamais. */
.sys-tuile[hidden], .sys-pastille[hidden] { display: none; }
.sys-pastille {
    position: absolute; top: 7px; right: 8px; width: 8px; height: 8px; border-radius: 50%;
    background: var(--danger); box-shadow: 0 0 0 2px var(--surface);
}
.sdg-carte { display: flex; flex-direction: column; gap: 12px; }
.sdg-carte + .sdg-carte { padding-top: 16px; border-top: 1px solid var(--line-soft); }
.sdg-tete {
    display: flex; align-items: center; gap: 8px; color: var(--muted);
    font-size: 0.72rem; letter-spacing: 0.06em; text-transform: uppercase;
}
.sdg-tete .mg-ic { width: 18px; height: 18px; color: var(--gold-bright); }
.sdg-question {
    margin: 0; font-family: var(--font-title); font-size: 1.05rem; line-height: 1.35;
    color: var(--text-light); text-wrap: balance;
}
.sdg-opts { display: flex; flex-direction: column; gap: 8px; }
.sdg-opt {
    display: flex; align-items: center; gap: 10px; min-height: 44px; padding: 8px 12px;
    background: var(--surface); border: 1px solid var(--line-soft); border-radius: var(--radius-sm);
    cursor: pointer; font-size: 0.86rem; color: var(--text-light);
}
.sdg-opt.on { border-color: var(--accent); background: rgba(212,165,72,0.08); }
.sdg-opt input[type="radio"] { accent-color: var(--accent); width: 18px; height: 18px; flex-shrink: 0; margin: 0; }
.sdg-opt > span { min-width: 0; overflow-wrap: anywhere; }
.sdg-autre input[type="text"] {
    flex: 1; min-width: 0; height: 32px; padding: 0 10px;
    background: rgba(0,0,0,0.25); border: 1px solid var(--panel-border); border-radius: 6px;
    color: var(--text-light); font-family: var(--font-ui); font-size: 0.84rem;
}
.sdg-pied { display: flex; align-items: center; flex-wrap: wrap; gap: 10px 14px; }
.sdg-info { font-size: 0.75rem; color: var(--muted); }
.sdg-mien { margin: 0; font-size: 0.8rem; color: var(--success); }
.sdg-mien:empty, .sdg-refus:empty { display: none; }
.sdg-refus { margin: 0; font-size: 0.8rem; color: var(--danger); }
.sdg-vide { margin: 0; color: var(--muted); font-size: 0.85rem; }
.sdg-res { display: flex; flex-direction: column; gap: 4px; }
.sdg-res-l { display: flex; justify-content: space-between; gap: 12px; font-size: 0.84rem; color: var(--text-light); }
.sdg-res-l span { min-width: 0; overflow-wrap: anywhere; }
.sdg-res-l b { font-variant-numeric: tabular-nums; color: var(--muted); }
.sdg-res-l em { font-style: normal; font-size: 0.7rem; color: var(--gold-bright); margin-left: 6px; }
.sdg-res.tete .sdg-res-l b { color: var(--gold-bright); }
.sdg-res small { font-size: 0.7rem; color: var(--muted); font-variant-numeric: tabular-nums; }
.sdg-barre { height: 8px; border-radius: 4px; background: rgba(255,255,255,0.06); overflow: hidden; }
.sdg-barre i { display: block; height: 100%; border-radius: 4px; background: #7d6a4d; }
.sdg-res.tete .sdg-barre i { background: var(--accent); }
.sdg-res.mien .sdg-barre { box-shadow: 0 0 0 1px var(--accent); }

/* L'administration des sondages. */
.sdg-adm-form { display: grid; gap: 10px; max-width: 560px; margin-bottom: 18px; }
.sdg-adm-form label { display: flex; flex-direction: column; gap: 4px; font-size: 0.8rem; color: var(--muted); }
.sdg-adm-form label.sdg-adm-case { flex-direction: row; align-items: center; gap: 8px; color: var(--text-light); }
.sdg-adm-form input[type="text"], .sdg-adm-form input[type="number"], .sdg-adm-form textarea {
    padding: 8px 10px; background: rgba(0,0,0,0.25); border: 1px solid var(--panel-border);
    border-radius: 6px; color: var(--text-light); font-family: var(--font-ui); font-size: 0.85rem;
}
.sdg-adm-form textarea { min-height: 110px; resize: vertical; }
.sdg-adm-carte {
    padding: 12px 14px; margin-bottom: 12px; border: 1px solid var(--line-soft);
    border-radius: var(--radius-sm); background: var(--surface); display: flex; flex-direction: column; gap: 8px;
}
.sdg-adm-carte h4 { margin: 0; font-size: 0.95rem; color: var(--text-light); }
.sdg-adm-etat { font-size: 0.72rem; color: var(--muted); }
.sdg-adm-etat b { color: var(--success); }
.sdg-adm-libres { margin: 0; padding-left: 18px; font-size: 0.8rem; color: var(--text-light); }
.sdg-adm-libres li { margin: 2px 0; overflow-wrap: anywhere; }
.sdg-adm-libres small { color: var(--muted); }
.sdg-adm-actions { display: flex; flex-wrap: wrap; gap: 8px; }

/* --- Les regles de la Gloire (1.26), par-dessus le classement. --- */
.regles-gloire {
    margin: 0 0 4px; padding-left: 20px;
    font-family: var(--font-ui); font-size: 0.9rem; line-height: 1.5;
    color: var(--text-light, #e8e0cc); text-align: left;
}
.regles-gloire li { margin: 3px 0; }

/* --- L'onglet Population (1.26) : qui travaille, sur quoi, et a quelle
   vitesse. Les jauges se remplissent en scaleX, jamais en width (la regle de
   la batterie). --- */
.plx { font-family: var(--font-ui); color: var(--text-light); text-align: left; }
.plx-tete { background: var(--surface); border: 1px solid var(--line-soft); border-radius: var(--radius); padding: 12px 14px; }
.plx-t1 { font-size: 1rem; font-weight: 700; color: var(--gold-bright); display: flex; align-items: center; gap: 8px; }
.plx-t1 b { margin-left: auto; color: var(--accent); font-variant-numeric: tabular-nums; }
.plx-jauge { height: 6px; border-radius: 99px; background: #2b231b; margin: 8px 0 6px; overflow: hidden; }
.plx-jauge i { display: block; height: 100%; background: linear-gradient(90deg, #b8862f, #e3b35a); transform-origin: left center; }
.plx-note { font-size: .74rem; color: var(--muted); line-height: 1.45; margin-top: 4px; }
.plx-titre { font-size: .64rem; text-transform: uppercase; letter-spacing: .1em; color: var(--muted); margin: 14px 2px 7px; }
.plx-liste { background: var(--surface); border: 1px solid var(--line-soft); border-radius: var(--radius-sm); overflow: hidden; }
.plx-ch { padding: 10px 12px; border-top: 1px solid var(--line-soft); }
.plx-ch:first-child { border-top: 0; }
.plx-ch1 { display: flex; align-items: baseline; gap: 8px; font-size: .84rem; }
.plx-niv { color: var(--muted); font-size: .74rem; white-space: nowrap; }
.plx-ch1 b { min-width: 0; }
.plx-reste { margin-left: auto; color: var(--accent); font-weight: 600; font-size: .76rem; white-space: nowrap; font-variant-numeric: tabular-nums; }
.plx-reste .mg-ic { width: 13px; height: 13px; vertical-align: -2px; }
.plx-ch2 { display: flex; align-items: center; gap: 8px; margin-top: 7px; flex-wrap: wrap; }
.plx-pions { display: flex; gap: 4px; }
.plp { width: 12px; height: 12px; border-radius: 50%; border: 1.5px solid #5a4630; box-sizing: border-box; }
.plp.on { background: var(--accent); border-color: var(--accent); }
.plx-vit { font-size: .74rem; color: var(--success); font-weight: 600; }
.plx-vit.off { color: var(--muted); font-weight: 500; }
.plx-btns { margin-left: auto; display: flex; gap: 6px; }
.plx-btn {
    display: inline-flex; align-items: center; gap: 5px; height: 30px; padding: 0 11px;
    border-radius: var(--radius-sm); border: 1px solid var(--accent); background: rgba(227,179,90,.08);
    color: var(--gold-bright); font: 600 .74rem var(--font-ui); cursor: pointer;
}
.plx-btn .mg-ic { width: 13px; height: 13px; }
.plx-btn.sec { border-color: var(--line-soft); color: var(--muted); background: transparent; }
.plx-btn:hover { background: rgba(227,179,90,.16); }
.plx-libre b { color: var(--success); font-size: .86rem; }
.plx-libre.plein b { color: var(--text-light); }
.plx-libre .plx-note { margin: 2px 0 0; }
.plx-regle { font-size: .74rem; color: var(--muted); line-height: 1.45; margin: 8px 2px 0; }
.plx-regle b { color: var(--text-light); }
.plx-carte { background: var(--surface); border: 1px solid var(--line-soft); border-radius: var(--radius-sm); padding: 10px 12px; }
.plx-ligne { display: flex; align-items: center; justify-content: space-between; gap: 8px; font-size: .84rem; font-weight: 600; flex-wrap: wrap; }
.plx-cout { display: inline-flex; gap: 10px; font-weight: 600; font-size: .78rem; font-variant-numeric: tabular-nums; }
.plx-res { white-space: nowrap; }

/* Les instructeurs de la Caserne (1.26.2) : des veterans, dans un encart
   au-dessus de la file d'entrainement, avec les pions de l'onglet Population. */
.mil-instr { background: var(--surface); border: 1px solid var(--line-soft); border-radius: var(--radius-sm);
    padding: 10px 12px; margin: 12px 0; font-family: var(--font-ui); display: flex; flex-direction: column; gap: 6px; }
.mil-instr-tete { display: flex; align-items: center; gap: 8px; font-size: .84rem; }
.mil-instr-etat { font-size: .76rem; color: var(--muted); line-height: 1.45; }
.mil-instr-etat b { color: var(--text-light); }
.mil-instr-btns { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
.mil-instr-refus { font-size: .74rem; color: var(--muted); font-style: italic; }
.mil-instr-poste { display: inline-flex; align-items: center; gap: 6px; font-size: .78rem; font-weight: 600; }
.mil-instr-n { font-weight: 500; opacity: .8; font-size: .72rem; }
.mil-instr-lab { font-size: .76rem; color: var(--muted); flex-basis: 100%; }
.plx-erudit { width: 18px; height: 18px; vertical-align: -4px; }
.plx-go {
    width: 100%; margin-top: 9px; min-height: 38px; border-radius: var(--radius-sm); border: 1px solid var(--accent);
    background: linear-gradient(180deg, #3a2a14, #2a1e0f); color: var(--gold-bright);
    font: 700 .8rem var(--font-ui); cursor: pointer;
}
.plx-go:disabled { opacity: .5; cursor: not-allowed; }

/* Le chariot qu'un cri du heraut designe : un anneau qui s'elargit trois fois,
   puis s'en va. Un evenement, pas un battement -- `transform` et `opacity`. */
.map-soldier.wm-repere::after {
    content: ''; position: absolute; left: 50%; top: 70%;
    width: 120px; height: 60px; margin: -30px 0 0 -60px;
    border: 3px solid var(--gold-bright, #f0c674); border-radius: 50%;
    pointer-events: none; animation: wmRepere 1.2s ease-out 3;
}
@keyframes wmRepere {
    from { transform: scale(0.4); opacity: 1; }
    to   { transform: scale(1.6); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
    .map-soldier.wm-repere::after { animation: none; opacity: 1; }
}

/* =============== LES CAPTURES DU TCHAT =============== */
.chat-joindre {
    flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
    width: 38px; height: 38px; border-radius: 10px; cursor: pointer;
    color: var(--muted); background: var(--surface-2); border: 1px solid var(--line-soft);
}
.chat-joindre:hover { color: var(--accent); border-color: var(--accent); }
.chat-capture {
    display: flex; align-items: center; gap: 10px; margin: 0 0 6px;
    padding: 6px 8px; border-radius: 10px; background: var(--surface-2); border: 1px solid var(--line-soft);
    font-family: var(--font-ui, sans-serif); font-size: .78rem; color: var(--muted);
}
.chat-capture[hidden] { display: none; }
.chat-capture img { width: 56px; height: 42px; object-fit: cover; border-radius: 6px; }
.chat-capture-info { flex: 1; min-width: 0; }
.chat-capture-x {
    flex: 0 0 auto; width: 28px; height: 28px; border-radius: 50%; cursor: pointer;
    color: var(--text-light); background: transparent; border: 1px solid var(--line-soft);
}
.chat-img {
    display: block; max-width: 100%; margin-top: 4px; padding: 0; overflow: hidden; cursor: zoom-in;
    border-radius: 10px; border: 1px solid var(--line-soft); background: var(--surface-2);
}
.chat-img img { display: block; width: 100%; height: 100%; object-fit: cover; }
.chat-img.indisponible { cursor: default; font-size: .75rem; color: var(--muted); }
.chat-img-expiree { margin-top: 4px; font-size: .75rem; color: var(--muted); font-style: italic; }
.capture-plein {
    position: fixed; inset: 0; z-index: 10070; cursor: zoom-out;
    display: flex; align-items: center; justify-content: center; padding: 16px;
    background: rgba(0, 0, 0, .88);
}
.capture-plein[hidden] { display: none; }
.capture-plein img { max-width: 100%; max-height: 100%; border-radius: 6px; box-shadow: 0 10px 40px rgba(0,0,0,.6); }
.capture-plein-x { position: absolute; top: 14px; right: 18px; font-size: 1.4rem; color: #fff; }

/* ==========================================================================
   Les textes legaux, le consentement, les donnees et le signalement (1.26.7)
   ========================================================================== */

/* Ils s'ouvrent aussi par-dessus l'ecran de connexion (z-index 12000) : leur
   voile est leur ombre, comme la boite des messages, puisque #modal-overlay
   vit sous l'ecran de connexion. */
.legal-modal {
    z-index: 12100; width: min(720px, calc(100vw - 24px));
    box-shadow: 0 0 0 100vmax rgba(0,0,0,0.72), 0 18px 50px rgba(0,0,0,0.6);
}
#modal-conditions { z-index: 12050; }
.legal-onglets { margin-top: 12px; flex-wrap: wrap; }
.legal-onglets button { white-space: nowrap; }
.legal-corps { overflow-y: auto; }
.legal-corps .conq-bloc a { color: var(--accent); }
.legal-liste { margin: 0 0 8px; padding-left: 1.15rem; display: flex; flex-direction: column; gap: 6px; font-size: 0.86rem; line-height: 1.55; }
.legal-liste:last-child { margin-bottom: 0; }
.legal-contact { font-family: ui-monospace, 'SFMono-Regular', Menlo, monospace; font-size: 0.84em; color: var(--gold-bright); user-select: all; word-break: break-all; }

/* Un lien qui est un bouton : il ouvre un texte, il ne quitte pas la page. */
.btn-lien {
    background: none; border: 0; padding: 0; margin: 0; cursor: pointer;
    font: inherit; color: var(--accent); text-decoration: underline; text-underline-offset: 2px;
}
@media (hover: hover) and (pointer: fine) { .btn-lien:hover { color: var(--gold-bright); } }

/* Le pied de page : sous la carte de connexion, et au bas du menu Systeme. */
.legal-pied {
    display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 4px 12px;
    margin: 10px 0 0; font-family: var(--font-ui); font-size: 0.66rem; color: #7d7260;
}
.legal-pied button {
    background: none; border: 0; padding: 2px 0; cursor: pointer; font: inherit; color: #9c8f78;
    text-decoration: underline; text-decoration-color: rgba(156,143,120,0.4); text-underline-offset: 2px;
}
@media (hover: hover) and (pointer: fine) { .legal-pied button:hover { color: var(--gold-bright); } }
.sys-legal { margin-top: 14px; }

/* Les cases a cocher de l'inscription et des conditions. */
.auth-cases { display: flex; flex-direction: column; gap: 8px; margin: 12px 0 2px; text-align: left; }
.auth-case {
    display: flex; align-items: flex-start; gap: 9px; cursor: pointer;
    font-family: var(--font-ui); font-size: 0.74rem; line-height: 1.45; color: var(--text-light, #e8dcc4);
}
.auth-case input { width: 16px; height: 16px; flex: 0 0 auto; margin: 1px 0 0; cursor: pointer; accent-color: var(--accent); }

/* Mes donnees : partir se lit comme un danger, pas comme un reglage. */

/* Le signalement. */
.sig-raisons { display: flex; flex-direction: column; gap: 7px; }
#modal-signaler textarea {
    width: 100%; box-sizing: border-box; resize: vertical; min-height: 64px;
    font-family: var(--font-ui); font-size: 0.85rem; padding: 8px 10px; border-radius: var(--radius-sm);
    background: rgba(0,0,0,0.3); border: 1px solid var(--panel-border); color: var(--text-light, #e8dcc4);
}
.chat-act-signaler { font-size: 0.74rem !important; }

/* ==========================================================================
   Mon compte (1.26.7) : une carte d'identite, trois volets, et des valeurs
   qu'on lit avant de les changer. Le gabarit est celui des fenetres du jeu
   (.mil-modal) ; le corps est en police de lecture, comme les deux fenetres
   qui se lisent.
   ========================================================================== */
.cpt-modal { width: min(560px, calc(100vw - 24px)); max-width: 560px; z-index: 10000; }
.cpt-modal .mil-head { padding-bottom: 0; }

.cpt-carte {
    display: flex; align-items: center; gap: 14px; margin-top: 14px; padding: 14px;
    border-radius: 10px; border: 1px solid var(--panel-border);
    background:
        radial-gradient(120% 140% at 0% 0%, rgba(212,165,72,0.14), transparent 60%),
        var(--surface);
    font-family: var(--font-ui); text-align: left;
}
.cpt-blason {
    flex: 0 0 auto; width: 54px; height: 54px; border-radius: 50%;
    display: grid; place-items: center;
    background: #0c0a07; border: 1px solid #6b5326; box-shadow: inset 0 0 0 3px rgba(212,165,72,0.12);
}
.cpt-blason .mg-ic { width: 32px; height: 32px; }
.cpt-qui { min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.cpt-pseudo {
    font-family: var(--font-title); font-weight: 700; font-size: 1.15rem; color: var(--gold-bright);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cpt-adresse { font-size: 0.76rem; color: var(--text-light); display: flex; flex-wrap: wrap; align-items: center; gap: 6px; min-width: 0; }
.cpt-adresse > span:first-child { overflow-wrap: anywhere; }
.cpt-depuis { font-size: 0.68rem; color: var(--muted); }
.cpt-depuis:empty { display: none; }
.cpt-pastille {
    font-size: 0.6rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em;
    padding: 2px 7px; border-radius: 999px; border: 1px solid currentColor;
}
.cpt-pastille.ok { color: var(--success); background: rgba(116,189,122,0.1); }
.cpt-pastille.attente { color: #e0a84a; background: rgba(224,168,74,0.1); }

.cpt-onglets { margin-top: 12px; }
.cpt-onglets button { flex: 1; white-space: nowrap; }

.cpt-corps { font-family: var(--font-ui); padding-top: 14px; padding-bottom: 16px; }
.cpt-volet { display: flex; flex-direction: column; gap: 12px; }
.cpt-volet[hidden] { display: none; }

.cpt-bloc {
    background: var(--surface); border: 1px solid var(--line-soft); border-radius: 10px;
    overflow: hidden;
}
.cpt-sous {
    font-size: 0.62rem; text-transform: uppercase; letter-spacing: 0.1em; color: var(--muted);
    margin: 4px 2px -4px;
}
.cpt-sous-dedans { margin: 0 0 6px; color: var(--gold-bright); font-size: 0.66rem; }
.cpt-note { margin: 0 0 12px; font-size: 0.74rem; line-height: 1.55; color: var(--muted); }
.cpt-note b { color: var(--text-light); }
.cpt-note-bas { margin: 0 2px; font-size: 0.7rem; }

/* Une valeur, puis « Modifier » : le formulaire ne se deplie qu'a la demande. */
.cpt-champ + .cpt-champ { border-top: 1px solid var(--line-soft); }
.cpt-champ > summary, .cpt-zone-danger > summary {
    list-style: none; cursor: pointer; display: flex; align-items: center; gap: 10px;
    min-height: 52px; padding: 8px 14px; box-sizing: border-box;
}
.cpt-champ > summary::-webkit-details-marker, .cpt-zone-danger > summary::-webkit-details-marker { display: none; }
.cpt-libelle { flex: 0 0 auto; font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--muted); min-width: 108px; }
.cpt-valeur { flex: 1; min-width: 0; font-size: 0.86rem; font-weight: 600; color: var(--text-light); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cpt-modifier {
    flex: 0 0 auto; font-size: 0.7rem; font-weight: 700; color: var(--accent);
    padding: 5px 10px; border-radius: 999px; border: 1px solid rgba(212,165,72,0.35);
}
details[open] > summary .cpt-modifier { color: var(--muted); border-color: var(--line-soft); }
details[open] > summary .cpt-modifier::after { content: " ✕"; }
@media (hover: hover) and (pointer: fine) {
    .cpt-champ > summary:hover .cpt-modifier, .cpt-zone-danger > summary:hover .cpt-modifier { border-color: var(--accent); }
}
.cpt-champ > summary:focus-visible, .cpt-zone-danger > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

.cpt-form { padding: 4px 14px 14px; }
.cpt-form-ouvert { padding: 14px; }
.cpt-submit { width: 100%; margin-top: 4px; }
.cpt-submit-court { width: auto; flex: 0 0 auto; padding: 0 18px; margin-top: 0; }
.cpt-submit-danger { background: linear-gradient(180deg, #a3483a, #7a2e22) !important; border-color: #c0614f !important; color: #fff3ea !important; }

/* Les lignes « ce que vous recevez » reprennent celles du menu Systeme. */
.cpt-volet .sys-ligne { min-height: 56px; padding: 8px 14px; }
.cpt-volet .sys-ligne > span { display: flex; flex-direction: column; gap: 2px; }
.cpt-volet .sys-ligne small { font-weight: 500; font-size: 0.68rem; color: var(--muted); }
.cpt-volet .sys-ligne:disabled { opacity: 0.6; cursor: progress; }
.cpt-retour { margin: -4px 2px 0; font-size: 0.74rem; color: var(--gold-bright); }
.cpt-retour.non { color: var(--danger); }

.cpt-rangee { display: flex; align-items: center; gap: 14px; padding: 14px; }
.cpt-rangee-texte { flex: 1; min-width: 0; }
.cpt-rangee .cpt-note { margin: 0; }
.cpt-liens { display: flex; flex-wrap: wrap; gap: 6px 16px; padding: 0 2px; font-size: 0.74rem; }

.cpt-zone-danger { border-color: rgba(207,106,85,0.35); background: rgba(207,106,85,0.05); }
.cpt-zone-danger .cpt-libelle { color: var(--danger); flex: 1; }
.cpt-zone-danger .cpt-modifier { color: var(--danger); border-color: rgba(207,106,85,0.4); }

@media (max-width: 480px) {
    .cpt-carte { padding: 12px; gap: 12px; }
    .cpt-blason { width: 46px; height: 46px; }
    .cpt-libelle { min-width: 0; }
    .cpt-champ > summary { flex-wrap: wrap; row-gap: 2px; }
    .cpt-champ > summary .cpt-libelle { flex-basis: 100%; }
    .cpt-rangee { flex-direction: column; align-items: stretch; }
    .cpt-submit-court { width: 100%; }
    .cpt-onglets button { padding-left: 6px; padding-right: 6px; }
}
