@charset "UTF-8";

/* ============================================================
   JDR Combat Log — styles de base
   Squelette d'interface uniquement : pas de logique, uniquement
   la mise en page (sidebar repliable + grille d'ennemis).
   ============================================================ */

/* Thème sombre : c'est le thème par défaut, donc celui des variables de
   base. Le thème clair (voir plus bas) ne fait que les redéfinir — toute
   couleur de l'interface doit donc passer par une de ces variables, jamais
   être écrite en dur dans une règle. */
:root {
  --color-bg: #15171c;
  --color-bg-elevated: #1c1f26;
  --color-bg-card: #21242c;
  --color-border: #333844;
  --color-border-soft: #292d36;

  --color-text: #e8e9ed;
  --color-text-muted: #9aa0ae;
  --color-text-faint: #5f6474;

  --color-accent: #e0a458;
  --color-accent-strong: #f0b96f;
  --color-danger: #d9534f;
  --color-danger-strong: #e5645f;
  --color-success: #6bbf7b;
  --color-warning: #e0c05c;

  /* Texte des lignes du journal de combat, par type d'événement. */
  --color-log-dmg: #e2a19f;
  --color-log-heal: #a7d9b0;
  --color-log-effect: #e6c599;
  --color-log-death: #f0b4b1;

  /* Fonds teintés (mêmes teintes, en transparence) du journal, des tags
     d'effet et des survols de menu. */
  --tint-danger-soft: rgba(217, 83, 79, 0.1);
  --tint-danger: rgba(217, 83, 79, 0.15);
  --tint-danger-strong: rgba(217, 83, 79, 0.2);
  --tint-accent-soft: rgba(224, 164, 88, 0.05);
  --tint-accent-mild: rgba(224, 164, 88, 0.1);
  --tint-accent: rgba(224, 164, 88, 0.12);
  --tint-accent-strong: rgba(224, 164, 88, 0.15);
  --tint-success: rgba(107, 191, 123, 0.1);
  --tint-neutral: rgba(154, 160, 174, 0.1);

  /* Texte posé sur un aplat de couleur vive (bouton principal, bouton
     "Fin de tour") : ne suit pas le thème, il doit contraster avec
     l'aplat. */
  --color-on-accent: #201705;
  --color-on-danger: #fff;

  --sidebar-width: 340px;
  --sidebar-width-collapsed: 56px;

  --radius-sm: 6px;
  --radius-md: 10px;

  --shadow-card: 0 1px 2px rgba(0, 0, 0, 0.35);
  --shadow-menu: 0 4px 16px rgba(0, 0, 0, 0.35);
  --shadow-modal: 0 8px 24px rgba(0, 0, 0, 0.4);
  --overlay-bg: rgba(0, 0, 0, 0.55);
}

/* Thème clair : activé par l'attribut data-theme="light" sur <html> (voir
   js/state/themeState.js, réglable depuis le menu Options). Les teintes
   vives sont assombries pour rester lisibles sur fond clair. */
:root[data-theme="light"] {
  --color-bg: #eef0f4;
  --color-bg-elevated: #ffffff;
  --color-bg-card: #ffffff;
  --color-border: #ccd1dc;
  --color-border-soft: #e2e5ec;

  --color-text: #1b1e25;
  --color-text-muted: #5b6273;
  --color-text-faint: #868d9d;

  --color-accent: #d9912f;
  --color-accent-strong: #8a5a12;
  --color-danger: #c9302c;
  --color-danger-strong: #a3231f;
  --color-success: #2f7a41;
  --color-warning: #92700a;

  --color-log-dmg: #9a2e2a;
  --color-log-heal: #226635;
  --color-log-effect: #7c4f0f;
  --color-log-death: #8c1b18;

  --tint-danger-soft: rgba(201, 48, 44, 0.08);
  --tint-danger: rgba(201, 48, 44, 0.12);
  --tint-danger-strong: rgba(201, 48, 44, 0.18);
  --tint-accent-soft: rgba(217, 145, 47, 0.06);
  --tint-accent-mild: rgba(217, 145, 47, 0.1);
  --tint-accent: rgba(217, 145, 47, 0.14);
  --tint-accent-strong: rgba(217, 145, 47, 0.18);
  --tint-success: rgba(47, 122, 65, 0.1);
  --tint-neutral: rgba(91, 98, 115, 0.09);

  --shadow-card: 0 1px 2px rgba(27, 30, 37, 0.12);
  --shadow-menu: 0 4px 16px rgba(27, 30, 37, 0.15);
  --shadow-modal: 0 8px 24px rgba(27, 30, 37, 0.2);
  --overlay-bg: rgba(27, 30, 37, 0.4);
}

* {
  box-sizing: border-box;
}

/* L'attribut `hidden` doit toujours l'emporter : sans ça, la règle
   `display` d'une classe (ex : `.btn { display: inline-flex }`) prend le
   dessus sur le `display: none` par défaut du navigateur et l'élément
   reste visible malgré son attribut `hidden`. */
[hidden] {
  display: none !important;
}

html, body {
  height: 100%;
}

/* ---- Icônes (public/icons) ----
   Chaque icône est accompagnée d'un repli en texte, masqué tant que
   l'image se charge correctement. Si le fichier est absent, l'image se
   retire et marque son conteneur (voir js/data/icons.js), ce qui révèle le
   libellé — mieux vaut un mot qu'une case vide. */

.icon {
  display: block;
  object-fit: contain;
  flex-shrink: 0;
}

.icon-fallback {
  display: none;
}

.has-missing-icon > .icon-fallback {
  display: inline-block;
}

body {
  margin: 0;
  font-family: "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  font-size: 14px;
  background: var(--color-bg);
  color: var(--color-text);
}

#app {
  display: flex;
  height: 100vh;
  overflow: hidden;
}

/* ============================================================
   SIDEBAR
   ============================================================ */

.app-sidebar {
  display: flex;
  flex-direction: column;
  width: var(--sidebar-width);
  flex-shrink: 0;
  background: var(--color-bg-elevated);
  border-right: 1px solid var(--color-border);
  transition: width 0.2s ease;
  overflow: hidden;
}

.app-sidebar.is-collapsed {
  width: var(--sidebar-width-collapsed);
}

.app-sidebar.is-collapsed .sidebar-content,
.app-sidebar.is-collapsed .sidebar-footer,
.app-sidebar.is-collapsed .sidebar-header__title {
  display: none;
}

.app-sidebar.is-collapsed .sidebar-toggle__icon {
  transform: rotate(180deg);
}

