:root {
  --bg: #05020d;
  --bg-soft: #0c0719;
  --panel: rgba(18, 12, 34, 0.76);
  --panel-strong: rgba(24, 17, 44, 0.9);
  --line: rgba(158, 110, 255, 0.28);
  --line-strong: rgba(158, 110, 255, 0.62);
  --text: #f7f3ff;
  --muted: #a79dbc;
  --soft: #d8ccff;
  --purple: #8b5cf6;
  --purple-2: #b15cff;
  --cyan: #62e6ff;
  --green: #65f596;
  --danger: #ff6b91;
  --shadow: 0 24px 80px rgba(84, 42, 180, 0.34);
  --radius: 8px;
  --radius-lg: 18px;
}

/* `hidden` vient du navigateur avec un display:none de faible poids :
   n'importe quel display:grid ecrit ici le battait. Le menu « Acces »
   restait donc ouvert en permanence, et la pastille d'etat premium
   s'affichait vide. La regle vaut pour tout le site. */
[hidden] {
  display: none !important;
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  scroll-behavior: smooth;
}

html {
  background: var(--bg);
}

body {
  min-height: 100vh;
  overflow-x: hidden;
  background:
    radial-gradient(circle at 12% 8%, rgba(113, 74, 255, 0.24), transparent 26rem),
    radial-gradient(circle at 88% 24%, rgba(177, 92, 255, 0.18), transparent 24rem),
    radial-gradient(circle at 52% 100%, rgba(98, 230, 255, 0.09), transparent 30rem),
    linear-gradient(180deg, #05020d 0%, #080411 48%, #05020d 100%);
  color: var(--text);
  font-family: Inter, Arial, sans-serif;
  font-weight: 600;
  /* Le francais a des mots longs : « confidentialite »,
     « administration ». Sur un telephone etroit, un seul de ces mots
     depassait de son cadre et se faisait couper. La propriete s'herite,
     donc une ligne suffit pour tout le site, et elle n'agit QUE quand un
     mot ne tient vraiment pas. */
  overflow-wrap: break-word;
}

body::before {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: -3;
  background-image:
    linear-gradient(rgba(143, 95, 255, 0.04) 1px, transparent 1px),
    linear-gradient(90deg, rgba(143, 95, 255, 0.04) 1px, transparent 1px);
  background-size: 48px 48px;
  mask-image: radial-gradient(circle at center, black, transparent 72%);
}

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

/* `select` et `textarea` manquaient : ils retombaient sur les polices
   du navigateur — Arial pour les listes, monospace pour les zones de
   texte — a cote d'Inter partout ailleurs. Invisible tant que les
   champs etaient surtout des <input> ; criant depuis que onze
   reglages se choisissent dans une liste. */
button,
input,
select,
textarea {
  font: inherit;
}

button {
  color: inherit;
  border: 0;
  cursor: pointer;
}

.starfield {
  position: fixed;
  inset: 0;
  z-index: -2;
  width: 100%;
  height: 100%;
}

.page-glow {
  position: fixed;
  inset: -20%;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(circle at 18% 45%, rgba(139, 92, 246, 0.14), transparent 28rem),
    radial-gradient(circle at 78% 70%, rgba(74, 222, 255, 0.08), transparent 24rem);
  filter: blur(18px);
  animation: glowMove 12s ease-in-out infinite alternate;
}

@keyframes glowMove {
  to {
    transform: translate3d(3%, -2%, 0) scale(1.08);
  }
}

.section-shell {
  width: min(1180px, calc(100% - 40px));
  margin: 0 auto;
}

.site-header {
  position: sticky;
  top: 14px;
  z-index: 50;
  padding: 0 20px;
  animation: navEnter 0.72s cubic-bezier(.2,.8,.2,1) both;
}

.navbar {
  width: min(1180px, 100%);
  min-height: 66px;
  margin: 0 auto;
  padding: 10px 12px 10px 18px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: rgba(8, 5, 18, 0.72);
  box-shadow:
    0 0 0 1px rgba(255, 255, 255, 0.03) inset,
    0 14px 44px rgba(91, 50, 188, 0.34),
    0 0 34px rgba(139, 92, 246, 0.25);
  backdrop-filter: blur(22px);
}

.brand,
.assistant-title {
  display: flex;
  align-items: center;
  gap: 12px;
}

.brand {
  font-weight: 900;
  letter-spacing: 0;
  white-space: nowrap;
}

.brand-mark,
.assistant-avatar {
  width: 38px;
  height: 38px;
  display: grid;
  place-items: center;
  overflow: hidden;
  border: 1px solid rgba(139, 92, 246, 0.48);
  border-radius: 50%;
  background:
    radial-gradient(circle at 45% 35%, rgba(98, 230, 255, 0.28), transparent 30%),
    linear-gradient(135deg, rgba(139, 92, 246, 0.28), rgba(10, 5, 22, 0.95));
  box-shadow: 0 0 18px rgba(139, 92, 246, 0.42);
}

.brand-mark img,
.assistant-avatar img {
  width: 100%;
  height: 100%;
  padding: 2px;
  object-fit: contain;
}

.brand-fallback::before,
.avatar-fallback::before {
  content: "MB";
  font-size: 0.72rem;
  color: var(--soft);
  font-weight: 900;
}

.nav-links {
  display: flex;
  align-items: center;
  gap: 22px;
  color: var(--muted);
  font-size: 0.9rem;
}

.nav-links a {
  transition: color 0.2s ease, transform 0.2s ease;
}

.nav-links a:hover {
  color: var(--text);
}

.nav-action-btn {
  min-height: 44px;
  padding: 0 18px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  border-radius: var(--radius);
  white-space: nowrap;
  color: var(--text);
  font-weight: 900;
  border: 1px solid rgba(158, 110, 255, 0.32);
  background: rgba(255, 255, 255, 0.055);
  box-shadow: 0 10px 26px rgba(8, 3, 20, 0.22);
}

.nav-dashboard-btn {
  color: #fff;
  border-color: rgba(205, 184, 255, 0.52);
  background: linear-gradient(135deg, #7c5cff, #b15cff);
  box-shadow:
    0 14px 34px rgba(139, 92, 246, 0.34),
    0 0 26px rgba(177, 92, 255, 0.22);
}

.nav-admin-btn {
  border-color: rgba(98, 230, 255, 0.28);
  background:
    linear-gradient(135deg, rgba(98, 230, 255, 0.1), rgba(139, 92, 246, 0.16)),
    rgba(255, 255, 255, 0.045);
}

.language-switch {
  min-height: 38px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 0 8px;
  border: 1px solid rgba(158, 110, 255, 0.24);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.045);
}

.language-switch select {
  max-width: 110px;
  border: 0;
  outline: 0;
  background: transparent;
  color: var(--text);
  font: inherit;
  font-weight: 900;
}

.language-switch option {
  background: #120c22;
  color: var(--text);
}

.nav-cta,
.primary-btn,
.secondary-btn {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius);
  padding: 0 20px;
  font-weight: 900;
  transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
}

.primary-btn {
  color: white;
  background: linear-gradient(135deg, #7c5cff, #b15cff);
  box-shadow:
    0 12px 30px rgba(139, 92, 246, 0.34),
    0 0 28px rgba(177, 92, 255, 0.26);
}

.secondary-btn {
  border: 1px solid var(--line);
  background: rgba(255, 255, 255, 0.045);
  color: var(--text);
}

.primary-btn:hover,
.secondary-btn:hover,
.nav-action-btn:hover {
  transform: translateY(-2px);
  border-color: var(--line-strong);
  box-shadow:
    0 18px 38px rgba(139, 92, 246, 0.38),
    0 0 32px rgba(177, 92, 255, 0.28);
}

.hero-actions a[href="dashboard.html"] {
  border-color: rgba(167, 139, 250, 0.58);
  background:
    linear-gradient(135deg, rgba(139, 92, 246, 0.22), rgba(88, 101, 242, 0.08)),
    rgba(255, 255, 255, 0.055);
  box-shadow:
    0 0 0 1px rgba(255, 255, 255, 0.035) inset,
    0 0 26px rgba(139, 92, 246, 0.18);
}

.hero-actions a[href="dashboard.html"]::after {
  content: "";
  position: absolute;
  inset: -1px;
  border-radius: inherit;
  background: linear-gradient(120deg, transparent 20%, rgba(255, 255, 255, 0.24), transparent 78%);
  opacity: 0;
  transform: translateX(-45%);
  transition: opacity 0.18s ease, transform 0.42s ease;
  pointer-events: none;
}

.hero-actions a[href="dashboard.html"]:hover::after {
  opacity: 1;
  transform: translateX(45%);
}

.nav-toggle {
  display: none;
  width: 42px;
  height: 42px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.07);
  border: 1px solid var(--line);
}

.nav-toggle span {
  display: block;
  width: 18px;
  height: 2px;
  margin: 4px auto;
  background: var(--text);
  border-radius: 20px;
}

.hero {
  min-height: 760px;
  padding: 130px 0 72px;
  display: grid;
  gap: 58px;
  justify-items: center;
}

.hero-copy {
  max-width: 900px;
  text-align: center;
}

.hero-copy > * {
  opacity: 0;
  animation: heroTextEnter 0.82s cubic-bezier(.2,.8,.2,1) forwards;
}

.hero-copy > *:nth-child(1) {
  animation-delay: 0.1s;
}

.hero-copy > *:nth-child(2) {
  animation-delay: 0.18s;
}

.hero-copy > *:nth-child(3) {
  animation-delay: 0.28s;
}

.hero-copy > *:nth-child(4) {
  animation-delay: 0.38s;
}

.eyebrow {
  margin-bottom: 14px;
  color: var(--purple-2);
  font-size: 0.78rem;
  font-weight: 900;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

h1,
h2,
h3 {
  letter-spacing: 0;
}

h1 {
  font-size: clamp(4.2rem, 12vw, 9.7rem);
  line-height: 0.82;
  font-weight: 900;
  text-shadow:
    0 0 24px rgba(139, 92, 246, 0.52),
    0 16px 60px rgba(0, 0, 0, 0.62);
}

.hero-lead {
  max-width: 760px;
  margin: 28px auto 0;
  color: var(--muted);
  font-size: clamp(1rem, 2vw, 1.18rem);
  line-height: 1.75;
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 14px;
  margin-top: 34px;
}

.hero-panel,
.discord-window,
.price-card,
.feature-card,
.faq-box,
.stat,
.assistant,
.patch-redirect,
.patch-item {
  position: relative;
  border: 1px solid var(--line);
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.055), rgba(255, 255, 255, 0.02)),
    var(--panel);
  box-shadow:
    0 0 0 1px rgba(255, 255, 255, 0.03) inset,
    var(--shadow);
  backdrop-filter: blur(18px);
}

.hero-panel {
  width: min(920px, 100%);
  min-height: 330px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 288px;
  overflow: hidden;
  border-radius: var(--radius-lg);
  opacity: 0;
  animation: panelEnter 0.9s cubic-bezier(.2,.8,.2,1) 0.32s forwards;
}

.panel-top {
  height: 44px;
  padding: 0 18px;
  display: flex;
  align-items: center;
  gap: 8px;
  border-bottom: 1px solid rgba(158, 110, 255, 0.15);
  background: rgba(255, 255, 255, 0.018);
}

.hero-panel .panel-top {
  grid-column: 1 / -1;
}

.dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
}

.red {
  background: #ff6b6b;
}

.yellow {
  background: #f8c14d;
}

.green {
  background: #69dd66;
}

.channel-name {
  margin-left: 8px;
  color: var(--muted);
  font-weight: 900;
}

.command-stage {
  min-height: 286px;
  padding: 28px;
  display: grid;
  align-content: center;
  gap: 14px;
}

.empty-state {
  color: var(--muted);
  text-align: center;
}

.command-rail {
  padding: 22px 18px;
  border-left: 1px solid rgba(158, 110, 255, 0.15);
}

.command-rail p,
.quick-questions p {
  margin-bottom: 14px;
  color: var(--muted);
  font-size: 0.78rem;
  font-weight: 900;
  text-transform: uppercase;
}

.command-card {
  width: 100%;
  min-height: 62px;
  margin-bottom: 12px;
  padding: 12px;
  display: grid;
  grid-template-columns: 38px 1fr;
  gap: 12px;
  align-items: center;
  border: 1px solid rgba(158, 110, 255, 0.18);
  border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.035);
  text-align: left;
  transition: border-color 0.2s ease, background 0.2s ease, transform 0.2s ease;
}

.command-card:hover,
.command-card.is-active {
  border-color: var(--line-strong);
  background: rgba(139, 92, 246, 0.16);
  transform: translateX(-2px);
}

.command-icon {
  width: 34px;
  height: 34px;
  display: grid;
  place-items: center;
  border-radius: var(--radius);
  background: rgba(139, 92, 246, 0.2);
  border: 1px solid rgba(139, 92, 246, 0.34);
  color: var(--purple-2);
  font-weight: 900;
}

.command-card small {
  display: block;
  margin-top: 3px;
  color: var(--muted);
}

.bot-embed {
  max-width: 560px;
  padding: 18px;
  border-left: 4px solid var(--purple);
  border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.055);
  animation: riseIn 0.28s ease both;
}

.bot-embed strong {
  display: block;
  margin-bottom: 8px;
}

.bot-embed p {
  color: var(--muted);
  line-height: 1.65;
}

.bot-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 14px;
}

.bot-tags span {
  padding: 7px 10px;
  border: 1px solid rgba(158, 110, 255, 0.22);
  border-radius: 999px;
  color: var(--soft);
  background: rgba(139, 92, 246, 0.12);
  font-size: 0.78rem;
}

@keyframes riseIn {
  from {
    opacity: 0;
    transform: translateY(14px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.stats {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 18px;
  padding: 24px 0 72px;
}

.stat {
  min-height: 132px;
  padding: 26px;
  border-radius: var(--radius);
}

.stat strong {
  display: block;
  margin-bottom: 8px;
  color: var(--soft);
  font-size: 2.45rem;
  font-weight: 900;
}

.stat span {
  color: var(--muted);
}

.features,
.demo,
.pricing,
.patch-notes,
.faq,
.cta {
  padding: 86px 0;
}

.section-heading {
  max-width: 760px;
  margin: 0 auto 42px;
  text-align: center;
}

.section-heading h2,
.cta h2 {
  font-size: clamp(2.2rem, 5vw, 4.2rem);
  line-height: 1.02;
  font-weight: 900;
}

.section-heading p:not(.eyebrow),
.cta p {
  margin-top: 16px;
  color: var(--muted);
  line-height: 1.7;
}

.feature-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 16px;
}

.feature-card {
  min-height: 218px;
  padding: 22px;
  border-radius: var(--radius);
  overflow: hidden;
  transition: transform 0.25s ease, border-color 0.25s ease, box-shadow 0.25s ease;
}

.feature-card::after,
.price-card::after,
.patch-item::after {
  content: "";
  position: absolute;
  inset: 0;
  opacity: 0;
  pointer-events: none;
  background: radial-gradient(circle at 30% 0%, rgba(139, 92, 246, 0.22), transparent 18rem);
  transition: opacity 0.25s ease;
}

.feature-card:hover {
  transform: translateY(-8px);
  border-color: var(--line-strong);
  box-shadow:
    0 26px 80px rgba(91, 50, 188, 0.34),
    0 0 32px rgba(139, 92, 246, 0.22);
}

.feature-card:hover::after,
.price-card:hover::after,
.patch-item:hover::after {
  opacity: 1;
}

.feature-icon {
  width: 36px;
  height: 36px;
  display: grid;
  place-items: center;
  border: 1px solid rgba(139, 92, 246, 0.32);
  border-radius: var(--radius);
  color: var(--purple-2);
  background: rgba(139, 92, 246, 0.14);
  font-size: 0.8rem;
  font-weight: 900;
}

.feature-card h3 {
  margin-top: 22px;
  font-size: 1.15rem;
}

.feature-card p {
  margin-top: 10px;
  color: var(--muted);
  line-height: 1.65;
  font-weight: 600;
}

.demo-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 260px;
  gap: 18px;
  align-items: stretch;
}

.discord-window {
  min-height: 430px;
  overflow: hidden;
  border-radius: var(--radius-lg);
}

.chat-feed {
  min-height: 386px;
  padding: 22px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.demo-controls {
  display: grid;
  gap: 8px;
  align-content: start;
  /* La demo est passee de 3 a 19 commandes : la colonne doit defiler au lieu
     d'etirer la page sur trois ecrans de haut. */
  max-height: 430px;
  overflow-y: auto;
  padding-right: 6px;
  scrollbar-width: thin;
}

.demo-group {
  margin: 10px 0 2px;
  font-size: 0.74rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--soft);
  opacity: 0.75;
  position: sticky;
  top: 0;
  background: var(--panel, #14101f);
  padding: 4px 0;
  z-index: 1;
}

.demo-group:first-child {
  margin-top: 0;
}

.demo-command {
  min-height: 44px;
  padding: 0 18px;
  border-radius: var(--radius);
  border: 1px solid rgba(158, 110, 255, 0.2);
  background: rgba(255, 255, 255, 0.045);
  color: var(--soft);
  text-align: left;
  transition: border-color 0.2s ease, background 0.2s ease, transform 0.2s ease;
}

.demo-command:hover,
.demo-command.is-active {
  border-color: var(--line-strong);
  background: rgba(139, 92, 246, 0.18);
  transform: translateX(4px);
}

.message {
  max-width: 78%;
  padding: 14px 16px;
  border-radius: var(--radius);
  line-height: 1.55;
  animation: riseIn 0.25s ease both;
}

.message.user {
  align-self: flex-end;
  background: linear-gradient(135deg, #7c5cff, #b15cff);
  color: #fff;
}

.message.bot {
  align-self: flex-start;
  border: 1px solid rgba(158, 110, 255, 0.24);
  background: rgba(255, 255, 255, 0.055);
  color: var(--soft);
}

.command-demo-message {
  width: 100%;
  max-width: 100%;
  padding: 14px;
}

.command-demo-message .discord-command-preview {
  max-width: 100%;
}

.pricing-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 22px;
  max-width: 1180px;
  margin: 0 auto;
}

.price-card {
  min-height: 490px;
  padding: 34px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border-radius: var(--radius-lg);
}

.price-card.premium {
  border-color: var(--line-strong);
  box-shadow:
    0 0 0 1px rgba(139, 92, 246, 0.18) inset,
    0 24px 90px rgba(139, 92, 246, 0.42);
}

.price-card.ultimate {
  border-color: rgba(255, 215, 0, 0.38);
  box-shadow:
    0 0 0 1px rgba(255, 215, 0, 0.12) inset,
    0 24px 90px rgba(139, 92, 246, 0.26);
}

.premium-ribbon {
  position: absolute;
  top: 22px;
  right: -44px;
  z-index: 2;
  width: 150px;
  padding: 9px 0;
  transform: rotate(45deg);
  background: linear-gradient(135deg, #7c5cff, #b15cff);
  color: white;
  text-align: center;
  font-size: 0.72rem;
  font-weight: 900;
}

.price-head h3 {
  font-size: 1.1rem;
}

.price-head p {
  margin-top: 10px;
  color: var(--muted);
  line-height: 1.55;
}

.price {
  margin: 28px 0;
  color: var(--soft);
  font-size: 3.6rem;
  font-weight: 900;
}

.price span {
  color: var(--muted);
  font-size: 0.92rem;
}

.price-card ul {
  display: grid;
  gap: 16px;
  margin-bottom: 30px;
  list-style: none;
}

.price-card li {
  position: relative;
  padding-left: 28px;
  color: var(--soft);
}

.price-card li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 2px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background:
    linear-gradient(135deg, rgba(139, 92, 246, 0.8), rgba(98, 230, 255, 0.45));
  box-shadow: 0 0 18px rgba(139, 92, 246, 0.36);
}

.stretch {
  width: 100%;
  margin-top: auto;
}

.admin-zone {
  padding-top: 92px;
}

.admin-site {
  padding-top: 118px;
}

.admin-page .dashboard-topbar {
  width: min(100% - 32px, 1480px);
}

.admin-hero {
  margin-bottom: 22px;
}

.admin-grid,
.admin-gate-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 18px;
}

.admin-grid.two {
  margin-top: 18px;
}

.admin-workspace {
  display: grid;
  grid-template-columns: 260px minmax(0, 1fr);
  gap: 18px;
}

.admin-sidebar-panel {
  position: sticky;
  top: 96px;
  align-self: start;
  padding: 16px;
  border: 1px solid rgba(158, 110, 255, 0.24);
  border-radius: var(--radius-lg);
  background: rgba(11, 7, 24, 0.78);
  box-shadow: var(--shadow);
}

.admin-nav {
  width: 100%;
  min-height: 42px;
  margin-bottom: 8px;
  display: grid;
  /* TROIS colonnes, pas deux : le numero, l'icone, puis l'intitule.
     Le bouton porte trois enfants — <span>01</span>, le <svg>, et le
     texte nu. Avec deux colonnes, ce texte devenait un troisieme item
     de grille pose sur la LIGNE SUIVANTE, dans une colonne de 34 px :
     « Vue globale » s'y coupait en deux, « Blacklist bot » aussi. Le
     defaut est apparu le jour ou les icones sont arrivees dans ces
     boutons, et se voyait sur toute la barre. */
  grid-template-columns: 34px auto minmax(0, 1fr);
  align-items: center;
  gap: 10px;
  border-radius: var(--radius);
  background: transparent;
  color: var(--muted);
  text-align: left;
}

.admin-nav > span:first-child {
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  margin-left: 6px;
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.06);
  color: var(--soft);
  font-size: 0.72rem;
}

.admin-nav:hover,
.admin-nav.is-active {
  color: var(--text);
  background: rgba(139, 92, 246, 0.18);
}

.admin-nav.is-active > span:first-child {
  background: linear-gradient(135deg, var(--purple), var(--cyan));
  color: #fff;
}

.admin-view {
  display: none;
}

.admin-view.is-active {
  display: block;
}

.admin-panel {
  padding: 24px;
  border: 1px solid rgba(158, 110, 255, 0.24);
  border-radius: var(--radius-lg);
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.055), rgba(255, 255, 255, 0.018)),
    var(--panel);
  box-shadow: var(--shadow);
}

.admin-panel h3 {
  margin-bottom: 10px;
}

.admin-panel p {
  color: var(--muted);
  line-height: 1.65;
}

.admin-panel label {
  display: grid;
  gap: 8px;
  color: var(--soft);
  font-size: 0.9rem;
  font-weight: 900;
}

.admin-panel input,
.admin-panel select {
  min-height: 44px;
  width: 100%;
  padding: 10px 12px;
  border: 1px solid rgba(158, 110, 255, 0.24);
  border-radius: var(--radius);
  outline: 0;
  background: rgba(6, 3, 14, 0.74);
  color: var(--text);
}

.admin-login-panel {
  display: grid;
  gap: 14px;
}

.admin-access-note {
  display: grid;
  align-content: start;
}

.admin-error {
  margin: 0;
  padding: 10px 12px;
  border: 1px solid rgba(255, 88, 88, 0.32);
  border-radius: var(--radius);
  background: rgba(255, 88, 88, 0.1);
  color: #ffd1d1 !important;
  font-weight: 900;
}

.admin-panel-head {
  margin-bottom: 14px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.admin-panel-head h3 {
  margin: 0;
}

.admin-badge {
  min-height: 28px;
  padding: 0 10px;
  display: inline-flex;
  align-items: center;
  border-radius: 999px;
  background: rgba(139, 92, 246, 0.16);
  color: var(--soft);
  font-size: 0.76rem;
  font-weight: 900;
}

.admin-badge.active {
  background: rgba(101, 245, 150, 0.14);
  color: #baffcf;
}

.site-stat-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
}

.site-stat-grid div,
.admin-list div,
.blacklist-list div,
.server-log-feed div,
.admin-server-list div {
  border: 1px solid rgba(158, 110, 255, 0.18);
  border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.045);
}

.site-stat-grid div {
  min-height: 104px;
  padding: 16px;
  display: grid;
  align-content: space-between;
}

.site-stat-grid span {
  font-size: 1.7rem;
  font-weight: 900;
}

.site-stat-grid small,
.admin-server-list small {
  color: var(--muted);
}

.admin-list,
.blacklist-list,
.server-log-feed,
.admin-server-list {
  margin-top: 14px;
  display: grid;
  gap: 10px;
}

.admin-list div,
.blacklist-list div {
  padding: 12px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.admin-list strong,
.admin-list small,
.blacklist-list strong,
.blacklist-list small {
  display: block;
}

.admin-list small,
.blacklist-list small {
  margin-top: 3px;
}

.admin-action-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 10px;
}

.admin-action-row.split {
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) auto;
}

.admin-list button,
.blacklist-list button {
  min-height: 34px;
  padding: 0 12px;
  border-radius: var(--radius);
  border: 1px solid rgba(158, 110, 255, 0.24);
  background: rgba(255, 255, 255, 0.06);
  color: var(--text);
}

.admin-list button:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

.danger-btn {
  background: linear-gradient(135deg, #ed4245, #b15cff) !important;
}

.server-log-feed div {
  padding: 14px;
  display: grid;
  grid-template-columns: 74px minmax(160px, 0.55fr) minmax(0, 1fr);
  gap: 12px;
  align-items: center;
}

.server-log-feed span {
  color: var(--cyan);
  font-weight: 900;
}

.server-log-feed em {
  color: var(--soft);
  font-style: normal;
}

.admin-server-list div {
  padding: 12px;
  display: grid;
  grid-template-columns: 54px minmax(0, 1fr);
  align-items: center;
  gap: 12px;
}

.admin-server-list .server-logo-shell {
  width: 54px;
  height: 54px;
}

.admin-server-list .server-logo-shell::before {
  font-size: 0.72rem;
}

.admin-server-list .server-logo-shell img {
  width: 54px;
  height: 54px;
  padding: 3px;
  object-fit: contain;
}

.admin-server-list strong,
.admin-server-list small {
  display: block;
}

.wiki-page .site-header {
  background: rgba(7, 4, 17, 0.72);
}

.wiki-shell {
  padding-top: 118px;
}

.wiki-hero {
  max-width: 960px;
  margin: 0 auto 26px;
  text-align: center;
}

.wiki-hero h1 {
  margin: 8px 0 14px;
  font-size: clamp(2.6rem, 7vw, 5.4rem);
  line-height: 0.95;
  letter-spacing: 0;
}

.wiki-hero p:not(.eyebrow) {
  color: var(--soft);
  line-height: 1.7;
}

.wiki-layout {
  display: grid;
  grid-template-columns: 250px minmax(0, 1fr);
  gap: 22px;
  align-items: start;
}

.wiki-toc {
  position: sticky;
  top: 108px;
  display: grid;
  gap: 8px;
  padding: 16px;
  border: 1px solid rgba(158, 110, 255, 0.24);
  border-radius: var(--radius-lg);
  background: rgba(11, 7, 24, 0.78);
  box-shadow: var(--shadow);
}

.wiki-toc a {
  min-height: 38px;
  padding: 0 12px;
  display: flex;
  align-items: center;
  border-radius: var(--radius);
  color: var(--soft);
  font-weight: 900;
}

.wiki-toc a:hover {
  background: rgba(139, 92, 246, 0.18);
  color: var(--text);
}

.wiki-content {
  display: grid;
  gap: 18px;
}

.wiki-section {
  padding: 26px;
  border: 1px solid rgba(158, 110, 255, 0.24);
  border-radius: var(--radius-lg);
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.055), rgba(255, 255, 255, 0.018)),
    rgba(18, 12, 34, 0.72);
  box-shadow: var(--shadow);
}

.wiki-section h2 {
  margin-bottom: 12px;
  font-size: 1.5rem;
}

.wiki-section p,
.wiki-check-list {
  color: var(--soft);
  line-height: 1.75;
}

.wiki-card-grid,
.wiki-plan-grid,
.command-doc-grid {
  display: grid;
  gap: 12px;
  margin-top: 16px;
}

.wiki-card-grid,
.wiki-plan-grid {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.command-doc-grid {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.wiki-card-grid article,
.wiki-plan-grid article,
.command-doc-grid article {
  padding: 16px;
  border: 1px solid rgba(158, 110, 255, 0.18);
  border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.045);
}

.wiki-card-grid strong,
.wiki-plan-grid strong,
.command-doc-grid code {
  display: block;
  margin-bottom: 8px;
  color: var(--text);
  font-weight: 900;
}

.wiki-card-grid span,
.wiki-plan-grid span,
.command-doc-grid span {
  color: var(--muted);
  line-height: 1.55;
}

.command-doc-grid code {
  width: fit-content;
  padding: 5px 8px;
  border-radius: 8px;
  background: rgba(139, 92, 246, 0.18);
  color: #dccdff;
}

.wiki-check-list {
  display: grid;
  gap: 10px;
  padding-left: 18px;
}

.patch-toolbar {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
  margin-bottom: 26px;
}

.filter-btn,
.quick-questions button {
  min-height: 38px;
  padding: 0 15px;
  border-radius: 999px;
  border: 1px solid rgba(158, 110, 255, 0.24);
  background: rgba(255, 255, 255, 0.035);
  color: var(--soft);
  transition: background 0.2s ease, border-color 0.2s ease, transform 0.2s ease;
}

.filter-btn:hover,
.filter-btn.is-active,
.quick-questions button:hover {
  border-color: var(--line-strong);
  background: rgba(139, 92, 246, 0.18);
  transform: translateY(-1px);
}

.patch-redirect {
  max-width: 900px;
  min-height: 310px;
  margin: 0 auto;
  padding: 34px;
  display: grid;
  grid-template-columns: 260px minmax(0, 1fr);
  gap: 26px;
  align-items: center;
  overflow: hidden;
  border-radius: var(--radius-lg);
}

.patch-redirect::before {
  content: "";
  position: absolute;
  inset: -20%;
  opacity: 0.7;
  background:
    radial-gradient(circle at 22% 36%, rgba(139, 92, 246, 0.3), transparent 16rem),
    radial-gradient(circle at 80% 68%, rgba(98, 230, 255, 0.11), transparent 18rem);
  pointer-events: none;
}

.patch-orbit {
  position: relative;
  z-index: 1;
  width: min(220px, 100%);
  aspect-ratio: 1;
  margin: auto;
  border: 1px solid rgba(158, 110, 255, 0.28);
  border-radius: 50%;
  background:
    radial-gradient(circle, rgba(177, 92, 255, 0.18), transparent 42%),
    rgba(255, 255, 255, 0.035);
  box-shadow:
    0 0 48px rgba(139, 92, 246, 0.34),
    0 0 0 1px rgba(255, 255, 255, 0.04) inset;
  animation: orbitPulse 4s ease-in-out infinite alternate;
}

.patch-orbit::before,
.patch-orbit::after,
.patch-orbit span {
  content: "";
  position: absolute;
  border-radius: 50%;
}

.patch-orbit::before {
  inset: 44px;
  border: 1px solid rgba(158, 110, 255, 0.34);
}

.patch-orbit::after {
  inset: 86px;
  background: linear-gradient(135deg, #7c5cff, #b15cff);
  box-shadow: 0 0 40px rgba(177, 92, 255, 0.58);
}

.patch-orbit span {
  width: 10px;
  height: 10px;
  background: var(--soft);
  box-shadow: 0 0 18px rgba(216, 204, 255, 0.8);
}

.patch-orbit span:nth-child(1) {
  top: 35px;
  left: 62px;
}

.patch-orbit span:nth-child(2) {
  right: 38px;
  top: 92px;
}

.patch-orbit span:nth-child(3) {
  left: 88px;
  bottom: 36px;
}

@keyframes orbitPulse {
  to {
    transform: scale(1.035);
    box-shadow:
      0 0 68px rgba(139, 92, 246, 0.46),
      0 0 0 1px rgba(255, 255, 255, 0.04) inset;
  }
}

.patch-redirect-content {
  position: relative;
  z-index: 1;
}

.patch-mini-label {
  width: max-content;
  max-width: 100%;
  min-height: 34px;
  padding: 0 12px;
  display: inline-flex;
  align-items: center;
  border: 1px solid rgba(158, 110, 255, 0.28);
  border-radius: 999px;
  color: var(--soft);
  background: rgba(139, 92, 246, 0.16);
  font-size: 0.82rem;
  font-weight: 900;
}

.patch-redirect h3 {
  margin-top: 18px;
  font-size: clamp(1.8rem, 4vw, 3rem);
  line-height: 1.06;
}

.patch-redirect p {
  margin-top: 14px;
  color: var(--muted);
  line-height: 1.72;
}

.patch-actions {
  margin-top: 24px;
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

.patch-list {
  max-width: 900px;
  margin: 0 auto;
  display: grid;
  gap: 16px;
}

.patch-item {
  padding: 24px;
  display: grid;
  grid-template-columns: 130px minmax(0, 1fr);
  gap: 24px;
  overflow: hidden;
  border-radius: var(--radius);
}

.patch-date {
  color: var(--muted);
  font-size: 0.9rem;
}

.patch-badge {
  width: max-content;
  margin-top: 12px;
  padding: 6px 10px;
  border-radius: 999px;
  color: var(--soft);
  background: rgba(139, 92, 246, 0.16);
  border: 1px solid rgba(139, 92, 246, 0.26);
  font-size: 0.72rem;
  text-transform: uppercase;
}

.patch-content h3 {
  font-size: 1.2rem;
}

.patch-content p {
  margin-top: 10px;
  color: var(--muted);
  line-height: 1.65;
}

.patch-content ul {
  margin-top: 14px;
  display: grid;
  gap: 8px;
  list-style: none;
}

.patch-content li {
  position: relative;
  padding-left: 18px;
  color: var(--soft);
  line-height: 1.55;
}

.patch-content li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.66em;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--purple-2);
}

.discord-link {
  width: max-content;
  max-width: 100%;
  min-height: 44px;
  margin: 28px auto 0;
  padding: 0 18px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  color: var(--soft);
  background: rgba(255, 255, 255, 0.04);
}

.faq-list {
  max-width: 860px;
  margin: 0 auto;
  display: grid;
  gap: 14px;
}

.faq-box {
  padding: 0;
  overflow: hidden;
  border-radius: var(--radius);
}

.faq-box summary {
  min-height: 62px;
  padding: 0 22px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  cursor: pointer;
  list-style: none;
}

.faq-box summary::-webkit-details-marker {
  display: none;
}

.faq-box summary::after {
  content: "+";
  color: var(--purple-2);
  font-size: 1.4rem;
}

.faq-box[open] summary::after {
  content: "−";
}

.faq-box p {
  padding: 0 22px 22px;
  color: var(--muted);
  line-height: 1.7;
}

.cta {
  max-width: 920px;
  margin-bottom: 0;
  padding: 70px 24px;
  text-align: center;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background:
    radial-gradient(circle at 50% 0%, rgba(139, 92, 246, 0.26), transparent 22rem),
    rgba(255, 255, 255, 0.035);
  box-shadow: var(--shadow);
}

.cta .primary-btn {
  margin-top: 24px;
}

.footer {
  position: relative;
  margin-top: 0;
  padding: 34px 20px 112px;
  color: var(--muted);
  text-align: center;
  background:
    radial-gradient(circle at 50% 100%, rgba(139, 92, 246, 0.24), transparent 18rem),
    linear-gradient(180deg, rgba(5, 2, 13, 0), rgba(5, 2, 13, 0.96));
  overflow: hidden;
}

.footer::before {
  content: "";
  position: absolute;
  top: 0;
  left: 50%;
  width: min(740px, calc(100% - 56px));
  height: 1px;
  transform: translateX(-50%);
  background: linear-gradient(90deg, transparent, rgba(177, 92, 255, 0.62), transparent);
}

.footer::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: 74px;
  width: min(220px, 46vw);
  height: 3px;
  transform: translateX(-50%);
  border-radius: 999px;
  background: linear-gradient(90deg, transparent, #8b5cf6, #62e6ff, transparent);
  box-shadow: 0 0 24px rgba(139, 92, 246, 0.5);
}

.assistant-launcher {
  position: fixed;
  right: 26px;
  bottom: 26px;
  z-index: 70;
  width: 62px;
  height: 62px;
  border-radius: 50%;
  background: linear-gradient(135deg, #7c5cff, #b15cff);
  box-shadow:
    0 18px 42px rgba(139, 92, 246, 0.48),
    0 0 36px rgba(177, 92, 255, 0.42);
}

.assistant-launcher span,
.assistant-launcher span::before {
  position: absolute;
  display: block;
  border: 2px solid white;
}

.assistant-launcher span {
  width: 26px;
  height: 22px;
  inset: 18px 16px;
  border-radius: 50% 50% 50% 12%;
}

.assistant-launcher span::before {
  content: "";
  width: 8px;
  height: 8px;
  right: -4px;
  bottom: -5px;
  border-left: 0;
  border-top: 0;
  transform: rotate(10deg);
}

.assistant {
  position: fixed;
  right: 24px;
  bottom: 96px;
  z-index: 80;
  width: min(390px, calc(100vw - 28px));
  max-height: min(680px, calc(100vh - 124px));
  display: grid;
  grid-template-rows: auto minmax(220px, 1fr) auto;
  overflow: hidden;
  border-radius: 22px;
  opacity: 0;
  pointer-events: none;
  transform: translateY(18px) scale(0.98);
  transition: opacity 0.22s ease, transform 0.22s ease;
}

.assistant.is-open {
  opacity: 1;
  pointer-events: auto;
  transform: translateY(0) scale(1);
}

.assistant-header {
  min-height: 72px;
  padding: 12px 16px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  border-bottom: 1px solid rgba(158, 110, 255, 0.22);
  background: rgba(22, 13, 42, 0.86);
}

.assistant-title strong {
  display: block;
}

.assistant-title small {
  margin-top: 3px;
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--muted);
}

.online-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--green);
  box-shadow: 0 0 12px rgba(101, 245, 150, 0.72);
}

.assistant-close {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: transparent;
  color: var(--muted);
  font-size: 2rem;
  line-height: 1;
}

.assistant-close:hover {
  color: var(--text);
  background: rgba(255, 255, 255, 0.06);
}

.assistant-messages {
  padding: 18px 16px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--purple) rgba(255, 255, 255, 0.04);
}

.assistant-messages::-webkit-scrollbar {
  width: 8px;
}

.assistant-messages::-webkit-scrollbar-thumb {
  border-radius: 20px;
  background: var(--purple);
}

.assistant-msg {
  max-width: 86%;
  padding: 13px 15px;
  border-radius: 8px;
  color: var(--soft);
  line-height: 1.55;
  animation: riseIn 0.22s ease both;
}

.assistant-msg.user {
  align-self: flex-end;
  background: linear-gradient(135deg, #7c5cff, #b15cff);
  color: white;
}

.assistant-msg.bot {
  align-self: flex-start;
  border: 1px solid rgba(158, 110, 255, 0.24);
  background: rgba(255, 255, 255, 0.055);
}

.assistant-msg a {
  min-height: 38px;
  margin-top: 12px;
  padding: 0 14px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius);
  background: rgba(139, 92, 246, 0.26);
  color: white;
  font-weight: 900;
}

.quick-questions {
  padding: 14px 16px 18px;
  border-top: 1px solid rgba(158, 110, 255, 0.22);
  background: rgba(8, 5, 18, 0.74);
}

.quick-questions p {
  margin-bottom: 10px;
}

.quick-questions button {
  margin: 4px 4px 4px 0;
  min-height: 34px;
  font-size: 0.82rem;
}

.reveal {
  opacity: 0;
  filter: blur(10px);
  transform: translateY(34px) scale(0.985);
}

.reveal.is-visible {
  opacity: 1;
  filter: blur(0);
  transform: translateY(0) scale(1);
  transition:
    opacity 0.72s cubic-bezier(.2,.8,.2,1),
    filter 0.72s cubic-bezier(.2,.8,.2,1),
    transform 0.72s cubic-bezier(.2,.8,.2,1);
}

