:root {
  color-scheme: light;
  --bg: #f6f7f9;
  --panel: #ffffff;
  --text: #1d232b;
  --muted: #667085;
  --muted-bg: #f1f5f9;
  --line: #d7dce3;
  --accent: #2563eb;
  --accent-soft: #e9f0ff;
  --primary: #2563eb;
  --primary-hover: #1d4ed8;
  --warning: #fff7d6;
  --success: #16a34a;
  --danger: #dc2626;
  --radius-md: 10px;
  --radius-lg: 14px;
  --shadow-soft: 0 8px 24px rgba(15, 23, 42, 0.08);
  --shadow-hover: 0 14px 34px rgba(15, 23, 42, 0.12);
  --chart-text: #667085;
  --chart-grid: #e5e7eb;
  --chart-axis: #d7dce3;
  --chart-line: #22d3ee;
  /* Échelle de valeur — 4 paliers, faible (1) vers excellent (4). Voir le
     bloc "Value scale" plus bas pour les déclinaisons dérivées. */
  --tier-1: #db2777;
  --tier-2: #d97706;
  --tier-3: #2563eb;
  --tier-4: #059669;
}

/* Parchemin — papier vieilli, encre sépia, accent rouge cire à cacheter.
   Seul thème clair chaud face au Clair neutre et froid ; comme il est clair,
   il hérite du reste de :root sans avoir besoin des dizaines de surcharges
   dont les thèmes sombres ont besoin. */
html[data-theme="parchment"] {
  color-scheme: light;
  --bg: #efe6d2;
  --panel: #fffaf0;
  --text: #2f2418;
  --muted: #7a6650;
  --muted-bg: #f3ebdb;
  --line: #d9c8a8;
  --accent: #8f2d20;
  --accent-soft: #f6e6df;
  --primary: #8f2d20;
  --primary-hover: #74241a;
  --warning: #fdf1d6;
  --success: #15803d;
  --danger: #b91c1c;
  --shadow-soft: 0 8px 24px rgba(74, 55, 30, 0.12);
  --shadow-hover: 0 14px 34px rgba(74, 55, 30, 0.18);
  --chart-text: #7a6650;
  --chart-grid: #e4d7bd;
  --chart-axis: #d9c8a8;
  --chart-line: #8f2d20;
  --tier-1: #a21caf;
  --tier-2: #b45309;
  --tier-3: #4338ca;
  --tier-4: #15803d;
}

/* Pirata One — SIL Open Font License 1.1, self-hosted (the CSP is
   font-src 'self', so no CDN). Titles only: blackletter is a display face and
   would be unreadable at body size. */