.sidebar-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-shrink: 0;
  height: 52px;
  padding: 0 8px 0 16px;
  border-bottom: 1px solid var(--color-border);
}

.sidebar-header__title {
  font-weight: 700;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  font-size: 12px;
  color: var(--color-text-muted);
}

.sidebar-toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border: none;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-text-muted);
  cursor: pointer;
}

.sidebar-toggle:hover {
  background: var(--color-bg-card);
  color: var(--color-text);
}

.sidebar-toggle__icon {
  display: inline-block;
  font-size: 16px;
  transition: transform 0.2s ease;
}

.sidebar-content {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
}

.sidebar-section {
  padding: 16px;
  border-bottom: 1px solid var(--color-border-soft);
}

.sidebar-section--logs {
  flex: 1 1 auto;
  min-height: 160px;
  display: flex;
  flex-direction: column;
}

.sidebar-section__title {
  margin: 0 0 12px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}

/* Titre de section accompagné d'une action (ex : ouvrir le journal en
   plein écran) : les deux sur une même ligne, la marge basse passant du
   titre à l'en-tête. */
.sidebar-section__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 12px;
  flex-shrink: 0;
}

.sidebar-section__header .sidebar-section__title {
  margin: 0;
}

.sidebar-section__action {
  padding: 3px 7px;
  background: transparent;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  color: var(--color-text-muted);
  font-family: inherit;
  font-size: 12px;
  line-height: 1.2;
  cursor: pointer;
}

.sidebar-section__action:hover {
  border-color: var(--color-accent);
  color: var(--color-accent);
}

.sidebar-footer {
  flex-shrink: 0;
  padding: 16px;
  border-top: 1px solid var(--color-border);
  background: var(--color-bg-elevated);
}

/* Le bouton "Appliquer les effets permanents" n'apparaît que lorsqu'un
   ennemi porte une brûlure ou un poison : sa couleur pulse doucement pour
   qu'on ne l'oublie pas en cours de tour. */
@keyframes permanent-effects-pulse {
  0%, 100% {
    border-color: var(--color-border);
    background: transparent;
    color: var(--color-text-muted);
  }
  50% {
    border-color: var(--color-danger);
    background: var(--tint-danger-strong);
    color: var(--color-danger-strong);
  }
}

#apply-permanent-effects {
  animation: permanent-effects-pulse 1.8s ease-in-out infinite;
}

/* Confort de lecture : pas de clignotement pour qui préfère limiter les
   animations — le bouton garde alors sa teinte d'appel, fixe. */
@media (prefers-reduced-motion: reduce) {
  #apply-permanent-effects {
    animation: none;
    border-color: var(--color-danger);
    color: var(--color-danger-strong);
  }
}

/* ---- Journal de combat ---- */

.combat-log {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.combat-log__entry {
  font-size: 12.5px;
  line-height: 1.5;
  padding: 4px 8px;
  border-radius: var(--radius-sm);
  color: var(--color-text-muted);
}

.combat-log__entry--turn {
  margin-top: 6px;
  font-weight: 700;
  text-align: center;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-accent);
  background: transparent;
}

.combat-log__entry--dmg {
  background: var(--tint-danger-soft);
  color: var(--color-log-dmg);
}

.combat-log__entry--heal {
  background: var(--tint-success);
  color: var(--color-log-heal);
}

.combat-log__entry--effect {
  background: var(--tint-accent-mild);
  color: var(--color-log-effect);
}

/* Effet qui disparaît (retiré à la main ou expiré en fin de tour) : même
   teinte que l'application d'un effet, mais en retrait. */
.combat-log__entry--effect-removed {
  background: var(--tint-accent-soft);
  color: var(--color-text-muted);
}

/* Mort d'un ennemi : la ligne la plus marquée du journal. */
.combat-log__entry--death {
  background: var(--tint-danger-strong);
  color: var(--color-log-death);
  font-weight: 600;
}

/* Correction manuelle des statistiques (équilibrage en cours de partie). */
.combat-log__entry--edit {
  background: var(--tint-neutral);
  color: var(--color-text-muted);
}

/* Compétence marquée utilisée (suivi de recharge) : même teinte neutre que
   "edit", ni positive ni négative pour l'ennemi. */
.combat-log__entry--skill {
  background: var(--tint-neutral);
  color: var(--color-text-muted);
}

/* Annulation (Ctrl+Z) : en italique pour marquer que la ligne rapporte une
   annulation plutôt qu'une action de combat, teinte neutre comme "edit". */
.combat-log__entry--undo {
  background: var(--tint-neutral);
  color: var(--color-text-muted);
  font-style: italic;
}

.combat-log__entry strong {
  color: var(--color-text);
}

/* Nom de l'ennemi en tête de ligne : c'est un <button> (cliquer dessus
   filtre le journal sur cet ennemi), rendu comme le texte en gras qu'il
   remplace. */
.combat-log__enemy {
  padding: 0;
  background: transparent;
  border: none;
  color: var(--color-text);
  font-family: inherit;
  font-size: inherit;
  font-weight: 700;
  line-height: inherit;
  cursor: pointer;
}

.combat-log__enemy:hover {
  color: var(--color-accent);
  text-decoration: underline;
}

/* Bandeau "Filtré sur X" : collé en haut de la liste, donc toujours
   atteignable même une fois le journal défilé jusqu'en bas. */
.combat-log__filter {
  position: sticky;
  top: 0;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 2px;
  padding: 6px 8px;
  border: 1px solid var(--color-accent);
  border-radius: var(--radius-sm);
  background: var(--color-bg-elevated);
  font-size: 12px;
  color: var(--color-text-muted);
}

.combat-log__filter strong {
  color: var(--color-accent-strong);
}

.combat-log__filter-clear {
  padding: 3px 7px;
  background: transparent;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  color: var(--color-text-muted);
  font-family: inherit;
  font-size: 11px;
  cursor: pointer;
  white-space: nowrap;
}

.combat-log__filter-clear:hover {
  border-color: var(--color-accent);
  color: var(--color-accent);
}

/* Même journal, mais au large dans la fenêtre plein écran : lignes plus
   aérées et texte un peu plus grand. */
.combat-log--fullscreen {
  gap: 5px;
  font-size: 14px;
}

.combat-log--fullscreen .combat-log__entry {
  font-size: 14px;
  padding: 7px 12px;
}

.combat-log--fullscreen .combat-log__time {
  font-size: 12.5px;
  margin-right: 10px;
}