@media (max-width: 980px) {
  .navbar {
    border-radius: 24px;
  }

  .language-switch {
    width: 100%;
    justify-content: space-between;
  }

  .language-switch select {
    max-width: 100%;
  }

  .nav-cta,
  .nav-action-btn {
    justify-content: center;
  }

  .hero-panel,
  .demo-layout {
    grid-template-columns: 1fr;
  }

  .demo-controls {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    max-height: 300px;
  }

  .demo-group {
    grid-column: 1 / -1;
  }

  .demo-command {
    text-align: center;
    padding: 0 10px;
    font-size: 0.9rem;
  }

  .command-rail {
    border-left: 0;
    border-top: 1px solid rgba(158, 110, 255, 0.15);
  }

  .feature-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .pricing-grid,
  .wiki-card-grid,
  .wiki-plan-grid,
  .command-doc-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .wiki-layout {
    /* minmax(0, 1fr) et pas 1fr : sinon un bloc large — le formulaire de
       retractation — ferait grandir la colonne au lieu de defiler seul. */
    grid-template-columns: minmax(0, 1fr);
  }

  .wiki-toc {
    position: relative;
    top: auto;
  }
}

@media (max-width: 760px) {
  .section-shell {
    width: min(100% - 28px, 1180px);
  }

  .site-header {
    top: 8px;
    padding: 0 10px;
  }

  .hero {
    min-height: auto;
    padding-top: 92px;
  }

  .stats,
  .pricing-grid,
  .feature-grid,
  .admin-grid,
  .admin-gate-grid,
  .wiki-card-grid,
  .wiki-plan-grid,
  .command-doc-grid {
    grid-template-columns: 1fr;
  }

  .stats {
    padding-bottom: 32px;
  }

  .features,
  .demo,
  .pricing,
  .admin-site,
  .admin-zone,
  .patch-notes,
  .faq,
  .cta {
    padding: 58px 0;
  }

  .hero-panel {
    min-height: auto;
  }

  .command-stage {
    min-height: 240px;
    padding: 18px;
  }

  .price-card {
    min-height: auto;
    padding: 24px;
  }

  .patch-item {
    grid-template-columns: 1fr;
    gap: 14px;
  }

  .patch-redirect {
    grid-template-columns: 1fr;
    padding: 24px;
  }

  .patch-orbit {
    width: min(180px, 78vw);
  }

  .message {
    max-width: 92%;
  }

  .assistant {
    right: 14px;
    bottom: 88px;
  }

  .assistant-launcher {
    right: 18px;
    bottom: 18px;
  }
}

body {
  animation: pageFade 0.78s ease both;
}

body.assistant-open {
  overflow: hidden;
}

@keyframes pageFade {
  from {
    opacity: 0;
    filter: blur(8px);
  }
  to {
    opacity: 1;
    filter: blur(0);
  }
}

.animated-bg {
  position: fixed;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  pointer-events: none;
}

.animated-bg span {
  position: absolute;
  width: 42vw;
  aspect-ratio: 1;
  border-radius: 50%;
  background:
    radial-gradient(circle at 35% 35%, rgba(177, 92, 255, 0.22), transparent 28%),
    radial-gradient(circle at 66% 62%, rgba(98, 230, 255, 0.1), transparent 34%),
    radial-gradient(circle, rgba(139, 92, 246, 0.12), transparent 66%);
  filter: blur(32px);
  opacity: 0.8;
  mix-blend-mode: screen;
  animation: nebulaFloat 18s ease-in-out infinite alternate;
}

.animated-bg span:nth-child(1) {
  left: -12vw;
  top: 8vh;
}

.animated-bg span:nth-child(2) {
  right: -14vw;
  top: 26vh;
  animation-duration: 22s;
  animation-delay: -6s;
}

.animated-bg span:nth-child(3) {
  left: 28vw;
  bottom: -20vw;
  animation-duration: 26s;
  animation-delay: -10s;
}

@keyframes nebulaFloat {
  to {
    transform: translate3d(8vw, -5vh, 0) rotate(18deg) scale(1.12);
  }
}

body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: 0.22;
  background:
    linear-gradient(115deg, transparent 0 44%, rgba(139, 92, 246, 0.18) 48%, transparent 54% 100%);
  animation: lightSweep 9s ease-in-out infinite;
}

@keyframes lightSweep {
  0%, 30% {
    transform: translateX(-70%);
    opacity: 0;
  }
  55% {
    opacity: 0.28;
  }
  100% {
    transform: translateX(70%);
    opacity: 0;
  }
}

@media (min-width: 981px) {
  .section-shell {
    width: min(1280px, calc(100% - 56px));
  }

  .navbar {
    width: min(1280px, 100%);
  }

  .nav-links {
    gap: 12px;
    font-size: 0.86rem;
  }

  .hero {
    min-height: auto;
    padding: 96px 0 58px;
    /* Une seule colonne depuis que l'apercu Discord a quitte l'accueil :
       la seconde restait ouverte, large de 680 px, et vide. */
    grid-template-columns: minmax(0, 1fr);
    gap: 38px;
    align-items: center;
    justify-items: center;
  }

  .hero-copy {
    max-width: 62ch;
    text-align: center;
  }

  .hero-copy .hero-actions { justify-content: center; }

  .hero-copy .eyebrow {
    margin-bottom: 18px;
  }

  h1 {
    font-size: clamp(4.8rem, 8vw, 7.2rem);
    line-height: 0.9;
  }

  .hero-lead {
    max-width: 520px;
    margin-left: 0;
    margin-right: 0;
    font-size: 1.04rem;
  }

  .hero-actions {
    justify-content: flex-start;
  }

  .hero-panel {
    width: 100%;
    min-height: 476px;
    grid-template-columns: minmax(0, 1fr) 256px;
  }

  .command-stage {
    min-height: 432px;
    padding: 24px;
    align-content: center;
  }
}

main {
  overflow: clip;
}

.embed-pill {
  width: fit-content;
  max-width: 100%;
  white-space: normal;
  overflow-wrap: anywhere;
}

/* On mesure le message, pas l'embed : une requete de conteneur ne peut
   pas modifier la largeur de son propre conteneur — la condition
   dependrait de ce qu'elle decide. */
.discord-message,
.discord-command-preview {
  container-type: inline-size;
}

.avert-embed {
  padding: 16px;
}

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

.avert-head h3 {
  margin: 0 0 12px;
  font-size: 1.05rem;
}

.avert-head h4 {
  margin: 0;
  font-size: 1.18rem;
  line-height: 1.2;
}

.avert-main-fields,
.avert-secondary-fields {
  margin-top: 14px;
  display: grid;
  gap: 12px 16px;
  align-items: start;
}

.avert-main-fields {
  grid-template-columns: 78px minmax(180px, 1fr) minmax(132px, 0.9fr);
}

.avert-secondary-fields {
  grid-template-columns: minmax(150px, 1fr) minmax(92px, 0.55fr) minmax(92px, 0.55fr);
}

.avert-field {
  min-width: 0;
  color: #ded8f5;
  line-height: 1.35;
}

.avert-field strong {
  display: block;
  margin-bottom: 5px;
  color: white;
  font-size: 0.98rem;
}

.progress-line {
  display: flex;
  align-items: center;
  gap: 8px;
}

.progress-line .meter {
  flex: 1 1 86px;
  min-width: 72px;
}

.mod-photo {
  flex: 0 0 auto;
  width: 106px;
  height: 92px;
}

@container (max-width: 560px) {
  .avert-main-fields {
    grid-template-columns: 72px minmax(0, 1fr);
  }

  .avert-field.joined {
    grid-column: 1 / -1;
  }

  .avert-secondary-fields {
    grid-template-columns: minmax(0, 1fr) minmax(84px, 0.6fr);
  }

  .avert-field.progress {
    grid-column: 1 / -1;
  }

  .mod-photo {
    width: 92px;
    height: 82px;
  }
}

@container (max-width: 420px) {
  .avert-head {
    display: grid;
    grid-template-columns: 1fr;
  }

  .mod-photo {
    width: 100%;
    max-width: 130px;
  }

  .avert-main-fields,
  .avert-secondary-fields {
    grid-template-columns: 1fr;
  }

  .avert-field.joined,
  .avert-field.progress {
    grid-column: auto;
  }
}

.discord-command-preview {
  width: 100%;
  max-width: 650px;
  margin: 0 auto;
  color: #ede9ff;
  font-size: 0.92rem;
}

.discord-message {
  display: grid;
  grid-template-columns: 44px minmax(0, 1fr);
  gap: 12px;
  animation: riseIn 0.28s ease both;
}

.discord-avatar {
  width: 42px;
  height: 42px;
  overflow: hidden;
  border-radius: 50%;
  border: 1px solid rgba(139, 92, 246, 0.35);
  background: linear-gradient(135deg, rgba(139, 92, 246, 0.42), rgba(8, 5, 18, 0.9));
  display: grid;
  place-items: center;
  color: var(--soft);
  font-size: 0.7rem;
  font-weight: 900;
}

.discord-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.discord-meta {
  margin-bottom: 5px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  color: #9f95b8;
  font-size: 0.82rem;
}

.discord-bot {
  color: #ffd84d;
  font-size: 1rem;
  font-weight: 900;
}

.discord-app {
  padding: 2px 5px;
  border-radius: 4px;
  background: #5865f2;
  color: white;
  font-size: 0.72rem;
  font-weight: 900;
}

.used-command {
  color: #c8c0ff;
}

.slash-chip {
  padding: 2px 6px;
  border-radius: 4px;
  background: rgba(88, 101, 242, 0.25);
  color: #b9c7ff;
}

.discord-embed {
  position: relative;
  overflow: hidden;
  padding: 16px 16px 15px;
  border-left: 4px solid #5865f2;
  border-radius: 5px;
  background: rgba(32, 25, 53, 0.96);
  box-shadow: 0 14px 38px rgba(0, 0, 0, 0.24);
}

/* La vignette est un vrai element de grille, pas un bloc pose sur un
   creux de 128 px reserve a l'aveugle : elle prend la place qu'elle
   occupe, et le texte tout le reste. */
.embed-with-thumb {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  column-gap: 14px;
}

.embed-with-thumb > * { grid-column: 1; }

.embed-with-thumb > .embed-thumb {
  grid-column: 2;
  grid-row: 1 / span 2;
  position: static;
  align-self: start;
}

.embed-thumb {
  position: absolute;
  top: 18px;
  right: 18px;
  width: 88px;
  height: 88px;
  display: grid;
  place-items: center;
  overflow: hidden;
  border-radius: 8px;
  border: 1px solid rgba(139, 92, 246, 0.28);
  background: rgba(8, 5, 18, 0.74);
}

.embed-thumb img {
  position: relative;
  z-index: 1;
  width: 100%;
  height: 100%;
  padding: 4px;
  object-fit: contain;
}

.embed-thumb::before {
  content: "";
  color: var(--soft);
  font-size: 0.74rem;
  font-weight: 900;
}

.embed-thumb img + * {
  display: none;
}

.discord-embed h3 {
  margin-bottom: 9px;
  font-size: 1.06rem;
}

.discord-embed p {
  color: #ddd7f7;
  line-height: 1.46;
}

.discord-embed strong {
  color: white;
}

.embed-grid {
  margin-top: 12px;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px 16px;
}

.embed-stat strong,
.embed-field strong {
  display: block;
  margin-bottom: 4px;
}

.embed-pill {
  width: max-content;
  min-width: 24px;
  padding: 2px 6px;
  border-radius: 4px;
  background: rgba(255, 255, 255, 0.1);
  color: #d8d2ef;
}

.embed-actions {
  margin-top: 12px;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

/* L'embed reservait 128 px a sa vignette quelle que soit sa largeur.
   Dans la colonne etroite de l'accueil il ne restait que 170 px de
   texte : le titre se pliait sur trois lignes, les six statistiques
   tenaient dans des colonnes de 46 px et les boutons descendaient un
   par ligne. La mesure qui compte n'est pas celle de l'ecran mais celle
   de l'embed — c'est ce que dit une requete de conteneur, et le
   `container-type: inline-size` etait deja pose plus haut. */
@container (max-width: 460px) {
  /* Trop etroit pour deux colonnes : la vignette passe sous le texte. */
  .embed-with-thumb {
    grid-template-columns: minmax(0, 1fr);
  }

  .embed-with-thumb > .embed-thumb {
    grid-column: 1;
    grid-row: auto;
    order: 99;
    width: 64px;
    height: 64px;
    margin-top: 12px;
  }

  .embed-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 8px 12px;
  }
}

.embed-actions span {
  min-height: 34px;
  padding: 0 13px;
  display: inline-flex;
  align-items: center;
  border-radius: 8px;
  color: white;
  font-weight: 900;
}

.action-red {
  background: #e74c5f;
}

.action-blue {
  background: #5865f2;
}

.action-green {
  background: #0aa966;
}

.action-dark {
  background: rgba(255, 255, 255, 0.08);
}

.embed-footer {
  margin-top: 13px;
  color: #d8d2ef;
  font-size: 0.78rem;
  font-weight: 800;
}

.mod-record {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 92px;
  gap: 18px;
  align-items: start;
}

.mod-photo {
  width: 92px;
  height: 92px;
  border-radius: 6px;
  background:
    radial-gradient(circle at 45% 34%, rgba(255, 216, 77, 0.36), transparent 22%),
    linear-gradient(135deg, rgba(89, 68, 41, 0.9), rgba(14, 13, 25, 0.95));
  border: 1px solid rgba(255, 255, 255, 0.08);
}

.mod-fields {
  margin-top: 12px;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px 16px;
}

.meter {
  width: 92px;
  height: 18px;
  border-radius: 3px;
  overflow: hidden;
  background: #f1f4ff;
}

.meter span {
  display: block;
  width: 0%;
  height: 100%;
  background: #5865f2;
}

.assistant-overlay {
  position: fixed;
  inset: 0;
  z-index: 9000;
  background: rgba(4, 2, 10, 0.76);
  backdrop-filter: blur(14px);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.22s ease, visibility 0.22s ease;
}

.assistant-overlay.is-open {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}

.assistant {
  left: 50%;
  top: 50%;
  right: auto;
  bottom: auto;
  z-index: 9001;
  width: min(520px, calc(100vw - 32px));
  height: min(650px, calc(100vh - 54px));
  max-height: calc(100vh - 54px);
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
  border-radius: 18px;
  background:
    radial-gradient(circle at 50% 0%, rgba(139, 92, 246, 0.22), transparent 18rem),
    linear-gradient(180deg, #120b25, #070411);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transform: translate(-50%, -45%) scale(0.96);
  transition:
    opacity 0.24s ease,
    visibility 0.24s ease,
    transform 0.24s cubic-bezier(.2,.8,.2,1);
}

.assistant.is-open {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transform: translate(-50%, -50%) scale(1);
}

.assistant-messages {
  min-height: 0;
  max-height: none;
}

@media (max-width: 980px) {
  .partner-grid {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 760px) {
  .hero-copy {
    text-align: center;
  }

  .hero-actions {
    justify-content: center;
  }

  .embed-with-thumb {
    padding-right: 16px;
  }

  .embed-thumb {
    position: relative;
    top: auto;
    right: auto;
    margin: 12px 0 0;
  }

  .embed-grid,
  .mod-fields {
    grid-template-columns: 1fr 1fr;
  }

  .mod-record {
    grid-template-columns: 1fr;
  }

  .assistant {
    left: 50%;
    top: 50%;
    right: auto;
    bottom: auto;
    width: min(430px, calc(100vw - 24px));
    max-height: calc(100vh - 42px);
    transform: translate(-50%, -45%) scale(0.96);
  }

  .assistant.is-open {
    transform: translate(-50%, -50%) scale(1);
  }

  .assistant-messages {
    min-height: 260px;
  }
}

/* Correctifs affichage: animations du hero, retour visuel fiable et assistant desktop centre. */
@keyframes navEnter {
  from {
    opacity: 0;
    transform: translateY(-18px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes heroTextEnter {
  from {
    opacity: 0;
    transform: translateY(24px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes panelEnter {
  from {
    opacity: 0;
    transform: translateY(28px) scale(0.98);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

html {
  scroll-padding-top: 110px;
}

.assistant-overlay {
  z-index: 9000;
}

.assistant {
  position: fixed;
  left: 50%;
  top: 50%;
  right: auto;
  bottom: auto;
  z-index: 9001;
  width: min(520px, calc(100vw - 32px));
  height: min(650px, calc(100dvh - 54px));
  max-height: calc(100dvh - 54px);
  transform: translate(-50%, -45%) scale(0.96);
}

.assistant.is-open {
  transform: translate(-50%, -50%) scale(1);
}

.assistant-launcher {
  z-index: 8999;
}

body.assistant-open {
  overflow: hidden;
}

@media (max-width: 760px) {
  .assistant {
    width: min(430px, calc(100vw - 24px));
    height: min(650px, calc(100dvh - 42px));
    max-height: calc(100dvh - 42px);
  }
}

body {
  animation: pageFadeClean 0.78s ease both;
  filter: none;
}

@keyframes pageFadeClean {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

/* Entrée propre au chargement : garde le même style, ajoute seulement une arrivée douce. */
html.site-is-loading {
  scroll-behavior: auto;
}

html.site-is-loading,
html.site-is-loading body {
  overflow-anchor: none;
}

html.site-is-loading main,
html.site-is-loading .site-header {
  opacity: 0;
  transform: translateY(14px);
}

main,
.site-header {
  transition: opacity 0.62s ease, transform 0.62s cubic-bezier(.2,.8,.2,1);
}

/* Dashboard ModBot */
.dashboard-page {
  background:
    radial-gradient(circle at 12% 0%, rgba(139, 92, 246, 0.18), transparent 28rem),
    radial-gradient(circle at 94% 12%, rgba(98, 230, 255, 0.1), transparent 24rem),
    linear-gradient(180deg, #05020d 0%, #080411 100%);
}

.dashboard-page [hidden] {
  display: none !important;
}

.dashboard-page button,
.dashboard-page .primary-btn,
.dashboard-page .secondary-btn {
  position: relative;
  overflow: hidden;
  isolation: isolate;
}

.dashboard-auth,
.server-picker {
  width: min(100% - 28px, 1080px);
  min-height: 100vh;
  margin: 0 auto;
  padding: 54px 0;
  display: grid;
  place-items: center;
}

.auth-card,
.server-picker-card {
  width: min(100%, 760px);
  padding: clamp(24px, 5vw, 46px);
  border: 1px solid rgba(158, 110, 255, 0.34);
  border-radius: var(--radius);
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.065), rgba(255, 255, 255, 0.02)),
    rgba(13, 7, 29, 0.86);
  box-shadow:
    0 0 0 1px rgba(255, 255, 255, 0.035) inset,
    0 26px 80px rgba(0, 0, 0, 0.48),
    0 0 60px rgba(139, 92, 246, 0.22);
  text-align: center;
}

.server-picker-card {
  width: min(100%, 980px);
  text-align: left;
}

.auth-logo {
  width: min(260px, 70vw);
  margin: 0 auto 18px;
  display: block;
  filter: drop-shadow(0 18px 35px rgba(139, 92, 246, 0.34));
}

.dashboard-auth h1,
.server-picker h1 {
  margin: 0 0 16px;
  font-size: clamp(2.3rem, 6vw, 4.4rem);
  line-height: 0.95;
}

.dashboard-auth p:not(.eyebrow),
.server-picker p:not(.eyebrow) {
  max-width: 620px;
  margin: 0 auto 24px;
  color: var(--soft);
  line-height: 1.7;
}

.server-picker-card p:not(.eyebrow) {
  margin-left: 0;
}

.api-url-field {
  width: min(100%, 560px);
  margin: 0 auto 12px;
  display: grid;
  gap: 8px;
  text-align: left;
  color: var(--soft);
  font-size: 0.86rem;
  font-weight: 900;
}

.api-url-field input {
  width: 100%;
  min-height: 48px;
  padding: 0 14px;
  border: 1px solid rgba(158, 110, 255, 0.34);
  border-radius: 8px;
  color: var(--text);
  background: rgba(4, 1, 12, 0.8);
  outline: none;
}

.api-url-field input:focus {
  border-color: rgba(178, 132, 255, 0.82);
  box-shadow: 0 0 0 3px rgba(139, 92, 246, 0.18);
}

.oauth-note {
  width: min(100%, 560px);
  margin: 0 auto 14px;
  padding: 12px 14px;
  border: 1px solid rgba(158, 110, 255, 0.28);
  border-radius: 8px;
  color: var(--soft);
  background: rgba(255, 255, 255, 0.045);
  line-height: 1.55;
}

.discord-login-btn,
.server-card {
  position: relative;
  overflow: hidden;
  border: 1px solid rgba(158, 110, 255, 0.38);
  border-radius: var(--radius);
  color: var(--text);
  background:
    linear-gradient(135deg, rgba(88, 101, 242, 0.3), rgba(177, 92, 255, 0.2)),
    rgba(255, 255, 255, 0.045);
  box-shadow:
    0 18px 42px rgba(88, 101, 242, 0.22),
    0 0 34px rgba(139, 92, 246, 0.18);
  transition: transform 0.18s ease, border-color 0.18s ease, box-shadow 0.18s ease, background 0.18s ease;
}

.discord-login-btn {
  min-height: 54px;
  padding: 0 24px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  font-weight: 900;
}

.discord-login-btn span {
  color: #c9b8ff;
}

.auth-return {
  display: block;
  width: fit-content;
  margin: 16px auto 0;
  color: var(--muted);
  font-weight: 800;
}

.server-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 14px;
}

.server-card {
  min-height: 150px;
  padding: 18px;
  display: grid;
  grid-template-columns: 72px minmax(0, 1fr);
  align-items: center;
  gap: 14px;
  text-align: left;
}

.server-logo-shell {
  position: relative;
  width: 72px;
  height: 72px;
  display: grid;
  place-items: center;
  overflow: hidden;
  border: 1px solid rgba(158, 110, 255, 0.34);
  border-radius: 8px;
  background:
    radial-gradient(circle at 35% 20%, rgba(98, 230, 255, 0.18), transparent 36%),
    linear-gradient(135deg, rgba(139, 92, 246, 0.25), rgba(9, 5, 20, 0.94));
  box-shadow: 0 0 22px rgba(139, 92, 246, 0.22);
  filter: drop-shadow(0 10px 18px rgba(139, 92, 246, 0.28));
}

.server-logo-shell::before {
  content: attr(data-initials);
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  color: var(--soft);
  font-size: 0.78rem;
  font-weight: 900;
}

.server-logo-shell img,
.server-logo {
  position: relative;
  z-index: 1;
  width: 72px;
  height: 72px;
  padding: 4px;
  object-fit: contain;
}

.server-logo-shell.is-fallback img {
  display: none;
}

.server-card strong {
  display: block;
  margin-bottom: 8px;
}

.server-card small {
  color: var(--muted);
  line-height: 1.45;
}

.server-card.is-uninstalled {
  opacity: 0.92;
  border-style: dashed;
}

.server-card.is-uninstalled small {
  color: #d0c5ff;
}

.discord-login-btn:hover,
.server-card:hover {
  transform: translateY(-3px);
  border-color: rgba(205, 184, 255, 0.7);
  box-shadow:
    0 22px 54px rgba(88, 101, 242, 0.3),
    0 0 42px rgba(139, 92, 246, 0.28);
}

.server-picker {
  width: 100%;
  max-width: none;
  min-height: 100vh;
  padding: 0;
  display: block;
  background: #313338;
  color: #f2f3f5;
}

.server-select-topbar {
  min-height: 62px;
  padding: 0 22px;
  display: flex;
  align-items: center;
  gap: 24px;
  background: #2b2d31;
  border-bottom: 1px solid rgba(0, 0, 0, 0.22);
}

.server-select-brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  color: #f2f3f5;
  font-size: 1.35rem;
  font-weight: 900;
}

.server-select-brand img {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  object-fit: cover;
}

.server-select-nav {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 20px;
  min-width: 0;
}

.server-select-nav a {
  color: #c7c9d1;
  font-size: 0.88rem;
  font-weight: 850;
  white-space: nowrap;
}

.server-select-nav a:hover {
  color: #fff;
}

.server-select-nav .is-premium {
  min-height: 28px;
  padding: 0 12px;
  display: inline-flex;
  align-items: center;
  border-radius: 6px;
  color: #fff;
  background: #3f9f63;
}

.server-picker .secondary-btn {
  background: #4b4d56;
  border-color: rgba(255, 255, 255, 0.08);
  box-shadow: none;
}

.server-picker-card {
  width: min(100% - 48px, 1320px);
  margin: 0 auto;
  padding: 46px 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
}

.server-select-heading {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px 14px;
  margin-bottom: 18px;
}

.server-select-heading h1 {
  margin: 0;
  /* 3 rem pour « Sélectionnez un serveur » au-dessus d'une liste de
     quatre cartes : le titre pesait plus lourd que ce qu'on vient
     choisir. */
  font-size: clamp(1.6rem, 2.6vw, 2.1rem);
  line-height: 1.15;
  letter-spacing: 0;
}

/* Le nombre de serveurs : une pastille a cote du titre, pas une phrase
   sur sa propre ligne. */
.server-select-heading p {
  margin: 0;
  padding: 3px 10px;
  border: 1px solid var(--line, #454750);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.04);
  color: #b5bac1;
  font-size: 0.82rem;
  font-weight: 650;
}

/* La recherche, le rafraichissement et l'invitation sur une seule
   ligne. Le grand bouton violet passait toute la largeur sous la
   recherche : sur un ecran dont le seul travail est de choisir un
   serveur, il pesait plus que les serveurs. */
.server-select-toolbar {
  margin-bottom: 16px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  gap: 10px;
  align-items: center;
}

.server-search {
  min-height: 44px;
  padding: 0 14px;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: 12px;
  border: 1px solid #454750;
  border-radius: 8px;
  background: #27292f;
  color: #b5bac1;
}

.server-search span {
  font-size: 1.2rem;
}

.server-search input {
  min-height: 40px;
  border: 0;
  outline: 0;
  background: transparent;
  color: #f2f3f5;
  font-weight: 750;
}

.server-search input::placeholder {
  color: #9499a3;
}

/* Trois colonnes imposees : sur un grand ecran les cartes s'etiraient
   a cinq cents pixels pour un nom et un chiffre, et la quatrieme
   restait seule sur sa ligne. Le nombre de colonnes suit desormais la
   largeur — quatre sur un grand ecran, une sur un telephone. */
.server-picker .server-grid {
  grid-template-columns: repeat(auto-fill, minmax(min(272px, 100%), 1fr));
  gap: 14px;
}

.server-picker .server-card {
  min-height: 150px;
  padding: 0;
  display: block;
  overflow: hidden;
  border: 1px solid #454750;
  border-radius: 8px;
  background: #2f3138;
  box-shadow: none;
  color: #f2f3f5;
}

.server-card-banner {
  height: 76px;
  display: block;
  background:
    linear-gradient(180deg, rgba(0, 0, 0, 0.05), rgba(0, 0, 0, 0.42)),
    var(--server-banner) center / cover,
    linear-gradient(135deg, #111318, #3a314d);
}

.server-card-body {
  min-height: 74px;
  padding: 0 14px 12px;
  display: grid;
  grid-template-columns: 64px minmax(0, 1fr) auto;
  align-items: end;
  gap: 12px;
}

.server-picker .server-card .server-logo-shell {
  width: 64px;
  height: 64px;
  margin-top: -28px;
  border: 4px solid #2f3138;
  border-radius: 50%;
  background: #15171c;
  box-shadow: none;
  filter: none;
}

.server-picker .server-card .server-logo-shell img,
.server-picker .server-card .server-logo {
  width: 56px;
  height: 56px;
  padding: 0;
  border-radius: 50%;
  object-fit: cover;
}

.server-card-copy {
  min-width: 0;
  padding-top: 8px;
}

.server-card-copy strong {
  margin: 0 0 5px;
  overflow: hidden;
  color: #fff;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.server-card-copy small {
  color: #b5bac1;
  font-size: 0.8rem;
  font-weight: 750;
}

.server-card-action {
  min-height: 32px;
  padding: 0 14px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 6px;
  background: #5865f2;
  color: #fff;
  font-size: 0.82rem;
  font-weight: 900;
  white-space: nowrap;
}

.server-card.is-uninstalled .server-card-action,
.server-card.is-local .server-card-action {
  background: #4b4d56;
}

.server-picker .dashboard-empty-state {
  grid-column: 1 / -1;
  border-color: #454750;
  background: #2f3138;
}

.button-ripple {
  position: absolute;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.42);
  pointer-events: none;
  transform: translate(-50%, -50%) scale(0);
  animation: dashboardRipple 0.55s ease-out forwards;
}

@keyframes dashboardRipple {
  to {
    opacity: 0;
    transform: translate(-50%, -50%) scale(14);
  }
}

.dashboard-topbar {
  position: sticky;
  top: 0;
  z-index: 60;
  min-height: 74px;
  display: grid;
  grid-template-columns: auto minmax(240px, 420px) auto;
  align-items: center;
  gap: 18px;
  padding: 14px 24px;
  border-bottom: 1px solid var(--line);
  background: rgba(7, 4, 17, 0.86);
  backdrop-filter: blur(18px);
}

.dashboard-server {
  min-width: 0;
  display: grid;
  grid-template-columns: auto 34px auto minmax(0, 1fr);
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border: 1px solid rgba(158, 110, 255, 0.26);
  border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.045);
}

.dashboard-server label {
  color: var(--muted);
  font-size: 0.82rem;
}

.dashboard-server span:not(.server-dot) {
  color: var(--muted);
  font-size: 0.82rem;
}

.dashboard-server strong {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.server-current-logo-shell,
.server-summary-logo-shell {
  width: 34px;
  height: 34px;
  padding: 2px;
  filter: drop-shadow(0 8px 16px rgba(139, 92, 246, 0.22));
}

.server-current-logo,
.server-current-logo-shell img {
  width: 100%;
  height: 100%;
  padding: 2px;
  object-fit: contain;
}

.server-summary {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

.server-summary-logo-shell {
  width: 30px;
  height: 30px;
}

.server-summary-logo-shell img {
  width: 100%;
  height: 100%;
  padding: 2px;
  object-fit: contain;
}

.dashboard-server select,
.dashboard-page input,
.dashboard-page textarea,
.dashboard-page select {
  min-width: 0;
  width: 100%;
  border: 1px solid rgba(158, 110, 255, 0.22);
  border-radius: var(--radius);
  outline: none;
  background: rgba(6, 3, 14, 0.74);
  color: var(--text);
}

.dashboard-server select {
  min-height: 38px;
  padding: 0 10px;
}

.server-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--green);
  box-shadow: 0 0 14px rgba(101, 245, 150, 0.7);
}

.dashboard-actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}

.compact {
  min-height: 38px;
  padding: 0 14px;
  font-size: 0.86rem;
}

.dashboard-shell {
  width: min(1480px, calc(100% - 32px));
  min-height: calc(100vh - 74px);
  margin: 0 auto;
  padding: 22px 0 42px;
  display: grid;
  grid-template-columns: 260px minmax(0, 1fr);
  gap: 20px;
}

.dashboard-sidebar {
  position: sticky;
  top: 96px;
  height: calc(100vh - 116px);
  min-height: 520px;
  padding: 16px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: rgba(11, 7, 24, 0.76);
  box-shadow: var(--shadow);
}

.sidebar-label {
  margin: 0 0 12px;
  color: var(--muted);
  font-size: 0.78rem;
  text-transform: uppercase;
}

.dash-nav {
  width: 100%;
  min-height: 42px;
  margin-bottom: 6px;
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr);
  align-items: center;
  gap: 10px;
  border-radius: var(--radius);
  background: transparent;
  color: var(--muted);
  text-align: left;
}

/* Le symbole, et lui seul. La regle visait TOUS les span de l'entree :
   la moitie des rubriques portent leur libelle dans un <span> pour le
   traduire, et ce libelle se retrouvait dans une boite de 28 px, en
   grille centree, coupee par le bouton. « Vie du serveur » n'a jamais
   pu s'afficher en entier, et ces rubriques-la n'avaient ni la meme
   taille de texte ni le meme alignement que les autres. */
.dash-nav > span[aria-hidden="true"] {
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  margin-left: 6px;
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.06);
  color: var(--soft);
  font-size: 0.72rem;
}

.dash-nav:hover,
.dash-nav.is-active {
  color: var(--text);
  background: rgba(139, 92, 246, 0.18);
}

.dash-nav.is-active > span[aria-hidden="true"] {
  background: linear-gradient(135deg, var(--purple), var(--cyan));
  color: #fff;
}

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

.dashboard-banner {
  min-height: 146px;
  margin-bottom: 18px;
  padding: 24px;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 20px;
  border: 1px solid rgba(158, 110, 255, 0.32);
  border-radius: var(--radius);
  background:
    linear-gradient(90deg, rgba(9, 5, 20, 0.62), rgba(9, 5, 20, 0.92)),
    url("assets/default_banner.svg") center / cover;
}

.dashboard-banner h1 {
  margin: 4px 0 8px;
  font-size: 2rem;
  letter-spacing: 0;
}

.dashboard-banner p:not(.eyebrow) {
  color: var(--soft);
}

.health-pill,
.state,
.embed-pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 30px;
  padding: 0 10px;
  border-radius: var(--radius);
  background: rgba(101, 245, 150, 0.12);
  color: #baffcf;
  white-space: nowrap;
}

.state.pending {
  background: rgba(255, 215, 0, 0.12);
  color: #ffeaa0;
}

.health-pill span {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--green);
}

.dash-panel {
  display: none;
}

.dash-panel.is-active {
  display: block;
}

.panel-title {
  margin-bottom: 16px;
  display: flex;
  align-items: end;
  justify-content: space-between;
  gap: 16px;
}

.panel-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 10px;
}

.panel-title h2 {
  margin-top: 4px;
  font-size: 1.42rem;
}

.metric-grid,
.dashboard-grid,
.toggle-grid {
  display: grid;
  gap: 14px;
}

.metric-grid {
  grid-template-columns: repeat(4, minmax(0, 1fr));
  margin-bottom: 14px;
}

.dashboard-grid.two {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.dashboard-grid.three {
  grid-template-columns: repeat(3, minmax(0, 1fr));
  margin-top: 14px;
}

.metric-card,
.tool-panel,
.channel-table,
.log-feed {
  border: 1px solid rgba(158, 110, 255, 0.24);
  border-radius: var(--radius);
  background: rgba(18, 12, 34, 0.72);
  box-shadow: 0 14px 40px rgba(8, 3, 20, 0.28);
}

.metric-card {
  min-height: 112px;
  padding: 18px;
  display: grid;
  align-content: space-between;
}

.metric-card span,
.metric-card small {
  color: var(--muted);
}

.metric-card strong {
  font-size: 1.62rem;
}

.tool-panel {
  padding: 18px;
}

.tool-panel h3 {
  margin-bottom: 14px;
  font-size: 1rem;
}

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

.quick-grid button,
.option-row button {
  position: relative;
  overflow: hidden;
  min-height: 40px;
  border: 1px solid rgba(158, 110, 255, 0.22);
  border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.055);
  color: var(--text);
  transition: transform 0.16s ease, border-color 0.16s ease, background 0.16s ease, box-shadow 0.16s ease;
}

.quick-grid button:hover,
.option-row button:hover {
  transform: translateY(-2px);
  border-color: rgba(205, 184, 255, 0.56);
  background: rgba(139, 92, 246, 0.16);
  box-shadow: 0 12px 28px rgba(139, 92, 246, 0.18);
}

.check-list {
  display: grid;
  gap: 10px;
  color: var(--soft);
  list-style: none;
}

.check-list li::before {
  content: "✓";
  margin-right: 8px;
  color: var(--green);
}

.field-help {
  display: block;
  margin-top: 6px;
  color: var(--muted);
  font-size: 0.78rem;
  line-height: 1.35;
}

.tournament-activation-card {
  display: grid;
  gap: 14px;
}

.tournament-state-line {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 14px;
}

.tournament-state-line p,
.tournament-flow p {
  color: var(--soft);
  line-height: 1.6;
}

.tournament-toggle {
  min-height: 112px;
}

.tournament-toggle.is-locked {
  cursor: not-allowed;
  opacity: 0.72;
}

.tournament-toggle.is-locked strong,
.tournament-toggle.is-locked small {
  color: var(--muted);
}

.tournament-api-note {
  color: var(--soft);
  line-height: 1.6;
}

.tournament-command-panel {
  margin-top: 14px;
}

.tournament-command-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px;
}

.tournament-command-card {
  min-height: 96px;
  padding: 14px;
  display: grid;
  align-content: start;
  gap: 8px;
  border: 1px solid rgba(158, 110, 255, 0.22);
  border-radius: var(--radius);
  background:
    linear-gradient(135deg, rgba(139, 92, 246, 0.13), rgba(101, 245, 150, 0.055)),
    rgba(255, 255, 255, 0.045);
  transition: opacity 0.18s ease, filter 0.18s ease, transform 0.18s ease, border-color 0.18s ease;
}

.tournament-command-card:not(.is-disabled):hover {
  transform: translateY(-2px);
  border-color: rgba(101, 245, 150, 0.42);
  box-shadow: 0 14px 34px rgba(101, 245, 150, 0.1);
}

.tournament-command-card.is-disabled {
  opacity: 0.42;
  filter: grayscale(0.8);
}

.tournament-command-card.spotlight {
  border-color: rgba(255, 215, 0, 0.3);
  background:
    linear-gradient(135deg, rgba(255, 215, 0, 0.12), rgba(139, 92, 246, 0.12)),
    rgba(255, 255, 255, 0.045);
}

.tournament-command-card strong {
  color: var(--text);
  font-size: 1rem;
}

.tournament-command-card span {
  color: var(--soft);
  line-height: 1.45;
}

.tournament-flow {
  margin-top: 14px;
}

.tournament-preview-grid {
  margin-top: 14px;
}

.ifc-data-list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
}

.ifc-data-list span {
  min-height: 38px;
  padding: 9px 10px;
  display: flex;
  align-items: center;
  border: 1px solid rgba(158, 110, 255, 0.24);
  border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.045);
  color: var(--soft);
  font-weight: 900;
}

.podium-preview {
  min-height: 180px;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  align-items: end;
  gap: 10px;
}

.podium-team {
  min-height: 118px;
  padding: 12px;
  display: grid;
  align-content: end;
  justify-items: center;
  gap: 8px;
  border: 1px solid rgba(158, 110, 255, 0.24);
  border-radius: var(--radius);
  background:
    linear-gradient(180deg, rgba(139, 92, 246, 0.18), rgba(255, 255, 255, 0.045));
}

.podium-team.first {
  min-height: 158px;
  border-color: rgba(255, 215, 0, 0.42);
}

.podium-team.second {
  min-height: 132px;
}

.podium-team.third {
  min-height: 110px;
}

.podium-team span {
  width: 46px;
  height: 46px;
  border-radius: 50%;
  background:
    radial-gradient(circle at 35% 30%, rgba(255,255,255,0.88), rgba(255,255,255,0.08) 42%, transparent 43%),
    linear-gradient(135deg, rgba(98, 230, 255, 0.74), rgba(139, 92, 246, 0.86));
  box-shadow: 0 0 24px rgba(139, 92, 246, 0.3);
}

.podium-team strong {
  font-size: 1.5rem;
}

.form-panel,
.mini-form {
  display: grid;
  gap: 14px;
}

.form-panel label,
.mini-form {
  display: grid;
  gap: 8px;
  color: var(--soft);
  font-size: 0.88rem;
}