@font-face {
  font-family: "Pirata One";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/pirata-one-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Pirata One";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/pirata-one-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* Grimdark — anthracite, dégradés de gris, contours gris clairs, accents
   rouges, angles vifs partout et titres en gothique. */
html[data-theme="grimdark"] {
  color-scheme: dark;
  --bg: #0d0d0f;
  --panel: #17171a;
  --text: #e8e6e3;
  --muted: #9d9aa0;
  --muted-bg: #202024;
  --line: #4d4d55;
  --accent: #e23140;
  --accent-soft: rgba(216, 30, 44, 0.14);
  --primary: #d81e2c;
  --primary-hover: #f43f4e;
  --warning: rgba(176, 125, 44, 0.22);
  --success: #4f9d5d;
  --danger: #e5484d;
  /* Angles vifs : le thème force aussi tous les rayons à 0 plus bas, mais les
     tokens doivent suivre pour ce qui les lit directement. */
  --radius-md: 0px;
  --radius-lg: 0px;
  --shadow-soft: 0 14px 40px rgba(0, 0, 0, 0.55);
  --shadow-hover: 0 18px 50px rgba(0, 0, 0, 0.65);
  --chart-text: #9d9aa0;
  --chart-grid: rgba(120, 120, 132, 0.20);
  --chart-axis: rgba(120, 120, 132, 0.46);
  --chart-line: #e23140;
  /* Colonnes de graphes carrées comme le reste du thème. */
  --chart-bar-radius: 0;
  --tier-1: #c9384a;
  --tier-2: #b07d2c;
  --tier-3: #6188c4;
  --tier-4: #4f9d5d;
}

/* Pas un seul angle arrondi. La règle balaie tout parce que le rayon vient de
   trois sources différentes — tokens, utilitaires Tailwind `rounded-*`, et
   valeurs en dur dans ce fichier — et qu'un thème "carré partout" ne tolère
   pas qu'il en reste un. Les graphes ApexCharts dessinent des chemins SVG,
   hors de portée du CSS : ils lisent --chart-bar-radius à la place. */
html[data-theme="grimdark"] *,
html[data-theme="grimdark"] *::before,
html[data-theme="grimdark"] *::after {
  border-radius: 0 !important;
}

/* Dégradés de gris : les surfaces ne sont pas des aplats, elles se lèvent
   légèrement vers le haut, ce qui donne aux contours gris clairs de quoi
   accrocher. */
html[data-theme="grimdark"] body .wcc-card,
html[data-theme="grimdark"] body .wcc-section,
html[data-theme="grimdark"] body .wcc-list,
html[data-theme="grimdark"] body .wcc-table {
  background-image: linear-gradient(180deg, #1e1e22 0%, #141417 100%);
}

html[data-theme="grimdark"] body .wcc-button-secondary,
html[data-theme="grimdark"] body .dashboard-widget-drag-handle {
  background-image: linear-gradient(180deg, #2a2a30 0%, #1c1c20 100%);
}

/* Titres en gothique. Réservé aux h1/h2 : au-delà, l'écriture noire cesse
   d'être lisible. La pile de repli garde une graisse comparable si le woff2
   n'arrive pas. */
html[data-theme="grimdark"] h1,
html[data-theme="grimdark"] h2,
html[data-theme="grimdark"] .wcc-page-header h1,
html[data-theme="grimdark"] .wcc-page-header h2 {
  font-family: "Pirata One", "Times New Roman", serif;
  font-weight: 400;
  letter-spacing: 0.02em;
}

html[data-theme="dark"] {
  color-scheme: dark;
  --bg: #070816;
  --panel: rgba(20, 25, 49, 0.88);
  --text: #e7edf8;
  --muted: #a9b7cf;
  --muted-bg: rgba(39, 53, 92, 0.42);
  --line: rgba(82, 121, 190, 0.48);
  --accent: #67e8f9;
  --accent-soft: rgba(74, 222, 255, 0.13);
  --primary: #67e8f9;
  --primary-hover: #a5f3fc;
  --warning: rgba(154, 96, 25, 0.24);
  --success: #2dd4bf;
  --danger: #ec4899;
  --shadow-soft: 0 18px 52px rgba(0, 0, 0, 0.22);
  --shadow-hover: 0 22px 64px rgba(0, 0, 0, 0.30);
  --chart-text: #a9b7cf;
  --chart-grid: rgba(107, 139, 199, 0.24);
  --chart-axis: rgba(107, 139, 199, 0.48);
  --chart-line: #67e8f9;
  --tier-1: #db2777;
  --tier-2: #d97706;
  --tier-3: #3b82f6;
  --tier-4: #0d9488;
}

html[data-theme="ember"] {
  color-scheme: dark;
  --bg: #080706;
  --panel: rgba(32, 27, 24, 0.90);
  --text: #f3ebe5;
  --muted: #c8b8ad;
  --muted-bg: rgba(66, 45, 36, 0.46);
  --line: rgba(190, 91, 54, 0.46);
  --accent: #fb6a2a;
  --accent-soft: rgba(251, 106, 42, 0.15);
  --primary: #fb6a2a;
  --primary-hover: #ff9b54;
  --warning: rgba(194, 91, 22, 0.28);
  --success: #ffb86b;
  --danger: #fb4b64;
  --shadow-soft: 0 18px 52px rgba(0, 0, 0, 0.30);
  --shadow-hover: 0 22px 64px rgba(0, 0, 0, 0.38);
  --chart-text: #c8b8ad;
  --chart-grid: rgba(190, 91, 54, 0.22);
  --chart-axis: rgba(190, 91, 54, 0.46);
  --chart-line: #fb6a2a;
  --tier-1: #db2777;
  --tier-2: #d97706;
  --tier-3: #0284c7;
  --tier-4: #65a30d;
}

html[data-theme="warp"] {
  color-scheme: dark;
  --bg: #09061a;
  --panel: rgba(28, 20, 52, 0.90);
  --text: #ece6fb;
  --muted: #b6a8dc;
  --muted-bg: rgba(72, 52, 120, 0.42);
  --line: rgba(157, 122, 234, 0.44);
  --accent: #c084fc;
  --accent-soft: rgba(192, 132, 252, 0.16);
  --primary: #c084fc;
  --primary-hover: #d8b4fe;
  --warning: rgba(180, 120, 40, 0.28);
  --success: #4ade80;
  --danger: #fb7185;
  --shadow-soft: 0 18px 52px rgba(0, 0, 0, 0.34);
  --shadow-hover: 0 22px 64px rgba(0, 0, 0, 0.42);
  --chart-text: #b6a8dc;
  --chart-grid: rgba(157, 122, 234, 0.22);
  --chart-axis: rgba(157, 122, 234, 0.46);
  --chart-line: #c084fc;
  --tier-1: #c026d3;
  --tier-2: #d97706;
  --tier-3: #8b5cf6;
  --tier-4: #16a34a;
}

/* ============================================================================
   Value scale — the one palette used everywhere a colour encodes "how good is
   this value": chart series, result pills, campaign row backgrounds, accent
   bars. Each theme picks its own four hues (above); the declinations below are
   derived from them so a theme only ever declares four colours.

     --tier-N        solid, for chart marks and accents
     --tier-N-grad   lighter end of the accent-bar gradient
     --tier-N-soft   pill / row background
     --tier-N-line   pill / row border
     --tier-N-ink    text on a -soft background

   Palette gate (dataviz six checks, adjacent pairs, per theme surface): the
   four solids clear the OKLCH lightness band, the chroma floor, CVD ΔE >= 8
   (protan/deutan), the normal-vision floor of 15 and 3:1 contrast on their
   theme's card surface. Re-run the validator before changing a tier hue.
   ========================================================================== */
:root {
  --tier-1-grad: color-mix(in srgb, var(--tier-1) 58%, #ffffff);
  --tier-2-grad: color-mix(in srgb, var(--tier-2) 58%, #ffffff);
  --tier-3-grad: color-mix(in srgb, var(--tier-3) 58%, #ffffff);
  --tier-4-grad: color-mix(in srgb, var(--tier-4) 58%, #ffffff);
  --tier-1-soft: color-mix(in srgb, var(--tier-1) 13%, #ffffff);
  --tier-2-soft: color-mix(in srgb, var(--tier-2) 13%, #ffffff);
  --tier-3-soft: color-mix(in srgb, var(--tier-3) 13%, #ffffff);
  --tier-4-soft: color-mix(in srgb, var(--tier-4) 13%, #ffffff);
  --tier-1-line: color-mix(in srgb, var(--tier-1) 34%, #ffffff);
  --tier-2-line: color-mix(in srgb, var(--tier-2) 34%, #ffffff);
  --tier-3-line: color-mix(in srgb, var(--tier-3) 34%, #ffffff);
  --tier-4-line: color-mix(in srgb, var(--tier-4) 34%, #ffffff);
  --tier-1-ink: color-mix(in srgb, var(--tier-1) 72%, #000000);
  --tier-2-ink: color-mix(in srgb, var(--tier-2) 72%, #000000);
  --tier-3-ink: color-mix(in srgb, var(--tier-3) 72%, #000000);
  --tier-4-ink: color-mix(in srgb, var(--tier-4) 72%, #000000);
}

/* Parchemin keeps the light recipe but lightens towards its own paper rather
   than pure white: a white-mixed pill reads cold and cut-out on ivory. */
html[data-theme="parchment"] {
  --tier-1-soft: color-mix(in srgb, var(--tier-1) 12%, #fffaf0);
  --tier-2-soft: color-mix(in srgb, var(--tier-2) 12%, #fffaf0);
  --tier-3-soft: color-mix(in srgb, var(--tier-3) 12%, #fffaf0);
  --tier-4-soft: color-mix(in srgb, var(--tier-4) 12%, #fffaf0);
  --tier-1-line: color-mix(in srgb, var(--tier-1) 32%, #fffaf0);
  --tier-2-line: color-mix(in srgb, var(--tier-2) 32%, #fffaf0);
  --tier-3-line: color-mix(in srgb, var(--tier-3) 32%, #fffaf0);
  --tier-4-line: color-mix(in srgb, var(--tier-4) 32%, #fffaf0);
}

/* The bottom nav's active glow otherwise defaults to the base rules' cyan/blue
   (see body .wcc-bottom-nav-indicator above), which reads cold and out of
   place against warm paper. Goldenrod instead — the same warm-gold family as
   the "excellent" tier on the campaign charts, so the chrome and the data
   speak the same colour instead of fighting each other. Hardcoded rather than
   read from --tier-4: that tier is user-customisable per theme (Interface →
   palette), and this is chrome, not a value encoding — it must not move just
   because someone resets or repicks their chart colours. */
html[data-theme="parchment"] body .wcc-bottom-nav-item.active {
  background: rgba(217, 165, 32, 0.22);
  color: #7a5a12;
}

html[data-theme="parchment"] body .wcc-bottom-nav-indicator {
  background:
    radial-gradient(circle at 50% 8%, rgba(255, 250, 240, 0.80), transparent 42%),
    linear-gradient(135deg, rgba(217, 165, 32, 0.46), rgba(180, 120, 20, 0.22));
  border: 1px solid rgba(217, 165, 32, 0.62);
  box-shadow:
    0 0 18px rgba(217, 165, 32, 0.30),
    0 8px 22px rgba(180, 120, 20, 0.20),
    inset 0 0 0 1px rgba(255, 255, 255, 0.50),
    inset 0 1px 0 rgba(255, 255, 255, 0.70);
}

html[data-theme="parchment"] body .wcc-bottom-nav.wcc-bottom-nav-ready .wcc-bottom-nav-item.active {
  color: #7a5a12;
  filter: saturate(1.1) drop-shadow(0 0 6px rgba(217, 165, 32, 0.40));
}

/* Dark themes: tint the surface instead of lightening towards white, and lift
   the ink so it stays readable on the tinted background. */
html[data-theme="dark"],
html[data-theme="ember"],
html[data-theme="warp"],
html[data-theme="grimdark"] {
  --tier-1-grad: color-mix(in srgb, var(--tier-1) 62%, #ffffff);
  --tier-2-grad: color-mix(in srgb, var(--tier-2) 62%, #ffffff);
  --tier-3-grad: color-mix(in srgb, var(--tier-3) 62%, #ffffff);
  --tier-4-grad: color-mix(in srgb, var(--tier-4) 62%, #ffffff);
  --tier-1-soft: color-mix(in srgb, var(--tier-1) 20%, transparent);
  --tier-2-soft: color-mix(in srgb, var(--tier-2) 20%, transparent);
  --tier-3-soft: color-mix(in srgb, var(--tier-3) 20%, transparent);
  --tier-4-soft: color-mix(in srgb, var(--tier-4) 20%, transparent);
  --tier-1-line: color-mix(in srgb, var(--tier-1) 46%, transparent);
  --tier-2-line: color-mix(in srgb, var(--tier-2) 46%, transparent);
  --tier-3-line: color-mix(in srgb, var(--tier-3) 46%, transparent);
  --tier-4-line: color-mix(in srgb, var(--tier-4) 46%, transparent);
  --tier-1-ink: color-mix(in srgb, var(--tier-1) 42%, #ffffff);
  --tier-2-ink: color-mix(in srgb, var(--tier-2) 42%, #ffffff);
  --tier-3-ink: color-mix(in srgb, var(--tier-3) 42%, #ffffff);
  --tier-4-ink: color-mix(in srgb, var(--tier-4) 42%, #ffffff);
}

* {
  box-sizing: border-box;
}

html {
  background: var(--bg);
  min-height: 100%;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  font-size: 14px;
  line-height: 1.45;
  min-height: 100dvh;
}

html[data-theme="dark"] body {
  background:
    radial-gradient(circle at 18% 0%, rgba(87, 71, 196, 0.38), transparent 34rem),
    radial-gradient(circle at 92% 8%, rgba(8, 145, 178, 0.24), transparent 30rem),
    linear-gradient(135deg, #060716 0%, #0b1026 48%, #111032 100%);
}

html[data-theme="ember"] body {
  background:
    radial-gradient(circle at 18% 0%, rgba(177, 48, 30, 0.34), transparent 32rem),
    radial-gradient(circle at 92% 10%, rgba(251, 146, 60, 0.18), transparent 30rem),
    linear-gradient(135deg, #060504 0%, #15100f 48%, #211210 100%);
}

html[data-theme="warp"] body {
  background:
    radial-gradient(circle at 16% -2%, rgba(168, 85, 247, 0.38), transparent 34rem),
    radial-gradient(circle at 94% 8%, rgba(232, 121, 249, 0.20), transparent 30rem),
    linear-gradient(135deg, #07041a 0%, #120a2e 48%, #1c1140 100%);
}

a {
  color: inherit;
  text-decoration: none;
}

.wcc-theme-row,
.wcc-mobile-controls {
  align-items: center;
  display: flex;
  gap: 8px;
}

.wcc-theme-row {
  justify-content: space-between;
}

.wcc-mobile-controls {
  flex: 0 0 auto;
}

.wcc-theme-menu {
  position: relative;
  z-index: 5;
}

.wcc-theme-menu-button {
  align-items: center;
  background: var(--accent-soft);
  /* Derived from --accent instead of a hardcoded blue: identical for Clair,
     and the pill follows any other light theme's accent without needing its
     own override block. */
  border: 1px solid color-mix(in srgb, var(--accent) 22%, transparent);
  border-radius: 999px;
  color: var(--accent);
  display: inline-flex;
  flex: 0 0 auto;
  font-size: 11px;
  font-weight: 700;
  gap: 6px;
  line-height: 1;
  min-height: 28px;
  padding: 5px 8px 5px 6px;
  width: auto;
}

.wcc-theme-menu-button:hover,
.wcc-theme-menu.open .wcc-theme-menu-button {
  background: color-mix(in srgb, var(--accent) 14%, transparent);
}

.wcc-theme-menu-button svg {
  height: 14px;
  transition: transform 180ms ease;
  width: 14px;
}

.wcc-theme-menu.open .wcc-theme-menu-button svg {
  transform: rotate(180deg);
}

.wcc-theme-menu-swatch,
.wcc-theme-option-swatch {
  border-radius: 999px;
  display: inline-block;
  flex: 0 0 auto;
}

.wcc-theme-menu-swatch {
  background: linear-gradient(135deg, #f8fafc 0%, #2563eb 100%);
  box-shadow: 0 0 0 4px rgba(37, 99, 235, 0.10);
  display: inline-block;
  height: 10px;
  width: 10px;
}

.wcc-theme-menu-swatch.is-parchment {
  background: linear-gradient(135deg, #fffaf0 0%, #d9c8a8 52%, #8f2d20 100%);
  box-shadow: 0 0 0 4px rgba(143, 45, 32, 0.12);
}

.wcc-theme-menu-swatch.is-grimdark {
  background: linear-gradient(135deg, #6c6c77 0%, #2a2a30 52%, #d81e2c 100%);
  box-shadow: 0 0 14px rgba(216, 30, 44, 0.40);
}

.wcc-theme-menu-swatch.is-dark {
  background: linear-gradient(135deg, #67e8f9 0%, #111032 100%);
  box-shadow: 0 0 14px rgba(103, 232, 249, 0.48);
}

.wcc-theme-menu-swatch.is-ember {
  background: linear-gradient(135deg, #fb4b64 0%, #fb6a2a 54%, #15100f 100%);
  box-shadow: 0 0 14px rgba(251, 106, 42, 0.48);
}

.wcc-theme-menu-swatch.is-warp {
  background: linear-gradient(135deg, #e879f9 0%, #7c3aed 54%, #0a0714 100%);
  box-shadow: 0 0 14px rgba(168, 85, 247, 0.5);
}

.wcc-theme-menu-panel {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 12px;
  box-shadow: var(--shadow-soft);
  display: grid;
  gap: 4px;
  min-width: 180px;
  /* Never spill past the viewport edge, whichever side it opens from. */
  max-width: calc(100vw - 24px);
  opacity: 0;
  padding: 6px;
  pointer-events: none;
  position: absolute;
  right: 0;
  top: calc(100% + 8px);
  transform: translate3d(0, -4px, 0) scale(0.98);
  transform-origin: top right;
  transition: opacity 160ms ease, transform 160ms ease;
  visibility: hidden;
}

/* The settings-page menu button sits at the left of its card, so the panel
   must open to the right of that edge instead of right-aligning (which pushed
   it off the left of the screen). */
.settings-theme-menu .wcc-theme-menu-panel {
  left: 0;
  right: auto;
  transform-origin: top left;
}

.wcc-theme-menu.open .wcc-theme-menu-panel {
  opacity: 1;
  pointer-events: auto;
  transform: translate3d(0, 0, 0) scale(1);
  visibility: visible;
}

.wcc-theme-option {
  align-items: center;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 9px;
  color: var(--text);
  display: flex;
  gap: 9px;
  padding: 8px;
  text-align: left;
  width: 100%;
}

.wcc-theme-option:hover,
.wcc-theme-option.active {
  background: var(--accent-soft);
  border-color: color-mix(in srgb, var(--accent) 22%, transparent);
}

.wcc-theme-option span:last-child {
  display: grid;
  gap: 1px;
}

.wcc-theme-option strong {
  font-size: 12px;
  line-height: 1.1;
}

.wcc-theme-option small {
  color: var(--muted);
  font-size: 10px;
  font-weight: 700;
}

.wcc-theme-option-swatch {
  height: 18px;
  width: 18px;
}

.wcc-theme-option-swatch.is-light {
  background: linear-gradient(135deg, #ffffff 0%, #dbeafe 48%, #2563eb 100%);
  border: 1px solid rgba(37, 99, 235, 0.26);
}

.wcc-theme-option-swatch.is-parchment {
  background: linear-gradient(135deg, #fffaf0 0%, #e4d7bd 50%, #8f2d20 100%);
  border: 1px solid rgba(143, 45, 32, 0.30);
}

.wcc-theme-option-swatch.is-grimdark {
  background: linear-gradient(135deg, #7a7a86 0%, #26262b 54%, #d81e2c 100%);
  border: 1px solid rgba(216, 30, 44, 0.42);
}

.wcc-theme-option-swatch.is-dark {
  background: linear-gradient(135deg, #67e8f9 0%, #4f46e5 46%, #070816 100%);
  border: 1px solid rgba(103, 232, 249, 0.34);
}

.wcc-theme-option-swatch.is-ember {
  background: linear-gradient(135deg, #fb4b64 0%, #fb6a2a 52%, #080706 100%);
  border: 1px solid rgba(251, 106, 42, 0.42);
}

.wcc-theme-option-swatch.is-warp {
  background: linear-gradient(135deg, #e879f9 0%, #8b5cf6 46%, #0a0714 100%);
  border: 1px solid rgba(168, 85, 247, 0.42);
}

.settings-theme-menu {
  justify-self: start;
}

/* --- Value-scale pickers (interface panel) --------------------------------
   Four colour inputs, one per tier, plus a reset. The chosen colours are
   stored per theme and applied as inline --tier-N overrides on <html>. */
.theme-palette {
  border-top: 1px solid var(--line);
  display: grid;
  gap: 12px;
  padding-top: 14px;
}

.theme-palette-head {
  align-items: flex-start;
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  justify-content: space-between;
}

.theme-palette-head p {
  margin: 4px 0 0;
}

.theme-palette-grid {
  display: grid;
  gap: 10px;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

@media (min-width: 640px) {
  .theme-palette-grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

.theme-palette-item {
  color: var(--muted);
  display: grid;
  font-size: 12px;
  font-weight: 700;
  gap: 6px;
  margin: 0;
  min-width: 0;
}

.wcc-color-input {
  -webkit-appearance: none;
  appearance: none;
  background: transparent;
  border: 1px solid var(--line);
  border-radius: 10px;
  cursor: pointer;
  height: 40px;
  padding: 3px;
  width: 100%;
}

.wcc-color-input::-webkit-color-swatch-wrapper {
  padding: 0;
}

.wcc-color-input::-webkit-color-swatch {
  border: 0;
  border-radius: 7px;
}

.wcc-color-input::-moz-color-swatch {
  border: 0;
  border-radius: 7px;
}

.discord-channel-select {
  min-width: 0;
  width: 100%;
}

.discord-channel-select[multiple] {
  border-radius: 12px;
  min-height: 10rem;
  padding: 8px;
}

body .wcc-mobile-topbar {
  align-items: center;
  background: transparent !important;
  -webkit-backdrop-filter: none !important;
  backdrop-filter: none !important;
  border: 0 !important;
  box-shadow: none !important;
  display: flex;
  gap: 8px;
  justify-content: space-between;
  left: 0;
  padding: calc(10px + env(safe-area-inset-top)) 16px 8px;
  position: fixed;
  right: 0;
  top: 0;
  z-index: 60;
}

body .wcc-shell {
  min-height: 100dvh;
}

body .wcc-mobile-topbar::before,
body .wcc-mobile-topbar::after {
  display: none !important;
}

.wcc-tooltip {
  display: inline-flex;
  position: relative;
}

.wcc-tooltip-content {
  background: #0f172a;
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 999px;
  box-shadow: 0 10px 26px rgba(15, 23, 42, 0.22);
  color: #ffffff;
  font-size: 11px;
  font-weight: 800;
  left: 50%;
  line-height: 1;
  opacity: 0;
  padding: 7px 9px;
  pointer-events: none;
  position: absolute;
  top: calc(100% + 8px);
  transform: translate3d(-50%, -3px, 0);
  transition: opacity 160ms ease, transform 160ms ease;
  white-space: nowrap;
  z-index: 90;
}

.wcc-tooltip:hover .wcc-tooltip-content,
.wcc-tooltip:focus-within .wcc-tooltip-content {
  opacity: 1;
  transform: translate3d(-50%, 0, 0);
}

.wcc-confirm-modal {
  align-items: center;
  background: rgba(3, 7, 18, 0.58);
  bottom: 0;
  display: flex;
  justify-content: center;
  left: 0;
  padding: 20px;
  position: fixed;
  right: 0;
  top: 0;
  z-index: 90;
}

.wcc-confirm-modal.hidden {
  display: none;
}

.wcc-confirm-dialog {
  max-width: 520px;
  width: min(100%, 520px);
}

.wcc-confirm-panel {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-hover);
  color: var(--text);
  padding: 18px;
}

.wcc-confirm-actions {
  display: flex;
  flex-direction: column-reverse;
  gap: 10px;
  margin-top: 18px;
}

.admin-deploy-log {
  background: rgba(3, 7, 18, 0.72);
  border: 1px solid var(--line);
  border-radius: 12px;
  color: var(--text);
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;
  font-size: 0.78rem;
  line-height: 1.45;
  margin: 14px 0 0;
  max-height: 16rem;
  overflow: auto;
  padding: 12px;
  white-space: pre-wrap;
}

@media (min-width: 640px) {
  .wcc-confirm-actions {
    flex-direction: row;
    justify-content: flex-end;
  }}

.wcc-settings-tooltip {
  flex: 0 0 auto;
  margin-left: auto;
}

body .wcc-bot-status-pill,
body .wcc-settings-bubble,
body .wcc-bottom-nav {
  -webkit-backdrop-filter: blur(18px);
  backdrop-filter: blur(18px);
  background: rgba(255, 255, 255, 0.72);
  border: 1px solid rgba(255, 255, 255, 0.78);
  box-shadow: 0 18px 44px rgba(55, 86, 120, 0.18), inset 0 1px 0 rgba(255, 255, 255, 0.72);
}

body .wcc-bot-status-pill {
  align-items: center;
  border-radius: 999px;
  color: var(--text);
  display: inline-flex;
  flex: 0 1 auto;
  gap: 7px;
  justify-content: flex-start;
  margin: 0;
  max-width: calc(100vw - 86px);
  min-height: 46px;
  min-width: 0;
  padding: 6px 7px 6px 12px;
}

body .wcc-bot-brand {
  align-items: center;
  display: inline-flex;
  gap: 8px;
  min-width: 0;
}

body .wcc-bot-brand svg {
  flex: 0 0 auto;
}

body .wcc-status-dot {
  border-radius: 999px;
  display: inline-block;
  flex: 0 0 auto;
  height: 9px;
  width: 9px;
}

body .wcc-status-dot.is-online {
  background: var(--tier-4);
  box-shadow: 0 0 0 5px color-mix(in srgb, var(--tier-4) 16%, transparent);
}

body .wcc-status-dot.is-offline {
  background: var(--tier-1);
  box-shadow: 0 0 0 5px color-mix(in srgb, var(--tier-1) 16%, transparent);
}

body .wcc-bot-status-name {
  font-size: 13px;
  font-weight: 850;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

body .wcc-bot-status-state {
  color: var(--muted);
  font-size: 11px;
  font-weight: 800;
  text-transform: uppercase;
}

body .wcc-bot-reload,
body .wcc-settings-bubble {
  align-items: center;
  border-radius: 999px;
  display: inline-flex;
  flex: 0 0 auto;
  height: 34px;
  justify-content: center;
  min-height: 34px;
  padding: 0;
  width: 34px;
}

body .wcc-bot-reload {
  background: var(--accent-soft);
  border: 1px solid color-mix(in srgb, var(--accent) 18%, transparent);
  color: var(--accent);
}

body .wcc-settings-bubble {
  color: var(--text);
  height: 46px;
  margin-left: auto;
  width: 46px;
}

body .wcc-bot-reload svg,
body .wcc-settings-bubble svg,
body .wcc-bottom-nav-item svg,
body .wcc-nav-link-main svg,
body .preview-card-icon svg,
body .tool-card-icon svg,
body .mobile-nav-preview svg,
body .wcc-button svg {
  height: 20px;
  width: 20px;
}

.icon-inline {
  display: inline-block;
  height: 1em;
  width: 1em;
  vertical-align: -0.15em;
}

.icon-inline--success {
  color: var(--tier-4);
}

.icon-inline--card-yellow {
  color: #eab308;
  fill: #eab308;
}

.icon-inline--card-red {
  color: #dc2626;
  fill: #dc2626;
}

/* --- Réponse à l'appel campagne (fiche joueur). ---
   Rides the theme's value scale: présent = palier excellent, partiel = palier
   bon, absent = palier le plus faible. "Sans réponse" stays a hollow, neutral
   circle — it is an absence of data, not a bad value. Partiel is filled so the
   two circles never read as the same mark when the hue is hard to tell apart. */
.call-response-icon--present {
  color: var(--tier-4);
}

.call-response-icon--partial {
  color: var(--tier-3);
  fill: var(--tier-3);
}

.call-response-icon--absent {
  color: var(--tier-1);
}

.call-response-icon--unknown {
  color: var(--muted);
}

body .wcc-nav-link-main {
  align-items: center;
  display: inline-flex;
  gap: 9px;
  min-width: 0;
}

body .wcc-bottom-nav {
  align-items: center;
  border-radius: 999px;
  bottom: calc(12px + env(safe-area-inset-bottom));
  display: flex;
  gap: 5px;
  justify-content: space-between;
  isolation: isolate;
  left: 50%;
  max-width: calc(100vw - 28px);
  overflow: hidden;
  padding: 7px;
  position: fixed;
  transform: translate3d(-50%, 0, 0);
  width: min(430px, calc(100vw - 28px));
  z-index: 50;
}

body .wcc-bottom-nav-indicator {
  background:
    radial-gradient(circle at 50% 8%, rgba(255, 255, 255, 0.72), transparent 42%),
    linear-gradient(135deg, rgba(103, 232, 249, 0.44), rgba(59, 130, 246, 0.18));
  border: 1px solid rgba(103, 232, 249, 0.62);
  border-radius: 999px;
  bottom: 7px;
  box-shadow:
    0 0 18px rgba(34, 211, 238, 0.28),
    0 8px 22px rgba(14, 165, 233, 0.20),
    inset 0 0 0 1px rgba(255, 255, 255, 0.46),
    inset 0 1px 0 rgba(255, 255, 255, 0.68);
  contain: layout paint style;
  display: none;
  left: 0;
  pointer-events: none;
  position: absolute;
  top: 7px;
  transform: translate3d(0, 0, 0) scale(1);
  transform-origin: 50% 50%;
  will-change: transform, opacity;
  width: clamp(52px, 17vw, 72px);
  z-index: 0;
}

body .wcc-bottom-nav.wcc-bottom-nav-ready .wcc-bottom-nav-indicator {
  display: block;
}

/* Pages none of the 5 tabs represent (Admin, Settings SQLite, Commandes,
   Actions, Audit — all reached from the gear icon) leave every tab inactive:
   bottom_nav.js then hides the glow instead of parking it under a tab that
   isn't actually current. Needs the extra class to outrank the rule above. */
body .wcc-bottom-nav.wcc-bottom-nav-ready .wcc-bottom-nav-indicator.wcc-bottom-nav-indicator-hidden {
  display: none;
}

body .wcc-bottom-nav-item {
  align-items: center;
  border-radius: 999px;
  color: rgba(67, 77, 92, 0.74);
  display: inline-flex;
  flex: 1 1 0;
  font-size: 11px;
  font-weight: 800;
  gap: 5px;
  justify-content: center;
  min-height: 50px;
  min-width: 0;
  padding: 0 6px;
  position: relative;
  transform: translateZ(0);
  transition:
    color 220ms ease,
    transform 260ms cubic-bezier(0.22, 1, 0.36, 1),
    filter 220ms ease;
  z-index: 1;
}

body .wcc-bottom-nav-item:hover {
  color: var(--accent);
}

body .wcc-bottom-nav-item:focus-visible {
  outline: 2px solid rgba(6, 182, 212, 0.70);
  outline-offset: 3px;
}

body .wcc-bottom-nav-icon-shell {
  align-items: center;
  display: inline-flex;
  justify-content: center;
  min-height: 28px;
  min-width: 28px;
  transform: scale(1);
  transition:
    transform 220ms cubic-bezier(0.22, 1, 0.36, 1),
    opacity 180ms ease,
    color 180ms ease;
  will-change: transform, opacity;
}

body .wcc-bottom-nav-item.active {
  background: rgba(103, 232, 249, 0.30);
  color: var(--accent);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.62);
}

body .wcc-bottom-nav.wcc-bottom-nav-ready .wcc-bottom-nav-item.active {
  background: transparent;
  box-shadow: none;
  color: #0891b2;
  filter: saturate(1.16) drop-shadow(0 0 7px rgba(6, 182, 212, 0.36));
  transform: scale(1.05);
}

body .wcc-bottom-nav.wcc-bottom-nav-ready .wcc-bottom-nav-item.active .wcc-bottom-nav-icon-shell {
  filter: drop-shadow(0 0 8px rgba(6, 182, 212, 0.48));
}

@media (prefers-reduced-motion: reduce) {
  body .wcc-bottom-nav-indicator,
  body .wcc-bottom-nav-item,
  body .wcc-bottom-nav-icon-shell {
    animation: none !important;
    transition-duration: 0ms !important;
  }

  body .wcc-bottom-nav.wcc-bottom-nav-ready .wcc-bottom-nav-item.active {
    transform: none;
  }

  .wcc-progress-bar {
    transition-duration: 0ms;
  }}

body .wcc-nav-fallback,
body.wcc-icons-ready .wcc-bottom-nav-label {
  clip: rect(0, 0, 0, 0);
  border: 0;
  height: 1px;
  margin: -1px;
  overflow: hidden;
  padding: 0;
  position: absolute;
  white-space: nowrap;
  width: 1px;
}

body .wcc-main {
  padding-bottom: calc(120px + env(safe-area-inset-bottom));
  padding-top: calc(72px + env(safe-area-inset-top));
}

/* iOS Safari sometimes mis-caches the auto-computed width of
   #wcc-content-frame (a `display: grid; max-width: 100%` element sized only
   implicitly) after an htmx swap changes the content's height enough to
   affect scrolling — the grid re-centers itself ~35-40px narrower than the
   available space and never recovers until the page is reloaded. Giving it
   an explicit width removes the ambiguity WebKit trips over. #id beats the
   .wcc-content class from dist/output.css regardless of link order. */
#wcc-content-frame {
  width: 100%;
}

.dashboard-customize-footer {
  display: flex;
  justify-content: flex-end;
}

body .mobile-hub-header .wcc-button {
  gap: 8px;
}

body .hub-card-list,
body .tools-grid,
body .activity-preview-grid,
body .admin-settings-grid,
body .preview-stack,
body .settings-link-grid,
body .settings-panel-list,
body .tool-list {
  display: grid;
  gap: 12px;
}

body .hub-card,
body .tool-list-row {
  align-items: center;
  background: rgba(255, 255, 255, 0.54);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  display: flex;
  gap: 12px;
  min-width: 0;
  padding: 12px;
  transition: border-color 180ms ease, box-shadow 180ms ease, transform 180ms ease;
}

body .hub-card:hover,
body .tool-list-row:hover {
  border-color: rgba(37, 99, 235, 0.30);
  box-shadow: var(--shadow-soft);
  transform: translateY(-1px);
}

body .hub-card-accent {
  background: linear-gradient(180deg, #67e8f9, #3b82f6);
  border-radius: 999px;
  flex: 0 0 auto;
  height: 42px;
  width: 5px;
}

/* Placement-based accent colours (gradient kept, hues follow the theme like
   the win-threshold pills). Thresholds: 1-3 green, 4-7 blue, 8-10 yellow,
   11+ red. */
body .hub-card-accent--green {
  background: linear-gradient(180deg, var(--tier-4-grad), var(--tier-4));
}

body .hub-card-accent--blue {
  background: linear-gradient(180deg, var(--tier-3-grad), var(--tier-3));
}

body .hub-card-accent--yellow {
  background: linear-gradient(180deg, var(--tier-2-grad), var(--tier-2));
}

body .hub-card-accent--red {
  background: linear-gradient(180deg, var(--tier-1-grad), var(--tier-1));
}

body .hub-card-main {
  display: grid;
  flex: 1 1 auto;
  gap: 2px;
  min-width: 0;
}

body .hub-card-main strong,
body .tool-list-row span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

body .hub-card-main span,
body .tool-list-row strong,
body .tool-card-preview p,
body .preview-card-head p,
body .tool-card-head p {
  color: var(--muted);
}

body .hub-action-section {
  align-items: center;
  display: flex;
  gap: 16px;
  justify-content: space-between;
}

body .hub-action-section h2,
body .preview-card-head h2,
body .tool-card-head h2,
body .settings-hub-card h2 {
  font-size: 18px;
  font-weight: 850;
  margin: 0;
}

body .preview-card-head,
body .tool-card-head {
  align-items: center;
  display: flex;
  gap: 12px;
  margin-bottom: 14px;
}

body .preview-card-icon,
body .tool-card-icon {
  align-items: center;
  background: var(--accent-soft);
  border: 1px solid color-mix(in srgb, var(--accent) 18%, transparent);
  border-radius: 999px;
  box-shadow: 0 8px 20px color-mix(in srgb, var(--accent) 12%, transparent);
  color: var(--accent);
  display: inline-flex;
  flex: 0 0 auto;
  height: 44px;
  justify-content: center;
  width: 44px;
}

body .activity-preview-card,
body .tool-card,
body .settings-hub-card {
  display: grid;
  gap: 14px;
}

body .preview-subcard {
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  display: grid;
  gap: 8px;
  padding: 12px;
}

body .preview-subcard h3 {
  color: var(--muted);
  font-size: 12px;
  font-weight: 850;
  letter-spacing: 0.04em;
  margin: 0;
  text-transform: uppercase;
}

body .tool-card-preview {
  background: var(--muted-bg);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  display: grid;
  gap: 6px;
  padding: 12px;
  white-space: pre-line;
}

body .mobile-nav-preview {
  display: grid;
  gap: 8px;
  grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));
}

body .mobile-nav-preview span {
  align-items: center;
  background: var(--muted-bg);
  border: 1px solid var(--line);
  border-radius: 999px;
  display: inline-flex;
  font-weight: 800;
  gap: 8px;
  justify-content: center;
  padding: 10px;
}

@media (min-width: 760px) {
  body .activity-preview-grid,
  body .tools-grid,
  body .admin-settings-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  body .activity-preview-card-wide,
  body .tool-card-wide,
  body .settings-hub-card-wide {
    grid-column: 1 / -1;
  }}

@media (min-width: 1024px) {
  body .wcc-mobile-topbar,
  body .wcc-bottom-nav {
    display: none;
  }

  body .wcc-main {
    padding-bottom: 2rem;
    padding-top: 0;
  }}

html[data-theme="dark"] .wcc-theme-menu-button {
  background: rgba(103, 232, 249, 0.12);
  border-color: rgba(103, 232, 249, 0.34);
  color: #9ef4ff;
}

html[data-theme="dark"] .wcc-theme-menu-button:hover,
html[data-theme="dark"] .wcc-theme-menu.open .wcc-theme-menu-button {
  background: rgba(103, 232, 249, 0.18);
}

html[data-theme="dark"] .wcc-theme-menu-panel {
  background: rgba(14, 19, 42, 0.98);
  border-color: rgba(103, 232, 249, 0.28);
}

html[data-theme="dark"] .wcc-theme-option:hover,
html[data-theme="dark"] .wcc-theme-option.active {
  background: rgba(103, 232, 249, 0.12);
  border-color: rgba(103, 232, 249, 0.28);
}

html[data-theme="ember"] .wcc-theme-menu-button {
  background: rgba(251, 106, 42, 0.14);
  border-color: rgba(251, 106, 42, 0.38);
  color: #ffb86b;
}

html[data-theme="ember"] .wcc-theme-menu-button:hover,
html[data-theme="ember"] .wcc-theme-menu.open .wcc-theme-menu-button {
  background: rgba(251, 106, 42, 0.20);
}

html[data-theme="ember"] .wcc-theme-menu-panel {
  background: rgba(24, 18, 16, 0.98);
  border-color: rgba(251, 106, 42, 0.34);
}

html[data-theme="ember"] .wcc-theme-option:hover,
html[data-theme="ember"] .wcc-theme-option.active {
  background: rgba(251, 106, 42, 0.14);
  border-color: rgba(251, 106, 42, 0.32);
}

/* The floating chrome (bot pill, settings bubble, bottom nav) is frosted glass:
   it needs a PALE tint at low alpha so the blurred backdrop lifts it above the
   page. A dark fill at high alpha reads as the page itself and the bar
   disappears — which is what Braise and Warp used to do. */
html[data-theme="ember"] body .wcc-bot-status-pill,
html[data-theme="ember"] body .wcc-settings-bubble,
html[data-theme="ember"] body .wcc-bottom-nav {
  background: rgba(255, 214, 184, 0.15);
  border-color: rgba(255, 198, 156, 0.26);
  box-shadow: 0 18px 52px rgba(0, 0, 0, 0.34), inset 0 1px 0 rgba(255, 255, 255, 0.14);
}

html[data-theme="ember"] body .wcc-settings-bubble,
html[data-theme="ember"] body .wcc-bot-status-pill,
html[data-theme="ember"] body .wcc-bottom-nav-item {
  color: var(--text);
}

html[data-theme="ember"] body .wcc-bottom-nav-item.active {
  background: rgba(251, 106, 42, 0.18);
  color: #ffb86b;
}

html[data-theme="ember"] body .wcc-bottom-nav-indicator {
  background:
    radial-gradient(circle at 50% 8%, rgba(255, 235, 220, 0.20), transparent 46%),
    linear-gradient(135deg, rgba(251, 106, 42, 0.36), rgba(251, 75, 100, 0.22));
  border-color: rgba(251, 106, 42, 0.64);
  box-shadow:
    0 0 22px rgba(251, 106, 42, 0.32),
    0 8px 24px rgba(0, 0, 0, 0.28),
    inset 0 0 0 1px rgba(255, 184, 107, 0.12),
    inset 0 1px 0 rgba(255, 184, 107, 0.16);
}

html[data-theme="ember"] body .wcc-bottom-nav.wcc-bottom-nav-ready .wcc-bottom-nav-item.active {
  color: #ffb86b;
  filter: saturate(1.18) drop-shadow(0 0 8px rgba(251, 106, 42, 0.46));
}

html[data-theme="dark"] body .wcc-bot-status-pill,
html[data-theme="dark"] body .wcc-settings-bubble,
html[data-theme="dark"] body .wcc-bottom-nav {
  background: rgba(168, 221, 239, 0.14);
  border-color: rgba(172, 220, 255, 0.22);
  box-shadow: 0 18px 52px rgba(0, 0, 0, 0.28), inset 0 1px 0 rgba(255, 255, 255, 0.12);
}

html[data-theme="dark"] body .wcc-settings-bubble,
html[data-theme="dark"] body .wcc-bot-status-pill,
html[data-theme="dark"] body .wcc-bottom-nav-item {
  color: var(--text);
}

html[data-theme="dark"] body .wcc-bottom-nav-item.active {
  background: rgba(103, 232, 249, 0.18);
  color: #9ef4ff;
}

html[data-theme="dark"] body .wcc-bottom-nav-indicator {
  background:
    radial-gradient(circle at 50% 8%, rgba(255, 255, 255, 0.22), transparent 46%),
    linear-gradient(135deg, rgba(103, 232, 249, 0.30), rgba(79, 70, 229, 0.22));
  border-color: rgba(103, 232, 249, 0.58);
  box-shadow:
    0 0 20px rgba(103, 232, 249, 0.30),
    0 8px 24px rgba(0, 0, 0, 0.24),
    inset 0 0 0 1px rgba(255, 255, 255, 0.12),
    inset 0 1px 0 rgba(255, 255, 255, 0.16);
}

html[data-theme="dark"] body .wcc-bottom-nav.wcc-bottom-nav-ready .wcc-bottom-nav-item.active {
  color: #9ef4ff;
  filter: saturate(1.18) drop-shadow(0 0 8px rgba(103, 232, 249, 0.45));
}

html[data-theme="dark"] body .hub-card,
html[data-theme="dark"] body .tool-list-row,
html[data-theme="dark"] body .tool-card-preview,
html[data-theme="dark"] body .preview-subcard,
html[data-theme="dark"] body .mobile-nav-preview span,
html[data-theme="dark"] body .rank-watch-row {
  background: rgba(11, 16, 38, 0.52);
  border-color: var(--line);
}

html[data-theme="dark"] body .rank-watch-row:hover {
  border-color: rgba(103, 232, 249, 0.38);
}

html[data-theme="dark"] body .rank-watch-wins {
  color: #9ef4ff;
}

html[data-theme="dark"] body .rank-watch-missing {
  background: rgba(103, 232, 249, 0.10);
  border-color: rgba(103, 232, 249, 0.26);
  color: #e6fbff;
}

html[data-theme="dark"] body .template-preview-box {
  background: rgba(11, 16, 38, 0.58);
  border-color: rgba(103, 232, 249, 0.20);
  color: var(--text);
}

html[data-theme="dark"] body .template-preview-box .template-preview-text {
  color: var(--text);
}

html[data-theme="dark"] body .filepond-upload-progress {
  background: rgba(11, 16, 38, 0.58);
  border-color: rgba(103, 232, 249, 0.24);
}

html[data-theme="dark"] .wcc-shell {
  background:
    radial-gradient(circle at 12% 0%, rgba(76, 67, 170, 0.30), transparent 32rem),
    linear-gradient(145deg, rgba(6, 7, 22, 0.96), rgba(15, 23, 56, 0.96));
}

html[data-theme="dark"] .wcc-sidebar,
html[data-theme="dark"] .wcc-mobile-topbar {
  border-color: var(--line);
}

html[data-theme="dark"] .wcc-mobile-topbar {
  background: transparent;
  box-shadow: none;
}

html[data-theme="dark"] .wcc-sidebar {
  background:
    linear-gradient(180deg, rgba(29, 25, 70, 0.96), rgba(10, 17, 39, 0.96)),
    #0b1026;
}

html[data-theme="dark"] .wcc-sidebar-header,
html[data-theme="dark"] .border-border {
  border-color: var(--line);
}

html[data-theme="dark"] .wcc-card,
html[data-theme="dark"] .wcc-section,
html[data-theme="dark"] .wcc-stat-card,
html[data-theme="dark"] .wcc-stat-strip,
html[data-theme="dark"] .campaign-overview-card,
html[data-theme="dark"] .player-overview-card,
html[data-theme="dark"] .wcc-table,
html[data-theme="dark"] .wcc-list,
html[data-theme="dark"] .wcc-filters,
html[data-theme="dark"] .action-note,
html[data-theme="dark"] .phase-row,
html[data-theme="dark"] .command-row,
html[data-theme="dark"] .reaction-role-row,
html[data-theme="dark"] .progress-card,
html[data-theme="dark"] .campaign-import-row {
  background: linear-gradient(180deg, rgba(24, 31, 61, 0.92), rgba(14, 19, 42, 0.92));
  border-color: var(--line);
  box-shadow: 0 18px 52px rgba(0, 0, 0, 0.24), inset 0 1px 0 rgba(125, 169, 255, 0.10);
}

html[data-theme="dark"] .wcc-nav-link:hover,
html[data-theme="dark"] .wcc-nav-link.active,
html[data-theme="dark"] .nav a:hover,
html[data-theme="dark"] .nav a.active,
html[data-theme="dark"] .nav-button:hover {
  background: rgba(103, 232, 249, 0.12);
  border-color: rgba(103, 232, 249, 0.28);
  color: var(--accent);
}

html[data-theme="dark"] .campaign-history-row:hover {
  background: rgba(103, 232, 249, 0.10);
}

html[data-theme="dark"] .apexcharts-text,
html[data-theme="dark"] .apexcharts-legend-text {
  fill: var(--chart-text) !important;
  color: var(--chart-text) !important;
}

html[data-theme="dark"] .apexcharts-gridline {
  stroke: var(--chart-grid) !important;
}

html[data-theme="dark"] .apexcharts-xaxis line,
html[data-theme="dark"] .apexcharts-yaxis line {
  stroke: var(--chart-axis) !important;
}

html[data-theme="ember"] body .hub-card,
html[data-theme="ember"] body .tool-list-row,
html[data-theme="ember"] body .tool-card-preview,
html[data-theme="ember"] body .preview-subcard,
html[data-theme="ember"] body .mobile-nav-preview span,
html[data-theme="ember"] body .rank-watch-row {
  background: rgba(15, 12, 11, 0.58);
  border-color: var(--line);
}

html[data-theme="ember"] body .rank-watch-row:hover {
  border-color: rgba(251, 106, 42, 0.42);
}

html[data-theme="ember"] body .rank-watch-wins {
  color: #ffb86b;
}

html[data-theme="ember"] body .rank-watch-missing {
  background: rgba(251, 106, 42, 0.12);
  border-color: rgba(251, 106, 42, 0.30);
  color: #ffe2c7;
}

html[data-theme="ember"] body .template-preview-box,
html[data-theme="ember"] body .filepond-upload-progress {
  background: rgba(15, 12, 11, 0.62);
  border-color: rgba(251, 106, 42, 0.26);
  color: var(--text);
}

html[data-theme="ember"] body .template-preview-box .template-preview-text {
  color: var(--text);
}

html[data-theme="ember"] .wcc-shell {
  background:
    radial-gradient(circle at 12% 0%, rgba(177, 48, 30, 0.24), transparent 32rem),
    linear-gradient(145deg, rgba(6, 5, 4, 0.96), rgba(30, 18, 16, 0.96));
}

html[data-theme="ember"] .wcc-sidebar,
html[data-theme="ember"] .wcc-mobile-topbar {
  border-color: var(--line);
}

html[data-theme="ember"] .wcc-mobile-topbar {
  background: transparent;
  box-shadow: none;
}

html[data-theme="ember"] .wcc-sidebar {
  background:
    linear-gradient(180deg, rgba(44, 25, 21, 0.96), rgba(12, 10, 9, 0.96)),
    #120d0b;
}

html[data-theme="ember"] .wcc-sidebar-header,
html[data-theme="ember"] .border-border {
  border-color: var(--line);
}

html[data-theme="ember"] .wcc-card,
html[data-theme="ember"] .wcc-section,
html[data-theme="ember"] .wcc-stat-card,
html[data-theme="ember"] .wcc-stat-strip,
html[data-theme="ember"] .campaign-overview-card,
html[data-theme="ember"] .player-overview-card,
html[data-theme="ember"] .wcc-table,
html[data-theme="ember"] .wcc-list,
html[data-theme="ember"] .wcc-filters,
html[data-theme="ember"] .action-note,
html[data-theme="ember"] .phase-row,
html[data-theme="ember"] .command-row,
html[data-theme="ember"] .reaction-role-row,
html[data-theme="ember"] .progress-card,
html[data-theme="ember"] .campaign-import-row {
  background: linear-gradient(180deg, rgba(37, 29, 26, 0.94), rgba(18, 14, 13, 0.94));
  border-color: var(--line);
  box-shadow: 0 18px 52px rgba(0, 0, 0, 0.30), inset 0 1px 0 rgba(255, 184, 107, 0.09);
}

html[data-theme="ember"] .wcc-nav-link:hover,
html[data-theme="ember"] .wcc-nav-link.active,
html[data-theme="ember"] .nav a:hover,
html[data-theme="ember"] .nav a.active,
html[data-theme="ember"] .nav-button:hover {
  background: rgba(251, 106, 42, 0.13);
  border-color: rgba(251, 106, 42, 0.31);
  color: var(--accent);
}

html[data-theme="ember"] .campaign-history-row:hover {
  background: rgba(251, 106, 42, 0.11);
}

html[data-theme="ember"] .apexcharts-text,
html[data-theme="ember"] .apexcharts-legend-text {
  fill: var(--chart-text) !important;
  color: var(--chart-text) !important;
}

html[data-theme="ember"] .apexcharts-gridline {
  stroke: var(--chart-grid) !important;
}

html[data-theme="ember"] .apexcharts-xaxis line,
html[data-theme="ember"] .apexcharts-yaxis line {
  stroke: var(--chart-axis) !important;
}

.login-shell {
  display: grid;
  min-height: 100vh;
  padding: 24px;
  place-items: center;
}

.login-card {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-soft);
  max-width: 520px;
  padding: 24px;
  width: 100%;
}

.login-card h1 {
  margin-bottom: 4px;
}

.wcc-progress {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  z-index: 1200;
  opacity: 0;
  pointer-events: none;
  transition: opacity 220ms ease;
}

.wcc-progress.is-active {
  opacity: 1;
}

.wcc-progress-bar {
  display: block;
  height: 100%;
  width: 0;
  background: var(--primary);
  box-shadow: 0 0 10px var(--primary), 0 0 4px var(--primary);
  transition: width 240ms ease;
}

.admin-action-panel {
  margin-top: 24px;
}

.dashboard-chart,
.campaign-detail-chart,
.player-detail-chart {
  min-height: 340px;
  width: 100%;
}

.activity-layout,
.activity-side,
.activity-two-column,
.activity-four-column {
  display: grid;
  gap: 16px;
}

@media (min-width: 760px) {
  .activity-two-column {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .activity-four-column {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }}

@media (min-width: 1024px) {
  .activity-layout {
    grid-template-columns: minmax(0, 1fr) minmax(320px, 0.8fr);
  }}

.devotion-title {
  align-items: center;
  display: inline-flex;
  gap: 8px;
}

.devotion-icon {
  flex: 0 0 auto;
  height: 32px;
  object-fit: contain;
  width: 32px;
}

.phase-list {
  display: grid;
  gap: 8px;
  margin-bottom: 18px;
}

.phase-row {
  align-items: center;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  display: grid;
  gap: 10px;
  grid-template-columns: minmax(190px, 1.4fr) minmax(210px, 1fr) 100px auto;
  padding: 10px;
  transition: border-color 180ms ease, box-shadow 180ms ease, transform 180ms ease;
}

.phase-row.active {
  border-color: #9bbcff;
  box-shadow: 0 0 0 1px #cfe0ff inset;
}

.phase-name {
  align-items: center;
  display: inline-flex;
  gap: 10px;
  min-width: 0;
}

.phase-icon {
  flex: 0 0 auto;
  height: 34px;
  object-fit: contain;
  width: 34px;
}

.phase-name strong {
  font-weight: 700;
  overflow-wrap: anywhere;
}

.phase-dates {
  color: var(--text);
  display: grid;
  gap: 8px;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.phase-duration {
  margin: 0;
}

.phase-duration input {
  max-width: 92px;
}

.phase-row button {
  justify-self: end;
}

.phase-row button:disabled,
.phase-row input:disabled {
  cursor: not-allowed;
  opacity: 0.55;
}

.phase-dates .wcc-stat-label,
.phase-duration .wcc-stat-label {
  color: var(--muted);
  font-size: 12px;
  margin-bottom: 2px;
}

.campaign-overview-card {
  align-items: stretch;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-soft);
  display: grid;
  grid-template-columns: minmax(0, 3fr) minmax(92px, 1fr);
  overflow: hidden;
}

.campaign-overview-factions,
.campaign-overview-rank {
  min-width: 0;
  padding: 17px 20px;
}

.campaign-overview-factions {
  display: grid;
  gap: 12px;
}

.campaign-overview-rank {
  border-left: 1px solid var(--line);
  display: grid;
  justify-items: center;
  place-content: center;
  text-align: center;
}

.campaign-matchup {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  min-width: 0;
}

.campaign-matchup .campaign-factions {
  gap: 7px;
}

.campaign-matchup .campaign-faction img {
  height: 34px;
  width: 34px;
}

.campaign-matchup-versus {
  color: var(--muted);
  flex: 0 0 auto;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.04em;
}

.player-overview-card {
  align-items: stretch;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-soft);
  display: grid;
  grid-template-columns: minmax(0, 3fr) minmax(132px, 1fr);
  overflow: hidden;
}

.player-overview-main,
.player-overview-rank {
  min-width: 0;
  padding: 17px 20px;
}

.player-overview-main {
  display: grid;
  gap: 10px;
}

.player-overview-name {
  color: var(--text);
  display: block;
  font-size: 30px;
  font-weight: 800;
  line-height: 1.1;
  min-width: 0;
  overflow-wrap: anywhere;
}

.player-overview-meta {
  align-items: center;
  color: var(--muted);
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  min-width: 0;
}

.player-overview-rank {
  border-left: 1px solid var(--line);
  display: grid;
  justify-items: center;
  place-content: center;
  text-align: center;
}

.player-stat-strip .wcc-stat-label {
  min-height: 30px;
}

/* --- Three-figure stat strips. --------------------------------------------
   The strip is laid out for four figures (2x2 on mobile, one row from sm up).
   The player and campaign heroes carry three, so without this the last tile
   sits alone in a half-width cell with a hole beside it. */
.wcc-stat-strip:has(> .wcc-stat-strip-item:last-child:nth-child(3)) > .wcc-stat-strip-item:last-child {
  grid-column: span 2;
}

@media (min-width: 640px) {
  .wcc-stat-strip:has(> .wcc-stat-strip-item:last-child:nth-child(3)) {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .wcc-stat-strip:has(> .wcc-stat-strip-item:last-child:nth-child(3)) > .wcc-stat-strip-item:last-child {
    grid-column: auto;
  }
}

.player-detail-section .wcc-page-header {
  margin-bottom: 14px;
}

/* Bannir : action destructrice isolée sous les panneaux d'édition, pas dans
   l'en-tête de page, pour ne pas la mettre à portée de pouce immédiate.
   Reprend la gouttière verticale de .action-note. */
.player-ban-action {
  margin-top: 18px;
}

.player-recent-list {
  display: grid;
  gap: 6px;
}

.player-recent-row {
  align-items: center;
  border: 1px solid transparent;
  border-radius: 8px;
  display: grid;
  gap: 8px;
  grid-template-columns: 76px minmax(0, 1fr) 24px;
  min-width: 0;
  padding: 9px 10px;
}

.player-recent-date {
  font-weight: 700;
  white-space: nowrap;
}

.player-recent-result {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.player-recent-call {
  text-align: center;
  white-space: nowrap;
}

.leaderboard-list {
  display: grid;
  gap: 8px;
}

.leaderboard-row {
  border: 1px solid var(--line);
  border-radius: 8px;
  min-width: 0;
  padding: 9px 12px;
}

.leaderboard-row-main {
  align-items: center;
  display: flex;
  gap: 10px;
  min-width: 0;
}

.leaderboard-row-name {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.leaderboard-row-xp {
  flex-shrink: 0;
  white-space: nowrap;
}

.leaderboard-row-meta {
  color: var(--muted);
  font-size: 12px;
  margin-top: 4px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Collapsible secondary panel: same chrome as .action-note, with a clickable
   title that folds the body away. Used for the panels of the player page that
   are edit/maintenance tools rather than information (édition, fusion de
   doublon, données brutes), so the page opens on the read-only summary. */
.wcc-collapse-panel,
.raw-json-toggle {
  overflow: hidden;
}

.wcc-collapse-panel > summary,
.raw-json-toggle summary {
  color: var(--text);
  cursor: pointer;
  font-size: 18px;
  font-weight: 800;
  list-style-position: inside;
}

/* The panel body is a flow of blocks (intro paragraph, form, actions) and
   .action-note zeroes paragraph margins, so space the direct children here
   instead of relying on each block's own margin. */
.wcc-collapse-panel > * + * {
  margin-top: 14px;
}

.raw-json-toggle .raw-json {
  margin-top: 12px;
}

.campaign-card-row strong {
  align-items: flex-start;
  display: inline-flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  text-align: left;
}

.campaign-card-count {
  color: var(--text);
  font-weight: 800;
}

.campaign-card-players {
  color: var(--muted);
  font-size: 12px;
  font-weight: 600;
  max-width: 360px;
  overflow-wrap: anywhere;
}

.bot-status-grid {
  display: grid;
  gap: 0;
}

.bot-status-grid .wcc-list-row {
  min-width: 0;
}

.bot-status-grid .wcc-list-row strong {
  min-width: 0;
  overflow-wrap: anywhere;
  text-align: right;
}

.action-note {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 8px;
  margin-top: 18px;
  padding: 16px;
}

.action-note h2 {
  font-size: 18px;
  margin: 0 0 8px;
}

.action-note p {
  color: var(--muted);
  margin: 0;
}

.command-list {
  display: grid;
  gap: 10px;
}

.command-row {
  align-items: stretch;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-soft);
  display: grid;
  gap: 12px;
  padding: 12px;
  transition: border-color 180ms ease, box-shadow 180ms ease, transform 180ms ease;
}

.command-row:hover,
.command-row:focus-within {
  border-color: rgba(37, 99, 235, 0.28);
  box-shadow: var(--shadow-hover);
}

.command-row.protected-row {
  border-color: #ead57a;
}

.command-header {
  align-items: flex-start;
  display: flex;
  gap: 12px;
  justify-content: space-between;
}

.command-main {
  align-items: center;
  display: flex;
  flex: 1 1 auto;
  flex-wrap: wrap;
  gap: 6px;
  min-width: 0;
  overflow-wrap: anywhere;
}

.command-main strong {
  display: block;
  margin-right: 4px;
}

.command-switches {
  align-items: flex-start;
  display: flex;
  flex: 0 0 auto;
  gap: 10px;
  justify-content: end;
  margin-left: auto;
  white-space: nowrap;
}

.command-switch-form {
  margin: 0;
}

.command-switch {
  align-items: center;
  color: var(--text);
  cursor: pointer;
  display: grid;
  gap: 6px;
  justify-items: center;
  margin: 0;
  min-width: 0;
  user-select: none;
}

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

.command-switch-track {
  background: rgba(148, 163, 184, 0.36);
  border: 1px solid rgba(148, 163, 184, 0.46);
  border-radius: 999px;
  box-shadow: inset 0 1px 2px rgba(15, 23, 42, 0.10);
  display: inline-flex;
  height: 28px;
  position: relative;
  transition: background-color 180ms ease, border-color 180ms ease, box-shadow 180ms ease;
  width: 52px;
}

.command-switch-track::before {
  background: #ffffff;
  border-radius: 999px;
  box-shadow: 0 2px 8px rgba(15, 23, 42, 0.22);
  content: "";
  height: 22px;
  left: 2px;
  position: absolute;
  top: 2px;
  transform: translateX(0);
  transition: transform 180ms ease;
  width: 22px;
}

.command-switch-input:checked + .command-switch-track {
  background: #14b8a6;
  border-color: rgba(20, 184, 166, 0.62);
  box-shadow: 0 0 0 3px rgba(20, 184, 166, 0.12);
}

.command-switch-input:checked + .command-switch-track::before {
  transform: translateX(24px);
}

.command-switch-input:focus-visible + .command-switch-track {
  outline: 2px solid var(--primary);
  outline-offset: 3px;
}

.command-switch-input:disabled + .command-switch-track,
.command-switch-input:disabled ~ .command-switch-copy {
  cursor: not-allowed;
  opacity: 0.55;
}

.command-switch-copy {
  display: grid;
  gap: 0;
  justify-items: center;
  min-width: 0;
}

.command-switch-copy strong {
  color: var(--text);
  font-size: 13px;
  line-height: 1.1;
}

.command-restrictions {
  background: rgba(148, 163, 184, 0.08);
  border: 1px solid rgba(148, 163, 184, 0.18);
  border-radius: var(--radius-md);
  overflow: hidden;
}

.command-restrictions summary {
  align-items: center;
  color: var(--muted);
  cursor: pointer;
  display: grid;
  font-size: 13px;
  font-weight: 700;
  gap: 10px;
  grid-template-columns: minmax(0, 1fr) auto auto;
  list-style: none;
  padding: 10px 12px;
  transition: background-color 180ms ease, color 180ms ease;
}

.command-restrictions summary::-webkit-details-marker {
  display: none;
}

.command-restrictions summary:hover {
  background: rgba(20, 184, 166, 0.08);
  color: var(--text);
}

.command-restrictions-title {
  align-items: center;
  display: inline-flex;
  gap: 8px;
  min-width: 0;
}

.command-restrictions-title svg {
  color: #14b8a6;
  flex: 0 0 auto;
  height: 16px;
  width: 16px;
}

.command-restrictions-hint {
  background: rgba(20, 184, 166, 0.10);
  border: 1px solid rgba(20, 184, 166, 0.18);
  border-radius: 999px;
  color: var(--muted);
  font-size: 11px;
  font-weight: 800;
  line-height: 1;
  padding: 5px 8px;
  text-transform: uppercase;
}

.command-restrictions-chevron {
  color: var(--muted);
  height: 16px;
  transition: transform 180ms ease, color 180ms ease;
  width: 16px;
}

.command-restrictions[open] .command-restrictions-chevron {
  color: #14b8a6;
  transform: rotate(180deg);
}

.command-restrictions-form {
  border-top: 1px solid rgba(148, 163, 184, 0.16);
  display: grid;
  gap: 10px;
  padding: 12px;
}

.command-restrictions-form label {
  display: grid;
  gap: 6px;
}

.command-restrictions-form label span {
  color: var(--muted);
  font-size: 12px;
  font-weight: 700;
}

.command-poll-toggle {
  display: flex;
  justify-content: flex-start;
}

.command-poll-toggle .command-switch {
  align-items: center;
  grid-template-columns: auto minmax(0, 1fr);
  justify-items: start;
}

.command-poll-toggle .command-switch-copy {
  justify-items: start;
}

.command-switch-copy small {
  color: var(--muted);
  font-size: 11px;
  font-weight: 700;
}

.command-poll-options {
  display: grid;
  gap: 8px;
}

.command-poll-options-head,
.command-poll-option-row {
  display: grid;
  gap: 8px;
  grid-template-columns: minmax(0, 1fr) minmax(76px, 120px);
}

.command-poll-options-head {
  color: var(--muted);
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.command-poll-option-row {
  align-items: end;
}

.command-poll-option-row label {
  display: grid;
  gap: 6px;
}

.command-poll-option-row label span {
  color: var(--muted);
  font-size: 12px;
  font-weight: 700;
}

html[data-theme="dark"] .command-switch-track {
  background: rgba(65, 82, 123, 0.72);
  border-color: rgba(103, 232, 249, 0.22);
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.22);
}

html[data-theme="dark"] .command-switch-track::before {
  background: #eef6ff;
}

html[data-theme="dark"] .command-switch-input:checked + .command-switch-track {
  background: rgba(45, 212, 191, 0.78);
  border-color: rgba(103, 232, 249, 0.70);
  box-shadow: 0 0 16px rgba(103, 232, 249, 0.22);
}

html[data-theme="dark"] .command-restrictions {
  background: rgba(19, 27, 57, 0.72);
  border-color: rgba(103, 232, 249, 0.18);
}

html[data-theme="dark"] .command-restrictions summary:hover {
  background: rgba(103, 232, 249, 0.10);
}

html[data-theme="dark"] .command-restrictions-title svg,
html[data-theme="dark"] .command-restrictions[open] .command-restrictions-chevron {
  color: #67e8f9;
}

html[data-theme="dark"] .command-restrictions-hint {
  background: rgba(103, 232, 249, 0.10);
  border-color: rgba(103, 232, 249, 0.18);
}

html[data-theme="ember"] .command-switch-track {
  background: rgba(76, 48, 38, 0.74);
  border-color: rgba(251, 106, 42, 0.24);
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.24);
}

html[data-theme="ember"] .command-switch-track::before {
  background: #fff2e8;
}

html[data-theme="ember"] .command-switch-input:checked + .command-switch-track {
  background: rgba(251, 106, 42, 0.82);
  border-color: rgba(255, 184, 107, 0.72);
  box-shadow: 0 0 16px rgba(251, 106, 42, 0.24);
}

html[data-theme="ember"] .command-restrictions {
  background: rgba(24, 18, 16, 0.76);
  border-color: rgba(251, 106, 42, 0.20);
}

html[data-theme="ember"] .command-restrictions summary:hover {
  background: rgba(251, 106, 42, 0.11);
}

html[data-theme="ember"] .command-restrictions-title svg,
html[data-theme="ember"] .command-restrictions[open] .command-restrictions-chevron {
  color: #fb6a2a;
}

html[data-theme="ember"] .command-restrictions-hint {
  background: rgba(251, 106, 42, 0.11);
  border-color: rgba(251, 106, 42, 0.20);
}

.reaction-role-list {
  display: grid;
  gap: 10px;
}

.reaction-role-quick-create {
  margin-bottom: 18px;
}

.reaction-role-row {
  align-items: center;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-soft);
  display: grid;
  gap: 12px;
  grid-template-columns: minmax(200px, 1.1fr) minmax(140px, 0.7fr) minmax(220px, 1fr) auto;
  padding: 12px;
  transition: border-color 180ms ease, box-shadow 180ms ease, transform 180ms ease;
}

.reaction-role-row:hover,
.reaction-role-row:focus-within {
  border-color: rgba(37, 99, 235, 0.28);
  box-shadow: var(--shadow-hover);
}

.reaction-role-row.warning-row {
  border-color: #ead57a;
}

.reaction-role-main {
  align-items: center;
  display: flex;
  gap: 10px;
  min-width: 0;
}

.reaction-emoji {
  align-items: center;
  background: #f8fafc;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  display: inline-flex;
  flex: 0 0 36px;
  font-size: 22px;
  height: 36px;
  justify-content: center;
  overflow: hidden;
  width: 36px;
}

.reaction-role-main strong {
  display: block;
  overflow-wrap: anywhere;
}

.reaction-role-badges,
.reaction-role-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.reaction-role-description {
  color: var(--muted);
  margin: 0;
  overflow-wrap: anywhere;
}

.reaction-role-style-badge {
  border-radius: var(--radius-md);
  color: #fff;
  font-size: 12px;
  font-weight: 600;
  padding: 3px 9px;
  text-transform: capitalize;
}

.reaction-role-style-badge--primary {
  background: #5865f2;
}

.reaction-role-style-badge--secondary {
  background: #4e5058;
}

.reaction-role-style-badge--success {
  background: #248046;
}

.reaction-role-style-badge--danger {
  background: #ed4245;
}

/* Aperçu d'un bouton Discord. Les quatre couleurs servent aux panneaux de
   rôles comme au parcours d'accueil : une seule définition, deux noms de
   classe, pour que les aperçus ne divergent jamais. */
.reaction-role-button-preview,
.discord-button-preview {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 10px 0 0;
}

.reaction-role-button-chip,
.discord-button-chip {
  border-radius: var(--radius-md);
  color: #fff;
  display: inline-flex;
  font-size: 13px;
  font-weight: 600;
  gap: 6px;
  padding: 6px 12px;
}

.reaction-role-button-chip--primary,
.discord-button-chip--primary {
  background: #5865f2;
}

.reaction-role-button-chip--secondary,
.discord-button-chip--secondary {
  background: #4e5058;
}

.reaction-role-button-chip--success,
.discord-button-chip--success {
  background: #248046;
}

.reaction-role-button-chip--danger,
.discord-button-chip--danger {
  background: #ed4245;
}

.reaction-role-button-overflow {
  color: #ed4245;
  display: block;
  margin-top: 6px;
}

/* Pastilles de réaction : ce que Discord affiche sous le message quand le
   panneau est servi en emojis plutôt qu'en boutons. */
.reaction-role-reaction-preview {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 10px 0 0;
}

.reaction-role-reaction-chip {
  align-items: center;
  background: rgba(78, 80, 88, 0.16);
  border: 1px solid rgba(78, 80, 88, 0.32);
  border-radius: 999px;
  display: inline-flex;
  font-size: 13px;
  gap: 6px;
  line-height: 1;
  padding: 5px 10px;
}

.reaction-role-reaction-count {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  opacity: 0.7;
}

.reaction-role-mode-switch {
  align-items: flex-start;
}

.reaction-role-mode-switch .command-switch-copy .meta {
  display: block;
  margin-top: 2px;
}

/* Ligne d'alerte d'une équipe : badge, liste des noms, bouton copier. Les
   noms passent à la ligne, le bouton reste à portée. */
/* Une équipe par ligne : libellé, rôle, ordre, actif et actions sur la même
   rangée en grand écran, empilés sur téléphone. */
.welcome-team-row,
.welcome-team-add {
  align-items: end;
  display: grid;
  gap: 10px;
  grid-template-columns: 1fr;
}

@media (min-width: 900px) {
  .welcome-team-row {
    grid-template-columns: minmax(120px, 1fr) minmax(160px, 1fr) 90px auto auto;
  }

  .welcome-team-add {
    grid-template-columns: minmax(120px, 1fr) minmax(160px, 1fr) auto;
  }
}

.welcome-team-list {
  display: grid;
  gap: 10px;
}

.welcome-team-row {
  background: rgba(78, 80, 88, 0.06);
  border-radius: var(--radius-md);
  padding: 10px;
}

.welcome-game + .welcome-game {
  margin-top: 16px;
}

.squad-alert-lists {
  display: grid;
  gap: 8px;
  margin-top: 12px;
}

.squad-alert-line {
  align-items: center;
  background: rgba(78, 80, 88, 0.08);
  border-radius: var(--radius-md);
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding: 8px 10px;
}

.squad-alert-line--exclude {
  background: rgba(237, 66, 69, 0.1);
}

.squad-alert-line--watch {
  background: rgba(234, 213, 122, 0.16);
}

.squad-alert-names {
  flex: 1;
  font-size: 13px;
  min-width: 0;
  overflow-wrap: anywhere;
}

.squad-alert-copy {
  flex-shrink: 0;
}

.upload-grid {
  display: grid;
  gap: 12px;
  margin: 12px 0;
}

@media (min-width: 640px) {
  .upload-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.upload-box {
  background: #f8fafc;
  border: 1px dashed #b8c7df;
  border-radius: var(--radius-lg);
  color: var(--muted);
  display: grid;
  font-weight: 700;
  gap: 8px;
  padding: 14px;
}

.upload-box > span {
  color: var(--muted);
}

.upload-box > input {
  color: var(--text);
  font-weight: 400;
  max-width: 100%;
}

.filepond-upload-form {
  display: grid;
  gap: 14px;
}

.campaign-import-mode {
  display: grid;
  gap: 10px;
}

@media (min-width: 640px) {
  .campaign-import-mode {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.campaign-import-mode label {
  align-items: flex-start;
  background: var(--muted-bg);
  border: 1px solid var(--line);
  border-radius: 12px;
  cursor: pointer;
  display: flex;
  gap: 10px;
  margin: 0;
  padding: 10px;
}

.campaign-import-mode input {
  margin-top: 3px;
  width: auto;
}

.campaign-import-mode strong,
.campaign-import-mode small {
  display: block;
}

.campaign-import-mode small {
  color: var(--muted);
  font-size: 12px;
}

.filepond-upload-form .upload-grid {
  margin: 0;
}

.filepond-upload-form .upload-grid[hidden],
.filepond-upload-form .upload-grid.is-hidden {
  display: none !important;
}

.filepond-upload-form .upload-box {
  padding: 12px;
}

.filepond-upload-progress {
  background: var(--muted-bg);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  display: grid;
  gap: 9px;
  padding: 12px;
}

.filepond-upload-progress[hidden] {
  display: none;
}

.filepond-upload-progress-head {
  align-items: center;
  color: var(--muted);
  display: flex;
  gap: 12px;
  justify-content: space-between;
}

.filepond-upload-progress-head strong,
.filepond-upload-progress-head span {
  color: var(--text);
  font-weight: 850;
}

.progress-card {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-soft);
  display: grid;
  gap: 10px;
  margin: 12px 0 18px;
  padding: 14px;
}

.progress-card.active {
  border-color: #9db7f2;
}

.progress-card.done {
  border-color: #9bd5af;
}

.progress-card.failed {
  border-color: #eea2a2;
}

.progress-head {
  align-items: start;
  display: flex;
  gap: 14px;
  justify-content: space-between;
}

.progress-head h2 {
  font-size: 16px;
  margin: 0 0 2px;
}

.progress-head p {
  color: var(--muted);
  margin: 0;
  overflow-wrap: anywhere;
}

.progress-head strong {
  color: var(--accent);
  font-size: 18px;
}

.progress-track {
  background: #e9edf4;
  border-radius: 999px;
  height: 10px;
  overflow: hidden;
}

.progress-fill {
  background: linear-gradient(90deg, #4f46e5, #22d3ee);
  border-radius: inherit;
  height: 100%;
  min-width: 0;
  transition: width 220ms ease;
}

.progress-meta {
  color: var(--muted);
  display: flex;
  flex-wrap: wrap;
  font-size: 12px;
  gap: 8px 14px;
}

.campaign-row-list {
  display: grid;
  gap: 10px;
}

.sr-only {
  clip: rect(0, 0, 0, 0);
  border: 0;
  height: 1px;
  margin: -1px;
  overflow: hidden;
  padding: 0;
  position: absolute;
  white-space: nowrap;
  width: 1px;
}

.campaign-import-row {
  align-items: end;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-soft);
  display: grid;
  gap: 12px;
  grid-template-columns: minmax(170px, 1fr) minmax(220px, 1.2fr) minmax(150px, 1fr) 90px 150px minmax(160px, 1fr) auto;
  padding: 12px;
  transition: border-color 180ms ease, box-shadow 180ms ease, transform 180ms ease;
}

.campaign-import-row:hover,
.campaign-import-row:focus-within {
  border-color: rgba(37, 99, 235, 0.28);
  box-shadow: var(--shadow-hover);
}

.campaign-import-row.warning-row {
  border-color: #ead57a;
}

.campaign-import-main {
  min-width: 0;
  overflow-wrap: anywhere;
}

.campaign-import-main strong {
  display: block;
  margin-bottom: 4px;
}

/* La fusion prend toute la largeur de la carte : le select doit rester
   lisible (il porte le nom et les deux scores de la ligne absorbée). */
.campaign-import-merge {
  grid-column: 1 / -1;
}

.campaign-import-merge-controls {
  align-items: center;
  display: flex;
  gap: 8px;
}

.campaign-import-merge-controls select {
  flex: 1;
  min-width: 0;
}

/* Sections de la relecture OCR : « À corriger » d'abord, « Scores OK »
   ensuite. */
.campaign-review-group {
  align-items: center;
  display: flex;
  font-size: 15px;
  gap: 8px;
  margin: 18px 0 8px;
}

/* Lignes d'un import déjà committé : repliées, elles ne séparent plus le haut
   de page de l'encart du message Discord. */
.campaign-committed-rows {
  padding: 12px 14px;
}

.campaign-committed-rows > summary {
  cursor: pointer;
  font-weight: 600;
}

.campaign-committed-rows[open] > summary {
  margin-bottom: 10px;
}

.campaign-history {
  padding: 0;
}

.campaign-history-head,
.campaign-history-row {
  align-items: center;
  display: grid;
  gap: 8px;
  grid-template-columns: 4px minmax(82px, 0.8fr) 48px 24px minmax(170px, 2fr);
  padding: 12px 14px;
}

/* Mini placement accent (same gradient principle as the hub cards, smaller). */
.campaign-history-accent {
  align-self: center;
  background: linear-gradient(180deg, #67e8f9, #3b82f6);
  border-radius: 999px;
  height: 26px;
  width: 4px;
}

.campaign-history-accent--green {
  background: linear-gradient(180deg, var(--tier-4-grad), var(--tier-4));
}

.campaign-history-accent--blue {
  background: linear-gradient(180deg, var(--tier-3-grad), var(--tier-3));
}

.campaign-history-accent--yellow {
  background: linear-gradient(180deg, var(--tier-2-grad), var(--tier-2));
}

.campaign-history-accent--red {
  background: linear-gradient(180deg, var(--tier-1-grad), var(--tier-1));
}

.campaign-history-head {
  border-bottom: 1px solid var(--line);
  color: var(--muted);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.campaign-history-row {
  color: var(--text);
  text-decoration: none;
}

.campaign-history-row + .campaign-history-row {
  border-top: 1px solid var(--line);
}

.campaign-history-row:hover {
  background: var(--muted-bg);
}

.campaign-date {
  color: var(--primary);
  font-weight: 700;
}

.campaign-history-row:hover .campaign-date {
  color: var(--primary-hover);
}

.campaign-placement {
  font-weight: 700;
}

.campaign-results-cell {
  align-items: center;
  display: inline-flex;
  justify-content: center;
  min-height: 18px;
}

.campaign-results-icon {
  color: var(--accent);
  flex: 0 0 auto;
  height: 16px;
  width: 16px;
}

.campaign-icon-groups,
.campaign-factions {
  align-items: center;
  display: inline-flex;
  flex-wrap: wrap;
  gap: 5px;
  min-width: 0;
}

/* Right-align the factions column (header label + row icons). */
.campaign-history-head span:last-child {
  justify-self: end;
  text-align: right;
}

.campaign-history-row .campaign-icon-groups {
  justify-content: flex-end;
  justify-self: end;
}

.campaign-versus {
  color: var(--muted);
  font-size: 11px;
  font-weight: 700;
  margin: 0 2px;
  text-transform: uppercase;
}

.campaign-faction {
  align-items: center;
  display: inline-flex;
  gap: 6px;
  min-width: 0;
}

.campaign-faction img {
  display: block;
  flex: 0 0 auto;
  height: 28px;
  object-fit: contain;
  width: 28px;
}

.campaign-faction.with-label {
  background: var(--muted-bg);
  border: 1px solid var(--line);
  border-radius: 999px;
  max-width: 100%;
  padding: 3px 9px 3px 4px;
}

.campaign-faction.with-label span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.campaign-results-list {
  display: grid;
  gap: 6px;
}

.campaign-result-row {
  align-items: center;
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  cursor: pointer;
  display: flex;
  gap: 8px;
  justify-content: space-between;
  min-width: 0;
  padding: 8px 10px;
  transition: border-color 160ms ease, box-shadow 160ms ease, transform 160ms ease;
}

.campaign-result-row:hover {
  box-shadow: 0 8px 18px rgba(15, 23, 42, 0.08);
  transform: translateY(-1px);
}

.campaign-result-row:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.campaign-result-player {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.campaign-result-wins {
  flex: 0 0 auto;
  font-weight: 800;
  line-height: 1;
  text-align: right;
}

.campaign-result-edit-icon {
  color: var(--muted);
  flex: 0 0 auto;
  height: 16px;
  width: 16px;
}

.campaign-result-wins {
  min-width: 42px;
}

.result-tone-green {
  background: var(--tier-4-soft);
  border-color: var(--tier-4-line);
  color: var(--tier-4-ink);
}

.result-tone-blue {
  background: var(--tier-3-soft);
  border-color: var(--tier-3-line);
  color: var(--tier-3-ink);
}

.result-tone-yellow {
  background: var(--tier-2-soft);
  border-color: var(--tier-2-line);
  color: var(--tier-2-ink);
}

.result-tone-red {
  background: var(--tier-1-soft);
  border-color: var(--tier-1-line);
  color: var(--tier-1-ink);
}

.result-tone-neutral {
  background: var(--muted-bg);
  border-color: var(--line);
  color: var(--text);
}

.discord-preview {
  background: #f7f8fb;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  font: 14px/1.45 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  margin: 12px 0;
  max-width: 100%;
  overflow-x: auto;
  padding: 14px;
  white-space: pre-wrap;
}

.inline-warning {
  color: #665200;
  font-size: 12px;
  grid-column: 1 / -1;
}

.campaign-history-row,
.rank-watch-row,
.tool-list-row,
.hub-card {
  -webkit-tap-highlight-color: transparent;
}

tr.clickable-row {
  cursor: pointer;
}

.roster-list {
  padding: 0;
}

.roster-list-head,
.roster-row {
  align-items: center;
  display: grid;
  gap: 8px;
  grid-template-columns: minmax(0, 1.35fr) minmax(82px, 0.8fr) minmax(76px, auto);
  padding: 12px 14px;
}

.roster-list-head {
  border-bottom: 1px solid var(--line);
  color: var(--muted);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.roster-row {
  color: var(--text);
  min-width: 0;
  text-decoration: none;
  -webkit-tap-highlight-color: transparent;
}

.roster-row + .roster-row {
  border-top: 1px solid var(--line);
}

.roster-row:hover {
  background: var(--muted-bg);
}

.roster-player-name {
  align-items: center;
  color: var(--primary);
  display: flex;
  font-weight: 800;
  gap: 2px;
  min-width: 0;
}

/* Le nom seul se laisse tronquer : l'indicateur, lui, ne doit jamais partir
   sous l'ellipse, sinon il n'alerte plus personne. */
.roster-player-label {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Joueur actif sans résultat sur la dernière campagne. Ambre de l'échelle de
   valeur (--tier-2) : chaque thème la redéfinit, l'alerte suit. */
.player-exit-help {
  color: var(--muted);
  font-size: 12px;
  line-height: 1.5;
  list-style: none;
  margin: 10px 0 0;
  padding: 0;
}

.player-exit-help li + li {
  margin-top: 6px;
}

.roster-player-flag {
  color: var(--tier-2);
  flex: none;
  height: 15px;
  margin-left: 6px;
  width: 15px;
}

.roster-missing-legend {
  align-items: center;
  color: var(--tier-2);
  display: flex;
  font-size: 13px;
  font-weight: 600;
  gap: 6px;
  margin-top: 4px;
}

.roster-missing-legend i {
  height: 15px;
  width: 15px;
}

.roster-player-rank {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

.roster-player-status {
  justify-self: end;
}

html[data-theme="dark"] .roster-row:hover {
  background: rgba(103, 232, 249, 0.08);
}

html[data-theme="ember"] .roster-row:hover {
  background: rgba(251, 106, 42, 0.09);
}

.wcc-pagination {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  justify-content: center;
  margin: 16px 0 4px;
}

.wcc-pagination-status {
  color: var(--muted);
  display: inline-flex;
  flex-direction: column;
  font-size: 12px;
  font-weight: 700;
  line-height: 1.25;
  text-align: center;
}

.wcc-pagination-status small {
  color: var(--muted);
  font-size: 11px;
  font-weight: 600;
  opacity: 0.85;
}

.wcc-theme-menu.open .wcc-theme-menu-panel {
  display: grid;
}

html[data-theme="dark"] .wcc-theme-menu .wcc-theme-menu-button {
  background: rgba(103, 232, 249, 0.12);
  border-color: rgba(103, 232, 249, 0.34);
  color: #9ef4ff;
}

html[data-theme="dark"] .wcc-theme-menu .wcc-theme-menu-button:hover,
html[data-theme="dark"] .wcc-theme-menu.open .wcc-theme-menu-button {
  background: rgba(103, 232, 249, 0.18);
  border-color: rgba(103, 232, 249, 0.40);
}

html[data-theme="dark"] .wcc-theme-menu .wcc-theme-option:hover,
html[data-theme="dark"] .wcc-theme-menu .wcc-theme-option.active {
  background: rgba(103, 232, 249, 0.12);
  border-color: rgba(103, 232, 249, 0.28);
}

html[data-theme="ember"] .wcc-theme-menu .wcc-theme-menu-button {
  background: rgba(251, 106, 42, 0.14);
  border-color: rgba(251, 106, 42, 0.38);
  color: #ffb86b;
}

html[data-theme="ember"] .wcc-theme-menu .wcc-theme-menu-button:hover,
html[data-theme="ember"] .wcc-theme-menu.open .wcc-theme-menu-button {
  background: rgba(251, 106, 42, 0.20);
  border-color: rgba(251, 106, 42, 0.44);
}

html[data-theme="ember"] .wcc-theme-menu .wcc-theme-option:hover,
html[data-theme="ember"] .wcc-theme-menu .wcc-theme-option.active {
  background: rgba(251, 106, 42, 0.14);
  border-color: rgba(251, 106, 42, 0.32);
}

/* The gear has no bottom-nav tab of its own (Admin/Settings/Commandes/Actions/
   Audit sit outside the 5 tabs), so it carries its own active state — same
   accent recipe as the hover, generic across all themes since it only reads
   tokens. Resting state stays highlighted; the hover lift only applies on
   top of it, it isn't part of the resting look. */
body .wcc-settings-bubble.active {
  background: var(--accent-soft);
  border-color: color-mix(in srgb, var(--accent) 28%, transparent);
  color: var(--accent);
}

body .wcc-bot-reload:hover,
body .wcc-settings-bubble:hover,
body .wcc-settings-bubble.active:hover {
  background: var(--accent-soft);
  border-color: color-mix(in srgb, var(--accent) 28%, transparent);
  box-shadow: 0 10px 24px color-mix(in srgb, var(--accent) 18%, transparent);
  color: var(--accent);
  transform: translateY(-1px);
}

.spaced-head {
  margin-top: 24px;
}

.settings-grid {
  display: grid;
  gap: 12px;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  margin-bottom: 20px;
}

.setting-card:focus-within,
.setting-card:hover {
  border-color: rgba(37, 99, 235, 0.28);
  box-shadow: var(--shadow-hover);
}

.setting-card.error-card {
  border-color: #f0b5b5;
}

.setting-card-head {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-bottom: 12px;
  overflow-wrap: anywhere;
}

.compact-textarea {
  min-height: 68px;
  overflow-wrap: anywhere;
}

.reaction-message-template {
  min-height: 150px;
}

.welcome-message-template {
  min-height: 170px;
}

.welcome-preview-message {
  white-space: pre-wrap;
}

.dashboard-widget-grid {
  align-items: stretch;
  display: grid;
  gap: 12px;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.dashboard-widget {
  min-width: 0;
}

/* ============================================================================
   Small dashboard widgets — minimalist zebra "tables".
   Rows are single-line label|value pairs, flush against each other, with an
   alternating row background. Selectors are scoped under .dashboard-widget-grid
   and use !important where needed to beat the generic .wcc-section / mobile
   .wcc-list-row rules coming from the later-loaded Tailwind bundle (output.css).
   ========================================================================== */
/* Uniform tile height: every small widget is at least this tall, and
   align-items: stretch on the grid makes the two widgets in a row match
   exactly, so the small-widget grid reads as a clean, even set of tiles.
   Chart widgets fill the leftover height (see .dashboard-chart below). */
.dashboard-widget-grid .dashboard-widget-is-small {
  display: flex;
  flex-direction: column;
  gap: 7px;
  min-height: 15.5rem;
  padding: 10px;
}

/* Left-align small-widget headers (title, then badge/button below-left) so
   they match the large widgets and each other — centring made short titles
   look centred while wrapping titles stayed left. */
.dashboard-widget-is-small .wcc-page-header {
  align-items: flex-start;
  gap: 4px 6px;
  margin-bottom: 0;
}

.dashboard-widget-is-small .wcc-page-header h1,
.dashboard-widget-is-small .wcc-page-header h2,
.dashboard-widget-is-small > h2 {
  font-size: 0.82rem !important;
  font-weight: 700;
  letter-spacing: 0.01em;
  line-height: 1.2;
  margin: 0 0 1px !important;
}

.dashboard-widget-is-small .wcc-page-header p {
  display: none;
}

/* Compact badges (heartbeat OK, actif(s), arrivée…). */
.dashboard-widget-is-small .wcc-badge {
  font-size: 0.6rem;
  font-weight: 700;
  gap: 3px;
  min-height: 18px;
  padding: 1px 6px;
  white-space: nowrap;
}

.dashboard-widget-is-small .wcc-button-small {
  font-size: 0.68rem;
  min-height: 24px;
  padding: 2px 8px;
}

/* The chart grows to fill the height left under the header, and the render
   JS reads this box's clientHeight and draws the Apex chart at exactly that
   many pixels — so the chart uses the whole tile instead of leaving a band
   of white at the bottom. */
.dashboard-widget-is-small .dashboard-chart {
  flex: 1 1 auto;
  min-height: 0;
}

/* --- Table wrappers: one bordered, rounded, clipped block per list. ---
   margin-top: auto pushes the table to the bottom of the tile, so the gap
   below it equals the tile's side padding (the title stays pinned at the
   top). Any slack from the uniform tile height sits between title and table
   instead of piling up under the table. */
.dashboard-widget-grid .dashboard-widget-is-small .bot-status-grid,
.dashboard-widget-grid .dashboard-widget-is-small .dashboard-mini-list,
.dashboard-widget-grid .dashboard-widget-is-small .dashboard-mini-table,
.dashboard-widget-grid .dashboard-widget-is-small .rank-watchlist,
.dashboard-widget-grid .dashboard-widget-is-small .grid.gap-2 {
  border: 1px solid var(--line);
  border-radius: 8px;
  display: block;
  gap: 0 !important;
  margin: auto 0 0 !important;
  overflow: hidden;
}

/* --- Table rows: single line, flush, zebra-striped. ---
   Every small-widget row shares one look regardless of its source component
   (.wcc-list-row, .rank-watch-row, .dashboard-mini-list rows). The base
   background is reset to transparent so the zebra is driven solely by the
   :nth-of-type(even) rule below (same muted-bg on both widgets), instead of
   .rank-watch-row's hardcoded #f8fafc leaking a second tint. flex-wrap is
   forced off so a long label can never push its value onto a second line —
   .wcc-list-row ships flex-wrap: wrap from the canonical component. */
.dashboard-widget-grid .dashboard-widget-is-small .wcc-list-row,
.dashboard-widget-grid .dashboard-widget-is-small .dashboard-mini-list > div,
.dashboard-widget-grid .dashboard-widget-is-small .rank-watch-row {
  align-items: center !important;
  background: transparent;
  border: 0 !important;
  border-radius: 0 !important;
  display: flex !important;
  flex-direction: row !important;
  flex-wrap: nowrap !important;
  gap: 8px !important;
  justify-content: space-between;
  /* Uniform row height across every zebra widget. rank_watchlist rows are
     naturally taller because of their inner pill (→ V 10); this floor makes
     the plain-text rows match it so all widgets line up. */
  min-height: 2rem;
  padding: 4px 8px !important;
}

.dashboard-widget-grid .dashboard-widget-is-small .wcc-list-row + .wcc-list-row,
.dashboard-widget-grid .dashboard-widget-is-small .rank-watch-row + .rank-watch-row {
  border-top: 0 !important;
}

.dashboard-widget-is-small .wcc-list-row:nth-of-type(even),
.dashboard-widget-is-small .dashboard-mini-list > div:nth-of-type(even),
.dashboard-widget-is-small .rank-watch-row:nth-of-type(even) {
  background: var(--muted-bg);
}

/* Left cell = muted label / title (grows, truncates). */
.dashboard-widget-is-small .wcc-list-row > *:first-child,
.dashboard-widget-is-small .dashboard-mini-list > div > *:first-child {
  color: var(--muted);
  flex: 1 1 auto;
  font-size: 0.72rem;
  font-weight: 600;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Right cell = bold value (any direct <strong>, or the trailing <dd>).
   Not :last-child — leaderboard rows carry a hidden trailing .meta node. */
.dashboard-widget-is-small .wcc-list-row > strong,
.dashboard-widget-is-small .dashboard-mini-list > div > *:last-child {
  color: var(--text);
  flex: 0 0 auto;
  font-size: 0.72rem;
  font-weight: 800;
  max-width: 60%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Drop secondary lines (subtitles, meta) — keep every row to one line. */
.dashboard-widget-is-small .wcc-list-row small,
.dashboard-widget-is-small .activity-leaderboard-row .meta {
  display: none;
}

/* "badge/dot + name" rows (leaderboard, member events): badge stays put, name
   truncates. */
.dashboard-widget-is-small .wcc-list-row > span:first-child:has(.wcc-badge),
.dashboard-widget-is-small .wcc-list-row > span:first-child:has(.dashboard-dot),
.dashboard-widget-is-small .wcc-list-row > span:first-child:has(.dashboard-event-arrow) {
  align-items: center;
  color: inherit;
  display: flex;
  gap: 5px;
}

.dashboard-widget-is-small .wcc-list-row > span:first-child:has(.wcc-badge) > strong,
.dashboard-widget-is-small .wcc-list-row > span:first-child:has(.dashboard-dot) > strong,
.dashboard-widget-is-small .wcc-list-row > span:first-child:has(.dashboard-event-arrow) > strong {
  color: var(--text);
  font-size: 0.72rem;
  font-weight: 700;
  margin-left: 0 !important;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Tiny status dot replacing wide text badges (member events). */
.dashboard-dot {
  border-radius: 999px;
  flex: 0 0 auto;
  height: 8px;
  width: 8px;
}

.dashboard-dot-success { background: var(--tier-4); }
.dashboard-dot-danger { background: var(--tier-1); }
.dashboard-dot-neutral { background: var(--muted); }

.dashboard-event-arrow {
  flex: 0 0 auto;
  height: 13px;
  stroke-width: 3;
  width: 13px;
}

.dashboard-event-arrow-success { color: var(--tier-4); }
.dashboard-event-arrow-danger { color: var(--tier-1); }
.dashboard-event-arrow-neutral { color: var(--muted); }

/* --- Compteurs: single-column table, never split into vertical cells. --- */
.dashboard-mini-list {
  display: grid;
  gap: 6px;
}

.dashboard-mini-table {
  display: grid;
}

/* --- Rank watchlist: name | wins + missing, on one zebra line. --- */
.dashboard-widget-is-small .rank-watch-row > strong {
  color: var(--text);
  flex: 1 1 auto;
  font-size: 0.72rem;
  font-weight: 700;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Keep only the headline metric (wins still needed for promotion) — drop the
   current rank arrow and the current/target detail. */
.dashboard-widget-is-small .rank-watch-target,
.dashboard-widget-is-small .rank-watch-wins {
  display: none;
}

.dashboard-widget-is-small .rank-watch-missing {
  align-items: center;
  display: inline-flex;
  flex: 0 0 auto;
  font-size: 0.72rem;
  font-weight: 800;
  gap: 2px;
  grid-row: auto;
  padding: 1px 6px;
}

/* --- À surveiller: name | red cards, on one zebra line. ---
   Must sit after the generic `.wcc-list-row > strong` rule above: same
   specificity, and the name has to keep growing and truncating instead of
   being pinned right like a value cell. */
.dashboard-widget-is-small .card-watch-row > strong {
  color: var(--text);
  flex: 1 1 auto;
  font-size: 0.72rem;
  font-weight: 700;
  max-width: none;
  min-width: 0;
  overflow: hidden;
  text-align: left;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.dashboard-widget-is-small .card-watch-count {
  font-size: 0.72rem;
}

/* --- Factions in a small tile: the name cell inherits the generic
   "first child grows and truncates" rule; only the text needs to stop looking
   like a muted label, and the artwork needs to shrink. --- */
.dashboard-widget-is-small .faction-rank-name {
  gap: 5px;
}

.dashboard-widget-is-small .faction-rank-label {
  color: var(--text);
  font-weight: 700;
}

.dashboard-widget-is-small .faction-rank-icon {
  height: 18px;
  width: 18px;
}

/* --- Dernier appel / dernier sondage: single-line "name | value" rows.
   Force every row onto one line (ellipsis on the name) in BOTH sizes; small
   mode inherits the generic .wcc-list-row zebra treatment. The compound
   .wcc-list-row.dashboard-result-row selector is needed to beat the mobile
   `.wcc-list-row { flex-direction: column !important }` rule from output.css. --- */
/* Constrain the (large-mode) grid column so rows never grow to their
   max-content width — otherwise the name never shrinks and pushes the value
   off the card edge. */
.dashboard-result-list {
  grid-template-columns: minmax(0, 1fr);
}

.wcc-list-row.dashboard-result-row {
  align-items: center !important;
  flex-direction: row !important;
  flex-wrap: nowrap;
  gap: 10px !important;
  min-width: 0;
}

.dashboard-result-row > .dashboard-result-name {
  color: var(--text);
  flex: 1 1 auto;
  font-weight: 600;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.dashboard-result-row > .dashboard-result-value {
  flex: 0 0 auto;
  white-space: nowrap;
}

/* Small mode: the right cell may be a status pill (span) rather than a
   <strong>, so size it explicitly like the other compact right cells. */
.dashboard-widget-grid .dashboard-widget-is-small .dashboard-result-row > .wcc-badge {
  flex: 0 0 auto;
  font-size: 0.6rem;
  font-weight: 700;
  min-height: 16px;
  padding: 1px 6px;
}

/* --- Raccourcis: icon-only tiles (labels via title/aria-label). --- */
.dashboard-shortcut-grid-compact {
  display: grid;
  gap: 6px;
  grid-template-columns: repeat(4, minmax(0, 1fr));
}

.dashboard-widget-grid .dashboard-shortcut-grid-compact .wcc-card {
  align-items: center;
  aspect-ratio: 1 / 1;
  border-radius: 8px;
  display: flex;
  justify-content: center;
  min-height: 0;
  padding: 0;
}

.dashboard-shortcut-grid-compact .wcc-card i[data-lucide] {
  color: var(--accent, #2563eb);
  flex: 0 0 auto;
  height: 20px;
  width: 20px;
}

.dashboard-shortcut-grid-compact .wcc-card strong {
  display: none;
}

.dashboard-widget-small {
  grid-column: span 1;
}

.dashboard-widget-large {
  grid-column: 1 / -1;
}

.dashboard-customizer[hidden] {
  display: none;
}

.dashboard-customizer {
  align-items: flex-end;
  backdrop-filter: blur(14px);
  background: rgba(5, 8, 20, 0.58);
  display: flex;
  inset: 0;
  justify-content: center;
  padding: 16px;
  position: fixed;
  z-index: 80;
}

.dashboard-customizer-panel {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 18px;
  box-shadow: 0 24px 80px rgba(0, 0, 0, 0.34);
  max-height: min(82vh, 760px);
  overflow: auto;
  padding: 16px;
  width: min(760px, 100%);
}

.dashboard-widget-editor-list {
  display: grid;
  gap: 12px;
}

/* --- Avertissements: une ligne par joueur retenu par les filtres. ---
   Mobile d'abord : case à cocher + identité sur la première colonne, compteurs
   de cartons calés à droite. La ligne entière est un <label>, donc toucher
   n'importe où bascule la case — cible bien plus large qu'une case de 16px. */
.warning-candidate-list {
  display: grid;
  gap: 8px;
}

.warning-candidate-row {
  align-items: center;
  background: var(--muted-bg);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  cursor: pointer;
  display: grid;
  gap: 10px;
  grid-template-columns: auto minmax(0, 1fr) auto;
  padding: 10px 12px;
}

.warning-candidate-row:hover {
  border-color: var(--accent);
}

.warning-candidate-row input[type="checkbox"] {
  flex: 0 0 auto;
  height: 18px;
  margin: 0;
  width: 18px;
}

.warning-candidate-main {
  display: grid;
  gap: 2px;
  min-width: 0;
}

.warning-candidate-main strong,
.warning-candidate-main .meta {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.warning-candidate-cards {
  display: inline-flex;
  flex: 0 0 auto;
  gap: 10px;
}

.warning-card-count {
  align-items: center;
  display: inline-flex;
  font-variant-numeric: tabular-nums;
  font-weight: 800;
  gap: 4px;
  white-space: nowrap;
}

/* --- File de sondages: une ligne par sondage en attente. ---
   Mobile d'abord : poignée + contenu sur la première ligne, boutons repliés
   dessous en pleine largeur ; à partir de sm, tout revient sur une ligne.
   Réutilise .dashboard-widget-drag-handle, la poignée déjà éprouvée du
   personnalisateur de dashboard. */
.poll-pipeline-list {
  display: grid;
  gap: 8px;
  margin-bottom: 12px;
}

.poll-pipeline-row {
  align-items: center;
  background: var(--muted-bg);
  border: 1px solid var(--line);
  border-radius: 12px;
  display: grid;
  gap: 10px;
  grid-template-columns: auto minmax(0, 1fr);
  padding: 12px;
  touch-action: manipulation;
}

.poll-pipeline-row.is-dragging {
  border-color: var(--accent);
  box-shadow: 0 0 0 1px rgba(88, 219, 236, 0.28), 0 16px 34px rgba(0, 0, 0, 0.24);
  opacity: 0.92;
}

.poll-pipeline-main {
  display: grid;
  gap: 2px;
  min-width: 0;
}

.poll-pipeline-main strong,
.poll-pipeline-main small,
.poll-pipeline-main .meta {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.poll-pipeline-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  grid-column: 1 / -1;
}

.poll-pipeline-actions form {
  display: contents;
}

@media (min-width: 640px) {
  .poll-pipeline-row {
    grid-template-columns: auto minmax(0, 1fr) auto;
  }

  .poll-pipeline-actions {
    flex-wrap: nowrap;
    grid-column: auto;
  }
}

.dashboard-widget-editor-row {
  align-items: center;
  background: var(--muted-bg);
  border: 1px solid var(--line);
  border-radius: 12px;
  display: grid;
  gap: 12px;
  grid-template-columns: auto minmax(0, 1fr) auto auto;
  padding: 12px;
  touch-action: manipulation;
}

.dashboard-widget-editor-row.is-dragging {
  border-color: var(--accent);
  box-shadow: 0 0 0 1px rgba(88, 219, 236, 0.28), 0 16px 34px rgba(0, 0, 0, 0.24);
  opacity: 0.92;
}

.dashboard-widget-drag-handle {
  align-items: center;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 10px;
  color: var(--muted);
  cursor: grab;
  display: inline-flex;
  height: 36px;
  justify-content: center;
  touch-action: none;
  width: 36px;
}

.dashboard-widget-drag-handle:active {
  cursor: grabbing;
}

.dashboard-widget-editor-main {
  display: grid;
  gap: 2px;
  min-width: 0;
}

.dashboard-widget-editor-main strong,
.dashboard-widget-editor-main small {
  min-width: 0;
  overflow-wrap: anywhere;
}

.dashboard-widget-editor-main small {
  color: var(--muted);
}

.dashboard-widget-size-control {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 999px;
  display: inline-flex;
  gap: 4px;
  padding: 3px;
}

.dashboard-widget-size-control label {
  cursor: pointer;
}

.dashboard-widget-size-control input {
  opacity: 0;
  pointer-events: none;
  position: absolute;
}

.dashboard-widget-size-control span {
  border-radius: 999px;
  color: var(--muted);
  display: inline-flex;
  font-size: 13px;
  font-weight: 700;
  justify-content: center;
  min-width: 64px;
  padding: 7px 12px;
}

.dashboard-widget-size-control input:checked + span {
  background: var(--accent);
  color: var(--bg);
}

.dashboard-customizer-actions {
  align-items: center;
  display: flex;
  gap: 16px;
  justify-content: space-between;
  margin-top: 16px;
}

[data-dashboard-widget-status][data-tone="success"] {
  color: var(--success);
}

[data-dashboard-widget-status][data-tone="error"] {
  color: var(--danger);
}

@media (max-width: 768px) {
  .dashboard-customizer {
    padding: 12px;
  }

  .dashboard-customizer-panel {
    border-radius: 16px;
    max-height: 86vh;
  }

  .dashboard-widget-editor-row {
    grid-template-columns: auto minmax(0, 1fr);
  }

  .dashboard-widget-enabled,
  .dashboard-widget-size-control {
    grid-column: 1 / -1;
  }

  .dashboard-customizer-actions {
    align-items: stretch;
    flex-direction: column;
  }}

.reaction-message-preview {
  max-height: 360px;
}

.template-preview {
  border-top: 1px solid var(--line);
  margin: 12px 0;
  padding-top: 10px;
}

.template-preview-box {
  background: #f8fafc;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  display: block;
  line-height: 1.45;
  margin: 6px 0;
  overflow-x: auto;
  padding: 10px;
  white-space: normal;
  word-break: break-word;
}

.template-preview-icon {
  display: inline-block;
  height: 1.35em;
  margin: 0 0.18em;
  object-fit: contain;
  vertical-align: -0.28em;
  width: 1.35em;
}

.template-preview-text {
  display: inline;
}

.template-preview small {
  color: var(--muted);
}

.error-text {
  color: var(--tone-danger-fg);
}

.call-response-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  justify-content: flex-end;
}

.rank-watchlist {
  display: grid;
  gap: 8px;
}

.rank-watch-row {
  align-items: center;
  background: #f8fafc;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  display: grid;
  gap: 4px 8px;
  grid-template-columns: minmax(0, 1fr) auto;
  padding: 9px 10px;
  transition: border-color 160ms ease, box-shadow 160ms ease, transform 160ms ease;
}

.rank-watch-row:hover {
  border-color: #93c5fd;
  box-shadow: var(--shadow-soft);
  transform: translateY(-1px);
}

.rank-watch-row strong {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.rank-watch-target {
  color: var(--muted);
  font-size: 12px;
}

/* --- À surveiller: nom | moyenne | cartons jaunes | cartons rouges. ---
   Reuses .wcc-list-row, so only the cells need styling. The card counters
   borrow the icon vocabulary of the player and campaign sheets
   (.icon-inline--card-*) rather than the value scale: a "carton rouge" is a
   named object whose colour is its identity, not a rating. */
/* Doubled class: the canonical `.wcc-list-row > strong` pins value cells to
   the right, and it ships from dist/output.css, which loads after this file. */
.wcc-list-row.card-watch-row > strong {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-align: left;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.card-watch-average {
  color: var(--muted);
  flex: 0 0 auto;
  font-size: 12px;
  font-weight: 700;
  white-space: nowrap;
}

.card-watch-count {
  align-items: center;
  display: inline-flex;
  flex: 0 0 auto;
  font-variant-numeric: tabular-nums;
  font-weight: 800;
  gap: 4px;
  white-space: nowrap;
}

/* --- Factions: (icon + name) | average placement. ---
   Same faction artwork as the campaign rows (/img/faction-*.png), smaller so
   nine of them fit a widget tile. Icon and name share one first-child cell,
   like the badge/dot rows of the leaderboard and member-event widgets: the
   generic small-widget rules then grow and truncate that whole cell, and the
   trailing <strong> stays the right-aligned value. Large mode splits the nine
   into two columns; small mode keeps one and the template caps it at five. */
.faction-rank-grid {
  grid-template-columns: minmax(0, 1fr);
}

.dashboard-widget-is-large .faction-rank-grid {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.faction-rank-name {
  align-items: center;
  color: inherit;
  display: flex;
  gap: 8px;
  min-width: 0;
}

.faction-rank-label {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.faction-rank-icon {
  align-items: center;
  display: inline-flex;
  flex: 0 0 auto;
  height: 22px;
  justify-content: center;
  width: 22px;
}

.faction-rank-icon img {
  display: block;
  height: 100%;
  object-fit: contain;
  width: 100%;
}

.faction-rank-average {
  flex: 0 0 auto;
  font-variant-numeric: tabular-nums;
  font-weight: 800;
  white-space: nowrap;
}

.rank-watch-wins,
.rank-watch-missing {
  font-weight: 800;
  text-align: right;
  white-space: nowrap;
}

.rank-watch-wins {
  color: #1e3a8a;
}

.rank-watch-missing {
  background: #eff6ff;
  border: 1px solid #bfdbfe;
  border-radius: 999px;
  color: #1d4ed8;
  grid-row: span 2;
  padding: 3px 8px;
}

.rank-message-grid {
  display: grid;
  gap: 12px;
}

@media (min-width: 900px) {
  .rank-message-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }}

@media (max-width: 760px) {
  /* Nine factions side by side do not fit a phone: back to one column. */
  .dashboard-widget-is-large .faction-rank-grid {
    grid-template-columns: minmax(0, 1fr);
  }

  .phase-row {
    align-items: stretch;
    grid-template-columns: 1fr;
  }

  .phase-dates {
    grid-template-columns: 1fr 1fr;
  }

  .phase-duration input {
    max-width: none;
  }

  .phase-row button {
    justify-self: stretch;
    width: 100%;
  }

  .command-row {
    align-items: stretch;
    grid-template-columns: 1fr;
  }

  .command-header {
    align-items: flex-start;
    flex-direction: row;
  }

  .command-switches {
    justify-content: flex-end;
  }

  .reaction-role-row {
    align-items: stretch;
    grid-template-columns: 1fr;
  }

  .campaign-import-row {
    align-items: stretch;
    grid-template-columns: 1fr;
  }

  .campaign-history-head,
  .campaign-history-row {
    gap: 7px;
    grid-template-columns: 4px 72px 36px 22px minmax(145px, 1fr);
    padding: 11px 10px;
  }

  .campaign-faction img {
    height: 24px;
    width: 24px;
  }

  .campaign-faction.with-label span {
    max-width: 150px;
  }

  .campaign-overview-card {
    grid-template-columns: minmax(0, 3fr) minmax(76px, 1fr);
  }

  .campaign-overview-factions,
  .campaign-overview-rank {
    padding: 12px 8px;
  }

  .campaign-matchup {
    gap: 7px;
  }

  .campaign-matchup .campaign-factions {
    gap: 4px;
  }

  .campaign-matchup .campaign-faction img {
    height: 28px;
    width: 28px;
  }

  .campaign-matchup-versus {
    font-size: 10px;
  }

  .player-overview-card {
    grid-template-columns: minmax(0, 3fr) minmax(96px, 1fr);
  }

  .player-overview-main,
  .player-overview-rank {
    padding: 12px 8px;
  }

  .player-overview-name {
    font-size: 23px;
  }

  .player-overview-meta {
    gap: 6px;
  }

  .player-stat-strip .wcc-stat-label {
    min-height: 24px;
  }

  .player-recent-row {
    grid-template-columns: 52px minmax(0, 1fr) 20px;
    gap: 6px;
    padding: 8px;
  }
}

@media (max-width: 639.98px) {
  html[data-theme="dark"] .wcc-table:not(.wcc-table-fit),
  html[data-theme="ember"] .wcc-table:not(.wcc-table-fit),
  html[data-theme="warp"] .wcc-table:not(.wcc-table-fit) {
    background: transparent;
    border: 0;
    box-shadow: none;
  }
}

/* ============================================================================
   Warp theme — violet "void" dark variant. Mirrors the dark/ember structural
   overrides (glass chrome, gradient panels, menu) with a violet palette. The
   token block above already drives cards, text, badges, alerts, inputs and
   buttons through the shared variables; the rules here cover the pieces that
   ship a hardcoded light or accent-tinted treatment.
   ========================================================================== */
html[data-theme="warp"] .wcc-theme-menu-button,
html[data-theme="warp"] .wcc-theme-menu .wcc-theme-menu-button {
  background: rgba(192, 132, 252, 0.14);
  border-color: rgba(192, 132, 252, 0.36);
  color: #e2c9ff;
}

html[data-theme="warp"] .wcc-theme-menu-button:hover,
html[data-theme="warp"] .wcc-theme-menu.open .wcc-theme-menu-button,
html[data-theme="warp"] .wcc-theme-menu .wcc-theme-menu-button:hover,
html[data-theme="warp"] .wcc-theme-menu.open .wcc-theme-menu .wcc-theme-menu-button {
  background: rgba(192, 132, 252, 0.20);
}

html[data-theme="warp"] .wcc-theme-menu-panel {
  background: rgba(20, 13, 42, 0.98);
  border-color: rgba(192, 132, 252, 0.30);
}

html[data-theme="warp"] .wcc-theme-option:hover,
html[data-theme="warp"] .wcc-theme-option.active,
html[data-theme="warp"] .wcc-theme-menu .wcc-theme-option:hover,
html[data-theme="warp"] .wcc-theme-menu .wcc-theme-option.active {
  background: rgba(192, 132, 252, 0.14);
  border-color: rgba(192, 132, 252, 0.30);
}

html[data-theme="warp"] body .wcc-bot-status-pill,
html[data-theme="warp"] body .wcc-settings-bubble,
html[data-theme="warp"] body .wcc-bottom-nav {
  background: rgba(226, 205, 255, 0.16);
  border-color: rgba(216, 180, 254, 0.28);
  box-shadow: 0 18px 52px rgba(0, 0, 0, 0.36), inset 0 1px 0 rgba(255, 255, 255, 0.14);
}

html[data-theme="warp"] body .wcc-settings-bubble,
html[data-theme="warp"] body .wcc-bot-status-pill,
html[data-theme="warp"] body .wcc-bottom-nav-item {
  color: var(--text);
}

html[data-theme="warp"] body .wcc-bottom-nav-item.active {
  background: rgba(192, 132, 252, 0.18);
  color: #e2c9ff;
}

html[data-theme="warp"] body .wcc-bottom-nav-indicator {
  background:
    radial-gradient(circle at 50% 8%, rgba(245, 230, 255, 0.20), transparent 46%),
    linear-gradient(135deg, rgba(192, 132, 252, 0.38), rgba(232, 121, 249, 0.22));
  border-color: rgba(192, 132, 252, 0.64);
  box-shadow:
    0 0 22px rgba(168, 85, 247, 0.34),
    0 8px 24px rgba(0, 0, 0, 0.30),
    inset 0 0 0 1px rgba(216, 180, 254, 0.14),
    inset 0 1px 0 rgba(216, 180, 254, 0.18);
}

html[data-theme="warp"] body .wcc-bottom-nav.wcc-bottom-nav-ready .wcc-bottom-nav-item.active {
  color: #e2c9ff;
  filter: saturate(1.18) drop-shadow(0 0 8px rgba(168, 85, 247, 0.48));
}

html[data-theme="warp"] .wcc-shell {
  background:
    radial-gradient(circle at 12% 0%, rgba(124, 58, 237, 0.24), transparent 32rem),
    linear-gradient(145deg, rgba(7, 4, 26, 0.96), rgba(24, 15, 56, 0.96));
}

html[data-theme="warp"] .wcc-sidebar {
  background:
    linear-gradient(180deg, rgba(36, 24, 72, 0.96), rgba(12, 8, 28, 0.96)),
    #0c081c;
  border-color: var(--line);
}

html[data-theme="warp"] .wcc-sidebar-header,
html[data-theme="warp"] .wcc-mobile-topbar,
html[data-theme="warp"] .border-border {
  border-color: var(--line);
}

html[data-theme="warp"] .wcc-mobile-topbar {
  background: transparent;
  box-shadow: none;
}

html[data-theme="warp"] .wcc-card,
html[data-theme="warp"] .wcc-section,
html[data-theme="warp"] .wcc-stat-card,
html[data-theme="warp"] .wcc-stat-strip,
html[data-theme="warp"] .campaign-overview-card,
html[data-theme="warp"] .player-overview-card,
html[data-theme="warp"] .wcc-table,
html[data-theme="warp"] .wcc-list,
html[data-theme="warp"] .wcc-filters,
html[data-theme="warp"] .action-note,
html[data-theme="warp"] .phase-row,
html[data-theme="warp"] .command-row,
html[data-theme="warp"] .reaction-role-row,
html[data-theme="warp"] .progress-card,
html[data-theme="warp"] .campaign-import-row {
  background: linear-gradient(180deg, rgba(34, 23, 64, 0.94), rgba(16, 10, 36, 0.94));
  border-color: var(--line);
  box-shadow: 0 18px 52px rgba(0, 0, 0, 0.32), inset 0 1px 0 rgba(192, 132, 252, 0.09);
}

html[data-theme="warp"] body .hub-card,
html[data-theme="warp"] body .tool-list-row,
html[data-theme="warp"] body .tool-card-preview,
html[data-theme="warp"] body .preview-subcard,
html[data-theme="warp"] body .mobile-nav-preview span,
html[data-theme="warp"] body .rank-watch-row {
  background: rgba(24, 16, 48, 0.58);
  border-color: var(--line);
}

html[data-theme="warp"] body .rank-watch-row:hover {
  border-color: rgba(192, 132, 252, 0.44);
}

html[data-theme="warp"] body .rank-watch-wins {
  color: #d8b4fe;
}

html[data-theme="warp"] body .rank-watch-missing {
  background: rgba(192, 132, 252, 0.12);
  border-color: rgba(192, 132, 252, 0.30);
  color: #e9d5ff;
}

html[data-theme="warp"] body .template-preview-box,
html[data-theme="warp"] body .filepond-upload-progress {
  background: rgba(20, 13, 42, 0.62);
  border-color: rgba(192, 132, 252, 0.26);
  color: var(--text);
}

html[data-theme="warp"] .wcc-nav-link:hover,
html[data-theme="warp"] .wcc-nav-link.active {
  background: rgba(192, 132, 252, 0.13);
  border-color: rgba(192, 132, 252, 0.31);
  color: var(--accent);
}

html[data-theme="warp"] .campaign-history-row:hover,
html[data-theme="warp"] .roster-row:hover,
html[data-theme="warp"] .wcc-button-secondary:hover {
  background: rgba(192, 132, 252, 0.11);
}

html[data-theme="warp"] input,
html[data-theme="warp"] select,
html[data-theme="warp"] textarea {
  background: var(--field);
  border-color: var(--line);
  color: var(--text);
}

html[data-theme="warp"] .apexcharts-text,
html[data-theme="warp"] .apexcharts-legend-text {
  fill: var(--chart-text) !important;
  color: var(--chart-text) !important;
}

html[data-theme="warp"] .apexcharts-gridline {
  stroke: var(--chart-grid) !important;
}

html[data-theme="warp"] .apexcharts-xaxis line,
html[data-theme="warp"] .apexcharts-yaxis line {
  stroke: var(--chart-axis) !important;
}

html[data-theme="warp"] .command-switch-track {
  background: rgba(60, 44, 96, 0.74);
  border-color: rgba(192, 132, 252, 0.24);
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.24);
}

html[data-theme="warp"] .command-switch-track::before {
  background: #f3ecff;
}

html[data-theme="warp"] .command-switch-input:checked + .command-switch-track {
  background: rgba(192, 132, 252, 0.82);
  border-color: rgba(216, 180, 254, 0.72);
  box-shadow: 0 0 16px rgba(168, 85, 247, 0.28);
}

html[data-theme="warp"] .command-restrictions {
  background: rgba(20, 13, 42, 0.76);
  border-color: rgba(192, 132, 252, 0.20);
}

html[data-theme="warp"] .command-restrictions summary:hover {
  background: rgba(192, 132, 252, 0.11);
}

html[data-theme="warp"] .command-restrictions-title svg,
html[data-theme="warp"] .command-restrictions[open] .command-restrictions-chevron {
  color: #c084fc;
}

html[data-theme="warp"] .command-restrictions-hint {
  background: rgba(192, 132, 252, 0.11);
  border-color: rgba(192, 132, 252, 0.20);
}

/* Campaign import step wizard (breadcrumb + step navigation). */
.wcc-divider {
  border: none;
  border-top: 1px solid var(--line);
  margin: 22px 0;
}

.wizard-steps {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 18px;
}

.wizard-step {
  align-items: center;
  background: var(--muted-bg);
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--muted);
  display: inline-flex;
  font-size: 13px;
  font-weight: 700;
  gap: 8px;
  line-height: 1;
  padding: 8px 14px;
  text-decoration: none;
}

.wizard-step-num {
  align-items: center;
  background: var(--line);
  border-radius: 999px;
  color: var(--text);
  display: inline-flex;
  font-size: 12px;
  height: 20px;
  justify-content: center;
  width: 20px;
}

a.wizard-step.is-done {
  color: var(--text);
  transition: border-color 160ms ease;
}
a.wizard-step.is-done:hover,
a.wizard-step.is-done:focus-visible {
  border-color: var(--accent);
}

.wizard-step.is-active {
  background: var(--accent-soft);
  border-color: var(--accent);
  color: var(--text);
}
.wizard-step.is-active .wizard-step-num {
  background: var(--accent);
  color: var(--panel);
}

.wizard-step.is-future {
  opacity: 0.55;
}

.wizard-nav {
  align-items: center;
  display: flex;
}

/* ============================================================================
   Grimdark — jeu complet de surcharges sombres.
   Un thème sombre ne peut pas se contenter de ses tokens : le shell, la
   sidebar, le chrome flottant, le menu de thème et les surfaces de cartes
   portent des traitements clairs codés en dur dans les règles de base. Le
   parti pris ici : gris sur gris, dégradés verticaux, contours gris nettement
   plus clairs que le fond, et le rouge réservé aux états actifs.
   Les rayons ne sont jamais redéclarés — la règle `border-radius: 0` du thème
   passe après et gagne de toute façon.
   ========================================================================== */
html[data-theme="grimdark"] body {
  background:
    linear-gradient(180deg, #131316 0%, #0b0b0d 100%),
    #0d0d0f;
}

html[data-theme="grimdark"] .wcc-shell {
  background: linear-gradient(160deg, #16161a 0%, #0b0b0d 62%);
}

html[data-theme="grimdark"] .wcc-sidebar {
  background: linear-gradient(180deg, #1c1c21 0%, #101013 100%), #101013;
  border-color: var(--line);
}

html[data-theme="grimdark"] .wcc-sidebar-header,
html[data-theme="grimdark"] .wcc-mobile-topbar,
html[data-theme="grimdark"] .border-border {
  border-color: var(--line);
}

html[data-theme="grimdark"] .wcc-mobile-topbar {
  background: transparent;
  box-shadow: none;
}

html[data-theme="grimdark"] .wcc-card,
html[data-theme="grimdark"] .wcc-section,
html[data-theme="grimdark"] .wcc-stat-card,
html[data-theme="grimdark"] .wcc-stat-strip,
html[data-theme="grimdark"] .campaign-overview-card,
html[data-theme="grimdark"] .player-overview-card,
html[data-theme="grimdark"] .wcc-table,
html[data-theme="grimdark"] .wcc-list,
html[data-theme="grimdark"] .wcc-filters,
html[data-theme="grimdark"] .action-note,
html[data-theme="grimdark"] .phase-row,
html[data-theme="grimdark"] .command-row,
html[data-theme="grimdark"] .reaction-role-row,
html[data-theme="grimdark"] .progress-card,
html[data-theme="grimdark"] .campaign-import-row {
  background: linear-gradient(180deg, #1e1e22 0%, #141417 100%);
  border-color: var(--line);
  box-shadow: 0 14px 40px rgba(0, 0, 0, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.05);
}

html[data-theme="grimdark"] body .hub-card,
html[data-theme="grimdark"] body .tool-list-row,
html[data-theme="grimdark"] body .tool-card-preview,
html[data-theme="grimdark"] body .preview-subcard,
html[data-theme="grimdark"] body .mobile-nav-preview span,
html[data-theme="grimdark"] body .rank-watch-row {
  background: linear-gradient(180deg, #232328 0%, #191a1d 100%);
  border-color: var(--line);
}

html[data-theme="grimdark"] body .rank-watch-row:hover {
  border-color: var(--accent);
}

html[data-theme="grimdark"] body .rank-watch-wins {
  color: #cfccc8;
}

html[data-theme="grimdark"] body .rank-watch-missing {
  background: rgba(226, 49, 64, 0.14);
  border-color: rgba(226, 49, 64, 0.38);
  color: #f2b6bd;
}

html[data-theme="grimdark"] body .template-preview-box,
html[data-theme="grimdark"] body .filepond-upload-progress {
  background: #131316;
  border-color: var(--line);
  color: var(--text);
}

/* Chrome flottant : sur ce thème il ne "flotte" pas, il est massif — plaque
   d'acier posée sur la page, contour gris clair, sans halo coloré. */
html[data-theme="grimdark"] body .wcc-bot-status-pill,
html[data-theme="grimdark"] body .wcc-settings-bubble,
html[data-theme="grimdark"] body .wcc-bottom-nav {
  background: linear-gradient(180deg, #26262c 0%, #17171b 100%);
  border-color: #5a5a63;
  box-shadow: 0 14px 40px rgba(0, 0, 0, 0.62), inset 0 1px 0 rgba(255, 255, 255, 0.07);
}

html[data-theme="grimdark"] body .wcc-settings-bubble,
html[data-theme="grimdark"] body .wcc-bot-status-pill,
html[data-theme="grimdark"] body .wcc-bottom-nav-item {
  color: var(--text);
}

html[data-theme="grimdark"] body .wcc-bottom-nav-item.active {
  background: rgba(226, 49, 64, 0.20);
  color: #f2b6bd;
}

html[data-theme="grimdark"] body .wcc-bottom-nav-indicator {
  background: linear-gradient(180deg, rgba(226, 49, 64, 0.42), rgba(150, 20, 32, 0.30));
  border-color: rgba(226, 49, 64, 0.70);
  box-shadow:
    0 0 18px rgba(216, 30, 44, 0.34),
    0 8px 24px rgba(0, 0, 0, 0.45),
    inset 0 1px 0 rgba(255, 255, 255, 0.10);
}

html[data-theme="grimdark"] body .wcc-bottom-nav.wcc-bottom-nav-ready .wcc-bottom-nav-item.active {
  color: #f2b6bd;
  filter: saturate(1.15) drop-shadow(0 0 8px rgba(216, 30, 44, 0.45));
}

html[data-theme="grimdark"] .wcc-theme-menu-button,
html[data-theme="grimdark"] .wcc-theme-menu .wcc-theme-menu-button {
  background: rgba(226, 49, 64, 0.14);
  border-color: rgba(226, 49, 64, 0.40);
  color: #f2b6bd;
}

html[data-theme="grimdark"] .wcc-theme-menu-button:hover,
html[data-theme="grimdark"] .wcc-theme-menu.open .wcc-theme-menu-button,
html[data-theme="grimdark"] .wcc-theme-menu .wcc-theme-menu-button:hover,
html[data-theme="grimdark"] .wcc-theme-menu.open .wcc-theme-menu .wcc-theme-menu-button {
  background: rgba(226, 49, 64, 0.22);
}

html[data-theme="grimdark"] .wcc-theme-menu-panel {
  background: #17171b;
  border-color: var(--line);
}

html[data-theme="grimdark"] .wcc-theme-option:hover,
html[data-theme="grimdark"] .wcc-theme-option.active,
html[data-theme="grimdark"] .wcc-theme-menu .wcc-theme-option:hover,
html[data-theme="grimdark"] .wcc-theme-menu .wcc-theme-option.active {
  background: rgba(226, 49, 64, 0.14);
  border-color: rgba(226, 49, 64, 0.36);
}

html[data-theme="grimdark"] .wcc-nav-link:hover,
html[data-theme="grimdark"] .wcc-nav-link.active {
  background: rgba(226, 49, 64, 0.14);
  border-color: rgba(226, 49, 64, 0.36);
  color: var(--accent);
}

html[data-theme="grimdark"] .campaign-history-row:hover,
html[data-theme="grimdark"] .roster-row:hover,
html[data-theme="grimdark"] .wcc-button-secondary:hover {
  background: rgba(226, 49, 64, 0.12);
}

html[data-theme="grimdark"] input,
html[data-theme="grimdark"] select,
html[data-theme="grimdark"] textarea {
  background: var(--field);
  border-color: var(--line);
  color: var(--text);
}

html[data-theme="grimdark"] .apexcharts-text,
html[data-theme="grimdark"] .apexcharts-legend-text {
  fill: var(--chart-text) !important;
  color: var(--chart-text) !important;
}

html[data-theme="grimdark"] .apexcharts-gridline {
  stroke: var(--chart-grid) !important;
}

html[data-theme="grimdark"] .apexcharts-xaxis line,
html[data-theme="grimdark"] .apexcharts-yaxis line {
  stroke: var(--chart-axis) !important;
}

html[data-theme="grimdark"] .command-switch-track {
  background: #2c2c33;
  border-color: var(--line);
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.4);
}

html[data-theme="grimdark"] .command-switch-track::before {
  background: #e8e6e3;
}

html[data-theme="grimdark"] .command-switch-input:checked + .command-switch-track {
  background: rgba(216, 30, 44, 0.85);
  border-color: rgba(244, 63, 78, 0.72);
  box-shadow: 0 0 14px rgba(216, 30, 44, 0.30);
}

html[data-theme="grimdark"] .command-restrictions {
  background: #16161a;
  border-color: var(--line);
}

html[data-theme="grimdark"] .command-restrictions summary:hover {
  background: rgba(226, 49, 64, 0.12);
}

html[data-theme="grimdark"] .command-restrictions-title svg,
html[data-theme="grimdark"] .command-restrictions[open] .command-restrictions-chevron {
  color: var(--accent);
}

html[data-theme="grimdark"] .command-restrictions-hint {
  background: rgba(226, 49, 64, 0.10);
  border-color: rgba(226, 49, 64, 0.24);
}

html[data-theme="grimdark"] .wcc-table:not(.wcc-table-fit) {
  background: linear-gradient(180deg, #1e1e22 0%, #141417 100%);
}