.combat-log--fullscreen .combat-log__entry--turn {
  margin-top: 14px;
  font-size: 13px;
}

.combat-log--fullscreen .combat-log__filter {
  padding: 9px 12px;
  font-size: 13px;
}

.combat-log--fullscreen .combat-log__filter-clear {
  padding: 5px 10px;
  font-size: 12px;
}

/* Heure (format court "14:32") en tête de chaque ligne. */
.combat-log__time {
  margin-right: 6px;
  font-variant-numeric: tabular-nums;
  font-size: 11px;
  color: var(--color-text-faint);
}

/* ---- Formulaires génériques ---- */

.field {
  margin-bottom: 14px;
}

.field:last-of-type {
  margin-bottom: 16px;
}

.field__label {
  display: block;
  margin-bottom: 6px;
  font-size: 12px;
  font-weight: 600;
  color: var(--color-text-muted);
}

.field__control {
  width: 100%;
  padding: 8px 10px;
  background: var(--color-bg-card);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  color: var(--color-text);
  font-size: 13px;
  font-family: inherit;
}

.field__control:focus {
  outline: none;
  border-color: var(--color-accent);
}

.field__control:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.field__hint {
  font-weight: 400;
  color: var(--color-text-faint);
  text-transform: none;
  letter-spacing: normal;
}

.field--invalid .field__control {
  border-color: var(--color-danger-strong);
}

.field__control--textarea {
  min-height: 72px;
  resize: vertical;
}

.field__control--multi {
  padding: 4px;
}

.field__control--multi option {
  padding: 6px 8px;
  border-radius: var(--radius-sm);
}

.field__control--multi option:checked {
  background: var(--color-accent);
  color: var(--color-bg);
}

/* Deux colonnes au minimum, davantage si la place le permet : la largeur
   d'une colonne est plafonnée à la moitié de la liste, il en tient donc
   toujours au moins deux. Pas plus de deux dans la sidebar telle quelle —
   à trois, l'icône ne laisserait plus assez de place au nom de l'effet,
   qui déborderait de sa vignette. */
.checkbox-group {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(120px, (100% - 8px) / 2), 1fr));
  gap: 8px;
  align-items: stretch;
}

/* Chaque effet est une vignette cliquable : la case à cocher est masquée
   (elle reste dans le DOM — c'est elle qui porte l'état lu au moment
   d'appliquer — et focalisable au clavier), l'état "coché" se lisant à la
   bordure et au fond de la vignette.

   L'état actif passe par :has(:checked) plutôt que par une classe posée en
   JS : les cases sont aussi décochées par programme ("Appliquer",
   "Réinitialiser"), ce qui n'émet aucun évènement — une classe se
   désynchroniserait, pas le sélecteur. */
.checkbox-group__item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  border: 1px solid var(--color-border-soft);
  border-radius: var(--radius-sm);
  font-size: 12.5px;
  color: var(--color-text);
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
}

.checkbox-group__item:hover {
  border-color: var(--color-accent);
}

.checkbox-group__item:has(input:checked) {
  border-color: var(--color-accent);
  background: var(--tint-accent);
}

.checkbox-group__item:has(input:checked) .checkbox-group__item-name {
  color: var(--color-accent-strong);
}