.dashboard-page input,
.dashboard-page textarea,
.dashboard-page select {
  min-height: 42px;
  padding: 10px 12px;
}

.dashboard-page textarea {
  min-height: 118px;
  resize: vertical;
}

.form-row {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
}

.preview-panel {
  min-width: 0;
}

.preview-banner {
  width: 100%;
  max-height: 170px;
  margin-top: 12px;
  border-radius: var(--radius);
  object-fit: cover;
}

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

.ticket-publish-btn {
  border: 1px solid rgba(101, 245, 150, 0.5);
  background: linear-gradient(135deg, rgba(67, 181, 129, 0.94), rgba(88, 101, 242, 0.92));
  box-shadow:
    0 14px 34px rgba(67, 181, 129, 0.24),
    0 0 28px rgba(101, 245, 150, 0.18);
}

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

.option-row,
.channel-row {
  display: grid;
  align-items: center;
  gap: 10px;
}

.option-row {
  grid-template-columns: 44px 66px minmax(120px, 0.8fr) minmax(180px, 1.4fr) 110px;
}

.option-row span {
  color: var(--muted);
}

.emoji-input,
.emoji-input-wide {
  text-align: center;
  font-size: 1.08rem;
}

.emoji-input-wide {
  max-width: 96px;
}

.file-field {
  position: relative;
}

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

.file-control {
  min-height: 48px;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: 10px;
  padding: 8px;
  border: 1px solid rgba(158, 110, 255, 0.28);
  border-radius: var(--radius);
  background: rgba(6, 3, 14, 0.76);
  cursor: pointer;
  transition: border-color 0.18s ease, box-shadow 0.18s ease, transform 0.18s ease;
}

.file-control:hover {
  transform: translateY(-1px);
  border-color: rgba(205, 184, 255, 0.6);
  box-shadow: 0 12px 30px rgba(139, 92, 246, 0.16);
}

.file-button {
  min-height: 32px;
  padding: 0 12px;
  display: inline-flex;
  align-items: center;
  border-radius: 6px;
  background: linear-gradient(135deg, #5865f2, #a855f7);
  color: white;
  font-weight: 900;
  white-space: nowrap;
}

.file-name {
  overflow: hidden;
  color: var(--muted);
  font-weight: 800;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.social-info {
  margin-bottom: 14px;
}

.social-info strong {
  display: block;
  margin-bottom: 6px;
}

.social-info p {
  color: var(--soft);
  line-height: 1.6;
}

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

.social-card {
  padding: 18px;
  display: grid;
  gap: 14px;
  border: 1px solid rgba(158, 110, 255, 0.24);
  border-radius: var(--radius);
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.055), rgba(255, 255, 255, 0.018)),
    rgba(18, 12, 34, 0.72);
  box-shadow: 0 14px 40px rgba(8, 3, 20, 0.24);
}

.social-card-head {
  display: grid;
  grid-template-columns: 48px minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
}

.social-icon {
  width: 48px;
  height: 48px;
  display: grid;
  place-items: center;
  border: 1px solid rgba(158, 110, 255, 0.34);
  border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.065);
  font-size: 1.35rem;
  box-shadow: 0 0 24px rgba(139, 92, 246, 0.16);
}

.social-card h3 {
  margin: 0 0 4px;
}

.social-card p,
.social-card label {
  color: var(--soft);
}

.social-card label {
  display: grid;
  gap: 8px;
  font-size: 0.88rem;
}

.social-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: 10px;
}

.mini-toggle {
  display: inline-flex !important;
  grid-template-columns: none !important;
  align-items: center;
  gap: 10px;
  color: var(--text) !important;
  font-weight: 900;
}

.mini-toggle input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.mini-toggle span {
  width: 42px;
  height: 24px;
  position: relative;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.12);
}

.mini-toggle span::after {
  content: "";
  position: absolute;
  top: 4px;
  left: 4px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--muted);
  transition: transform 0.18s ease, background 0.18s ease;
}

.mini-toggle input:checked + span {
  background: rgba(101, 245, 150, 0.18);
}

.mini-toggle input:checked + span::after {
  transform: translateX(18px);
  background: var(--green);
}

.toggle-grid {
  grid-template-columns: repeat(5, minmax(150px, 1fr));
}

.toggle-line {
  min-height: 150px;
  padding: 16px;
  display: grid;
  align-content: start;
  gap: 10px;
  border: 1px solid rgba(158, 110, 255, 0.22);
  border-radius: var(--radius);
  background: rgba(18, 12, 34, 0.72);
}

.toggle-line input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.toggle-line span {
  width: 46px;
  height: 24px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.12);
  position: relative;
}

.toggle-line span::after {
  content: "";
  position: absolute;
  top: 4px;
  left: 4px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--muted);
  transition: transform 0.18s ease, background 0.18s ease;
}

.toggle-line input:checked + span {
  background: rgba(101, 245, 150, 0.18);
}

.toggle-line input:checked + span::after {
  transform: translateX(22px);
  background: var(--green);
}

.toggle-line small {
  color: var(--muted);
}

.toggle-line.danger input:checked + span::after {
  background: var(--danger);
}

.channel-table,
.log-feed {
  overflow: hidden;
}

.channel-row {
  grid-template-columns: 180px minmax(0, 1fr) 110px;
  padding: 12px 14px;
  border-bottom: 1px solid rgba(158, 110, 255, 0.16);
}

.channel-row:last-child {
  border-bottom: 0;
}

.state.active {
  color: #baffcf;
}

.state.inactive {
  background: rgba(255, 107, 145, 0.12);
  color: #ffc3d0;
}

.color-row {
  display: flex;
  gap: 10px;
}

.color-swatch {
  width: 36px;
  height: 36px;
  border: 2px solid transparent;
  border-radius: 50%;
  background: var(--swatch);
}

.color-swatch.is-selected {
  border-color: white;
  box-shadow: 0 0 0 4px rgba(255, 255, 255, 0.12);
}

.live-color-preview {
  border-left-color: var(--dashboard-accent, #5865F2);
}

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

.sanction-flow span {
  min-height: 44px;
  display: grid;
  place-items: center;
  border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.06);
  color: var(--soft);
  text-align: center;
}

.dashboard-empty-state {
  min-height: 76px;
  padding: 14px;
  display: grid;
  align-content: center;
  gap: 4px;
  border: 1px dashed rgba(205, 184, 255, 0.28);
  border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.035);
  color: var(--soft);
}

.dashboard-empty-state strong {
  color: var(--text);
}

.dashboard-empty-state span {
  color: var(--muted);
  line-height: 1.45;
}

.moderation-word-panel,
.moderation-sanction-panel {
  display: grid;
  align-content: start;
  gap: 14px;
}

.filtered-word-list {
  max-height: 280px;
  overflow: auto;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.filtered-word-chip {
  min-height: 34px;
  padding: 6px 10px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  border: 1px solid rgba(158, 110, 255, 0.22);
  border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.055);
}

.filtered-word-chip em {
  color: var(--muted);
  font-size: 0.72rem;
  font-style: normal;
}

.filtered-word-chip.is-custom {
  border-color: rgba(101, 245, 150, 0.32);
  background: rgba(101, 245, 150, 0.08);
}

.sanction-list {
  max-height: 360px;
  overflow: auto;
  display: grid;
  gap: 10px;
}

.sanction-row {
  min-width: 0;
  padding: 12px;
  display: grid;
  grid-template-columns: auto minmax(120px, 1fr) minmax(130px, auto);
  gap: 8px 12px;
  align-items: center;
  border: 1px solid rgba(158, 110, 255, 0.18);
  border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.045);
}

.sanction-row code {
  color: var(--cyan);
  white-space: nowrap;
}

.sanction-row small {
  grid-column: 1 / -1;
  color: var(--soft);
  line-height: 1.45;
}

.narrow {
  max-width: 520px;
}

.log-feed div {
  padding: 14px 16px;
  display: grid;
  grid-template-columns: 70px minmax(0, 1fr);
  gap: 12px;
  border-bottom: 1px solid rgba(158, 110, 255, 0.16);
}

.log-feed div:last-child {
  border-bottom: 0;
}

.log-feed span {
  color: var(--cyan);
}

.welcome-preview-panel,
.recurring-list-panel {
  overflow: hidden;
}

.welcome-discord-preview {
  display: grid;
  gap: 12px;
}

.welcome-discord-preview p {
  color: var(--soft);
  font-weight: 800;
}

.welcome-card {
  --welcome-title-color: #ffffff;
  min-height: 230px;
  padding: 28px;
  display: grid;
  place-items: center;
  gap: 12px;
  border-radius: var(--radius);
  text-align: center;
  background:
    linear-gradient(90deg, rgba(19, 15, 70, 0.58), rgba(42, 94, 255, 0.72)),
    url("assets/default_banner.svg") center / cover;
  box-shadow: inset 0 0 80px rgba(0, 0, 0, 0.24);
}

.welcome-avatar {
  width: 86px;
  height: 86px;
  border: 4px solid rgba(255, 255, 255, 0.92);
  border-radius: 50%;
  object-fit: cover;
  background: rgba(255, 255, 255, 0.12);
  box-shadow: 0 14px 34px rgba(0, 0, 0, 0.3);
}

.departure-preview {
  padding: 10px 12px;
  border: 1px solid rgba(158, 110, 255, 0.18);
  border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.045);
}

.welcome-card strong {
  display: block;
  color: var(--welcome-title-color);
  font-size: clamp(2rem, 5vw, 3.7rem);
  line-height: 0.9;
  text-shadow: 0 4px 14px rgba(0, 0, 0, 0.46);
}

.welcome-card small {
  color: #ffffff;
  font-size: 1.1rem;
  font-weight: 900;
  text-shadow: 0 3px 12px rgba(0, 0, 0, 0.46);
}

.departure-card {
  min-height: 180px;
  background:
    linear-gradient(90deg, rgba(70, 15, 32, 0.58), rgba(42, 94, 255, 0.62)),
    url("assets/default_banner.svg") center / cover;
}

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

.reaction-role-row {
  display: grid;
  grid-template-columns: 48px 68px minmax(0, 1fr) minmax(0, 1.25fr) auto;
  gap: 10px;
  align-items: center;
}

.reaction-role-row > span,
.option-row > span {
  color: var(--muted);
  font-weight: 900;
}

.reaction-role-row button {
  min-height: 40px;
  padding: 0 12px;
  border: 1px solid rgba(255, 88, 88, 0.28);
  border-radius: var(--radius);
  background: rgba(255, 88, 88, 0.12);
  color: #ffd7d7;
}

.reaction-chip-list {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.reaction-chip-list span {
  min-height: 32px;
  padding: 0 10px;
  display: inline-flex;
  align-items: center;
  border-radius: var(--radius);
  background: rgba(139, 92, 246, 0.26);
  color: var(--text);
  font-weight: 900;
}

.recurring-layout {
  display: grid;
  grid-template-columns: minmax(0, 1.6fr) minmax(320px, 0.8fr);
  gap: 14px;
}

.recurring-builder {
  display: grid;
  gap: 14px;
}

.segmented-control,
.day-pill-row,
.message-composer-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.segmented-control button,
.day-pill-row button,
.message-composer-tabs button {
  min-height: 38px;
  padding: 0 14px;
  border: 1px solid rgba(158, 110, 255, 0.22);
  border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.055);
  color: var(--soft);
  font-weight: 900;
}

.segmented-control button.is-active,
.day-pill-row button.is-active,
.message-composer-tabs button.is-active {
  border-color: rgba(205, 184, 255, 0.54);
  background: linear-gradient(135deg, rgba(124, 92, 255, 0.74), rgba(177, 92, 255, 0.64));
  color: #fff;
  box-shadow: 0 14px 34px rgba(139, 92, 246, 0.22);
}

.recurring-empty,
.recurring-item {
  padding: 14px;
  border: 1px dashed rgba(205, 184, 255, 0.3);
  border-radius: var(--radius);
  color: var(--muted);
  text-align: center;
}

.recurring-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  border-style: solid;
  color: var(--text);
  text-align: left;
  background: rgba(255, 255, 255, 0.05);
}

.recurring-item strong,
.recurring-item small {
  display: block;
}

.recurring-item small {
  margin-top: 4px;
  color: var(--muted);
}

.dashboard-toast {
  position: fixed;
  right: 22px;
  bottom: 22px;
  z-index: 90;
  padding: 12px 16px;
  border: 1px solid rgba(101, 245, 150, 0.38);
  border-radius: var(--radius);
  background: rgba(8, 20, 14, 0.92);
  color: #baffcf;
  opacity: 0;
  transform: translateY(14px);
  pointer-events: none;
  transition: opacity 0.2s ease, transform 0.2s ease;
}

.dashboard-toast.is-visible {
  opacity: 1;
  transform: translateY(0);
}

.dashboard-modal {
  position: fixed;
  inset: 0;
  z-index: 120;
  display: grid;
  place-items: center;
  padding: 20px;
  background: rgba(4, 2, 10, 0.72);
  backdrop-filter: blur(12px);
}

.dashboard-modal-card {
  width: min(100%, 520px);
  padding: 24px;
  border: 1px solid rgba(255, 215, 0, 0.34);
  border-radius: var(--radius);
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.07), rgba(255, 255, 255, 0.025)),
    rgba(17, 10, 32, 0.96);
  box-shadow:
    0 28px 80px rgba(0, 0, 0, 0.56),
    0 0 44px rgba(255, 215, 0, 0.14);
}

.dashboard-modal-card h2 {
  margin: 2px 0 10px;
  font-size: 1.55rem;
}

.dashboard-modal-card p:not(.eyebrow) {
  color: var(--soft);
  line-height: 1.6;
}

.dashboard-modal-actions {
  margin-top: 18px;
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

@media (max-width: 1120px) {
  .dashboard-topbar,
  .dashboard-shell,
  .admin-workspace,
  .recurring-layout {
    grid-template-columns: 1fr;
  }

  .dashboard-sidebar,
  .admin-sidebar-panel {
    position: relative;
    top: auto;
    height: auto;
    min-height: 0;
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 8px;
  }

  .sidebar-label {
    grid-column: 1 / -1;
  }

  .dash-nav {
    margin: 0;
  }

  .metric-grid,
  .toggle-grid,
  .server-grid,
  .social-grid,
  .tournament-command-grid,
  .wiki-card-grid,
  .wiki-plan-grid,
  .command-doc-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .server-select-topbar {
    flex-wrap: wrap;
    padding: 12px 16px;
  }

  .server-select-nav {
    order: 3;
    width: 100%;
    overflow-x: auto;
  }

  .server-picker .server-grid {
    grid-template-columns: repeat(2, minmax(240px, 1fr));
  }
}

@media (max-width: 760px) {
  .dashboard-topbar {
    position: relative;
    top: auto;
    z-index: 20;
    padding: 12px;
  }

  .dashboard-actions,
  .hero-actions {
    flex-wrap: wrap;
  }

  .dashboard-shell {
    width: min(100% - 20px, 1480px);
    padding-top: 12px;
  }

  .server-picker-card {
    width: min(100% - 24px, 1320px);
    padding: 28px 0;
  }

  .server-select-toolbar {
    grid-template-columns: 1fr;
  }

  .dashboard-sidebar,
  .admin-sidebar-panel {
    grid-template-columns: 1fr;
  }

  .dashboard-banner,
  .panel-title {
    align-items: flex-start;
    flex-direction: column;
  }

  .panel-actions {
    justify-content: flex-start;
  }

  .dashboard-grid.two,
  .dashboard-grid.three,
  .metric-grid,
  .toggle-grid,
  .server-grid,
  .social-grid,
  .tournament-command-grid,
  .wiki-card-grid,
  .wiki-plan-grid,
  .command-doc-grid,
  .admin-action-row,
  .admin-action-row.split,
  .server-log-feed div,
  .form-row,
  .sanction-flow {
    grid-template-columns: 1fr;
  }

  .tournament-state-line {
    flex-direction: column;
  }

  .option-row,
  .reaction-role-row,
  .channel-row,
  .sanction-row {
    grid-template-columns: 1fr;
  }

  .recurring-item,
  .admin-list div,
  .blacklist-list div {
    align-items: stretch;
    flex-direction: column;
  }

  .server-card,
  .file-control {
    grid-template-columns: 1fr;
  }

  .server-picker .server-grid {
    grid-template-columns: 1fr;
  }

  .server-card-body {
    grid-template-columns: 56px minmax(0, 1fr);
  }

  .server-card-action {
    grid-column: 1 / -1;
    width: 100%;
  }

  .file-button {
    justify-content: center;
  }
}

/* ═══════════════════════════════════════════════════════════════════════
   MODBOT — COUCHE DESIGN v2
   Nouveaux composants (sécurité, logs, sauvegardes, connexion),
   accessibilité, animations et corrections responsive.
   Placée en fin de feuille : elle complète et surcharge les règles
   ci-dessus sans les réécrire.
   ═══════════════════════════════════════════════════════════════════════ */

:root {
  --ok: #65f596;
  --warn: #ffc861;
  --err: #ff6b91;
  --ring: 0 0 0 3px rgba(139, 92, 246, 0.45);
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  --dur: 220ms;
  --surface-1: rgba(255, 255, 255, 0.04);
  --surface-2: rgba(255, 255, 255, 0.07);
}

/* ── Accessibilité : focus visible et respect des préférences système ── */

:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: none;
  box-shadow: var(--ring);
  border-radius: var(--radius);
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* Barre de défilement discrète et cohérente avec le thème */
* {
  scrollbar-width: thin;
  scrollbar-color: rgba(139, 92, 246, 0.5) transparent;
}
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
  border: 3px solid transparent;
  border-radius: 10px;
  background: rgba(139, 92, 246, 0.45);
  background-clip: content-box;
}
*::-webkit-scrollbar-thumb:hover {
  background: rgba(139, 92, 246, 0.75);
  background-clip: content-box;
}

/* Transitions homogènes sur les éléments interactifs */
.primary-btn,
.secondary-btn,
.dash-nav,
.tool-panel,
.server-card,
.price-card,
.log-filter,
.backup-card {
  transition: transform var(--dur) var(--ease),
              box-shadow var(--dur) var(--ease),
              border-color var(--dur) var(--ease),
              background-color var(--dur) var(--ease),
              color var(--dur) var(--ease);
}

.primary-btn:active,
.secondary-btn:active { transform: translateY(1px) scale(0.99); }

/* ── Écran de connexion ────────────────────────────────────────────── */

.discord-login-btn svg {
  width: 22px;
  height: 22px;
  flex: 0 0 auto;
}

.auth-status {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  width: 100%;
  margin-top: 14px;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface-1);
  color: var(--soft);
  font-size: 0.86rem;
  font-weight: 600;
  line-height: 1.5;
  text-align: left;
}

.auth-status[data-level="ok"]    { border-color: rgba(101, 245, 150, 0.45); background: rgba(101, 245, 150, 0.08); }
.auth-status[data-level="warn"]  { border-color: rgba(255, 200, 97, 0.45);  background: rgba(255, 200, 97, 0.08); }
.auth-status[data-level="error"] { border-color: rgba(255, 107, 145, 0.45); background: rgba(255, 107, 145, 0.08); }

.auth-status-dot {
  flex: 0 0 auto;
  width: 9px;
  height: 9px;
  margin-top: 6px;
  border-radius: 50%;
  background: var(--muted);
}
.auth-status-dot.is-ok      { background: var(--ok);   box-shadow: 0 0 0 4px rgba(101, 245, 150, 0.18); }
.auth-status-dot.is-warn    { background: var(--warn); box-shadow: 0 0 0 4px rgba(255, 200, 97, 0.18); }
.auth-status-dot.is-error   { background: var(--err);  box-shadow: 0 0 0 4px rgba(255, 107, 145, 0.18); }
.auth-status-dot.is-pending { background: var(--cyan); animation: mbPulse 1.1s ease-in-out infinite; }

@keyframes mbPulse {
  0%, 100% { opacity: 1;    transform: scale(1); }
  50%      { opacity: 0.45; transform: scale(0.8); }
}

.auth-advanced {
  width: 100%;
  margin-top: 12px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface-1);
  text-align: left;
}

.auth-advanced > summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 12px 14px;
  cursor: pointer;
  color: var(--soft);
  font-size: 0.86rem;
  list-style: none;
}
.auth-advanced > summary::-webkit-details-marker { display: none; }
.auth-advanced > summary:hover { color: var(--text); }

.auth-advanced-badge {
  padding: 3px 9px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.08);
  color: var(--muted);
  font-size: 0.74rem;
  white-space: nowrap;
}
.auth-advanced-badge[data-level="ok"]    { background: rgba(101, 245, 150, 0.16); color: #baffcf; }
.auth-advanced-badge[data-level="warn"]  { background: rgba(255, 200, 97, 0.16);  color: #ffeaa0; }
.auth-advanced-badge[data-level="error"] { background: rgba(255, 107, 145, 0.16); color: #ffc2d2; }

.auth-advanced-body {
  display: grid;
  gap: 12px;
  padding: 0 14px 14px;
  color: var(--muted);
  font-size: 0.84rem;
  line-height: 1.55;
}

.auth-field { display: grid; gap: 6px; color: var(--soft); font-size: 0.84rem; }
.auth-field input {
  width: 100%;
  min-height: 42px;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: rgba(0, 0, 0, 0.28);
  color: var(--text);
}
.auth-advanced-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.auth-hint { font-size: 0.78rem; color: var(--muted); }
.auth-hint code,
.auth-advanced-body code {
  padding: 1px 5px;
  border-radius: 4px;
  background: rgba(255, 255, 255, 0.08);
  font-size: 0.92em;
}

/* ── Tarifs : offre unique ─────────────────────────────────────────── */

.pricing-solo {
  display: flex;
  justify-content: center;
}

.price-card.is-solo {
  max-width: 460px;
  width: 100%;
  display: grid;
  gap: 18px;
  align-content: start;
}

.price-card.is-solo .price {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 10px;
}
.price-card.is-solo .price-amount {
  font-size: clamp(2.4rem, 6vw, 3.2rem);
  font-weight: 900;
  line-height: 1;
  background: linear-gradient(120deg, var(--text), var(--purple-2));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.price-card.is-solo .price-period { color: var(--muted); font-size: 1rem; }
.price-note,
.price-support { color: var(--muted); font-size: 0.84rem; }
.price-support { text-align: center; }

.price-features { display: grid; gap: 10px; }

/* ── En-têtes de panneau ───────────────────────────────────────────── */

.panel-title-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

/* ── Blocs de sécurité ─────────────────────────────────────────────── */

.security-block { margin-top: 16px; }

.switch-inline {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--surface-1);
  color: var(--soft);
  font-size: 0.84rem;
  cursor: pointer;
}
.switch-inline input { accent-color: var(--purple); width: 16px; height: 16px; }

.toggle-line.compact {
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface-1);
}

.alert-panel {
  display: grid;
  gap: 8px;
  margin-bottom: 16px;
  padding: 14px 16px;
  border: 1px solid rgba(255, 200, 97, 0.5);
  border-left-width: 4px;
  border-radius: var(--radius);
  background: rgba(255, 200, 97, 0.08);
  color: #ffeaa0;
  font-size: 0.88rem;
  line-height: 1.55;
}
.alert-panel ul { margin: 0; padding-left: 20px; display: grid; gap: 4px; }

.info-list {
  margin: 0;
  padding-left: 20px;
  display: grid;
  gap: 8px;
  color: var(--muted);
  font-size: 0.88rem;
  line-height: 1.55;
}
.info-list strong { color: var(--soft); }

/* ── Échelle de sanctions ──────────────────────────────────────────── */

.sanction-ladder { display: grid; gap: 10px; margin: 12px 0 16px; }

.sanction-step {
  display: grid;
  grid-template-columns: 40px repeat(3, minmax(0, 1fr));
  align-items: end;
  gap: 12px;
  padding: 12px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface-1);
}

.sanction-rank {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--purple), var(--cyan));
  color: #fff;
  font-size: 0.82rem;
  font-weight: 800;
}
.sanction-step input:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

/* ── Journal / logs ────────────────────────────────────────────────── */

.log-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 16px;
}

.log-filter {
  padding: 8px 14px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--surface-1);
  color: var(--muted);
  font-size: 0.84rem;
  cursor: pointer;
}
.log-filter:hover { color: var(--text); border-color: var(--line-strong); }
.log-filter.is-active {
  background: linear-gradient(135deg, rgba(139, 92, 246, 0.35), rgba(98, 230, 255, 0.22));
  border-color: var(--line-strong);
  color: var(--text);
}

.log-toggle-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(220px, 100%), 1fr));
  gap: 10px;
}

.log-feed { display: grid; gap: 10px; }

.log-entry {
  display: grid;
  gap: 8px;
  padding: 14px 16px;
  border: 1px solid var(--line);
  border-left: 3px solid var(--muted);
  border-radius: var(--radius);
  background: var(--surface-1);
  animation: mbFadeIn var(--dur) var(--ease) both;
}
.log-entry[data-severity="success"]  { border-left-color: var(--ok); }
.log-entry[data-severity="warning"]  { border-left-color: var(--warn); }
.log-entry[data-severity="danger"]   { border-left-color: var(--err); }
.log-entry[data-severity="critical"] { border-left-color: #ff3860; background: rgba(255, 56, 96, 0.07); }

.log-entry header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}
.log-entry header strong { color: var(--text); font-size: 0.95rem; }
.log-entry header time { margin-left: auto; color: var(--muted); font-size: 0.78rem; }
.log-entry p { margin: 0; color: var(--soft); font-size: 0.88rem; line-height: 1.55; }
.log-entry footer {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  color: var(--muted);
  font-size: 0.8rem;
}

.log-chip {
  padding: 2px 9px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.07);
  color: var(--muted);
  font-size: 0.75rem;
  white-space: nowrap;
}

.log-empty {
  padding: 28px 16px;
  border: 1px dashed var(--line);
  border-radius: var(--radius);
  color: var(--muted);
  text-align: center;
}

@keyframes mbFadeIn {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}

/* ── Sauvegardes ───────────────────────────────────────────────────── */

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

.backup-card {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 16px;
  padding: 14px 16px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface-1);
}
.backup-card:hover { border-color: var(--line-strong); background: var(--surface-2); }

.backup-main { display: grid; gap: 3px; min-width: 0; }
.backup-main strong {
  color: var(--text);
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 0.9rem;
}
.backup-main small { color: var(--muted); font-size: 0.8rem; }
.backup-main em { color: var(--soft); font-size: 0.82rem; font-style: normal; }

