:root {
  /* espacements et rayons : une seule echelle pour tout le produit */
  --e1: 4px; --e2: 8px; --e3: 12px; --e4: 16px; --e5: 24px; --e6: 32px;
  --r1: 8px; --r2: 10px; --r3: 14px; --r-plein: 999px;
  --ombre: 0 10px 30px rgba(0, 0, 0, .45);
  --transition: 140ms cubic-bezier(.2, .7, .4, 1);
  --densite: 1;                      /* 0.8 compact, 1 normal, 1.25 confortable */

  --bg: #0d0f13;
  --panel: #161920;
  --panel-2: #1d212a;
  --line: #282d38;
  --text: #e9ecf3;
  --dim: #8b93a5;
  --accent: #5b6ef5;
  --ok: #35d07f;
  --twitch: #a970ff;
  --youtube: #ff4e45;
  --tiktok: #25f4ee;
  --kick: #53fc18;
}
* { box-sizing: border-box; }
html, body { height: 100%; margin: 0; }
body {
  background: var(--bg);
  color: var(--text);
  font: 15px/1.55 "Segoe UI", system-ui, sans-serif;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
a { color: #8ba7ff; }

/* ---------------------------------------------------------- barre du haut */
.topbar {
  flex: none; display: flex; align-items: center; gap: 10px;
  padding: 10px 16px; background: var(--panel); border-bottom: 1px solid var(--line);
}
.brand { font-weight: 800; letter-spacing: .12em; font-size: 13px; }
.brand b { color: var(--accent); }
.grow { flex: 1; }

.pill {
  display: none; align-items: center; gap: 6px; padding: 4px 11px; border-radius: 999px;
  background: var(--panel-2); border: 1px solid transparent;
  font-size: 12px; font-weight: 700; color: var(--dim);
}
body[data-view="chat"] .pill:not([hidden]) { display: flex; }
.pill .plat { width: 13px; height: 13px; }
.pill[data-state="on"] { color: var(--text); }
.pill.twitch[data-state="on"] { border-color: var(--twitch); }
.pill.youtube[data-state="on"] { border-color: var(--youtube); }
.pill.tiktok[data-state="on"] { border-color: var(--tiktok); }
.pill.kick[data-state="on"] { border-color: var(--kick); }
.pill::after {
  content: ''; width: 7px; height: 7px; border-radius: 50%; background: #4a5160;
}
.pill[data-state="on"]::after { background: var(--ok); box-shadow: 0 0 6px #35d07f88; }
.pill[data-state="connecting"]::after, .pill[data-state="retry"]::after { background: #e5a83c; animation: blink 1.1s infinite; }
@keyframes blink { 50% { opacity: .25; } }

.btn {
  background: var(--panel-2); border: 1px solid var(--line); color: var(--text);
  padding: 7px 13px; border-radius: 8px; cursor: pointer; font: 600 13px inherit;
}
.btn:hover { border-color: #47506a; }
.btn.primary { background: var(--accent); border-color: var(--accent); }
.btn.on { background: var(--accent); border-color: var(--accent); }
.vues { display: none; gap: 6px; }
body[data-view="chat"] .vues { display: flex; }

/* ---------------------------------------------------------- accueil */
.accueil { flex: 1; overflow-y: auto; display: none; padding: 40px 20px; }
body[data-view="accueil"] .accueil { display: block; }
body[data-view="chat"] .accueil { display: none; }

.hero { max-width: 560px; margin: 0 auto; }
.hero h1 { font-size: 30px; line-height: 1.2; margin: 0 0 10px; }
.hero p.sub { color: var(--dim); margin: 0 0 26px; }
.field { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.field .plat { width: 18px; height: 18px; flex: none; }
.field.twitch .plat { color: var(--twitch); }
.field.youtube .plat { color: var(--youtube); }
.field.tiktok .plat { color: var(--tiktok); }
.field.kick .plat { color: var(--kick); }
.field input {
  flex: 1; min-width: 0; background: #0a0c10; border: 1px solid var(--line); border-radius: 9px;
  color: var(--text); padding: 11px 13px; font: inherit;
}
.field input:focus { outline: none; border-color: #4a5578; }
.field .tag { font-size: 11px; color: var(--dim); white-space: nowrap; }
.hero .actions { display: flex; gap: 10px; align-items: center; margin-top: 18px; }
.hero .note { font-size: 13px; color: var(--dim); margin-top: 22px; }

/* ---------------------------------------------------------- chat */
.board { flex: 1; display: none; min-height: 0; }
body[data-view="chat"] .board { display: flex; }
.board.melange .col { flex: 1; }
.board.separe { gap: 1px; background: var(--line); }
.board.separe .col { flex: 1; min-width: 0; background: var(--bg); display: flex; flex-direction: column; }
.col { display: flex; flex-direction: column; min-height: 0; }
.col header {
  flex: none; display: flex; align-items: center; gap: 8px;
  padding: 8px 12px; background: var(--panel); border-bottom: 1px solid var(--line);
  font-size: 12px; font-weight: 700; letter-spacing: .04em;
}
.col header .plat { width: 14px; height: 14px; }
.col.twitch header .plat { color: var(--twitch); }
.col.youtube header .plat { color: var(--youtube); }
.col.tiktok header .plat { color: var(--tiktok); }
.col.kick header .plat { color: var(--kick); }
.col header .dot { width: 7px; height: 7px; border-radius: 50%; background: #4a5160; margin-left: auto; }
.col header .dot[data-state="on"] { background: var(--ok); }
.col header .dot[data-state="connecting"], .col header .dot[data-state="retry"] { background: #e5a83c; }

.feed {
  flex: 1; overflow-y: auto; padding: 8px 0 14px;
  scrollbar-width: thin; scrollbar-color: #3a414f transparent;
}
.feed::-webkit-scrollbar { width: 9px; }
.feed::-webkit-scrollbar-thumb { background: #3a414f; border-radius: 5px; }
.empty { padding: 34px 18px; text-align: center; color: var(--dim); font-size: 13px; }

/* ---------------------------------------------------------- messages */
.msg {
  position: relative; padding: 5px 12px 5px 13px;
  border-left: 3px solid transparent; overflow-wrap: anywhere;
  animation: in .16s ease-out;
}
@keyframes in { from { opacity: 0; transform: translateY(4px); } }
.msg:hover { background: rgba(255,255,255,.03); }
.msg.twitch { border-left-color: var(--twitch); }
.msg.youtube { border-left-color: var(--youtube); }
.msg.tiktok { border-left-color: var(--tiktok); }
.msg.kick { border-left-color: var(--kick); }
.board.separe .msg { border-left-color: transparent; }

.msg .time { color: var(--dim); font-size: 11px; margin-right: 7px; opacity: .75; font-variant-numeric: tabular-nums; }
.msg .plat { width: 15px; height: 15px; vertical-align: -2px; margin-right: 6px; }
.msg .plat path { fill: currentColor; }
.msg.twitch .plat, .msg.twitch .who { color: var(--twitch); }
.msg.youtube .plat, .msg.youtube .who { color: var(--youtube); }
.msg.tiktok .plat, .msg.tiktok .who { color: var(--tiktok); }
.msg.kick .plat, .msg.kick .who { color: var(--kick); }
.board.separe .msg .plat { display: none; }
.msg .ava { width: 20px; height: 20px; border-radius: 50%; vertical-align: -5px; margin-right: 6px; object-fit: cover; }
.msg .bdg { width: 18px; height: 18px; vertical-align: -4px; margin-right: 4px; }
.msg .bdg-txt {
  display: inline-block; margin-right: 4px; padding: 0 4px; border-radius: 3px;
  font-size: 9px; font-weight: 700; text-transform: uppercase; vertical-align: 1px;
  background: #39404e; color: #cdd4e0;
}
.msg .who { font-weight: 700; }
.msg .sep { color: var(--dim); margin-right: 3px; }
.msg .emote { height: 28px; vertical-align: -8px; margin: -2px 2px; }
.msg .emote.zw { margin-left: -30px; }
.msg .mention { color: #ffd479; }
.msg .muted { color: var(--dim); font-style: italic; }
.msg .chip {
  display: inline-block; margin-right: 6px; padding: 1px 7px; border-radius: 999px;
  font-size: 10px; font-weight: 700; text-transform: uppercase; background: #3a445c; color: #fff;
}
.msg.hl-cheer { background: #2e2413; }
.msg.hl-cheer .chip { background: #b8801f; }
.msg.hl-sub { background: #1c2440; }
.msg.hl-sub .chip { background: var(--accent); }
.msg.hl-mod { background: #2c1c1c; }
.msg.hl-mod .chip { background: #a33b3b; }
.msg.event .txt { color: var(--dim); }
.msg .hide-user {
  position: absolute; top: 3px; right: 6px; width: 20px; height: 20px; line-height: 1;
  border: 0; border-radius: 5px; cursor: pointer; display: none;
  background: rgba(255,255,255,.08); color: var(--dim); font-size: 15px;
}
.msg:hover .hide-user { display: block; }
.msg .hide-user:hover { background: #a33b3b; color: #fff; }

/* ---------------------------------------------------------- pub et bas de page */
.pub {
  flex: none; display: none; align-items: center; justify-content: center; gap: 12px;
  padding: 10px 16px; background: var(--panel); border-top: 1px solid var(--line);
  font-size: 13px; color: var(--dim);
}
body[data-view="chat"] .pub { display: flex; }
.pub .slot {
  flex: 1; max-width: 728px; height: 62px; border: 1px dashed var(--line); border-radius: 8px;
  display: flex; align-items: center; justify-content: center; font-size: 12px;
}
.pub a { font-weight: 600; }

#toast {
  position: fixed; left: 50%; bottom: 90px; transform: translateX(-50%);
  background: var(--panel-2); border: 1px solid var(--line); color: var(--text);
  padding: 9px 18px; border-radius: 999px; font-size: 13px;
  opacity: 0; pointer-events: none; transition: opacity .2s;
}
#toast.show { opacity: 1; }
#toast.avec-lien { pointer-events: auto; }
#toast a { color: var(--accent-clair); text-decoration: none; font-weight: 600; margin-left: 2px; }
#toast a:hover { text-decoration: underline; }

@media (max-width: 780px) {
  .board.separe { flex-direction: column; }
  .topbar { flex-wrap: wrap; }
}

/* ---------------------------------------------------------- barre d'outils */
.outils {
  flex: none; display: none; align-items: center; gap: 8px;
  padding: 8px 14px; background: var(--panel); border-bottom: 1px solid var(--line);
}
body[data-view="chat"] .outils { display: flex; }
.outils input {
  background: #0a0c10; border: 1px solid var(--line); border-radius: 8px;
  color: var(--text); padding: 7px 11px; font: inherit; font-size: 13px;
}
.outils input:focus { outline: none; border-color: #4a5578; }
#recherche { flex: 1; min-width: 0; }
#pseudo { width: 210px; }
.msg.mention-me { background: #3a3212; box-shadow: inset 3px 0 0 #e5a83c; }

/* ---------------------------------------------------------- panneau stats */
.panneau {
  position: fixed; top: 104px; right: 16px; width: 260px; z-index: 5;
  background: var(--panel); border: 1px solid var(--line); border-radius: 12px;
  padding: 14px 16px; box-shadow: 0 12px 30px rgba(0,0,0,.5);
}
.panneau h2 { margin: 0 0 12px; font-size: 12px; letter-spacing: .12em; text-transform: uppercase; color: var(--dim); }
.panneau h3 { margin: 16px 0 8px; font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--dim); font-weight: 700; }
.panneau h3 small { text-transform: none; letter-spacing: 0; opacity: .7; }
.panneau .grille { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.panneau .grille b { display: block; font-size: 22px; font-variant-numeric: tabular-nums; }
.panneau .grille span { font-size: 10px; color: var(--dim); text-transform: uppercase; letter-spacing: .06em; }
.panneau ul { list-style: none; margin: 0; padding: 0; font-size: 13px; }
.panneau li { display: flex; justify-content: space-between; gap: 10px; padding: 3px 0; }
.panneau li span:last-child { color: var(--dim); font-variant-numeric: tabular-nums; }
.panneau li .nom { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---------------------------------------------------------- version complete */
.field.licence input { flex: 1; }
body[data-pro="1"] .pub { display: none; }
body[data-pro="1"] #etat-licence { color: var(--ok); }
.btn.pro { display: none; }
body[data-pro="1"] .btn.pro { display: inline-block; }
.panneau .ligne { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 10px; font-size: 13px; }
.panneau .ligne input[type="number"] {
  width: 80px; background: #0a0c10; border: 1px solid var(--line); border-radius: 7px;
  color: var(--text); padding: 6px 8px; font: inherit; font-size: 13px;
}
.panneau .ligne input[type="checkbox"] { width: 16px; height: 16px; accent-color: var(--accent); }
.panneau .btn { width: 100%; margin-top: 6px; }
.pied { flex: none; padding: 8px 16px; text-align: center; font-size: 12px; background: var(--panel); border-top: 1px solid var(--line); }
.pied a { color: var(--dim); text-decoration: none; }
.pied a:hover { color: var(--text); }
body[data-view="chat"] .pied { display: none; }

/* messages d'historique : presents des l'ouverture, legerement en retrait */
.msg.historique { opacity: .72; }
.msg.historique:hover { opacity: 1; }
.empty small { display: block; margin-top: 8px; opacity: .75; line-height: 1.5; }

/* etat des connexions, affiche tant que le chat est vide */
.attente { text-align: left; max-width: 460px; margin: 24px auto; }
.attente .etats { list-style: none; margin: 0 0 16px; padding: 0; }
.attente .etats li {
  display: flex; justify-content: space-between; gap: 12px; align-items: center;
  padding: 9px 12px; margin-bottom: 6px; border-radius: 9px;
  background: var(--panel); border-left: 3px solid var(--line);
}
.attente .etats li.twitch { border-left-color: var(--twitch); }
.attente .etats li.youtube { border-left-color: var(--youtube); }
.attente .etats li.tiktok { border-left-color: var(--tiktok); }
.attente .etats li.kick { border-left-color: var(--kick); }
.attente .etats span { font-weight: 700; font-size: 13px; }
.attente .etats b { font-weight: 500; font-size: 12px; color: var(--dim); text-align: right; }
.attente .etats b[data-state="on"] { color: var(--ok); }
.attente .etats b[data-state="retry"] { color: #e5a83c; }
.attente p { font-size: 13px; color: var(--dim); margin: 10px 0; }

/* ============================================================ passe d'interface */

/* --- barre d'outils : des groupes plutot qu'une rangee de boutons */
.outils { gap: 10px; flex-wrap: wrap; }
.groupe {
  display: flex; align-items: center; gap: 4px;
  padding: 3px; border-radius: 10px; background: var(--panel-2);
  border: 1px solid var(--line);
}
.groupe .etiquette {
  font-size: 10px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--dim); padding: 0 8px 0 6px;
}
.btn.petit { padding: 5px 10px; font-size: 12px; background: transparent; border-color: transparent; }
.btn.petit:hover { background: var(--bg); border-color: transparent; }
.btn.petit.on { background: var(--accent); color: #fff; }
.file {
  min-width: 26px; text-align: center; padding: 3px 7px; margin-left: 2px;
  border-radius: 999px; background: #e5a83c; color: #16191f;
  font-size: 11px; font-weight: 800; font-variant-numeric: tabular-nums;
}

/* --- retour au direct quand on a remonte le chat */
#reprendre {
  position: fixed; left: 50%; bottom: 96px; transform: translateX(-50%); z-index: 6;
  background: var(--accent); color: #fff; border: 0; border-radius: 999px;
  padding: 9px 18px; font: 700 13px inherit; cursor: pointer;
  box-shadow: 0 8px 24px rgba(0, 0, 0, .5);
}
#reprendre:hover { filter: brightness(1.1); }

/* --- messages : plus d'air, meilleure lecture */
.msg { padding: 7px 14px 7px 15px; line-height: 1.5; }
.msg + .msg { border-top: 1px solid rgba(255, 255, 255, .035); }
.msg:hover { background: rgba(255, 255, 255, .045); }
.msg .who { letter-spacing: .01em; }
.msg .txt { color: #dde2ec; }
.msg .time { opacity: .55; }
.msg:hover .time { opacity: .9; }
.msg .bdg, .msg .ava { filter: saturate(1.05); }
.msg.hl { border-radius: 0 8px 8px 0; margin: 3px 6px 3px 0; }

/* --- en-tete de colonne en mode separe */
.col header { letter-spacing: .06em; text-transform: uppercase; font-size: 11px; }
.board.separe .col + .col { box-shadow: -1px 0 0 var(--line); }

/* --- accueil : plus aere, exemples cliquables */
.hero h1 { font-size: 34px; letter-spacing: -.01em; }
.hero p.sub { font-size: 16px; line-height: 1.6; margin-bottom: 30px; }
.field { margin-bottom: 12px; }
.field input { padding: 13px 14px; border-radius: 10px; }
.field input::placeholder { color: #5f6879; }
.exemples { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px; align-items: center; }
.exemples span { font-size: 12px; color: var(--dim); }
.puce {
  border: 1px solid var(--line); background: var(--panel); color: var(--text);
  border-radius: 999px; padding: 6px 12px; font: 600 12px inherit; cursor: pointer;
}
.puce:hover { border-color: #46506a; }
.hero .actions .btn.primary { padding: 12px 22px; font-size: 14px; }

/* --- barre du haut : le direct se voit */
.topbar { padding: 12px 18px; }
.compteur {
  font-size: 12px; color: var(--dim); font-variant-numeric: tabular-nums;
  padding: 4px 10px; border-radius: 999px; background: var(--panel-2);
}
body[data-view="accueil"] .compteur { display: none; }

/* --- bandeau : ce qui passe en direct sur chaque plateforme */
.bandeau {
  flex: none; display: flex; flex-wrap: wrap; gap: 8px;
  padding: 8px 14px; background: var(--panel); border-bottom: 1px solid var(--line);
}
.bandeau .direct {
  display: flex; align-items: center; gap: 8px; min-width: 0;
  padding: 6px 12px; border-radius: 999px; background: var(--panel-2);
  border-left: 3px solid var(--line); font-size: 13px;
}
.bandeau .direct.twitch { border-left-color: var(--twitch); }
.bandeau .direct.youtube { border-left-color: var(--youtube); }
.bandeau .direct.tiktok { border-left-color: var(--tiktok); }
.bandeau .direct.kick { border-left-color: var(--kick); }
.bandeau .plat { width: 14px; height: 14px; flex: none; }
.bandeau .direct.twitch .plat { color: var(--twitch); }
.bandeau .direct.youtube .plat { color: var(--youtube); }
.bandeau .direct.tiktok .plat { color: var(--tiktok); }
.bandeau .direct.kick .plat { color: var(--kick); }
.bandeau .titre {
  font-weight: 600; max-width: 420px; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap;
}
.bandeau .cat, .bandeau .audience { font-size: 11px; color: var(--dim); white-space: nowrap; }
.bandeau .cat::before { content: '· '; }
.bandeau .audience { font-variant-numeric: tabular-nums; }
body[data-view="accueil"] .bandeau { display: none; }

/* ============================================================ finitions */

/* --- ce qui se clique reagit, et se voit au clavier */
button, input, a { transition: background var(--transition), border-color var(--transition),
  color var(--transition), filter var(--transition), transform var(--transition); }
button:active { transform: translateY(1px); }
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--r1);
}
::selection { background: rgba(91, 110, 245, .35); }

/* --- densite d'affichage du chat */
.msg { padding: calc(7px * var(--densite)) 14px calc(7px * var(--densite)) 15px; }
body[data-densite="compact"] { --densite: .6; }
body[data-densite="confortable"] { --densite: 1.5; }
body[data-densite="compact"] .msg .ava { width: 17px; height: 17px; }
body[data-densite="compact"] .msg .emote { height: 22px; }
body[data-densite="confortable"] .msg .emote { height: 32px; }

/* --- taille du texte du chat */
.board { font-size: var(--taille-chat, 15px); }

/* --- carte d'un spectateur */
.carte {
  position: fixed; z-index: 20; width: 320px; max-height: 60vh; overflow: auto;
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--r3);
  box-shadow: var(--ombre); padding: var(--e4);
}
.carte h3 { margin: 0 0 var(--e2); font-size: 15px; display: flex; align-items: center; gap: var(--e2); }
.carte .meta { font-size: 12px; color: var(--dim); margin-bottom: var(--e3); }
.carte .liste { list-style: none; margin: 0 0 var(--e3); padding: 0; font-size: 13px; }
.carte .liste li { padding: 5px 0; border-top: 1px solid var(--line); color: #cfd6e4; }
.carte .actions { display: flex; gap: var(--e2); }
.carte .actions .btn { flex: 1; }

/* --- mobile */
@media (max-width: 720px) {
  .topbar { padding: 10px 12px; gap: 6px; }
  .topbar .compteur, .brand span { display: none; }
  .outils { padding: 8px 10px; }
  #recherche { flex: 1 1 100%; order: -1; }
  #pseudo { display: none; }
  .groupe { flex: 1; justify-content: center; }
  .hero h1 { font-size: 26px; }
  .bandeau .titre { max-width: 190px; }
  .msg { padding-left: 11px; padding-right: 10px; }
  .pub .slot { display: none; }
  .carte { left: 12px !important; right: 12px; width: auto; }
}

.panneau .ligne select, .panneau input[type="text"], .panneau input:not([type]) {
  background: #0a0c10; border: 1px solid var(--line); border-radius: var(--r1);
  color: var(--text); padding: 6px 8px; font: inherit; font-size: 13px;
}
.panneau .ligne select { width: 130px; }
.panneau .case {
  display: flex; align-items: center; gap: var(--e2);
  font-size: 13px; color: #cfd6e4; margin-bottom: 7px; cursor: pointer;
}
.panneau .case input { width: 15px; height: 15px; accent-color: var(--accent); }
.panneau > input { width: 100%; margin-top: var(--e1); }
.msg.alerte { background: #3a3212; box-shadow: inset 3px 0 0 #e5a83c; }

.msg .who { cursor: pointer; }
.msg .who:hover { text-decoration: underline; }

/* le nom ramene a l'accueil, comme partout ailleurs sur le web */
button.brand {
  background: none; border: 0; padding: 4px 6px; margin-left: -6px;
  color: var(--text); font: 800 13px/1 "Segoe UI", system-ui, sans-serif;
  letter-spacing: .12em; cursor: pointer; border-radius: var(--r1);
}
button.brand b { color: var(--accent); }
button.brand:hover { background: var(--panel-2); }

/* --- bandeau du bas : une vraie invitation tant qu'aucune regie n'est branchee */
.pub { padding: 8px 14px; gap: var(--e3); }
.pub .slot {
  height: auto; min-height: 52px; border-style: solid; border-color: var(--line);
  padding: 8px 16px; background: var(--panel-2);
}
.pub .promo { display: flex; flex-direction: column; gap: 2px; text-decoration: none; color: var(--text); }
.pub .promo b { font-size: 13px; }
.pub .promo span { font-size: 12px; color: var(--dim); }
.pub .promo:hover b { color: var(--accent); }

/* l'overlay appartient a la version complete */
.btn.verrouille { position: relative; }
/* Fonction reservee : un point discret, et le nom qui recule d'un cran. Onze etoiles dans
   une barre d'outils, ca ressemble a un sapin ; un point suffit a dire « pas inclus ». */
.btn.verrouille { color: var(--dim); }
.btn.verrouille::after {
  content: ''; display: inline-block; width: 4px; height: 4px; border-radius: 50%;
  background: currentColor; opacity: .5; margin-left: 6px; vertical-align: 2px;
}
.btn.verrouille:hover { color: var(--text); }
.overlay-verrou {
  position: fixed; inset: 0; display: flex; align-items: center; justify-content: center;
  background: rgba(10, 12, 16, .92); color: #e9ecf3; text-align: center;
  font: 600 15px/1.6 "Segoe UI", system-ui, sans-serif; padding: 24px;
}
.overlay-verrou b { display: block; font-size: 18px; margin-bottom: 8px; }
.overlay-verrou span { display: block; font-weight: 400; color: #8b93a5; font-size: 13px; margin-top: 10px; }

/* --- dons, abonnements et raids : mis en avant sans clignoter */
.msg.hl {
  border-radius: 0 var(--r2) var(--r2) 0;
  margin: 4px 8px 4px 0;
  background-image: linear-gradient(90deg, rgba(255, 255, 255, .05), transparent 60%);
}
.msg.hl .chip {
  font-size: 9px; letter-spacing: .08em; padding: 2px 8px;
  box-shadow: none; text-shadow: none;
}
/* les icones de cadeaux TikTok sont tres saturees : on les pose au calme */
.msg.hl .emote, .msg.event .emote {
  height: 22px; margin: -2px 3px; vertical-align: -5px;
  filter: saturate(.85) brightness(.95);
  border-radius: 4px;
}
.msg.hl:hover .emote, .msg.event:hover .emote { filter: none; }
.msg.hl-cheer { background-color: #2a2214; }
.msg.hl-sub { background-color: #1b2138; }
.msg.hl-mod { background-color: #2a1b1b; }
.msg.event .who { opacity: .95; }

/* ============================================================ habillage FuseChat
   Cartes par plateforme, polices servies en local. La direction visuelle est reprise
   plus bas par la passe sobre : ce qui reste ici, ce sont les briques communes. */

@font-face { font-family: 'Inter'; src: url('polices/inter-400.woff2') format('woff2');
  font-weight: 400; font-display: swap; }
@font-face { font-family: 'Inter'; src: url('polices/inter-600.woff2') format('woff2');
  font-weight: 600; font-display: swap; }
@font-face { font-family: 'Inter'; src: url('polices/inter-800.woff2') format('woff2');
  font-weight: 800; font-display: swap; }

:root {
  --bg: #06060a;
  --panel: #0c0c13;
  --panel-2: #12121b;
  --line: rgba(255, 255, 255, .09);
  --text: #f4f3f8;
  --dim: #8d8b9c;
  --accent: #9b3cff;
  --accent-clair: #c33dff;
  --ok: #3ce089;
}
body { font-family: 'Inter', 'Segoe UI', system-ui, sans-serif; background: var(--bg); }

/* --- la marque et les titres */
button.brand { font-size: 17px; letter-spacing: -.5px; }
button.brand b { color: var(--accent); }
/* le titre est habille dans la passe sobre */
.hero .accent { color: var(--accent); }
.eyebrow {
  font-size: 10px; letter-spacing: .25em; font-weight: 800; color: var(--accent-clair);
  margin-bottom: 14px; display: flex; align-items: center; gap: 9px;
}
.eyebrow::before {
  content: ''; width: 6px; height: 6px; border-radius: 50%;
  background: var(--accent-clair); box-shadow: 0 0 14px var(--accent);
}

/* --- panneaux et boutons */
.topbar, .outils, .bandeau, .pub, .pied, .col header {
  background: linear-gradient(145deg, rgba(18, 18, 27, .96), rgba(8, 8, 13, .92));
}
.btn { border-radius: var(--r-plein); }
.btn.primary { background: linear-gradient(135deg, var(--accent), var(--accent-clair)); border: 0; }
.btn.primary:hover { filter: brightness(1.08); }
.btn.on { background: linear-gradient(135deg, var(--accent), var(--accent-clair)); border-color: transparent; }
.pill { border-radius: var(--r-plein); }
.groupe { border-radius: var(--r-plein); }

/* --- les champs de l'accueil deviennent des cartes par plateforme */
.field {
  border: 1px solid var(--line); border-radius: var(--r3); padding: 10px 14px;
  background: linear-gradient(90deg, var(--teinte, transparent), rgba(12, 12, 19, .9) 70%);
  transition: border-color var(--transition), transform var(--transition);
}
.field:hover { transform: translateX(3px); }
.field.twitch { --teinte: rgba(87, 23, 130, .30); border-color: rgba(155, 60, 255, .45); }
.field.kick { --teinte: rgba(24, 100, 10, .24); border-color: rgba(93, 255, 24, .35); }
.field.youtube { --teinte: rgba(110, 15, 15, .26); border-color: rgba(255, 45, 45, .35); }
.field.tiktok { --teinte: rgba(0, 100, 115, .22); border-color: rgba(17, 217, 238, .35); }
.field.licence { --teinte: transparent; border-color: var(--line); }
.field input { background: transparent; border: 0; padding: 8px 2px; }
.field input:focus { outline: none; }
.field .plat { width: 20px; height: 20px; }
.puce { border-radius: var(--r-plein); }

/* --- l'accueil respire : largeur geree par la passe sobre */
.hero p.sub { font-size: 15px; }

/* --- thème clair */
body.clair {
  --bg: #f5f3fa; --panel: #ffffff; --panel-2: #f0edf7;
  --line: rgba(20, 10, 40, .12); --text: #17131f; --dim: #6a6577;
}
body.clair { background: var(--bg); }
body.clair .topbar, body.clair .outils, body.clair .bandeau,
body.clair .pub, body.clair .pied, body.clair .col header {
  background: rgba(255, 255, 255, .96);
}
body.clair .msg:hover { background: rgba(0, 0, 0, .035); }
body.clair .msg .txt { color: #2a2634; }
body.clair .field input { color: var(--text); }
body.clair .msg + .msg { border-top-color: rgba(0, 0, 0, .06); }

/* --- lisibilite du chat sur la palette sombre */
.msg .txt { color: #eceef6; }
.msg .time { opacity: .8; color: #9a98ab; }
.msg.historique { opacity: .88; }
.msg.historique .txt { color: #d5d8e4; }
.board { background: rgba(4, 4, 8, .35); }
.feed { padding-top: 10px; }
.msg + .msg { border-top-color: rgba(255, 255, 255, .05); }
.msg:hover { background: rgba(155, 60, 255, .07); }
.bandeau .titre { color: #f2f0f8; }
body.clair .msg .txt { color: #201c29; }
body.clair .msg.historique .txt { color: #3a3548; }
body.clair .board { background: rgba(255, 255, 255, .5); }

.panneau .note-panneau { font-size: 12px; color: var(--dim); line-height: 1.6; margin: 12px 0 0; }
.panneau .note-panneau b { color: var(--text); }

/* --- les logos se dessinent partout, pas seulement dans les messages */
.plat { flex: none; }
.plat path { fill: currentColor; }
.field .plat { width: 22px; height: 22px; }
.field.twitch .plat { color: #b57bff; }
.field.kick .plat { color: #7dff4a; }
.field.youtube .plat { color: #ff6a62; }
.field.tiktok .plat { color: #45f6ef; }
.pill .plat { color: currentColor; }
.bandeau .direct .plat, .col header .plat { opacity: 1; }

/* --- les logos gagnent en presence */
.field .plat { width: 26px; height: 26px; margin-right: 4px; }
.pill .plat { width: 14px; height: 14px; }
.bandeau .plat { width: 16px; height: 16px; }
.col header .plat { width: 16px; height: 16px; }
.msg .plat { width: 16px; height: 16px; }

/* ============================================================ mouvements
   Discrets et courts : ils guident l'oeil, ils ne font pas attendre.
   Tout est desactive si le systeme demande moins d'animations. */

@keyframes monter { from { opacity: 0; transform: translateY(14px); } }
@keyframes fondu { from { opacity: 0; } }
@keyframes glisser { from { opacity: 0; transform: translateX(-10px); } }
@keyframes pulsation { 0%, 100% { opacity: 1; } 50% { opacity: .45; } }


/* l'accueil se pose */
body[data-view="accueil"] .hero > * { animation: monter .5s cubic-bezier(.2, .7, .3, 1) both; }
body[data-view="accueil"] .hero .eyebrow { animation-delay: .02s; }
body[data-view="accueil"] .hero h1 { animation-delay: .06s; }
body[data-view="accueil"] .hero p.sub { animation-delay: .12s; }
body[data-view="accueil"] .hero form { animation-delay: .16s; }
.field { animation: monter .45s cubic-bezier(.2, .7, .3, 1) both; }
.field:nth-of-type(1) { animation-delay: .18s; }
.field:nth-of-type(2) { animation-delay: .23s; }
.field:nth-of-type(3) { animation-delay: .28s; }
.field:nth-of-type(4) { animation-delay: .33s; }
.field:focus-within {
  border-color: var(--accent-clair);
  box-shadow: 0 0 0 3px rgba(155, 60, 255, .15);
  transform: translateX(3px);
}

/* les messages arrivent par la gauche, comme dans un vrai chat */
.msg { animation: glisser .18s cubic-bezier(.2, .7, .3, 1) both; }
.msg.hl { animation: glisser .28s cubic-bezier(.2, .7, .3, 1) both; }

/* les pastilles vivent quand la chaine est en direct */
.pill[data-state="on"]::after { animation: pulsation 2.4s ease-in-out infinite; }

/* panneaux et bandeaux */
.panneau { animation: monter .22s cubic-bezier(.2, .7, .3, 1) both; }
.bandeau .direct { animation: fondu .4s ease both; }
.carte { animation: monter .18s cubic-bezier(.2, .7, .3, 1) both; }
#toast { transition: opacity .25s, transform .25s; transform: translate(-50%, 8px); }
#toast.show { transform: translate(-50%, 0); }
#reprendre { animation: monter .25s cubic-bezier(.2, .7, .3, 1) both; }

/* boutons : reponse immediate au doigt */
.btn:hover { transform: translateY(-1px); }
.btn:active { transform: translateY(0); }
.puce:hover { transform: translateY(-1px); }
.btn.primary:hover { box-shadow: 0 8px 24px rgba(155, 60, 255, .35); }

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

/* ============================================================ mode clair
   Refait proprement : fond papier, panneaux blancs, couleurs de plateformes
   assombries pour rester lisibles sur clair. */

body.clair {
  --bg: #f4f2f9;
  --panel: #ffffff;
  --panel-2: #f0edf7;
  --line: rgba(26, 16, 48, .12);
  --text: #191426;
  --dim: #66607a;
  --accent: #7326e8;
  --accent-clair: #a234f0;
  --ok: #17a15c;
  --twitch: #7326e8;
  --youtube: #d42a20;
  --tiktok: #0898a8;
  --kick: #2b9410;
  color-scheme: light;
}
body.clair .topbar, body.clair .outils, body.clair .bandeau,
body.clair .pub, body.clair .pied, body.clair .col header, body.clair .panneau, body.clair .carte {
  background: #ffffff;
  border-color: var(--line);
}
body.clair .topbar, body.clair .outils { box-shadow: 0 1px 0 rgba(26, 16, 48, .06); }
body.clair .board { background: #fbfaff; }
body.clair .msg { border-top-color: rgba(26, 16, 48, .07); }
body.clair .msg:hover { background: rgba(115, 38, 232, .06); }
body.clair .msg .txt { color: #241f31; }
body.clair .msg.historique .txt { color: #4a4459; }
body.clair .msg .time { color: #8b8599; opacity: 1; }
body.clair .msg .bdg-txt { background: #ece8f6; color: #4a4459; }
body.clair .msg .sep { color: #a9a3b8; }
body.clair .msg.hl-cheer { background-color: #fdf3e0; }
body.clair .msg.hl-sub { background-color: #eef0fd; }
body.clair .msg.hl-mod { background-color: #fdeeee; }
body.clair .msg.alerte { background: #fff6dc; box-shadow: inset 3px 0 0 #d99b18; }
body.clair .btn { background: #ffffff; border-color: var(--line); color: #241f31; }
body.clair .btn:hover { border-color: #b79bf0; }
body.clair .btn.on, body.clair .btn.primary { color: #ffffff; border-color: transparent; }
body.clair .btn.petit { background: transparent; }
body.clair .btn.petit:hover { background: #f2eefc; }
body.clair .groupe { background: #f4f1fb; }
body.clair .pill { background: #f4f1fb; color: #66607a; }
body.clair .pill[data-state="on"] { color: #241f31; }
body.clair .field { background: linear-gradient(90deg, var(--teinte-clair, #ffffff), #ffffff 70%); }
body.clair .field.twitch { --teinte-clair: #f3ecff; border-color: #c9aef7; }
body.clair .field.kick { --teinte-clair: #edfbe8; border-color: #a8e29a; }
body.clair .field.youtube { --teinte-clair: #fdeceb; border-color: #f2b0ac; }
body.clair .field.tiktok { --teinte-clair: #e6f9fb; border-color: #93d7df; }
body.clair .field.licence { border-color: var(--line); }
body.clair .field input { color: var(--text); }
body.clair .field input::placeholder, body.clair .outils input::placeholder { color: #8b8599; }
body.clair .outils input { background: #ffffff; }
body.clair .puce { background: #ffffff; color: #241f31; }
body.clair .empty, body.clair .attente p { color: #66607a; }
body.clair .attente .etats li { background: #f7f5fd; }
body.clair .panneau { box-shadow: 0 12px 30px rgba(26, 16, 48, .12); }
body.clair .panneau .ligne select, body.clair .panneau input { background: #ffffff; color: var(--text); }
body.clair #toast { background: #241f31; color: #ffffff; border-color: transparent; }
body.clair .pub .slot { background: #f7f5fd; }
body.clair a { color: #6a2ce0; }
body.clair .msg .mention { color: #8a5406; }   /* 3,68:1 avant : sous le seuil WCAG AA */
body.clair .file { background: #d99b18; color: #ffffff; }

/* ============================================================ telephone
   Sur petit ecran le chat occupe tout : la barre d'outils devient un tiroir
   qu'on ouvre par le bouton ⋯, et les cibles tactiles passent a 44 px. */

.seul-mobile { display: none; }

@media (max-width: 720px) {
  .seul-mobile { display: inline-block; }

  /* en-tete compact, pastilles qui defilent */
  .topbar { padding: 8px 10px; gap: 6px; flex-wrap: nowrap; overflow: hidden; }
  .topbar .vues, .topbar #btn-overlay, .topbar #btn-lien, .topbar .compteur { display: none; }
  body[data-view="accueil"] .topbar #btn-reglages { display: none; }
  .pill { padding: 6px 10px; font-size: 11px; }
  .btn { min-height: 40px; padding: 9px 14px; }

  /* la barre d'outils devient un tiroir qui monte du bas */
  .outils {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 30;
    display: none; flex-wrap: wrap; gap: 8px; padding: 14px 12px 18px;
    border-top: 1px solid var(--line); border-radius: 18px 18px 0 0;
    box-shadow: 0 -14px 40px rgba(0, 0, 0, .5);
    animation: monter .2s cubic-bezier(.2, .7, .3, 1) both;
  }
  body[data-view="chat"] .outils { display: none; }
  body.tiroir[data-view="chat"] .outils { display: flex; }
  .outils #recherche { flex: 1 1 100%; min-height: 44px; }
  .outils #pseudo { display: block; flex: 1 1 100%; min-height: 44px; }
  .groupe { flex: 1 1 100%; justify-content: space-between; }
  .btn.petit { flex: 1; min-height: 40px; text-align: center; justify-content: center; }

  /* le chat prend toute la place */
  .board { padding-bottom: 4px; }
  .msg { padding: 9px 12px 9px 13px; }
  .msg .ava { width: 18px; height: 18px; }
  .msg .hide-user { display: none; }
  .bandeau { padding: 6px 10px; }
  .bandeau .direct { font-size: 12px; padding: 5px 10px; }
  .bandeau .titre { max-width: 60vw; }

  /* le bandeau du bas se resume a une ligne */
  .pub { padding: 8px 10px; gap: 8px; }
  .pub .slot { min-height: 0; padding: 8px 10px; border: 0; background: transparent; }
  .pub .promo span { display: none; }

  /* accueil : une colonne, gros doigts */
  .accueil { padding: 22px 14px 40px; }
  .hero h1 { font-size: 30px; }
  .hero p.sub { font-size: 14px; }
  .field { padding: 8px 12px; }
  .field input { min-height: 46px; font-size: 16px; }   /* 16 px : evite le zoom automatique */
  .hero .actions { flex-wrap: wrap; }
  .hero .actions .btn { flex: 1 1 100%; }
  .exemples { gap: 6px; }
  .puce { min-height: 38px; }

  /* panneaux en feuille basse */
  .panneau {
    position: fixed; left: 8px; right: 8px; bottom: 8px; top: auto; width: auto;
    max-height: 70vh; border-radius: 18px;
  }
  #reprendre { bottom: 82px; }
}

/* tablette : deux colonnes de reglages, outils toujours visibles */
@media (min-width: 721px) and (max-width: 1024px) {
  .outils { flex-wrap: wrap; }
  #pseudo { width: 170px; }
  .hero { max-width: none; }
  .bandeau .titre { max-width: 300px; }
}

/* --- mode clair : ce qui restait blanc sur blanc */
body.clair .btn.on, body.clair .btn.primary {
  background: linear-gradient(135deg, var(--accent), var(--accent-clair));
  color: #ffffff;
}
body.clair .btn.petit.on { background: linear-gradient(135deg, var(--accent), var(--accent-clair)); }
body.clair .bandeau .titre { color: #241f31; }
body.clair .bandeau .cat, body.clair .bandeau .audience { color: #66607a; }
body.clair .brand { color: #191426; }
body.clair .attente .etats b { color: #66607a; }
body.clair .carte .liste li { border-top-color: var(--line); color: #3a3548; }

/* ============================================================ page d'accueil */

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

/* la mise en page de l'accueil est definie dans la passe sobre, en bas de ce fichier */
.plateformes-ligne { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 28px; }
.tag-plat {
  font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  padding: 5px 12px; border-radius: var(--r-plein); border: 1px solid;
}
.tag-plat.twitch { color: #b57bff; border-color: rgba(145, 70, 255, .5); }
.tag-plat.youtube { color: #ff6a62; border-color: rgba(255, 0, 51, .45); }
.tag-plat.tiktok { color: #45f6ef; border-color: rgba(0, 242, 234, .4); }
.tag-plat.kick { color: #7dff4a; border-color: rgba(83, 252, 24, .4); }
.hero form { max-width: 620px; }
.hero .note { font-size: 13px; color: var(--dim); margin-top: 18px; }

/* --- demonstration en direct */
.demo { padding-top: 20px; padding-bottom: 56px; }
.demo-tete p { color: var(--dim); font-size: 14px; max-width: 620px; margin: -8px 0 20px; line-height: 1.6; }
.demo-cadre {
  border: 1px solid var(--line); border-radius: var(--r3); overflow: hidden;
  background: linear-gradient(160deg, rgba(18, 18, 27, .96), rgba(8, 8, 13, .94));
  box-shadow: 0 24px 60px rgba(0, 0, 0, .45);
}
.demo-barre {
  display: flex; align-items: center; gap: 10px; padding: 10px 16px;
  border-bottom: 1px solid var(--line); font-size: 12px; color: var(--dim);
}
.demo-barre .voyant {
  width: 8px; height: 8px; border-radius: 50%; background: #4a5160;
}
.demo-barre .voyant.actif { background: var(--ok); box-shadow: 0 0 8px var(--ok); animation: pulsation 2.4s ease-in-out infinite; }
.demo-compteur { margin-left: auto; font-variant-numeric: tabular-nums; }
.demo-flux { height: 300px; overflow: hidden; padding: 6px 0; }
.demo-flux .msg { animation: glisser .25s cubic-bezier(.2, .7, .3, 1) both; }

/* --- avant / apres */
.probleme { padding-top: 20px; padding-bottom: 56px; }
.avant-apres { display: grid; grid-template-columns: 1fr auto 1fr; gap: 22px; align-items: center; }
.avant, .apres {
  border: 1px solid var(--line); border-radius: var(--r3); padding: 22px;
  background: var(--panel);
}
.etiquette {
  font-size: 10px; letter-spacing: .12em; text-transform: uppercase; color: var(--dim);
  display: block; margin-bottom: 14px;
}
.avant ul { list-style: none; margin: 0 0 14px; padding: 0; display: grid; gap: 8px; }
.avant li {
  padding: 10px 14px; border-radius: var(--r2); font-size: 13px; font-weight: 600;
  border-left: 3px solid; background: var(--panel-2);
}
.avant li.twitch { border-left-color: var(--twitch); }
.avant li.youtube { border-left-color: var(--youtube); }
.avant li.tiktok { border-left-color: var(--tiktok); }
.avant li.kick { border-left-color: var(--kick); }
.avant p, .apres p { font-size: 13px; color: var(--dim); margin: 0; line-height: 1.6; }
.fleche { font-size: 26px; color: var(--accent); }
.fusion {
  display: flex; align-items: center; gap: 8px; padding: 18px 16px; margin-bottom: 14px;
  border-radius: var(--r2); background: var(--panel-2);
  border: 1px solid rgba(155, 60, 255, .35);
}
.fusion strong { margin-left: 6px; font-size: 14px; }
.pastille { width: 12px; height: 12px; border-radius: 50%; }
/* conteneur des pastilles : sans lui, des span en ligne ignorent leur taille */
#probleme-pastilles { display: flex; align-items: center; gap: 6px; }
.pastille.twitch { background: var(--twitch); }
.pastille.youtube { background: var(--youtube); }
.pastille.tiktok { background: var(--tiktok); }
.pastille.kick { background: var(--kick); }

/* --- fonctions */
.fonctions { padding-bottom: 56px; }
.grille-fonctions { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 14px; }
.grille-fonctions article {
  border: 1px solid var(--line); border-radius: var(--r3); padding: 20px;
  background: var(--panel); transition: border-color var(--transition), transform var(--transition);
}
.grille-fonctions article:hover { border-color: rgba(155, 60, 255, .45); transform: translateY(-2px); }
.grille-fonctions h3 { margin: 0 0 8px; font-size: 15px; }
.grille-fonctions p { margin: 0; font-size: 13px; color: var(--dim); line-height: 1.6; }

/* --- tarifs */
.grille-tarifs { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 16px; }
.carte-tarif {
  position: relative; border: 1px solid var(--line); border-radius: var(--r3); padding: 26px;
  background: var(--panel); display: flex; flex-direction: column; gap: 10px;
}
.carte-tarif.mise-en-avant { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent) inset; }
.carte-tarif h3 { margin: 0; font-size: 16px; }
.carte-tarif .montant { font-size: 32px; font-weight: 800; }
.carte-tarif .montant small { font-size: 13px; font-weight: 500; color: var(--dim); }
.carte-tarif .mensuel { font-size: 13px; color: var(--ok); margin: -6px 0 0; }
.carte-tarif p { font-size: 13px; color: var(--dim); line-height: 1.6; margin: 0; }
.carte-tarif .btn { margin-top: auto; text-align: center; text-decoration: none; }
.badge-eco {
  position: absolute; top: -11px; right: 18px;
  background: linear-gradient(135deg, var(--accent), var(--accent-clair)); color: #fff;
  font-size: 10px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase;
  padding: 4px 12px; border-radius: var(--r-plein);
}

body.clair .avant, body.clair .apres, body.clair .grille-fonctions article,
body.clair .carte-tarif, body.clair .demo-cadre { background: #ffffff; }
body.clair .avant li, body.clair .fusion { background: #f7f5fd; }

@media (max-width: 860px) {
  .hero { padding-top: 34px; }
  .hero h1 { font-size: 36px; }
  .avant-apres { grid-template-columns: 1fr; }
  .fleche { transform: rotate(90deg); text-align: center; }
  .demo-flux { height: 240px; }
}

.demo-flux .msg.historique { opacity: 1; }
.demo-flux .msg .txt { color: #e9ebf4; }
body.clair .demo-flux .msg .txt { color: #241f31; }

/* --- grille des plateformes (page dediee) */
.grille-regions { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 14px; }
.region {
  border: 1px solid var(--line); border-radius: var(--r3); padding: 18px; background: var(--panel);
}
.region h3 {
  margin: 0 0 12px; font-size: 11px; letter-spacing: .12em; text-transform: uppercase; color: var(--dim);
}
.region ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 7px; }
.region li { display: flex; align-items: center; gap: 9px; font-size: 13px; }
.region .point { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.region .nom { flex: 1; }
.region .etat { font-size: 10px; letter-spacing: .04em; text-transform: uppercase; color: var(--dim); }
.region .etat.ok { color: var(--ok); }
.region .etat.attente { color: #e5a83c; }
.region .etat.non { color: #8b8599; }
body.clair .region { background: #ffffff; }

/* ---------------------------------------------------------- copilote (offre IA) */
/* Le panneau du copilote est plus large que les autres : il montre des listes, pas
   deux reglages. Sur telephone il devient une feuille pleine hauteur. */
.panneau.large { width: 420px; max-height: calc(100vh - 130px); overflow-y: auto; }

.etat-ia {
  float: right; font-size: 10px; letter-spacing: .04em; text-transform: none;
  padding: 2px 8px; border-radius: 999px; border: 1px solid var(--line); color: var(--dim);
}
.etat-ia.ok { color: var(--ok); border-color: color-mix(in srgb, var(--ok) 45%, transparent); }
.etat-ia.non { color: #e5a83c; border-color: rgba(229, 168, 60, .4); }

.ia-verrou p { font-size: 13px; line-height: 1.65; color: #c9d0de; margin: 0 0 12px; }
.ia-verrou .btn { width: 100%; text-align: center; text-decoration: none; }

.ia-onglets { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 14px; }
/* les onglets forment une rangee : sans ca, ils heritent du « bouton pleine largeur »
   des panneaux et s'empilent */
.ia-onglets .btn { width: auto; margin: 0; padding: 6px 12px; }

.ia-bloc { border-top: 1px solid var(--line); padding: 12px 0 4px; }
.ia-bloc:first-child { border-top: 0; padding-top: 0; }
.ia-bloc > header {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  flex-wrap: wrap; margin-bottom: 8px;
}
.ia-bloc h3 {
  margin: 0; font-size: 11px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--dim); font-weight: 700;
}
.ia-bloc .btn.petit { width: auto; margin: 0; }
.ia-actions { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.ia-actions select, .ia-actions input {
  background: #0a0c10; border: 1px solid var(--line); border-radius: 7px;
  color: var(--text); font: inherit; font-size: 12px; padding: 5px 8px; max-width: 150px;
}

.ia-sortie { font-size: 13px; }
.ia-message { margin: 0; color: var(--dim); font-size: 12px; line-height: 1.6; }
.ia-message.ok { color: var(--ok); }
.ia-message.non { color: #e5a83c; }
.ia-texte { margin: 0 0 10px; line-height: 1.6; color: #d9dfea; }
.ia-source {
  margin: 10px 0 0; font-size: 11px; line-height: 1.55; color: var(--dim);
  border-left: 2px solid var(--line); padding-left: 8px;
}
.ia-sortie h4 {
  margin: 12px 0 6px; font-size: 10px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--dim); font-weight: 700;
}

.ia-liste { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.ia-liste li {
  display: block; padding: 8px 10px; border: 1px solid var(--line); border-radius: 9px;
  background: color-mix(in srgb, var(--panel) 60%, transparent);
}
.ia-liste li.fort { border-color: rgba(229, 168, 60, .45); }
.ia-liste li b { display: block; font-size: 13px; line-height: 1.45; }
.ia-liste li span { display: block; font-size: 11px; color: var(--dim); margin-top: 2px; line-height: 1.5; }
.ia-liste li .cite { font-style: italic; opacity: .85; }

.ia-puces { display: flex; flex-wrap: wrap; gap: 6px; margin: 8px 0 0; }
.puce-ia {
  font-size: 11px; padding: 3px 9px; border-radius: 999px;
  border: 1px solid var(--line); color: #c9d0de;
}

.ia-jauges { display: grid; gap: 7px; }
.ia-jauge { display: grid; grid-template-columns: 74px 1fr 62px; align-items: center; gap: 8px; }
.ia-jauge .nom { font-size: 11px; color: var(--dim); }
.ia-jauge .barre { height: 7px; border-radius: 999px; background: var(--line); overflow: hidden; }
.ia-jauge .barre i { display: block; height: 100%; border-radius: 999px; background: var(--accent); transition: width .35s ease; }
.ia-jauge .val { font-size: 11px; text-align: right; font-variant-numeric: tabular-nums; color: #c9d0de; }
.ia-jauge .val em { font-style: normal; color: var(--dim); }
.ia-jauge[data-cat="hype"] .barre i { background: #f0a12e; }
.ia-jauge[data-cat="rire"] .barre i { background: #45c8f0; }
.ia-jauge[data-cat="soutien"] .barre i { background: var(--ok); }
.ia-jauge[data-cat="frustration"] .barre i { background: #e5a83c; }
.ia-jauge[data-cat="toxique"] .barre i { background: #e2564f; }

/* la traduction collee sous un message du chat */
.msg .traduction {
  margin-top: 3px; padding-left: 8px; font-size: .92em; line-height: 1.45;
  color: var(--dim); border-left: 2px solid color-mix(in srgb, var(--accent) 50%, transparent);
}

/* le bouton Copilote ne s'affiche qu'avec une cle, comme les autres reserves */
body:not([data-niveau="ia"]) .btn.ia.verrouille::after { background: var(--accent-clair); opacity: .9; }

@media (max-width: 780px) {
  .panneau.large {
    position: fixed; inset: auto 0 0 0; width: auto; max-height: 78vh;
    border-radius: 16px 16px 0 0; padding: 16px 16px 22px;
  }
  .ia-onglets { position: sticky; top: 0; background: var(--panel); padding: 6px 0; z-index: 1; }
  .ia-onglets .btn.petit { flex: 1 1 auto; }
  .ia-jauge { grid-template-columns: 66px 1fr 56px; }
  .ia-actions { width: 100%; }
  .ia-actions select, .ia-actions input { flex: 1; max-width: none; }
  .ia-bloc > header { flex-direction: column; align-items: flex-start; gap: 8px; }
  .ia-bloc > header .btn.petit, .ia-actions { align-self: stretch; }
  .ia-bloc > header .btn.petit { text-align: center; }
}

/* --- section copilote de la page d'accueil */
.copilote { padding-bottom: 56px; }
.copilote-tete { max-width: 640px; margin-bottom: 24px; }
.copilote-tete h2 { margin: 8px 0 10px; }
.copilote-tete p { margin: 0; color: var(--dim); font-size: 15px; line-height: 1.65; }
.grille-copilote { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 12px; }
.grille-copilote article {
  border: 1px solid var(--line); border-radius: var(--r3); padding: 16px 18px;
  background: var(--panel); transition: border-color var(--transition), transform var(--transition);
}
.grille-copilote article:hover { border-color: rgba(139, 53, 255, .5); transform: translateY(-2px); }
.grille-copilote h3 { margin: 0 0 6px; font-size: 14px; }
.grille-copilote p { margin: 0; font-size: 12.5px; color: var(--dim); line-height: 1.55; }
.copilote-note {
  margin: 18px 0 0; font-size: 13px; color: var(--dim); line-height: 1.6; max-width: 700px;
  border-left: 2px solid var(--line); padding-left: 12px;
}

.carte-tarif.ia { border-color: rgba(139, 53, 255, .55); box-shadow: 0 0 0 1px rgba(139, 53, 255, .35) inset; }
.carte-tarif.ia .montant { color: #c98bff; }
.carte-tarif.ia .mensuel { color: #c98bff; }
.badge-ia { background: #8b35ff; right: auto; left: 18px; }

body.clair .grille-copilote article { background: #fff; }
body.clair .carte-tarif.ia .montant, body.clair .carte-tarif.ia .mensuel { color: #6a1fd0; }
body.clair .offre.ia .prix { color: #6a1fd0; }

@media (max-width: 720px) {
  .grille-copilote { grid-template-columns: 1fr 1fr; gap: 8px; }
  .grille-copilote article { padding: 12px 13px; }
  .grille-copilote h3 { font-size: 13px; }
  .grille-copilote p { font-size: 12px; }
  .copilote-tete p { font-size: 14px; }
}

/* ---------------------------------------------------------- page des plateformes */
.grille-regions.detaillee { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
.grille-regions.detaillee li {
  display: grid; grid-template-columns: 9px 1fr auto; gap: 4px 9px; align-items: center;
  padding: 8px 0; border-bottom: 1px solid var(--line);
}
.grille-regions.detaillee li:last-child { border-bottom: 0; }
.grille-regions.detaillee .note {
  grid-column: 2 / -1; font-size: 11.5px; color: var(--dim); line-height: 1.5;
}

/* liens de la barre du haut, visibles seulement sur l'accueil */
.seul-accueil { display: none; text-decoration: none; }
body[data-view="accueil"] .seul-accueil { display: inline-flex; align-items: center; }
.probleme-note { margin: 18px 0 0; font-size: 13px; }
.probleme-note a { color: var(--accent); text-decoration: none; border-bottom: 1px solid transparent; }
.probleme-note a:hover { border-bottom-color: currentColor; }

/* la demonstration au repos */
.demo-cadre { position: relative; }
.demo-repos {
  display: none; flex-direction: column; align-items: center; gap: 12px;
  padding: 40px 24px; text-align: center;
}
.demo-cadre[data-etat="repos"] .demo-repos { display: flex; }
.demo-cadre[data-etat="repos"] .demo-barre, .demo-cadre[data-etat="repos"] .demo-flux { display: none; }
.demo-repos p { margin: 0; max-width: 420px; font-size: 13px; color: var(--dim); line-height: 1.6; }
#demo-arreter { margin: 10px auto 12px; display: block; }
#demo-arreter[hidden] { display: none; }

@media (max-width: 780px) {
  .seul-accueil { font-size: 12px; padding: 6px 10px; }
  body[data-view="accueil"] .seul-accueil[href="plateformes"] { display: none; }
  body[data-view="accueil"] .topbar .btn.primary { padding: 7px 13px; font-size: 12px; }
  .demo-repos { padding: 26px 16px; }
}

/* ============================================================ passe sobre
   Cette couche remplace l'habillage precedent (halos violets, degrades, titre en
   italique). Le principe : peu de couleur, beaucoup d'air, des titres qui portent le
   message, et rien qui brille. Le chat garde sa densite : ce sont les pages publiques
   qui changent de ton.
   Elle vient en dernier pour neutraliser ce qui la precede sans avoir a le retirer
   ligne par ligne. */

:root {
  --bg: #000000;
  --panel: #0e0e10;
  --panel-2: #16161a;
  --line: rgba(255, 255, 255, .12);
  --text: #f5f5f7;
  --dim: #86868b;
  --accent: #7c5cff;
  --accent-clair: #9b7dff;
  --ok: #32d74b;
  --r1: 10px; --r2: 14px; --r3: 20px;
  --ombre: none;
  --marge-page: 1120px;
}

body {
  background: var(--bg);
  font-family: 'Inter', -apple-system, 'Segoe UI', system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
  letter-spacing: -.011em;
}

/* --- plus de degrades ni de lueurs nulle part */
.topbar, .outils, .bandeau, .pub, .pied, .col header,
.demo-cadre, .btn, .btn.primary, .btn.on, .field {
  background-image: none;
}
.topbar, .outils, .bandeau, .pub, .col header { background-color: rgba(10, 10, 12, .82); }
.pill[data-state="on"]::after, .demo-barre .voyant.actif, .eyebrow::before { box-shadow: none; }
.demo-cadre { box-shadow: none; }

/* --- typographie : une seule famille, du poids et un interlettrage serre */
button.brand {
  font-family: inherit; font-size: 15px; font-weight: 700;
  letter-spacing: -.01em; text-transform: none;
}
button.brand b { color: var(--text); font-weight: 700; }
.hero h1, .accueil h2, .page h1 {
  font-family: inherit; font-style: normal; font-weight: 700;
}
.eyebrow {
  font-size: 12px; font-weight: 600; letter-spacing: 0; text-transform: none;
  color: var(--dim); margin-bottom: 10px; display: block;
}
.eyebrow::before { display: none; }

/* --- boutons : pleins ou en texte, jamais decores */
.btn {
  border-radius: var(--r-plein); border: 1px solid var(--line);
  background-color: transparent; color: var(--text); font-weight: 500;
}
.btn:hover { background-color: rgba(255, 255, 255, .08); }
.btn.primary {
  background-color: var(--accent); border-color: var(--accent); color: #fff; font-weight: 600;
}
.btn.primary:hover { background-color: var(--accent-clair); filter: none; }
.btn.on { background-color: var(--accent); border-color: var(--accent); color: #fff; }

/* ------------------------------------------------------------ pages publiques */

.accueil { padding: 0 0 0; }
/* la specificite compte : cette regle doit ceder le pas aux sections qui veulent
   leur propre respiration verticale, d'ou le padding horizontal seul */
.accueil > section { max-width: var(--marge-page); margin: 0 auto; padding-left: 26px; padding-right: 26px; }
.accueil h2 {
  font-size: clamp(30px, 4vw, 46px); line-height: 1.08; letter-spacing: -.025em;
  margin: 0 0 16px;
}

/* --- ouverture : le titre d'abord, le formulaire ensuite */
.hero { padding-top: 96px; padding-bottom: 84px; text-align: center; }
.hero h1 {
  font-size: clamp(38px, 6.4vw, 72px); line-height: 1.05; letter-spacing: -.035em;
  margin: 0 auto 20px; max-width: 22ch;
}
.hero .accent { color: var(--dim); }
.hero p.sub {
  font-size: clamp(17px, 1.6vw, 20px); line-height: 1.5; color: var(--dim);
  max-width: 48ch; margin: 0 auto 32px;
}
.plateformes-ligne { justify-content: center; gap: 10px; margin: 0 0 34px; }
.tag-plat {
  font-size: 12px; font-weight: 500; letter-spacing: 0; text-transform: none;
  padding: 6px 14px; color: var(--dim); border-color: var(--line);
}
.tag-plat.twitch, .tag-plat.youtube, .tag-plat.tiktok, .tag-plat.kick {
  color: var(--dim); border-color: var(--line);
}
.hero form { max-width: 460px; margin: 0 auto; text-align: left; }
.hero .actions { justify-content: center; }
.hero .exemples { justify-content: center; }
.hero .note { font-size: 13px; color: var(--dim); margin-top: 20px; text-align: center; }

/* --- les sections alternent le fond, comme des plans successifs */
.demo, .fonctions, .tarifs { background: var(--panel); }
.demo, .probleme, .fonctions, .copilote, .tarifs { padding-top: 96px; padding-bottom: 96px; }
.accueil > section.demo, .accueil > section.fonctions, .accueil > section.tarifs {
  max-width: none;
}
.demo > *, .fonctions > *, .tarifs > * { max-width: var(--marge-page); margin-left: auto; margin-right: auto; }

.demo-tete, .copilote-tete { text-align: center; }
.demo-tete p, .copilote-tete p {
  font-size: 17px; line-height: 1.5; color: var(--dim); max-width: 46ch; margin: 0 auto 34px;
}

.demo-cadre {
  border: 1px solid var(--line); border-radius: var(--r3); background: var(--bg);
  max-width: 900px; margin: 0 auto;
}
.demo-repos { padding: 72px 26px; }
.demo-repos p { font-size: 14px; max-width: 38ch; }
.demo-flux { height: 340px; }

/* --- avant / apres : deux colonnes, pas de fleche criarde */
.probleme h2, .fonctions h2, .tarifs h2 { text-align: center; }
.avant-apres { max-width: 900px; margin: 0 auto; gap: 26px; }
.avant, .apres { background: var(--panel); border: 0; border-radius: var(--r3); padding: 28px; }
.avant li { background: var(--panel-2); font-weight: 500; }
.fleche { color: var(--dim); font-size: 22px; }
.fusion { background: var(--panel-2); border: 0; }
.probleme-note { text-align: center; margin-top: 26px; }
.probleme-note a { color: var(--accent-clair); }

/* --- fonctions et copilote : des cartes calmes */
.grille-fonctions article, .grille-copilote article {
  background: var(--bg); border: 1px solid var(--line); border-radius: var(--r3); padding: 26px;
}
.grille-fonctions article:hover, .grille-copilote article:hover {
  border-color: rgba(255, 255, 255, .22); transform: none;
}
.grille-fonctions h3, .grille-copilote h3 { font-size: 17px; font-weight: 600; margin-bottom: 8px; }
.grille-fonctions p, .grille-copilote p { font-size: 14px; line-height: 1.55; }
.copilote-note { text-align: center; border: 0; padding: 0; max-width: 52ch; margin: 30px auto 0; }

/* --- tarifs : le prix se lit de loin */
.grille-tarifs { max-width: 1000px; margin: 0 auto; }
.carte-tarif {
  background: var(--bg); border: 1px solid var(--line); border-radius: var(--r3);
  padding: 34px 30px; gap: 12px;
}
.carte-tarif.mise-en-avant, .carte-tarif.ia { box-shadow: none; }
.carte-tarif.mise-en-avant { border-color: rgba(255, 255, 255, .28); }
.carte-tarif.ia { border-color: var(--accent); }
.carte-tarif h3 { font-size: 15px; font-weight: 600; color: var(--dim); letter-spacing: 0; }
.carte-tarif .montant { font-size: 44px; letter-spacing: -.03em; font-weight: 700; }
.carte-tarif .montant small { font-size: 15px; font-weight: 400; }
.carte-tarif .mensuel { color: var(--dim); }
.carte-tarif.ia .montant, .carte-tarif.ia .mensuel { color: var(--text); }
.carte-tarif p { font-size: 14px; }
/* les boutons s'alignent en bas des trois cartes, quelle que soit la longueur du texte */
.carte-tarif .btn { margin-top: auto; padding: 12px 18px; }
.carte-tarif p:last-of-type { margin-bottom: 18px; }
.badge-eco, .badge-ia {
  position: static; align-self: flex-start; margin-bottom: 2px;
  background: var(--panel-2); color: var(--dim); font-weight: 600; letter-spacing: 0;
  text-transform: none; font-size: 11px; padding: 4px 10px; border: 1px solid var(--line);
}
.badge-ia { background: var(--accent); color: #fff; border-color: var(--accent); }
.offre .badge-ia { position: static; align-self: flex-start; margin-bottom: 6px; }

/* --- barre du haut sur les pages publiques : discrete, collante */
body[data-view="accueil"] .topbar {
  position: sticky; top: 0; z-index: 20;
  background-color: rgba(0, 0, 0, .72);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
  border-bottom: 1px solid var(--line);
  padding: 12px 26px;
}
body[data-view="accueil"] .topbar .btn {
  border: 0; font-size: 13px; color: var(--dim); padding: 6px 10px;
}
body[data-view="accueil"] .topbar .btn:hover { color: var(--text); background: transparent; }
body[data-view="accueil"] .topbar .btn.primary {
  color: #fff; background-color: var(--accent); padding: 7px 16px;
}

/* --- le pied de page ferme la page au lieu de flotter au-dessus du contenu */
body[data-view="accueil"] .pied {
  border-top: 1px solid var(--line); background: var(--bg); padding: 28px 26px;
}
body[data-view="accueil"] { overflow: auto; }

/* --- champs : gris neutre, la couleur reste dans le logo */
.field {
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--r2);
  padding: 12px 16px;
}
.field:hover { transform: none; border-color: rgba(255, 255, 255, .22); }
.field.twitch, .field.kick, .field.youtube, .field.tiktok, .field.licence {
  border-color: var(--line); background: var(--panel);
}
.field:focus-within { border-color: var(--accent); }
.field input::placeholder { color: var(--dim); }
body.clair .field { background: var(--panel); }
#etat-licence { color: var(--dim); font-size: 11px; }

/* --- action secondaire : un lien, pas un deuxieme bouton */
.hero .actions { gap: 18px; align-items: center; }
.hero .actions .btn.primary { padding: 12px 26px; font-size: 15px; }
.hero .actions a.btn:not(.primary) {
  border: 0; background: none; color: var(--accent-clair); text-decoration: none;
  padding: 6px 0; font-size: 15px;
}
.hero .actions a.btn:not(.primary):hover { background: none; text-decoration: underline; }
.hero .actions a.btn:not(.primary)::after { content: ' ›'; }

/* --- le pied de page se place a la fin du recit, pas au-dessus */
body[data-view="accueil"] .pied { display: none; }
.pied-page {
  border-top: 1px solid var(--line); padding: 40px 26px; text-align: center;
  font-size: 13px; color: var(--dim);
}
.pied-page a { color: var(--dim); text-decoration: none; }
.pied-page a:hover { color: var(--text); }
.pied-page .liens { display: flex; flex-wrap: wrap; gap: 20px; justify-content: center; margin-bottom: 14px; }

/* --- pages autonomes : offre, plateformes, confidentialite */
.page { max-width: 980px; }
.page h1 {
  font-size: clamp(34px, 5vw, 52px); line-height: 1.06; letter-spacing: -.03em; margin-bottom: 14px;
}
.page .chapeau { font-size: 17px; line-height: 1.55; }
.offre, .cle, .questions details {
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--r3);
}
.offre.mise-en-avant { border-color: rgba(255, 255, 255, .28); box-shadow: none; }
.offre.ia { border-color: var(--accent); box-shadow: none; }
.offre .prix { font-size: 40px; letter-spacing: -.03em; }
.offre.ia .prix { color: var(--text); }
.offre li { color: #d2d2d7; }
.offre .btn { border-radius: var(--r-plein); }
.offre.ia .btn.primary { background-color: var(--accent); border-color: var(--accent); }
.region { background: var(--panel); border: 1px solid var(--line); border-radius: var(--r3); padding: 24px; }
.region h3 { color: var(--dim); font-size: 12px; }

/* ------------------------------------------------------------ mode clair */
body.clair {
  --bg: #ffffff;
  --panel: #f5f5f7;
  --panel-2: #ebebef;
  --line: rgba(0, 0, 0, .12);
  --text: #1d1d1f;
  --dim: #6e6e73;
  --accent: #6c47e6;
  --accent-clair: #8560f0;
}
body.clair .topbar, body.clair .outils, body.clair .bandeau, body.clair .pub, body.clair .col header {
  background-color: rgba(255, 255, 255, .86);
}
body.clair[data-view="accueil"] .topbar { background-color: rgba(255, 255, 255, .78); }
body.clair .demo-cadre, body.clair .grille-fonctions article, body.clair .grille-copilote article,
body.clair .carte-tarif, body.clair .avant, body.clair .apres { background: var(--bg); }
body.clair .demo, body.clair .fonctions, body.clair .tarifs { background: var(--panel); }
body.clair .offre li { color: #3a3a3c; }
body.clair .hero .accent { color: var(--dim); }

/* ------------------------------------------------------------ telephone */
@media (max-width: 780px) {
  .hero { padding-top: 56px; padding-bottom: 52px; }
  .hero h1 { max-width: none; letter-spacing: -.03em; }
  .hero p.sub { max-width: none; font-size: 16px; }
  .demo, .probleme, .fonctions, .copilote, .tarifs { padding-top: 60px; padding-bottom: 60px; }
  .accueil > section { padding: 0 20px; }
  .avant, .apres, .carte-tarif { padding: 22px; }
  .demo-flux { height: 260px; }
  .demo-repos { padding: 44px 20px; }
  .carte-tarif .montant { font-size: 36px; }
  body[data-view="accueil"] .topbar { padding: 10px 16px; }
  .grille-fonctions article, .grille-copilote article { padding: 20px; }
}

/* --- un mouvement, discret : le contenu monte quand il entre dans l'ecran */
@media (prefers-reduced-motion: no-preference) {
  .accueil > section > * { animation: monter .6s cubic-bezier(.16, 1, .3, 1) both; }
  @keyframes monter { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
}

/* ============================================================ finition du chat
   Le chat est l'ecran ou l'on passe des heures : il doit se lire vite et sans fatigue.
   Trois choix ici : le pseudo et le texte se distinguent nettement, une ligne sur deux
   n'est pas grisee (ca fatigue sur un flux rapide) mais separee d'un filet tres fin, et
   tout ce qui n'est pas le message (heure, badges, boutons) recule d'un cran. */

.msg { padding: 6px 14px 6px 15px; line-height: 1.5; }
.msg + .msg { border-top: 1px solid rgba(255, 255, 255, .04); }
.msg:hover { background: rgba(255, 255, 255, .04); }
.msg .time { font-size: 10.5px; opacity: .45; margin-right: 8px; }
.msg:hover .time { opacity: .8; }
.msg .who { font-weight: 600; letter-spacing: -.005em; }
.msg .sep { opacity: .45; }
.msg .txt { color: #e3e7ef; }
body.clair .msg .txt { color: #26232c; }

/* badges : petits, sobres, jamais plus de trois */
.msg .bdg { width: 15px; height: 15px; vertical-align: -3px; margin-right: 4px; }
.msg .bdg-txt {
  display: inline-block; margin-right: 4px; padding: 1px 5px; border-radius: 4px;
  font-size: 9px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  vertical-align: 1.5px; background: rgba(255, 255, 255, .1); color: var(--dim);
}
body.clair .msg .bdg-txt { background: rgba(0, 0, 0, .07); color: var(--dim); }
.msg.twitch .bdg-txt { color: #c7a6ff; }
.msg.kick .bdg-txt { color: #9ff07a; }
.msg.youtube .bdg-txt { color: #ff9b96; }
.msg.tiktok .bdg-txt { color: #7ff2ec; }

/* le bouton « masquer » ne doit pas attirer l'oeil avant qu'on en ait besoin */
.msg .hide-user { opacity: 0; transition: opacity var(--transition); }
.msg:hover .hide-user { opacity: .5; }
.msg .hide-user:hover { opacity: 1; }

/* barre des directs : une ligne compacte, le titre garde sa place */
.bandeau { padding: 7px 14px; gap: 7px; }
.bandeau .direct {
  padding: 5px 12px; font-size: 12.5px; background: rgba(255, 255, 255, .04);
  border: 1px solid var(--line); border-left-width: 3px;
  /* le titre a la priorite sur la categorie et le compteur, qui ne se coupent pas */
  max-width: min(620px, 48vw);
}
.bandeau .direct .titre { flex: 1 1 auto; min-width: 8ch; max-width: none; }
body.clair .bandeau .direct { background: rgba(0, 0, 0, .03); }
.bandeau .direct .titre { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bandeau .direct .compte { color: var(--dim); font-variant-numeric: tabular-nums; flex: none; }

/* en-tete de colonne, en vue separee */
.col header {
  letter-spacing: .04em; text-transform: none; font-size: 12px; font-weight: 600;
  padding: 8px 12px; border-bottom: 1px solid var(--line);
}
.col header .dot { width: 6px; height: 6px; }

/* retour au direct : discret mais trouvable */
#reprendre {
  border-radius: var(--r-plein); font-size: 12.5px; font-weight: 600; padding: 8px 16px;
  background: var(--accent); border: 0; box-shadow: 0 4px 16px rgba(0, 0, 0, .4);
}
#reprendre:hover { background: var(--accent-clair); filter: none; }

/* ce qu'on voit quand une colonne n'a encore rien recu */
.col .attente, .board .attente {
  padding: 22px 16px; text-align: center; color: var(--dim); font-size: 12.5px; line-height: 1.6;
}

/* barre d'outils : les groupes se lisent comme des blocs, pas comme une rangee de boutons */
.outils { padding: 9px 14px; gap: 9px; }
.outils input { font-size: 13px; }
.outils .groupe { background: rgba(255, 255, 255, .04); border: 1px solid var(--line); }
body.clair .outils .groupe { background: rgba(0, 0, 0, .03); }
.outils .etiquette { font-size: 9.5px; letter-spacing: .1em; color: var(--dim); }
.outils .btn.petit { font-size: 12px; padding: 6px 11px; }

/* barre du haut du chat : le compteur et les pastilles respirent */
body[data-view="chat"] .topbar { padding: 9px 14px; }
.pill { font-size: 11.5px; padding: 4px 11px; }
.compteur { font-size: 11.5px; color: var(--dim); font-variant-numeric: tabular-nums; }

/* le fil garde une largeur de lecture confortable en vue melangee sur grand ecran */
@media (min-width: 1500px) {
  .board:not(.separe) .msg { max-width: 1400px; }
}

/* --- bandeau du bas, version sobre : une phrase, un bouton, pas de clignotant */
.pub { padding: 12px 16px; gap: 14px; align-items: center; }
.pub .promo { text-decoration: none; display: block; }
.pub .promo b { display: block; font-size: 13.5px; font-weight: 600; margin-bottom: 3px; }
.pub .promo span { font-size: 12.5px; color: var(--dim); line-height: 1.5; }
.pub .btn { flex: none; }
body[data-view="accueil"] .pub { display: none; }

/* ============================================================ barre en pilule
   Reprise de la maquette fournie : une barre flottante aux angles très arrondis,
   translucide sur le fond, bordure fine, ombre basse, liens en petites capitales avec
   un soulignement qui se déploie au survol. La police reste Inter (servie en local) :
   la maquette utilisait Poppins via Google Fonts, que la politique de sécurité du site
   interdit de charger. */

.pilule {
  position: sticky; top: 14px; z-index: 40;
  display: flex; align-items: center; gap: 22px;
  max-width: var(--marge-page); margin: 14px auto 0;
  padding: 0 26px; height: 66px;
  border-radius: 26px;
  background: rgba(18, 18, 22, .55);
  border: 1px solid rgba(255, 255, 255, .1);
  box-shadow: 0 10px 15px -3px rgba(0, 0, 0, .28), 0 4px 6px -4px rgba(0, 0, 0, .3);
  -webkit-backdrop-filter: saturate(160%) blur(18px);
  backdrop-filter: saturate(160%) blur(18px);
  color: #fff;
  transition: background-color .3s cubic-bezier(.4, 0, .2, 1), border-color .3s cubic-bezier(.4, 0, .2, 1);
}
body.clair .pilule {
  background: rgba(255, 255, 255, .72);
  border-color: rgba(0, 0, 0, .08);
  color: var(--text);
}

.pilule .marque {
  font-size: 15px; font-weight: 700; letter-spacing: -.01em;
  text-decoration: none; color: inherit; flex: none;
}
.pilule .marque b { color: inherit; }

.pilule nav { display: flex; align-items: center; gap: 34px; flex: 1 1 auto; }

.pilule a.lien {
  position: relative; display: inline-flex; align-items: center;
  font-size: 12px; font-weight: 500; letter-spacing: .08em; text-transform: uppercase;
  color: inherit; text-decoration: none; padding: 10px 0; white-space: nowrap; opacity: .85;
}
.pilule a.lien::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 4px; height: 1px;
  background: currentColor; transform: scaleX(0); transform-origin: left;
  transition: transform .3s cubic-bezier(.4, 0, .2, 1);
}
.pilule a.lien:hover { opacity: 1; }
.pilule a.lien:hover::after { transform: scaleX(1); }

/* la pastille de la maquette, ici pour signaler l'offre récente */
.pilule .pastille {
  margin-left: 7px; padding: 3px 6px; border-radius: 6px;
  background: var(--accent); color: #fff;
  font-size: 9px; font-weight: 600; letter-spacing: .08em; line-height: 1; text-transform: uppercase;
}

.pilule .droite { display: flex; align-items: center; gap: 12px; flex: none; }
.pilule .btn { border-radius: var(--r-plein); font-size: 12.5px; padding: 9px 18px; }
.pilule .btn.primary { background: var(--accent); border-color: var(--accent); color: #fff; }

/* la barre du haut de l'accueil adopte la même forme */
body[data-view="accueil"] .topbar {
  position: sticky; top: 14px; z-index: 40;
  max-width: var(--marge-page); margin: 14px auto 0;
  height: 66px; padding: 0 26px;
  border-radius: 26px;
  background: rgba(18, 18, 22, .55);
  border: 1px solid rgba(255, 255, 255, .1);
  box-shadow: 0 10px 15px -3px rgba(0, 0, 0, .28), 0 4px 6px -4px rgba(0, 0, 0, .3);
}
body.clair[data-view="accueil"] .topbar {
  background: rgba(255, 255, 255, .72);
  border-color: rgba(0, 0, 0, .08);
}
body[data-view="accueil"] .topbar .brand { font-size: 15px; letter-spacing: -.01em; }
body[data-view="accueil"] .topbar .seul-accueil {
  font-size: 12px; font-weight: 500; letter-spacing: .08em; text-transform: uppercase;
  position: relative; opacity: .85; padding: 10px 0; margin: 0 6px;
}
body[data-view="accueil"] .topbar .seul-accueil:hover { opacity: 1; }
body[data-view="accueil"] .topbar .seul-accueil:not(.primary)::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 4px; height: 1px;
  background: currentColor; transform: scaleX(0); transform-origin: left;
  transition: transform .3s cubic-bezier(.4, 0, .2, 1);
}
body[data-view="accueil"] .topbar .seul-accueil:not(.primary):hover::after { transform: scaleX(1); }
body[data-view="accueil"] .topbar .seul-accueil.primary {
  text-transform: none; letter-spacing: 0; font-weight: 600; padding: 9px 18px; margin-left: 10px;
}
/* le premier écran commence sous la barre flottante */
body[data-view="accueil"] .hero { padding-top: 76px; }

@media (max-width: 780px) {
  .pilule, body[data-view="accueil"] .topbar {
    top: 8px; margin: 8px 12px 0; height: 58px; padding: 0 16px; border-radius: 20px; gap: 10px;
  }
  .pilule nav { gap: 16px; overflow-x: auto; scrollbar-width: none; }
  .pilule nav::-webkit-scrollbar { display: none; }
  .pilule a.lien { font-size: 11px; letter-spacing: .06em; }
  body[data-view="accueil"] .hero { padding-top: 52px; }
}

/* --- les outils du chat n'ont rien a faire sur la page d'accueil : il n'y a pas de chat */
body[data-view="accueil"] .vues,
body[data-view="accueil"] #btn-overlay,
body[data-view="accueil"] #btn-lien,
body[data-view="accueil"] #btn-reglages,
body[data-view="accueil"] #btn-outils-mobile,
body[data-view="accueil"] .compteur,
body[data-view="accueil"] .outils { display: none; }
body[data-view="accueil"] .topbar .grow { flex: 1 1 auto; }
body[data-view="accueil"] .topbar .pastille {
  width: auto; height: auto; border-radius: 6px; margin-left: 6px; padding: 3px 6px;
  background: var(--accent); color: #fff;
  font-size: 9px; font-weight: 600; letter-spacing: .08em; line-height: 1;
}

/* ============================================================ verre liquide
   Toutes les surfaces qui flottent au-dessus du contenu — barres, panneaux, cartes,
   bandeaux — passent en verre : fond très translucide, flou d'arrière-plan, un liseré
   clair en haut qui imite la tranche éclairée, une ombre basse pour décoller du fond.

   Deux règles tenues partout : le texte reste sur un fond assez dense pour rester
   lisible, et le flou ne s'applique qu'aux surfaces fixes — jamais aux lignes de chat,
   qui défilent trop vite pour qu'on paie un flou par message. */

:root {
  --verre-fond: rgba(20, 20, 26, .55);
  --verre-fond-dense: rgba(16, 16, 21, .78);
  --verre-bord: rgba(255, 255, 255, .12);
  --verre-lueur: rgba(255, 255, 255, .10);
  --verre-ombre: 0 12px 32px -12px rgba(0, 0, 0, .55), 0 2px 8px -4px rgba(0, 0, 0, .4);
  --verre-flou: saturate(170%) blur(22px);
}
body.clair {
  --verre-fond: rgba(255, 255, 255, .62);
  --verre-fond-dense: rgba(255, 255, 255, .84);
  --verre-bord: rgba(0, 0, 0, .09);
  --verre-lueur: rgba(255, 255, 255, .8);
  --verre-ombre: 0 12px 30px -14px rgba(20, 16, 40, .28), 0 2px 6px -3px rgba(20, 16, 40, .16);
}

/* --- barres et panneaux */
.topbar, .outils, .bandeau, .pub, .pied, .panneau, .col header, #toast, .carte, .pilule {
  background-color: var(--verre-fond) !important;
  background-image: none;
  -webkit-backdrop-filter: var(--verre-flou);
  backdrop-filter: var(--verre-flou);
  border-color: var(--verre-bord);
}
.panneau, .carte {
  box-shadow: var(--verre-ombre);
  border: 1px solid var(--verre-bord);
  border-radius: 20px;
}
.panneau.large { border-radius: 22px; }
#toast { box-shadow: var(--verre-ombre); border: 1px solid var(--verre-bord); }

/* le panneau reste lisible même au-dessus d'un chat qui défile */
.panneau { background-color: var(--verre-fond-dense) !important; }

/* --- cartes des pages publiques */
.grille-fonctions article, .grille-copilote article, .carte-tarif,
.avant, .apres, .demo-cadre, .region, .offre, .cle, .questions details, .cle-livree {
  background-color: var(--verre-fond) !important;
  -webkit-backdrop-filter: var(--verre-flou);
  backdrop-filter: var(--verre-flou);
  border: 1px solid var(--verre-bord);
  box-shadow: var(--verre-ombre);
}
.grille-fonctions article, .grille-copilote article { border-radius: 20px; }
.carte-tarif, .offre { border-radius: 24px; }
.demo-cadre { border-radius: 24px; }

/* Un reflet en haut de chaque carte. Attention : ne jamais toucher au « position » des
   panneaux, qui sont ancres en fixe — le reflet leur est simplement retire. */
.carte-tarif, .offre, .demo-cadre, .grille-copilote article, .grille-fonctions article,
.region, .cle, .cle-livree { position: relative; }
.carte-tarif::before, .offre::before, .demo-cadre::before, .grille-copilote article::before,
.grille-fonctions article::before, .region::before, .cle::before, .cle-livree::before {
  content: ''; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  background: linear-gradient(180deg, var(--verre-lueur), transparent 38%);
  opacity: .55;
}
/* le contenu passe au-dessus du reflet */
.carte-tarif > *, .offre > *, .grille-copilote article > *, .grille-fonctions article > *,
.region > *, .cle > * { position: relative; z-index: 1; }

/* --- boutons : verre pour les secondaires, plein pour l'action principale */
.btn:not(.primary):not(.on) {
  background-color: rgba(255, 255, 255, .06);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  border-color: var(--verre-bord);
}
body.clair .btn:not(.primary):not(.on) { background-color: rgba(0, 0, 0, .04); }
.btn:not(.primary):not(.on):hover { background-color: rgba(255, 255, 255, .12); }
body.clair .btn:not(.primary):not(.on):hover { background-color: rgba(0, 0, 0, .07); }
.btn.primary {
  box-shadow: 0 6px 18px -6px color-mix(in srgb, var(--accent) 70%, transparent);
}

/* --- champs de saisie */
.field, .outils input, .cle input, .ia-actions input, .ia-actions select {
  background-color: rgba(255, 255, 255, .05) !important;
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  border-color: var(--verre-bord);
}
body.clair .field, body.clair .outils input, body.clair .cle input { background-color: rgba(0, 0, 0, .03) !important; }

/* --- overlay OBS : le verre y a tout son sens, il flotte sur une image */
/* (défini dans overlay.html, gardé cohérent ici pour la démonstration) */
.demo-flux .msg { backdrop-filter: none; }

/* le flou coûte cher : on l'enlève quand la machine demande moins d'effets */
@media (prefers-reduced-motion: reduce) {
  .topbar, .outils, .bandeau, .pub, .pied, .panneau, .col header, #toast, .carte, .pilule,
  .grille-fonctions article, .grille-copilote article, .carte-tarif, .avant, .apres,
  .demo-cadre, .region, .offre, .cle, .questions details {
    -webkit-backdrop-filter: none; backdrop-filter: none;
    background-color: var(--verre-fond-dense) !important;
  }
}

/* ============================================================ agent de surveillance
   L'agent parle rarement : quand il parle, on doit le voir sans lire. Une bande de
   couleur à gauche de chaque alerte donne le ton en un coup d'œil, et une pastille
   sur le bouton Copilote prévient quand le panneau est fermé. */

.ia-liste li.alerte-bien      { border-left: 3px solid var(--ok); }
.ia-liste li.alerte-info      { border-left: 3px solid #45c8f0; }
.ia-liste li.alerte-attention { border-left: 3px solid #f0a12e; }
.ia-liste li.alerte-alerte    { border-left: 3px solid #e5553c; }
.ia-liste li .quand { font-variant-numeric: tabular-nums; opacity: .6; }

#ia-agent-bascule.on { border-color: color-mix(in srgb, var(--ok) 55%, transparent); }

/* le compteur : posé sur le coin du bouton, il se lit sans s'arrêter de jouer */
#btn-ia { position: relative; }
#btn-ia.a-du-neuf::after {
  content: attr(data-neuf);
  position: absolute; top: -6px; right: -6px;
  min-width: 17px; height: 17px; padding: 0 4px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 999px; background: #e5553c; color: #fff;
  font-size: 10px; font-weight: 700; line-height: 1; font-variant-numeric: tabular-nums;
  box-shadow: 0 0 0 2px var(--bg), 0 2px 6px -1px rgba(0, 0, 0, .5);
  animation: pastille 1.4s ease-out 2;
}
@keyframes pastille {
  0%, 100% { transform: scale(1); }
  30%      { transform: scale(1.28); }
}
@media (prefers-reduced-motion: reduce) { #btn-ia.a-du-neuf::after { animation: none; } }
#ia-agent-etat { margin-bottom: 10px; }

/* ============================================================ remise sur l'axe
   Un bloc plus étroit que sa section doit garder des marges automatiques. Sans
   elles il se colle à gauche : le titre n'est plus au-dessus de son contenu et
   toute la page dérive vers la gauche dès qu'on dépasse ~1200 px de large.
   Le défaut ne se voit pas sur un écran d'ordinateur portable — d'où le fait
   qu'il ait tenu jusqu'ici. */

.copilote > *, .probleme > * {
  max-width: var(--marge-page); margin-left: auto; margin-right: auto;
}
.copilote-tete, .demo-tete { margin-left: auto; margin-right: auto; }
.demo-repos p, .demo-tete p, .copilote-tete p { margin-left: auto; margin-right: auto; }
.hero .note { margin-left: auto; margin-right: auto; }

/* `.accueil h2 { margin: 0 0 16px }` est plus spécifique que `.fonctions > *` :
   le raccourci remettait les marges latérales à zéro et décalait le titre de
   273 px vers la gauche. On les rétablit avec assez de poids pour gagner. */
.accueil > section > h2 { margin-left: auto; margin-right: auto; }

/* La remise est l'argument : le bouton l'annonce, la ligne en dessous dit la
   suite pour que personne ne découvre le vrai prix après avoir payé. */
.apres-remise { margin: 8px 0 0; font-size: 12px; color: var(--dim); text-align: center; }

/* ============================================================ direction
   La page d'accueil cesse d'être une colonne centrée. Deux plans : le texte à
   gauche, le produit qui tourne à droite. Le mouvement ne décore pas, il donne
   l'ordre de lecture — et il s'efface entièrement pour qui demande moins
   d'animations. */

/* --- apparitions */
.reveal {
  opacity: 0; transform: translate3d(0, 18px, 0);
  transition: opacity .62s cubic-bezier(.22, 1, .36, 1) var(--retard, 0ms),
              transform .62s cubic-bezier(.22, 1, .36, 1) var(--retard, 0ms);
  will-change: opacity, transform;
}
.reveal.vu { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; transition: none; }
}

/* --- ouverture : le texte tient la gauche, le direct occupe la droite */
.accueil > section.hero {
  display: grid; grid-template-columns: minmax(0, 1.02fr) minmax(0, .98fr);
  gap: clamp(32px, 5vw, 76px); align-items: center; text-align: left;
  padding-top: clamp(64px, 8vw, 116px); padding-bottom: clamp(56px, 7vw, 104px);
  max-width: 1260px;
}
.hero-texte { min-width: 0; }
.hero .eyebrow {
  font-size: 12px; letter-spacing: .16em; text-transform: uppercase;
  color: var(--dim); margin: 0 0 22px;
}
.accueil .hero h1 {
  font-size: clamp(40px, 5.6vw, 82px); line-height: .98; letter-spacing: -.04em;
  margin: 0 0 22px; max-width: 17ch; text-wrap: balance;
}
.accueil .hero p.sub {
  font-size: clamp(16px, 1.25vw, 19px); max-width: 42ch; margin: 0 0 32px;
}
.accueil .hero form { max-width: 440px; margin: 0; }
.accueil .hero .actions, .accueil .hero .exemples { justify-content: flex-start; }
.accueil .hero .note { text-align: left; margin-left: 0; margin-right: 0; }

/* --- la vitrine : une fenêtre, pas une image */
.vitrine { min-width: 0; }
.vitrine-cadre {
  border: 1px solid var(--verre-bord); border-radius: 22px; overflow: hidden;
  background: var(--verre-fond-dense);
  -webkit-backdrop-filter: var(--verre-flou); backdrop-filter: var(--verre-flou);
  box-shadow: 0 40px 90px -50px rgba(0, 0, 0, .9), 0 2px 10px -4px rgba(0, 0, 0, .5);
}
.vitrine-tete, .vitrine-pied {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 16px; font-size: 12px; color: var(--dim);
}
.vitrine-tete { border-bottom: 1px solid var(--line); }
.vitrine-pied { border-top: 1px solid var(--line); justify-content: space-between; }
.vitrine-chaine { color: var(--text); font-weight: 600; font-size: 13px; }
.vitrine-chiffre { margin-left: auto; font-variant-numeric: tabular-nums; }
.pastille-direct {
  width: 7px; height: 7px; border-radius: 999px; background: var(--dim); flex: none;
}
.pastille-direct.actif { background: #e5553c; box-shadow: 0 0 0 0 rgba(229, 85, 60, .6); animation: bat 2s infinite; }
@keyframes bat {
  70% { box-shadow: 0 0 0 7px rgba(229, 85, 60, 0); }
  100% { box-shadow: 0 0 0 0 rgba(229, 85, 60, 0); }
}

/* le flux est coupé en haut par un dégradé : on sent qu'il continue au-delà du cadre */
.vitrine-flux {
  height: clamp(320px, 42vh, 460px); overflow: hidden; padding: 6px 0;
  -webkit-mask-image: linear-gradient(180deg, transparent, #000 52px);
  mask-image: linear-gradient(180deg, transparent, #000 52px);
}
.vitrine-flux .msg { padding: 6px 16px; font-size: 14px; animation: entre .3s cubic-bezier(.22, 1, .36, 1); }
@keyframes entre { from { opacity: 0; transform: translateY(8px); } }
@media (prefers-reduced-motion: reduce) { .vitrine-flux .msg { animation: none; } }
.vitrine-note { margin: 14px 0 0; font-size: 12px; color: var(--dim); text-align: center; }

/* --- le bandeau qui traverse : plein cadre, sans marge, il casse la colonne */
.bandeau-defile {
  overflow: hidden; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
  padding: 18px 0; user-select: none;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
}
.defile-piste {
  display: flex; align-items: center; gap: 26px; width: max-content;
  animation: defile 46s linear infinite;
}
.defile-piste span {
  font-size: clamp(20px, 2.4vw, 34px); font-weight: 600; letter-spacing: -.02em;
  color: color-mix(in srgb, var(--text) 26%, transparent); white-space: nowrap;
}
.defile-piste i { color: color-mix(in srgb, var(--accent) 55%, transparent); font-style: normal; }
@keyframes defile { to { transform: translate3d(-50%, 0, 0); } }
@media (prefers-reduced-motion: reduce) { .defile-piste { animation: none; } }

/* --- les chiffres : grands, alignés sur une ligne, sans décor */
.accueil > section.chiffres { padding-top: 84px; padding-bottom: 84px; }
.chiffres-grille {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: clamp(20px, 3vw, 44px);
}
.chiffre strong {
  display: block; font-size: clamp(38px, 4.4vw, 62px); line-height: 1; letter-spacing: -.04em;
  font-variant-numeric: tabular-nums; margin-bottom: 10px;
}
.chiffre span { font-size: 13px; line-height: 1.5; color: var(--dim); display: block; max-width: 24ch; }

/* --- écrans étroits : la colonne revient, mais le direct reste au-dessus du formulaire */
@media (max-width: 1040px) {
  .accueil > section.hero { grid-template-columns: 1fr; text-align: center; }
  .hero-texte { display: contents; }
  .hero .eyebrow { order: 1; margin-bottom: 16px; }
  .accueil .hero h1 { order: 2; margin-left: auto; margin-right: auto; max-width: 16ch; }
  .accueil .hero p.sub { order: 3; margin-left: auto; margin-right: auto; }
  .vitrine { order: 4; margin: 8px 0 30px; transform: none !important; }
  .accueil .hero form { order: 5; margin: 0 auto; text-align: left; }
  .accueil .hero .note { order: 6; text-align: center; }
  .accueil .hero .actions, .accueil .hero .exemples { justify-content: center; }
  .chiffres-grille { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .chiffre span { max-width: none; }
}
@media (max-width: 560px) {
  .accueil .hero h1 { font-size: clamp(34px, 10vw, 46px); }
  .vitrine-flux { height: 300px; }
  .chiffres-grille { grid-template-columns: 1fr; gap: 26px; }
  .chiffre strong { font-size: 40px; }
}

/* le choix de langue se fond dans la barre : c'est un réglage, pas une action */
.choix-langue {
  -webkit-appearance: none; appearance: none; cursor: pointer;
  padding-right: 22px; font-size: 12px;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
                    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 12px) 52%, calc(100% - 8px) 52%;
  background-size: 4px 4px, 4px 4px; background-repeat: no-repeat;
}
.choix-langue option { background: var(--panel); color: var(--text); }

/* ============================================================ barre en petit écran
   En pilule, la barre du haut suppose de la place. À 500 px, « Comment ça marche »
   se casse sur trois lignes et le choix de langue sort de l'écran. Les liens d'ancre
   disparaissent — on les rencontre de toute façon en descendant — et ce qui reste
   ne se coupe plus jamais. */

@media (max-width: 780px) {
  .topbar { flex-wrap: nowrap; gap: 6px; padding: 7px 10px; overflow: hidden; }
  .topbar .btn, .topbar .brand { white-space: nowrap; flex: none; }
  .topbar .seul-accueil[href^="#"] { display: none; }
  .topbar .brand { font-size: 13px; letter-spacing: -.01em; }
  .topbar .btn.primary { font-size: 12px; padding: 7px 12px; }
  .choix-langue { padding: 6px 20px 6px 9px; max-width: 92px; }
}
@media (max-width: 560px) {
  .topbar .seul-accueil:not(.primary) { display: none; }
}

/* ============================================================ mise en page dirigée
   Le hero était la seule page composée ; en dessous, tout retombait au centre. Deux
   patrons remplacent la colonne : une section éditoriale dont le titre reste accroché
   pendant que la liste défile, et une grille où une carte pèse plus que les autres. */

/* --- section éditoriale : le titre tient à gauche, le contenu passe */
.accueil > section.editoriale {
  display: grid; grid-template-columns: minmax(0, 360px) minmax(0, 1fr);
  gap: clamp(32px, 6vw, 96px); align-items: start;
}
.colonne-titre { position: sticky; top: 108px; }
.accueil > section.editoriale > .colonne-titre > h2 {
  margin: 0 0 14px; text-align: left; font-size: clamp(30px, 3.4vw, 46px);
}
.colonne-titre .numero {
  display: block; font-size: 12px; letter-spacing: .18em; color: var(--dim);
  margin-bottom: 18px; font-variant-numeric: tabular-nums;
}
.colonne-titre p { color: var(--dim); font-size: 15px; line-height: 1.6; margin: 0; max-width: 32ch; }

/* la liste : des lignes numérotées, pas des boîtes. Le trait sépare, le fond ne pèse pas */
.liste-fonctions { list-style: none; margin: 0; padding: 0; counter-reset: f; }
.liste-fonctions li {
  counter-increment: f; padding: 26px 0 26px 62px; position: relative;
  border-top: 1px solid var(--line);
}
.liste-fonctions li:last-child { border-bottom: 1px solid var(--line); }
.liste-fonctions li::before {
  content: counter(f, decimal-leading-zero);
  position: absolute; left: 0; top: 29px;
  font-size: 12px; color: var(--dim); font-variant-numeric: tabular-nums; letter-spacing: .1em;
}
.liste-fonctions h3 { margin: 0 0 6px; font-size: clamp(19px, 1.7vw, 24px); font-weight: 600; letter-spacing: -.015em; }
.liste-fonctions p { margin: 0; color: var(--dim); font-size: 15px; line-height: 1.6; max-width: 52ch; }
.liste-fonctions li::after {
  content: ''; position: absolute; left: 0; right: 0; top: -1px; height: 1px;
  background: var(--accent); transform: scaleX(0); transform-origin: left;
  transition: transform .5s cubic-bezier(.22, 1, .36, 1);
}
.liste-fonctions li:hover::after { transform: scaleX(1); }

/* --- la grille du copilote cesse d'être dix rectangles égaux */
.grille-copilote { grid-template-columns: repeat(4, minmax(0, 1fr)); align-items: stretch; }
.grille-copilote .carte-large {
  grid-column: span 2; grid-row: span 2;
  display: flex; flex-direction: column; gap: 14px;
  background: linear-gradient(160deg,
    color-mix(in srgb, var(--accent) 12%, var(--bg)), var(--bg) 62%) !important;
  border-color: color-mix(in srgb, var(--accent) 34%, transparent) !important;
}
.carte-large h3 { font-size: clamp(21px, 2vw, 27px) !important; letter-spacing: -.02em; }
.carte-large > p { font-size: 15px; }
.exemples-agent { list-style: none; margin: 4px 0 0; padding: 0; display: grid; gap: 8px; }
.exemples-agent li {
  background: color-mix(in srgb, var(--bg) 72%, transparent);
  border: 1px solid var(--line); border-radius: 12px; padding: 11px 13px;
}
.exemples-agent b { display: block; font-size: 13px; font-weight: 600; line-height: 1.4; }
.exemples-agent span { display: block; font-size: 11.5px; color: var(--dim); margin-top: 3px; }
.carte-note { margin-top: auto; font-size: 11.5px; color: var(--dim); }

@media (max-width: 1040px) {
  .accueil > section.editoriale { grid-template-columns: 1fr; gap: 26px; }
  .colonne-titre { position: static; }
  .grille-copilote { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .grille-copilote .carte-large { grid-column: span 2; grid-row: auto; }
}
@media (max-width: 620px) {
  .grille-copilote { grid-template-columns: 1fr; }
  .grille-copilote .carte-large { grid-column: auto; }
  .liste-fonctions li { padding-left: 46px; }
}

/* ============================================================ signature
   Passer d'une page à l'autre ne doit pas ressembler à un rechargement. Là où le
   navigateur sait le faire, le contenu glisse et le fond reste : c'est la même
   application qui continue, pas un autre site qui s'ouvre. */

@view-transition { navigation: auto; }

::view-transition-old(root) {
  animation: sortie .28s cubic-bezier(.4, 0, 1, 1) both;
}
::view-transition-new(root) {
  animation: entree .42s cubic-bezier(.22, 1, .36, 1) both;
}
@keyframes sortie { to { opacity: 0; transform: translateY(-8px); } }
@keyframes entree { from { opacity: 0; transform: translateY(12px); } }

@media (prefers-reduced-motion: reduce) {
  ::view-transition-old(root), ::view-transition-new(root) { animation: none; }
}

/* le dégradé du haut ne doit pas trancher un message en deux : il fait juste
   apparaître celui qui entre */
.vitrine-flux {
  -webkit-mask-image: linear-gradient(180deg, transparent, #000 34px);
  mask-image: linear-gradient(180deg, transparent, #000 34px);
}

/* ============================================================ mouvement
   Les titres montent ligne par ligne depuis une fenêtre qui les coupe. La barre du
   haut porte l'avancée dans la page et se resserre dès qu'on quitte le sommet. Les
   cartes répondent au survol. Rien de tout cela ne s'exécute si la machine demande
   moins d'animations. */

.titre-anime .ligne { display: block; overflow: hidden; padding-bottom: .06em; margin-bottom: -.06em; }
.titre-anime .ligne-int {
  display: block; transform: translate3d(0, 105%, 0);
  transition: transform .78s cubic-bezier(.19, 1, .22, 1) var(--retard, 0ms);
  will-change: transform;
}
.titre-anime.vu .ligne-int { transform: none; }

/* la ligne de progression, posée sur le bord bas de la barre */
.jauge-defilement {
  position: absolute; left: 0; right: 0; bottom: 0; height: 2px;
  background: linear-gradient(90deg, var(--accent), var(--accent-clair, var(--accent)));
  transform: scaleX(0); transform-origin: left; border-radius: 2px;
  pointer-events: none; opacity: .9;
}
.topbar { transition: padding .3s cubic-bezier(.22, 1, .36, 1), background-color .3s ease; }
.topbar.resserree { padding-top: 7px; padding-bottom: 7px; }
body[data-view="accueil"] .topbar.resserree {
  background-color: var(--verre-fond-dense) !important;
}

/* les cartes se soulèvent, les boutons répondent */
.grille-copilote article, .grille-fonctions article, .carte-tarif {
  transition: transform .4s cubic-bezier(.22, 1, .36, 1), border-color .3s ease, box-shadow .4s ease;
}
.grille-copilote article:hover, .grille-fonctions article:hover {
  transform: translateY(-3px);
  box-shadow: 0 18px 40px -28px rgba(0, 0, 0, .9);
}
.carte-tarif:hover { transform: translateY(-4px); }
.btn { transition: transform .18s cubic-bezier(.22, 1, .36, 1), background-color .2s ease, border-color .2s ease, box-shadow .25s ease; }
.btn:active { transform: scale(.975); }
.btn.primary:hover { transform: translateY(-1px); }

/* le voyant du direct respire au lieu de clignoter */
.vitrine-cadre { transition: border-color .4s ease; }
.vitrine:hover .vitrine-cadre { border-color: color-mix(in srgb, var(--accent) 30%, var(--verre-bord)); }

@media (prefers-reduced-motion: reduce) {
  .titre-anime .ligne-int { transform: none; transition: none; }
  .jauge-defilement { display: none; }
  .grille-copilote article:hover, .grille-fonctions article:hover, .carte-tarif:hover { transform: none; }
  .btn:active, .btn.primary:hover { transform: none; }
}

/* ============================================================ le deck
   La section du copilote prend la forme de l'objet que les streamers ont déjà sur le
   bureau : un boîtier, des touches carrées qui s'allument, une fiche qui répond quand
   on appuie. Ce n'est pas un décor — c'est la bonne métaphore : dix fonctions qu'on
   déclenche pendant qu'on joue, sans quitter le jeu des yeux. */

.deck {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 320px);
  gap: clamp(26px, 4vw, 56px); align-items: center; margin-top: 44px;
}

/* --- le boîtier */
.deck-chassis {
  border-radius: 26px; padding: clamp(14px, 1.6vw, 22px);
  background: linear-gradient(168deg, #24242c, #131318 58%, #0d0d11);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .09),
    inset 0 -1px 0 rgba(0, 0, 0, .6),
    0 34px 70px -34px rgba(0, 0, 0, .95),
    0 4px 14px -6px rgba(0, 0, 0, .6);
  border: 1px solid rgba(255, 255, 255, .06);
}
body.clair .deck-chassis {
  background: linear-gradient(168deg, #e9e9ee, #d8d8e0 60%, #cfcfd8);
  border-color: rgba(0, 0, 0, .08);
}

.deck-touches {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(8px, .9vw, 13px);
}

/* --- une touche : carrée, légèrement bombée, elle s'enfonce quand on appuie */
.touche {
  aspect-ratio: 1; border: 0; border-radius: 12px; cursor: pointer;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 7px;
  padding: 6px; text-align: center; color: var(--dim); font: inherit;
  background:
    radial-gradient(120% 100% at 50% 0%, rgba(255, 255, 255, .10), transparent 58%),
    linear-gradient(180deg, #1c1c23, #101015);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .08),
    inset 0 -2px 4px rgba(0, 0, 0, .55),
    0 2px 5px rgba(0, 0, 0, .45);
  transition: transform .13s cubic-bezier(.3, 0, .2, 1), box-shadow .2s ease,
              color .2s ease, background-color .2s ease;
}
body.clair .touche { background: linear-gradient(180deg, #fff, #ececf2); }

.touche .icone { font-size: clamp(17px, 1.7vw, 23px); line-height: 1; filter: saturate(.85); }
.touche .etiquette {
  font-size: 10.5px; font-weight: 600; letter-spacing: .01em; line-height: 1.15;
  max-width: 100%; overflow-wrap: anywhere;
}

.touche:hover { color: var(--text); transform: translateY(-1px); }
.touche:active { transform: translateY(1px) scale(.985); box-shadow: inset 0 2px 6px rgba(0, 0, 0, .7); }
.touche:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* la touche allumée : le halo vient de sous la touche, comme une vraie LED */
.touche[aria-pressed="true"] {
  color: #fff;
  background:
    radial-gradient(120% 100% at 50% 0%, color-mix(in srgb, var(--accent) 55%, transparent), transparent 62%),
    linear-gradient(180deg, color-mix(in srgb, var(--accent) 34%, #14141a), #14141a);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .18),
    inset 0 -2px 4px rgba(0, 0, 0, .5),
    0 0 0 1px color-mix(in srgb, var(--accent) 45%, transparent),
    0 6px 18px -6px color-mix(in srgb, var(--accent) 60%, transparent);
}
.touche[aria-pressed="true"] .icone { filter: none; }

/* la touche de marque ne se clique pas : elle occupe la douzième place */
.touche-marque { cursor: default; opacity: .5; }
.touche-marque:hover { transform: none; color: var(--dim); }

/* --- la fiche : ce que la touche vient de dire */
.deck-fiche { min-width: 0; }
.deck-fiche b {
  display: block; font-size: clamp(19px, 1.8vw, 25px); font-weight: 600;
  letter-spacing: -.02em; line-height: 1.2; margin-bottom: 10px;
}
.deck-fiche p { margin: 0 0 14px; color: var(--dim); font-size: 15px; line-height: 1.6; }
.deck-aide { font-size: 11.5px; color: var(--dim); opacity: .7; }
.deck-fiche.change b, .deck-fiche.change p { animation: fiche .32s cubic-bezier(.22, 1, .36, 1); }
@keyframes fiche { from { opacity: 0; transform: translateY(6px); } }

@media (max-width: 1040px) {
  .deck { grid-template-columns: 1fr; gap: 26px; }
  .deck-fiche { text-align: center; }
}
@media (max-width: 560px) {
  .deck-touches { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .touche .etiquette { font-size: 9.5px; }
}
@media (prefers-reduced-motion: reduce) {
  .touche, .touche:hover, .touche:active { transform: none; }
  .deck-fiche.change b, .deck-fiche.change p { animation: none; }
}

/* le lien de gestion d'abonnement : discret, mais toujours présent — on ne cache pas
   la porte de sortie */
.gerer { margin: 14px 0 0; font-size: 13px; color: var(--dim); line-height: 1.6; }
.gerer a { color: var(--accent-clair, var(--accent)); }
.pied { display: flex; gap: 18px; justify-content: center; flex-wrap: wrap; }

/* ============================================================ la barre, reprise
   Le dessin voulu (des liens nus, un soulignement au survol) était écrasé par la règle
   de verre appliquée à tous les boutons : chaque lien portait donc son propre fond gris,
   et on obtenait des pilules dans une pilule. On rend leur nudité aux liens, la barre
   n'a plus qu'un seul objet plein : le bouton d'achat. */

body[data-view="accueil"] .topbar .seul-accueil:not(.primary) {
  background: none !important;
  -webkit-backdrop-filter: none; backdrop-filter: none;
  border: 0; box-shadow: none;
}
body[data-view="accueil"] .topbar .seul-accueil:not(.primary):hover {
  background: none !important; color: var(--text);
}

/* la section où l'on se trouve est marquée, comme dans un sommaire */
body[data-view="accueil"] .topbar .seul-accueil.ici { color: var(--text); opacity: 1; }
body[data-view="accueil"] .topbar .seul-accueil.ici::after { transform: scaleX(1) !important; }

/* un filet avant l'appel à l'action : il sépare la navigation de l'achat */
body[data-view="accueil"] .topbar .btn.primary.seul-accueil {
  margin-left: 16px; position: relative;
}
body[data-view="accueil"] .topbar .btn.primary.seul-accueil::before {
  content: ''; position: absolute; left: -16px; top: 50%; transform: translateY(-50%);
  width: 1px; height: 20px; background: var(--line);
}

/* le choix de langue : discret, jamais coupé */
.choix-langue {
  background: none !important; border: 0 !important; box-shadow: none;
  -webkit-backdrop-filter: none; backdrop-filter: none;
  color: var(--dim); font-size: 12px; font-weight: 500;
  padding: 6px 20px 6px 8px; width: auto; min-width: 78px;
  background-position: right 6px center !important;
}
.choix-langue:hover { color: var(--text); }
.choix-langue:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 8px; }

/* le bouton de thème : rond, de la taille d'une icône, pas d'un mot */
#btn-theme {
  width: 30px; height: 30px; padding: 0; border-radius: 999px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 13px; line-height: 1;
}

@media (max-width: 780px) {
  body[data-view="accueil"] .topbar .btn.primary.seul-accueil { margin-left: 8px; }
  body[data-view="accueil"] .topbar .btn.primary.seul-accueil::before { display: none; }
  .choix-langue { min-width: 0; max-width: 84px; }
}

/* Sur petit écran le hero passe en `text-align: center` — et la vitrine héritait du
   centrage, donc les messages du chat s'alignaient au milieu. Un chat se lit à gauche. */
.vitrine, .vitrine-tete, .vitrine-flux, .vitrine-flux * { text-align: left; }

/* ============================================================ le bureau
   Des fenêtres, pas une grille. Le cadre est le plan de travail ; chaque chat y est
   posé, déplaçable par sa barre de titre, redimensionnable par le coin. On soigne
   trois choses : qu'on voie tout de suite ce qui s'attrape, que rien ne saute pendant
   qu'on lit, et que la fenêtre du dessus soit lisible sur celle du dessous. */

.board.bureau {
  position: relative; overflow: hidden;
  background-image:
    radial-gradient(circle at 1px 1px, color-mix(in srgb, var(--text) 7%, transparent) 1px, transparent 0);
  background-size: 24px 24px;
}

.board.bureau .fenetre {
  position: absolute; display: flex; flex-direction: column;
  border: 1px solid var(--verre-bord); border-radius: 14px; overflow: hidden;
  background: var(--verre-fond-dense);
  -webkit-backdrop-filter: var(--verre-flou); backdrop-filter: var(--verre-flou);
  box-shadow: 0 22px 50px -30px rgba(0, 0, 0, .95), 0 2px 8px -4px rgba(0, 0, 0, .5);
  transition: box-shadow .25s ease;
}
.board.bureau .fenetre:focus-within,
.board.bureau .fenetre.en-main {
  box-shadow: 0 30px 70px -30px rgba(0, 0, 0, 1),
              0 0 0 1px color-mix(in srgb, var(--accent) 40%, transparent);
}
/* pendant la manipulation, on coupe les transitions : le suivi doit coller au pointeur */
.board.bureau .fenetre.en-main { transition: none; user-select: none; }
.board.bureau .fenetre.en-main .feed { pointer-events: none; }

.board.bureau .fenetre > header {
  cursor: grab; touch-action: none; flex: none;
  display: flex; align-items: center; gap: 8px; padding: 9px 10px;
  border-bottom: 1px solid var(--line);
}
.board.bureau .fenetre.en-main > header { cursor: grabbing; }
.board.bureau .fenetre > header .dot { margin-left: auto; }
.board.bureau .fenetre > header .replier {
  background: none; border: 0; color: var(--dim); cursor: pointer;
  font-size: 15px; line-height: 1; padding: 2px 6px; border-radius: 6px;
}
.board.bureau .fenetre > header .replier:hover { color: var(--text); background: rgba(255, 255, 255, .08); }

.board.bureau .fenetre .feed { flex: 1 1 auto; overflow-y: auto; }

/* repliée : il ne reste que la barre de titre, comme un onglet posé sur le bureau */
.board.bureau .fenetre.repliee { height: auto !important; }
.board.bureau .fenetre.repliee .feed, .board.bureau .fenetre.repliee .poignee { display: none; }

/* la poignée : discrète, mais elle se voit dès qu'on approche de la fenêtre */
.board.bureau .poignee {
  position: absolute; right: 0; bottom: 0; width: 18px; height: 18px;
  cursor: nwse-resize; touch-action: none; opacity: 0; transition: opacity .2s ease;
}
.board.bureau .poignee::before {
  content: ''; position: absolute; right: 4px; bottom: 4px; width: 8px; height: 8px;
  border-right: 2px solid var(--dim); border-bottom: 2px solid var(--dim); border-radius: 0 0 3px 0;
}
.board.bureau .fenetre:hover .poignee, .board.bureau .fenetre.en-main .poignee { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .board.bureau .fenetre { transition: none; }
}

/* le bouton de remise en ordre : posé sur le plan de travail, hors du chemin */
.ranger-bureau {
  position: absolute; right: 10px; bottom: 10px; z-index: 5;
  opacity: .45; transition: opacity .2s ease;
}
.ranger-bureau:hover { opacity: 1; }

/* ============================================================ palette de commandes
   Ctrl+K. Un champ, une liste, rien d'autre. Elle se pose au tiers haut de l'écran :
   plus bas, elle couvre ce qu'on lit ; plus haut, elle sort du regard. */

.palette { position: fixed; inset: 0; z-index: 120; }
.palette[hidden] { display: none; }
.palette-fond {
  position: absolute; inset: 0; background: rgba(0, 0, 0, .5);
  -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px);
  animation: pal-fond .18s ease;
}
.palette-boite {
  position: relative; margin: 12vh auto 0; width: min(560px, calc(100vw - 32px));
  border: 1px solid var(--verre-bord); border-radius: 16px; overflow: hidden;
  background: var(--verre-fond-dense);
  -webkit-backdrop-filter: var(--verre-flou); backdrop-filter: var(--verre-flou);
  box-shadow: 0 40px 90px -40px rgba(0, 0, 0, .95);
  animation: pal-boite .2s cubic-bezier(.22, 1, .36, 1);
}
@keyframes pal-fond { from { opacity: 0; } }
@keyframes pal-boite { from { opacity: 0; transform: translateY(-10px) scale(.985); } }

#palette-champ {
  width: 100%; border: 0; border-bottom: 1px solid var(--line); background: none;
  color: var(--text); font: inherit; font-size: 16px; padding: 16px 18px; outline: none;
}
#palette-champ::placeholder { color: var(--dim); }

#palette-liste { list-style: none; margin: 0; padding: 6px; max-height: 46vh; overflow-y: auto; }
#palette-liste li {
  display: flex; align-items: center; gap: 10px; padding: 10px 12px;
  border-radius: 10px; cursor: pointer; font-size: 14px;
}
#palette-liste li.sur { background: color-mix(in srgb, var(--accent) 22%, transparent); }
#palette-liste li:hover:not(.cmd-rien) { background: rgba(255, 255, 255, .06); }
.cmd-ou { margin-left: auto; font-size: 11px; color: var(--dim); }
.cmd-rien { color: var(--dim); cursor: default; font-size: 13px; }

.palette-boite footer {
  padding: 9px 14px; border-top: 1px solid var(--line);
  font-size: 11px; color: var(--dim); display: flex; gap: 5px; align-items: center;
}
.palette-boite kbd {
  font: inherit; font-size: 10px; padding: 2px 5px; border-radius: 5px;
  border: 1px solid var(--line); background: rgba(255, 255, 255, .05);
}

@media (prefers-reduced-motion: reduce) {
  .palette-fond, .palette-boite { animation: none; }
}

/* ============================================================ ambiances
   Cinq réglages complets, nommés par la situation plutôt que par le paramètre : on ne
   choisit pas « densité compacte, 13 px », on choisit « compact pro ». Les couleurs
   d'accent sont des pastilles : on voit ce qu'on prend avant de le prendre. */

.aide-courte { margin: -4px 0 10px; font-size: 12px; color: var(--dim); line-height: 1.5; }

.ambiances { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 16px; }
.ambiances .ambiance { font-size: 12px; }
.ambiances .ambiance.on {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 20%, transparent) !important;
  color: var(--text);
}

.accents { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 16px; }
.pastille-accent {
  width: 24px; height: 24px; border-radius: 999px; cursor: pointer; padding: 0;
  border: 2px solid transparent; box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .25);
  transition: transform .15s ease, border-color .15s ease;
}
.pastille-accent:hover { transform: scale(1.12); }
.pastille-accent.on { border-color: var(--text); }
.pastille-accent:focus-visible { outline: 2px solid var(--text); outline-offset: 2px; }

@media (prefers-reduced-motion: reduce) { .pastille-accent:hover { transform: none; } }

/* ============================================================ mode clair : rattrapages
   L'ambiance « Papier » a mis au jour trois défauts qui traînaient depuis le début, et que
   personne ne voyait parce que presque personne n'essayait le thème clair :
   le champ « taille du texte » était noir sur noir, le bandeau de message blanc sur blanc,
   et les libellés des cases en gris pâle sur fond blanc. */

body.clair .panneau input,
body.clair .panneau select,
body.clair .panneau textarea {
  background-color: #fff !important;
  color: var(--text);
  border: 1px solid rgba(0, 0, 0, .14);
}
body.clair .panneau input[type="checkbox"] { background-color: transparent !important; }

body.clair #toast {
  background-color: rgba(255, 255, 255, .94) !important;
  color: var(--text);
  border: 1px solid rgba(0, 0, 0, .10);
  box-shadow: 0 12px 30px -14px rgba(20, 16, 40, .35);
}
body.clair #toast a { color: var(--accent); }

body.clair .panneau .case,
body.clair .panneau label,
body.clair .panneau h3 { color: var(--text); }
body.clair .panneau .aide-courte,
body.clair .panneau .ia-message,
body.clair .panneau .ia-source { color: #55555c; }

/* les pastilles d'accent gardent un contour visible sur fond blanc */
body.clair .pastille-accent { box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .15); }
body.clair .pastille-accent.on { border-color: #1d1d1f; }

/* ============================================================ le menu « ⋯ »
   La barre gardait dix-huit commandes visibles en permanence. On garde devant ce qu'on
   touche à chaque direct, on range le reste ici. Le menu montre le nom en clair à gauche
   et le bouton d'origine à droite : on lit ce qu'on va faire avant de le faire. */

#btn-plus { font-size: 15px; line-height: 1; padding: 6px 11px; }

.menu-plus {
  position: fixed; right: 14px; top: 106px; z-index: 60; width: 264px;
  border: 1px solid var(--verre-bord); border-radius: 16px; padding: 8px;
  background: var(--verre-fond-dense);
  -webkit-backdrop-filter: var(--verre-flou); backdrop-filter: var(--verre-flou);
  box-shadow: 0 26px 60px -30px rgba(0, 0, 0, .95);
  animation: menu-entre .18s cubic-bezier(.22, 1, .36, 1);
}
.menu-plus[hidden] { display: none; }
@keyframes menu-entre { from { opacity: 0; transform: translateY(-6px); } }

.menu-ligne {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 8px; border-radius: 10px; font-size: 13px;
}
.menu-ligne:hover { background: rgba(255, 255, 255, .05); }
body.clair .menu-ligne:hover { background: rgba(0, 0, 0, .04); }
.menu-ligne > span:first-child { flex: 1 1 auto; color: var(--dim); }
.menu-ligne .btn, .menu-ligne select { flex: none; }

.menu-astuce {
  margin: 8px 4px 2px; font-size: 11px; color: var(--dim); line-height: 1.5;
  border-top: 1px solid var(--line); padding-top: 9px;
}
.menu-astuce kbd {
  font: inherit; font-size: 10px; padding: 1px 4px; border-radius: 4px;
  border: 1px solid var(--line); background: rgba(255, 255, 255, .05);
}

@media (max-width: 780px) { .menu-plus { right: 8px; left: 8px; width: auto; top: 96px; } }
@media (prefers-reduced-motion: reduce) { .menu-plus { animation: none; } }

/* ============================================================ actions sur un message
   Un bouton discret au survol, un menu court, et la traduction qui vient se poser sous le
   message sans le remplacer — on peut toujours revenir à l'original d'un clic. */

.msg { position: relative; }
.actions-msg {
  position: absolute; right: 6px; top: 4px; z-index: 2;
  border: 0; background: none; color: var(--dim); cursor: pointer;
  font-size: 14px; line-height: 1; padding: 2px 6px; border-radius: 6px;
  opacity: 0; transition: opacity .15s ease;
}
.msg:hover .actions-msg { opacity: 1; }
.actions-msg:hover { color: var(--text); background: rgba(255, 255, 255, .10); }
body.clair .actions-msg:hover { background: rgba(0, 0, 0, .07); }

.menu-message {
  position: fixed; z-index: 130; min-width: 168px; padding: 5px;
  border: 1px solid var(--verre-bord); border-radius: 12px;
  background: var(--verre-fond-dense);
  -webkit-backdrop-filter: var(--verre-flou); backdrop-filter: var(--verre-flou);
  box-shadow: 0 20px 46px -24px rgba(0, 0, 0, .95);
}
.menu-message button {
  display: block; width: 100%; text-align: left; border: 0; background: none;
  color: var(--text); font: inherit; font-size: 13px; padding: 8px 10px;
  border-radius: 8px; cursor: pointer;
}
.menu-message button:hover { background: color-mix(in srgb, var(--accent) 24%, transparent); }

.traduction {
  margin: 4px 0 2px 0; padding: 6px 10px; border-radius: 8px;
  border-left: 2px solid var(--accent);
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  font-size: .95em; line-height: 1.5; color: var(--text);
}
.traduction.rate { border-left-color: var(--dim); color: var(--dim); }
.voir-original {
  display: inline-block; margin-left: 8px; border: 0; background: none; cursor: pointer;
  color: var(--dim); font: inherit; font-size: 11px; text-decoration: underline;
}
.voir-original:hover { color: var(--text); }

/* ============================================================ poste de commande
   Un écran qui répond à « est-ce que tout va bien ? » sans qu'on ait à lire. Les
   plateformes en haut, six chiffres en dessous, et rien d'autre. */

#controle { width: min(420px, calc(100vw - 24px)); }

.ctrl-plateformes { list-style: none; margin: 0 0 16px; padding: 0; display: grid; gap: 6px; }
.ctrl-plateformes li {
  display: flex; align-items: center; gap: 9px; font-size: 13px;
  padding: 8px 10px; border-radius: 10px; background: var(--panel-2);
}
.ctrl-plateformes i { width: 7px; height: 7px; border-radius: 999px; background: var(--dim); flex: none; }
.ctrl-plateformes li.ok i { background: var(--ok); }
.ctrl-plateformes li.attente i { background: #f0a12e; }
.ctrl-plateformes li.non i { background: #e5553c; }
.ctrl-plateformes li b { margin-left: auto; font-weight: 500; font-size: 11.5px; color: var(--dim); }
.ctrl-plateformes li.ok b { color: var(--ok); }

.ctrl-grille { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
.ctrl-bloc {
  padding: 12px; border-radius: 12px; background: var(--panel-2);
  border: 1px solid transparent;
}
.ctrl-bloc.bien { border-color: color-mix(in srgb, var(--ok) 38%, transparent); }
.ctrl-bloc.alerte { border-color: color-mix(in srgb, #e5553c 46%, transparent); }
.ctrl-bloc.faible { border-color: color-mix(in srgb, #f0a12e 34%, transparent); }
.ctrl-titre { display: block; font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--dim); }
.ctrl-bloc strong {
  display: block; margin: 5px 0 3px; font-size: 24px; line-height: 1;
  letter-spacing: -.03em; font-variant-numeric: tabular-nums;
}
.ctrl-detail { display: block; font-size: 11px; color: var(--dim); line-height: 1.4; }
.ctrl-note { margin: 14px 0 0; font-size: 11px; color: var(--dim); line-height: 1.5; }

/* ============================================================ une seule barre
   L'accueil a une barre flottante en pilule, l'application avait deux bandes plates
   collées au bord : deux directions artistiques dans le même produit. On aligne
   l'application sur l'accueil — un seul bloc flottant, en verre, aux angles arrondis,
   dont la première rangée porte l'identité et la seconde les outils. */

body[data-view="chat"] .topbar,
body[data-view="chat"] .outils {
  background-color: var(--verre-fond) !important;
  -webkit-backdrop-filter: var(--verre-flou); backdrop-filter: var(--verre-flou);
  border: 1px solid var(--verre-bord);
  margin-left: 10px; margin-right: 10px;
}
body[data-view="chat"] .topbar {
  margin-top: 8px;
  border-radius: 18px 18px 0 0;
  border-bottom: 0;
  padding: 10px 16px;
}
body[data-view="chat"] .outils {
  margin-bottom: 10px;
  border-radius: 0 0 18px 18px;
  border-top: 1px solid var(--line);
  padding: 10px 16px;
  box-shadow: 0 18px 40px -30px rgba(0, 0, 0, .9);
}

/* les boutons des deux rangées parlent la même langue */
body[data-view="chat"] .topbar .btn,
body[data-view="chat"] .outils .btn {
  font-size: 12px; padding: 6px 12px; border-radius: 999px; font-weight: 500;
}
body[data-view="chat"] .topbar .btn.on,
body[data-view="chat"] .outils .btn.on {
  background: var(--accent); color: #fff; border-color: transparent;
}
body[data-view="chat"] .outils input {
  border-radius: 999px; padding: 7px 14px; font-size: 12.5px;
}
body[data-view="chat"] .topbar .brand { font-size: 14px; }
body[data-view="chat"] .vues { gap: 4px; }

/* le bandeau des titres de direct suit le même retrait */
body[data-view="chat"] .bandeau { margin: 0 10px; border-radius: 14px; }

@media (max-width: 780px) {
  body[data-view="chat"] .topbar, body[data-view="chat"] .outils {
    margin-left: 6px; margin-right: 6px; padding: 8px 10px;
  }
}

/* l'interrupteur de plateforme : on coupe une source sans perdre son nom */
.ctrl-plateformes li.pause i { background: #8a8a95; }
.ctrl-plateformes li.pause span { opacity: .6; }
.ctrl-inter {
  width: 34px; height: 19px; border-radius: 999px; border: 0; cursor: pointer;
  background: rgba(255, 255, 255, .16); position: relative; flex: none; margin-left: 10px;
  transition: background-color .2s ease;
}
.ctrl-inter span {
  position: absolute; top: 2px; left: 2px; width: 15px; height: 15px; border-radius: 999px;
  background: #fff; transition: transform .2s cubic-bezier(.22, 1, .36, 1);
}
.ctrl-inter.actif { background: var(--ok); }
.ctrl-inter.actif span { transform: translateX(15px); }
.ctrl-inter:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
body.clair .ctrl-inter { background: rgba(0, 0, 0, .18); }
@media (prefers-reduced-motion: reduce) { .ctrl-inter span { transition: none; } }

/* les trois tempéraments de modération, et les scores qui vont avec */
.ia-modes { display: flex; gap: 6px; margin-bottom: 10px; }
.ia-modes .btn { font-size: 11.5px; flex: 1 1 auto; }
.ia-scores { display: block; font-size: 11px; color: var(--dim); margin-top: 3px; }
.ia-scores b { color: var(--text); font-variant-numeric: tabular-nums; }

/* le centre de confidentialité : ce que le navigateur contient, en clair */
.stockage { display: grid; gap: 6px; margin: 14px 0; }
.stockage .entree {
  display: flex; align-items: baseline; gap: 10px; padding: 10px 12px;
  border: 1px solid var(--line); border-radius: 10px; background: var(--panel); font-size: 13px;
}
.stockage .entree b { font-family: ui-monospace, monospace; font-size: 12px; }
.stockage .entree span { color: var(--dim); flex: 1 1 auto; }
.stockage .entree i { font-style: normal; color: var(--dim); font-size: 11.5px; white-space: nowrap; }
.stockage .vide { color: var(--dim); margin: 0; }
.efface { margin-left: 10px; font-size: 13px; color: var(--ok); }

/* ==========================================================================
   Passe de correction du 19/08/2026, d'apres un audit boite noire mene sur le
   site en ligne pendant un direct a 400-800 messages/minute.
   Chaque bloc porte le defaut qu'il repare.
   ========================================================================== */

/* --- C-1 : sous ~600 px, « Chaines » et le menu « ... » sortaient de l'ecran.
   La barre du haut est en `flex-wrap: nowrap; overflow: hidden` sur mobile, et les
   boutons portent `flex-shrink: 0` : ce qui depasse est simplement decoupe, sans
   retour a la ligne ni defilement de secours. La regle qui masque `.vues` existait
   deja mais `body[data-view="chat"] .vues { display: flex }` est plus specifique,
   donc les trois boutons de vue restaient la et poussaient le reste dehors.
   On rend la main aux deux boutons qui comptent : ceux qui ouvrent le reste. */
@media (max-width: 720px) {
  body[data-view="chat"] .topbar .vues { display: none; }
  .topbar #btn-reglages, .topbar #btn-outils-mobile {
    flex: none; margin-left: auto; order: 20;
  }
  .topbar #btn-outils-mobile { margin-left: 6px; }
  /* Les pastilles de plateforme cedent avant les boutons : quatre plateformes actives
     prenaient a elles seules plus de place que la barre n'en a. */
  .topbar .pill { min-width: 0; flex-shrink: 1; overflow: hidden; text-overflow: ellipsis; }
  .topbar .brand { flex-shrink: 1; min-width: 0; overflow: hidden; }
}
/* En dessous de 420 px, meme les pastilles ne tiennent plus. L'etat de chaque plateforme
   reste lisible dans le poste de commande et dans la colonne en attente. */
@media (max-width: 420px) {
  body[data-view="chat"] .topbar .pill { display: none; }
}

/* --- M-2 : le bandeau de message et la pastille « Nouveaux messages » etaient
   centres au meme endroit, a six pixels d'ecart, et la pastille passait devant
   (z-index 6 contre 0). Chaque message systeme etait donc masque au moment ou il
   avait quelque chose a dire. On le remonte et on le passe devant. */
#toast { bottom: 148px; z-index: 20; }
@media (max-width: 720px) { #toast { bottom: 158px; } }

/* --- E-2 : en theme clair, l'horodatage et le deux-points tombaient sous le seuil
   WCAG AA (3,55:1 et 2,44:1 pour un minimum de 4,5:1). Les couleurs de pseudo, elles,
   sont ramenees dans une plage lisible par le code (voir render.js). */
body.clair { --mut-clair: #5b6473; }
body.clair .msg .time { color: var(--mut-clair); opacity: 1; }
body.clair .msg:hover .time { opacity: 1; }
body.clair .msg .sep { color: var(--mut-clair); opacity: 1; }
body.clair #compteur { color: var(--mut-clair); }

/* --- E-3 : l'ambiance selectionnee forcait `color: #fff` sur un fond violet a 20 %
   d'opacite. Sur un panneau sombre le blanc ressort ; sur un panneau blanc le meme
   fond donne un lavande tres pale, et le libelle disparait (1,34:1). On lit la
   couleur du texte du theme, et on ajoute un liseré : l'etat reste visible meme si
   la couleur du texte ne suffit pas. */
body.clair .ambiances .ambiance.on,
body.clair .btn.on.ambiance {
  color: var(--text);
  box-shadow: inset 0 0 0 1.5px var(--accent);
}

/* --- F-2 : cibles tactiles sous 24 x 24 px (WCAG 2.2 AA, critere 2.5.8).
   On agrandit la zone cliquable sans changer le dessin. */
.actions-msg { min-width: 24px; min-height: 24px; }
.ctrl-inter { min-height: 24px; padding: 4px 0; }
#accueil-lien { min-height: 24px; display: inline-flex; align-items: center; }
@media (pointer: coarse) {
  .actions-msg { min-width: 44px; min-height: 44px; }
  .ctrl-inter { min-height: 44px; }
}

/* --- F-4 : lien d'evitement. Invisible tant qu'on ne tabule pas, il donne au clavier
   une porte d'entree vers le contenu au lieu de traverser toute la barre du haut. */
.evitement {
  position: fixed; top: 8px; left: 8px; z-index: 100;
  transform: translateY(-200%); transition: transform .18s;
  background: var(--accent); color: #fff; text-decoration: none;
  padding: 10px 18px; border-radius: var(--r-plein); font-weight: 600; font-size: 13px;
}
.evitement:focus { transform: translateY(0); outline: 2px solid #fff; outline-offset: 2px; }
body[data-view="chat"] .evitement.pour-accueil { display: none; }
body[data-view="accueil"] .evitement.pour-chat { display: none; }

/* --- E-4 : la cle de licence est le seul secret du produit. Elle reste masquee, et
   le bouton qui la revele se tient dans le champ. */
.field.licence { position: relative; }
.field.licence input { padding-right: 96px; letter-spacing: .04em; }
.oeil {
  position: absolute; right: 96px; top: 50%; transform: translateY(-50%);
  background: transparent; border: 0; color: var(--dim); cursor: pointer;
  font: 600 12px inherit; padding: 6px 8px; border-radius: 8px; min-height: 24px;
}
.oeil:hover { color: var(--text); background: var(--panel-2); }
.oeil:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* --- M-9 : la recherche ne disait pas combien elle avait trouve. Deux lignes
   affichees pouvaient aussi bien etre tout le resultat qu'un fragment. */
#recherche-compteur {
  font-size: 11.5px; color: var(--dim); white-space: nowrap;
  font-variant-numeric: tabular-nums; padding: 0 2px;
}
@media (max-width: 720px) { #recherche-compteur { width: 100%; order: 5; } }

/* --- Modeles d'overlay : cinq habillages prets a poser, plus un apercu qui est la
   vraie page d'overlay chargee dans un cadre. Un apercu redessine a cote finit
   toujours par mentir : celui-ci ne peut pas, c'est le meme code. */
.modeles { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px; }
.modeles .modele { font-size: 12px; }
.modeles .modele.on { border-color: var(--accent); }
body.clair .modeles .modele.on { color: var(--text); box-shadow: inset 0 0 0 1.5px var(--accent); }

.apercu-overlay {
  margin: 0 0 18px; border: 1px solid var(--line); border-radius: var(--r3);
  overflow: hidden; height: 190px;
  /* damier discret : on voit tout de suite ce qui est transparent, comme sur une scene OBS */
  background-color: #191721;
  background-image:
    linear-gradient(45deg, rgba(255, 255, 255, .045) 25%, transparent 25%, transparent 75%, rgba(255, 255, 255, .045) 75%),
    linear-gradient(45deg, rgba(255, 255, 255, .045) 25%, transparent 25%, transparent 75%, rgba(255, 255, 255, .045) 75%);
  background-size: 18px 18px;
  background-position: 0 0, 9px 9px;
}
.apercu-overlay iframe { display: block; width: 100%; height: 100%; border: 0; background: transparent; }

/* --- F-5 : un filtre coche s'applique aussi aux messages deja affiches. On masque plutot
   que de supprimer, pour que le decocher les ramene — et pour ne pas retirer des noeuds
   dans le dos de la colonne, qui compte ses lignes par plateforme. */
.msg.filtre-off { display: none; }

/* --- Historique des alertes de l'agent : filtres par gravite. Elles defilaient et
   disparaissaient ; quelqu'un qui joue vingt minutes ne pouvait pas savoir ce qu'il
   avait manque. */
.ia-filtres { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 0 0 10px; }
.ia-filtres .btn { font-size: 11.5px; }
.ia-filtres .btn[disabled] { opacity: .38; cursor: default; }
.ia-filtres .grow { flex: 1; }

/* --- M-9 : la recherche cherche dans la memoire (cinq mille messages), pas dans l'ecran
   (trois cents). Ses resultats se posent par-dessus le flux, qui continue de tourner
   dessous : chercher ne doit pas couper le direct. */
.resultats { flex: 1; min-height: 0; display: flex; flex-direction: column; background: var(--bg); }
.resultats[hidden] { display: none; }
/* Le flux vivant continue de recevoir ses messages, il est simplement mis de cote le temps
   de la recherche : au retour, chaque colonne repart en bas, au direct. */
body[data-recherche="1"] .board { display: none; }
.resultats > header {
  flex: none; display: flex; align-items: center; gap: 12px;
  padding: 10px 14px; border-bottom: 1px solid var(--line); background: var(--panel);
  font-size: 12.5px; font-weight: 600;
}
.resultats > header b { flex: 1; font-weight: 600; color: var(--dim); }
.resultats .feed { flex: 1; overflow-y: auto; }

/* --- E-2 (suite) : le texte pose sur la couleur d'accent. « Blanc sur l'accent » donnait
   4,34:1 sur le violet par defaut, et bien pire sur l'orange ou le vert — or l'accent est
   justement ce que la personne choisit. `--sur-accent` est calcule au moment ou l'accent
   est applique (voir appliquerAffichage dans app.js) : blanc ou presque noir, celui des
   deux qui tient. */
.btn.on,
.btn.primary,
body[data-view="chat"] .topbar .btn.on,
body[data-view="chat"] .outils .btn.on,
body[data-view="accueil"] .topbar .btn.primary,
body.clair .btn.on,
body.clair .btn.primary,
.evitement,
#reprendre {
  color: var(--sur-accent, #fff);
  /* `--accent-fond`, c'est l'accent deplace du minimum necessaire pour porter ce texte —
     un pour cent de luminosite sur le violet par defaut, rien du tout sur les six autres.
     Les bordures et les liseres gardent `--accent` tel quel. */
  background: var(--accent-fond, var(--accent));
  border-color: var(--accent-fond, var(--accent));
}
body[data-view="chat"] .topbar .btn.on,
body[data-view="chat"] .outils .btn.on,
.btn.primary { border-color: transparent; }

/* --- Les boutons verrouilles (fonctions reservees) etaient a 4,34:1 : ils portent
   `--dim` sur un voile blanc a 6 %, qui eclaircit le fond juste assez pour faire tomber
   le contraste sous le seuil. Ils restent visiblement en retrait, mais lisibles. */
.btn.verrouille { color: #9c9ca5; }
body.clair .btn.verrouille { color: #5b5b66; }

/* En theme clair, l'estompage des messages d'historique compose le texte vers le blanc et
   fait perdre environ 3 % de contraste. Ils restent distincts, un peu moins pales. */
body.clair .msg.historique { opacity: .94; }

/* ==========================================================================
   Rangs, bande de l'equipe, bots, et mise en avant au clic — 19/08/2026
   ========================================================================== */

/* --- Le rang de la personne se lit d'un coup d'œil. Les badges images de Twitch sont deja
   affiches ; ce liseré dit la meme chose a la vitesse ou l'on lit un chat qui defile. */
.msg[data-rang="chaine"] { box-shadow: inset 3px 0 0 #e5553c; background: rgba(229, 85, 60, .07); }
.msg[data-rang="mod"] { box-shadow: inset 3px 0 0 #42c96a; background: rgba(66, 201, 106, .06); }
.msg[data-rang="vip"] { box-shadow: inset 3px 0 0 #ff3dce; background: rgba(255, 61, 206, .05); }
.msg[data-rang="abonne"] { box-shadow: inset 2px 0 0 rgba(155, 60, 255, .5); }
body.clair .msg[data-rang="chaine"] { background: rgba(229, 85, 60, .1); }
body.clair .msg[data-rang="mod"] { background: rgba(66, 201, 106, .1); }
body.clair .msg[data-rang="vip"] { background: rgba(255, 61, 206, .08); }

/* --- Un compte de service, dit une fois, discretement. Le but n'est pas de le cacher :
   c'est de ne plus le prendre pour un spammeur, ni de le compter comme une personne. */
.msg[data-bot] .who::after {
  content: 'bot'; margin-left: 5px; padding: 1px 4px; border-radius: 4px;
  font-size: .68em; font-weight: 700; letter-spacing: .04em; vertical-align: 1px;
  background: rgba(255, 255, 255, .1); color: var(--dim);
}
body.clair .msg[data-bot] .who::after { background: rgba(0, 0, 0, .07); }
/* On n'estompe pas la ligne entiere : l'opacite compose le pseudo vers le fond et le fait
   tomber sous le seuil WCAG (mesure : 4,29:1). Seul le corps du message recule, et le pseudo
   garde exactement le contraste qui lui a ete calcule. */
.msg[data-bot] .txt { color: var(--dim); }
body.clair .msg[data-bot] .txt { color: var(--mut-clair); }
.msg[data-bot]:hover .txt { color: inherit; }

/* --- La bande de l'equipe : un couloir epingle au-dessus du flux. A huit cents messages
   par minute, un message de moderateur dure une seconde a l'ecran. */
.equipe {
  flex: none; display: flex; flex-direction: column; max-height: 26vh; min-height: 0;
  border-bottom: 1px solid var(--line); background: var(--panel);
}
.equipe[hidden] { display: none; }
.equipe > header {
  flex: none; display: flex; align-items: center; gap: 10px;
  padding: 7px 14px; font-size: 11.5px; border-bottom: 1px solid var(--line);
}
.equipe > header b { letter-spacing: .1em; text-transform: uppercase; font-size: 10.5px; color: var(--dim); }
.equipe-qui {
  flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: var(--dim); font-size: 11.5px;
}
.equipe .feed { flex: 1; overflow-y: auto; min-height: 0; padding: 4px 0; }
.equipe .msg { padding-top: 5px; padding-bottom: 5px; }
@media (max-width: 720px) { .equipe { max-height: 32vh; } }

/* --- Cliquer un message le sort du lot.
   Viser un bouton de trois pixels sur une ligne qui defile est un exercice d'adresse ; la
   ligne entiere est une cible qu'on ne rate pas, et la mise en avant dit sans un mot que
   le flux attend qu'on ait fini. */
.msg { transition: transform .16s cubic-bezier(.2, .8, .3, 1), box-shadow .16s, background .16s; }
.msg.sortie {
  position: relative; z-index: 5;
  transform: scale(1.015);
  background: var(--panel-2);
  box-shadow: 0 8px 28px rgba(0, 0, 0, .5), inset 3px 0 0 var(--accent);
  border-radius: 10px;
}
body.clair .msg.sortie { box-shadow: 0 8px 24px rgba(26, 16, 48, .16), inset 3px 0 0 var(--accent); }
/* le reste du flux s'efface derriere, sans disparaitre : on garde le contexte */
body.un-message-sorti .feed .msg:not(.sortie) { opacity: .45; }
@media (prefers-reduced-motion: reduce) {
  .msg { transition: none; }
  .msg.sortie { transform: none; }
}

/* --- L'estompage par opacite est un piege a contraste.
   Une opacite sur la ligne compose TOUT son contenu vers le fond, y compris le pseudo dont
   la couleur vient d'etre calculee pour tenir le seuil WCAG. Mesure : un pseudo a 4,9:1 sur
   blanc tombait a 4,29:1 une fois pose sur une ligne d'historique (0,94) teintee « mod »
   (10 %). On estompe donc le corps du message, jamais la ligne. */
.msg.historique { opacity: 1; }
.msg.historique .txt { color: var(--dim); }
body.clair .msg.historique .txt { color: var(--mut-clair); }