/* Repère au clavier, la case à cocher elle-même n'étant plus visible. */
.checkbox-group__item:has(input:focus-visible) {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

.checkbox-group__item input[type="checkbox"] {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

/* Icône de l'effet dans la sidebar : ici, contrairement aux cartes
   d'ennemis, elle accompagne le nom et la description plutôt que de les
   remplacer. */
/* 28 px : c'est l'icône, et non le texte, qui fixe la hauteur d'une ligne
   de la grille — quelques pixels de moins font gagner une trentaine de
   pixels sur l'ensemble de la liste. */
.icon--effect-list {
  width: 28px;
  height: 28px;
  border-radius: var(--radius-sm);
}

.checkbox-group__item-text {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}

/* Description courte de l'effet, en dessous du nom. Tronquée sur une seule
   ligne (texte complet toujours disponible via le title de la vignette) :
   une vraie ligne qui passe à la ligne ferait regagner la hauteur qu'on
   avait justement gagnée en retirant la description de l'icône. */
.checkbox-group__item-description {
  font-size: 11px;
  color: var(--color-text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Seul le champ "Dégâts" doit passer à la ligne suivante : le nom et la
   description restent à côté de l'icône, d'où la base de flex nulle qui les
   empêche de déclencher un retour à la ligne dans une colonne étroite. */
.checkbox-group__item--permanent {
  flex-wrap: wrap;
}

.checkbox-group__item--permanent .checkbox-group__item-text {
  flex: 1 1 0;
}

.checkbox-group__item--permanent .effect-value-input {
  flex-basis: 100%;
  width: 100%;
}

.damage-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
}

.damage-grid__item {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 11px;
  font-weight: 700;
  color: var(--color-text-faint);
  text-align: center;
}

.damage-grid__item .field__control {
  text-align: center;
  padding: 6px 4px;
}

/* Ligne "Appliquer" + sélecteur de répétition (x1-x5) : le bouton prend
   toute la place restante, le select reste à sa largeur de contenu. */
.apply-row {
  display: flex;
  gap: 8px;
}

/* Le bouton "Réinitialiser" suit la ligne .apply-row plutôt qu'un
   .btn--block directement (voir règle .btn--block + .btn--block
   ci-dessus) : il lui faut son propre espacement. */
.apply-row + .btn--block {
  margin-top: 10px;
}

.apply-row .btn {
  flex: 1 1 auto;
}

.apply-row__hit-count {
  flex: 0 0 auto;
  width: 56px;
  text-align: center;
  padding: 6px 4px;
}

/* ---- Boutons ---- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 10px 16px;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.02em;
  cursor: pointer;
  transition: filter 0.15s ease;
}

.btn:hover {
  filter: brightness(1.1);
}

.btn--block {
  width: 100%;
}

/* Deux boutons pleine largeur qui se suivent : on les sépare, sinon ils se
   touchent (risque de clic à côté, et lecture moins claire). */
.btn--block + .btn--block {
  margin-top: 10px;
}

.btn--primary {
  background: var(--color-accent);
  color: var(--color-on-accent);
}

.btn--secondary {
  background: transparent;
  border-color: var(--color-border);
  color: var(--color-text-muted);
}

.btn--secondary:hover {
  border-color: var(--color-text-faint);
  color: var(--color-text);
}

/* Ferré au centre de la top bar, à côté du numéro de tour (voir
   index.html/.app-main__header-center) : c'est l'action la plus fréquente
   du MJ, elle doit rester bien visible. Le bouton lui-même reste
   transparent et sans padding — c'est .btn--end-turn__inner (span) qui
   porte le fond plein, pour que seul l'anneau arc-en-ciel de ::before /
   ::after (voir plus bas) dépasse derrière, sans teinter le contenu. */
.btn--end-turn {
  position: relative;
  z-index: 1;
  background: none;
  padding: 0;
}

.btn--end-turn__inner {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 10px 28px;
  border-radius: var(--radius-sm);
  background: var(--color-danger);
  color: var(--color-on-danger);
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

/* Liseré arc-en-ciel animé, en permanence (contrairement à la secousse
   ci-dessous, qui ne se déclenche qu'après une action) : ::before dessine
   l'anneau dégradé juste derrière .btn--end-turn__inner (inset -2px,
   z-index -1 — cette dernière le recouvre entièrement sauf sur ces 2px),
   ::after en est une copie floutée pour l'effet de halo lumineux. Les deux
   suivent le bouton pendant la secousse (position relative à son propre
   cadre, pas à la page). */
.btn--end-turn::before,
.btn--end-turn::after {
  content: "";
  position: absolute;
  inset: -2px;
  z-index: -1;
  border-radius: calc(var(--radius-sm) + 2px);
  background: linear-gradient(
    45deg,
    #fb0094,
    #0000ff,
    #00ff00,
    #ffff00,
    #ff0000,
    #fb0094,
    #0000ff,
    #00ff00,
    #ffff00,
    #ff0000
  );
  background-size: 400% 400%;
  animation: end-turn-rainbow 20s linear infinite;
}

.btn--end-turn::after {
  filter: blur(14px);
  opacity: 0.75;
}

@keyframes end-turn-rainbow {
  0% {
    background-position: 0% 50%;
  }
  50% {
    background-position: 400% 50%;
  }
  100% {
    background-position: 0% 50%;
  }
}

@media (prefers-reduced-motion: reduce) {
  .btn--end-turn::before,
  .btn--end-turn::after {
    animation: none;
    background-position: 0% 50%;
  }
}

/* Dès qu'un dégât/effet est appliqué à un ennemi (voir markEndTurnPending
   dans js/app.js), le bouton secoue brièvement toutes les 10 secondes
   jusqu'au prochain clic dessus — rappel pour ne pas oublier de clôturer le
   tour en cours. */
@keyframes end-turn-shake {
  0%, 8%, 100% {
    transform: translateX(0);
  }
  1% {
    transform: translateX(-8px);
  }
  2% {
    transform: translateX(7px);
  }
  3% {
    transform: translateX(-6px);
  }
  4% {
    transform: translateX(5px);
  }
  5% {
    transform: translateX(-3px);
  }
  6% {
    transform: translateX(2px);
  }
  7% {
    transform: translateX(-1px);
  }
}

.btn--end-turn.is-pending {
  animation: end-turn-shake 10s cubic-bezier(0.36, 0.07, 0.19, 0.97) infinite;
}

@media (prefers-reduced-motion: reduce) {
  .btn--end-turn.is-pending {
    animation: none;
    box-shadow: 0 0 0 3px var(--color-danger-strong);
  }
}

/* ============================================================
   CONTENU PRINCIPAL
   ============================================================ */

.app-main {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
}

/* Trois zones ferrées : gauche (nouveau/réinitialiser combat), centre
   (tour courant + "Fin de tour"), droite (menu) — voir index.html. La
   colonne centrale en "auto" reste calée au milieu de l'écran tant que les
   colonnes gauche/droite (1fr chacune) ont une largeur proche ; elle garde
   la priorité sur elles si l'espace vient à manquer.
   Sticky en haut de .app-main (le conteneur qui défile, voir overflow-y
   plus haut) : reste visible quelle que soit la quantité d'ennemis dans la
   grille. Fond opaque + z-index pour passer au-dessus des cartes qui
   défilent dessous, et une ombre légère pour marquer la séparation une fois
   du contenu scrollé sous elle. */
.app-main__header {
  flex-shrink: 0;
  position: sticky;
  top: 0;
  z-index: 5;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 12px;
  padding: 20px 24px 4px;
  background: var(--color-bg);
  box-shadow: 0 4px 10px -6px rgba(0, 0, 0, 0.35);
}

.app-main__header-left {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.app-main__header-center {
  display: flex;
  align-items: center;
  gap: 16px;
  justify-self: center;
}

.app-main__header-right {
  display: flex;
  justify-content: flex-end;
}

.header-action-btn {
  padding: 7px 12px;
  background: var(--color-bg-card);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  color: var(--color-text);
  font-family: inherit;
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
}

.header-action-btn:hover {
  border-color: var(--color-accent);
  color: var(--color-accent);
}

.header-action-btn--danger {
  color: var(--color-danger-strong);
}

.header-action-btn--danger:hover {
  border-color: var(--color-danger-strong);
  background: var(--tint-danger);
}

.header-action-btn--success {
  color: var(--color-success);
}

.header-action-btn--success:hover {
  border-color: var(--color-success);
  background: var(--tint-success);
}

.app-menu {
  position: relative;
  flex-shrink: 0;
}

.app-menu__btn {
  padding: 7px 12px;
  background: var(--color-bg-card);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  color: var(--color-text);
  font-family: inherit;
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
}

.app-menu__btn:hover {
  border-color: var(--color-accent);
  color: var(--color-accent);
}

.app-menu__list {
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  z-index: 20;
  display: flex;
  flex-direction: column;
  min-width: 230px;
  padding: 4px;
  background: var(--color-bg-elevated);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-menu);
}

.app-menu__item {
  padding: 8px 10px;
  background: transparent;
  border: none;
  border-radius: var(--radius-sm);
  color: var(--color-text);
  font-family: inherit;
  font-size: 12.5px;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
}

.app-menu__item:hover {
  background: var(--tint-accent);
  color: var(--color-accent-strong);
}

.app-menu__item--danger {
  color: var(--color-danger-strong);
}

.app-menu__item--danger:hover {
  background: var(--tint-danger);
  color: var(--color-danger-strong);
}

.app-main__title {
  margin: 0;
  font-size: 18px;
  font-weight: 700;
}

/* Trois fiches par ligne au maximum : chaque colonne fait au moins un
   tiers de la largeur disponible (gouttières déduites), ce qui plafonne le
   nombre de colonnes sans média-query — et au moins 320 px, pour retomber
   à deux puis une colonne quand la fenêtre se resserre. */
.enemies-grid {
  flex: 1 1 auto;
  padding: 20px 24px 24px;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(max(320px, (100% - 2 * 16px) / 3), 1fr));
  gap: 16px;
  align-content: start;
}

/* ---- Carte ennemi ---- */

.enemy-card {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px;
  background: var(--color-bg-card);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-card);
  cursor: pointer;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.enemy-card--selected {
  border-color: var(--color-accent);
  box-shadow: 0 0 0 1px var(--color-accent), var(--shadow-card);
}

.enemy-card__header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
}

.enemy-card__title {
  display: flex;
  align-items: baseline;
  gap: 6px;
  min-width: 0;
}

.enemy-card__name {
  margin: 0;
  font-size: 15px;
  font-weight: 700;
}

/* Pastille de numéro, à gauche du nom — sur la carte d'ennemi (voir
   ui/enemyCard.js) comme sur le banc des morts (voir ui/deadBench.js). */
.enemy-number-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  min-width: 20px;
  height: 20px;
  padding: 0 6px;
  border-radius: 999px;
  background: var(--color-border);
  color: var(--color-accent);
  font-size: 11px;
  font-weight: 700;
  line-height: 1;
}

.enemy-number-badge--dead {
  color: var(--color-text-muted);
}

.enemy-card__level {
  font-size: 11px;
  font-weight: 700;
  color: var(--color-accent);
  white-space: nowrap;
}

.enemy-card__header-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}