.backup-counts {
  display: flex;
  gap: 12px;
  color: var(--muted);
  font-size: 0.84rem;
  white-space: nowrap;
}
.backup-actions { display: flex; gap: 8px; }
.secondary-btn.danger { border-color: rgba(255, 107, 145, 0.45); color: #ffc2d2; }
.secondary-btn.danger:hover { background: rgba(255, 107, 145, 0.12); }

.backup-empty {
  padding: 28px 16px;
  border: 1px dashed var(--line);
  border-radius: var(--radius);
  color: var(--muted);
  text-align: center;
}

.state[data-level="ok"]   { background: rgba(101, 245, 150, 0.14); color: #baffcf; }
.state[data-level="idle"] { background: rgba(255, 255, 255, 0.07); color: var(--muted); }

/* ── Navigation latérale : emoji au lieu du numéro ─────────────────── */

.dash-nav > span[aria-hidden="true"] {
  font-size: 0.95rem;
  background: rgba(255, 255, 255, 0.05);
}
.dash-nav.is-active > span[aria-hidden="true"] {
  background: linear-gradient(135deg, var(--purple), var(--cyan));
}
.sidebar-label:not(:first-child) { margin-top: 18px; }

.dashboard-sidebar { overflow-y: auto; }

/* ── Repli des logos serveur (initiales) ───────────────────────────── */

.server-logo-shell.is-fallback img { display: none; }
.server-logo-shell.is-fallback::after {
  content: attr(data-initials);
  display: grid;
  place-items: center;
  width: 100%;
  height: 100%;
  border-radius: inherit;
  background: linear-gradient(135deg, var(--purple), var(--cyan));
  color: #fff;
  font-size: 0.82rem;
  font-weight: 800;
  letter-spacing: 0.02em;
}

/* ═══════════════════════════════════════════════════════════════════
   RESPONSIVE — corrections tablette et mobile
   ═══════════════════════════════════════════════════════════════════ */

@media (max-width: 1120px) {
  .sanction-step { grid-template-columns: 32px repeat(2, minmax(0, 1fr)); }
  .sanction-step .sanction-rank { grid-row: span 2; }
  .backup-card { grid-template-columns: minmax(0, 1fr) auto; }
  .backup-counts { grid-column: 1 / -1; }
}

@media (max-width: 860px) {
  .panel-title {
    flex-direction: column;
    align-items: flex-start;
  }
  .panel-title-actions { width: 100%; }
  .panel-title-actions > * { flex: 1 1 auto; }

  .table-head {
    flex-direction: column;
    align-items: flex-start;
  }

  .log-entry header time { margin-left: 0; width: 100%; }
}

/* ── Bouton d'ouverture de la navigation dashboard ────────────────── */
/* Masqué par défaut : au-dessus de 760 px la barre latérale est déjà
   entièrement visible, un bouton n'y ajouterait rien. La règle qui
   l'affiche vit dans la media query, avec le reste du menu déroulant. */
.sidebar-toggle {
  display: none;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: 48px;
  margin-bottom: 8px;
  padding: 0 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: rgba(11, 7, 24, 0.76);
  color: var(--text);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.sidebar-toggle-burger {
  font-size: 1.05rem;
  line-height: 1;
}

.sidebar-toggle-label {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
  flex: 1;
}

.sidebar-toggle-label small {
  color: var(--muted);
  font-size: 0.68rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.sidebar-toggle-label strong {
  overflow: hidden;
  font-size: 0.94rem;
  font-weight: 600;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.sidebar-toggle-chevron {
  width: 12px;
  flex: 0 0 auto;
  transition: transform 0.2s ease;
}

.sidebar-toggle[aria-expanded="true"] .sidebar-toggle-chevron {
  transform: rotate(180deg);
}

@media (max-width: 760px) {
  /* La barre latérale devient un menu déroulant.
     Avant : un ruban horizontal défilable. Treize entrées y tenaient sur
     près de trois écrans de large, les intitulés de groupe étaient masqués,
     et rien n'annonçait qu'il fallait faire défiler — le menu passait
     simplement pour absent. */
  .sidebar-toggle { display: flex; }

  .dashboard-sidebar {
    display: none;
    position: static;      /* le sticky n'a plus de sens hors colonne */
    height: auto;
    min-height: 0;
    max-height: min(68vh, 560px);
    overflow-x: hidden;
    overflow-y: auto;
    padding: 12px;
    margin-bottom: 4px;
  }
  .dashboard-sidebar.is-open { display: block; }

  /* Les intitulés de groupe reviennent : c'est ce qui rend une liste de
     treize entrées lisible d'un coup d'œil. */
  .dashboard-sidebar .sidebar-label { display: block; }
  .dashboard-sidebar .sidebar-label:first-child { margin-top: 0; }

  .dash-nav {
    width: 100%;
    margin: 0 0 2px;
    padding: 0 12px;
    grid-template-columns: 28px minmax(0, 1fr);
    white-space: normal;
  }

  .sanction-step {
    grid-template-columns: 1fr;
    gap: 10px;
  }
  .sanction-step .sanction-rank { grid-row: auto; }

  .backup-card {
    grid-template-columns: 1fr;
    align-items: stretch;
  }
  .backup-actions > * { flex: 1; }

  .log-filters {
    flex-wrap: nowrap;
    overflow-x: auto;
    padding-bottom: 6px;
    -webkit-overflow-scrolling: touch;
  }
  .log-filter { flex: 0 0 auto; }

  .log-toggle-grid { grid-template-columns: 1fr; }

  .auth-advanced-actions > * { flex: 1 1 100%; }

  .price-card.is-solo { max-width: 100%; }

  /* Aucun débordement horizontal du document sur mobile */
  .dashboard-content,
  .dash-panel,
  .tool-panel { min-width: 0; }
}

@media (max-width: 480px) {
  .log-entry { padding: 12px; }
  .log-entry header strong { font-size: 0.88rem; }
}

/* Les contenus larges défilent dans leur propre conteneur,
   jamais en faisant déborder la page. */
.tool-panel table,
.log-feed,
.backup-list { max-width: 100%; }

/* ── Correctif : conteneur des interrupteurs ─────────────────────────
   .toggle-line input est en position:absolute ; sans ancetre positionne
   il se cale sur le viewport et s etire sur toute la largeur, ce qui
   creait un debordement horizontal fantome (masque par overflow-x:hidden).
   ------------------------------------------------------------------ */
.toggle-line {
  position: relative;
}

/* Variante compacte : une ligne interrupteur + libelle, sans hauteur imposee */
.toggle-line.compact {
  min-height: 0;
  grid-template-columns: auto minmax(0, 1fr);
  grid-template-areas:
    "switch title"
    "switch desc";
  align-items: center;
  gap: 4px 12px;
}
.toggle-line.compact > span   { grid-area: switch; align-self: center; }
.toggle-line.compact > strong { grid-area: title; }
.toggle-line.compact > small  { grid-area: desc; }
.toggle-line.compact:not(:has(small)) {
  grid-template-areas: "switch title";
}

/* Les badges d etat peuvent contenir un texte long : sur petit ecran ils
   passent a la ligne au lieu de deborder (.state est en nowrap par defaut). */
@media (max-width: 860px) {
  .state,
  .embed-pill {
    max-width: 100%;
    height: auto;
    padding: 6px 10px;
    white-space: normal;
    line-height: 1.4;
  }
}

/* Meme cause que .toggle-line : les cases masquees en position:absolute
   doivent etre contenues par leur label, sinon elles se calent sur le
   viewport et debordent. On couvre tous les interrupteurs personnalises. */
.mini-toggle,
.switch-inline,
label:has(> input[type="checkbox"] + span) {
  position: relative;
}

/* ═══════════════════════════════════════════════════════════════════════
   MODBOT — THÈME PROFESSIONNEL
   Refonte visuelle complète : palette sobre, typographie maîtrisée,
   surfaces nettes, suppression des effets décoratifs.
   Placée en dernier : redéfinit les tokens (donc tout ce qui les utilise)
   puis reprend les composants structurants.
   ═══════════════════════════════════════════════════════════════════════ */

:root {
  /* Fonds — gris-bleu neutre, pas de violet saturé */
  --bg: #0a0c11;
  --bg-soft: #10131a;
  --panel: #141821;
  --panel-strong: #1a1f2a;

  /* Bordures — fines et discrètes */
  --line: rgba(255, 255, 255, 0.08);
  --line-strong: rgba(255, 255, 255, 0.16);

  /* Texte — hiérarchie en 3 niveaux */
  --text: #e8ecf4;
  --soft: #c3cbd9;
  --muted: #8b95a7;

  /* Accent — blurple Discord, cohérent avec le produit */
  --accent: #5865f2;
  --accent-hover: #4854e0;
  --accent-soft: rgba(88, 101, 242, 0.13);
  --accent-line: rgba(88, 101, 242, 0.38);

  /* Les anciens noms restent définis : tout l'existant suit la nouvelle palette */
  --purple: #5865f2;
  --purple-2: #7c86ff;
  --cyan: #4aa8ff;
  --green: #3ba55d;
  --danger: #ed4245;

  /* États */
  --ok: #3ba55d;
  --warn: #e8a33d;
  --err: #ed4245;

  /* Élévation — ombres réelles, pas de halos colorés */
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.32);
  --shadow: 0 4px 16px rgba(0, 0, 0, 0.38);
  --shadow-lg: 0 16px 48px rgba(0, 0, 0, 0.46);

  --radius: 10px;
  --radius-lg: 16px;
  --ring: 0 0 0 3px rgba(88, 101, 242, 0.4);
}

/* ── Fond : uni et calme ──────────────────────────────────────────── */

body {
  background: var(--bg);
  font-weight: 400;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* Suppression des décorations d'arrière-plan : elles nuisaient à la
   lisibilité et donnaient un rendu « template » peu crédible. */
.starfield,
.page-glow,
.animated-bg,
body::before {
  display: none !important;
}

/* Un dégradé unique et sobre remplace les halos animés */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(900px 500px at 50% -10%, rgba(88, 101, 242, 0.10), transparent 70%),
    linear-gradient(180deg, #0a0c11 0%, #0c0f15 100%);
}

/* ── Typographie ──────────────────────────────────────────────────── */

h1, h2, h3, h4 {
  color: var(--text);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.2;
}

h1 { font-size: clamp(2rem, 4.5vw, 3.25rem); }
h2 { font-size: clamp(1.5rem, 3vw, 2.1rem); }
h3 { font-size: 1.05rem; font-weight: 650; letter-spacing: -0.01em; }

p { color: var(--soft); }

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
  color: var(--muted);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* Le pictogramme d'une rubrique accompagne le mot, il ne le remplace
   pas : il reste discret et ne grossit jamais avec la casse du texte. */
.eyebrow .ui-icon {
  flex: none;
  width: 15px;
  height: 15px;
  color: var(--purple-2);
}

.section-heading { max-width: 720px; margin-bottom: 40px; }
.section-heading h2 { margin-bottom: 12px; }
.section-heading p { font-size: 1.02rem; color: var(--muted); }

/* ── Boutons ──────────────────────────────────────────────────────── */

.primary-btn,
.secondary-btn,
.nav-cta,
.nav-action-btn {
  min-height: 42px;
  padding: 0 18px;
  border-radius: var(--radius);
  font-size: 0.92rem;
  font-weight: 600;
  letter-spacing: 0;
  transition: background-color 160ms ease, border-color 160ms ease,
              color 160ms ease, box-shadow 160ms ease;
}

.primary-btn {
  background: var(--accent);
  border: 1px solid var(--accent);
  color: #fff;
  box-shadow: var(--shadow-sm);
}
.primary-btn:hover {
  background: var(--accent-hover);
  border-color: var(--accent-hover);
  transform: none;
  box-shadow: var(--shadow);
}

.secondary-btn,
.nav-action-btn {
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--line);
  color: var(--soft);
  box-shadow: none;
}
.secondary-btn:hover,
.nav-action-btn:hover {
  background: rgba(255, 255, 255, 0.08);
  border-color: var(--line-strong);
  color: var(--text);
  transform: none;
}

.primary-btn.compact,
.secondary-btn.compact {
  min-height: 36px;
  padding: 0 14px;
  font-size: 0.85rem;
}

/* Les effets de brillance décoratifs sont neutralisés */
.primary-btn::before,
.primary-btn::after,
.secondary-btn::before,
.secondary-btn::after { display: none !important; }

/* ── En-tête ──────────────────────────────────────────────────────── */

.site-header {
  top: 0;
  padding: 0;
  animation: none;
  border-bottom: 1px solid var(--line);
  background: rgba(10, 12, 17, 0.85);
  backdrop-filter: blur(14px);
}

.navbar {
  width: min(1240px, 100%);
  min-height: 62px;
  padding: 10px 22px;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  backdrop-filter: none;
}

.brand { font-weight: 650; letter-spacing: -0.01em; }
.brand-mark {
  width: 30px;
  height: 30px;
  border-radius: 8px;
  overflow: hidden;
}

.nav-links a {
  color: var(--soft);
  font-size: 0.92rem;
  transition: color 150ms ease;
}
.nav-links a:hover { color: var(--text); }

/*
 * Le bouton d'appel principal garde son texte blanc.
 *
 * `.nav-links a` (specificite 0-1-1) l'emportait sur `.nav-cta` (0-1-0) et
 * lui imposait le gris des liens : le libelle tombait a 1,5:1 de contraste
 * sur le violet sature, soit trois fois moins que le minimum lisible. Le
 * defaut valait pour l'ordinateur comme pour le tiroir mobile.
 */
.nav-links a.nav-cta { color: #fff; }

/* ── Section héro ─────────────────────────────────────────────────── */

.hero {
  min-height: 0;
  padding: 88px 0 64px;
  gap: 44px;
}
.hero h1 { margin-bottom: 16px; }
.hero-lead {
  max-width: 620px;
  font-size: 1.08rem;
  color: var(--muted);
}
.hero-actions { gap: 10px; margin-top: 28px; }

/* ── Surfaces ─────────────────────────────────────────────────────── */

.tool-panel,
.price-card,
.server-card,
.auth-card,
.dashboard-sidebar,
.admin-panel,
.hero-panel,
.log-entry,
.backup-card,
.feature-card,
.wiki-card {
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--panel);
  box-shadow: var(--shadow-sm);
}

.tool-panel { padding: 20px; }
.tool-panel h3 { margin-bottom: 6px; }

.tool-panel:hover,
.feature-card:hover,
.wiki-card:hover {
  border-color: var(--line-strong);
  transform: none;
}

/* ── Formulaires ──────────────────────────────────────────────────── */

input,
textarea,
select {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: rgba(0, 0, 0, 0.24);
  color: var(--text);
  font-size: 0.92rem;
  font-weight: 400;
  transition: border-color 150ms ease, box-shadow 150ms ease;
}
input::placeholder,
textarea::placeholder { color: #6b7688; }

input:focus,
textarea:focus,
select:focus {
  outline: none;
  border-color: var(--accent-line);
  box-shadow: var(--ring);
}

label,
.mini-form,
.form-panel label {
  color: var(--muted);
  font-size: 0.85rem;
  font-weight: 500;
}

.field-help {
  color: var(--muted);
  font-size: 0.82rem;
  font-weight: 400;
  line-height: 1.55;
}

/* ── Tarifs ───────────────────────────────────────────────────────── */

.pricing-duo {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr));
  gap: 20px;
  max-width: 880px;
  margin: 0 auto;
  align-items: start;
}

.price-card {
  padding: 28px;
  display: grid;
  gap: 18px;
  align-content: start;
}

.price-card.is-highlight {
  border-color: var(--accent-line);
  background: linear-gradient(180deg, rgba(88, 101, 242, 0.07), transparent 220px), var(--panel);
  box-shadow: var(--shadow);
}

.price-card::after,
.price-card::before { display: none !important; }

.premium-ribbon {
  position: static;
  justify-self: start;
  width: auto;
  padding: 4px 11px;
  transform: none;
  border-radius: 999px;
  background: var(--accent-soft);
  border: 1px solid var(--accent-line);
  color: #b6bdff;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.price-head h3 { font-size: 1.25rem; font-weight: 700; margin-bottom: 6px; }
.price-head p { color: var(--muted); font-size: 0.92rem; }

.price {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px;
  padding-bottom: 4px;
}
.price-amount {
  font-size: 2.5rem;
  font-weight: 750;
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--text);
  background: none;
  -webkit-text-fill-color: currentColor;
}
.price-period { color: var(--muted); font-size: 0.95rem; }
.price-note { color: var(--muted); font-size: 0.82rem; margin-top: -8px; }

.price-features { display: grid; gap: 11px; padding: 0; margin: 0; list-style: none; }
.price-card li {
  position: relative;
  padding-left: 26px;
  color: var(--soft);
  font-size: 0.91rem;
  font-weight: 400;
}
.price-card li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.42em;
  width: 15px;
  height: 15px;
  border-radius: 50%;
  background: var(--accent-soft) center / 9px no-repeat
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath fill='%237c86ff' d='M4.6 9.2 1.4 6l1-1 2.2 2.2L9.6 2.2l1 1z'/%3E%3C/svg%3E");
}
.price-card li.is-inherited { color: var(--muted); font-style: italic; }
.price-support { color: var(--muted); font-size: 0.8rem; text-align: center; margin-top: -4px; }

/* ── Écran de connexion ───────────────────────────────────────────── */

.dashboard-auth {
  display: grid;
  place-items: center;
  min-height: 100vh;
  padding: 32px 20px;
}

.auth-card {
  width: min(460px, 100%);
  padding: 36px 32px;
  display: grid;
  justify-items: center;
  gap: 6px;
  text-align: center;
  box-shadow: var(--shadow-lg);
}
.auth-logo { width: 56px; height: 56px; margin-bottom: 4px; }
.auth-card h1 { font-size: 1.55rem; margin-bottom: 6px; }
.auth-card > p { color: var(--muted); font-size: 0.92rem; }

.discord-login-btn {
  width: 100%;
  min-height: 46px;
  margin-top: 20px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  border: 0;
  border-radius: var(--radius);
  background: var(--accent);
  color: #fff;
  font-size: 0.95rem;
  font-weight: 600;
  cursor: pointer;
  transition: background-color 160ms ease;
}
.discord-login-btn:hover { background: var(--accent-hover); transform: none; }

.oauth-note { color: var(--muted); font-size: 0.8rem; margin-top: 12px; }
.auth-return {
  margin-top: 18px;
  color: var(--muted);
  font-size: 0.86rem;
  transition: color 150ms ease;
}
.auth-return:hover { color: var(--text); }

/* ── Dashboard ────────────────────────────────────────────────────── */

.dashboard-topbar {
  border-bottom: 1px solid var(--line);
  background: rgba(10, 12, 17, 0.9);
  backdrop-filter: blur(14px);
  box-shadow: none;
}

.dashboard-sidebar {
  padding: 14px;
  border-radius: var(--radius-lg);
}

.sidebar-label {
  margin: 0 0 8px;
  padding-left: 10px;
  color: var(--muted);
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.08em;
}

.dash-nav {
  min-height: 38px;
  margin-bottom: 2px;
  padding-right: 12px;
  grid-template-columns: 30px minmax(0, 1fr);
  gap: 8px;
  color: var(--muted);
  font-size: 0.9rem;
  font-weight: 500;
  border-radius: 8px;
}
.dash-nav > span[aria-hidden="true"] {
  width: 22px;
  height: 22px;
  margin-left: 8px;
  background: none;
  font-size: 0.95rem;
}
.dash-nav:hover { background: rgba(255, 255, 255, 0.05); color: var(--soft); }
.dash-nav.is-active {
  background: var(--accent-soft);
  color: var(--text);
  /* Pas de gras : la barre a gauche, le fond et la couleur du symbole
     designent deja la rubrique ouverte trois fois. Le gras, lui,
     elargissait le mot et faisait sauter la liste d'une rubrique a
     l'autre. */
  box-shadow: inset 2px 0 0 var(--accent);
}
.dash-nav.is-active > span[aria-hidden="true"] { background: none; }

.dashboard-banner {
  padding: 22px 24px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: linear-gradient(180deg, rgba(88, 101, 242, 0.08), transparent), var(--panel);
  box-shadow: none;
}
.dashboard-banner h1 { font-size: 1.5rem; margin-bottom: 8px; }

.panel-title { margin-bottom: 20px; }
.panel-title h2 { font-size: 1.3rem; }

.health-pill,
.state,
.embed-pill {
  min-height: 28px;
  border-radius: 999px;
  font-size: 0.8rem;
  font-weight: 500;
}

/* ── Cartes serveur ───────────────────────────────────────────────── */

.server-card {
  padding: 0;
  overflow: hidden;
  text-align: left;
}
.server-card:hover {
  border-color: var(--accent-line);
  transform: translateY(-2px);
  box-shadow: var(--shadow);
}
.server-card-body { padding: 16px; }
.server-logo-shell {
  border-radius: 12px;
  overflow: hidden;
  background: var(--panel-strong);
}

/* ── Journal ──────────────────────────────────────────────────────── */

.log-entry { box-shadow: none; border-radius: var(--radius); }
.log-filter { border-radius: 8px; font-weight: 500; }
.log-filter.is-active {
  background: var(--accent-soft);
  border-color: var(--accent-line);
  color: var(--text);
}

/* ── Sauvegardes ──────────────────────────────────────────────────── */

.backup-card { box-shadow: none; border-radius: var(--radius); }

/* ── Interrupteurs ────────────────────────────────────────────────── */

.toggle-line {
  min-height: 0;
  padding: 16px;
  border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.02);
}
.toggle-line strong { color: var(--text); font-size: 0.92rem; font-weight: 600; }
.toggle-line small { color: var(--muted); font-size: 0.82rem; font-weight: 400; }
.toggle-line input:checked + span { background: var(--accent); }
.toggle-line input:checked + span::after { background: #fff; }

/* ── Notifications ────────────────────────────────────────────────── */

.dashboard-toast,
.admin-toast {
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: var(--panel-strong);
  color: var(--text);
  font-size: 0.9rem;
  font-weight: 500;
  box-shadow: var(--shadow-lg);
}

/* ── Divers ───────────────────────────────────────────────────────── */

.sanction-rank {
  background: var(--accent-soft);
  border: 1px solid var(--accent-line);
  color: #b6bdff;
}

.server-logo-shell.is-fallback::after {
  background: var(--accent);
}

.footer,
.site-footer {
  border-top: 1px solid var(--line);
  background: transparent;
}

@media (max-width: 760px) {
  .navbar { padding: 10px 16px; }
  .hero { padding: 60px 0 44px; }
  .auth-card { padding: 28px 20px; }
  .price-card { padding: 22px; }
}

/* État de chargement des listes de serveurs — jamais de données fictives */
.server-grid-loading {
  grid-column: 1 / -1;
  padding: 32px 20px;
  border: 1px dashed var(--line);
  border-radius: var(--radius);
  color: var(--muted);
  font-size: 0.9rem;
  text-align: center;
}

/* ═══════════════════════════════════════════════════════════════════════
   SÉLECTEUR DE SERVEUR — menu déroulant animé
   ═══════════════════════════════════════════════════════════════════════ */

.server-switcher {
  position: relative;
  min-width: 0;
}

.server-switcher-trigger {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: 44px;
  padding: 6px 12px 6px 6px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.03);
  color: var(--text);
  cursor: pointer;
  text-align: left;
  transition: background-color 160ms var(--ease), border-color 160ms var(--ease);
}
.server-switcher-trigger:hover {
  background: rgba(255, 255, 255, 0.07);
  border-color: var(--line-strong);
}
.server-switcher.is-open .server-switcher-trigger {
  background: rgba(255, 255, 255, 0.07);
  border-color: var(--accent-line);
}

.server-switcher-trigger .server-logo-shell {
  flex: 0 0 auto;
  width: 32px;
  height: 32px;
  border-radius: 9px;
}

.server-switcher-label {
  display: grid;
  gap: 1px;
  min-width: 0;
}
.server-switcher-label small {
  color: var(--muted);
  font-size: 0.68rem;
  font-weight: 500;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
.server-switcher-label strong {
  overflow: hidden;
  color: var(--text);
  font-size: 0.92rem;
  font-weight: 600;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.server-switcher-chevron {
  flex: 0 0 auto;
  width: 11px;
  margin-left: 4px;
  color: var(--muted);
  transition: transform 220ms var(--ease), color 160ms var(--ease);
}
.server-switcher.is-open .server-switcher-chevron {
  transform: rotate(180deg);
  color: var(--accent);
}

/* ── Panneau déroulant ─────────────────────────────────────────────── */

.server-switcher-menu {
  position: absolute;
  top: calc(100% + 8px);
  left: 0;
  z-index: 200;
  width: min(340px, calc(100vw - 32px));
  display: grid;
  overflow: hidden;
  border: 1px solid var(--line-strong);
  border-radius: 14px;
  background: var(--panel-strong);
  box-shadow: var(--shadow-lg);

  /* État fermé : légèrement remonté, réduit et transparent */
  opacity: 0;
  transform: translateY(-8px) scale(0.97);
  transform-origin: top left;
  transition: opacity 170ms var(--ease), transform 170ms var(--ease);
  pointer-events: none;
}

.server-switcher.is-open .server-switcher-menu {
  opacity: 1;
  transform: translateY(0) scale(1);
  pointer-events: auto;
}

/* ── Recherche ─────────────────────────────────────────────────────── */

.server-switcher-search {
  position: relative;
  display: flex;
  align-items: center;
  padding: 10px 12px;
  border-bottom: 1px solid var(--line);
}
.server-switcher-search svg {
  position: absolute;
  left: 22px;
  width: 15px;
  height: 15px;
  color: var(--muted);
  pointer-events: none;
}
.server-switcher-search input {
  width: 100%;
  min-height: 36px;
  padding: 8px 10px 8px 32px;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: rgba(0, 0, 0, 0.28);
  color: var(--text);
  font-size: 0.88rem;
}
.server-switcher-search input::-webkit-search-cancel-button { display: none; }

/* ── Liste ─────────────────────────────────────────────────────────── */

.server-switcher-list {
  max-height: min(340px, 50vh);
  padding: 6px;
  overflow-y: auto;
  overscroll-behavior: contain;
}

.server-switcher-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 8px;
  border: 0;
  border-radius: 10px;
  background: transparent;
  color: var(--soft);
  cursor: pointer;
  text-align: left;
  transition: background-color 140ms var(--ease), color 140ms var(--ease);

  /* Apparition en cascade à l'ouverture */
  opacity: 0;
  transform: translateY(4px);
  animation: switcherItemIn 200ms var(--ease) forwards;
  animation-delay: calc(var(--i, 0) * 28ms + 60ms);
}

@keyframes switcherItemIn {
  to { opacity: 1; transform: none; }
}

.server-switcher-item:hover,
.server-switcher-item:focus-visible {
  background: rgba(255, 255, 255, 0.06);
  color: var(--text);
  outline: none;
}
.server-switcher-item.is-current {
  background: var(--accent-soft);
  color: var(--text);
}
.server-switcher-item.is-uninstalled { opacity: 0.75; }

.server-switcher-item .server-logo-shell {
  flex: 0 0 auto;
  width: 30px;
  height: 30px;
  border-radius: 8px;
}

.server-switcher-item-text {
  display: grid;
  gap: 1px;
  min-width: 0;
  flex: 1;
}
.server-switcher-item-text strong {
  overflow: hidden;
  font-size: 0.89rem;
  font-weight: 600;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.server-switcher-item-text small {
  color: var(--muted);
  font-size: 0.76rem;
}
.server-switcher-item.is-uninstalled .server-switcher-item-text small {
  color: var(--warn);
}

.server-switcher-check {
  flex: 0 0 auto;
  color: var(--accent);
  font-size: 0.9rem;
  font-weight: 700;
}

.server-switcher-empty {
  padding: 22px 12px;
  color: var(--muted);
  font-size: 0.86rem;
  text-align: center;
}

/* ── Pied ──────────────────────────────────────────────────────────── */

.server-switcher-footer {
  padding: 6px;
  border-top: 1px solid var(--line);
}
/* Le pied contient un <button> ET un <a> : ne styler que le bouton laissait
   le lien avec sa taille et son alignement par defaut, decale du reste. */
.server-switcher-footer button,
.server-switcher-footer a {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  min-height: 36px;
  padding: 0 10px;
  border: 0;
  border-radius: 9px;
  background: transparent;
  color: var(--muted);
  font-size: 0.85rem;
  font-weight: 500;
  cursor: pointer;
  transition: background-color 140ms var(--ease), color 140ms var(--ease);
}
.server-switcher-footer a {
  text-decoration: none;
}

.server-switcher-footer button:hover,
.server-switcher-footer a:hover {
  background: rgba(255, 255, 255, 0.06);
  color: var(--text);
}

/* Les animations en cascade sont neutralisées si l'utilisateur les refuse */
@media (prefers-reduced-motion: reduce) {
  .server-switcher-item {
    opacity: 1;
    transform: none;
    animation: none;
  }
}

@media (max-width: 760px) {
  /* Le menu epouse la largeur de son bouton, qui occupe toute la ligne.
     Bride a 320 px et ancre a droite, il demarrait plus etroit que ce qui
     l'ouvre — decale sur la gauche, et son contenu a l'etroit. */
  .server-switcher-menu {
    left: 0;
    right: 0;
    width: auto;
    transform-origin: top center;
  }
  .server-switcher-label small { display: none; }

  /* Plus de place pour la liste : sur telephone, la moitie de l'ecran ne
     laissait voir que deux ou trois serveurs. */
  .server-switcher-list {
    max-height: min(420px, 58vh);
  }
}

/* ═══════════════════════════════════════════════════════════════════════
   POLISSAGE PROFESSIONNEL
   Cartes partenaires, rythme des sections, micro-interactions,
   états vides et de chargement.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── Cartes partenaires ────────────────────────────────────────────── */

/* Les cartes partenaires ont leur page et leur feuille de style plus
   bas. Les deux blocs qui vivaient ici stylaient la section de
   l'accueil, retiree depuis ; leur grid-template-columns pliait le
   texte de la nouvelle page dans une colonne de 78 px. */
/* ── Rythme des sections ───────────────────────────────────────────── */

.section-shell {
  width: min(1240px, 100%);
  margin: 0 auto;
  padding: 72px 22px;
}

.section-heading h2 { margin-bottom: 10px; }

/* ── Grille de fonctionnalités ─────────────────────────────────────── */

.feature-card {
  padding: 22px;
  transition: border-color 200ms var(--ease), transform 200ms var(--ease),
              box-shadow 200ms var(--ease);
}
.feature-card:hover {
  border-color: var(--line-strong);
  transform: translateY(-2px);
  box-shadow: var(--shadow);
}
.feature-card h3 { margin-bottom: 6px; }
.feature-card p { color: var(--muted); font-size: 0.9rem; }

/* ── Cartes de serveur ─────────────────────────────────────────────── */

.server-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(260px, 100%), 1fr));
  gap: 14px;
}

/* C'est CE bloc qui gouverne les cartes de serveur : la reprise sobre
   recouvre entierement celui d'en haut. */
.server-card-banner {
  display: block;
  height: 56px;
  background:
    linear-gradient(180deg, rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.45)),
    /* Sans banniere, une teinte tiree de l'identifiant du serveur :
       quatre bandeaux identiques se ressemblent tous, et on clique sur
       le mauvais. Rien n'est invente — la couleur sort du numero. */
    var(--server-banner, linear-gradient(135deg,
      hsl(var(--server-teinte, 250) 30% 18%),
      hsl(calc(var(--server-teinte, 250) + 40) 36% 30%))) center / cover;
}

/* Le nom passe avant tout : c'est ce qu'on cherche des yeux. Partageant
   sa ligne avec la pastille d'action, « BE VPG Belgique BE » devenait
   « BE VPG Belgiq… » — un ecran de choix ou l'on ne peut plus choisir.
   L'action descend sur sa propre ligne, le nom prend la carte. */
.server-card-body {
  display: grid;
  /* « auto » et non 42 px : la pastille du logo est portee a 64 px par
     une regle plus specifique plus haut, et une colonne de 42 la
     laissait recouvrir la premiere lettre du nom. */
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: 10px 12px;
  padding: 14px 16px 16px;
}
.server-card-body .server-logo-shell {
  width: 42px;
  height: 42px;
  margin-top: -32px;
  border: 2px solid var(--panel);
  border-radius: 12px;
}
.server-card-copy { display: grid; gap: 2px; min-width: 0; }
.server-card-copy strong {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  /* Deux lignes, puis on coupe : au-dela c'est la carte qui grandit et
     la grille qui se deregle. */
  overflow-wrap: anywhere;
  font-size: 0.94rem;
  font-weight: 650;
  line-height: 1.25;
}
.server-card-copy small { color: var(--muted); font-size: 0.79rem; }

/* « Ouvrir » etait une pastille grise, de la couleur du texte secondaire :
   la seule chose sur laquelle on vient cliquer n'avait pas l'air d'un
   bouton. */
.server-card-action {
  grid-column: 1 / -1;
  min-height: 34px;
  padding: 0 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  background: var(--accent-soft);
  border: 1px solid var(--accent-line);
  color: var(--soft);
  font-size: 0.8rem;
  font-weight: 600;
}
.server-card:hover .server-card-action {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}
.server-card.is-uninstalled .server-card-action {
  background: rgba(232, 163, 61, 0.14);
  border-color: rgba(232, 163, 61, 0.32);
  color: var(--warn);
}
.server-card.is-uninstalled:hover .server-card-action {
  background: rgba(232, 163, 61, 0.26);
  color: var(--warn);
}

/* ── États vides et chargement ─────────────────────────────────────── */

.dashboard-empty-state,
.server-grid-loading,
.log-empty,
.backup-empty {
  grid-column: 1 / -1;
  display: grid;
  gap: 8px;
  justify-items: center;
  padding: 40px 24px;
  border: 1px dashed var(--line);
  border-radius: var(--radius-lg);
  background: rgba(255, 255, 255, 0.015);
  color: var(--muted);
  font-size: 0.9rem;
  text-align: center;
}

/* Barre de progression indéterminée pendant le chargement */
.server-grid-loading::after {
  content: "";
  width: 120px;
  height: 2px;
  border-radius: 2px;
  background: linear-gradient(90deg, transparent, var(--accent), transparent);
  background-size: 50% 100%;
  background-repeat: no-repeat;
  animation: chargementGlisse 1.2s ease-in-out infinite;
}
@keyframes chargementGlisse {
  0%   { background-position: -60% 0; }
  100% { background-position: 160% 0; }
}

/* ── Indicateurs chiffrés ──────────────────────────────────────────── */

.metric-grid { display: grid; gap: 14px; }
.metric-grid > * {
  padding: 18px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--panel);
}
.metric-grid strong,
.site-stat-grid span {
  display: block;
  color: var(--text);
  font-size: 1.7rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.1;
}
.metric-grid small,
.site-stat-grid small {
  color: var(--muted);
  font-size: 0.8rem;
  font-weight: 500;
}

/* ── Tableaux ──────────────────────────────────────────────────────── */

.channel-table,
.admin-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.88rem;
}
.channel-table th,
.admin-table th {
  padding: 10px 12px;
  border-bottom: 1px solid var(--line);
  color: var(--muted);
  font-size: 0.76rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-align: left;
  text-transform: uppercase;
}
.channel-table td,
.admin-table td {
  padding: 12px;
  border-bottom: 1px solid var(--line);
  color: var(--soft);
}
.channel-table tr:last-child td,
.admin-table tr:last-child td { border-bottom: 0; }

/* ── Barre supérieure du dashboard ─────────────────────────────────── */

.dashboard-topbar {
  gap: 16px;
  padding: 10px 20px;
}
.dashboard-actions { gap: 8px; }

/* ── Bandeau de section ────────────────────────────────────────────── */

.dashboard-banner .eyebrow { margin-bottom: 6px; }
.server-summary {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 10px;
  color: var(--muted);
  font-size: 0.88rem;
}
.server-summary .server-logo-shell {
  width: 22px;
  height: 22px;
  border-radius: 7px;
}

/* ── Sélection de texte ────────────────────────────────────────────── */

::selection {
  background: rgba(88, 101, 242, 0.32);
  color: #fff;
}

/* ── Responsive ────────────────────────────────────────────────────── */

@media (max-width: 860px) {
  .section-shell { padding: 52px 18px; }
}

@media (max-width: 760px) {
  .dashboard-topbar {
    flex-wrap: wrap;
    padding: 10px 14px;
  }
  .server-switcher { order: 3; width: 100%; }
  .dashboard-actions { margin-left: auto; }
  .server-grid { grid-template-columns: 1fr; }
}

/* ═══════════════════════════════════════════════════════════════════════
   SÉLECTEUR D'IMAGE — bannière et logo du ticket
   ═══════════════════════════════════════════════════════════════════════ */

.image-picker {
  display: grid;
  gap: 10px;
  padding: 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.02);
}

.image-picker-label {
  color: var(--soft);
  font-size: 0.85rem;
  font-weight: 500;
}

/* L'apercu et les boutons se separent des que la colonne descend sous
   150 px : sinon « Choisir une image » se retrouvait dans 64 px, moitie
   coupee, dans les panneaux a deux colonnes. */
.image-picker-body {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 14px;
}

.image-picker-preview {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 152px;
  height: 58px;
  overflow: hidden;
  border: 1px dashed var(--line);
  border-radius: var(--radius);
  background: rgba(0, 0, 0, 0.28);
}
.image-picker-preview.is-square { width: 58px; }
.image-picker-preview.has-image { border-style: solid; border-color: var(--accent-line); }
.image-picker-preview img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.image-picker-empty {
  padding: 0 8px;
  color: var(--muted);
  font-size: 0.74rem;
  text-align: center;
  line-height: 1.3;
}

.image-picker-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  min-width: 0;
  flex: 1 1 150px;
}
.image-picker-actions > button {
  height: auto;
  min-height: 38px;
  min-width: 0;
  padding: 8px 14px;
  white-space: normal;
  text-align: center;
}
.image-picker-hint {
  flex: 1 1 100%;
  color: var(--muted);
  font-size: 0.76rem;
  line-height: 1.45;
}

.image-picker-url > summary {
  color: var(--muted);
  font-size: 0.8rem;
  cursor: pointer;
  list-style: none;
}
.image-picker-url > summary::-webkit-details-marker { display: none; }
.image-picker-url > summary::before { content: "▸ "; }
.image-picker-url[open] > summary::before { content: "▾ "; }
.image-picker-url > summary:hover { color: var(--text); }
.image-picker-url input {
  width: 100%;
  min-height: 38px;
  margin-top: 8px;
  padding: 8px 12px;
}

@media (max-width: 760px) {
  .image-picker-body { flex-direction: column; }
  .image-picker-preview { width: 100%; }
  .image-picker-preview.is-square { width: 72px; }
  .image-picker-actions > button { flex: 1; }
}

/* ═══════════════════════════════════════════════════════════════════
   PANNEAU RECHERCHE — membres et rôles
   Deux colonnes : résultats à gauche, fiche détaillée à droite.
   ═══════════════════════════════════════════════════════════════════ */

.search-modes {
  display: flex;
  gap: 6px;
  padding: 4px;
  margin-bottom: 14px;
  background: var(--bg-soft);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  width: fit-content;
  max-width: 100%;
}

.search-mode {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 18px;
  border: 0;
  border-radius: 7px;
  background: transparent;
  color: var(--soft);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.16s ease, color 0.16s ease;
}

.search-mode:hover { color: var(--text); background: rgba(255, 255, 255, 0.04); }

.search-mode.is-active {
  background: var(--accent);
  color: #fff;
  box-shadow: var(--shadow-sm);
}

.search-mode:focus-visible { outline: none; box-shadow: var(--ring); }

/* ── Barre de recherche ─────────────────────────────────────────── */

.search-bar {
  position: relative;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 14px;
  background: var(--panel);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  transition: border-color 0.16s ease, box-shadow 0.16s ease;
}

.search-bar:focus-within {
  border-color: var(--accent-line);
  box-shadow: var(--ring);
}

.search-bar-icon { color: var(--muted); flex: none; }

.search-bar input {
  flex: 1;
  min-width: 0;
  padding: 13px 0;
  border: 0;
  background: transparent;
  color: var(--text);
  font: inherit;
}

.search-bar input:focus { outline: none; }
.search-bar input::placeholder { color: var(--muted); }
.search-bar input::-webkit-search-cancel-button { display: none; }

/* ── Disposition en deux colonnes ───────────────────────────────── */

.search-layout {
  display: grid;
  grid-template-columns: minmax(0, 320px) minmax(0, 1fr);
  gap: 16px;
  margin-top: 16px;
  align-items: start;
}

.search-results-panel h3 { margin: 0 0 12px; font-size: 0.95rem; }

.search-results {
  display: flex;
  flex-direction: column;
  gap: 4px;
  max-height: 520px;
  overflow-y: auto;
  overflow-x: hidden;
  padding-right: 4px;
}

.search-results::-webkit-scrollbar { width: 8px; }
.search-results::-webkit-scrollbar-thumb {
  background: var(--line-strong);
  border-radius: 4px;
}

/* ── Une ligne de résultat ──────────────────────────────────────── */

.search-result {
  display: flex;
  align-items: center;
  gap: 11px;
  width: 100%;
  padding: 9px 11px;
  border: 1px solid transparent;
  border-radius: var(--radius);
  background: transparent;
  color: var(--text);
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: background 0.14s ease, border-color 0.14s ease;
}

.search-result:hover { background: rgba(255, 255, 255, 0.045); }

.search-result.is-active {
  background: var(--accent-soft);
  border-color: var(--accent-line);
}

.search-result:focus-visible { outline: none; box-shadow: var(--ring); }

.search-result-avatar {
  flex: none;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  overflow: hidden;
  background: var(--panel-strong);
  border: 1px solid var(--line);
}

.search-result-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
.search-result-avatar.large { width: 60px; height: 60px; }

.search-result-dot {
  flex: none;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.06);
}

.search-result-dot.large { width: 22px; height: 22px; }

.search-result-body {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}

.search-result-body strong {
  font-size: 0.92rem;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.search-result-body small {
  color: var(--muted);
  font-size: 0.78rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ── Fiche détaillée ────────────────────────────────────────────── */

.search-detail-panel { min-height: 260px; }

.search-detail-head {
  display: flex;
  align-items: center;
  gap: 14px;
  padding-bottom: 14px;
  margin-bottom: 14px;
  border-bottom: 1px solid var(--line);
}

.search-detail-head h3 { margin: 0 0 2px; font-size: 1.15rem; }
.search-detail-head .field-help { margin: 0; }
.search-detail-head code {
  padding: 1px 5px;
  background: var(--bg-soft);
  border-radius: 4px;
  font-size: 0.78rem;
}

.search-detail-facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(140px, 100%), 1fr));
  gap: 10px;
  margin-bottom: 14px;
}

.search-detail-facts > div {
  padding: 10px 12px;
  background: var(--bg-soft);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

.search-detail-facts span {
  display: block;
  color: var(--muted);
  font-size: 0.74rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-bottom: 3px;
}

.search-detail-facts strong { font-size: 0.92rem; font-weight: 600; }

.search-role-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 14px;
}

.search-role-chip {
  padding: 3px 10px;
  font-size: 0.78rem;
  background: var(--bg-soft);
  border: 1px solid var(--line-strong);
  border-left-width: 3px;
  border-radius: 6px;
  color: var(--soft);
}

.search-reason { margin-bottom: 14px; }

.search-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

/* Second clic obligatoire sur les actions irréversibles */
.search-actions .is-confirming {
  background: var(--err);
  border-color: var(--err);
  animation: search-pulse 1.1s ease-in-out infinite;
}

@keyframes search-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(237, 66, 69, 0.5); }
  50%      { box-shadow: 0 0 0 6px rgba(237, 66, 69, 0); }
}

@media (prefers-reduced-motion: reduce) {
  .search-actions .is-confirming { animation: none; }
}

.secondary-btn.danger { border-color: rgba(237, 66, 69, 0.45); color: #ff8b8d; }
.secondary-btn.danger:hover { background: rgba(237, 66, 69, 0.12); }

/* ── Encarts d'aide et états ────────────────────────────────────── */

.alert-panel.subtle {
  background: var(--bg-soft);
  border-color: var(--line-strong);
  margin-bottom: 14px;
}

.alert-panel.subtle p { margin: 6px 0 0; font-size: 0.84rem; color: var(--muted); }

.inline-hint {
  margin-top: 12px;
  padding: 11px 13px;
  background: var(--accent-soft);
  border: 1px solid var(--accent-line);
  border-radius: var(--radius);
  font-size: 0.85rem;
  color: var(--soft);
  line-height: 1.55;
}

.inline-hint code {
  padding: 1px 6px;
  background: rgba(0, 0, 0, 0.3);
  border-radius: 4px;
  font-size: 0.82rem;
  color: var(--text);
}

.captcha-state { justify-content: flex-start; }
.captcha-state > span {
  color: var(--muted);
  font-size: 0.74rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.captcha-state-value {
  margin: 6px 0 0;
  font-weight: 600;
  font-size: 0.92rem;
}

@media (max-width: 900px) {
  .search-layout { grid-template-columns: minmax(0, 1fr); }
  .search-results { max-height: 320px; }
}

@media (max-width: 560px) {
  .search-modes { width: 100%; }
  .search-mode { flex: 1; justify-content: center; padding: 8px 10px; }
  .search-actions > button { flex: 1 1 100%; }
}

/* ═══════════════════════════════════════════════════════════════════
   STATISTIQUES PUBLIQUES — page d'accueil
   Chiffres réels servis par le bot, pas des valeurs décoratives.
   ═══════════════════════════════════════════════════════════════════ */

.stats[data-live-stats] {
  display: block;
  text-align: center;
}

.stats-headline { margin-bottom: 26px; }

.stats-big {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: center;
  gap: 12px;
  margin: 0 0 8px;
  font-size: clamp(1.05rem, 2.4vw, 1.5rem);
  color: var(--soft);
}

.stats-big strong {
  font-size: clamp(2.4rem, 7vw, 4.2rem);
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.02em;
  background: linear-gradient(135deg, var(--purple-2), var(--cyan));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  /* Repli si le dégradé sur texte n'est pas supporté */
  -webkit-text-fill-color: transparent;
  font-variant-numeric: tabular-nums;
}

.stats-sub {
  margin: 0;
  color: var(--muted);
  font-size: 0.94rem;
}

.stats-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(150px, 100%), 1fr));
  gap: 14px;
  max-width: 720px;
  margin: 0 auto;
}

.stats-row .stat strong { font-variant-numeric: tabular-nums; }

/* ── Répartition par langue ─────────────────────────────────────── */
/* Les classes gardent leur nom historique (.stat-country) : elles servent
   aussi à d'autres règles et un renommage n'apporterait rien. */

.stats-countries {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  margin-top: 12px;
}

/* ── Compte Discord connecté, dans la barre du dashboard ─────────── */

.account-switch { position: relative; }

.account-trigger {
  display: flex;
  align-items: center;
  gap: 9px;
  max-width: 220px;
  padding: 6px 10px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--panel);
  color: var(--soft);
  cursor: pointer;
  transition: border-color 150ms ease, background 150ms ease;
}
.account-trigger:hover,
.account-switch.is-open .account-trigger {
  border-color: var(--accent-line);
  background: var(--panel-strong);
}

.account-avatar {
  flex: none;
  width: 28px;
  height: 28px;
  overflow: hidden;
  border-radius: 50%;
  background: var(--panel-strong);
}
.account-avatar img { width: 100%; height: 100%; object-fit: cover; }

.account-label {
  display: grid;
  min-width: 0;
  text-align: left;
  line-height: 1.2;
}
.account-label small { color: var(--muted); font-size: 0.68rem; }
/* Un pseudo Discord peut etre long : on coupe plutot que d'etirer la barre */
.account-label strong {
  overflow: hidden;
  color: var(--text);
  font-size: 0.85rem;
  font-weight: 600;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.account-chevron {
  flex: none;
  width: 10px;
  transition: transform 180ms ease;
}
.account-switch.is-open .account-chevron { transform: rotate(180deg); }

.account-menu {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  z-index: 60;
  width: 268px;
  padding: 10px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-lg);
  background: var(--panel-strong);
  box-shadow: var(--shadow-lg);
}
.account-menu-note {
  margin: 2px 4px 8px;
  color: var(--muted);
  font-size: 0.76rem;
  line-height: 1.45;
}
.account-menu button {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 9px 10px;
  border: 0;
  border-radius: var(--radius);
  background: transparent;
  color: var(--soft);
  font-size: 0.88rem;
  text-align: left;
  cursor: pointer;
  transition: background 140ms ease, color 140ms ease;
}
.account-menu button:hover { background: rgba(255, 255, 255, 0.06); color: var(--text); }
.account-menu button.is-danger:hover { background: rgba(240, 71, 71, 0.14); color: #ff8a8a; }

@media (max-width: 900px) {
  /* Le libelle disparait la ou la place manque vraiment. Dans la barre du
     dashboard il revient (voir plus bas) : la pastille y a sa propre ligne,
     et un avatar seul dans une bande vide ne dit pas a qui on est connecte. */
  .account-label { display: none; }
  .account-trigger { padding: 6px; }
  /* 268 px sur un telephone obligeaient la note a se replier sur trois
     lignes ; on prend la largeur disponible. */
  .account-menu { width: min(330px, calc(100vw - 24px)); }
}

/* Barre du dashboard : le compte partage la ligne du logo, il y a la place
   d'annoncer qui est connecte. En dessous de 360 px on repasse a l'avatar
   seul, le pseudo n'aurait plus que quelques pixels. */
@media (min-width: 360px) and (max-width: 900px) {
  .dashboard-topbar .account-label { display: grid; }
  .dashboard-topbar .account-trigger { padding: 5px 10px 5px 5px; }
  /* Le pseudo seul : « Connecte en tant que » prend deux fois sa largeur
     pour ne rien apprendre que le pseudo ne dise deja. */
  .dashboard-topbar .account-label small { display: none; }
  .dashboard-topbar .account-label strong { max-width: 34vw; font-size: 0.9rem; }
}

/* Intitule de chaque repartition : « Par pays », « Par langue ». */
.stats-list-title {
  margin-top: 26px;
  color: var(--muted);
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-align: center;
}

.stat-country {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 7px 13px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: 0.87rem;
  transition: border-color 0.16s ease, transform 0.16s ease;
}

.stat-country:hover {
  border-color: var(--accent-line);
  transform: translateY(-1px);
}

.stat-country-flag { font-size: 1.05rem; line-height: 1; }
.stat-country-name { color: var(--soft); }

/* Serveurs dont personne n'a choisi la langue : comptés dans le total, mais
   visuellement en retrait — ce n'est pas une langue, c'est une absence. */
.stat-country.is-unknown {
  background: transparent;
  border-style: dashed;
  opacity: 0.72;
}

.stat-country.is-unknown .stat-country-count { color: var(--soft); font-weight: 600; }

.stat-country-count {
  color: var(--text);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.stats-note {
  margin: 16px auto 0;
  max-width: 560px;
  color: var(--muted);
  font-size: 0.8rem;
  line-height: 1.5;
}

.stats-offline .stats-big strong {
  background: none;
  -webkit-text-fill-color: var(--muted);
  color: var(--muted);
}

@media (prefers-reduced-motion: reduce) {
  .stat-country:hover { transform: none; }
}

@media (max-width: 560px) {
  .stats-big { gap: 6px; }
  .stats-countries { gap: 6px; }
  .stat-country { padding: 6px 11px; font-size: 0.82rem; }
}

/* â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
   BIENVENUE ET DÃ‰PARTS
   â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â• */

.welcome-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 380px);
  gap: 16px;
  margin-top: 16px;
  align-items: start;
}

.welcome-form h3,
.welcome-preview-panel h3 { margin: 0 0 12px; font-size: 0.95rem; }

.welcome-form .mini-form { margin-bottom: 12px; }

.welcome-form textarea {
  width: 100%;
  resize: vertical;
  min-height: 104px;
  font-family: inherit;
  line-height: 1.6;
}

/*
 * Ce panneau sert a ECRIRE puis a RELIRE un message : ses champs et son
 * apercu ne peuvent pas garder la taille des petits libelles du reste du
 * dashboard, ou l'on ne fait que cocher des cases.
 */
.welcome-form textarea,
.welcome-form input[type="text"],
.welcome-form input[type="url"] {
  font-size: 1.02rem;
}

.welcome-form .mini-form > span {
  font-size: 0.95rem;
  color: var(--soft);
}

/* Puces de variables insÃ©rables au curseur */
/* Le -4 px collait les pastilles au champ qu'elles remplissent. Sous
   une etiquette complete — son intitule ET sa liste deroulante — il
   les faisait remonter DANS la liste : les noms de salons passaient
   par-dessus le bord du champ. Deux pixels d'air a la place. */
.variable-chips {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 6px;
  margin: 2px 0 14px;
}