.enemy-card__menu-wrap {
  position: relative;
}

.enemy-card__menu-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  padding: 0;
  border: none;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-text-faint);
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
}

.enemy-card__menu-btn:hover,
.enemy-card__menu-btn[aria-expanded="true"] {
  background: var(--color-bg-elevated);
  color: var(--color-accent);
}

.enemy-card__menu {
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  z-index: 5;
  display: flex;
  flex-direction: column;
  min-width: 150px;
  padding: 4px;
  background: var(--color-bg-elevated);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-menu);
}

.enemy-card__menu[hidden] {
  display: none;
}

.enemy-card__menu-item {
  padding: 7px 10px;
  border: none;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-text);
  font-size: 12.5px;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
}

.enemy-card__menu-item:hover {
  background: var(--color-bg-card);
  color: var(--color-accent);
}

.enemy-card__menu-item--danger {
  color: var(--color-danger-strong);
}

.enemy-card__menu-item--danger:hover {
  background: var(--tint-danger);
  color: var(--color-danger-strong);
}

.enemy-card__hp {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.hp-bar {
  height: 8px;
  border-radius: 999px;
  background: var(--color-bg-elevated);
  overflow: hidden;
}

.hp-bar__fill {
  height: 100%;
  background: var(--color-success);
  border-radius: 999px;
}

.hp-bar__fill--warning {
  background: var(--color-warning);
}

.hp-bar__fill--danger {
  background: var(--color-danger);
}

.hp-bar__label {
  font-size: 11px;
  color: var(--color-text-muted);
}

/* Trois colonnes de statistiques sur une fiche étroite, quatre dès que la
   fiche s'élargit (les sept statistiques tiennent alors sur deux lignes au
   lieu de trois, sans cellules vides qui traînent). */
.enemy-card__stats {
  margin: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(max(72px, (100% - 3 * 8px) / 4), 1fr));
  gap: 6px 8px;
}

.stat {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 6px;
  background: var(--color-bg-elevated);
  border-radius: var(--radius-sm);
}