.variable-chip {
  padding: 4px 10px;
  border: 1px solid var(--accent-line);
  border-radius: 999px;
  background: var(--accent-soft);
  color: var(--soft);
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 0.78rem;
  cursor: pointer;
  transition: background 0.14s ease, color 0.14s ease;
}

.variable-chip:hover { background: var(--accent); color: #fff; }
.variable-chip:focus-visible { outline: none; box-shadow: var(--ring); }

/* AperÃ§u faÃ§on Discord */
.discord-preview {
  padding: 18px;
  background: #313338;
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

.discord-preview-row { display: flex; gap: 12px; }

.discord-preview-avatar {
  flex: none;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--purple), var(--cyan));
}

.discord-preview-body { min-width: 0; flex: 1; }

.discord-preview-author {
  margin: 0 0 6px;
  font-weight: 600;
  font-size: 1.02rem;
  color: #f2f3f5;
}

.discord-preview-tag {
  margin-left: 6px;
  padding: 1px 5px;
  border-radius: 4px;
  background: var(--accent);
  color: #fff;
  font-size: 0.7rem;
  font-weight: 700;
  vertical-align: middle;
}

.discord-preview-embed {
  padding: 14px 18px;
  border-left: 4px solid var(--accent);
  border-radius: 4px;
  background: #2b2d31;
  color: #dbdee1;
}

.discord-preview-embed.is-plain {
  border-left-color: transparent;
  background: transparent;
  padding: 0;
}

.discord-preview-embed strong {
  display: block;
  margin-bottom: 8px;
  color: #f2f3f5;
  font-size: 1.2rem;
  line-height: 1.35;
}

.discord-preview-embed p {
  margin: 0;
  font-size: 1.06rem;
  line-height: 1.6;
  white-space: pre-wrap;
  word-break: break-word;
}

.discord-preview-embed img {
  display: block;
  width: 100%;
  max-height: 180px;
  object-fit: cover;
  margin-top: 10px;
  border-radius: 6px;
}

.discord-preview-footer {
  display: block;
  margin-top: 10px;
  color: #949ba4;
  font-size: 0.88rem;
}

.discord-preview-button {
  display: inline-block;
  margin-top: 10px;
  padding: 9px 18px;
  border-radius: 4px;
  background: #4e5058;
  color: #fff;
  font-size: 0.98rem;
  font-weight: 500;
  text-decoration: none;
}

/* â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
   GIVEAWAYS
   â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â• */

.giveaway-form { margin-bottom: 16px; }
.giveaway-form h3 { margin: 0 0 12px; font-size: 1rem; }
.giveaway-form h4 { margin: 18px 0 4px; font-size: 0.88rem; color: var(--soft); }

.giveaway-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(320px, 100%), 1fr));
  gap: 12px;
}

.giveaway-card {
  padding: 16px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  transition: border-color 0.16s ease, transform 0.16s ease;
}

.giveaway-card:hover { border-color: var(--accent-line); transform: translateY(-2px); }
.giveaway-card.is-ended { opacity: 0.72; }

.giveaway-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 10px;
}

.giveaway-head h3 { margin: 0 0 3px; font-size: 1rem; }
.giveaway-head .field-help { margin: 0; font-size: 0.8rem; }

.giveaway-state {
  flex: none;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.giveaway-state.is-live {
  background: rgba(59, 165, 93, 0.16);
  color: #4ade80;
  border: 1px solid rgba(59, 165, 93, 0.4);
}

.giveaway-state.is-ended {
  background: rgba(148, 155, 164, 0.14);
  color: var(--muted);
  border: 1px solid var(--line-strong);
}

/* Archive : range, pas efface. La carte s'efface davantage que
   « terminee » sans disparaitre — on doit pouvoir la relire. */
.giveaway-card.is-archived { opacity: 0.55; }
.giveaway-card.is-archived:hover { opacity: 0.85; }

.giveaway-state.is-archived {
  background: rgba(120, 130, 150, 0.12);
  color: var(--muted);
  border: 1px dashed var(--line-strong);
}

.giveaway-conditions,
.giveaway-winners {
  margin: 0 0 10px;
  font-size: 0.82rem;
  color: var(--muted);
}

.giveaway-winners { color: var(--soft); }

/* â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
   ASSISTANT IA
   â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â• */

/* La spécificité est volontairement portée à .dashboard-page :
   `.dashboard-page button` impose position:relative avec une spécificité
   supérieure (0,1,1), ce qui renvoyait le lanceur en bas du flux, hors écran.
   Il doit rester visible en permanence, quel que soit le défilement. */
.dashboard-page .ai-launcher,
.ai-launcher {
  position: fixed;
  right: 22px;
  bottom: 22px;
  z-index: 80;
  /* Annule l'overflow/isolation hérités de la règle générique des boutons */
  overflow: visible;
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 12px 20px;
  border: 0;
  border-radius: 999px;
  background: linear-gradient(135deg, var(--purple), var(--purple-2));
  color: #fff;
  font: inherit;
  font-weight: 600;
  cursor: pointer;
  box-shadow: var(--shadow-lg);
  transition: transform 0.18s ease, box-shadow 0.18s ease;
}

.ai-launcher:hover { transform: translateY(-2px); }
.ai-launcher:focus-visible { outline: none; box-shadow: var(--ring), var(--shadow-lg); }
.ai-launcher.is-active { transform: scale(0.94); opacity: 0.85; }

.ai-launcher-icon {
  font-size: 1.1rem;
  animation: ai-sparkle 2.8s ease-in-out infinite;
}

@keyframes ai-sparkle {
  0%, 100% { transform: scale(1) rotate(0deg); }
  50%      { transform: scale(1.18) rotate(12deg); }
}

.ai-assistant {
  position: fixed;
  right: 22px;
  bottom: 88px;
  z-index: 81;
  display: flex;
  flex-direction: column;
  width: min(400px, calc(100vw - 32px));
  height: min(560px, calc(100vh - 130px));
  background: var(--panel);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
  opacity: 0;
  transform: translateY(14px) scale(0.97);
  transition: opacity 0.2s ease, transform 0.2s cubic-bezier(0.22, 1, 0.36, 1);
}

.ai-assistant.is-open { opacity: 1; transform: translateY(0) scale(1); }

.ai-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 16px;
  border-bottom: 1px solid var(--line);
  background: var(--bg-soft);
}

.ai-header-title { display: flex; align-items: center; gap: 11px; min-width: 0; }
.ai-header-title strong { display: block; font-size: 0.94rem; }
.ai-header-title small { display: block; color: var(--muted); font-size: 0.76rem; }

.ai-avatar {
  flex: none;
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--purple), var(--cyan));
  font-size: 1rem;
}

.ai-close {
  flex: none;
  width: 30px;
  height: 30px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--muted);
  font-size: 1rem;
  cursor: pointer;
}

.ai-close:hover { background: rgba(255, 255, 255, 0.06); color: var(--text); }

.ai-messages {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.ai-message { display: flex; }
.ai-message.is-user { justify-content: flex-end; }

.ai-bubble {
  max-width: 86%;
  padding: 10px 13px;
  border-radius: 14px;
  font-size: 0.87rem;
  line-height: 1.55;
  word-break: break-word;
}

.ai-message.is-bot .ai-bubble {
  background: var(--bg-soft);
  border: 1px solid var(--line);
  border-bottom-left-radius: 4px;
}

.ai-message.is-user .ai-bubble {
  background: var(--accent);
  color: #fff;
  border-bottom-right-radius: 4px;
}

.ai-bubble code {
  padding: 1px 5px;
  border-radius: 4px;
  background: rgba(0, 0, 0, 0.28);
  font-size: 0.82em;
}

.ai-message.is-thinking .ai-bubble {
  animation: ai-thinking 1.3s ease-in-out infinite;
  letter-spacing: 3px;
}

@keyframes ai-thinking {
  0%, 100% { opacity: 0.4; }
  50%      { opacity: 1; }
}

.ai-panel-link {
  display: block;
  margin-top: 9px;
  padding: 7px 11px;
  border: 1px solid var(--accent-line);
  border-radius: 8px;
  background: var(--accent-soft);
  color: var(--text);
  font: inherit;
  font-size: 0.82rem;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
  transition: background 0.14s ease;
}

.ai-panel-link:hover { background: var(--accent); color: #fff; }

.ai-suggestions {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 0 16px 12px;
}

.ai-suggestions button {
  padding: 6px 11px;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: var(--bg-soft);
  color: var(--soft);
  font: inherit;
  font-size: 0.78rem;
  cursor: pointer;
  transition: border-color 0.14s ease, color 0.14s ease;
}

.ai-suggestions button:hover { border-color: var(--accent-line); color: var(--text); }

.ai-composer {
  display: flex;
  gap: 8px;
  padding: 12px 16px 16px;
  border-top: 1px solid var(--line);
}

.ai-composer input {
  flex: 1;
  min-width: 0;
  padding: 11px 14px;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: var(--bg-soft);
  color: var(--text);
  font: inherit;
}

.ai-composer input:focus { outline: none; border-color: var(--accent-line); box-shadow: var(--ring); }
.ai-composer button { flex: none; border-radius: 50%; width: 42px; height: 42px; padding: 0; }

/* â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
   MENU MOBILE â€” hamburger animÃ© et panneau latÃ©ral
   â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â• */

.nav-toggle {
  position: relative;
  display: none;
  width: 42px;
  height: 42px;
  padding: 0;
  border: 1px solid var(--line-strong);
  border-radius: 10px;
  background: var(--panel);
  cursor: pointer;
  z-index: 102;
}

/* Les deux <span> deviennent trois traits : le second porte un ::after */
.nav-toggle span {
  position: absolute;
  left: 50%;
  width: 18px;
  height: 2px;
  border-radius: 2px;
  background: var(--text);
  transform: translateX(-50%);
  transition: transform 0.28s cubic-bezier(0.65, 0, 0.35, 1),
              opacity 0.18s ease,
              top 0.28s cubic-bezier(0.65, 0, 0.35, 1);
}

.nav-toggle span:nth-child(1) { top: 14px; }
.nav-toggle span:nth-child(2) { top: 20px; }

.nav-toggle span:nth-child(2)::after {
  content: "";
  position: absolute;
  left: 0;
  top: 6px;
  width: 18px;
  height: 2px;
  border-radius: 2px;
  background: var(--text);
  transition: transform 0.28s cubic-bezier(0.65, 0, 0.35, 1), opacity 0.18s ease;
}

/* Croix : le trait du haut descend et pivote, celui du bas remonte */
.nav-toggle[aria-expanded="true"] span:nth-child(1) {
  top: 20px;
  transform: translateX(-50%) rotate(45deg);
}

.nav-toggle[aria-expanded="true"] span:nth-child(2) {
  transform: translateX(-50%) rotate(-45deg);
}

.nav-toggle[aria-expanded="true"] span:nth-child(2)::after {
  opacity: 0;
  transform: translateY(-6px);
}

@media (max-width: 980px) {
  .nav-toggle { display: block; }

  /*
   * L'en-tete doit cesser d'etre un piege pour le tiroir qu'il contient.
   *
   * `backdrop-filter` (comme `transform`) fait d'un element le bloc
   * conteneur de ses descendants `position: fixed` : `bottom: 0` valait
   * alors le bas de l'en-tete, et le tiroir mesurait 114 px de haut au
   * lieu de toute la hauteur de l'ecran.
   *
   * Le meme attribut, avec `position: sticky`, cree aussi un contexte
   * d'empilement : le `z-index: 101` du tiroir restait enferme sous le
   * `z-index: 50` de l'en-tete, donc sous le voile (100) et son flou.
   * C'est ce qui rendait le menu flou une fois ouvert.
   *
   * Le fond de l'en-tete est deja opaque a 85 % : perdre le flou sur
   * mobile ne se voit pratiquement pas, et c'est le prix d'un menu qui
   * fonctionne.
   */
  .site-header {
    backdrop-filter: none;
    animation: none;
    transform: none;
    z-index: 120;
  }

  .nav-links {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    /* Explicite : sans cela une regle plus ancienne pourrait de nouveau
       ancrer le tiroir a gauche, ce qui annule `right`. */
    left: auto;
    z-index: 101;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 4px;
    width: min(320px, 84vw);
    padding: 84px 20px 28px;
    background: var(--panel);
    border-left: 1px solid var(--line-strong);
    box-shadow: var(--shadow-lg);
    overflow-y: auto;
    /* FermÃ© : hors Ã©cran Ã  droite. visibility Ã©vite le focus au clavier. */
    transform: translateX(100%);
    visibility: hidden;
    transition: transform 0.34s cubic-bezier(0.22, 1, 0.36, 1),
                visibility 0s linear 0.34s;
  }

  .nav-links.is-open {
    transform: translateX(0);
    visibility: visible;
    transition: transform 0.34s cubic-bezier(0.22, 1, 0.36, 1), visibility 0s;
  }

  /* Chaque entrÃ©e arrive en cascade derriÃ¨re le panneau */
  .nav-links > * {
    opacity: 0;
    transform: translateX(18px);
    transition: opacity 0.26s ease, transform 0.26s ease;
  }

  .nav-links.is-open > * { opacity: 1; transform: translateX(0); }

  .nav-links.is-open > *:nth-child(1)  { transition-delay: 0.06s; }
  .nav-links.is-open > *:nth-child(2)  { transition-delay: 0.09s; }
  .nav-links.is-open > *:nth-child(3)  { transition-delay: 0.12s; }
  .nav-links.is-open > *:nth-child(4)  { transition-delay: 0.15s; }
  .nav-links.is-open > *:nth-child(5)  { transition-delay: 0.18s; }
  .nav-links.is-open > *:nth-child(6)  { transition-delay: 0.21s; }
  .nav-links.is-open > *:nth-child(7)  { transition-delay: 0.24s; }
  .nav-links.is-open > *:nth-child(8)  { transition-delay: 0.27s; }
  .nav-links.is-open > *:nth-child(9)  { transition-delay: 0.30s; }
  .nav-links.is-open > *:nth-child(10) { transition-delay: 0.33s; }
  .nav-links.is-open > *:nth-child(11) { transition-delay: 0.36s; }

  .nav-links a {
    padding: 13px 14px;
    border-radius: 10px;
    font-size: 0.98rem;
  }

  .nav-links a:hover,
  .nav-links a:focus-visible { background: rgba(255, 255, 255, 0.05); }

  .nav-links .nav-cta,
  .nav-links .nav-action-btn { justify-content: center; margin-top: 6px; }

  .nav-links .language-switch { margin-top: 12px; justify-content: center; }

  /* Voile derriÃ¨re le panneau */
  .nav-backdrop {
    position: fixed;
    inset: 0;
    z-index: 100;
    background: rgba(5, 7, 12, 0.62);
    backdrop-filter: blur(2px);
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.3s ease, visibility 0s linear 0.3s;
  }

  .nav-backdrop.is-open {
    opacity: 1;
    visibility: visible;
    transition: opacity 0.3s ease, visibility 0s;
  }

  body.nav-open { overflow: hidden; }

  /*
   * Le tiroir ferme est pousse hors de l'ecran a droite. Un element
   * `position: fixed` compte malgre tout dans la largeur defilable de la
   * page : sans ce clip, on pouvait faire glisser tout le site vers la
   * droite et decouvrir une bande vide de 320 px.
   *
   * `clip` et non `hidden` : `hidden` ferait de la racine un conteneur de
   * defilement, ce qui casserait l'en-tete colle. `clip` se contente de
   * couper, et reste compatible avec `overflow-y: visible`.
   */
  html { overflow-x: clip; }
}

@media (prefers-reduced-motion: reduce) {
  .ai-launcher-icon,
  .ai-message.is-thinking .ai-bubble { animation: none; }
  .ai-assistant { transition: opacity 0.01s; }
  .ai-launcher:hover,
  .giveaway-card:hover { transform: none; }
  .nav-links,
  .nav-links > *,
  .nav-backdrop,
  .nav-toggle span,
  .nav-toggle span::after { transition-duration: 0.01s; transition-delay: 0s; }
}

@media (max-width: 900px) {
  .welcome-layout { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 560px) {
  .ai-launcher { right: 14px; bottom: 14px; padding: 11px 16px; }
  .ai-launcher-label { display: none; }
  .ai-assistant {
    right: 8px;
    left: 8px;
    bottom: 74px;
    width: auto;
    height: min(70vh, 520px);
  }
  .giveaway-list { grid-template-columns: minmax(0, 1fr); }
}


/* Le toast occupait le coin bas droit, exactement sous le lanceur de
   l'assistant. Il passe à gauche : les deux restent lisibles ensemble. */
.dashboard-page .dashboard-toast {
  right: auto;
  left: 22px;
}

@media (max-width: 560px) {
  .dashboard-page .dashboard-toast {
    left: 14px;
    right: 78px;
  }
}

/* ── Selecteur d'image (bienvenue) ─────────────────────────────────── */
/* Le champ fichier natif est masque : son rendu varie selon les
   navigateurs et ne se style pas. Le bouton visible le declenche. */
.image-picker {
  gap: 8px;
}

.image-picker-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.image-picker-preview {
  display: block;
  width: 100%;
  max-width: 320px;
  aspect-ratio: 1000 / 380;
  object-fit: cover;
  border-radius: 12px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  background: rgba(0, 0, 0, 0.25);
}

.image-picker-preview[hidden] {
  display: none;
}

/* ── Barre du haut du dashboard, écrans réduits ───────────────────── */
/* Sous 1120 px la barre passait en grille d'une seule colonne : ses trois
   blocs s'empilaient alors sur toute la largeur, 184 px de haut, et sur
   téléphone `.dashboard-actions` était renvoyée seule sur une ligne — la
   pastille du compte se retrouvait isolée tout à droite avec une large
   bande noire vide entre le logo et elle. `flex-wrap` était bien déclaré,
   mais sur un conteneur grille, où il ne s'applique pas.

   `display: contents` fait disparaître la boîte de `.dashboard-actions`
   sans toucher au HTML : ses enfants deviennent des éléments flexibles de
   la barre elle-même, et peuvent donc être ordonnés librement. */
@media (max-width: 1120px) {
  .dashboard-topbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    padding: 10px 14px;
  }

  .dashboard-actions { display: contents; }

  /* Ligne 1 : le logo pousse contre le bord droit la pastille d'identite —
     le compte connecte sur le dashboard, le bandeau « Espace actif » sur la
     page d'administration. Les deux barres partagent ces regles : donner un
     ordre aux seules classes du dashboard laissait celles de l'admin a
     l'ordre 0, c'est-a-dire AVANT le logo. */
  /* `margin-right: auto` et NON `flex: 1 1 auto` : la marge absorbe
     l'espace libre sans agrandir le lien. Etendu, il faisait 238 px
     de large et un clic au milieu de la barre renvoyait a l'accueil,
     alors qu'on visait le vide. */
  .dashboard-topbar .brand { order: 1; flex: 0 0 auto; margin-right: auto; }
  .dashboard-topbar .account-switch,
  .dashboard-topbar .dashboard-server { order: 2; flex: 0 0 auto; }

  /* Puis le serveur, la langue et les deux boutons, qui se replient
     d'eux-memes selon la place. */
  .dashboard-topbar .server-switcher { order: 3; flex: 1 1 260px; min-width: 0; }
  /* `width: auto` : avec flex-basis auto, c'est la largeur declaree qui
     sert de base, et le selecteur de langue est a 100 % sur ces
     ecrans — il occupait donc une ligne entiere pour lui seul. */
  .dashboard-topbar .language-switch {
    order: 4;
    flex: 0 1 auto;
    width: auto;
    min-width: 0;
  }
  /* `.secondary-btn` plutot que `[data-dashboard-save]` : c'est la classe du
     bouton Enregistrer du dashboard ET du lien Dashboard de l'admin. */
  .dashboard-topbar .secondary-btn { order: 5; flex: 0 1 auto; }
  .dashboard-topbar .primary-btn { order: 6; flex: 0 1 auto; }
}

/* Téléphone : le serveur prend sa propre ligne, la langue occupe la place
   restante à côté des deux boutons. */
@media (max-width: 760px) {
  .dashboard-topbar .server-switcher { flex: 1 1 100%; }
  .dashboard-topbar .language-switch { flex: 1 1 130px; }
  .dashboard-topbar .language-switch select { width: 100%; min-width: 0; }
}

/* Sous 430 px, les deux boutons prennent chacun la moitié d'une ligne :
   côte à côte avec la langue, leurs libellés se tronquaient. */
@media (max-width: 430px) {
  .dashboard-topbar .language-switch { flex: 1 1 100%; }
  .dashboard-topbar .secondary-btn,
  .dashboard-topbar .primary-btn { flex: 1 1 0; }
}

/* ── Bandeau « Espace actif » de la page d'administration ─────────── */
/* `.dashboard-server` porte une grille de quatre colonnes, dont une figee
   a 34 px, heritee d'un balisage a quatre enfants. La barre de l'admin n'en
   a que trois : le libelle « 🔐 Espace actif » tombait dans la colonne
   etroite et se coupait en deux lignes. Une simple rangee flexible suffit. */
.admin-topbar .dashboard-server {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

.admin-topbar .dashboard-server > span:not(.server-dot),
.admin-topbar .dashboard-server > strong {
  white-space: nowrap;
}

/* ── Espace d'administration : finitions ──────────────────────────── */
/* Ces règles corrigent des vides et des signaux contradictoires : une
   colonne réservait 520 px pour cinq entrées, une carte flottait au milieu
   d'une boîte étirée, une pastille verte annonçait « Verrouillé ». */

/* Les deux cartes de la porte d'entrée se calent en haut. Sans cela la
   grille les étire à la même hauteur, et la plus courte donnait
   l'impression d'un bloc vide avec du texte au milieu. */
.admin-gate-grid {
  align-items: start;
}

/* Une carte seule occupait une demi-largeur, laissant un trou à sa droite. */
.admin-grid.two > :only-child {
  grid-column: 1 / -1;
}

/* Note d'explication : à l'intérieur d'une carte, l'encadré et la largeur
   centrée la faisaient passer pour un avertissement technique. */
.admin-login-panel .oauth-note {
  width: auto;
  margin: 4px 0 0;
  padding: 0;
  border: 0;
  background: none;
  font-size: 0.82rem;
}

/* La pastille d'état était verte quel que soit l'état — y compris pour
   annoncer que l'espace est verrouillé. */
.health-pill.is-locked {
  background: rgba(255, 196, 84, 0.14);
  color: #ffdda6;
}

.health-pill.is-locked span {
  background: #ffc454;
}

/* Tuiles de chiffres : un peu plus compactes, le chiffre et son libellé
   étaient séparés par un vide qui les faisait paraître sans rapport. */
.site-stat-grid div {
  min-height: 88px;
  gap: 6px;
  align-content: center;
}

/* Sous 620 px, deux colonnes de chiffres deviennent illisibles. */
@media (max-width: 620px) {
  .site-stat-grid,
  .admin-gate-grid,
  .admin-grid {
    grid-template-columns: 1fr;
  }
}

/* ── Tableaux des pages légales ───────────────────────────────────── */
/* Un tableau à trois colonnes ne rétrécit pas indéfiniment : il défile
   dans son propre cadre, pour que la PAGE, elle, ne défile jamais
   horizontalement. */
.table-scroll {
  overflow-x: auto;
  margin: 4px 0 8px;
  border-radius: var(--radius);
  -webkit-overflow-scrolling: touch;
}

.table-scroll table {
  min-width: 520px;
  width: 100%;
  border-collapse: collapse;
}

.table-scroll th,
.table-scroll td {
  padding: 10px 12px;
  border-bottom: 1px solid var(--line);
  text-align: left;
  vertical-align: top;
  font-size: 0.9rem;
}

.table-scroll th {
  color: var(--soft);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  white-space: nowrap;
}

.table-scroll td { color: var(--muted); }
.table-scroll tr:last-child td { border-bottom: 0; }

/* Liens légaux du pied de page. */
.footer-links {
  margin-top: 6px;
  font-size: 0.86rem;
}

.footer-links a {
  color: var(--muted);
  text-decoration: none;
}

.footer-links a:hover {
  color: var(--text);
  text-decoration: underline;
}

/* ── Barres du haut sur téléphone : lisibles et cliquables ────────── */
/* Constat avant correction, mesuré à 390 px :
     - la barre de l'admin ne faisait que 358 px de large (un retrait de
       32 px pensé pour le bureau, qui ampute un écran déjà étroit) ;
     - ses libellés tombaient à 13,6 px et ses boutons à 36 px de haut,
       contre 16 px et 46 px ailleurs ;
     - la pastille du compte du dashboard faisait 106 × 40 px, avec un
       avatar de 28 px et un chevron de 10 × 7 px, alors que le sélecteur
       de serveur juste en dessous fait 46 px de haut. */
@media (max-width: 760px) {
  /* La barre de l'admin prend toute la largeur, comme celle du dashboard. */
  .admin-page .dashboard-topbar {
    width: 100%;
    border-radius: 0;
  }

  /* Cibles tactiles : 44 px, la taille sous laquelle on rate le bouton.
     Le logo en fait partie : c'est un lien vers l'accueil. */
  .dashboard-topbar .brand {
    min-height: 44px;
  }

  .dashboard-topbar .compact,
  .dashboard-topbar .secondary-btn,
  .dashboard-topbar .primary-btn {
    min-height: 44px;
    font-size: 0.95rem;
  }

  .dashboard-topbar .language-switch {
    min-height: 44px;
  }

  .dashboard-topbar .language-switch select {
    font-size: 0.95rem;
  }

  /* La pastille du compte se met au niveau de ce qui l'entoure. */
  .dashboard-topbar .account-trigger {
    min-height: 44px;
    gap: 8px;
  }

  .dashboard-topbar .account-avatar {
    width: 34px;
    height: 34px;
  }

  .dashboard-topbar .account-label strong {
    font-size: 0.95rem;
  }

  .dashboard-topbar .account-chevron {
    width: 14px;
  }

  /* Le bandeau « Espace actif » de l'admin, meme traitement. */
  .admin-topbar .dashboard-server {
    min-height: 44px;
  }
}

/* ── Barre de l'ecran de choix du serveur, sur telephone ──────────── */
/* Elle mesurait 586 px de large dans un parent de 390 : le logo sortait
   par la gauche (x = -132) et la navigation par la droite (jusqu'a 522).
   La regle qui devait faire passer la navigation a la ligne posait
   `width: 100%`, sans effet : un `flex: 1 1 0%` heritable prend le pas sur
   la largeur pour la taille principale d'un element flexible. Il faut agir
   sur la BASE flexible. */
@media (max-width: 760px) {
  .server-select-topbar {
    width: 100%;
    max-width: 100%;
    flex-wrap: wrap;
    gap: 10px;
    padding: 10px 14px;
  }

  /* Ligne 1 : logo, puis compte et retour pousses a droite. La marge
     evite d'agrandir la zone cliquable du logo. */
  .server-select-brand {
    order: 1;
    flex: 0 0 auto;
    margin-right: auto;
  }

  .server-select-topbar .account-switch { order: 2; flex: 0 0 auto; }
  .server-select-topbar .secondary-btn { order: 3; flex: 0 0 auto; }

  /* Ligne 2 : la navigation, sur toute la largeur, defilante si besoin. */
  .server-select-nav {
    order: 4;
    flex: 1 1 100%;
    width: 100%;
    min-width: 0;
    overflow-x: auto;
  }

  /* La pastille du compte se met au niveau du reste, comme dans la barre
     du dashboard : elle etait a 61 x 42 avec un avatar de 28 px. */
  .server-select-topbar .account-trigger {
    min-height: 44px;
    gap: 8px;
  }

  .server-select-topbar .account-avatar {
    width: 34px;
    height: 34px;
  }

  .server-select-topbar .account-chevron { width: 14px; }

  .server-select-topbar .account-label { display: grid; }
  .server-select-topbar .account-label small { display: none; }

  .server-select-topbar .account-label strong {
    max-width: 30vw;
    font-size: 0.95rem;
  }
}

/* Sous 360 px, le pseudo cede la place : l'avatar suffit a retrouver le menu. */
@media (max-width: 360px) {
  .server-select-topbar .account-label { display: none; }
}

/* ═══════════════════════════════════════════════════════════════════
   ACCÈS ADMINISTRATEUR — connexion Discord réelle
   ═══════════════════════════════════════════════════════════════════ */

.admin-login-panel .discord-login-btn {
  width: 100%;
  margin: 16px 0 4px;
}

/* État de la vérification : attente, refus, erreur */
.admin-gate-state {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin-top: 14px;
  padding: 11px 13px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: var(--bg-soft);
  font-size: 0.86rem;
  line-height: 1.5;
  color: var(--soft);
}

.admin-gate-dot {
  flex: none;
  width: 9px;
  height: 9px;
  margin-top: 6px;
  border-radius: 50%;
  background: var(--muted);
}

.admin-gate-dot[data-level="attente"] {
  background: var(--warn);
  animation: admin-pulse 1.6s ease-in-out infinite;
}

.admin-gate-dot[data-level="refus"]  { background: var(--err); }
.admin-gate-dot[data-level="erreur"] { background: var(--err); }

.admin-gate-state[data-level="refus"] {
  border-color: rgba(237, 66, 69, 0.45);
  background: rgba(237, 66, 69, 0.08);
  color: #ffb3b4;
}

.admin-gate-state[data-level="erreur"] {
  border-color: rgba(232, 163, 61, 0.45);
  background: rgba(232, 163, 61, 0.08);
  color: #f5cf94;
}

@keyframes admin-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.35; }
}

/* Compte Discord connecté */
.admin-identity {
  display: flex;
  align-items: center;
  gap: 11px;
  margin-top: 14px;
  padding: 11px 13px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--panel-strong);
}

.admin-identity img {
  flex: none;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  object-fit: cover;
  background: var(--bg-soft);
}

.admin-identity > div { flex: 1; min-width: 0; }