.stat dt {
  font-size: 10px;
  color: var(--color-text-faint);
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

/* Armure et résistance magique : l'icône précède le libellé, qui reste
   affiché comme pour les autres statistiques. */
.stat__label--icon {
  display: flex;
  align-items: center;
  gap: 4px;
  min-height: 16px;
}

.icon--stat {
  width: 16px;
  height: 16px;
}

.stat dd {
  margin: 0;
  font-size: 13px;
  font-weight: 700;
}

/* Statistique modifiée par un effet actif de l'ennemi (voir
   data/effects.csv, colonne "effect") : vert pour un bonus, rouge pour un
   malus. Revient automatiquement à la couleur normale dès que l'effet
   disparaît (la valeur n'est jamais "recolorée" en dur). */
.stat-value--buff {
  color: var(--color-success);
}

.stat-value--debuff {
  color: var(--color-danger-strong);
}

/* ---- Armes + compétences ---- */

.enemy-card__weapons {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding-top: 8px;
  border-top: 1px solid var(--color-border-soft);
}

.weapon-block {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.weapon-block__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  font-size: 12.5px;
}

.icon--weapon {
  width: 22px;
  height: 22px;
  flex-shrink: 0;
}

/* Le nom occupe l'espace restant, la maîtrise reste collée à droite. */
.weapon-block__row .weapon-block__name {
  flex: 1 1 auto;
}

.weapon-block__name {
  font-weight: 600;
  color: var(--color-text);
}

.weapon-block__mastery {
  font-size: 11px;
  font-weight: 700;
  color: var(--color-text-muted);
  white-space: nowrap;
}

.weapon-block__meta {
  display: flex;
  gap: 14px;
}

.weapon-block__meta-item {
  font-size: 11px;
  color: var(--color-text-muted);
}

.weapon-block__meta-item strong {
  color: var(--color-text);
  font-weight: 700;
  margin-right: 3px;
}

/* Lien dépliable "Afficher / masquer le passif" (élément <details> natif) */

.weapon-passive {
  font-size: 11px;
}

.weapon-passive__summary {
  display: inline-flex;
  width: fit-content;
  list-style: none;
  color: var(--color-accent);
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
  user-select: none;
}

.weapon-passive__summary::-webkit-details-marker {
  display: none;
}

.weapon-passive__summary:hover {
  color: var(--color-accent-strong);
}

.weapon-passive__summary-open {
  display: none;
}

.weapon-passive[open] > .weapon-passive__summary .weapon-passive__summary-open {
  display: inline;
}

.weapon-passive[open] > .weapon-passive__summary .weapon-passive__summary-closed {
  display: none;
}

.weapon-passive__text {
  margin: 6px 0 0;
  font-size: 11.5px;
  line-height: 1.5;
  color: var(--color-text-muted);
}

/* Panneau dépliable "Compétences" (élément <details> natif) */

.skills-panel {
  font-size: 12px;
}

.skills-panel__summary {
  display: flex;
  align-items: center;
  gap: 6px;
  list-style: none;
  padding: 4px 0;
  color: var(--color-text-muted);
  font-weight: 600;
  cursor: pointer;
  user-select: none;
}

.skills-panel__summary::-webkit-details-marker {
  display: none;
}

.skills-panel__summary::before {
  content: "\25B8";
  display: inline-block;
  font-size: 10px;
  color: var(--color-text-faint);
  transition: transform 0.15s ease;
}

.skills-panel[open] > .skills-panel__summary::before {
  transform: rotate(90deg);
}

.skills-panel__summary:hover {
  color: var(--color-text);
}

.skills-panel__body {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 4px 0 4px 16px;
}

.skills-panel__empty {
  margin: 0;
  padding: 4px 0 4px 16px;
  font-size: 11.5px;
  color: var(--color-text-faint);
  font-style: italic;
}

/* Panneau dépliable d'une compétence individuelle (imbriqué). L'indicateur
   (cadenas / coche / sablier) vit en dehors de l'encadré, à sa gauche — voir
   .skill-item__lock et .skill-item__status plus bas — d'où ce conteneur en
   ligne qui les aligne côte à côte. */

.skill-row {
  display: flex;
  align-items: flex-start;
  gap: 6px;
}

.skill-item {
  flex: 1;
  min-width: 0;
  background: var(--color-bg-elevated);
  border: 1px solid var(--color-border-soft);
  border-radius: var(--radius-sm);
  overflow: hidden;
}

.skill-item--locked {
  opacity: 0.6;
}

/* Compétence débloquée mais en recharge (voir combat/cooldowns.js) : même
   grisé que "verrouillée" — c'est le sablier affiché à la place de la coche
   qui précise pourquoi. */
.skill-item--cooldown {
  opacity: 0.6;
}

.skill-item__summary {
  display: flex;
  align-items: center;
  gap: 8px;
  list-style: none;
  padding: 6px 8px;
  cursor: pointer;
  user-select: none;
}

.skill-item__summary::-webkit-details-marker {
  display: none;
}

.skill-item__summary::after {
  content: "\25B8";
  margin-left: auto;
  font-size: 10px;
  color: var(--color-text-faint);
  transition: transform 0.15s ease;
}

.skill-item[open] > .skill-item__summary::after {
  transform: rotate(90deg);
}

.skill-item__name {
  font-size: 12px;
  font-weight: 600;
  color: var(--color-text);
}

.skill-item__lvl {
  font-size: 10.5px;
  font-weight: 700;
  color: var(--color-accent);
  white-space: nowrap;
}

/* Compétence non débloquée : un cadenas fermé remplace l'ancien libellé
   "Non débloquée" (le texte reste en infobulle du SVG). Vit à gauche de
   l'encadré (voir .skill-row) — le margin-top l'aligne sur la ligne de nom
   de l'encadré voisin, dont le <summary> a 6px de padding vertical. */
.skill-item__lock {
  width: 13px;
  height: 13px;
  margin-top: 7px;
  flex-shrink: 0;
  color: var(--color-text-faint);
}

/* Indicateur de disponibilité d'une compétence débloquée (coche cliquable /
   sablier), à la place du cadenas — même emplacement, même gabarit. */
.skill-item__status {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 13px;
  height: 13px;
  margin-top: 7px;
  flex-shrink: 0;
  padding: 0;
  border: none;
  background: none;
  font: inherit;
  line-height: 0;
}

.skill-item__status-icon {
  width: 100%;
  height: 100%;
}

/* Sablier (en recharge) : non interactif, teinte neutre comme le cadenas. */
.skill-item__status--cooldown {
  color: var(--color-text-faint);
}

/* Coche (disponible) : un vrai bouton — cliquer dessus marque la compétence
   utilisée ce tour, sans déplier/replier sa description (voir
   ui/enemyCard.js). Vert "disponible", pour rester "parlante" d'un coup
   d'œil, distincte du gris neutre du sablier/cadenas. */
.skill-item__status--available {
  color: var(--color-success);
  cursor: pointer;
  border-radius: 3px;
}

.skill-item__status--available:hover {
  filter: brightness(1.15);
}

.skill-item__body {
  padding: 0 8px 10px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.skill-item__meta {
  display: flex;
  gap: 14px;
}

.skill-item__meta-item {
  font-size: 11px;
  color: var(--color-text-muted);
}

.skill-item__meta-item strong {
  color: var(--color-text);
  font-weight: 700;
  margin-right: 3px;
}

.skill-item__desc {
  margin: 0;
  font-size: 11.5px;
  line-height: 1.5;
  color: var(--color-text-muted);
}

/* Panneau dépliable "Notes" d'un ennemi (élément <details> natif), sous les
   blocs d'armes/compétences — même langage visuel que .skills-panel. */

.enemy-card__notes {
  font-size: 12px;
  padding-top: 8px;
  border-top: 1px solid var(--color-border-soft);
}

.enemy-card__notes-summary {
  display: flex;
  align-items: center;
  gap: 6px;
  list-style: none;
  padding: 4px 0;
  color: var(--color-text-muted);
  font-weight: 600;
  cursor: pointer;
  user-select: none;
}

.enemy-card__notes-summary::-webkit-details-marker {
  display: none;
}

.enemy-card__notes-summary::before {
  content: "\25B8";
  display: inline-block;
  font-size: 10px;
  color: var(--color-text-faint);
  transition: transform 0.15s ease;
}

.enemy-card__notes[open] > .enemy-card__notes-summary::before {
  transform: rotate(90deg);
}

.enemy-card__notes-summary:hover {
  color: var(--color-text);
}

.enemy-card__notes-text {
  margin: 4px 0 0;
  padding: 0 0 4px 16px;
  font-size: 11.5px;
  line-height: 1.5;
  color: var(--color-text-muted);
  white-space: pre-line;
}

.enemy-card__effects {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.tag {
  font-size: 11px;
  font-weight: 600;
  padding: 3px 8px;
  border-radius: 999px;
}

/* .tag--effect est un <button> (cliquer dessus retire l'effet de l'ennemi)
   — on efface les styles par défaut du bouton pour garder l'apparence d'un
   simple tag, avec juste un curseur pointeur et un léger assombrissement au
   survol pour signaler que c'est cliquable. */
/* Sur une carte d'ennemi, un effet se résume à sa vignette : le nom
   n'apparaît qu'au survol (attribut title). C'est un <button> — cliquer
   dessus retire l'effet. */
.tag--effect {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  padding: 0;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--tint-accent-strong);
  color: var(--color-accent-strong);
  font-family: inherit;
  overflow: hidden;
  cursor: pointer;
}

.tag--effect:hover {
  border-color: var(--color-accent);
  filter: brightness(1.1);
}

.tag--effect .icon {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Repli si l'icône est absente : le nom reprend sa place, et la vignette
   s'élargit pour l'accueillir plutôt que de le tronquer. */
.tag--effect.has-missing-icon {
  width: auto;
  min-width: 34px;
  padding: 0 7px;
}

.tag--effect .icon-fallback {
  font-size: 10px;
  font-weight: 600;
  line-height: 1.2;
  white-space: nowrap;
}

/* Effet permanent (durée -1, ex Brûlure/Empoisonné) : liseré "danger" pour
   le distinguer d'un effet de durée 1 tour. */
.tag--effect-permanent {
  border-color: var(--color-danger);
  background: var(--tint-danger);
  color: var(--color-danger-strong);
}

/* Dégâts d'un effet permanent, inscrits par-dessus son icône. */
.tag__value {
  position: absolute;
  right: 0;
  bottom: 0;
  min-width: 15px;
  padding: 0 3px;
  border-top-left-radius: var(--radius-sm);
  background: var(--color-danger);
  color: var(--color-on-danger);
  font-size: 10px;
  font-weight: 700;
  line-height: 15px;
  text-align: center;
}

/* ---- Banc des morts ---- */

/* Le banc des morts se démarque de la grille par un fond plus sombre (plus
   clair en thème clair) teinté de rouge : on voit d'un coup d'œil où
   s'arrêtent les ennemis encore en vie. */
.dead-bench {
  flex-shrink: 0;
  padding: 4px 24px 24px;
  border-top: 1px solid var(--color-danger);
  background:
    linear-gradient(var(--tint-danger-soft), var(--tint-danger-soft)),
    var(--color-bg-elevated);
}

.dead-bench__title {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 16px 0 12px;
  font-size: 13px;
  font-weight: 700;
  color: var(--color-danger-strong);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.dead-bench__skull {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
}

.dead-bench__list {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.dead-card {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  background: var(--color-bg-card);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  opacity: 0.85;
}

.dead-card__info {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.dead-card__title {
  display: flex;
  align-items: baseline;
  gap: 6px;
  min-width: 0;
}

.dead-card__name {
  font-size: 13px;
  font-weight: 700;
  color: var(--color-text-muted);
  text-decoration: line-through;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.dead-card__level {
  font-size: 11px;
  color: var(--color-text-faint);
}

.dead-card__weapon {
  font-size: 11px;
  color: var(--color-text-faint);
}

.dead-card__revive-btn {
  flex-shrink: 0;
  padding: 6px 10px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-text);
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
}

.dead-card__revive-btn:hover {
  border-color: var(--color-accent);
  color: var(--color-accent-strong);
}

/* ---- Carte "Ajouter un ennemi" ---- */

.enemy-card--add {
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 160px;
  background: transparent;
  border: 1px dashed var(--color-border);
  color: var(--color-text-faint);
  cursor: pointer;
  font-family: inherit;
}

.enemy-card--add:hover {
  border-color: var(--color-accent);
  color: var(--color-accent);
}

.enemy-card--add__icon {
  font-size: 26px;
  line-height: 1;
}

.enemy-card--add__label {
  font-size: 13px;
  font-weight: 600;
}

/* ============================================================
   MODALE (sélection d'un modèle d'ennemi à ajouter)
   ============================================================ */

.modal-overlay {
  position: fixed;
  inset: 0;
  background: var(--overlay-bg);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  z-index: 100;
}

.modal {
  width: 100%;
  max-width: 360px;
  background: var(--color-bg-elevated);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: 20px;
  box-shadow: var(--shadow-modal);
}

.modal__title {
  margin: 0 0 14px;
  font-size: 15px;
  font-weight: 700;
}

/* Recherche au-dessus de la liste des modèles (fenêtre d'ajout). */
.modal__search {
  margin-bottom: 12px;
}

.modal__list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 16px;
  max-height: 320px;
  overflow-y: auto;
}

/* Pagination de la liste des modèles, au-delà de 10 résultats — vide (donc
   masquée, voir :empty) tant que tout tient sur une page. */
.modal__pagination {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 16px;
}

.modal__pagination:empty {
  display: none;
  margin-bottom: 0;
}

.modal__pagination-nav {
  padding: 6px 12px;
  font-size: 12px;
}

.modal__pagination-nav:disabled {
  opacity: 0.4;
  cursor: not-allowed;
  filter: none;
}

.modal__pagination-status {
  font-size: 12px;
  color: var(--color-text-muted);
  white-space: nowrap;
}

.modal__item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 10px 12px;
  background: var(--color-bg-card);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  color: var(--color-text);
  font-family: inherit;
  font-size: 13px;
  cursor: pointer;
  text-align: left;
}

.modal__item:hover {
  border-color: var(--color-accent);
}

/* "Créer un ennemi" : première entrée de la liste d'ajout, distinguée des
   modèles du CSV par un liseré accentué et un fond neutre. */
.modal__item--custom {
  background: transparent;
  border-style: dashed;
  border-color: var(--color-accent);
  color: var(--color-accent-strong);
  margin-bottom: 4px;
}

.modal__item--custom .modal__item-level {
  color: var(--color-text-muted);
}

.modal__item-name {
  font-weight: 600;
}

.modal__item-level {
  font-size: 11px;
  font-weight: 700;
  color: var(--color-accent);
  white-space: nowrap;
}

.modal__cancel {
  background: transparent;
  border: 1px solid var(--color-border);
  color: var(--color-text-muted);
}

/* ---- Modale "Modifier l'ennemi" ---- */

.modal--edit-enemy {
  max-width: 480px;
  max-height: 90vh;
  overflow-y: auto;
}

/* Journal de combat en plein écran : occupe tout l'écran (à la marge de
   l'overlay près), c'est la liste qui défile à l'intérieur, pas la
   fenêtre. */
.modal--combat-log {
  display: flex;
  flex-direction: column;
  max-width: none;
  width: 100%;
  height: 100%;
  min-height: 0;
}

.modal__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 14px;
  flex-shrink: 0;
}

.modal__header .modal__title {
  margin: 0;
}

/* Fenêtre "Options" : les réglages de l'application. */
.modal--options {
  max-width: 420px;
}

.modal__empty {
  margin: 0;
  padding: 18px 0;
  text-align: center;
  font-size: 13px;
  color: var(--color-text-faint);
}

/* Une ligne de réglage : intitulé à gauche, contrôle à droite. */
.option-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  padding: 6px 0;
}

.option-row__label {
  font-size: 13px;
  font-weight: 600;
  color: var(--color-text);
}

/* Interrupteur à bascule : une vraie case à cocher (masquée visuellement,
   mais toujours focalisable au clavier) encadrée par ses deux libellés. */
.switch {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  user-select: none;
}

.switch__side {
  font-size: 12px;
  color: var(--color-text-muted);
}

.switch__input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.switch__track {
  position: relative;
  display: inline-block;
  width: 40px;
  height: 22px;
  border: 1px solid var(--color-border);
  border-radius: 999px;
  background: var(--color-bg-card);
  transition: background 0.15s ease, border-color 0.15s ease;
}

.switch__thumb {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--color-text-muted);
  transition: transform 0.15s ease, background 0.15s ease;
}

.switch__input:checked + .switch__track {
  border-color: var(--color-accent);
  background: var(--tint-accent-strong);
}

.switch__input:checked + .switch__track .switch__thumb {
  transform: translateX(18px);
  background: var(--color-accent);
}

.switch__input:focus-visible + .switch__track {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

.modal__close {
  padding: 4px 9px;
  background: transparent;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  color: var(--color-text-muted);
  font-family: inherit;
  font-size: 13px;
  line-height: 1.2;
  cursor: pointer;
}

.modal__close:hover {
  border-color: var(--color-danger);
  color: var(--color-danger-strong);
}

.edit-enemy-form {
  display: flex;
  flex-direction: column;
}

.edit-enemy-form__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px 12px;
}

.edit-enemy-form__grid--weapons {
  grid-template-columns: 2fr 1fr;
  margin-top: 4px;
}

/* Éditeur "Compétences spéciales" (fenêtre d'édition d'un ennemi) : liste de
   compétences propres au modèle, indépendantes des armes équipées — voir
   ui/editEnemyModal.js. */

.edit-enemy-form__special-skills {
  margin-top: 6px;
  padding-top: 14px;
  border-top: 1px solid var(--color-border-soft);
}

.special-skills-editor__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 10px;
}