.admin-identity strong {
  display: block;
  font-size: 0.92rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.admin-identity small {
  display: block;
  color: var(--muted);
  font-size: 0.76rem;
}

/* Explication du fonctionnement */
.admin-steps {
  margin: 12px 0;
  padding-left: 20px;
  font-size: 0.87rem;
  line-height: 1.65;
  color: var(--soft);
}

.admin-steps li { margin-bottom: 6px; }

.admin-steps code,
.admin-access-note code {
  padding: 1px 6px;
  border-radius: 4px;
  background: var(--bg-soft);
  font-size: 0.85em;
  color: var(--text);
}

@media (max-width: 700px) {
  .admin-identity { flex-wrap: wrap; }
  .admin-identity .secondary-btn { width: 100%; }
}

/* ═══════════════════════════════════════════════════════════════════
   ICÔNES ET MARQUES
   Le sprite est inline dans la page ; il ne doit jamais occuper de
   place ni être lu par un lecteur d'écran.
   ═══════════════════════════════════════════════════════════════════ */

.icon-sprite {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

/* ── Icônes des rubriques ───────────────────────────────────────── */

.feature-icon {
  display: inline-grid;
  place-items: center;
  width: 46px;
  height: 46px;
  border-radius: 13px;
  background: var(--accent-soft);
  border: 1px solid var(--accent-line);
  color: var(--purple-2);
  /* Le numéro qui occupait cette place imposait une graisse et une
     taille de texte : on les neutralise. */
  font-size: 0;
  transition: background 0.18s ease, color 0.18s ease, transform 0.18s ease;
}

.feature-icon svg {
  width: 24px;
  height: 24px;
  display: block;
}

.feature-card:hover .feature-icon {
  background: var(--accent);
  color: #fff;
  transform: translateY(-2px);
}

/* ── Logo dans un bouton ────────────────────────────────────────── */

.primary-btn.has-logo,
.secondary-btn.has-logo {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
}

.btn-logo {
  width: 18px;
  height: 18px;
  flex: none;
}

/* ── Bandeau des plateformes relayées ───────────────────────────── */

.integrations {
  padding-top: 8px;
  padding-bottom: 8px;
  text-align: center;
}

.integrations-title {
  margin: 0 0 18px;
  color: var(--muted);
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.integration-list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 10px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.integration {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 10px 18px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--panel);
  color: var(--soft);
  font-size: 0.9rem;
  font-weight: 600;
  transition: border-color 0.18s ease, color 0.18s ease,
              transform 0.18s ease, background 0.18s ease;
}

.integration svg {
  width: 18px;
  height: 18px;
  flex: none;
  /* Gris au repos : la couleur de marque n'arrive qu'au survol, sinon
     cinq logos saturés se disputent l'attention en même temps. */
  color: var(--muted);
  transition: color 0.18s ease;
}

.integration:hover {
  transform: translateY(-2px);
  color: var(--text);
  background: var(--panel-strong);
}

/* Couleurs officielles, au survol seulement */
.integration.is-twitch:hover    { border-color: #9146ff; }
.integration.is-twitch:hover svg    { color: #9146ff; }
.integration.is-tiktok:hover    { border-color: #ff0050; }
.integration.is-tiktok:hover svg    { color: #ff0050; }
.integration.is-instagram:hover { border-color: #e1306c; }
.integration.is-instagram:hover svg { color: #e1306c; }
.integration.is-x:hover         { border-color: #e8ecf4; }
.integration.is-x:hover svg         { color: #e8ecf4; }
.integration.is-discord:hover   { border-color: #5865f2; }
.integration.is-discord:hover svg   { color: #5865f2; }

/* ── Logos de marque dans le dashboard (cartes réseaux) ─────────── */

.social-icon {
  display: inline-grid;
  place-items: center;
  width: 40px;
  height: 40px;
  flex: none;
  border-radius: 11px;
  background: var(--bg-soft);
  border: 1px solid var(--line);
  font-size: 0;
}

.social-icon svg {
  width: 20px;
  height: 20px;
  display: block;
}

.social-icon.brand-twitch    { color: #9146ff; background: rgba(145, 70, 255, 0.12); border-color: rgba(145, 70, 255, 0.32); }
.social-icon.brand-tiktok    { color: #ff0050; background: rgba(255, 0, 80, 0.10);   border-color: rgba(255, 0, 80, 0.30); }
.social-icon.brand-instagram { color: #e1306c; background: rgba(225, 48, 108, 0.11); border-color: rgba(225, 48, 108, 0.30); }
.social-icon.brand-x         { color: #e8ecf4; background: rgba(232, 236, 244, 0.08); border-color: rgba(232, 236, 244, 0.22); }
.social-icon.brand-youtube   { color: #ff0000; background: rgba(255, 0, 0, 0.10);     border-color: rgba(255, 0, 0, 0.30); }

@media (prefers-reduced-motion: reduce) {
  .feature-card:hover .feature-icon,
  .integration:hover { transform: none; }
}

@media (max-width: 560px) {
  .integration { padding: 8px 14px; font-size: 0.84rem; }
  .integration svg { width: 16px; height: 16px; }
  .integrations-title { font-size: 0.76rem; }
}

/* ═══════════════════════════════════════════════════════════════════
   SYMBOLES D'INTERFACE
   Ils remplacent les emoji : ceux-ci changeaient de dessin d'un système
   à l'autre, n'héritaient pas de la couleur du texte, et leur graisse
   ne s'accordait à rien. Un tracé suit la couleur et la taille de son
   libellé, partout pareil.
   ═══════════════════════════════════════════════════════════════════ */

.ui-icon {
  width: 1.05em;
  height: 1.05em;
  flex: none;
  /* Alignement sur la ligne de base du texte voisin : sans ce décalage
     l'icône flotte trop haut à côté d'une majuscule. */
  vertical-align: -0.16em;
  color: inherit;
}

/* Un titre porte son symbole un peu plus grand, et légèrement en retrait */
h2 > .ui-icon,
h3 > .ui-icon,
.panel-title h2 > .ui-icon {
  width: 1.1em;
  height: 1.1em;
  margin-right: 0.42em;
  color: var(--purple-2);
}

/* ── La navigation du dashboard ecrit d'une seule main ──────────────── */
/*
   Une rubrique sur deux porte son libelle dans un <span> — c'est ce
   qu'exige la traduction quand le symbole occupe deja le premier. Sans
   cette regle, ce <span> heritait de la pastille : taille differente,
   boite de 22 px, texte coupe. On fixe donc le libelle lui-meme, plutot
   que de compter sur ce que l'entree lui transmet.
*/
.dash-nav > span:not([aria-hidden="true"]),
.admin-nav > span:not(:first-child) {
  display: inline;
  min-width: 0;
  width: auto;
  height: auto;
  margin: 0;
  padding: 0;
  border-radius: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
}

/* Le libelle du menu deroulant des petits ecrans nomme la rubrique
   ouverte : c'est un nom, pas une mise en avant. */
.sidebar-toggle-label strong { font-weight: 500; }

/* ═══════════════════════════════════════════════════════════════════
   LE WIKI SE LIT
   Une documentation grise et compacte ne se lit pas, elle se survole.
   Ce bloc lui donne des reperes : un numero par chapitre, une puce
   coloree, une mesure de ligne, et un sommaire qui dit ou l'on est.
   ═══════════════════════════════════════════════════════════════════ */

.wiki-content { counter-reset: chapitre; }

.wiki-section { counter-increment: chapitre; }

/* Le numero du chapitre, dans la marge du titre. Il donne un rythme a
   treize sections qui se ressemblaient toutes. */
.wiki-section > h2 {
  display: flex;
  align-items: baseline;
  gap: 12px;
  margin-bottom: 14px;
  font-size: clamp(1.35rem, 2.4vw, 1.7rem);
  line-height: 1.25;
}
.wiki-section > h2::before {
  content: counter(chapitre, decimal-leading-zero);
  flex: none;
  color: var(--purple-2, #b794ff);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  opacity: 0.85;
}

/* Le titre reste sous la barre du haut quand on vient du sommaire. */
.wiki-section { scroll-margin-top: 104px; }

/* Une ligne de quatre-vingt-dix caracteres se relit deux fois. On la
   ramene a ce que l'oeil suit sans se perdre. */
.wiki-section > p,
.wiki-section > .wiki-check-list {
  max-width: 74ch;
}

/* Le premier paragraphe annonce le chapitre : il se lit d'abord. */
.wiki-section > h2 + p {
  color: var(--text);
  font-size: 1.02rem;
}

.wiki-check-list li {
  padding-left: 4px;
}
.wiki-check-list li::marker {
  color: var(--purple-2, #b794ff);
  content: "▸  ";
}

/* Une commande au milieu d'une phrase doit se voir comme une commande. */
.wiki-section p code,
.wiki-check-list code {
  padding: 2px 7px;
  border: 1px solid rgba(158, 110, 255, 0.22);
  border-radius: 7px;
  background: rgba(139, 92, 246, 0.14);
  color: #dccdff;
  font-size: 0.9em;
  /* Pas de nowrap : un gabarit comme « {account} est en live, venez le
     voir ! » tenait alors sur une seule ligne de 260 px et sortait de
     l'ecran a 320. Sans lui il se coupe a ses espaces, et une commande
     d'un seul mot ne se coupe de toute facon que si elle ne tient pas. */
  max-width: 100%;
}

@media (max-width: 480px) {
  /* Vingt-six pixels de marge de chaque cote sur un ecran de 320, c'est
     un sixieme de la page rendu a la bordure. */
  .wiki-section { padding: 18px 16px; }
}

.wiki-section strong { color: var(--text); }

/* Le sommaire : le chapitre ouvert se designe par un filet et un fond,
   pas par du gras — le gras elargissait le mot et faisait sauter la
   liste entiere d'une entree a l'autre. */
.wiki-toc a {
  font-weight: 500;
  border-left: 2px solid transparent;
  border-radius: 0 var(--radius) var(--radius) 0;
  transition: background 0.18s ease, color 0.18s ease, border-color 0.18s ease;
}
.wiki-toc a.is-active {
  border-left-color: var(--accent, #8b5cf6);
  background: rgba(139, 92, 246, 0.16);
  color: var(--text);
}

/* ═══════════════════════════════════════════════════════════════════
   LES OUVERTURES
   Une page qui apparait d'un bloc donne l'impression d'un saut ; un
   menu dont tout arrive en meme temps ne se lit pas. Tout ici est
   court — au-dela de trois cents millisecondes, on attend.
   ═══════════════════════════════════════════════════════════════════ */

@keyframes page-ouverture {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}

@keyframes menu-ouverture {
  from { opacity: 0; transform: translateY(-8px) scale(0.98); }
  to   { opacity: 1; transform: none; }
}

@keyframes menu-entree {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: no-preference) {
  /* Une balise <main> qui entre dans la page — au chargement, ou quand
     le dashboard passe d'un ecran a l'autre — monte en fondu. L'anim
     repart d'elle-meme a chaque fois que l'element cesse d'etre
     `hidden` : c'est le passage par display:none qui la relance. */
  main,
  .dashboard-app {
    animation: page-ouverture 380ms cubic-bezier(0.22, 0.7, 0.3, 1) both;
  }

  /* Le menu « Accès » : le panneau s'ouvre, puis ses entrees arrivent
     une par une. Quarante millisecondes d'ecart suffisent a faire lire
     la liste de haut en bas ; au-dela, on attend le dernier bouton. */
  .nav-menu-panel {
    animation: menu-ouverture 200ms cubic-bezier(0.22, 0.7, 0.3, 1) both;
    transform-origin: top right;
  }
  .nav-menu-panel > * {
    animation: menu-entree 240ms cubic-bezier(0.22, 0.7, 0.3, 1) both;
  }
  .nav-menu-panel > *:nth-child(1) { animation-delay: 60ms; }
  .nav-menu-panel > *:nth-child(2) { animation-delay: 100ms; }
  .nav-menu-panel > *:nth-child(3) { animation-delay: 140ms; }
  .nav-menu-panel > *:nth-child(4) { animation-delay: 180ms; }
  .nav-menu-panel > *:nth-child(5) { animation-delay: 220ms; }
  .nav-menu-panel > *:nth-child(6) { animation-delay: 260ms; }
  .nav-menu-panel > *:nth-child(7) { animation-delay: 300ms; }
  .nav-menu-panel > *:nth-child(n + 8) { animation-delay: 340ms; }

  /* Le dashboard change de rubrique : le panneau qui prend la place
     arrive en fondu, sinon le contenu saute d'un coup. */
  .dash-panel:not([hidden]) {
    animation: page-ouverture 260ms cubic-bezier(0.22, 0.7, 0.3, 1) both;
  }
}

/* Le bouton « Nous écrire » terminait la page collé à gauche, sous un
   titre centré. */
.partners-join > .primary-btn {
  display: flex;
  width: fit-content;
  max-width: 100%;
  margin-inline: auto;
}

/* ── Les paliers de niveau ──────────────────────────────────────────── */
/*
   Un palier tient sur une ligne : le niveau, le role, et la croix qui
   l'enleve. Sous 520 px la ligne se plie en deux plutot que d'ecraser
   la liste des roles a soixante pixels.
*/
.recompense-list {
  display: grid;
  gap: 8px;
  margin: 12px 0;
}

.recompense-row {
  display: grid;
  grid-template-columns: 108px minmax(0, 1fr) auto;
  align-items: end;
  gap: 8px;
}

.recompense-row .mini-form { margin: 0; min-width: 0; }
.recompense-row .mini-form.compact span { font-size: 0.76rem; }
.recompense-row > button { align-self: end; min-height: 38px; }

@media (max-width: 520px) {
  .recompense-row {
    grid-template-columns: minmax(0, 1fr) auto;
  }
  .recompense-row .mini-form:first-child { grid-column: 1 / -1; }
}

/* La vie du serveur compte maintenant trois blocs — les niveaux, les
   paliers, puis les anniversaires et le mur. Deux colonnes fixes en
   laissaient un seul, large et vide, sur la deuxieme ligne. */
[data-dashboard-panel="communaute"] .welcome-layout {
  grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr));
}

/* ── Les salons ou un filtre recule ─────────────────────────────────── */
/*
   Trois blocs, mais rarement trois a l'ecran : chacun n'apparait que si
   son filtre est allume. La grille s'adapte donc au nombre visible
   plutot que de reserver trois colonnes dont deux resteraient vides.
*/
.exempt-grille {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr));
  gap: 12px;
  margin-top: 12px;
}

.exempt-bloc h3 { margin: 0 0 8px; font-size: 0.95rem; }
.exempt-bloc .mini-form { margin-bottom: 0; }
/* Un nom de salon Discord tient parfois vingt-cinq caracteres : la
   pastille se coupe plutot que de pousser la colonne. */
.exempt-bloc .variable-chip {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ── L'ecran de choix du serveur ────────────────────────────────────── */
/*
   Ce qu'on vient y faire tient en un geste : reconnaitre son serveur et
   cliquer dessus. Tout le reste doit s'effacer derriere.
*/

/* Une carte se souleve au survol : elle se clique, il faut que ca se
   voie avant de cliquer. */
.server-picker .server-card {
  transition: transform 0.16s ease, border-color 0.16s ease,
              box-shadow 0.16s ease;
}
.server-picker .server-card:hover,
.server-picker .server-card:focus-visible {
  transform: translateY(-2px);
  border-color: var(--accent, #5865f2);
  box-shadow: 0 12px 28px rgba(0, 0, 0, 0.35);
}
@media (prefers-reduced-motion: reduce) {
  .server-picker .server-card:hover,
  .server-picker .server-card:focus-visible { transform: none; }
}

/* Un serveur ou ModBot n'est pas encore installe se distingue d'un coup
   d'oeil : le liseré le dit avant qu'on lise l'etiquette. */
.server-picker .server-card.is-uninstalled { border-style: dashed; }

/* Le nom d'un serveur Discord fait parfois trente caracteres ; le
   compte des membres, jamais. L'un se coupe, l'autre pas. */
.server-card-copy small { white-space: nowrap; }

/* Sur telephone, l'invitation passe sous la recherche : trois boutons
   sur une ligne de 360 px ne laissent plus de place a la recherche. */
@media (max-width: 620px) {
  .server-select-toolbar { grid-template-columns: minmax(0, 1fr); }
  .server-select-toolbar > * { width: 100%; }
  .server-picker-card { width: min(100% - 24px, 1320px); padding: 26px 0; }
}

/* Dans un bouton, l'icône se sépare du libellé sans espace insécable */
.primary-btn > .ui-icon,
.secondary-btn > .ui-icon,
.dash-nav .ui-icon,
.admin-nav .ui-icon,
.log-filter > .ui-icon,
.search-mode > .ui-icon {
  margin-right: 0.5em;
}

/* Les entrées de navigation gardent leur symbole en gris tant qu'elles
   ne sont pas actives : l'accent doit désigner une seule chose. */
.dash-nav .ui-icon,
.admin-nav .ui-icon { color: var(--muted); transition: color 0.16s ease; }
.dash-nav:hover .ui-icon,
.admin-nav:hover .ui-icon { color: var(--soft); }
.dash-nav.is-active .ui-icon,
.admin-nav.is-active .ui-icon { color: var(--purple-2); }

/* Les boutons pleins portent un symbole de la couleur du texte */
.primary-btn > .ui-icon { color: currentColor; }

/* Danger : le symbole prend la teinte de l'action */
.secondary-btn.danger > .ui-icon,
.danger-btn > .ui-icon { color: #ff8b8d; }

/* Les alertes et encarts colorent leur symbole comme leur bordure */
.alert-panel > strong > .ui-icon { color: var(--warn); }
.inline-hint > strong > .ui-icon { color: var(--purple-2); }

/* Le bouton d'envoi de l'assistant est rond : le symbole se centre */
.ai-composer button > .ui-icon {
  margin: 0;
  width: 1.15em;
  height: 1.15em;
  vertical-align: middle;
}

@media (max-width: 560px) {
  .dash-nav .ui-icon,
  .admin-nav .ui-icon { margin-right: 0.35em; }
}

/* ═══════════════════════════════════════════════════════════════════
   PASTILLES D'ÉTAT
   Le point coloré était un emoji (⚪ 🟢 🔴) collé au libellé. Il devient
   une puce dessinée en CSS : même information, une seule teinte par état,
   et un alignement qui ne dépend plus de la police d'emoji du système.
   ═══════════════════════════════════════════════════════════════════ */

.state,
.health-pill,
.admin-badge,
.giveaway-state,
.auth-advanced-badge {
  display: inline-flex;
  align-items: center;
  gap: 7px;
}

.state::before,
.health-pill::before,
.admin-badge::before,
.auth-advanced-badge::before {
  content: "";
  flex: none;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  /* Actif par défaut : c'est l'état le plus fréquent. */
  background: var(--ok);
  box-shadow: 0 0 0 3px rgba(59, 165, 93, 0.16);
}

.state.inactive::before,
.admin-badge:not(.active)::before,
.auth-advanced-badge::before {
  background: var(--muted);
  box-shadow: 0 0 0 3px rgba(139, 149, 167, 0.14);
}

.state.warning::before,
.health-pill.is-warning::before {
  background: var(--warn);
  box-shadow: 0 0 0 3px rgba(232, 163, 61, 0.16);
}

.state.danger::before,
.health-pill.is-locked::before {
  background: var(--err);
  box-shadow: 0 0 0 3px rgba(237, 66, 69, 0.16);
}

/* Le premier <span> vide de .health-pill servait de puce : il n'a plus
   lieu d'être maintenant que ::before s'en charge. */
.health-pill > span:empty { display: none; }

/* Un état qui change doit se voir sans clignoter */
.state::before,
.health-pill::before { transition: background 0.2s ease, box-shadow 0.2s ease; }

@media (prefers-reduced-motion: reduce) {
  .state::before,
  .health-pill::before { transition: none; }
}

/* Un compteur n'est pas un état : « 0 sauvegarde » ne mérite pas de
   pastille verte, qui laisserait croire à une confirmation. */
.state.is-count::before { display: none; }
.state.is-count { gap: 0; }

/* ═══════════════════════════════════════════════════════════════════
   OPTIONS DE TICKET — colonne image
   La ligne portait emoji + libellé + description. Elle porte désormais
   une image, et le libellé peut rester vide : le bot publie alors le
   panneau en boutons, seule forme où Discord accepte un composant sans
   texte.
   ═══════════════════════════════════════════════════════════════════ */

/* La cellule d'image n'est plus un champ d'URL mais un bouton, une
   vignette et un bouton de retrait. */
.option-image-pick {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}

.option-image-pick button {
  white-space: nowrap;
}

.option-thumb {
  width: 32px;
  height: 32px;
  flex: none;
  object-fit: cover;
  border-radius: 6px;
  border: 1px solid var(--line);
  background: var(--panel);
}

/* Un champ laissé vide n'est pas une erreur ici : on le montre comme un
   choix, pas comme un oubli. */
.option-row input:placeholder-shown {
  border-style: dashed;
  border-color: var(--line-strong);
}

/* ═══════════════════════════════════════════════════════════════════
   RELAIS RÉSEAUX — mentions de rôles
   ═══════════════════════════════════════════════════════════════════ */

.social-card [data-social-ping] { font-family: ui-monospace, Menlo, Consolas, monospace; }

.social-card .mini-toggle { margin-top: 4px; }

/* ═══════════════════════════════════════════════════════════════════
   CAPTCHA — actions du dashboard
   ═══════════════════════════════════════════════════════════════════ */

.captcha-actions { margin-top: 14px; }

/* Le masquage des salons change les permissions de tout le serveur :
   le bouton se signale pendant qu'il attend le second clic. */
.captcha-actions .is-confirming {
  border-color: var(--err);
  color: #ff8b8d;
  animation: captcha-attente 1.1s ease-in-out infinite;
}

@keyframes captcha-attente {
  0%, 100% { box-shadow: 0 0 0 0 rgba(237, 66, 69, 0.45); }
  50%      { box-shadow: 0 0 0 6px rgba(237, 66, 69, 0); }
}

@media (prefers-reduced-motion: reduce) {
  .captcha-actions .is-confirming { animation: none; }
}

@media (max-width: 700px) {
  .captcha-actions > button { flex: 1 1 100%; }
  .option-row { flex-wrap: wrap; }
  .option-row .option-image { flex: 1 1 100%; }
}

/* Les auto-roles tiennent en trois champs ; les roles-reactions ont
   besoin de largeur : une ligne y aligne emoji, identifiant, libelle et
   bouton. Dans la colonne de 380px de .welcome-layout, le champ
   d'identifiant tombait a 34px — illisible pour un ID a 18 chiffres. */
.roles-layout {
  display: grid;
  grid-template-columns: minmax(0, 320px) minmax(0, 1fr);
  gap: 16px;
  margin-top: 16px;
  align-items: start;
}

/* Deux colonnes seulement quand la droite reste utilisable. Sous 1280px
   le champ d'identifiant tombait a 75px pour un contenu de 182px : l'ID
   defilait hors de vue pendant qu'on le tapait. */
@media (max-width: 1280px) {
  .roles-layout { grid-template-columns: minmax(0, 1fr); }
}

/* Un identifiant Discord fait 18 chiffres. La colonne ne descend donc
   pas sous 150px ; si la place manque vraiment, c'est la ligne qui
   defile dans son cadre, jamais la page.

   Borne a 761px : sous 760px la ligne s'empile (regle commune aux
   .option-row, .channel-row et .sanction-row). Sans cette borne, la
   specificite de ce selecteur (0,2,0) l'emporterait sur celle de la
   regle d'empilement (0,1,0) et la ligne resterait sur cinq colonnes
   sur telephone. */
@media (min-width: 761px) {
  .roles-layout .reaction-role-row {
    grid-template-columns: 40px 64px minmax(150px, 1fr) minmax(90px, 1fr) auto;
  }
}

.roles-layout [data-reaction-role-list] {
  overflow-x: auto;
}

/* Six cellules depuis que l'image se choisit dans la galerie : numero,
   emoji, image, libelle, description, suppression. La grille n'en
   declarait que cinq, et la sixieme repassait a la ligne. */
.option-row {
  grid-template-columns: 40px 60px minmax(150px, auto) minmax(120px, 1fr) minmax(140px, 1.3fr) auto;
}

@media (max-width: 1100px) {
  .option-row { grid-template-columns: 40px 60px minmax(150px, auto) minmax(0, 1fr) auto; }
  .option-row [data-option-desc] { grid-column: 1 / -1; }
}

/* ═══════════════════════════════════════════════════════════════════
   LISTES DEROULANTES
   Une <option> n'heritait de rien : fond transparent, texte quasi
   blanc. Le navigateur peint la liste ouverte avec SA propre couleur —
   blanche, faute de `color-scheme` — et les entrees devenaient du blanc
   sur blanc. La liste s'ouvrait sur du vide : on ne pouvait pas choisir
   de salon ni de role.
   ═══════════════════════════════════════════════════════════════════ */

:root {
  /* Fait peindre au navigateur ses controles natifs en sombre :
     listes deroulantes, barres de defilement, calendriers. */
  color-scheme: dark;
}

select option,
select optgroup {
  /* Reprecise malgre color-scheme : certains navigateurs peignent la
     liste ouverte avec la couleur du systeme et ignorent l'heritage. */
  background-color: #14101f;
  color: var(--text);
}

select option:disabled {
  color: var(--muted);
}

/* La fleche par defaut disparait avec appearance:none sur certains
   moteurs : on la redessine, pour qu'un select reste reconnaissable
   comme tel a cote d'un champ de saisie. */
select {
  appearance: none;
  -webkit-appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--muted) 50%),
                    linear-gradient(135deg, var(--muted) 50%, transparent 50%);
  background-position: calc(100% - 18px) calc(50% + 2px),
                       calc(100% - 13px) calc(50% + 2px);
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  padding-right: 34px;
  cursor: pointer;
}

/* ═══════════════════════════════════════════════════════════════════
   PALETTE D'EMOJIS
   Posee sur le document, pas dans la ligne : une ligne de tableau a un
   `overflow` qui la couperait, et un `position: relative` de parent la
   decalerait.
   ═══════════════════════════════════════════════════════════════════ */

.emoji-palette {
  position: absolute;
  z-index: 120;
  display: grid;
  grid-template-columns: repeat(10, 1fr);
  gap: 2px;
  width: min(292px, calc(100vw - 16px));
  max-height: 260px;
  overflow-y: auto;
  padding: 8px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: var(--panel);
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.45);
}

.emoji-palette button {
  min-height: 26px;
  padding: 0;
  border: 0;
  border-radius: 6px;
  background: transparent;
  font-size: 1.05rem;
  line-height: 1;
  cursor: pointer;
}

.emoji-palette button:hover,
.emoji-palette button:focus-visible {
  background: var(--accent);
}

.emoji-palette-clear {
  grid-column: 1 / -1;
  margin-top: 6px;
  padding: 6px 0 !important;
  border-top: 1px solid var(--line) !important;
  border-radius: 0 !important;
  color: var(--muted);
  font-size: 0.78rem !important;
}

/* Le champ garde l'air d'un champ, mais se comporte comme un bouton :
   on clique dessus pour ouvrir la palette. */
.emoji-input,
.emoji-input-wide {
  cursor: pointer;
  text-align: center;
}

@media (max-width: 520px) {
  .emoji-palette { grid-template-columns: repeat(8, 1fr); }
}

/* ═══════════════════════════════════════════════════════════════════
   PAGE PREMIUM
   Le haut vend, le bas explique. Deux grilles, une respiration entre
   les deux : personne ne lit une liste de fonctionnalites avant de
   savoir combien ca coute.
   ═══════════════════════════════════════════════════════════════════ */

.premium-shell {
  max-width: 1120px;
  margin: 0 auto;
  padding: 0 20px 80px;
}

.premium-hero { text-align: center; }

.premium-hero h1 {
  margin: 8px 0 14px;
  font-size: clamp(2rem, 5vw, 3.1rem);
  line-height: 1.08;
}

.premium-lead {
  max-width: 62ch;
  margin: 0 auto 28px;
  color: var(--muted);
  font-size: 1.03rem;
}

.premium-state {
  max-width: 520px;
  margin: 0 auto 26px;
  padding: 14px 18px;
  display: grid;
  gap: 4px;
  border: 1px solid rgba(241, 196, 15, 0.35);
  border-radius: var(--radius-lg);
  background: rgba(241, 196, 15, 0.08);
}

.premium-state strong { color: #f7d354; }
.premium-state span { color: var(--muted); font-size: 0.9rem; }

/* ── Les offres ─────────────────────────────────────────────────── */

.premium-offers {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(230px, 100%), 1fr));
  gap: 16px;
  margin-bottom: 24px;
  align-items: stretch;
}

.premium-offer {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 26px 20px 20px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--panel);
  text-align: center;
}

/* L'offre mise en avant se distingue par la bordure, pas par la
   taille : une carte plus grande decale les autres et casse la ligne
   de lecture des prix. */
.premium-offer.is-featured {
  border-color: rgba(241, 196, 15, 0.55);
  box-shadow: 0 0 0 1px rgba(241, 196, 15, 0.18), 0 18px 40px rgba(0, 0, 0, 0.35);
}

.premium-badge {
  position: absolute;
  top: -11px;
  left: 50%;
  transform: translateX(-50%);
  padding: 3px 12px;
  border-radius: 999px;
  background: #f1c40f;
  color: #1a1405;
  font-size: 0.72rem;
  font-weight: 800;
  white-space: nowrap;
}

.premium-offer h3 { margin: 0; font-size: 1.05rem; }

.premium-price {
  margin: 6px 0 0;
  font-size: 2.1rem;
  font-weight: 900;
  line-height: 1;
}

.premium-period { margin: 0; color: var(--muted); font-size: 0.86rem; }

.premium-saving {
  align-self: center;
  margin-top: 4px;
  padding: 2px 10px;
  border-radius: 999px;
  background: rgba(67, 181, 129, 0.16);
  color: #6ee7a8;
  font-size: 0.76rem;
  font-weight: 700;
}

.premium-offer button { margin-top: auto; padding-top: 12px; padding-bottom: 12px; }
.premium-note { max-width: 62ch; margin: 0 auto 8px; }

/* ── Les fonctionnalites ────────────────────────────────────────── */

.premium-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(250px, 100%), 1fr));
  gap: 14px;
  margin-top: 22px;
}

.premium-feature {
  display: grid;
  gap: 8px;
  padding: 20px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--panel);
}

.premium-feature-icon {
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border-radius: 10px;
  background: rgba(241, 196, 15, 0.14);
  color: #f1c40f;
}

.premium-feature h3 { margin: 0; font-size: 0.98rem; }
.premium-feature p { margin: 0; color: var(--muted); font-size: 0.88rem; line-height: 1.5; }

.premium-faq-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
  gap: 14px;
  margin-top: 20px;
}

/* ── LA BOUTIQUE ─────────────────────────────────────────────────── */
/*    Trois rayons, une teinte chacun : violet pour les bots, cyan pour
      les sites, or pour les packs. La teinte colore l'icone, la bordure
      au survol et la carte recommandee — jamais le texte a lire. */

.boutique-shell {
  max-width: 1160px;
  margin: 0 auto;
  padding: 0 20px 90px;
}

.boutique-hero {
  display: grid;
  justify-items: center;
  gap: 16px;
  padding-top: 72px;
  text-align: center;
}

.boutique-hero-tag,
.home-boutique-tag {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  margin: 0;
  padding: 5px 14px;
  border: 1px solid rgba(241, 196, 15, 0.4);
  border-radius: 999px;
  background: rgba(241, 196, 15, 0.1);
  color: #f7d354;
  font-size: 0.76rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.boutique-hero-titre {
  max-width: 17ch;
  margin: 0;
  font-size: clamp(2.2rem, 5.6vw, 3.6rem);
  line-height: 1.04;
  background: linear-gradient(120deg, #ffffff 15%, #f7d354 60%, #f59e0b 95%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.boutique-hero-chapo {
  max-width: 60ch;
  margin: 0;
  color: var(--muted);
  font-size: 1.05rem;
  line-height: 1.6;
}

.boutique-confiance {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px 20px;
  margin: 2px 0 0;
  padding: 0;
  list-style: none;
  color: var(--muted);
  font-size: 0.86rem;
  font-weight: 600;
}

.boutique-confiance li { display: inline-flex; align-items: center; gap: 7px; }
.boutique-confiance .ui-icon { color: #6ee7a8; }

.boutique-rayons {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 12px;
  width: min(760px, 100%);
  margin-top: 18px;
}

.boutique-rayons a {
  display: grid;
  justify-items: center;
  gap: 4px;
  padding: 16px 12px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--panel);
  color: inherit;
  text-decoration: none;
  transition: transform 180ms ease, border-color 180ms ease;
}

.boutique-rayons a:hover,
.boutique-rayons a:focus-visible {
  transform: translateY(-3px);
  border-color: rgba(241, 196, 15, 0.55);
}

.boutique-rayons .ui-icon { width: 22px; height: 22px; color: #f7d354; }
.boutique-rayons span { font-weight: 800; }
.boutique-rayons small { color: var(--muted); font-size: 0.82rem; font-weight: 600; }

.boutique-section { margin-top: 64px; scroll-margin-top: 96px; }

.boutique-grille {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
  gap: 18px;
  margin-top: 26px;
  align-items: stretch;
}

.boutique-carte {
  --teinte: 265 85% 68%;
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 24px 22px 20px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background:
    radial-gradient(120% 60% at 0% 0%, hsl(var(--teinte) / 0.1), transparent 60%),
    var(--panel);
  transition: transform 200ms ease, border-color 200ms ease, box-shadow 200ms ease;
}

.boutique-carte-site { --teinte: 189 86% 58%; }
.boutique-carte-pack { --teinte: 45 93% 60%; }

.boutique-carte:hover {
  transform: translateY(-4px);
  border-color: hsl(var(--teinte) / 0.55);
  box-shadow: 0 22px 44px rgba(0, 0, 0, 0.38);
}

/* La carte recommandee se distingue par sa bordure et sa lueur, pas par
   sa taille : une carte plus grande decalerait la ligne des prix. */
.boutique-carte.is-featured {
  border-color: hsl(var(--teinte) / 0.6);
  box-shadow: 0 0 0 1px hsl(var(--teinte) / 0.22), 0 20px 44px rgba(0, 0, 0, 0.4);
}

.boutique-badge {
  position: absolute;
  top: -11px;
  left: 50%;
  transform: translateX(-50%);
  padding: 3px 12px;
  border-radius: 999px;
  background: hsl(var(--teinte));
  color: #120d02;
  font-size: 0.72rem;
  font-weight: 800;
  white-space: nowrap;
}

.boutique-carte-tete {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.boutique-icone {
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  border-radius: 12px;
  background: hsl(var(--teinte) / 0.15);
  color: hsl(var(--teinte));
}

.boutique-economie {
  padding: 3px 10px;
  border-radius: 999px;
  background: rgba(67, 181, 129, 0.16);
  color: #6ee7a8;
  font-size: 0.76rem;
  font-weight: 800;
}

.boutique-carte h3 { margin: 4px 0 0; font-size: 1.15rem; }
.boutique-resume { margin: 0; color: var(--muted); font-size: 0.9rem; line-height: 1.45; }

.boutique-contenu {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin-top: 2px;
}

.boutique-piece {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 10px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.03);
  font-size: 0.8rem;
  font-weight: 700;
}

.boutique-piece .ui-icon { width: 14px; height: 14px; color: hsl(var(--teinte)); }
.boutique-plus { color: var(--muted); font-weight: 800; }

.boutique-prix {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 10px;
  margin-top: 6px;
}

.boutique-montant { font-size: 2.3rem; font-weight: 900; line-height: 1; }

.boutique-valeur {
  margin: 0;
  color: var(--muted);
  font-size: 0.86rem;
  text-decoration: line-through;
}

.boutique-points {
  display: grid;
  gap: 7px;
  margin: 6px 0 4px;
  padding: 0;
  list-style: none;
  font-size: 0.9rem;
}

.boutique-points li { position: relative; padding-inline-start: 22px; line-height: 1.4; }

.boutique-points li::before {
  content: "";
  position: absolute;
  inset-inline-start: 3px;
  top: 0.42em;
  width: 9px;
  height: 5px;
  border-left: 2px solid #43b581;
  border-bottom: 2px solid #43b581;
  transform: rotate(-45deg);
}

.boutique-delai { margin: 0; color: var(--muted); font-size: 0.8rem; }

/* Cote a cote quand la carte est large, l'un sous l'autre sinon :
   « Carte bancaire » coupe en deux lignes se lit mal. */
.boutique-payer {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(168px, 100%), 1fr));
  gap: 8px;
  margin-top: auto;
  padding-top: 14px;
}

.boutique-carte .boutique-payer button {
  margin-top: 0;
  justify-content: center;
  gap: 8px;
  padding: 11px 10px;
}

.boutique-bientot {
  grid-column: 1 / -1;
  margin: 0;
  color: var(--muted);
  font-size: 0.88rem;
  text-align: center;
}

.boutique-retour {
  max-width: 560px;
  margin: 8px auto 0;
  padding: 14px 18px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--panel);
}

.boutique-retour.is-ok {
  border-color: rgba(67, 181, 129, 0.5);
  background: rgba(67, 181, 129, 0.1);
}

.boutique-shell .premium-note { max-width: 62ch; margin: 30px auto 0; text-align: center; }

/* ── Toujours compris ── */
.boutique-atouts { margin-top: 64px; }

.boutique-atouts-grille {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr));
  gap: 14px;
  margin-top: 24px;
}

.boutique-atouts-grille article {
  display: grid;
  align-content: start;
  gap: 8px;
  padding: 20px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--panel);
}

.boutique-atout-icone {
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border-radius: 10px;
  background: rgba(67, 181, 129, 0.14);
  color: #6ee7a8;
}

.boutique-atouts-grille h3 { margin: 0; font-size: 0.98rem; }
.boutique-atouts-grille p { margin: 0; color: var(--muted); font-size: 0.88rem; line-height: 1.5; }

/* ── Les etapes ── */
.boutique-etapes { margin-top: 64px; }

.boutique-etapes-liste {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr));
  gap: 14px;
  margin: 22px 0 0;
  padding: 0;
  list-style: none;
  counter-reset: etape;
}

.boutique-etapes-liste li {
  position: relative;
  padding: 20px;
  padding-inline-start: 64px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--panel);
  counter-increment: etape;
}

.boutique-etapes-liste li::before {
  content: counter(etape);
  position: absolute;
  inset-inline-start: 20px;
  top: 18px;
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: rgba(241, 196, 15, 0.14);
  color: #f1c40f;
  font-weight: 800;
}

.boutique-etapes-liste p { margin: 6px 0 0; color: var(--muted); font-size: 0.9rem; line-height: 1.5; }

.boutique-shell .premium-faq { margin-top: 64px; }

/* ── Sur devis ── */
.boutique-devis { margin-top: 64px; }

.boutique-devis-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  padding: 28px;
  border: 1px solid rgba(241, 196, 15, 0.35);
  border-radius: var(--radius-lg);
  background:
    linear-gradient(120deg, rgba(241, 196, 15, 0.12), rgba(139, 92, 246, 0.1) 60%, transparent),
    var(--panel);
}

.boutique-devis-inner h2 { margin: 0 0 6px; font-size: 1.35rem; }
.boutique-devis-inner p { max-width: 58ch; margin: 0; color: var(--muted); }
.boutique-devis-inner .primary-btn { gap: 8px; white-space: nowrap; }

/* ── Le compte Discord : connecte, on sait a qui ecrire ── */
.boutique-actions-hero {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
  margin-top: 20px;
}

.boutique-actions-hero a { gap: 8px; }

.boutique-compte {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 10px 14px;
  max-width: 680px;
  margin: 18px auto 0;
  padding: 12px 16px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--panel);
  color: var(--muted);
  font-size: 0.9rem;
  text-align: center;
}

.boutique-compte:empty { display: none; }

.boutique-compte.is-connecte {
  border-color: rgba(88, 101, 242, 0.5);
  background: rgba(88, 101, 242, 0.1);
  color: inherit;
}

.boutique-compte img { width: 28px; height: 28px; border-radius: 50%; }
.boutique-compte .secondary-btn { gap: 8px; }
.boutique-compte a { color: #aab4ff; }

.boutique-compte-lien {
  padding: 0;
  border: 0;
  background: none;
  color: var(--soft);
  font: inherit;
  text-decoration: underline;
  cursor: pointer;
}

.boutique-connecte {
  margin: 0;
  padding: 10px 12px;
  border-radius: 10px;
  background: rgba(88, 101, 242, 0.12);
  font-size: 0.88rem;
}

.boutique-succes {
  margin: 0;
  padding: 10px 12px;
  border-radius: 10px;
  background: rgba(67, 181, 129, 0.12);
  color: #8ff0bd;
  font-size: 0.9rem;
}

/* ── « Ideal pour » : a qui s'adresse chaque formule ── */
.boutique-ideal {
  margin: 0;
  color: var(--muted);
  font-size: 0.86rem;
  line-height: 1.45;
}

.boutique-ideal strong { color: hsl(var(--teinte, 45 93% 60%)); }

/* ── Des exemples concrets ── */
.boutique-exemples { margin-top: 64px; scroll-margin-top: 96px; }

/* Quatre, deux ou une colonne : jamais trois, qui laisserait la
   quatrieme carte seule sur sa ligne. */
.boutique-exemples-grille {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 16px;
  margin-top: 24px;
}

@media (max-width: 1180px) {
  .boutique-exemples-grille { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 620px) {
  .boutique-exemples-grille { grid-template-columns: 1fr; }
}

.boutique-exemple {
  display: grid;
  grid-template-rows: auto auto auto 1fr auto;
  gap: 10px;
  padding: 16px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--panel);
}

.boutique-exemple h3 { margin: 4px 0 0; font-size: 1rem; }
.boutique-exemple > p { margin: 0; color: var(--muted); font-size: 0.88rem; line-height: 1.5; }

.boutique-exemple ul {
  display: grid;
  align-content: start;
  gap: 6px;
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: 0.86rem;
}

.boutique-exemple li { display: flex; align-items: flex-start; gap: 8px; }
.boutique-exemple li::before { content: "✓"; color: #6ee7a8; font-weight: 800; }

.boutique-exemple-formule {
  margin: 0;
  padding-top: 10px;
  border-top: 1px solid var(--line);
  color: #f7d354;
  font-size: 0.84rem;
  font-weight: 700;
}

.boutique-exemple-formule a { color: inherit; text-decoration: none; }
.boutique-exemple-formule a:hover { text-decoration: underline; }

.boutique-exemples-note {
  margin: 14px auto 0;
  max-width: 70ch;
  color: var(--muted);
  font-size: 0.82rem;
  text-align: center;
}

/* Les apercus : dessines en HTML, pas en image — ils suivent la langue
   de la page, et restent nets a toutes les tailles. */
.mk {
  position: relative;
  min-height: 150px;
  padding: 12px;
  overflow: hidden;
  border-radius: 12px;
  background: #313338;
  color: #dbdee1;
  font-size: 0.8rem;
  line-height: 1.4;
}

.mk-message { display: grid; grid-template-columns: 32px minmax(0, 1fr); gap: 10px; }

.mk-avatar {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: linear-gradient(135deg, #8b5cf6, #22d3ee);
}

.mk-nom { color: #fff; font-weight: 700; }

.mk-nom::after {
  content: "BOT";
  margin-inline-start: 6px;
  padding: 1px 4px;
  border-radius: 3px;
  background: #5865f2;
  color: #fff;
  font-size: 0.6rem;
  vertical-align: middle;
}

.mk-embed {
  margin-top: 6px;
  padding: 8px 10px;
  border-inline-start: 4px solid #f1c40f;
  border-radius: 4px;
  background: #2b2d31;
}

.mk-embed.is-vert { border-inline-start-color: #43b581; }
.mk-embed strong { display: block; margin-bottom: 3px; color: #fff; }

.mk-boutons { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }

.mk-bouton {
  padding: 4px 10px;
  border-radius: 4px;
  background: #4e5058;
  color: #fff;
  font-size: 0.72rem;
  font-weight: 600;
}

.mk-bouton.is-rouge { background: #da373c; }
.mk-bouton.is-bleu { background: #5865f2; }
.mk-bouton.is-vert { background: #248046; }

.mk-web { padding: 0; background: #0f1320; }

.mk-barre { display: flex; gap: 5px; padding: 8px 10px; background: #1b2030; }
.mk-barre span { width: 8px; height: 8px; border-radius: 50%; background: #3a4152; }

.mk-page {
  display: grid;
  justify-items: center;
  gap: 8px;
  padding: 18px 12px;
  background: radial-gradient(circle at 50% 0, rgba(139, 92, 246, 0.35), transparent 70%);
  text-align: center;
}

.mk-page strong { color: #fff; font-size: 1rem; }
.mk-page small { color: #aab0c0; }

.mk-dash { display: grid; grid-template-columns: 64px minmax(0, 1fr); min-height: 126px; }

.mk-dash-menu {
  display: grid;
  align-content: start;
  gap: 7px;
  padding: 12px 8px;
  background: #151a28;
}

.mk-dash-menu span { height: 7px; border-radius: 4px; background: #2c3347; }
.mk-dash-menu span:first-child { background: #8b5cf6; }

.mk-dash-corps { display: grid; align-content: start; gap: 7px; padding: 10px; }
.mk-dash-corps strong { color: #fff; }

.mk-reglage {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 5px 8px;
  border-radius: 6px;
  background: #1b2030;
}

.mk-interrupteur {
  position: relative;
  flex: none;
  width: 26px;
  height: 14px;
  border-radius: 999px;
  background: #43b581;
}

.mk-interrupteur::after {
  content: "";
  position: absolute;
  top: 2px;
  inset-inline-end: 2px;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: #fff;
}

.mk-interrupteur.is-off { background: #4e5058; }
.mk-interrupteur.is-off::after { inset-inline-end: auto; inset-inline-start: 2px; }

.boutique-preuve {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  margin-top: 18px;
  padding: 18px 22px;
  border: 1px solid rgba(139, 92, 246, 0.4);
  border-radius: var(--radius-lg);
  background:
    linear-gradient(120deg, rgba(139, 92, 246, 0.14), transparent 70%),
    var(--panel);
}

.boutique-preuve h3 { margin: 0 0 4px; font-size: 1.05rem; }
.boutique-preuve p { max-width: 60ch; margin: 0; color: var(--muted); font-size: 0.9rem; }
.boutique-preuve .secondary-btn { gap: 8px; white-space: nowrap; }

/* ── La demande sur mesure : un vrai formulaire ── */
.boutique-devis { scroll-margin-top: 96px; }

.boutique-devis-inner.boutique-demande {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.25fr);
  align-items: start;
  gap: 28px;
  text-align: start;
}

.boutique-demande-etapes {
  display: grid;
  gap: 8px;
  margin: 16px 0 0;
  padding: 0;
  list-style: none;
  counter-reset: demande;
}

.boutique-demande-etapes li {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 0.9rem;
  counter-increment: demande;
}

.boutique-demande-etapes li::before {
  content: counter(demande);
  display: grid;
  flex: none;
  place-items: center;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: rgba(241, 196, 15, 0.16);
  color: #f1c40f;
  font-size: 0.8rem;
  font-weight: 800;
}

.boutique-formulaire { display: grid; gap: 12px; }

.boutique-formulaire label {
  display: grid;
  gap: 6px;
  font-size: 0.9rem;
  font-weight: 600;
}

.boutique-formulaire input,
.boutique-formulaire textarea,
.boutique-formulaire select {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.04);
  color: inherit;
  font: inherit;
  font-weight: 500;
  resize: vertical;
}

.boutique-formulaire :is(input, textarea, select):focus {
  outline: 2px solid rgba(241, 196, 15, 0.55);
  outline-offset: 1px;
}

.boutique-formulaire-ligne {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(180px, 100%), 1fr));
  gap: 12px;
}

.boutique-formulaire .primary-btn { justify-self: start; gap: 8px; }

/* La premiere question du sur-mesure : quatre cases numerotees. Le bouton
   radio est cache mais reste atteignable au clavier (fleches, Tab). */
.boutique-choix { min-width: 0; margin: 0; padding: 0; border: 0; }

.boutique-choix legend {
  margin-bottom: 8px;
  padding: 0;
  font-size: 0.9rem;
  font-weight: 600;
}

.boutique-choix-grille {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
}

/* Volontairement SANS le prefixe « .boutique-formulaire » : ces cases
   servent aussi au calculateur de la boutique, qui n'est pas ce
   formulaire-la. Scopees, elles s'y affichaient sans cadre, avec le
   bouton radio d'origine visible au-dessus de la pastille. */
label.boutique-choix-option {
  position: relative;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.03);
  cursor: pointer;
}

.boutique-choix-option input[type="radio"] {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: 0;
  padding: 0;
  opacity: 0;
  pointer-events: none;
}

.boutique-choix-numero {
  display: grid;
  flex: none;
  place-items: center;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: rgba(241, 196, 15, 0.16);
  color: #f1c40f;
  font-weight: 800;
}

.boutique-choix-option input:checked + .boutique-choix-numero { background: #f1c40f; color: #1a1300; }

.boutique-choix-option:has(input:checked) {
  border-color: rgba(241, 196, 15, 0.7);
  background: rgba(241, 196, 15, 0.12);
}

.boutique-choix-option:has(input:focus-visible) {
  outline: 2px solid rgba(241, 196, 15, 0.55);
  outline-offset: 1px;
}

@media (max-width: 420px) {
  .boutique-choix-grille { grid-template-columns: 1fr; }
}

/* Le bloc devis grise ses paragraphes ; pas les messages du formulaire. */
.boutique-devis-inner .boutique-formulaire .boutique-erreur { max-width: none; color: #ff9b9b; }
.boutique-devis-inner .boutique-formulaire .boutique-succes { max-width: none; color: #8ff0bd; }
.boutique-devis-inner .boutique-formulaire .boutique-connecte { max-width: none; color: inherit; }
.boutique-devis-inner .boutique-formulaire .field-help { max-width: none; }

@media (max-width: 860px) {
  .boutique-devis-inner.boutique-demande { grid-template-columns: 1fr; }
}

/* ── Le devis du client, ouvert depuis son lien ── */
.boutique-ton-devis { margin-top: 36px; scroll-margin-top: 96px; }

.boutique-ton-devis-boite {
  display: grid;
  gap: 14px;
  max-width: 640px;
  margin: 0 auto;
  padding: 24px;
  border: 1px solid rgba(241, 196, 15, 0.45);
  border-radius: var(--radius-lg);
  background:
    linear-gradient(135deg, rgba(241, 196, 15, 0.12), transparent 70%),
    var(--panel);
}

.boutique-ton-devis-boite h2 { margin: 0; font-size: 1.3rem; }
.boutique-ton-devis-boite > p { margin: 0; color: var(--muted); }

.boutique-ton-devis-prix { color: #f7d354; font-size: 2rem; font-weight: 800; }

.boutique-ton-devis-boite blockquote {
  margin: 0;
  padding: 10px 14px;
  border-inline-start: 3px solid rgba(241, 196, 15, 0.5);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.03);
  white-space: pre-wrap;
}

.boutique-ton-devis-description { white-space: pre-wrap; font-size: 0.9rem; }
.boutique-ton-devis-pdf { justify-self: start; gap: 8px; }

.boutique-ton-devis-boite .boutique-conditions {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  font-size: 0.9rem;
  line-height: 1.45;
}

/* ── L'assistance ── */
.boutique-aide { margin-top: 64px; scroll-margin-top: 96px; }

.boutique-aide-grille {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr));
  gap: 14px;
  margin-top: 24px;
}

.boutique-aide-grille article {
  display: grid;
  align-content: start;
  gap: 8px;
  padding: 20px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--panel);
}

.boutique-aide-grille h3 { margin: 0; font-size: 0.98rem; }
.boutique-aide-grille p { margin: 0; color: var(--muted); font-size: 0.88rem; line-height: 1.5; }
.boutique-aide-grille a { justify-self: start; color: #7dd3fc; font-size: 0.88rem; font-weight: 700; }

.boutique-aide-icone {
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border-radius: 10px;
  background: rgba(34, 211, 238, 0.14);
  color: #67e8f9;
}

.boutique-aide-formulaire {
  margin-top: 14px;
  padding: 22px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--panel);
}

.boutique-aide-formulaire h3 { margin: 0 0 4px; font-size: 1.05rem; }

/* ── Achats & paiements, dans l'administration ── */
.btq-compteurs {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(150px, 100%), 1fr));
  gap: 10px;
  margin: 16px 0 4px;
}

.btq-compteurs div {
  display: grid;
  gap: 2px;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--panel);
}

.btq-compteurs strong { font-size: 1.35rem; }
.btq-compteurs span { color: var(--muted); font-size: 0.8rem; }

.btq-onglets { display: flex; flex-wrap: wrap; gap: 8px; margin: 18px 0 12px; }

.btq-onglet {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: transparent;
  color: var(--muted);
  font: inherit;
  font-weight: 700;
  cursor: pointer;
}

.btq-onglet.is-active {
  border-color: rgba(241, 196, 15, 0.6);
  background: rgba(241, 196, 15, 0.14);
  color: #f7d354;
}

.btq-nombre {
  min-width: 22px;
  padding: 1px 7px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.08);
  font-size: 0.75rem;
  text-align: center;
}

.btq-nombre:empty { display: none; }

.btq-liste { display: grid; gap: 12px; }

.btq-fiche {
  display: grid;
  gap: 10px;
  padding: 16px 18px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--panel);
}

.btq-fiche-tete { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px; }
.btq-ident { display: grid; gap: 2px; min-width: 0; margin-inline-end: auto; }
.btq-ident code { color: var(--soft); font-size: 0.78rem; letter-spacing: 0.04em; }
.btq-montant { color: #f7d354; font-weight: 800; white-space: nowrap; }

.btq-tag {
  padding: 3px 11px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.06);
  color: var(--muted);
  font-size: 0.72rem;
  font-weight: 800;
  white-space: nowrap;
}

/* Orange : ce qui attend l'equipe. Violet : en travail. Bleu : programme
   ou chiffre. Vert : fait. Gris : termine sans suite. */
.btq-tag[data-statut="payee"],
.btq-tag[data-statut="d-nouveau"],
.btq-tag[data-statut="s-ouvert"] { background: hsl(34 92% 60% / 0.18); color: hsl(34 92% 68%); }
.btq-tag[data-statut="en_cours"] { background: hsl(265 85% 68% / 0.18); color: hsl(265 85% 80%); }
.btq-tag[data-statut="planifiee"],
.btq-tag[data-statut="d-propose"] { background: hsl(210 90% 60% / 0.18); color: hsl(210 90% 74%); }
.btq-tag[data-statut="attente"] { background: hsl(45 93% 60% / 0.16); color: hsl(45 93% 68%); }
.btq-tag[data-statut="livree"],
.btq-tag[data-statut="d-payee"],
.btq-tag[data-statut="s-repondu"] { background: hsl(142 62% 52% / 0.16); color: hsl(142 62% 64%); }

.btq-meta { margin: 0; color: var(--muted); font-size: 0.84rem; line-height: 1.5; }
.btq-meta b { color: var(--text, #fff); }

.btq-texte {
  margin: 0;
  padding: 10px 12px;
  border-inline-start: 3px solid rgba(241, 196, 15, 0.45);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.03);
  font-size: 0.9rem;
  line-height: 1.5;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.btq-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }

.btq-jours {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  padding: 4px;
  padding-inline-start: 10px;
  border: 1px solid var(--line);
  border-radius: 12px;
}

.btq-jours label { display: inline-flex; align-items: center; gap: 6px; color: var(--muted); font-size: 0.85rem; }

.btq-jours input {
  width: 64px;
  padding: 6px 8px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.04);
  color: inherit;
  font: inherit;
}

.btq-formulaire { display: grid; gap: 8px; }

.btq-formulaire input,
.btq-formulaire textarea {
  width: 100%;
  padding: 9px 11px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.04);
  color: inherit;
  font: inherit;
  resize: vertical;
}

.btq-formulaire input { max-width: 240px; }

.btq-lien { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 0; color: var(--muted); font-size: 0.84rem; }
.btq-lien a { color: #f7d354; overflow-wrap: anywhere; }

.btq-suivi summary { color: var(--soft); font-size: 0.84rem; cursor: pointer; }

.btq-suivi ol,
.btq-reponses {
  display: grid;
  gap: 6px;
  margin: 8px 0 0;
  padding-inline-start: 18px;
  color: var(--muted);
  font-size: 0.84rem;
}

.btq-suivi time,
.btq-reponses time { color: var(--soft); }
.btq-reponses p { margin: 4px 0 0; color: inherit; white-space: pre-wrap; overflow-wrap: anywhere; }
.btq-suivi em,
.btq-reponses em { color: #ff9b9b; font-style: normal; }

/* Le champ Discord des formulaires : range comme ses voisins, et
   vraiment cache quand le client est connecte — un `display` pose ici
   l'emporterait sinon sur l'attribut `hidden`. */
[data-boutique-contact] { display: grid; gap: 12px; }
[data-boutique-contact][hidden],
.boutique-ton-devis[hidden] { display: none; }

@media (max-width: 640px) {
  .boutique-hero { padding-top: 48px; }
  .boutique-rayons { grid-template-columns: 1fr; }
  .boutique-devis-inner { justify-content: center; text-align: center; }
}

@media (prefers-reduced-motion: reduce) {
  .boutique-carte,
  .boutique-rayons a { transition: none; }
  .boutique-carte:hover,
  .boutique-rayons a:hover { transform: none; }
}

/* ── L'accueil : la boutique, juste apres le partenaire principal ── */
.home-boutique { padding-top: 0; }

.home-boutique-inner {
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr) auto;
  align-items: center;
  gap: 22px;
  padding: 24px 26px;
  border: 1px solid rgba(241, 196, 15, 0.32);
  border-radius: var(--radius-lg);
  background:
    linear-gradient(115deg, rgba(241, 196, 15, 0.1), rgba(139, 92, 246, 0.08) 55%, transparent 90%),
    var(--panel);
}

.home-boutique-texte h2 { margin: 10px 0 6px; font-size: 1.45rem; }
.home-boutique-texte p { margin: 0; color: var(--muted); font-size: 0.93rem; line-height: 1.5; }

.home-boutique-apercu {
  display: grid;
  gap: 8px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.home-boutique-apercu li {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.03);
  font-size: 0.88rem;
  font-weight: 700;
}

.home-boutique-apercu .ui-icon { width: 16px; height: 16px; color: #f7d354; }
.home-boutique-apercu strong { margin-inline-start: auto; color: #f7d354; font-weight: 800; white-space: nowrap; }

.home-boutique-bouton { gap: 8px; white-space: nowrap; }
/* La fleche du bouton pointe vers l'avant du texte : a droite, sauf en
   arabe, ou l'on lit de droite a gauche. */
html:not([dir="rtl"]) .home-boutique-bouton .ui-icon { transform: scaleX(-1); }

@media (max-width: 900px) {
  .home-boutique-inner {
    grid-template-columns: 1fr;
    justify-items: center;
    text-align: center;
  }
  .home-boutique-apercu { width: min(360px, 100%); }
}

/* ── Le bouton « Boutique » de la barre du haut ── */
.nav-links a.nav-boutique {
  gap: 7px;
  border-color: rgba(241, 196, 15, 0.55);
  background: linear-gradient(135deg, rgba(241, 196, 15, 0.22), rgba(245, 158, 11, 0.1));
  color: #f7d354;
  font-weight: 700;
}

.nav-links a.nav-boutique:hover,
.nav-links a.nav-boutique:focus-visible,
.nav-links a.nav-boutique[aria-current="page"] {
  border-color: rgba(241, 196, 15, 0.85);
  background: linear-gradient(135deg, rgba(241, 196, 15, 0.34), rgba(245, 158, 11, 0.18));
  color: #fff3c4;
}

.nav-links a.nav-boutique .ui-icon { width: 16px; height: 16px; }

/* La fenetre de commande. Opaque : un formulaire de paiement lu a
   travers le decor anime ne donnerait pas confiance. */
.boutique-fenetre {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: grid;
  place-items: center;
  padding: 16px;
}

.boutique-fenetre[hidden] { display: none; }

.boutique-fenetre-fond {
  position: absolute;
  inset: 0;
  background: rgba(5, 8, 14, 0.74);
  backdrop-filter: blur(4px);
}

.boutique-fenetre-boite {
  position: relative;
  display: grid;
  gap: 12px;
  width: min(480px, 100%);
  max-height: calc(100vh - 32px);
  overflow: auto;
  padding: 26px 22px 20px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: rgb(20, 24, 33);
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.5);
}

.boutique-fenetre-boite h2 { margin: 0; font-size: 1.25rem; }
.boutique-recap { margin: 0; color: var(--muted); }

.boutique-fenetre-boite label {
  display: grid;
  gap: 6px;
  font-size: 0.9rem;
  font-weight: 600;
}

.boutique-fenetre-boite input[type="text"],
.boutique-fenetre-boite textarea {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.04);
  color: inherit;
  font: inherit;
  font-weight: 500;
  resize: vertical;
}

.boutique-fenetre-boite input[type="text"]:focus,
.boutique-fenetre-boite textarea:focus {
  outline: 2px solid rgba(241, 196, 15, 0.55);
  outline-offset: 1px;
}

.boutique-fenetre-boite .boutique-conditions {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  font-weight: 500;
  line-height: 1.45;
}

.boutique-conditions input { margin-top: 3px; flex: none; }
.boutique-conditions a { color: #f7d354; }

.boutique-erreur {
  margin: 0;
  padding: 10px 12px;
  border-radius: 10px;
  background: rgba(240, 71, 71, 0.12);
  color: #ff9b9b;
  font-size: 0.88rem;
}

.boutique-fenetre-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 10px;
}

.boutique-fenetre-x {
  position: absolute;
  top: 10px;
  inset-inline-end: 10px;
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border: 0;
  border-radius: 10px;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
}

.boutique-fenetre-x:hover { background: rgba(255, 255, 255, 0.06); color: inherit; }

body.boutique-fenetre-ouverte { overflow: hidden; }

.premium-faq-grid article {
  padding: 18px 20px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--panel);
}

.premium-faq-grid h3 { margin: 0 0 6px; font-size: 0.95rem; }
.premium-faq-grid p { margin: 0; color: var(--muted); font-size: 0.88rem; line-height: 1.55; }

.nav-premium-btn { border-color: rgba(241, 196, 15, 0.4) !important; }
.nav-premium-btn .ui-icon { color: #f1c40f; }

@media (max-width: 640px) {
  .premium-shell { padding: 0 14px 60px; }
  .premium-offers { grid-template-columns: 1fr; }
}

/* ═══════════════════════════════════════════════════════════════════
   VERROUS PREMIUM
   Le reglage reste visible et modifiable : on prepare sa configuration
   avant de payer. Le bandeau dit seulement que rien ne s'appliquera
   d'ici la.
   ═══════════════════════════════════════════════════════════════════ */

.premium-lock {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 14px;
  margin: 0 0 18px;
  padding: 14px 18px;
  border: 1px solid rgba(241, 196, 15, 0.35);
  border-radius: var(--radius-lg);
  background: rgba(241, 196, 15, 0.07);
}

.premium-lock-icon {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border-radius: 10px;
  background: rgba(241, 196, 15, 0.16);
  color: #f1c40f;
}

.premium-lock strong { display: block; color: #f7d354; font-size: 0.95rem; }
.premium-lock small { display: block; margin-top: 2px; color: var(--muted); line-height: 1.5; }
.premium-lock .primary-btn { white-space: nowrap; }

/* La pastille de l'onglet : on doit voir le verrou sans ouvrir. */
.dash-nav.is-locked { position: relative; opacity: 0.62; }

.dash-nav.is-locked::after {
  content: "";
  width: 6px;
  height: 6px;
  margin-left: auto;
  border-radius: 50%;
  background: #f1c40f;
  flex: none;
}

@media (max-width: 640px) {
  .premium-lock {
    grid-template-columns: auto 1fr;
    row-gap: 10px;
  }
  .premium-lock .primary-btn { grid-column: 1 / -1; justify-content: center; }
}

/* ═══════════════════════════════════════════════════════════════════
   MENU D'ACCES
   ═══════════════════════════════════════════════════════════════════ */

.nav-menu { position: relative; }

/* Les boutons de la barre — « Support Discord », « Ajouter ModBot » et
   « Acces » — forment un ensemble : meme hauteur, meme pilule, le fond
   de la page et un filet gris. Le violet plein est reserve aux appels a
   l'action dans le corps des pages, ou il ne fait pas concurrence a la
   navigation. */
/* Toute la barre est faite de pilules : les ancres de navigation, le
   bouton Discord et le menu « Acces » se ressemblent parce qu'ils font
   la meme chose — mener quelque part. Rien n'y crie plus fort que le
   reste, et l'oeil n'a plus a trier deux familles de formes.

   Le selecteur passe par `.nav-links a` (0-1-1) : la regle de couleur
   des liens, ecrite plus haut avec cette meme specificite, gagnerait
   sinon sur un simple `.nav-cta` (0-1-0). */
.nav-links a,
.nav-links a.nav-cta,
.nav-menu-trigger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 40px;
  /* La hauteur vient de min-height, pas d'un rembourrage vertical :
     sinon chaque bouton la calculait a sa facon et « Acces » depassait
     ses voisins de quatre pixels. */
  padding: 0 16px;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: var(--panel);
  color: var(--text);
  font-weight: 750;
  font-size: 0.92rem;
  letter-spacing: 0;
  box-shadow: none;
  transition: border-color 160ms ease, background-color 160ms ease;
}

.nav-links a:hover,
.nav-cta:hover,
.nav-menu-trigger:hover,
.nav-menu.is-open .nav-menu-trigger {
  border-color: var(--accent-line);
  background: var(--panel-strong);
  transform: none;
  box-shadow: none;
}

.nav-menu-trigger {
  gap: 8px;
  cursor: pointer;
}

.nav-menu-trigger:hover,
.nav-menu.is-open .nav-menu-trigger {
  border-color: var(--accent);
}

.nav-menu-chevron {
  width: 11px;
  transition: transform 0.18s ease;
}

.nav-menu.is-open .nav-menu-chevron { transform: rotate(180deg); }

.nav-menu-panel {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  z-index: 90;
  display: grid;
  gap: 2px;
  min-width: 232px;
  padding: 8px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-lg);
  background: var(--panel);
  box-shadow: 0 20px 46px rgba(0, 0, 0, 0.45);
}

.nav-menu-panel a,
.nav-menu-lang {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border-radius: var(--radius);
  color: var(--text);
  font-size: 0.92rem;
  font-weight: 650;
  text-decoration: none;
}

.nav-menu-panel a:hover { background: rgba(158, 110, 255, 0.14); }

/* « Revenir au site » n'est pas une destination de meme nature que le
   dashboard ou l'admin : un filet l'en separe, comme la ligne qui
   isole deja le choix de la langue en bas du menu. */
.nav-menu-home {
  margin-bottom: 6px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--line);
  border-radius: 8px 8px 0 0;
}
.nav-menu-panel .ui-icon { color: var(--muted); flex: none; }
.nav-menu-panel a:hover .ui-icon { color: var(--accent); }

.nav-menu-lang {
  justify-content: space-between;
  margin-top: 4px;
  border-top: 1px solid var(--line);
  border-radius: 0;
  padding-top: 12px;
}

.nav-menu-lang > span {
  display: flex;
  align-items: center;
  gap: 10px;
}

.nav-menu-lang select {
  min-width: 108px;
  padding: 6px 30px 6px 10px;
  font-size: 0.86rem;
}

/* Sur telephone, le menu s'etale au lieu de flotter : une liste
   ancree a droite deborderait de l'ecran. */
@media (max-width: 640px) {
  .nav-menu { width: 100%; }
  .nav-menu-trigger { width: 100%; justify-content: center; }
  .nav-menu-panel { position: static; width: 100%; box-shadow: none; margin-top: 8px; }
}

/* ═══════════════════════════════════════════════════════════════════
   DEMO
   Un seul ecran : ce que le membre voit. Le journal du bot occupait la
   moitie de la place pour un public qui n'est pas celui de l'accueil.
   ═══════════════════════════════════════════════════════════════════ */

/* La colonne est declaree ici, pas deduite du contenu : avec un simple
   `justify-content: center` la piste prenait sa largeur du contenu, et
   le `width: 100%` de la fenetre se resolvait contre cette largeur —
   chacun attendait l'autre, la fenetre tombait a 194 px et l'entete
   « # salon-test » se retrouvait a l'etroit. */
/* La fenetre a gauche, les commandes a droite. Elles etaient dessous,
   sur toute la largeur : une commande de douze caracteres par ligne de
   douze cents pixels, et il fallait remonter apres chaque clic pour
   voir la reponse. Cote a cote, on clique et on lit sans bouger. */
.demo-duo {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 288px;
  gap: 18px;
  align-items: start;
}

.demo-duo .discord-window {
  min-height: 430px;
}

.demo-duo .demo-controls {
  max-height: 430px;
  padding: 12px;
  border: 1px solid rgba(158, 110, 255, 0.2);
  border-radius: var(--radius-lg);
  background: rgba(11, 7, 24, 0.6);
}
.demo-duo .demo-group { background: transparent; }

@media (max-width: 980px) {
  /* Empilees, les commandes reprennent deux colonnes : c'est deja ce
     que prevoit la regle des petits ecrans plus haut. */
  .demo-duo { grid-template-columns: minmax(0, 1fr); }
  .demo-duo .discord-window { min-height: 260px; }
  .demo-duo .demo-controls { max-height: 300px; }
}

/* ═══════════════════════════════════════════════════════════════════
   PARTENAIRES
   ═══════════════════════════════════════════════════════════════════ */

.partners-shell { max-width: 1080px; margin: 0 auto; padding: 0 20px 80px; }
.partners-hero { text-align: center; }
.partners-hero h1 { margin: 8px 0 14px; font-size: clamp(1.9rem, 4.5vw, 2.9rem); }
.partners-lead { max-width: 62ch; margin: 0 auto; color: var(--muted); }

.partners-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
  gap: 16px;
  margin-top: 22px;
}

.partner-card {
  display: grid;
  gap: 8px;
  align-content: start;
  padding: 22px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--panel);
}

.partner-card h3 { margin: 0; font-size: 1.12rem; }
.partner-card p { margin: 0; color: var(--muted); font-size: 0.9rem; line-height: 1.6; }
.partner-card .secondary-btn,
.partner-card .primary-btn { margin-top: 8px; justify-self: start; }

.partner-size {
  color: var(--accent) !important;
  font-size: 0.82rem !important;
  font-weight: 700;
}

/* Le partenaire principal se distingue par sa bordure et sa largeur,
   pas par une couleur criarde : c'est une mise en avant, pas une
   publicite. */
.partner-card.is-main {
  border-color: rgba(241, 196, 15, 0.45);
  background: linear-gradient(180deg, rgba(241, 196, 15, 0.06), transparent 60%), var(--panel);
  padding: 28px;
}

.partner-card.is-main h2 { margin: 0 0 10px; font-size: 1.6rem; }

/* Le bandeau de l'accueil */
.main-partner { padding-top: 0; }

.main-partner-inner {
  position: relative;
  overflow: hidden;
  display: grid;
  gap: 8px;
  justify-items: center;
  text-align: center;
  padding: 22px;
  border: 1px solid rgba(241, 196, 15, 0.32);
  border-radius: var(--radius-lg);
  background: linear-gradient(180deg, rgba(241, 196, 15, 0.07), transparent 70%), var(--panel);
}

/* La banniere du serveur, posee en fond. Elle est volontairement
   assourdie : c'est un decor derriere le texte, pas une affiche — le
   nom et les boutons doivent rester lisibles quelle que soit l'image
   que le serveur a choisie. */
.main-partner-banner {
  position: absolute;
  inset: 0 0 auto;
  height: 132px;
  background-position: center;
  background-size: cover;
  opacity: 0.28;
  -webkit-mask-image: linear-gradient(180deg, #000 0%, transparent 100%);
  mask-image: linear-gradient(180deg, #000 0%, transparent 100%);
  pointer-events: none;
}

/* Sans banniere, le bandeau garde exactement l'allure qu'il avait. */
.main-partner-inner:not(.has-banner) .main-partner-banner { display: none; }

.main-partner-inner > *:not(.main-partner-banner) { position: relative; }

.main-partner-logo {
  width: 72px;
  height: 72px;
  margin-bottom: 4px;
  border-radius: 22px;
  border: 1px solid rgba(241, 196, 15, 0.38);
  background: rgba(8, 5, 18, 0.72);
  font-size: 1.2rem;
}

.main-partner-inner .partner-size {
  margin-top: -2px;
  font-size: 0.82rem;
  font-weight: 700;
  color: var(--accent);
}

.main-partner-tag {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 12px;
  border-radius: 999px;
  background: rgba(241, 196, 15, 0.16);
  color: #f7d354;
  font-size: 0.76rem;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.main-partner-inner h2 { margin: 4px 0 0; font-size: 1.5rem; }
.main-partner-inner p { margin: 0; color: var(--muted); font-size: 0.92rem; }

.main-partner-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  justify-content: center;
  margin-top: 8px;
}

@media (max-width: 640px) {
  .partners-shell { padding: 0 14px 60px; }
  .main-partner-actions > a { flex: 1 1 100%; justify-content: center; }
}

/* ═══════════════════════════════════════════════════════════════════
   EVENEMENTS
   Une carte par evenement, pliee comme un formulaire : c'est ce qu'elle
   est. Le badge dit d'un coup d'oeil ce qui est publie et ce qui ne
   l'est pas encore.
   ═══════════════════════════════════════════════════════════════════ */

.event-list {
  display: grid;
  gap: 16px;
  margin-top: 18px;
}

.event-card {
  display: grid;
  gap: 12px;
  padding: 20px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--panel);
}

.event-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--line);
}

.event-card-head strong { font-size: 1.02rem; }
.event-card .search-actions { margin-top: 4px; }

/* ═══════════════════════════════════════════════════════════════════
   CARTES PARTENAIRES
   Le logo vient de Discord, a partir du lien d'invitation deja present
   dans la page : pas de fichier a maintenir, et il suit le serveur
   quand celui-ci change d'avatar. Tant qu'il n'est pas arrive, le
   monogramme tient la place — la carte ne saute pas.
   ═══════════════════════════════════════════════════════════════════ */

.partner-card {
  grid-template-columns: 56px minmax(0, 1fr);
  grid-template-areas:
    "logo tete"
    "corps corps";
  align-items: center;
  column-gap: 14px;
}

/* `.partner-logo` reclame la zone « logo » de la carte partenaire. Le
   bandeau de l'accueil, lui, n'a pas de zones nommees : la grille en
   creait une implicite, passait a deux colonnes et dispersait chaque
   element. La reprise doit etre ecrite ici — plus haut, elle perdait
   contre cette regle, declaree cent lignes plus bas a specificite
   egale. */
.partner-logo.main-partner-logo {
  grid-area: auto;
}

.partner-logo {
  grid-area: logo;
  display: grid;
  place-items: center;
  width: 56px;
  height: 56px;
  overflow: hidden;
  border-radius: 16px;
  border: 1px solid var(--line-strong);
  background: rgba(139, 92, 246, 0.14);
  color: var(--soft);
  font-size: 1.05rem;
  font-weight: 800;
  letter-spacing: 0.02em;
}

.partner-logo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.partner-head { grid-area: tete; display: grid; gap: 2px; align-content: center; }
.partner-body { grid-area: corps; display: grid; gap: 8px; margin-top: 4px; }

.partner-card h2,
.partner-card h3 { margin: 0; }

/* Le compte remplace « 2 400 membres » ecrit en dur : il vient de
   Discord, donc il est juste le jour ou on le lit. */
.partner-size { display: inline-flex; align-items: center; gap: 6px; }
.partner-size.is-live::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #3ba55d;
  box-shadow: 0 0 8px rgba(59, 165, 93, 0.8);
}

.partner-card.is-main .partner-logo { width: 72px; height: 72px; border-radius: 20px; }
.partner-card.is-main { grid-template-columns: 72px minmax(0, 1fr); }

@media (max-width: 560px) {
  .partner-card,
  .partner-card.is-main {
    grid-template-columns: 1fr;
    grid-template-areas: "logo" "tete" "corps";
    justify-items: start;
  }
}

/* ═══════════════════════════════════════════════════════════════════
   PANNEAU VERROUILLE
   Un cadenas qui laisse cliquer n'est pas un cadenas : on donne le
   panneau a lire, jamais a modifier.
   ═══════════════════════════════════════════════════════════════════ */

.dash-panel.is-locked > *:not(.premium-lock) {
  opacity: 0.42;
  filter: grayscale(0.5);
  pointer-events: none;
  user-select: none;
}

.dash-panel.is-locked { position: relative; }

/* ═══════════════════════════════════════════════════════════════════
   RYTHME DES PAGES COURTES
   L'accueil respire sur 72 px parce qu'il est long et qu'on le
   parcourt. Les pages Premium et Partenaires tiennent en trois ou
   quatre blocs : le meme espacement y creusait 144 px de noir entre
   chaque titre, et les boutons paraissaient perdus, trop bas.
   ═══════════════════════════════════════════════════════════════════ */

.premium-page .section-shell,
.partners-page .section-shell {
  padding-top: 40px;
  padding-bottom: 40px;
}

.premium-page main > section:first-child,
.partners-page main > section:first-child {
  padding-top: 64px;
}

.premium-page main > section:last-child,
.partners-page main > section:last-child {
  padding-bottom: 64px;
}

/* Le titre de section colle a son contenu plutot que de flotter. */
.premium-page .section-heading,
.partners-page .section-heading {
  margin-bottom: 18px;
}

/* ═══════════════════════════════════════════════════════════════════
   L'ECHEANCE DU PREMIUM, ET LES CHAMPS QU'IL OUVRE
   ═══════════════════════════════════════════════════════════════════ */

.premium-banner {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 14px;
  margin-bottom: 18px;
  padding: 14px 18px;
  border: 1px solid rgba(241, 196, 15, 0.34);
  border-radius: var(--radius-lg);
  background: linear-gradient(180deg, rgba(241, 196, 15, 0.09), transparent 80%), var(--panel);
}

.premium-banner-icon {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border-radius: 10px;
  background: rgba(241, 196, 15, 0.16);
  color: #f1c40f;
}

.premium-banner-text strong {
  display: block;
  color: #f7d354;
  font-size: 0.98rem;
}

.premium-banner-text small {
  display: block;
  margin-top: 2px;
  color: var(--muted);
  line-height: 1.5;
}

.premium-banner-source {
  padding: 4px 12px;
  border-radius: 999px;
  background: rgba(241, 196, 15, 0.14);
  color: #f7d354;
  font-size: 0.76rem;
  font-weight: 700;
  white-space: nowrap;
}

/* Un champ premium pose au milieu d'une rubrique gratuite. Il se lit,
   il ne se regle pas : le griser sans le desactiver laissait croire
   qu'on pouvait, et le bot refusait ensuite en silence. */
.is-premium-locked {
  position: relative;
  opacity: 0.5;
  filter: grayscale(0.4);
}

.is-premium-locked input,
.is-premium-locked select,
.is-premium-locked textarea,
.is-premium-locked button {
  cursor: not-allowed;
}

.premium-tag {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-top: 6px;
  padding: 2px 9px;
  border-radius: 999px;
  background: rgba(241, 196, 15, 0.18);
  color: #f7d354;
  font-size: 0.68rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  filter: none;
}

@media (max-width: 640px) {
  .premium-banner {
    grid-template-columns: auto minmax(0, 1fr);
  }
  .premium-banner-source { grid-column: 1 / -1; justify-self: start; }
}

/* ═══════════════════════════════════════════════════════════════════
   LES VISITES
   Deux chiffres et quatorze barres. Pas de camembert, pas de courbe
   lissee : on compare des jours entre eux, une barre par jour suffit.
   ═══════════════════════════════════════════════════════════════════ */

.visite-chiffres {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr));
  gap: 14px;
  margin: 18px 0 26px;
}

.visite-carte {
  padding: 20px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--panel);
}

.visite-carte.is-jour {
  border-color: var(--accent-line);
  background: linear-gradient(180deg, rgba(139, 92, 246, 0.09), transparent 70%), var(--panel);
}

.visite-carte strong {
  display: block;
  font-size: 2rem;
  font-weight: 900;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}

.visite-carte span {
  display: block;
  margin-top: 4px;
  color: var(--muted);
  font-size: 0.86rem;
}

/* Le chiffre qui vient de bouger s'annonce une fois, brievement : c'est
   ce qui distingue un compteur vivant d'une capture d'ecran. */
.vient-de-changer {
  animation: visite-pulse 620ms ease;
}

@keyframes visite-pulse {
  0%   { color: var(--accent); transform: scale(1.06); }
  100% { color: inherit; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .vient-de-changer { animation: none; }
}

.visite-sous-titre {
  margin: 0 0 12px;
  color: var(--soft);
  font-size: 0.92rem;
}

.visite-histogramme {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  align-items: end;
  gap: 6px;
  min-height: 150px;
  padding: 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--panel);
  overflow-x: auto;
}

.visite-barre {
  display: grid;
  grid-template-rows: auto 1fr auto;
  align-items: end;
  justify-items: center;
  gap: 5px;
  height: 100%;
  min-width: 28px;
}

.visite-barre i {
  display: block;
  width: 100%;
  max-width: 26px;
  height: var(--part, 4%);
  border-radius: 4px 4px 2px 2px;
  background: linear-gradient(180deg, var(--purple-2), rgba(139, 92, 246, 0.35));
}

.visite-barre-valeur,
.visite-barre-jour {
  color: var(--muted);
  font-size: 0.68rem;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.visite-barre-jour { color: var(--dim, var(--muted)); }

/* Une barre est un bouton : on clique dessus pour corriger le jour. Le
   bouton natif arrive avec un fond et une bordure qui casseraient la
   grille de l'histogramme — on les retire, on garde le curseur. */
button.visite-barre {
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  cursor: pointer;
}

button.visite-barre:hover i,
button.visite-barre:focus-visible i {
  background: linear-gradient(180deg, var(--purple-1, var(--purple-2)), rgba(139, 92, 246, 0.55));
}

/* Un jour corrige a la main se voit : sa barre est rayee. Un chiffre
   retouche qui aurait l'air d'un chiffre mesure serait le contraire de
   ce qu'on cherche. */
.visite-barre.est-corrige i {
  background-image:
    repeating-linear-gradient(135deg,
      rgba(255, 255, 255, 0.28) 0 3px, rgba(255, 255, 255, 0) 3px 7px),
    linear-gradient(180deg, var(--purple-2), rgba(139, 92, 246, 0.35));
}

.visite-barre.est-corrige .visite-barre-valeur::after {
  content: " *";
  color: var(--purple-2);
}

.visite-aide {
  margin: 10px 0 0;
  color: var(--muted);
  font-size: 0.82rem;
  line-height: 1.5;
}

.visite-correction {
  margin-top: 12px;
  padding: 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--panel);
}

.visite-correction h4 {
  margin: 0 0 10px;
  font-size: 0.95rem;
}

.visite-correction-champs {
  display: grid;
  grid-template-columns: minmax(0, 140px) minmax(0, 1fr);
  gap: 10px;
  margin-bottom: 12px;
}

@media (max-width: 640px) {
  .visite-correction-champs { grid-template-columns: minmax(0, 1fr); }
}

.visite-corrections {
  display: grid;
  gap: 8px;
}

.visite-correction-ligne {
  display: grid;
  grid-template-columns: auto auto 1fr;
  align-items: baseline;
  gap: 10px;
  padding: 8px 12px;
  border: 1px solid var(--line);
  border-radius: var(--radius-md, 10px);
  background: var(--panel);
  font-size: 0.82rem;
}

.visite-correction-ligne span {
  color: var(--soft);
  font-variant-numeric: tabular-nums;
}

.visite-correction-ligne small { color: var(--muted); }

@media (max-width: 640px) {
  .visite-correction-ligne { grid-template-columns: minmax(0, 1fr); gap: 2px; }
}

/* ═══════════════════════════════════════════════════════════════════
   LA COULEUR DE CHAQUE DESTINATION

   La teinte suit la destination, pas le rang : les liens ne sont pas
   dans le meme ordre d'une page a l'autre, et un :nth-child aurait
   donne a « Wiki » la couleur de « FAQ » selon la page ou on se trouve.
   Chaque lien porte donc son data-teinte, ecrit dans le HTML.

   Au repos, toute la barre reste sobre. La couleur ne parait qu'au
   survol, au focus clavier, et sur l'entree active : elle sert a
   reperer, pas a decorer.
   ═══════════════════════════════════════════════════════════════════ */

[data-teinte="violet"] { --teinte: 265 85% 68%; }
[data-teinte="cyan"]   { --teinte: 189 86% 58%; }
[data-teinte="rose"]   { --teinte: 330 85% 66%; }
[data-teinte="ambre"]  { --teinte: 34 92% 60%; }
[data-teinte="menthe"] { --teinte: 162 68% 52%; }
[data-teinte="rouge"]  { --teinte: 4 84% 64%; }
[data-teinte="vert"]   { --teinte: 142 62% 52%; }
[data-teinte="or"]     { --teinte: 45 93% 60%; }
[data-teinte="acier"]  { --teinte: 213 22% 66%; }

.nav-links a[data-teinte]:hover,
.nav-links a[data-teinte]:focus-visible {
  border-color: hsl(var(--teinte) / 0.62);
  background: hsl(var(--teinte) / 0.14);
  color: hsl(var(--teinte));
}

/* Dans le menu deroulant, les entrees ne sont pas des pilules : la
   couleur y prend la forme d'un fond et d'un liseré a gauche. */
.nav-menu-panel a[data-teinte]:hover,
.nav-menu-panel a[data-teinte]:focus-visible {
  background: hsl(var(--teinte) / 0.16);
  color: hsl(var(--teinte));
  box-shadow: inset 3px 0 0 hsl(var(--teinte));
}

.nav-menu-panel a[data-teinte]:hover .ui-icon,
.nav-menu-panel a[data-teinte]:focus-visible .ui-icon {
  color: hsl(var(--teinte));
}

/* Le bouton « Acces » ne se confond plus avec ses voisins : il ouvre un
   menu au lieu de mener quelque part, et sa couleur le dit. */
.nav-menu-trigger {
  --teinte: 45 93% 60%;
  border-color: hsl(var(--teinte) / 0.42);
  color: hsl(var(--teinte));
}

.nav-menu-trigger:hover,
.nav-menu-trigger:focus-visible,
.nav-menu.is-open .nav-menu-trigger {
  border-color: hsl(var(--teinte) / 0.75);
  background: hsl(var(--teinte) / 0.16);
  color: hsl(var(--teinte));
}

.nav-menu-trigger .ui-icon,
.nav-menu-chevron { color: currentColor; }

/* Ouvert, le menu montre ses couleurs sans qu'on ait a survoler chaque
   ligne : c'est ce qui permet de trouver « Admin » sans le lire. */
.nav-menu.is-open .nav-menu-panel a[data-teinte] .ui-icon {
  color: hsl(var(--teinte));
}

@media (prefers-reduced-motion: no-preference) {
  .nav-menu-panel a[data-teinte] {
    transition: background-color 140ms var(--ease), color 140ms var(--ease),
                box-shadow 140ms var(--ease);
  }
}

/* L'offre en cours se reconnait sans lire le bandeau : sa carte porte
   le liseré, et son bouton propose de prolonger plutot que de choisir. */
.premium-offer.is-current {
  border-color: hsl(142 62% 52% / 0.55);
  background: linear-gradient(180deg, hsl(142 62% 52% / 0.08), transparent 70%), var(--panel);
}

.premium-offer.is-current::after {
  content: attr(data-badge);
  position: absolute;
  top: 12px;
  right: 12px;
  padding: 2px 10px;
  border-radius: 999px;
  background: hsl(142 62% 52% / 0.18);
  color: hsl(142 62% 62%);
  font-size: 0.68rem;
  font-weight: 800;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.premium-offer { position: relative; }

/* Le grand chiffre est peint en degrade sur texte transparent. Un tiret
   d'attente y devenait un rectangle bleu plein, qu'on prenait pour une
   image cassee. Pendant l'attente, on rend au texte sa couleur. */
.stats-attente .stats-big strong,
.stats-attente .stat-card strong {
  background: none;
  -webkit-text-fill-color: currentColor;
  color: var(--muted);
  opacity: 0.55;
  animation: stats-attente-pulse 1.4s ease-in-out infinite;
}

@keyframes stats-attente-pulse {
  0%, 100% { opacity: 0.32; }
  50%      { opacity: 0.62; }
}

@media (prefers-reduced-motion: reduce) {
  .stats-attente .stats-big strong,
  .stats-attente .stat-card strong { animation: none; }
}

/* ═══════════════════════════════════════════════════════════════════
   L'ACTIVATION D'UNE LICENCE
   Un seul bouton, large, qui ne parait que s'il y a vraiment une place
   a poser. Il doit se voir avant la liste des serveurs — c'est la
   premiere chose a faire apres un achat.
   ═══════════════════════════════════════════════════════════════════ */

.licence-cta { margin: 0 0 18px; }

.licence-cta-button {
  width: 100%;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 16px;
  padding: 18px 22px;
  border: 1px solid hsl(45 93% 60% / 0.42);
  border-radius: var(--radius-lg);
  background: linear-gradient(135deg, hsl(45 93% 60% / 0.14), hsl(45 93% 60% / 0.04));
  color: var(--text);
  text-align: left;
  cursor: pointer;
  transition: border-color 160ms var(--ease), background-color 160ms var(--ease);
}

.licence-cta-button:hover,
.licence-cta-button:focus-visible {
  border-color: hsl(45 93% 60% / 0.8);
  background: linear-gradient(135deg, hsl(45 93% 60% / 0.2), hsl(45 93% 60% / 0.07));
}

.licence-cta-icon {
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  border-radius: 12px;
  background: hsl(45 93% 60% / 0.18);
  color: #f7d354;
}

.licence-cta-texte strong {
  display: block;
  font-size: 1.08rem;
  color: #f7d354;
}

.licence-cta-texte small {
  display: block;
  margin-top: 2px;
  color: var(--muted);
}

.licence-cta-fleche { color: #f7d354; }

.licence-choix-tete {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 16px;
}

.licence-choix-tete strong { display: block; font-size: 1.05rem; }
.licence-choix-tete small { display: block; margin-top: 2px; color: var(--muted); }

.licence-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(240px, 100%), 1fr));
  gap: 12px;
}