.special-skills-editor {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.special-skills-editor__empty {
  margin: 0;
  font-size: 12px;
  color: var(--color-text-faint);
  font-style: italic;
}

.special-skill-row {
  display: flex;
  flex-direction: column;
  padding: 10px 10px 0;
  background: var(--color-bg-elevated);
  border: 1px solid var(--color-border-soft);
  border-radius: var(--radius-sm);
}

.special-skill-row__grid {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr;
  gap: 10px 12px;
}

.special-skill-row__remove {
  align-self: flex-start;
  margin: -6px 0 10px;
  padding: 0;
  background: none;
  border: none;
  font-size: 11.5px;
  font-weight: 600;
  color: var(--color-danger-strong);
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}

.special-skill-row__remove:hover {
  filter: brightness(1.15);
}

.btn--small {
  padding: 6px 10px;
  font-size: 12px;
}

@media (max-width: 480px) {
  .special-skill-row__grid {
    grid-template-columns: 1fr;
  }
}

.edit-enemy-form__errors {
  margin: 12px 0 0;
  padding: 10px 12px;
  list-style: none;
  background: var(--tint-danger);
  border: 1px solid var(--color-danger-strong);
  border-radius: var(--radius-sm);
  display: flex;
  flex-direction: column;
  gap: 4px;
}

/* `display: flex` ci-dessus l'emporterait sinon sur l'attribut `hidden`
   natif, qui laisserait alors un cadre vide visible quand il n'y a aucune
   erreur à afficher. */
.edit-enemy-form__errors[hidden] {
  display: none;
}

.edit-enemy-form__errors li {
  font-size: 12px;
  color: var(--color-log-death);
}

.edit-enemy-form__csv {
  margin-top: 6px;
  padding-top: 14px;
  border-top: 1px solid var(--color-border-soft);
}

.edit-enemy-form__csv-status {
  margin: 8px 0 0;
  font-size: 12px;
  color: var(--color-success);
}

.edit-enemy-form__csv-status--error {
  color: var(--color-danger-strong);
}

.modal__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 18px;
}