.licence-carte {
  display: grid;
  grid-template-columns: 44px minmax(0, 1fr);
  grid-template-areas: "logo nom" "logo action";
  align-items: center;
  gap: 2px 14px;
  padding: 14px 16px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--panel);
  color: var(--text);
  text-align: left;
  cursor: pointer;
  transition: border-color 160ms var(--ease), background-color 160ms var(--ease);
}

.licence-carte:hover,
.licence-carte:focus-visible {
  border-color: hsl(142 62% 52% / 0.6);
  background: var(--panel-strong);
}

.licence-carte-logo {
  grid-area: logo;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  overflow: hidden;
  border-radius: 12px;
  border: 1px solid var(--line);
  background: rgba(139, 92, 246, 0.14);
  font-weight: 800;
}

.licence-carte-logo img { width: 100%; height: 100%; object-fit: cover; }
.licence-carte-nom { grid-area: nom; font-weight: 700; }
.licence-carte-action {
  grid-area: action;
  color: hsl(142 62% 62%);
  font-size: 0.82rem;
  font-weight: 700;
}

@media (max-width: 560px) {
  .licence-cta-button { grid-template-columns: auto minmax(0, 1fr); }
  .licence-cta-fleche { display: none; }
}

/* ═══════════════════════════════════════════════════════════════════
   LES ACHETEURS PREMIUM
   Un identifiant Discord ne dit rien a personne : on montre le visage
   et le pseudo, comme pour les serveurs.
   ═══════════════════════════════════════════════════════════════════ */

.admin-sous-titre {
  margin: 26px 0 4px;
  color: var(--soft);
  font-size: 0.95rem;
}

.admin-buyers {
  display: grid;
  gap: 10px;
  margin-top: 12px;
}

.admin-buyer {
  display: grid;
  grid-template-columns: 42px minmax(0, 1fr) auto;
  align-items: center;
  gap: 14px;
  padding: 12px 16px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--panel);
}

.admin-buyer-avatar {
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  overflow: hidden;
  border-radius: 50%;
  border: 1px solid var(--line-strong);
  background: rgba(139, 92, 246, 0.16);
  font-weight: 800;
  font-size: 0.86rem;
}

.admin-buyer-avatar img { width: 100%; height: 100%; object-fit: cover; }

.admin-buyer-texte strong { display: block; }
.admin-buyer-texte small {
  display: block;
  margin-top: 2px;
  color: var(--muted);
  font-size: 0.8rem;
}

.admin-buyer-serveurs { color: var(--soft) !important; }

.admin-tag {
  padding: 3px 11px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.06);
  color: var(--muted);
  font-size: 0.72rem;
  font-weight: 800;
  white-space: nowrap;
}

/* Une licence payee et jamais posee : c'est celle qu'il faut aller
   aider, elle se voit donc en premier et en couleur. */
.admin-tag.is-dormant {
  background: hsl(34 92% 60% / 0.18);
  color: hsl(34 92% 68%);
}

.admin-tag.is-live {
  background: hsl(142 62% 52% / 0.16);
  color: hsl(142 62% 64%);
}

@media (max-width: 560px) {
  .admin-buyer {
    grid-template-columns: 42px minmax(0, 1fr);
  }
  .admin-tag { grid-column: 2; justify-self: start; }
}

/* ═══════════════════════════════════════════════════════════════════
   LE SCORE DE SECURITE
   Une note, quatre familles, et des conseils tries par ce qu'ils
   rapportent. La couleur suit le rang : elle informe, elle ne decore
   pas.
   ═══════════════════════════════════════════════════════════════════ */

.score-tete {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: 22px;
  margin: 18px 0 24px;
  padding: 22px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--panel);
}

.score-jauge {
  position: relative;
  display: grid;
  place-content: center;
  justify-items: center;
  width: 124px;
  height: 124px;
  border-radius: 50%;
  background: conic-gradient(hsl(var(--teinte, 4 84% 64%)) var(--part, 0%),
                             rgba(255, 255, 255, 0.07) 0);
}

.score-jauge::before {
  content: "";
  position: absolute;
  inset: 9px;
  border-radius: 50%;
  background: var(--panel);
}

.score-jauge strong,
.score-jauge small { position: relative; }

.score-jauge strong {
  font-size: 2.3rem;
  font-weight: 900;
  line-height: 1;
  color: hsl(var(--teinte, 4 84% 64%));
  font-variant-numeric: tabular-nums;
}

.score-jauge small { color: var(--muted); font-size: 0.74rem; }

.score-resume strong { display: block; font-size: 1.2rem; }
.score-resume p { margin: 6px 0 0; color: var(--muted); line-height: 1.6; }

.score-familles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr));
  gap: 12px;
  margin-bottom: 26px;
}

.score-famille {
  display: grid;
  gap: 8px;
  padding: 14px 16px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--panel);
}

.score-famille strong { font-size: 0.92rem; }
.score-famille small { color: var(--muted); font-size: 0.78rem; }

.score-barre {
  display: block;
  height: 6px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.08);
  overflow: hidden;
}

.score-barre i {
  display: block;
  width: var(--part, 0%);
  height: 100%;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--purple-2), var(--cyan));
}

.score-sous-titre { margin: 0 0 12px; font-size: 1rem; }

.score-conseils { display: grid; gap: 10px; }

.score-conseil {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: start;
  gap: 14px;
  padding: 14px 16px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--panel);
}

/* Ce que le conseil rapporte, en premier : c'est ce qui permet de
   choisir quoi faire quand on n'a que dix minutes. */
.score-gain {
  display: grid;
  place-items: center;
  min-width: 42px;
  padding: 4px 10px;
  border-radius: 999px;
  background: hsl(142 62% 52% / 0.16);
  color: hsl(142 62% 62%);
  font-weight: 900;
  font-variant-numeric: tabular-nums;
}

.score-conseil-texte strong { display: block; }
.score-conseil-texte small {
  display: block;
  margin-top: 3px;
  color: var(--muted);
  line-height: 1.6;
}

@media (max-width: 620px) {
  .score-tete { grid-template-columns: 1fr; justify-items: center; text-align: center; }
}

/* ═══════════════════════════════════════════════════════════════════
   LE MOUVEMENT

   Le site portait deja vingt-deux animations. Ce qui manquait n'etait
   pas la quantite, mais deux endroits precis :

     * l'onde au clic ne vivait que sur le dashboard, et seulement sur
       les boutons presents au chargement ;
     * changer de rubrique etait une coupure nette, sans rien entre les
       deux — c'est pourtant le geste le plus repete du produit.

   LE FOND, LUI, N'EST PAS UN OUBLI. Le champ d'etoiles, les trois
   nebuleuses et `body::before` sont eteints plus haut, en
   `display: none !important`, avec la raison ecrite a cote : ils
   nuisaient a la lisibilite et donnaient un rendu « template ». Ce qui
   reste — `body::after` — porte deja `lightSweep`, un balayage toutes
   les neuf secondes. Et une animation en cours l'emporte sur toute
   declaration : y poser un mouvement de plus n'aurait rien fait sans
   d'abord supprimer celui-la. Rallumer le decor est une decision de
   design, pas une correction : elle ne se prend pas ici.

   Tout ce bloc se tait sous « prefers-reduced-motion ». Une animation
   qui continue quand le systeme demande le contraire n'est pas un
   detail de confort : elle rend le site penible, voire inutilisable,
   pour qui en souffre.
   ═══════════════════════════════════════════════════════════════════ */

/* ── Ce qui peut porter une onde doit pouvoir la contenir ─────────── */
/*    `.primary-btn` et `.secondary-btn` le pouvaient deja : position
      relative, overflow cache. Les autres cibles, non — l'onde y
      debordait, ou se posait en haut de la page. */
.nav-action-btn,
.dash-nav,
.admin-nav,
.demo-command,
.variable-chip {
  position: relative;
  overflow: hidden;
}

/* ── Le changement de rubrique ────────────────────────────────────── */
/*    `display: block` seul faisait une coupure. Quarante centiemes de
      seconde suffisent a dire « c'est un autre panneau » sans faire
      attendre. */
.dash-panel.is-active,
.admin-view.is-active {
  animation: rubriqueEntre 0.4s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}

@keyframes rubriqueEntre {
  from {
    opacity: 0;
    transform: translateY(12px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

/* ── Les deux cartes qui n'avaient pas de survol ──────────────────── */
/*    Les cartes de fonctionnalite et de tarif en avaient un ; celles
      des partenaires et du premium, non. Ce sont pourtant les deux
      pages ou l'on vient regarder avant de decider. */
.partner-card,
.premium-feature {
  transition:
    transform 0.28s cubic-bezier(0.2, 0.8, 0.2, 1),
    border-color 0.28s ease,
    box-shadow 0.28s ease;
}

.partner-card:hover,
.premium-feature:hover {
  transform: translateY(-4px);
  border-color: var(--line-strong);
  box-shadow:
    0 20px 44px rgba(0, 0, 0, 0.34),
    0 0 26px rgba(139, 92, 246, 0.16);
}

/* ── LA LUEUR DU FOND, rallumee sur les pages publiques ───────────── */
/*    Elle faisait partie des decorations que le theme eteint plus haut,
      et la raison tient : tout le decor a la fois nuisait a la
      lisibilite. On n'en rallume donc QU'UNE — pas le champ d'etoiles,
      pas les trois nebuleuses — a moitie moins forte, et pas sur le
      dashboard ni l'espace d'administration : on y reste longtemps,
      devant des chiffres et des champs.

      `body:not(.dashboard-page)` dit exactement cela : `admin.html`
      porte les deux classes, il est donc exclu lui aussi.

      Le `!important` n'est pas un caprice : la regle qui eteint la
      lueur en porte un, et rien d'autre ne la rallumerait. */
body:not(.dashboard-page) .page-glow {
  display: block !important;
  opacity: 0.5;
}

/*    Le pointeur est compose DANS la keyframe, pas a cote.

      C'est le piege du jour : une animation en cours l'emporte sur
      toute declaration de la cascade. `.page-glow` porte deja
      `glowMove`, qui pilote `transform` — poser une seconde
      transformation sur l'element n'aurait rien fait, et lui donner la
      place aurait supprime la derive existante. Les deux translations
      s'additionnent donc dans la meme valeur, et la derive lente reste
      exactement ce qu'elle etait.

      Dix-huit pixels : le fond doit se deplacer moins que ce qu'on
      regarde, sinon ce n'est plus un fond. */
@keyframes glowMove {
  from {
    transform: translate3d(
      calc(var(--parallaxe-x, 0) * 18px),
      calc(var(--parallaxe-y, 0) * 18px),
      0) scale(1);
  }
  to {
    transform: translate3d(
      calc(3% + var(--parallaxe-x, 0) * 18px),
      calc(-2% + var(--parallaxe-y, 0) * 18px),
      0) scale(1.08);
  }
}

/* ── LE TITRE DE L'ACCUEIL : un halo qui respire, un reflet qui passe ─ */
/*    Le reflet est un degrade peint DANS les lettres
      (`background-clip: text`), avec une bande lavande qui traverse le
      mot de gauche a droite, puis se tait quatre secondes.

      Le halo ne peut plus etre un `text-shadow`. Avec un texte
      transparent, l'ombre de texte se peint PAR-DESSUS le degrade
      decoupe dans les lettres : le titre virait au lavande terne, loin
      du blanc d'origine. `filter: drop-shadow` s'applique au rendu
      fini, donc derriere lui — mesure a l'ecran, c'est la seule des
      deux versions qui garde le blanc.

      `heroTextEnter` est repete dans la liste, avec son delai de
      0,18 s. Ce selecteur est plus precis que `.hero-copy > *` : un
      `animation` qui l'omettrait remplacerait l'entree, et le titre
      resterait a l'opacite nulle d'ou il part.

      Le tout sous `@supports` : sur un navigateur qui ne sait pas
      decouper un fond dans du texte, un texte transparent serait
      invisible. Il garde alors le titre d'avant, blanc et fixe. */
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  .hero-copy h1 {
    background:
      linear-gradient(100deg,
        #ffffff 0%, #ffffff 38%,
        #d6c6ff 47%,
        #ffffff 56%, #ffffff 100%)
      100% 0 / 260% 100% no-repeat;
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    -webkit-text-fill-color: transparent;
    text-shadow: none;
    filter:
      drop-shadow(0 0 22px rgba(139, 92, 246, 0.55))
      drop-shadow(0 12px 34px rgba(0, 0, 0, 0.55));
    animation:
      heroTextEnter 0.82s cubic-bezier(0.2, 0.8, 0.2, 1) 0.18s forwards,
      haloRespire 6.5s ease-in-out 1.2s infinite alternate,
      refletTitre 7s ease-in-out 2s infinite;
  }
}

@keyframes haloRespire {
  from {
    filter:
      drop-shadow(0 0 22px rgba(139, 92, 246, 0.55))
      drop-shadow(0 12px 34px rgba(0, 0, 0, 0.55));
  }
  to {
    filter:
      drop-shadow(0 0 38px rgba(139, 92, 246, 0.82))
      drop-shadow(0 12px 34px rgba(0, 0, 0, 0.55));
  }
}

/*    La bande est a 47 % d'un degrade large de 260 %. A 100 % puis a
      0 % elle est hors du mot : le debut et la fin du cycle sont donc
      tous deux du blanc pur, et le retour a zero ne se voit pas. */
@keyframes refletTitre {
  0%, 18% {
    background-position: 100% 0;
  }
  46%, 100% {
    background-position: 0% 0;
  }
}

/* ── LE FOND VIVANT : sentinelles, boucliers et eclats ────────────── */
/*    La toile est creee par le JavaScript (`initFondVivant`), sur les
      pages publiques seulement. Fixee, derriere tout ce qui se lit, et
      transparente aux clics : c'est le document qui ecoute, pas elle.

      Le z-index negatif la glisse sous le contenu sans creer de
      contexte d'empilement. Elle passe au-dessus de la lueur, qui la
      precede dans le document, et sous `body::after` — le degrade sobre
      a 22 % d'opacite, qui la voile a peine. */
.fond-vivant {
  position: fixed;
  inset: 0;
  z-index: -1;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

/* ── Le silence, quand le systeme le demande ──────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .dash-panel.is-active,
  .admin-view.is-active {
    animation: none;
  }

  .partner-card,
  .premium-feature {
    transition: none;
  }

  .partner-card:hover,
  .premium-feature:hover {
    transform: none;
  }

  /* La lueur reste visible — c'est un degrade, pas un mouvement — mais
     elle cesse de deriver et ne suit plus le pointeur. */
  body:not(.dashboard-page) .page-glow {
    animation: none;
    transform: none;
  }

  /* Le titre garde son entree et rien d'autre : sans elle il resterait
     a l'opacite nulle d'ou part `.hero-copy > *`. Au repos, le degrade
     est blanc et le halo fixe — le titre d'avant, a l'identique. */
  .hero-copy h1 {
    animation: heroTextEnter 0.82s cubic-bezier(0.2, 0.8, 0.2, 1) 0.18s forwards;
  }

  /* La toile, elle, reste : sous ce reglage le JavaScript la fait passer
     en mode calme — aucun deplacement, seulement des fondus. */

  /* Le JavaScript ne la cree deja plus ; la regle couvre le cas ou le
     reglage change apres le chargement de la page. */
  .button-ripple {
    display: none;
  }
}

/* ═══════════════════════════════════════════════════════════════════
   LA BARRE DU HAUT, AVEC SES ICONES
   Chaque lien porte son icone, a gauche du libelle, comme « Boutique ».
   ═══════════════════════════════════════════════════════════════════ */
.nav-links > a {
  display: inline-flex;
  align-items: center;
  gap: 7px;
}

.nav-links > a .ui-icon {
  flex: none;
  width: 16px;
  height: 16px;
}

/* Dans le tiroir du telephone, les liens gardent toute la largeur. */
@media (max-width: 980px) {
  .nav-links > a { display: flex; gap: 10px; }
}

/* Un libelle de la barre ne se coupe jamais en deux : « Ajouter ModBot »
   passait sur deux lignes des que la place manquait, et gonflait l'en-tete. */
@media (min-width: 981px) {
  .navbar .nav-links > a,
  .navbar .nav-menu-trigger { white-space: nowrap; }
}

/* Grands ecrans : les icones tiennent toutes si l'on resserre un peu les
   pastilles. Sans cela, elles faisaient 1159 px pour 1076 disponibles. */
@media (min-width: 1321px) {
  .navbar .nav-links { gap: 6px; }
  .navbar .nav-links > a,
  .navbar .nav-menu-trigger { padding: 0 11px; font-size: 0.875rem; }
}

/* Entre le tiroir et les grands ecrans : barre compacte, icones effacees
   sauf celle de la boutique. Ce passage debordait deja avant les icones :
   la page glissait de cote a 1000 et 1100 px. */
@media (min-width: 981px) and (max-width: 1320px) {
  .navbar { padding-left: 12px; padding-right: 12px; }
  .navbar .nav-links { gap: 4px; }
  .navbar .nav-links > a,
  .navbar .nav-menu-trigger { padding: 0 10px; font-size: 0.8rem; }
  .navbar .nav-links > a:not(.nav-boutique) .ui-icon { display: none; }
}

/* ── Les cartes acceptees, sur le bouton « Carte bancaire » ── */
.boutique-marques {
  display: inline-flex;
  gap: 4px;
  margin-inline-start: 2px;
}

.boutique-marques svg {
  width: 30px;
  height: 19px;
  border-radius: 3px;
}

/* Le temoin « en direct » du panneau des achats : discret quand tout va
   bien, absent des que le bot ne repond plus — un mensonge vert serait
   pire que rien. */
.admin-panel-outils { display: flex; align-items: center; gap: 10px; }
.btq-direct { display: inline-flex; align-items: center; gap: 6px;
  font-size: 0.78rem; color: var(--text-dim, #8a93a6); white-space: nowrap; }
.btq-pastille { width: 7px; height: 7px; border-radius: 50%;
  background: #43b581; box-shadow: 0 0 0 0 rgba(67, 181, 129, 0.5);
  animation: btq-pouls 2.4s ease-out infinite; }
@keyframes btq-pouls {
  0% { box-shadow: 0 0 0 0 rgba(67, 181, 129, 0.5); }
  70% { box-shadow: 0 0 0 6px rgba(67, 181, 129, 0); }
  100% { box-shadow: 0 0 0 0 rgba(67, 181, 129, 0); }
}
@media (prefers-reduced-motion: reduce) { .btq-pastille { animation: none; } }

/* Le formulaire type de retractation : un texte a recopier tel quel, donc
   une chasse fixe et des retours a la ligne conserves. Il defile seul
   plutot que de pousser la page de cote sur telephone. */
/* Les sections du wiki sont les cases d'une grille, et une case de
   grille ne descend PAS sous la largeur de son contenu tant qu'on ne le
   lui permet pas. Un tableau un peu large suffisait donc a pousser toute
   la section a 574 px dans un telephone de 375 : le texte etait coupe a
   droite sur les conditions, la confidentialite, les mentions et les
   guides. Avec min-width:0 la section suit l'ecran, et ce qui est
   vraiment trop large (un tableau) defile seul dans son cadre. */
.wiki-content { min-width: 0; }
.wiki-content > * { min-width: 0; }
.wiki-code { margin: 14px 0 0; padding: 16px 18px; border-radius: 12px;
  background: rgba(255, 255, 255, 0.04); border: 1px solid rgba(255, 255, 255, 0.08);
  font: 12px/1.7 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  color: var(--text-dim, #aab2c5); white-space: pre; overflow-x: auto;
  max-width: 100%; }

/* ── Le tableau comparatif et le calculateur ────────────────────────────
   Le tableau defile seul quand il ne tient pas : trois colonnes de texte
   sur un telephone, c'est illisible autrement. La premiere colonne reste
   collee a gauche pour qu'on sache toujours quelle ligne on lit. */
.boutique-cmp-onglets { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center;
  margin: 0 0 18px; }
.boutique-cmp-onglet { border: 1px solid rgba(255, 255, 255, 0.12); background: transparent;
  color: var(--text-dim, #aab2c5); border-radius: 999px; padding: 8px 18px;
  font: inherit; font-size: 0.9rem; font-weight: 600; cursor: pointer;
  transition: background 0.18s ease, color 0.18s ease, border-color 0.18s ease; }
.boutique-cmp-onglet:hover { color: #fff; border-color: rgba(255, 255, 255, 0.28); }
.boutique-cmp-onglet.is-active { background: rgba(88, 101, 242, 0.18);
  border-color: rgba(88, 101, 242, 0.55); color: #fff; }
.boutique-cmp-cadre { overflow-x: auto; border-radius: 16px;
  border: 1px solid rgba(255, 255, 255, 0.08); background: rgba(255, 255, 255, 0.03); }
.boutique-cmp { width: 100%; min-width: 620px; border-collapse: collapse; }
.boutique-cmp th, .boutique-cmp td { padding: 14px 16px; text-align: left; vertical-align: top;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06); font-size: 0.92rem; }
.boutique-cmp tbody th { width: 150px; color: var(--text-dim, #aab2c5); font-weight: 600;
  white-space: nowrap; background: rgba(255, 255, 255, 0.02); }
.boutique-cmp thead th { font-size: 1.02rem; color: #fff; }
.boutique-cmp-nom { display: block; }
.boutique-cmp thead .boutique-badge {
  position: static;
  display: inline-block;
  margin-top: 6px;
  /* --teinte n'est declaree que sur les cartes : hors d'elles, la
     pastille se retrouvait noire sur noir. */
  background: var(--or, #f1c40f);
  color: #1a1300;
}
.boutique-cmp-prix { font-size: 1.25rem; color: var(--or, #f1c40f); }
.boutique-cmp-points { margin: 0; padding-left: 18px; }
.boutique-cmp-points li { margin: 0 0 4px; }
.boutique-cmp tfoot td { border-bottom: 0; }

.boutique-calcul-inner { display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
  gap: 22px; align-items: start; }
.boutique-calcul-form { display: grid; gap: 16px; }
.boutique-calcul-resultat { border: 1px solid rgba(255, 255, 255, 0.1); border-radius: 18px;
  padding: 22px; background: rgba(88, 101, 242, 0.08); }
.boutique-calcul-resultat h3 { margin: 4px 0 2px; }
.boutique-calcul-etiquette { margin: 0; font-size: 0.78rem; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--text-dim, #8a93a6); }
.boutique-calcul-montant { margin: 6px 0 2px; font-size: 2rem; font-weight: 800;
  color: var(--or, #f1c40f); }
.boutique-calcul-detail { margin: 0 0 10px; color: var(--text-dim, #aab2c5); font-size: 0.88rem; }
.boutique-calcul-resume { margin: 0 0 16px; }
.boutique-calcul-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 10px; }

@media (max-width: 900px) {
  .boutique-calcul-inner { grid-template-columns: minmax(0, 1fr); }
}

/* ── Options, code promo, total, abonnement, codes de l'administration ──
   Le total est la seule ligne qui compte vraiment dans la fenetre de
   commande : il est gros, et le prix d'avant reste barre a cote pour que
   la remise se voie sans se calculer. */
.boutique-options { border: 1px solid rgba(255, 255, 255, 0.1); border-radius: 14px;
  padding: 12px 14px; margin: 0; }
.boutique-options legend { padding: 0 6px; font-size: 0.82rem; font-weight: 700;
  color: var(--text-dim, #aab2c5); }
.boutique-options-liste { display: grid; gap: 8px; }
.boutique-option { display: flex; gap: 10px; align-items: flex-start; cursor: pointer;
  padding: 8px; border-radius: 10px; transition: background 0.15s ease; }
.boutique-option:hover { background: rgba(255, 255, 255, 0.04); }
.boutique-option input { margin-top: 3px; flex: 0 0 auto; }
.boutique-option span { display: grid; gap: 2px; }
.boutique-option small { color: var(--text-dim, #8a93a6); font-size: 0.8rem; }
.boutique-promo { display: flex; gap: 10px; align-items: flex-end; flex-wrap: wrap; }
.boutique-promo label { flex: 1 1 190px; }
.boutique-promo-etat { margin: 6px 0 0; font-size: 0.86rem; color: #f0a5a5; }
.boutique-promo-etat.is-ok { color: #7fd6a9; }
.boutique-total { margin: 4px 0 0; font-size: 1.3rem; font-weight: 800; }
.boutique-total s { margin-left: 8px; font-size: 0.95rem; font-weight: 600;
  color: var(--text-dim, #8a93a6); }

.boutique-abo-inner { display: grid; grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
  gap: 26px; align-items: start; }
.boutique-abo-carte { border: 1px solid rgba(241, 196, 15, 0.28); border-radius: 18px;
  padding: 24px; background: rgba(241, 196, 15, 0.06); text-align: center; }
.boutique-abo-prix { margin: 0; font-size: 2.4rem; font-weight: 900;
  color: var(--or, #f1c40f); min-height: 1.2em; }
.boutique-abo-periode { margin: 0 0 16px; color: var(--text-dim, #aab2c5); }
.boutique-abo-etat { margin: 10px 0 0; font-size: 0.86rem; color: #f0a5a5; }
.boutique-abo-etat.is-ok { color: #7fd6a9; }

.btq-promo-form { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(150px, 100%), 1fr));
  gap: 12px; align-items: end; margin-bottom: 16px; }
.btq-promos { display: grid; gap: 10px; }
.btq-promo { border: 1px solid rgba(255, 255, 255, 0.08); border-radius: 14px;
  padding: 14px 16px; background: rgba(255, 255, 255, 0.03); }

@media (max-width: 900px) {
  .boutique-abo-inner { grid-template-columns: minmax(0, 1fr); }
}

/* ── Les chiffres, les etapes, la livraison, les avis ───────────────────
   La courbe des douze mois est faite de barres : pas de bibliotheque, pas
   de requete de plus, et elle reste lisible sur un telephone. */
.btq-courbe { display: flex; align-items: flex-end; gap: 6px; height: 140px;
  margin: 16px 0; padding: 10px 8px 0; border-radius: 14px;
  background: rgba(255, 255, 255, 0.03); }
.btq-barre { flex: 1 1 0; display: flex; flex-direction: column; justify-content: flex-end;
  align-items: center; height: 100%; gap: 6px; }
.btq-barre span { display: block; width: 70%; min-height: 2px; border-radius: 5px 5px 0 0;
  background: linear-gradient(180deg, rgba(88, 101, 242, 0.95), rgba(88, 101, 242, 0.45)); }
.btq-barre small { font-size: 0.68rem; color: var(--text-dim, #8a93a6); }
.btq-top { display: grid; gap: 6px; }
.btq-top-ligne { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; gap: 12px;
  margin: 0; padding: 8px 12px; border-radius: 10px; font-size: 0.88rem;
  background: rgba(255, 255, 255, 0.03); }
.btq-top-ligne span:nth-child(2) { color: var(--text-dim, #8a93a6); }

.btq-etapes { margin: 10px 0 0; padding: 12px 14px; border-radius: 12px;
  background: rgba(255, 255, 255, 0.03); display: grid; gap: 6px; }
.btq-etapes-tete { margin: 0 0 4px; font-size: 0.8rem; font-weight: 700;
  color: var(--text-dim, #aab2c5); }
.btq-etape { display: flex; gap: 9px; align-items: center; font-size: 0.9rem; cursor: pointer; }
.btq-livrer { display: flex; flex-wrap: wrap; gap: 10px; align-items: end; margin-top: 10px; }
.btq-livrer label { flex: 1 1 220px; font-size: 0.82rem; }
.btq-livrer input[type="text"] { flex: 1 1 220px; }

.boutique-avis-moyenne { margin: 10px 0 0; font-size: 1.05rem; font-weight: 700;
  color: var(--or, #f1c40f); }
.boutique-avis-grille { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr));
  gap: 16px; }
.boutique-avis-carte { border: 1px solid rgba(255, 255, 255, 0.08); border-radius: 16px;
  padding: 18px 20px; background: rgba(255, 255, 255, 0.03); }
.boutique-avis-note { margin: 0 0 8px; color: var(--or, #f1c40f); letter-spacing: 2px; }
.boutique-avis-texte { margin: 0 0 12px; }
.boutique-avis-pied { margin: 0; display: flex; flex-wrap: wrap; gap: 8px;
  font-size: 0.84rem; color: var(--text-dim, #8a93a6); }


/* ── Les tout petits écrans (320 à 400 px) ─────────────────────────────
   Une case de grille ne descend pas sous la largeur de son contenu tant
   qu'on ne le lui permet pas : c'est ce qui faisait dépasser une section,
   une liste numérotée ou un bouton de quelques pixels, juste assez pour
   que le texte soit coupé à droite sur un téléphone étroit. */
.wiki-content > *,
.wiki-section > *,
.boutique-formulaire > *,
.boutique-calcul-form > * { min-width: 0; }

@media (max-width: 480px) {
  /* La maquette de salon Discord de l'accueil : à cette largeur, deux
     colonnes de statistiques ne tiennent plus, et l'embed était rogné. */
  .embed-grid { grid-template-columns: minmax(0, 1fr); }
  .embed-actions > * { min-width: 0; }
  .discord-embed { min-width: 0; }

  /* Un bouton ne doit jamais être plus large que ce qui le contient. */
  .primary-btn,
  .secondary-btn,
  .boutique-payer > * { max-width: 100%; }
}

/* Une liste à puces numérotées est faite de lignes flex : sans min-width
   nulle, la ligne refuse de descendre sous la longueur de son texte, et
   la section entière s'élargit pour la suivre. */
.boutique-demande-etapes li { min-width: 0; }
.boutique-demande-etapes li > * { min-width: 0; }

@media (max-width: 480px) {
  /* Les pastilles de la maquette Discord et les boutons : plutôt deux
     lignes qu'un mot coupé au bord de l'écran. */
  .embed-actions span { min-width: 0; max-width: 100%; white-space: normal;
                        text-align: center; }
  .primary-btn,
  .secondary-btn {
    height: auto;
    min-width: 0;
    min-height: 44px;
    padding: 10px 16px;
    white-space: normal;
    text-align: center;
  }
}

/* Sur téléphone, le tableau comparatif est plus large que l'écran : il
   défile dans son cadre. On garde alors la colonne des intitulés collée à
   gauche — sans elle, on fait glisser « 49 € » sans plus savoir si on lit
   un prix, un délai ou des révisions. Le fond doit être opaque : une
   colonne collée à moitié transparente laisse passer le texte qui glisse
   dessous. */
@media (max-width: 760px) {
  .boutique-cmp tbody th {
    position: sticky;
    left: 0;
    z-index: 2;
    width: 118px;
    background: #15111f;
    box-shadow: 1px 0 0 rgba(255, 255, 255, 0.07);
  }
  .boutique-cmp { min-width: 560px; }
  .boutique-cmp th,
  .boutique-cmp td { padding: 12px 12px; font-size: 0.86rem; }
}

/* ── Les options de la fenetre de commande ─────────────────────────── */
/*
   « .boutique-fenetre-boite label » impose une grille a TOUTES les
   etiquettes de la fenetre. La case a cocher s'y etirait sur toute la
   largeur et se retrouvait centree AU-DESSUS de son texte, au lieu
   d'etre a sa gauche : on ne voyait plus ce qu'elle cochait. Une option
   se lit case a gauche, texte a droite.
*/
.boutique-options .boutique-option {
  display: flex;
  gap: 10px;
  align-items: flex-start;
}
.boutique-options .boutique-option input {
  width: auto;
  min-width: 0;
  min-height: 0;
  margin-top: 3px;
  padding: 0;
  flex: 0 0 auto;
}
.boutique-options .boutique-option span { min-width: 0; }

/* Les deux abonnements se suivent dans la meme section : sans cet air,
   le surtitre du second collait a la derniere ligne du premier. */
.boutique-abo-inner + .boutique-abo-inner {
  margin-top: 34px;
  padding-top: 30px;
  border-top: 1px solid var(--line);
}

/* ═══════════════════════════════════════════════════════════════════
   L'ecran de choix laisse voir le fond du site
   ═══════════════════════════════════════════════════════════════════
   Il portait un aplat gris Discord (#313338) etale sur toute la
   hauteur : les etoiles, le halo et le decor vivant etaient bien la,
   derriere, et on n'en voyait rien. Quatre cartes grises sur un gris
   uni, et six cents pixels de vide en dessous.

   Le gris part ; ce qui restait en gris Discord — la barre du haut, la
   recherche, les cartes — reprend la palette du site, sinon on aurait
   des boites grises posees sur un ciel violet.
   ═══════════════════════════════════════════════════════════════════ */

.server-picker {
  background: transparent;
  color: var(--text);
}

/* Le fond vivant est peint DERRIERE (z-index -1) : un voile suffit a
   garder les cartes lisibles sans effacer le decor. */
.server-picker::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(900px 520px at 50% -10%, rgba(139, 92, 246, 0.16), transparent 70%),
    linear-gradient(180deg, rgba(5, 2, 13, 0.55), rgba(5, 2, 13, 0.82));
}

.server-select-topbar {
  background: rgba(10, 6, 22, 0.72);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--line);
}

.server-select-brand { color: var(--text); }
.server-select-nav a { color: var(--muted); font-weight: 650; }
.server-select-nav a:hover { color: var(--text); }

.server-picker .secondary-btn {
  background: var(--surface-1);
  border-color: var(--line);
}

.server-search {
  border-color: var(--line);
  background: rgba(10, 6, 22, 0.6);
  color: var(--muted);
}
.server-search input { color: var(--text); font-weight: 600; }
.server-search input::placeholder { color: var(--muted); }

.server-picker .server-card {
  border-color: var(--line);
  background: var(--panel);
  color: var(--text);
}

.server-picker .server-card .server-logo-shell {
  border-color: rgba(18, 12, 34, 0.9);
  background: var(--bg);
}

.server-card-copy strong { color: var(--text); }

.server-picker .dashboard-empty-state {
  border-color: var(--line);
  background: var(--panel);
}

/* Le compte des serveurs et le titre se lisent sur le decor. */
.server-select-heading p {
  background: rgba(10, 6, 22, 0.55);
}

/* ═══════════════════════════════════════════════════════════════════
   LA TRANSITION D'UNE PAGE A L'AUTRE
   ═══════════════════════════════════════════════════════════════════
   Un clic dans la barre du haut remplacait l'ecran d'un coup : le fond
   sautait, le decor repartait de zero, et l'oeil devait retrouver ou il
   en etait. Le voile noir tient la seconde qui manque — il se pose au
   depart, il s'efface a l'arrivee.

   L'opacite de REPOS est zero, et l'animation part de un. Si les
   animations ne tournent pas — vieux navigateur, moteur en panne — le
   voile reste donc invisible. L'inverse aurait laisse un ecran noir.
   ═══════════════════════════════════════════════════════════════════ */

.voile-page {
  position: fixed;
  inset: 0;
  /* Au-dessus de tout, assistant compris (9001) : un voile qu'un
     panneau traverse ne voile rien. */
  z-index: 10000;
  opacity: 0;
  pointer-events: none;
  background: #05020d;
}

@keyframes voile-arrivee {
  from { opacity: 1; }
  to   { opacity: 0; }
}

@keyframes voile-depart {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@media (prefers-reduced-motion: no-preference) {
  /* L'arrivee : le noir s'efface. Un peu plus long que le depart —
     on decouvre une page, on ne la quitte pas. */
  .voile-page {
    animation: voile-arrivee 420ms cubic-bezier(0.22, 0.7, 0.3, 1);
  }

  /* Le depart : le noir se pose, et RESTE pose jusqu'a ce que la page
     suivante s'affiche (« forwards »). Sans cela, l'ecran se rallumerait
     une fraction de seconde avant de changer. */
  html.page-part .voile-page {
    animation: voile-depart 190ms cubic-bezier(0.4, 0, 1, 1) forwards;
  }
}

/* ═══════════════════════════════════════════════════════════════════
   « Gerer mon abonnement », sous les deux cartes
   ═══════════════════════════════════════════════════════════════════
   Une seule ligne pour les deux : chez Stripe, maintenance et
   hebergement sont le meme client. La poser dans l'une des deux cartes
   aurait laisse croire qu'elle ne gere que celle-la.
   ═══════════════════════════════════════════════════════════════════ */

.boutique-abo-gerer {
  margin-top: 26px;
  padding-top: 24px;
  border-top: 1px solid var(--line);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 10px 16px;
  text-align: center;
}

.boutique-abo-gerer .field-help {
  margin: 0;
  max-width: 46ch;
}

.boutique-abo-gerer .boutique-abo-etat { flex-basis: 100%; margin: 0; }

/* ═══════════════════════════════════════════════════════════════════
   « Hebergement a activer », sur la fiche d'une commande
   ═══════════════════════════════════════════════════════════════════
   Une creation livree, hebergee par nous, dont l'abonnement n'a jamais
   demarre : elle tourne sur notre machine sans que rien ne soit
   preleve, ou elle est eteinte et le client ne le sait pas encore. Les
   deux valent qu'on regarde la fiche. D'ou la couleur d'alerte, la
   seule de cette liste.
   ═══════════════════════════════════════════════════════════════════ */

.btq-tag.btq-tag-alerte {
  background: rgba(232, 163, 61, 0.16);
  border: 1px solid rgba(232, 163, 61, 0.38);
  color: var(--warn);
  font-weight: 700;
}

/* L'etat du service : quatre chiffres, une pastille, un tableau. */
.etat-pastille { display:inline-flex; align-items:center; gap:.5rem; padding:.35rem .9rem;
  border-radius:999px; border:1px solid rgba(255,255,255,.14); font-weight:600; }
.etat-pastille.est-en-ligne { color:#2ECC71; border-color:rgba(46,204,113,.45); }
.etat-pastille.est-hors-ligne { color:#ED4245; border-color:rgba(237,66,69,.45); }
.etat-cartes { display:grid; gap:1rem; grid-template-columns:repeat(auto-fit,minmax(180px,1fr));
  margin-bottom:2rem; }
.etat-carte { padding:1.1rem 1.2rem; border-radius:16px; background:rgba(255,255,255,.04);
  border:1px solid rgba(255,255,255,.08); display:flex; flex-direction:column; gap:.2rem; }
.etat-carte strong { font-size:1.8rem; line-height:1.1; }
.etat-carte span { font-weight:600; }
.etat-carte small { opacity:.7; }

/* L'essai deja utilise : le bouton reste la, en retrait, et s'explique
   quand on clique dessus. */
.primary-btn.is-indisponible { opacity:.55; }