.modal__actions .btn {
  width: auto;
}

.btn--csv {
  background: transparent;
  border: 1px solid var(--color-accent);
  color: var(--color-accent);
}

@media (max-width: 480px) {
  .edit-enemy-form__grid {
    grid-template-columns: repeat(2, 1fr);
  }

  .edit-enemy-form__grid--weapons {
    grid-template-columns: 1fr;
  }

  .modal__actions {
    justify-content: stretch;
  }

  .modal__actions .btn {
    flex: 1 1 auto;
  }
}

.btn--danger {
  background: var(--color-danger);
  color: var(--color-on-danger);
}

/* ---- Modale "Supprimer des modèles" ---- */

.modal--manage-templates {
  max-width: 420px;
  max-height: 90vh;
  overflow-y: auto;
}

.manage-templates__hint {
  margin: 0 0 14px;
  font-size: 12px;
  color: var(--color-text-muted);
}

.manage-templates__list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-height: 340px;
  overflow-y: auto;
}

.manage-templates__row {
  display: grid;
  grid-template-columns: 1fr;
  align-items: center;
  gap: 10px 12px;
  padding: 10px 12px;
  background: var(--color-bg-card);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  cursor: pointer;
}

.manage-templates__checkbox {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  cursor: pointer;
}

.manage-templates__level {
  font-size: 11px;
  font-weight: 700;
  color: var(--color-accent);
  white-space: nowrap;
}

.manage-templates__toolbar {
  display: flex;
  gap: 16px;
  margin-bottom: 10px;
}

.manage-templates__select-link {
  padding: 0;
  background: none;
  border: none;
  font-size: 12px;
  font-weight: 600;
  color: var(--color-accent);
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}

.manage-templates__select-link:hover {
  filter: brightness(1.15);
}

/* ============================================================
   RESPONSIVE
   ============================================================ */

@media (max-width: 720px) {
  #app {
    flex-direction: column;
    height: auto;
    min-height: 100vh;
  }

  .app-sidebar {
    width: 100%;
    max-height: 60vh;
  }

  .app-sidebar.is-collapsed {
    width: 100%;
    max-height: 52px;
  }
}
