*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

/* ───────────────────────────────────────────────────────────────────────────
   Thème "paper" — palette éditoriale chaude (papier vieilli) reprise depuis
   doracom-site-complete.html. Devient le thème PAR DÉFAUT de l'app : si
   l'utilisateur n'a rien choisi, c'est ce qui s'applique.
   Activé via <html data-theme="paper">.
   ─────────────────────────────────────────────────────────────────────────── */
[data-theme="paper"] {
  /* Aligné sur DoraCom Design System v2 (paper · maroon · ephemeral).
     Bg/raised/sunken : warm cream à 3 niveaux.
     Accent : maroon burgundy — remplace l'ancien rust pour un rendu plus
     éditorial / moins agressif. */
  --bg:        #F4ECE0;      /* paper-200 — canvas principal */
  --bg-glass:  rgba(244, 236, 224, 0.92);
  --bg2:       #FBF4E8;      /* paper-100 — raised (cards, bubbles surface) */
  --bg2-glass: rgba(251, 244, 232, 0.92);
  --bg3:       #EDE3D2;      /* paper-300 — sunken (sidebar) */
  --bg3-glass: rgba(237, 227, 210, 0.95);
  --bg4:       #E0D3BD20;
  --hover:     #E0D3BD;      /* paper-400 — hover/active */
  --accent:    #8A2E25;      /* maroon-600 — button bg, send */
  --accent2:   #7A2E2E;      /* maroon-700 — deep, active borders */
  --accent-glow: rgba(156, 58, 46, 0.18);
  --text:      #2A1A14;      /* ink-700 — primary text */
  --text2:     #7A6B5C;      /* ink-300 — secondary text */
  --muted:     #A89A8B;      /* ink-200 — tertiary / meta */
  --border:    #E0D3BD;      /* paper-400 — default hairlines */
  --border2:   #D6C3A8;      /* darker hairline */
  --green:     #16A85F;      /* call-500 — voice/video active (Skype-tier green) */
  --red:       #B83A3A;      /* crimson-500 — danger */
  --yellow:    #C58A2A;      /* amber-500 — warn */
  /* Nouveaux tokens design system : */
  --bg-bubble: #EDE5F2;      /* lilac-100 — message bubble bg (post-quantum lilac) */
  --e2e:       #7D5A85;      /* lilac-700 — E2E badge text */
  --e2e-bg:    #EDE5F2;      /* lilac-100 — E2E badge bg */
  --ephemeral: #3F8B7A;      /* sea-500 — countdown trail ephemeral msgs */
  --call:      #16A85F;      /* call-500 — alias call */
  --call-soft: rgba(22, 168, 95, 0.10);
}

/* Matrix rain ACTIF en thème paper, version SUBTILE :
   - opacity 0.30 sur le canvas → la pluie reste perceptible mais ne domine
     plus la zone chat
   - background: var(--bg) pour ne jamais voir le noir résiduel canvas
   - z-index 0 (sous #app z:1)
   Combiné à #messages-area rgba 0.85 ci-dessous : matrix subtil derrière,
   fond paper dominant — lisible, ambiant, pas envahissant. */
/* Matrix paper : palette rouille rgb(196,74,44) avec bgFade boosté à 0.10
   dans matrix-rain.js → le canvas converge rapidement vers paper sans
   noir résiduel. opacity CSS 0.55 → pluie franche mais sous fond papier. */
[data-theme="paper"] #matrix-bg {
  display: block !important;
  opacity: 0.55 !important;
  z-index: 0;
  background: var(--bg) !important;
}

/* Grain papier — texture SVG noise subtile sur tout le fond, multiplie
   pour assombrir les zones colorées (effet imprimé).
   Typographie design system : Geist sans pour le corps. */
[data-theme="paper"] body {
  background: var(--bg);
  font-family: 'Geist', 'Manrope', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  color: var(--text2);
  font-weight: 400;
  letter-spacing: 0;
}
/* Grain papier : posé SOUS le canvas matrix (z-index -1) pour ne pas le
   masquer. Opacité réduite pour rester un détail subtil. */
[data-theme="paper"] body::before {
  content: '';
  position: fixed; inset: 0;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2'/%3E%3CfeColorMatrix values='0 0 0 0 0.4 0 0 0 0 0.35 0 0 0 0 0.25 0 0 0 0.06 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  opacity: 0.25;
  pointer-events: none;
  mix-blend-mode: multiply;
  z-index: -1;
}
/* Le canvas matrix doit être au-dessus du grain (mais sous l'app) */
/* paper : matrix-bg masqué (cf. règle plus haut) — z-index neutralisé */

/* Typographie design system v2 :
   - Instrument Serif italic pour le wordmark/display (titres marquants)
   - Geist sans pour les headlines (semibold)
   - Geist Mono pour les pseudos/IDs/codes
   Fraunces/Manrope/JetBrains Mono restent en fallback pour les autres
   thèmes (terminal/cyber/etc). */
[data-theme="paper"] .app-logo,
[data-theme="paper"] .pseudo-display {
  font-family: 'Instrument Serif', 'Fraunces', 'Iowan Old Style', Georgia, serif;
  font-style: italic;
  font-weight: 400;
  color: var(--text);
  letter-spacing: -0.02em;
}
[data-theme="paper"] .channel-name,
[data-theme="paper"] .ch-title,
[data-theme="paper"] .modal-create-title,
[data-theme="paper"] h1,
[data-theme="paper"] h2,
[data-theme="paper"] h3 {
  font-family: 'Geist', 'Manrope', system-ui, sans-serif;
  font-weight: 600;
  color: var(--text);
  letter-spacing: -0.015em;
}
[data-theme="paper"] em,
[data-theme="paper"] .fraunces-italic {
  font-style: italic;
  font-family: 'Instrument Serif', 'Fraunces', Georgia, serif;
  color: var(--accent);
}
[data-theme="paper"] code,
[data-theme="paper"] pre,
[data-theme="paper"] .msg-csv-table,
[data-theme="paper"] .id-display,
[data-theme="paper"] [class*="-id-"],
[data-theme="paper"] kbd {
  font-family: 'Geist Mono', 'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace;
}

/* Ajustements composants spécifiques pour le rendu papier */
[data-theme="paper"] #sidebar {
  background: var(--bg2);
  border-right: 1px solid var(--border);
}
[data-theme="paper"] #tab-bar,
[data-theme="paper"] #content-header {
  background: var(--bg-glass);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--border);
}
[data-theme="paper"] .tab {
  background: transparent;
  color: var(--text2);
}
[data-theme="paper"] .tab.active {
  color: var(--text);
  border-bottom-color: var(--accent);
}
[data-theme="paper"] .channel-item:hover,
[data-theme="paper"] .channel-item.active {
  background: var(--hover);
}
/* Message bubbles design system : reçus = bubble lilac (post-quantum lilac),
   envoyés = accent maroon. Le lilac est la signature visuelle du design v2,
   il dit "ce contenu est E2E chiffré" sans avoir besoin de l'écrire. */
[data-theme="paper"] .msg-bubble,
[data-theme="paper"] .dm-bubble {
  background: var(--bg-bubble);
  color: var(--text);
  border: 1px solid transparent;
  border-radius: 12px;
}
[data-theme="paper"] .dm-row.sent .dm-bubble {
  background: var(--accent);
  color: var(--bg2);
  border-color: transparent;
}
/* Underline subtile sur les messages éphémères (couleur sea du design v2) */
[data-theme="paper"] .msg-bubble.ephemeral,
[data-theme="paper"] .dm-bubble.ephemeral {
  box-shadow: inset 0 -2px 0 var(--ephemeral);
}
[data-theme="paper"] .msg-card { border-color: var(--border); }
/* Médias (image/vidéo) en thème paper : pas de halo noir — bordure chaude
   fine fondue dans le crème + ombre douce teintée encre (rgba 42,26,20), au
   lieu du rgba(0,0,0,…) qui jurait. Plus doux, plus « sur le fond » (retour
   user 2026-06-11). */
[data-theme="paper"] .msg-img,
[data-theme="paper"] .dm-img,
[data-theme="paper"] .msg-video {
  box-shadow: 0 1px 6px rgba(42, 26, 20, 0.10);
  border: 1px solid var(--border);
}
[data-theme="paper"] input,
[data-theme="paper"] textarea {
  background: var(--bg);
  color: var(--text);
  border-color: var(--border2);
}
[data-theme="paper"] input::placeholder,
[data-theme="paper"] textarea::placeholder { color: var(--muted); }
[data-theme="paper"] #composer {
  background: var(--bg-glass);
  backdrop-filter: blur(8px);
  border-top: 1px solid var(--border);
}
/* Boutons design system v2 : primary = maroon burgundy, secondary = ghost
   beige solide. Plus de "btn = texte sombre" — l'accent maroon devient
   l'élément actif principal. */
[data-theme="paper"] .btn,
[data-theme="paper"] .btn-primary {
  background: var(--accent);
  color: var(--bg2);
  border: none;
  font-weight: 500;
  letter-spacing: 0;
}
[data-theme="paper"] .btn:hover,
[data-theme="paper"] .btn-primary:hover {
  background: var(--accent2);
}
[data-theme="paper"] .btn-secondary {
  background: transparent;
  color: var(--text);
  border: 1px solid var(--border);
  font-weight: 500;
}
[data-theme="paper"] .btn-secondary:hover {
  background: var(--bg3);
  border-color: var(--border2);
}
[data-theme="paper"] .btn-send {
  background: var(--accent);
  color: var(--bg2);
}
/* Z-index : le grain papier doit rester DESSOUS le contenu */
[data-theme="paper"] #app { position: relative; z-index: 2; }

/* ════════════════════════════════════════════════════════════════════════════
   Design System v2 — composants supplémentaires (paper)
   Récupéré du ui_kits/desktop/style.css :
   - .pq-chip       → pill maroon outline "pq · verified" dans header canal
   - .members-chip  → pill verte avec dot "● N members"
   - .call-btn      → bouton call carré vert (au lieu d'icône grise)
   - .msg-crown     → couronne 👑 à côté du nom auteur si owner/admin
   - .msg-countdown → texte "⌛ MM:SS" à droite du nom (couleur sea-500)
   - .msg-expiry-bar→ trace 2px sea-500 en bas de bulle (border-trace)
   - .ch-channel-topic → ligne discrète "Daily ops. Ephemeral 1h."
   ════════════════════════════════════════════════════════════════════════════ */

[data-theme="paper"] .pq-chip {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--accent-glow);
  border: 1px solid rgba(156, 58, 46, 0.18);
  color: var(--accent2);
  font: 500 10px/1 'Geist', 'Manrope', system-ui, sans-serif;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  white-space: nowrap;
}

[data-theme="paper"] .members-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 10px;
  border-radius: 999px;
  background: var(--call-soft);
  border: 1px solid rgba(22, 168, 95, 0.18);
  color: #0C7A41;       /* call-700 deep green pour le texte */
  font: 500 12px/1 'Geist', 'Manrope', system-ui, sans-serif;
  white-space: nowrap;
}
[data-theme="paper"] .members-chip .dot {
  width: 6px; height: 6px;
  border-radius: 999px;
  background: var(--call);
  box-shadow: 0 0 0 3px rgba(22, 168, 95, 0.18);
  animation: members-pulse 2.6s ease-in-out infinite;
}
@keyframes members-pulse {
  0%, 100% { box-shadow: 0 0 0 3px rgba(22, 168, 95, 0.18); }
  50%      { box-shadow: 0 0 0 6px rgba(22, 168, 95, 0); }
}

/* Boutons call (design system v2) : carré 36×36, vert pâle au repos,
   vert vif au hover. Skype-tier green — signale clairement "appel" sans
   bruit visuel.
   Spécificité gérée par cascade : #incoming-call .call-btn (déclaré
   plus bas ligne ~2579) gagne grâce à l'ID → les contrôles in-call
   gardent leur look pill blanc. */
.call-btn {
  width: 36px; height: 36px;
  border-radius: 8px;
  background: rgba(22, 168, 95, 0.10);
  border: 1px solid rgba(22, 168, 95, 0.22);
  color: #0C7A41;
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer;
  transition: background 120ms cubic-bezier(0.2, 0, 0, 1),
              transform 80ms, box-shadow 120ms,
              border-color 120ms, color 120ms;
  padding: 0;
  flex-shrink: 0;
}
.call-btn:hover {
  background: #16A85F;
  color: #fff;
  border-color: #16A85F;
  box-shadow: 0 4px 12px -4px rgba(22, 168, 95, 0.40);
}
.call-btn:active { transform: scale(0.95); }
.call-btn[disabled] { opacity: 0.4; cursor: not-allowed; }
.call-btn[disabled]:hover { background: rgba(22, 168, 95, 0.10); color: #0C7A41; border-color: rgba(22, 168, 95, 0.22); box-shadow: none; }
/* SVG inside : hérite de currentColor, taille fixe pour ne pas dépendre de font-size. */
.call-btn svg { width: 16px; height: 16px; }
/* En communication (1-to-1 ou groupe) → on masque les boutons « appel » et
   « vidéo » de l'en-tête (DM + canal). Décision user v423 : tant que je suis en
   appel, ces boutons n'ont pas de sens. La sonnerie (🔔) et le reste restent. */
html.weeair-in-call .btn-call-audio,
html.weeair-in-call .btn-call-video,
html.weeair-in-call .btn-group-call-audio,
html.weeair-in-call .btn-group-call-video { display: none !important; }

/* Header canal : flex layout + topic line discrète */
[data-theme="paper"] .ch-channel-simple {
  display: flex; align-items: center; gap: 14px; flex-wrap: nowrap;
}
[data-theme="paper"] .ch-channel-block {
  display: flex; flex-direction: column; gap: 2px;
  flex: 1; min-width: 0;
}
[data-theme="paper"] .ch-channel-line {
  display: inline-flex; align-items: center; gap: 8px;
  white-space: nowrap;
}
/* Cluster meta à droite du header : 🛡 PQ icon + 📌 Épinglés filter +
   readonly tag + members-chip + boutons call, tous alignés sur la même
   ligne. */
[data-theme="paper"] .ch-channel-meta {
  display: inline-flex; align-items: center;
  gap: 8px;
  flex-shrink: 0;
}
/* Hauteurs harmonisées : pills/chips à 28px, boutons à 32×32. */
[data-theme="paper"] .ch-channel-meta .pq-chip,
[data-theme="paper"] .ch-channel-meta .badge-readonly,
[data-theme="paper"] .ch-channel-meta .members-chip {
  height: 28px;
  display: inline-flex; align-items: center;
  padding-top: 0; padding-bottom: 0;
  box-sizing: border-box;
}
[data-theme="paper"] .ch-channel-meta .call-btn {
  width: 32px; height: 32px;
}
/* 🛡 Bouton icône PQ : remplace l'ancien pill "pq · verified". Tooltip
   au hover, toast détaillé au clic. Couleur accent maroon pour rester
   dans le DS, fond transparent pour rester discret. */
[data-theme="paper"] .pq-icon-btn {
  width: 32px; height: 32px;
  border-radius: 8px;
  background: var(--accent-glow);
  border: 1px solid rgba(156, 58, 46, 0.18);
  color: var(--accent2);
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer;
  font-size: 14px;
  padding: 0;
  transition: background 120ms, border-color 120ms, transform 80ms;
}
[data-theme="paper"] .pq-icon-btn:hover {
  background: rgba(156, 58, 46, 0.12);
  border-color: rgba(156, 58, 46, 0.32);
}
[data-theme="paper"] .pq-icon-btn:active { transform: scale(0.95); }
/* 📌 Bouton filtre épinglés : pill compacte avec compteur. État "active"
   = jaune doré soutenu (style highlight) pour signaler le mode filtre ON. */
[data-theme="paper"] .btn-pin-filter {
  height: 28px;
  display: inline-flex; align-items: center; gap: 5px;
  padding: 0 10px;
  border-radius: 999px;
  background: rgba(245, 197, 24, 0.10);
  border: 1px solid rgba(245, 197, 24, 0.30);
  color: #8a6a00;
  font: 600 11.5px/1 'Geist', 'Manrope', system-ui, sans-serif;
  letter-spacing: 0.02em;
  cursor: pointer;
  white-space: nowrap;
  transition: background 120ms, border-color 120ms, color 120ms, transform 80ms;
}
[data-theme="paper"] .btn-pin-filter:hover {
  background: rgba(245, 197, 24, 0.18);
  border-color: rgba(245, 197, 24, 0.50);
}
[data-theme="paper"] .btn-pin-filter:active { transform: scale(0.96); }
[data-theme="paper"] .btn-pin-filter.active {
  background: #f5c518;
  border-color: #e0a800;
  color: #1a1500;
  box-shadow: 0 0 0 2px rgba(245, 197, 24, 0.25);
}
/* Mode filtre actif : cache toutes les msg-card chronologiques + le banner
   "msgs-empty" éventuel. Seule la pinned-section reste visible. */
.pinned-filter-active > .msg-card:not(.msg-card-pinned),
.pinned-filter-active > .msgs-empty,
.pinned-filter-active > .msgs-sk-lost-banner {
  display: none !important;
}
/* En mode filtre, supprime le séparateur dashed (pas de chrono dessous) */
.pinned-filter-active .pinned-section {
  border-bottom: none;
  margin-bottom: 0;
  padding-bottom: 0;
}
[data-theme="paper"] .channel-prefix {
  color: var(--accent);
  font-family: 'Geist Mono', ui-monospace, 'SF Mono', monospace;
  font-weight: 600;
  font-size: 18px;
}
[data-theme="paper"] .ch-channel-name {
  font: 600 18px/1.1 'Geist', 'Manrope', system-ui, sans-serif;
  letter-spacing: -0.01em;
  color: var(--text);
}
[data-theme="paper"] .ch-channel-topic {
  padding-left: 0;
  font: 400 12px/1.4 'Geist', 'Manrope', system-ui, sans-serif;
  color: var(--text2);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  max-width: 280px;
}

/* Crown couronne pour owner/admin : juste à droite du nom auteur dans la bulle. */
[data-theme="paper"] .msg-crown {
  font-size: 13px;
  line-height: 1;
  filter: drop-shadow(0 1px 0 rgba(122, 46, 46, 0.15));
}

/* Countdown sablier+temps : couleur sea (--ephemeral) au repos, ambre si
   < 10min, crimson si < 1min. Mono pour aligner les chiffres. */
[data-theme="paper"] .msg-countdown {
  display: inline-flex; align-items: center; gap: 4px;
  margin-left: auto;
  font: 500 10px/1 'Geist Mono', ui-monospace, monospace;
  color: var(--ephemeral);
  letter-spacing: 0.02em;
  white-space: nowrap;
}
[data-theme="paper"] .msg-countdown.warn { color: var(--yellow); }
[data-theme="paper"] .msg-countdown.urgent { color: var(--red); }

/* Trace sea-500 en bas de bulle (border-trace du design v2) — surclasse
   l'ancienne msg-expiry-bar verticale. 2px de hauteur, ne déborde pas. */
[data-theme="paper"] .msg-card .msg-expiry-bar {
  height: 2px;
  background: var(--hover);
  border-radius: 0 0 12px 12px;
  overflow: hidden;
  margin: 8px -1px -1px;
}
[data-theme="paper"] .msg-card .msg-expiry-fill {
  height: 100%;
  background: var(--ephemeral);
  border-radius: 0 0 12px 12px;
  transition: width 1s linear;
}
[data-theme="paper"] .msg-card .msg-expiry-fill.warn  { background: var(--yellow); }
[data-theme="paper"] .msg-card .msg-expiry-fill.urgent { background: var(--red); }


/* Force globale paper : body reste paper-0 (base), mais les conteneurs
   principaux passent en SEMI-TRANSPARENT pour laisser passer la pluie
   matrix derrière. Sidebar et composer en paper-1 alpha avec backdrop-blur. */
[data-theme="paper"] html,
[data-theme="paper"] body { background: #F4ECE0 !important; color: #2A1A14 !important; }
[data-theme="paper"] #main-ui,
[data-theme="paper"] #content {
  background: transparent !important;
  color: #2A1A14;
}
[data-theme="paper"] #sidebar {
  /* Sidebar paper-300 (sunken) à 0.92 — la lisibilité prime sur le matrix.
     Léger blur pour profondeur. */
  background: rgba(237, 227, 210, 0.92) !important;
  backdrop-filter: blur(12px) saturate(110%);
  -webkit-backdrop-filter: blur(12px) saturate(110%);
  border-right: 1px solid #E0D3BD;
}
[data-theme="paper"] #tab-bar,
[data-theme="paper"] #content-header,
[data-theme="paper"] #composer {
  background: rgba(244, 236, 224, 0.92) !important;
  backdrop-filter: blur(10px) saturate(110%);
  -webkit-backdrop-filter: blur(10px) saturate(110%);
  border-color: #E0D3BD !important;
  color: #2A1A14;
}
[data-theme="paper"] #messages-area {
  /* Zone chat paper-200 translucide 0.62 → matrix rouille reste perceptible. */
  background: rgba(244, 236, 224, 0.62) !important;
  color: #2A1A14;
}
/* Bandeaux de contexte (wall/dm/channel) en thème paper. */
[data-theme="paper"] #messages-area[data-context="wall"],
[data-theme="paper"] #messages-area[data-context="dm"],
[data-theme="paper"] #messages-area[data-context="channel"] {
  background: rgba(244, 236, 224, 0.62) !important;
}

/* Texte muted, hover sidebar items, badges secondaires : tons ink. */
[data-theme="paper"] .section-header,
[data-theme="paper"] .section-title { color: #7A6B5C !important; }
[data-theme="paper"] .channel-item,
[data-theme="paper"] .user-item { color: #2A1A14; }
[data-theme="paper"] .channel-item:hover,
[data-theme="paper"] .channel-item.active,
[data-theme="paper"] .user-item:hover {
  background: #EDE3D2 !important;
}

/* Tabs : labels en ink, soulignement en accent rouille */
[data-theme="paper"] .tab { color: #7A6B5C !important; }
[data-theme="paper"] .tab.active {
  color: #2A1A14 !important;
  border-bottom: 2px solid #8A2E25 !important;
}

/* Boutons principaux & icônes — convertit l'accent violet en rouille */
[data-theme="paper"] .btn-icon,
[data-theme="paper"] #btn-create-channel,
[data-theme="paper"] .modal-create-icon {
  background: linear-gradient(135deg, #8A2E25, #7A2E2E) !important;
  color: #F4ECE0 !important;
  box-shadow: 0 3px 12px rgba(156,58,46,0.18) !important;
}
[data-theme="paper"] .btn-send {
  background: #8A2E25 !important; color: #F4ECE0 !important;
}
[data-theme="paper"] .btn-send:disabled { background: #E0D3BD !important; color: #A89A8B !important; }
[data-theme="paper"] .btn-primary {
  background: #2A1A14 !important; color: #F4ECE0 !important; border: none;
}
[data-theme="paper"] .btn-primary:hover { background: #2a261f !important; }
[data-theme="paper"] .btn-secondary {
  background: transparent !important; color: #2A1A14 !important;
  border: 1px solid rgba(42,26,20,0.25) !important;
}
[data-theme="paper"] .btn-secondary:hover {
  background: #EDE3D2 !important;
}

/* Bulles messages — fond paper-1 + bordure hairline, sent en ink-0 */
[data-theme="paper"] .msg-bubble,
[data-theme="paper"] .dm-bubble {
  background: #FBF4E8 !important;
  color: #2A1A14 !important;
  border: 1px solid rgba(42,26,20,0.10) !important;
}
[data-theme="paper"] .dm-row.sent .dm-bubble {
  background: #2A1A14 !important;
  color: #F4ECE0 !important;
  border-color: #2A1A14 !important;
}
[data-theme="paper"] .msg-card { border-color: rgba(42,26,20,0.10) !important; background: transparent !important; }

/* Composer textarea & inputs : fond paper + bord hairline */
[data-theme="paper"] input,
[data-theme="paper"] textarea,
[data-theme="paper"] .composer-main {
  background: #F4ECE0 !important;
  color: #2A1A14 !important;
  border-color: rgba(42,26,20,0.25) !important;
}
[data-theme="paper"] input::placeholder,
[data-theme="paper"] textarea::placeholder { color: #A89A8B !important; }

/* Profile section & logo */
[data-theme="paper"] .sidebar-profile,
[data-theme="paper"] .sidebar-header {
  background: transparent !important;
  border-color: rgba(42,26,20,0.10) !important;
}
/* Logo "DoraCom" en serif Fraunces ink-0 (au lieu du violet) avec un trait
   rouille subtil pour rappeler l'accent DoraCom. */
[data-theme="paper"] .app-logo,
[data-theme="paper"] .logo-text {
  color: #2A1A14 !important;
  background: none !important;
  -webkit-text-fill-color: #2A1A14 !important;
  font-family: 'Fraunces', Georgia, serif !important;
  font-weight: 500 !important;
  letter-spacing: -0.01em;
}
[data-theme="paper"] .pseudo-display {
  color: #2A1A14 !important;
  font-family: 'Fraunces', Georgia, serif !important;
  font-weight: 500 !important;
}

/* Boutons sidebar (EN, 🔔, ✎) : style paper hairline */
[data-theme="paper"] #btn-lang-toggle,
[data-theme="paper"] .btn-lang-toggle,
[data-theme="paper"] .btn-push-toggle,
[data-theme="paper"] .btn-edit-pseudo,
[data-theme="paper"] .btn-recovery-small {
  background: transparent !important;
  color: #2A1A14 !important;
  border: 1px solid rgba(42,26,20,0.20) !important;
  font-family: 'JetBrains Mono', ui-monospace, monospace !important;
}
[data-theme="paper"] #btn-lang-toggle:hover,
[data-theme="paper"] .btn-push-toggle:hover,
[data-theme="paper"] .btn-edit-pseudo:hover {
  background: rgba(42,26,20,0.06) !important;
  border-color: #8A2E25 !important;
  color: #8A2E25 !important;
}

/* Bouton Options (gros bouton sous le pseudo) — paper-2 + ink */
[data-theme="paper"] #btn-open-settings,
[data-theme="paper"] .btn-recovery-small {
  background: rgba(42,26,20,0.06) !important;
  color: #2A1A14 !important;
  border: 1px solid rgba(42,26,20,0.18) !important;
}
[data-theme="paper"] #btn-open-settings:hover {
  background: rgba(156,58,46,0.10) !important;
  border-color: #8A2E25 !important;
  color: #8A2E25 !important;
}

/* Section header "CHANNELS" — uppercase tracked, ink-3 */
[data-theme="paper"] .section-header {
  color: #A89A8B !important;
  font-family: 'JetBrains Mono', ui-monospace, monospace !important;
  font-size: 11px !important;
  letter-spacing: 0.08em !important;
}

/* Bouton "Installer l'application" — palette rouille au lieu de vert DoraCom */
[data-theme="paper"] .btn-install-pwa {
  background: linear-gradient(180deg, rgba(156,58,46,0.10), rgba(156,58,46,0.04)) !important;
  border: 1px solid rgba(156,58,46,0.35) !important;
  color: #8A2E25 !important;
}
[data-theme="paper"] .btn-install-pwa:hover {
  background: linear-gradient(180deg, rgba(156,58,46,0.18), rgba(156,58,46,0.08)) !important;
  border-color: #8A2E25 !important;
  box-shadow: 0 4px 14px rgba(156,58,46,0.18) !important;
}

/* Theme switcher cards en thème paper : neutralise les fonds noir/vert
   hardcodés des autres thèmes pour les afficher comme des "pastilles"
   tons paper. Sauf l'active qui prend l'accent rouille. */
[data-theme="paper"] .sidebar-theme-bar {
  background: transparent;
  border-top: 1px solid rgba(42,26,20,0.10);
  padding-top: 10px;
}
[data-theme="paper"] .btn-theme {
  background: rgba(244,236,224,0.6) !important;
  border: 1px solid rgba(42,26,20,0.20) !important;
}

/* Avatar fallback color (gradient violet → rouille) */
[data-theme="paper"] .avatar {
  background: linear-gradient(135deg, #8A2E25, #C58A2A) !important;
  color: #F4ECE0 !important;
}

/* (matrix-bg conservé en paper avec palette adaptée — cf. matrix-rain.js) */

/* Watermark central DoraCom : moins prononcé en paper */
[data-theme="paper"] .msgs-empty,
[data-theme="paper"] .msgs-empty * { color: #A89A8B !important; }

/* Scrollbar paper */
[data-theme="paper"] ::-webkit-scrollbar-thumb { background: rgba(42,26,20,0.2) !important; }
[data-theme="paper"] ::-webkit-scrollbar-thumb:hover { background: rgba(42,26,20,0.35) !important; }

/* Theme switcher : carte active en accent rouille */
[data-theme="paper"] .btn-theme.active {
  border-color: #8A2E25 !important;
  background: rgba(156,58,46,0.10) !important;
}
[data-theme="paper"] .btn-theme:hover { border-color: #8A2E25 !important; }

/* ── Modales en thème paper ───────────────────────────────────────────────
   Surface paper-1, header ink+rouille, boutons sticky bar en paper-1
   transparent → opaque, dégradé titre ink → rouille au lieu de violet. */
[data-theme="paper"] #modal-overlay {
  background: rgba(42,26,20,0.42) !important;
  backdrop-filter: blur(8px);
}
[data-theme="paper"] .modal {
  background: #F4ECE0 !important;
  color: #2A1A14 !important;
  border: 1px solid rgba(42,26,20,0.18) !important;
  box-shadow: 0 30px 80px rgba(42,26,20,0.25), 0 0 0 1px rgba(42,26,20,0.04) !important;
}
[data-theme="paper"] .modal-actions {
  background: linear-gradient(180deg, transparent, #F4ECE0 35%) !important;
}
[data-theme="paper"] .modal::-webkit-scrollbar-thumb { background: rgba(42,26,20,0.22) !important; }
[data-theme="paper"] .modal::-webkit-scrollbar-thumb:hover { background: rgba(42,26,20,0.38) !important; }
[data-theme="paper"] .modal-title { color: #2A1A14 !important; }
[data-theme="paper"] .modal-body { color: #2A1A14; }
[data-theme="paper"] .modal-create-header {
  border-bottom: 1px solid rgba(42,26,20,0.10) !important;
}
[data-theme="paper"] .modal-create-icon {
  filter: drop-shadow(0 4px 10px rgba(156,58,46,0.32)) !important;
  background: none !important;     /* annule le gradient bouton si la classe est partagée */
  color: #8A2E25 !important;
  box-shadow: none !important;
  width: auto; height: auto; border-radius: 0;
}
[data-theme="paper"] .modal-create-title {
  font-family: 'Fraunces', Georgia, serif !important;
  font-weight: 500 !important;
  background: linear-gradient(135deg, #2A1A14, #8A2E25) !important;
  -webkit-background-clip: text !important; background-clip: text !important;
  -webkit-text-fill-color: transparent !important;
}
[data-theme="paper"] .modal-create-subtitle { color: #A89A8B !important; }
[data-theme="paper"] .form-label { color: #7A6B5C !important; }
[data-theme="paper"] .form-input {
  background: #FBF4E8 !important;
  color: #2A1A14 !important;
  border: 1.5px solid rgba(42,26,20,0.20) !important;
}
[data-theme="paper"] .form-input::placeholder { color: #A89A8B !important; }
[data-theme="paper"] .form-input:focus {
  border-color: #8A2E25 !important;
  box-shadow: 0 0 0 3px rgba(156,58,46,0.18) !important;
}
[data-theme="paper"] .form-hint { color: #A89A8B !important; }
[data-theme="paper"] .modal-actions.centered .btn-primary {
  background: linear-gradient(135deg, #2A1A14, #8A2E25) !important;
  box-shadow: 0 4px 18px rgba(156,58,46,0.22) !important;
  color: #F4ECE0 !important;
}

/* Toast notifications en thème paper */
[data-theme="paper"] .toast {
  background: #2A1A14 !important;
  color: #F4ECE0 !important;
  border: 1px solid rgba(244,236,224,0.10) !important;
}
[data-theme="paper"] .toast.success { background: #2A1A14 !important; border-color: #8A2E25 !important; }
[data-theme="paper"] .toast.error { background: #b8362a !important; }

/* Vars partagées (non-couleurs) — toujours appliquées peu importe le thème */
:root {
  --sidebar:   300px;
  --radius:    10px;
  --radius-lg: 14px;
  --radius-xl: 18px;
}

/* Thème "default" (sombre violet) — défaut historique. Appliqué via
   <html data-theme="default">. theme-switcher.js force toujours un thème
   au boot (paper par défaut, ou la valeur saved). Si jamais aucun thème
   n'est appliqué (e.g. theme-switcher.js KO), le sélecteur :root vide
   ci-dessus laisse tomber les couleurs → flash de fond non-thémé, mais
   l'app reste utilisable. */
[data-theme="default"] {
  --bg:        #0c0c12;
  --bg-glass:  rgba(12, 12, 18, 0.40);
  --bg2:       #13131c;
  --bg2-glass: rgba(19, 19, 28, 0.45);
  --bg3:       #1a1a26;
  --bg3-glass: rgba(26, 26, 38, 0.80);
  --bg4:       #17172120;
  --hover:     #252535;
  --accent:    #7c6af7;
  --accent2:   #6457e8;
  --accent-glow: rgba(124,106,247,0.22);
  --text:      #e4e4f0;
  --text2:     #8888a8;
  --muted:     #55556a;
  --border:    #252535;
  --border2:   #303048;
  --green:     #3dd68c;
  --red:       #ff5572;
  --yellow:    #ffb340;
}

html, body {
  height: 100%;
  background: var(--bg);
  color: var(--text);
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  font-size: 14px;
  line-height: 1.5;
  overflow: hidden;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* ── Matrix rain background ── */
#matrix-bg {
  position: fixed; inset: 0;
  width: 100%; height: 100%;
  z-index: 0;
  pointer-events: none;
  opacity: 1;
}
#app { position: relative; z-index: 1; height: 100%; background: transparent; }

.hidden { display: none !important; }

/* ── Scrollbars ── */
::-webkit-scrollbar { width: 4px; height: 4px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--border2); border-radius: 4px; }
::-webkit-scrollbar-thumb:hover { background: var(--muted); }

/* ── Loading ── */
#loading-screen {
  position: fixed; inset: 0;
  background: var(--bg);
  display: flex; align-items: center; justify-content: center;
  z-index: 999;
}
.loading-content {
  text-align: center;
  display: flex; flex-direction: column; align-items: center; gap: 22px;
}
.loading-logo {
  font-size: 50px; font-weight: 800;
  background: linear-gradient(135deg, var(--accent) 0%, #a78bfa 50%, #60a5fa 100%);
  -webkit-background-clip: text; -webkit-text-fill-color: transparent;
  letter-spacing: -2px;
  filter: drop-shadow(0 0 32px var(--accent-glow));
}
.loading-text { color: var(--text2); font-size: 13px; font-weight: 500; letter-spacing: 0.02em; }
.spinner {
  width: 30px; height: 30px;
  border: 2px solid var(--border2);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin 0.75s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ── Layout ── */
#main-ui {
  display: flex;
  height: 100vh;                       /* fallback for very old browsers */
  height: calc(var(--vh, 1vh) * 100);  /* JS fallback for older Safari */
  height: 100dvh;                      /* dynamic viewport — fixes iOS Safari toolbar (wins if supported) */
}

/* ── Sidebar ── */
#sidebar {
  width: var(--sidebar); min-width: var(--sidebar);
  background: var(--bg2-glass);
  backdrop-filter: blur(1px);
  -webkit-backdrop-filter: blur(1px);
  border-right: 1px solid var(--border);
  overflow: hidden;
  /* Colonne flex : indispensable pour que .sidebar-sections (flex:1) et le
     scroll interne de #channels-list fonctionnent. Sans ça, la liste déborde
     et #sidebar{overflow:hidden} coupe les canaux du bas (inaccessibles). */
  display: flex;
  flex-direction: column;
  transition: width 0.3s cubic-bezier(0.4,0,0.2,1),
              min-width 0.3s cubic-bezier(0.4,0,0.2,1),
              transform 0.3s cubic-bezier(0.4,0,0.2,1);
  z-index: 10;
}
#sidebar.collapsed {
  width: 0; min-width: 0; border-right: none;
}

/* ── Theme bar ── */
.sidebar-theme-bar {
  display: flex; gap: 6px; padding: 10px 16px 14px;
  border-top: 1px solid var(--border);
  flex-shrink: 0; margin-top: auto;
}
.btn-theme {
  flex: 1; padding: 6px; border-radius: 8px; cursor: pointer;
  background: var(--bg3); border: 1.5px solid var(--border);
  font-size: 16px; transition: all 0.15s;
}
.btn-theme:hover { border-color: var(--accent); }
.btn-theme.active { border-color: var(--accent); background: var(--accent-glow); }

/* ══ MATRIX THEME ═══════════════════════════════════════════════════════════ */
[data-theme="matrix"] {
  --bg:           #000000;
  --bg-glass:     rgba(0, 0, 0, 0.45);
  --bg2:          #001a00;
  --bg2-glass:    rgba(0, 20, 0, 0.50);
  --bg3:          #002200;
  --bg3-glass:    rgba(0, 30, 0, 0.85);
  --bg4:          rgba(0, 40, 0, 0.15);
  --hover:        #003300;
  --accent:       #00dc50;
  --accent2:      #00b840;
  --accent-glow:  rgba(0, 220, 80, 0.20);
  --text:         #00ff66;
  --text2:        #00aa44;
  --muted:        #005522;
  --border:       #003300;
  --border2:      #004400;
  --green:        #00ff66;
  --red:          #ff4466;
  --yellow:       #aaff00;
}
[data-theme="matrix"] * {
  font-family: 'Courier New', Courier, monospace !important;
}
[data-theme="matrix"] .msg-bubble,
[data-theme="matrix"] .dm-bubble {
  background: #001800 !important;
  border: 1px solid #005500 !important;
  color: #00ff66 !important;
}
[data-theme="matrix"] .dm-bubble a,
[data-theme="matrix"] .msg-body a { color: #00ffaa !important; }
[data-theme="matrix"] .msg-card {
  background: rgba(0,20,0,0.6) !important;
  border-color: #003300 !important;
}
[data-theme="matrix"] input,
[data-theme="matrix"] textarea {
  color: #00ff66 !important;
  background: #001500 !important;
  border-color: #004400 !important;
}
[data-theme="matrix"] input::placeholder,
[data-theme="matrix"] textarea::placeholder { color: #005522 !important; }
[data-theme="matrix"] .composer-main {
  background: #001500 !important;
  border-color: #004400 !important;
}
[data-theme="matrix"] .avatar {
  filter: hue-rotate(100deg) saturate(2) !important;
}
[data-theme="matrix"] .app-logo .logo-text { color: #00ff66 !important; }
[data-theme="matrix"] #matrix-bg { opacity: 1; }
[data-theme="default"] #matrix-bg { opacity: 1; }


#sidebar-backdrop {
  display: none;
  position: fixed; inset: 0;
  background: rgba(0,0,0,0.55);
  z-index: 9;
  backdrop-filter: blur(2px);
}

.sidebar-header {
  padding: 15px 16px;
  border-bottom: 1px solid var(--border);
  display: flex; align-items: center; justify-content: space-between;
  flex-shrink: 0; gap: 8px;
}
.btn-sidebar-close {
  display: none; /* hidden on desktop */
  align-items: center; justify-content: center;
  width: 36px; height: 36px; flex-shrink: 0;
  background: var(--bg3); border: 1px solid var(--border);
  border-radius: 50%; cursor: pointer;
  font-size: 16px; font-weight: 700; color: var(--text2);
  transition: background 0.15s, color 0.15s;
  line-height: 1;
}
.btn-sidebar-close:hover { background: var(--hover); color: var(--text); }
.app-logo { display: flex; align-items: center; gap: 8px; font-weight: 800; font-size: 18px; letter-spacing: -0.5px; }
.logo-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px;
  color: var(--accent);
}
.logo-icon svg { width: 100%; height: 100%; }
.logo-text {
  background: linear-gradient(135deg, var(--accent), #a78bfa);
  -webkit-background-clip: text; -webkit-text-fill-color: transparent;
}
.btn-lang-toggle {
  background: var(--bg3);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: 5px;
  padding: 3px 9px;
  font-size: 11px;
  font-weight: 700;
  cursor: pointer;
  letter-spacing: 0.5px;
  flex-shrink: 0;
  margin-left: auto;
}
.btn-lang-toggle:hover { background: var(--accent); color: #fff; border-color: var(--accent); }
.network-badge {
  display: flex; align-items: center; gap: 5px;
  font-size: 11px; color: var(--text2); font-weight: 500;
  background: var(--bg3);
  padding: 4px 10px; border-radius: 20px;
  border: 1px solid var(--border);
}

/* Admin badge in profile */
.admin-badge {
  font-size: 9px; font-weight: 700; letter-spacing: 0.08em;
  text-transform: uppercase;
  background: linear-gradient(135deg, var(--accent), #a78bfa);
  color: white;
  padding: 2px 7px; border-radius: 10px;
  flex-shrink: 0;
  box-shadow: 0 1px 6px var(--accent-glow);
}

/* WiFi channel as first item in channels list */
.wifi-channel-item {
  display: flex; align-items: center; gap: 9px;
  width: 100%; padding: 9px 14px;
  background: none; border: none;
  cursor: pointer; text-align: left;
  font-family: inherit; font-size: 13px; font-weight: 600;
  color: var(--text);
  border-left: 3px solid transparent;
  transition: all 0.15s;
  position: relative;
  margin-bottom: 2px;
}
.wifi-channel-item:hover { background: var(--hover); border-radius: 0 8px 8px 0; }
.wifi-channel-item.active, .wifi-channel-item:focus {
  background: rgba(124,106,247,0.12);
  border-left-color: var(--accent);
  color: var(--accent);
  outline: none;
}
/* Icône WiFi : SVG inline animé (3 arcs qui pulsent en cascade)
   Plus net qu'un emoji, hérite de currentColor donc s'adapte au theme. */
.wifi-channel-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px;
  color: var(--accent);
  flex-shrink: 0;
}
.wifi-channel-icon svg { width: 100%; height: 100%; }
.wifi-channel-icon .wifi-arc-1,
.wifi-channel-icon .wifi-arc-2,
.wifi-channel-icon .wifi-arc-3 {
  transform-origin: 12px 20px;
  animation: wifi-pulse 2.4s ease-in-out infinite;
}
.wifi-channel-icon .wifi-arc-2 { animation-delay: 0.2s; }
.wifi-channel-icon .wifi-arc-3 { animation-delay: 0.4s; }
@keyframes wifi-pulse {
  0%, 60%, 100% { opacity: 1; }
  30% { opacity: 0.35; }
}
.wifi-channel-item.active .wifi-channel-icon { color: #fff; }

/* Icône WiFi inline (header, modales, etc.) — suit currentColor. */
.wifi-icon-svg { width: 1em; height: 1em; vertical-align: -2px; }
.ch-wifi-icon { color: #3dd68c; display: inline-flex; align-items: center; }

/* Tab WiFi temporairement masquée (UX peu comprise). Pour réactiver,
   retirer cette règle + le style display:none sur #btn-open-wall. */
.tab.tab-wall { display: none !important; }
/* Force le respect du HTML[hidden] sur l'item WiFi — le default display:flex
   du selector .wifi-channel-item gagnait sinon. */
.wifi-channel-item[hidden] { display: none !important; }

/* ── Channels actions (sous la liste, bas du bloc Channels) ────────── */
.channels-actions {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  padding: 10px 14px 6px;
  border-top: 1px solid var(--border);
  margin-top: 4px;
}
.btn-channel-action {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 8px 10px;
  background: var(--bg3, color-mix(in srgb, var(--accent) 6%, transparent));
  border: 1px solid var(--border);
  border-radius: 8px;
  cursor: pointer;
  font-family: inherit;
  font-size: 12px;
  font-weight: 600;
  color: var(--text);
  transition: background 120ms, border-color 120ms, transform 80ms;
}
.btn-channel-action:hover {
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  border-color: color-mix(in srgb, var(--accent) 30%, var(--border));
  color: var(--accent);
}
.btn-channel-action:active { transform: scale(0.96); }
.btn-channel-action-icon { font-size: 14px; line-height: 1; }
.btn-channel-action-label { line-height: 1; }
@supports not (color: color-mix(in srgb, red, blue)) {
  .btn-channel-action { background: rgba(124,106,247,0.08); }
  .btn-channel-action:hover { background: rgba(124,106,247,0.14); border-color: rgba(124,106,247,0.3); }
}

/* « Connecter mon ID » : CTA pleine largeur au-dessus des actions canal.
   Prérequis pour créer un canal → mis en avant (accent) tant que non lié.
   Une fois lié (.connected), passe en état discret « ✓ ID connecté ». */
.btn-connect-id {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  width: calc(100% - 28px);
  margin: 6px 14px 0;
  padding: 9px 12px;
  background: var(--accent);
  border: 1px solid var(--accent);
  border-radius: 8px;
  cursor: pointer;
  font-family: inherit;
  font-size: 12.5px;
  font-weight: 700;
  color: #fff;
  letter-spacing: 0.2px;
  box-shadow: 0 2px 10px var(--accent-glow);
  transition: background 120ms, border-color 120ms, transform 80ms, box-shadow 120ms;
}
.btn-connect-id:hover {
  background: color-mix(in srgb, var(--accent) 88%, #fff);
  box-shadow: 0 3px 14px var(--accent-glow);
}
.btn-connect-id:active { transform: scale(0.97); }
.btn-connect-id-icon { font-size: 14px; line-height: 1; }
.btn-connect-id-label { line-height: 1; }
/* État lié : plus de CTA, juste un repère discret. */
.btn-connect-id.connected {
  background: transparent;
  border-color: var(--border);
  color: var(--text-muted, #8a93a3);
  font-weight: 600;
  box-shadow: none;
}
.btn-connect-id.connected:hover {
  background: color-mix(in srgb, var(--accent) 8%, transparent);
  border-color: color-mix(in srgb, var(--accent) 30%, var(--border));
  color: var(--accent);
}
@supports not (color: color-mix(in srgb, red, blue)) {
  .btn-connect-id:hover { background: var(--accent); }
}

/* Tab WiFi avec icône SVG. */
.tab-wall .tab-label {
  display: inline-flex; align-items: center; gap: 6px;
}
.tab-wifi-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 14px; height: 14px;
  color: #3dd68c;
}
.tab-wifi-icon svg { width: 100%; height: 100%; }
.tab-wall.active .tab-wifi-icon { color: #fff; }

/* (watermark WiFi retiré : redondant avec l'icône sidebar/tab/header) */
.wifi-channel-name { flex: 1; }

/* Prominent create-channel CTA */
.dot { width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0; }
.dot.online {
  background: var(--green);
  box-shadow: 0 0 6px var(--green);
  animation: pulse-dot 2.5s ease infinite;
}
@keyframes pulse-dot { 0%, 100% { opacity: 1; } 50% { opacity: 0.6; } }

.sidebar-profile {
  padding: 12px 16px;
  border-bottom: 1px solid var(--border);
  display: flex; align-items: center; gap: 10px;
  flex-shrink: 0;
  background: var(--bg3);
}
.avatar {
  border-radius: 50%;
  background: linear-gradient(135deg, var(--accent), #a78bfa);
  display: flex; align-items: center; justify-content: center;
  font-weight: 700; color: white;
  flex-shrink: 0; user-select: none;
  box-shadow: 0 2px 10px var(--accent-glow);
  overflow: hidden;
}
.avatar.lg { width: 38px; height: 38px; font-size: 15px; }
.avatar.sm { width: 28px; height: 28px; font-size: 11px; }
.avatar.xs { width: 22px; height: 22px; font-size: 9px; }

.clickable-avatar {
  cursor: pointer;
  position: relative;
  transition: filter 0.2s;
}
.clickable-avatar:hover { filter: brightness(0.7); }
.clickable-avatar::after {
  content: '📷';
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: 14px; opacity: 0;
  transition: opacity 0.2s;
}
.clickable-avatar:hover::after { opacity: 1; }
.profile-info { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.pseudo-name-row { display: flex; align-items: center; gap: 6px; min-width: 0; cursor: pointer; }
.pseudo-name-row:hover .pseudo-display { color: var(--accent); }
.pseudo-name-row:hover .btn-edit-pseudo { color: var(--accent); opacity: 1; }
.pseudo-display { font-weight: 600; font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex: 1; min-width: 0; transition: color 0.15s; }
.btn-edit-pseudo {
  background: none; border: none; color: var(--text2);
  cursor: pointer; font-size: 14px; padding: 2px 5px; border-radius: 4px;
  flex-shrink: 0; transition: all 0.15s; line-height: 1; opacity: 0.7;
}
.btn-edit-pseudo:hover { color: var(--accent); opacity: 1; background: rgba(124,106,247,0.12); }

/* ── Gear "Options" icon-only dans la pseudo-name-row ─────────────────
   Remplace l'ancien bouton "⚙ Options" large en dessous. Stop propagation
   au click (handler JS) pour ne pas déclencher l'edit pseudo via le row. */
.btn-open-settings {
  background: none;
  border: 1px solid var(--border);
  color: var(--text2);
  cursor: pointer;
  font-size: 14px;
  padding: 4px 8px;
  border-radius: 6px;
  flex-shrink: 0;
  margin-left: auto;
  line-height: 1;
  transition: all 0.15s;
}
.btn-open-settings:hover {
  color: var(--accent);
  border-color: color-mix(in srgb, var(--accent) 35%, var(--border));
  background: color-mix(in srgb, var(--accent) 10%, transparent);
}
@supports not (color: color-mix(in srgb, red, blue)) {
  .btn-open-settings:hover { background: rgba(124,106,247,0.10); border-color: rgba(124,106,247,0.3); }
}
.sidebar-profile.editing { flex-wrap: wrap; }
.sidebar-profile.editing .pseudo-edit {
  width: 100%; flex-basis: 100%;
}
.pseudo-edit { display: flex; gap: 6px; align-items: center; width: 100%; }
.pseudo-edit input {
  flex: 1; background: var(--bg); border: 1.5px solid var(--accent);
  border-radius: 8px; color: var(--text);
  padding: 7px 12px; font-size: 14px;
  outline: none; min-width: 0; font-family: inherit;
  box-shadow: 0 0 0 3px var(--accent-glow);
}
.pseudo-edit input:focus { border-color: var(--accent); }
.pseudo-edit button { background: none; border: none; cursor: pointer; padding: 4px 8px; border-radius: 6px; font-size: 13px; font-weight: 600; font-family: inherit; white-space: nowrap; }
#pseudo-save { color: var(--green); }
#pseudo-cancel { color: var(--red); }

/* Recovery buttons */
.profile-recovery-row { display: flex; gap: 6px; margin-top: 6px; }
.btn-recovery-small {
  flex: 1; font-size: 10px; font-weight: 600; padding: 4px 6px;
  border-radius: 6px; cursor: pointer; border: 1px solid var(--border2);
  background: var(--bg3); color: var(--text2);
  white-space: nowrap; transition: all 0.15s; font-family: inherit;
}
.btn-recovery-small:hover { border-color: var(--accent); color: var(--accent); }
.btn-recovery-restore { border-color: rgba(0,220,80,0.3); color: var(--green); }
.btn-recovery-restore:hover { border-color: var(--green); background: rgba(0,220,80,0.1); }

/* Recovery phrase modal */
.recovery-phrase-grid {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 8px; margin: 16px 0;
}
.recovery-word {
  background: var(--bg3); border: 1px solid var(--border2);
  border-radius: 8px; padding: 8px 10px;
  display: flex; align-items: center; gap: 8px;
}
.recovery-word-num { font-size: 10px; color: var(--muted); font-weight: 700; min-width: 16px; }
.recovery-word-text { font-size: 13px; font-weight: 600; color: var(--text); font-family: monospace; }
.recovery-warning {
  background: rgba(255,181,64,0.12); border: 1px solid rgba(255,181,64,0.3);
  border-radius: 10px; padding: 12px 14px; font-size: 12px;
  color: var(--yellow); margin-bottom: 12px; line-height: 1.5;
}
.recovery-input-grid {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; margin: 12px 0;
}
.recovery-input-grid input {
  background: var(--bg3); border: 1px solid var(--border2); border-radius: 8px;
  color: var(--text); padding: 8px; font-size: 12px; text-align: center;
  font-family: monospace; outline: none; width: 100%;
}
.recovery-input-grid input:focus { border-color: var(--accent); }

.sidebar-sections { flex: 1; min-height: 0; display: flex; flex-direction: column; overflow: hidden; }
.sidebar-section { overflow-y: auto; padding: 8px 0; }
/* Channels : colonne flex interne — header figé en haut, #channels-list
   scrollable au milieu, .channels-actions figées en bas. min-height:0 lève le
   blocage flexbox classique (un flex-item ne peut pas shrink sous sa hauteur
   de contenu sans ça → le scroll ne s'activait jamais). */
.sidebar-section.channels-section {
  flex: 1; min-height: 0;
  display: flex; flex-direction: column;
  overflow: hidden;
  border-top: 1px solid var(--border);
}
.channels-section #channels-list {
  flex: 1; min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
}
.channels-section .section-header { flex: 0 0 auto; }
.channels-section .channels-actions { flex: 0 0 auto; }
/* État REPLIÉ = on FERME chaque canal : on masque les listes de membres et les
   actions par-canal, mais on GARDE les NOMS de canaux visibles (vue compacte).
   Avant : tout #channels-list était display:none → les canaux DISPARAISSAIENT
   complètement (bug signalé). « Replier » ≠ « masquer ». */
.channels-section.collapsed .channel-item-members,
.channels-section.collapsed .channel-item-actions { display: none !important; }
/* L'item actif ne reste pas en 2 lignes quand on replie : retour ligne simple
   (le nom + badges sur une seule ligne, comme les items inactifs). */
.channels-section.collapsed .channel-item.active > .channel-item-main {
  flex-wrap: nowrap; justify-content: flex-start;
}
.channels-section.collapsed .channel-item.active .channel-name-wrap { flex: 1 1 auto; }

/* En-tête « Channels » cliquable (toggle replier/déplier toute la liste). */
.channels-section-header {
  justify-content: flex-start;
  gap: 6px;
  cursor: pointer;
  user-select: none;
  -webkit-user-select: none;
}
.channels-section-header:hover { color: var(--text); }
.section-collapse-caret {
  display: inline-flex;
  font-size: 9px;
  line-height: 1;
  transition: transform 0.18s ease;
  opacity: 0.8;
}
.channels-section.collapsed .section-collapse-caret { transform: rotate(-90deg); }

.section-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 6px 16px;
  font-size: 10px; font-weight: 700; letter-spacing: 0.12em;
  color: var(--muted); text-transform: uppercase;
}
.btn-icon {
  background: var(--accent); border: none; color: #fff;
  cursor: pointer; font-size: 15px;
  width: 24px; height: 24px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 8px;
  transition: all 0.15s; line-height: 1;
  box-shadow: 0 2px 8px var(--accent-glow);
  flex-shrink: 0;
}
.btn-icon:hover { background: var(--accent2); transform: scale(1.1); box-shadow: 0 3px 12px var(--accent-glow); }
.wall-badge {
  background: var(--red); color: #fff;
  font-size: 10px; font-weight: 700;
  min-width: 18px; height: 18px; padding: 0 4px;
  border-radius: 9px; display: inline-flex; align-items: center; justify-content: center;
  animation: badgePop 0.25s ease;
}
@keyframes badgePop { from { transform: scale(0); } to { transform: scale(1); } }

.user-item {
  display: flex; align-items: center; gap: 8px;
  padding: 5px 10px;
  cursor: pointer; border-radius: 8px;
  margin: 1px 8px;
  transition: background 0.12s;
}
.user-item:hover { background: var(--hover); }
.user-item.me { cursor: default; }
.user-item.me:hover { background: transparent; }
.user-name { font-size: 13px; color: var(--text2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex: 1; }
.user-item.me .user-name { color: var(--text); font-weight: 500; }
.status-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--green); flex-shrink: 0; box-shadow: 0 0 5px var(--green); }
.dm-unread {
  background: var(--accent); color: white;
  font-size: 10px; padding: 1px 6px;
  border-radius: 10px; font-weight: 700;
  min-width: 18px; text-align: center;
}

/* Tous les indicateurs de notification utilisent maintenant le rouge
   (auparavant vert #22c55e). Une seule animation 'dmPulse' partagée
   par .dm-pending-dot, .tab-badge, .chan-badge. */
.dm-pending-dot {
  display: inline-block;
  width: 8px; height: 8px;
  border-radius: 50%;
  background: #ef4444;
  margin-left: auto;
  flex-shrink: 0;
  box-shadow: 0 0 0 0 rgba(239,68,68,0.5);
  animation: dmPulse 1.5s ease-in-out infinite;
}
/* Point rouge sur les onglets de canaux et sur la sidebar quand un nouveau
   message arrive dans un canal pas actif. La numérotation du compteur reste
   en mémoire (this.unreadChannels) mais le visuel ne montre qu'un dot. */
.tab-badge, .chan-badge {
  display: inline-block;
  width: 8px; height: 8px;
  border-radius: 50%;
  background: #ef4444;
  margin-left: 6px;
  flex-shrink: 0;
  vertical-align: middle;
  box-shadow: 0 0 0 0 rgba(239,68,68,0.5);
  animation: dmPulse 1.5s ease-in-out infinite;
  font-size: 0;
  color: transparent;
  overflow: hidden;
  text-indent: -9999px;
  line-height: 0;
}
.tab-badge.hidden, .chan-badge.hidden { display: none; }
@keyframes dmPulse {
  0%   { box-shadow: 0 0 0 0 rgba(239,68,68,0.5); }
  70%  { box-shadow: 0 0 0 5px rgba(239,68,68,0); }
  100% { box-shadow: 0 0 0 0 rgba(239,68,68,0); }
}

/* WiFi wall : caché pour l'instant — l'utilisateur n'en a pas besoin.
   Le code reste en place (state, handlers) au cas où on le réactive. */
.tab[data-tab="wall"] { display: none !important; }

.channel-item {
  display: flex; flex-direction: column;
  margin: 1px 8px;
  cursor: pointer; border-radius: 8px;
  border: 1px solid transparent;
  transition: background 0.12s, border-color 0.12s;
}
.channel-item:hover > .channel-item-main { background: var(--hover); border-radius: 7px; }
.channel-item.active { border-color: rgba(124,106,247,0.3); }
.channel-item.active > .channel-item-main {
  background: linear-gradient(135deg, rgba(124,106,247,0.15), rgba(124,106,247,0.06));
  border-radius: 7px;
}
/* Item ACTIF — actions sur la LIGNE DU NAME, poussées à droite (v381).
   La sidebar élargie (v380, 300px) laisse la place : plus besoin de wrapper
   les actions sur une 2e ligne (le comportement v373 servait à tenir dans une
   sidebar étroite). Retour à l'alignement « comme avant », inline à droite. */
.channel-item.active .channel-item-actions {
  margin-left: 6px;
}
.channel-item.active .channel-name { color: var(--accent); font-weight: 600; }
.channel-item.dragging { opacity: 0.4; cursor: grabbing; }
/* Canal avec un appel de groupe EN COURS : liseré vert "live" + pastille 📞
   pulsée, pour repérer en un coup d'œil sur quel canal on est en communication. */
.channel-item.channel-in-call { border-color: rgba(61, 214, 140, 0.5); }
.channel-item.channel-in-call > .channel-item-main {
  background: linear-gradient(135deg, rgba(61, 214, 140, 0.16), rgba(61, 214, 140, 0.05));
  border-radius: 7px;
}
.channel-item.channel-in-call .channel-name { color: var(--green, #3dd68c); }
.channel-call-badge {
  flex: 0 0 auto; margin-left: 4px; font-size: 11px; line-height: 1;
  animation: channel-call-pulse 1.6s ease-in-out infinite;
}
@keyframes channel-call-pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.45; transform: scale(0.86); }
}
.channel-item.drag-over { border-color: var(--accent); background: rgba(124,106,247,0.08); border-radius: 8px; }
.channel-item-main {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px; row-gap: 5px;
  padding: 6px 10px;
}
.channel-prefix { color: var(--muted); font-size: 15px; flex-shrink: 0; line-height: 1; }
/* flex-basis 0 → le name-wrap contribue 0 au calcul de wrap : le cluster méta
   reste sur la ligne 1 (à droite), et le nom rétrécit/tronque au lieu de
   pousser le méta à la ligne. */
.channel-name-wrap { flex: 1 1 0; min-width: 0; display: inline-flex; align-items: center; gap: 6px; }
/* Cluster méta (🔒 📞 👑 N👤 unread) aligné à DROITE, jamais tronqué. */
.channel-meta-right { display: inline-flex; align-items: center; gap: 6px; flex: 0 0 auto; margin-left: auto; }
.channel-name { font-size: 13px; color: var(--text2); min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.channel-lock { font-size: 11px; }
/* Badge "wall" : signale "ici on parle à tout le canal" (vs DM membre). */
.channel-wall-tag {
  display: inline-flex; align-items: center; flex-shrink: 0;
  font-size: 9.5px; font-weight: 700; letter-spacing: 0.6px; text-transform: lowercase;
  padding: 1px 6px; border-radius: 4px;
  background: rgba(255,255,255,0.06); color: var(--muted);
  line-height: 1.4;
}
.channel-item:hover .channel-wall-tag,
.channel-item.active .channel-wall-tag { background: rgba(61,214,140,0.18); color: var(--green); }
[data-theme="paper"] .channel-wall-tag { background: rgba(0,0,0,0.06); color: var(--muted); }
[data-theme="paper"] .channel-item:hover .channel-wall-tag,
[data-theme="paper"] .channel-item.active .channel-wall-tag { background: rgba(156,58,46,0.14); color: var(--accent); }

/* ── Main content ── */
#content { flex: 1; display: flex; flex-direction: column; overflow: hidden; background: var(--bg-glass); backdrop-filter: blur(1px); -webkit-backdrop-filter: blur(1px); min-width: 0; position: relative; }

/* ── Tab bar ── */
#tab-bar {
  height: 48px; min-height: 48px;
  border-bottom: 1px solid var(--border);
  background: var(--bg2);
  display: flex; align-items: center;
  padding: 0 12px; gap: 4px;
  flex-shrink: 0;
  overflow: hidden;
}
.tabbar-left {
  display: flex; align-items: center; gap: 4px;
  flex-shrink: 0;
}
.tabbar-logo {
  display: none;
  width: 26px; height: 26px;
  border-radius: 6px;
  flex-shrink: 0;
}

/* ── Tab-bar brand (mobile : logo + texte DoraCom avant le burger) ──── */
.tabbar-brand {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  text-decoration: none;
  padding: 5px 10px;
  border-radius: 10px;
  flex-shrink: 0;
  order: 0;                /* avant le burger partout */
  transition: transform 0.2s, background 0.15s;
  -webkit-tap-highlight-color: transparent;
}
#btn-sidebar-toggle { order: 1; }
.tabbar-brand:hover { background: var(--hover); }
.tabbar-brand:active { transform: scale(0.95); }
.tabbar-brand-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px;
  color: var(--accent);
  filter: drop-shadow(0 0 4px rgba(156, 58, 46, 0.35));
  animation: tabbar-brand-pulse 3.5s ease-in-out infinite;
}
.tabbar-brand-icon svg { width: 100%; height: 100%; }
.tabbar-brand-text {
  font-weight: 800;
  font-size: 17px;
  letter-spacing: -0.5px;
  background: linear-gradient(135deg, var(--accent) 0%, #a78bfa 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
  line-height: 1;
}
@keyframes tabbar-brand-pulse {
  0%, 100% { filter: drop-shadow(0 0 4px rgba(156,58,46,0.35)); transform: scale(1); }
  50%      { filter: drop-shadow(0 0 9px rgba(156,58,46,0.65)); transform: scale(1.04); }
}
#tabs-container {
  display: flex; gap: 4px; align-items: center;
  overflow-x: auto; flex: 1;
}
#tabs-container::-webkit-scrollbar { height: 2px; }
#tabs-container::-webkit-scrollbar-thumb { background: var(--border); }
#btn-sidebar-toggle {
  display: flex; flex-direction: column; justify-content: center; align-items: center;
  width: 34px; height: 34px; border-radius: 8px; flex-shrink: 0;
  background: transparent; border: none; cursor: pointer;
  gap: 4px; padding: 6px; margin-right: 4px;
  transition: background 0.15s;
}
#btn-sidebar-toggle:hover { background: var(--hover); }
.hamburger-icon,
.hamburger-icon::before,
.hamburger-icon::after {
  display: block; width: 18px; height: 2px;
  background: var(--text2); border-radius: 2px;
  transition: transform 0.25s, opacity 0.25s;
}
.hamburger-icon { position: relative; }
.hamburger-icon::before { content:''; position: absolute; top: -5px; left: 0; }
.hamburger-icon::after  { content:''; position: absolute; bottom: -5px; left: 0; }
/* Animate to × when open (sidebar not collapsed on mobile) */
#main-ui.sidebar-mobile-open .hamburger-icon { background: transparent; }
#main-ui.sidebar-mobile-open .hamburger-icon::before { transform: translateY(5px) rotate(45deg); background: var(--text); }
#main-ui.sidebar-mobile-open .hamburger-icon::after  { transform: translateY(-5px) rotate(-45deg); background: var(--text); }
.tab {
  display: flex; align-items: center; gap: 6px;
  padding: 6px 12px; border-radius: 8px;
  cursor: pointer; font-size: 13px; font-weight: 500;
  color: var(--text2); white-space: nowrap;
  transition: all 0.15s;
}
.tab:hover { background: var(--hover); color: var(--text); }
.tab.active {
  background: var(--bg3); color: var(--text);
  box-shadow: inset 0 0 0 1px var(--border2);
}
.tab-close { font-size: 14px; color: var(--muted); margin-left: 2px; opacity: 0; transition: opacity 0.1s; line-height: 1; }
.tab:hover .tab-close { opacity: 1; }
.tab-close:hover { color: var(--red); }
/* Onglet AVEC UN APPEL EN COURS : teinte verte « live » + liseré, distinct de
   l'état actif (.active) → on voit sur quel onglet on est ET lesquels sonnent. */
.tab.tab-in-call {
  background: linear-gradient(135deg, rgba(61,214,140,0.20), rgba(61,214,140,0.06));
  box-shadow: inset 0 0 0 1px rgba(61,214,140,0.55);
  color: var(--green, #3dd68c);
}
.tab.tab-in-call.active { box-shadow: inset 0 0 0 1.5px rgba(61,214,140,0.85); }
.tab-call-dot { font-size: 11px; line-height: 1; flex: 0 0 auto; animation: channel-call-pulse 1.6s ease-in-out infinite; }

/* ── Content header ──
   Couleur d'accent par contexte (variable lue par les éléments enfants) :
   - Mur (wall)   → vert  : "broadcast public"
   - DM           → orange : "privé chiffré"
   - Canal (#)    → violet : "groupe chiffré"
   Le header reçoit une bordure colorée + une bande haute, et la zone de
   messages prend une teinte de fond très subtile, pour que l'utilisateur
   sache toujours dans quel mode il écrit. */
#content-header {
  border-bottom: 1px solid var(--border);
  background: var(--bg2-glass);
  backdrop-filter: blur(1px); -webkit-backdrop-filter: blur(1px);
  flex-shrink: 0;
  position: relative;
  /* Au-dessus de #messages-area (sœur suivante, elle aussi avec
     backdrop-filter → contexte de stacking) : sinon le menu ⋯ qui déborde
     du header est peint SOUS les messages et leur blur le délave. */
  z-index: 20;
}
#content-header[data-context]::before {
  content: '';
  position: absolute; left: 0; right: 0; top: 0;
  height: 3px;
  background: var(--ctx-color, var(--accent));
  opacity: 0.85;
}
#content-header[data-context="wall"]    { --ctx-color: #3dd68c; }
#content-header[data-context="dm"]      { --ctx-color: #ffb340; }
#content-header[data-context="channel"] { --ctx-color: #7c6af7; }
#content-header[data-context="wall"]    .ch-context-icon { filter: drop-shadow(0 0 4px rgba(61,214,140,0.6)); }
#content-header[data-context="dm"]      .ch-context-icon { filter: drop-shadow(0 0 4px rgba(255,179,64,0.6)); }
#content-header[data-context="channel"] .ch-context-icon { filter: drop-shadow(0 0 4px rgba(124,106,247,0.6)); }
.ch-context-icon { font-size: 17px; line-height: 1; flex-shrink: 0; }
.ch-context-sub {
  font-size: 11px; color: var(--text2);
  font-weight: 500; letter-spacing: 0.01em;
  display: inline-flex; align-items: center; gap: 4px;
}
.ch-dm-line { display: flex; align-items: center; gap: 8px; }
.ch-channel-block { display: flex; flex-direction: column; gap: 1px; flex: 1; min-width: 0; }
.ch-channel-line { display: flex; align-items: center; gap: 6px; }

/* Teinte de fond très subtile sur la zone de messages selon le contexte. */
#messages-area[data-context="wall"]    { background: linear-gradient(180deg, rgba(61,214,140,0.025), transparent 80px); }
#messages-area[data-context="dm"]      { background: linear-gradient(180deg, rgba(255,179,64,0.030), transparent 80px); }
#messages-area[data-context="channel"] { background: linear-gradient(180deg, rgba(124,106,247,0.025), transparent 80px); }

/* Bandeau "▲ Nouveau" pour les canaux en mode feed (read-only).
   S'affiche au-dessus de #messages-area quand un nouveau message arrive
   et que l'user est descendu dans le feed. */
.feed-new-banner {
  position: absolute; top: 8px; left: 50%;
  transform: translateX(-50%);
  z-index: 5;
  background: var(--accent);
  color: #fff; font-weight: 600; font-size: 12px;
  border: none; border-radius: 16px;
  padding: 7px 14px; cursor: pointer;
  box-shadow: 0 6px 18px rgba(124,106,247,0.45);
  transition: transform 0.15s, box-shadow 0.15s;
  animation: feedBannerIn 0.25s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.feed-new-banner:hover { transform: translateX(-50%) translateY(-1px); box-shadow: 0 8px 22px rgba(124,106,247,0.55); }
@keyframes feedBannerIn {
  from { opacity: 0; transform: translateX(-50%) translateY(-12px); }
  to   { opacity: 1; transform: translateX(-50%) translateY(0); }
}
.ch-wall { padding: 12px 20px; display: flex; align-items: center; justify-content: space-between; }
.ch-title { font-weight: 700; font-size: 15px; display: flex; align-items: center; gap: 8px; letter-spacing: -0.2px; }
.ch-sub { font-size: 12px; color: var(--text2); font-weight: 400; }
.ch-channel { padding: 12px 20px; display: flex; align-items: center; gap: 10px; }
.ch-channel-name { font-weight: 700; flex: 1; font-size: 15px; letter-spacing: -0.2px; }
.ch-members { font-size: 12px; color: var(--text2); }
.btn-leave {
  background: none; border: 1px solid var(--border);
  color: var(--text2); padding: 5px 13px;
  border-radius: 8px; font-size: 12px; font-weight: 500;
  cursor: pointer; transition: all 0.15s;
}
.btn-leave:hover { border-color: var(--red); color: var(--red); background: rgba(255,85,114,0.07); }
.btn-del-chan {
  background: none; border: 1px solid rgba(255,85,114,0.3);
  color: var(--red); padding: 5px 13px;
  border-radius: 8px; font-size: 12px; font-weight: 500;
  cursor: pointer; transition: all 0.15s; margin-left: 6px;
}
.btn-del-chan:hover { background: var(--red); color: white; border-color: var(--red); }
.ch-dm { padding: 12px 20px; display: flex; align-items: center; gap: 10px; }
.ch-dm-info { display: flex; flex-direction: column; gap: 2px; }
.ch-dm-name { font-weight: 700; font-size: 15px; letter-spacing: -0.2px; }
.ch-dm-status {
  font-size: 12px;
  color: var(--muted);
  font-weight: 500;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  transition: color 200ms ease;
}
.ch-dm-status[data-online="true"] { color: var(--green); }
.ch-dm-status-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.ch-dm-status-icon svg { width: 18px; height: 18px; }
/* Anciennes règles dot+label conservées en compat (le span existe encore
   en hidden si un autre flow le réveille). Le dot historique est masqué
   par cette structure — on garde le label "Online" caché en mobile (CSS
   existant L3160). */
.ch-dm-status-dot { display: none; }
.dm-ctx-channel { font-size: 11px; color: var(--text2); background: var(--bg3); border-radius: 8px; padding: 1px 7px; display: inline-block; }

/* Bouton "Vérifier" : fusionne l'ex-badge ⚪/🟢/🟠/🔴 avec le bouton
   d'action. Plus de confusion avec un toggle on/off. data-state pilote
   l'apparence (couleur, animation pour mismatch).
   Couleurs adaptatives via --bg3 / --text2 → marche sur paper, dark, matrix. */
.btn-verify-dm {
  display: inline-flex; align-items: center; gap: 5px;
  background: var(--bg3);
  border: 1px solid var(--bg4, transparent);
  border-radius: 14px;
  padding: 5px 11px;
  cursor: pointer;
  font-size: 12px; font-weight: 600;
  color: var(--text);
  transition: background 0.15s ease, border-color 0.15s ease, transform 0.15s ease, box-shadow 0.15s ease;
  white-space: nowrap;
  line-height: 1;
}
.btn-verify-dm:hover { filter: brightness(1.08); transform: scale(1.03); }
.btn-verify-dm:active { transform: scale(0.98); }

/* Variante "bare" : juste l'icône, pas d'encadré. Override le bg/border
   pour rester un bouton cliquable mais visuellement nu. */
.btn-verify-dm-bare {
  background: transparent !important;
  border: none !important;
  padding: 4px !important;
  border-radius: 6px;
}
.btn-verify-dm-bare:hover {
  background: color-mix(in srgb, currentColor 10%, transparent) !important;
}
@supports not (color: color-mix(in srgb, red, blue)) {
  .btn-verify-dm-bare:hover { background: rgba(0,0,0,0.05) !important; }
}
/* Anim alerte mismatch : on garde un halo rouge sans encadré (box-shadow). */
.btn-verify-dm-bare[data-state="mismatch"] {
  background: transparent !important;
  color: #c53030 !important;
}
.btn-verify-dm-icon {
  font-size: 13px;
  line-height: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.btn-verify-dm-icon svg { width: 16px; height: 16px; }
/* Bouclier remplace le texte "Vérifier/Vérifié/..." : icon-only.
   Le label reste en aria-label/title pour l'accessibilité. */
.btn-verify-dm-label { display: none; }
.btn-verify-dm[data-state="unverified"] { color: var(--text2); }
.btn-verify-dm[data-state="verified"] {
  color: #1a5e2e; border-color: #5a8a3a; background: rgba(127,255,170,0.18);
}
.btn-verify-dm[data-state="legacy"] {
  color: #7a5500; border-color: #c89a4a; background: rgba(255,208,127,0.22);
}
.btn-verify-dm[data-state="mismatch"] {
  color: #fff; border-color: #c53030; background: #e53e3e;
  animation: dm-verify-alert 2.2s ease-in-out infinite;
}
@keyframes dm-verify-alert {
  0%, 100% { box-shadow: 0 0 0 0 rgba(229,62,62,0); }
  50% { box-shadow: 0 0 0 5px rgba(229,62,62,0.28); }
}

/* Dark theme : couleurs verified/legacy plus claires pour contraste */
[data-theme="default"] .btn-verify-dm[data-state="verified"],
[data-theme="matrix"] .btn-verify-dm[data-state="verified"] {
  color: #7fffaa; border-color: rgba(127,255,170,0.45); background: rgba(26,94,46,0.30);
}
[data-theme="default"] .btn-verify-dm[data-state="legacy"],
[data-theme="matrix"] .btn-verify-dm[data-state="legacy"] {
  color: #ffd07f; border-color: rgba(255,208,127,0.45); background: rgba(94,74,26,0.30);
}

/* ── Messages ── */
#messages-area {
  flex: 1; overflow-y: auto;
  overflow-x: hidden; /* anti-overflow horizontal sur mobile (bubble audio
                        large = scrollbar gênante + bubble qui dépasse) */
  padding: 20px;
  display: flex; flex-direction: column; gap: 8px;
  position: relative;
}
#messages-area::before {
  content: 'DoraCom';
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%) rotate(-18deg);
  font-family: 'Fraunces', Georgia, serif;
  font-size: 88px;
  font-weight: 500;
  letter-spacing: -1.5px;
  font-style: italic;
  color: var(--accent);
  opacity: 0.04;
  pointer-events: none;
  user-select: none;
  white-space: nowrap;
  z-index: 0;
}
/* En paper : le watermark est encore plus discret (palette claire = on
   voit déjà tout, pas besoin de surcharge). */
[data-theme="paper"] #messages-area::before { opacity: 0.025; }
#messages-area.drag-over::after,
#content.drag-over::after {
  content: '';
  position: absolute; inset: 8px;
  border: 2.5px dashed var(--accent);
  border-radius: 16px;
  background: rgba(124,106,247,0.07);
  pointer-events: none;
  z-index: 30;
}
#messages-area .drag-hint,
#content .drag-hint {
  position: absolute; inset: 0; z-index: 31;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: 10px; pointer-events: none;
}
#messages-area .drag-hint .dh-icon,
#content .drag-hint .dh-icon { font-size: 52px; }
#messages-area .drag-hint .dh-label,
#content .drag-hint .dh-label { font-size: 18px; font-weight: 700; color: var(--accent); }
#messages-area .drag-hint .dh-limit,
#content .drag-hint .dh-limit { font-size: 12px; color: var(--text2); background: var(--bg2); padding: 3px 12px; border-radius: 20px; }
.msgs-empty {
  flex: 1; display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  color: var(--text2);
  gap: 16px;
  padding: 32px 24px;
  text-align: center;
}
.msgs-empty-icon {
  font-size: 44px;
  line-height: 1;
  width: 96px;
  height: 96px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: radial-gradient(circle at 30% 30%,
    color-mix(in srgb, var(--accent) 18%, transparent),
    color-mix(in srgb, var(--accent) 6%, transparent) 65%,
    transparent 100%);
  box-shadow:
    0 0 0 1px color-mix(in srgb, var(--accent) 14%, transparent) inset,
    0 8px 24px -10px color-mix(in srgb, var(--accent) 25%, transparent);
  animation: msgs-empty-pulse 4s ease-in-out infinite;
}
.msgs-empty-text {
  font-size: 14px;
  font-weight: 500;
  color: var(--text2);
  max-width: 360px;
  line-height: 1.5;
}
@keyframes msgs-empty-pulse {
  0%, 100% { transform: scale(1); opacity: 0.95; }
  50%      { transform: scale(1.04); opacity: 1; }
}
/* Fallback browsers without color-mix : opacité directe.
   Le @supports test color-mix garde la version richer pour les browsers OK. */
@supports not (color: color-mix(in srgb, red, blue)) {
  .msgs-empty-icon {
    background: rgba(124, 106, 247, 0.10);
    box-shadow: 0 0 0 1px rgba(124, 106, 247, 0.18) inset;
  }
}

.msg-card {
  background: var(--bg2);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 12px 14px;
  position: relative;
  transition: all 0.15s;
  animation: fadeUp 0.2s ease;
}
.msg-card:hover { border-color: var(--border2); background: var(--bg3); }
.msg-card.mine {
  border-color: rgba(124,106,247,0.28);
  background: rgba(124,106,247,0.05);
}
.msg-card.mine:hover {
  border-color: rgba(124,106,247,0.42);
  background: rgba(124,106,247,0.09);
}
@keyframes fadeUp { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }

/* ── QuantumSafe reveal ─────────────────────────────────────────────────────
   Apparition « déchiffrement » des NOUVEAUX messages (live uniquement, jamais
   le render d'historique) : la bulle monte en fondu pendant que le texte se
   résout depuis des glyphes chiffrés vers le clair (JS ui._qsReveal). C'est
   le storytelling E2E du produit — on VOIT le déchiffrement se produire.
   Coupé proprement par prefers-reduced-motion (bulle simple, pas de scramble). */
/* ── Decrypt média (image + son) — design handoff « DoraCom Decrypt Demo »
   (claude.ai/design, chat2). Image : arrive floutée + voile vert chiffré qui
   se résout en net. Son : balayage vert « décodage » qui traverse la bulle.
   CSS pur (animation-fill-mode both → état final net garanti même onglet en
   arrière-plan), aucune chirurgie DOM, coupé par prefers-reduced-motion. */
/* Image : flou→net piloté en JS (setInterval + filet setTimeout, comme le
   moteur texte) — robuste au throttling d'onglet en arrière-plan, là où une
   animation CSS resterait gelée au 1er keyframe = image bloquée floutée.
   Cf. ui._qsRevealMedia. */
.qs-media-audio { position: relative; overflow: hidden; }
.qs-media-audio::after {
  content: ''; position: absolute; inset: 0; pointer-events: none; z-index: 2;
  background: linear-gradient(90deg, rgba(47,158,106,0) 0%, rgba(47,158,106,0.38) 50%, rgba(47,158,106,0) 100%);
  animation: qsAudioSweep 1.5s ease-out forwards;
}
@keyframes qsAudioSweep {
  0%   { transform: translateX(-110%); opacity: 1; }
  100% { transform: translateX(110%);  opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .qs-media-img { animation: none; }
  .qs-media-audio::after { animation: none; display: none; }
}

/* ── QuantumSafe reveal ─────────────────────────────────────────────────────
   Apparition « déchiffrement » des NOUVEAUX messages (live uniquement, jamais
   le render d'historique) : la bulle monte en fondu pendant que le texte se
   résout depuis des glyphes chiffrés vers le clair (JS ui._qsReveal). C'est
   le storytelling E2E du produit — on VOIT le déchiffrement se produire.
   Coupé proprement par prefers-reduced-motion (bulle simple, pas de scramble). */
.qs-reveal { animation: qsBubbleIn 0.3s cubic-bezier(0.16, 1, 0.3, 1) both; }
@keyframes qsBubbleIn {
  from { opacity: 0; transform: translateY(10px) scale(0.985); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .qs-reveal { animation: fadeUp 0.15s ease both; }
}

/* Glyphes chiffrés du reveal (design handoff « DoraCom Decrypt Demo ») :
   vert #2f9e6a + lueur, bord de résolution plus lumineux. Les spans sont
   générés par ui._qsReveal avec caractères échappés. */
.d-on { }
.d-sc { color: #2f9e6a; opacity: 0.92; text-shadow: 0 0 7px rgba(47, 158, 106, 0.6); }
.d-edge { text-shadow: 0 0 11px rgba(47, 158, 106, 0.95); }
.dm-row.sent .d-sc { filter: brightness(1.35); }

/* Pastille « 🔓 DECRYPTING » — inline après l'heure, verre dépoli pro :
   bordure fine translucide, voile flouté, remplissage vert voilé qui balaie
   derrière le label avec un bord lumineux (scanner). Retirée au onDone. */
.decrypt-pill {
  position: relative; display: inline-flex; align-items: center;
  overflow: hidden; justify-content: flex-start; vertical-align: middle;
  margin-left: 8px; padding: 4px 11px; min-width: 132px;
  border-radius: 10px; white-space: nowrap;
  font-size: 9.5px; font-weight: 800; letter-spacing: 0.13em;
  text-transform: uppercase; color: #143527; font-style: normal;
  background: linear-gradient(180deg, rgba(255,255,255,0.58), rgba(255,255,255,0.4));
  -webkit-backdrop-filter: blur(9px) saturate(150%); backdrop-filter: blur(9px) saturate(150%);
  border: 1px solid rgba(255,255,255,0.75);
  box-shadow: 0 6px 16px rgba(20,53,39,0.12), inset 0 1px 0 rgba(255,255,255,0.7);
}
.dp-fill {
  position: absolute; left: 0; top: 0; bottom: 0; width: 0; z-index: 0;
  background: linear-gradient(90deg, rgba(47,158,106,0.48), rgba(66,196,137,0.7));
  transition: width 0.12s linear;
}
.dp-fill::after {
  content: ''; position: absolute; right: 0; top: 0; bottom: 0; width: 2px;
  background: rgba(236,255,246,0.95); box-shadow: 0 0 10px rgba(120,240,190,0.9);
}
.dp-txt {
  position: relative; z-index: 1; white-space: nowrap;
  display: inline-flex; align-items: center; gap: 6px;
}

/* ── Chips d'états crypto ───────────────────────────────────────────────────
   Remplacent les ~10 placeholders texte bruts ('🔒 (clé sender en attente)',
   '✉️ envoi en cours…', …) par un rendu système unifié dans la bulle.
   Deux familles : TRANSITOIRE (pending/sending/desync — point lilas qui pulse,
   ça va se résoudre tout seul) vs PERMANENT (lost/missing/error — cadenas
   sobre, pas anxiogène). Libellés via i18n (crypto_*). */
.crypto-chip {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: 12.5px; font-style: italic; line-height: 1.4;
  color: var(--muted, #8a86a0); opacity: 0.9;
}
.crypto-chip::before {
  content: ''; flex: 0 0 auto; width: 7px; height: 7px; border-radius: 50%;
  background: currentColor; opacity: 0.4;
}
.crypto-chip--pending::before,
.crypto-chip--sending::before,
.crypto-chip--desync::before {
  background: var(--accent, #7c6af7); opacity: 1;
  animation: qsChipPulse 1.2s ease-in-out infinite;
}
@keyframes qsChipPulse {
  0%, 100% { opacity: 0.35; transform: scale(0.8); }
  50%      { opacity: 1;    transform: scale(1); }
}
/* « Défilement decrypting » : balayage lumineux continu sur le libellé
   pending (gradient clipé sur le texte qui défile, façon matrix discret) —
   l'état « Déchiffrement en cours… » se reconnaît au premier coup d'œil. */
.crypto-chip--pending {
  background: linear-gradient(90deg,
    currentColor 0%, currentColor 38%,
    var(--accent, #7c6af7) 50%,
    currentColor 62%, currentColor 100%);
  background-size: 250% 100%;
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
  animation: qsChipSweep 1.8s linear infinite;
}
@keyframes qsChipSweep {
  0%   { background-position: 125% 0; }
  100% { background-position: -125% 0; }
}
@media (prefers-reduced-motion: reduce) {
  .crypto-chip--pending::before,
  .crypto-chip--sending::before,
  .crypto-chip--desync::before { animation: none; }
  .crypto-chip--pending {
    animation: none; background: none;
    -webkit-text-fill-color: currentColor;
  }
}
[data-theme="paper"] .crypto-chip { color: var(--text2); }
[data-theme="paper"] .dm-row.sent .crypto-chip { color: var(--bg2); }

/* Bannière « messages protégés par clé renouvelée » : dépliable, explicative.
   Remplace le div gris inline-styled — clic = comprendre pourquoi + quoi faire. */
.sk-lost-details {
  margin: 6px auto 10px; max-width: 540px; text-align: center;
  font-size: 12.5px; color: var(--muted, #8a86a0);
}
.sk-lost-details summary {
  cursor: pointer; list-style: none; display: inline-flex; align-items: center;
  gap: 6px; padding: 4px 12px; border-radius: 999px; opacity: 0.8;
  background: rgba(124, 106, 247, 0.07); border: 1px solid rgba(124, 106, 247, 0.16);
  transition: opacity 0.15s;
}
.sk-lost-details summary::-webkit-details-marker { display: none; }
.sk-lost-details summary:hover, .sk-lost-details[open] summary { opacity: 1; }
.sk-lost-details .sk-lost-info {
  margin-top: 8px; padding: 10px 14px; border-radius: 10px; text-align: left;
  line-height: 1.55; background: rgba(124, 106, 247, 0.06);
  border: 1px solid rgba(124, 106, 247, 0.12);
}
[data-theme="paper"] .sk-lost-details { color: var(--text2); }
[data-theme="paper"] .sk-lost-details summary,
[data-theme="paper"] .sk-lost-details .sk-lost-info {
  background: var(--bg-bubble, #EDE5F2); border-color: var(--border, #d9cfc0);
}

.msg-header { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
.msg-author { font-weight: 600; font-size: 13px; }
/* Avatar + pseudo de l'auteur = cliquables → ouvrent un DM direct (1-to-1).
   Curseur pointeur + léger feedback au survol pour signaler l'action. */
.msg-card .avatar { cursor: pointer; transition: filter 0.12s ease, transform 0.12s ease; }
.msg-card .avatar:hover { filter: brightness(1.08); transform: scale(1.05); }
.msg-author { cursor: pointer; }
.msg-author:hover { text-decoration: underline; text-underline-offset: 2px; }
.msg-time { font-size: 11px; color: var(--muted); flex: 1; }
.msg-duration {
  font-size: 10px; font-weight: 700;
  color: var(--text2);
  background: rgba(255,255,255,0.08);
  padding: 1px 7px; border-radius: 8px;
  letter-spacing: 0.04em;
}
/* Legacy text expiry (kept for DMs) */
.msg-expiry {
  display: flex; align-items: center; gap: 3px;
  font-size: 11px; padding: 2px 9px;
  border-radius: 12px; font-weight: 600;
}
.msg-expiry.ok { color: var(--green); background: rgba(61,214,140,0.1); }
.msg-expiry.warn { color: var(--yellow); background: rgba(255,179,64,0.1); }
.msg-expiry.urgent { color: var(--red); background: rgba(255,85,114,0.1); animation: blink 1s ease infinite; }
@keyframes blink { 0%,100% { opacity: 1; } 50% { opacity: 0.5; } }

/* Expiry progress bar */
.msg-expiry-bar {
  height: 2px;
  background: rgba(255,255,255,0.04);
  border-radius: 0 0 10px 10px;
  overflow: hidden;
  margin-top: 8px;
  opacity: 0.55;
}
.msg-expiry-fill {
  height: 100%;
  border-radius: 0 0 10px 10px;
  transition: width 1s linear, background 1s;
}
.msg-expiry-fill.ok { background: var(--green); }
.msg-expiry-fill.warn { background: var(--yellow); }
.msg-expiry-fill.urgent { background: var(--red); animation: blink 1s ease infinite; }

.msg-actions { display: flex; gap: 3px; opacity: 0.35; transition: opacity 0.15s; }
.msg-card:hover .msg-actions { opacity: 1; }
/* Mobile / tactile : pas de hover → actions toujours visibles. On double la
   garde avec la largeur d'écran (certains appareils hybrides rapportent
   hover:hover) → sur mobile les actions (dont 📌 épingler) sont toujours
   atteignables sans hover. */
@media (hover: none) {
  .msg-actions { opacity: 1; }
}
@media (max-width: 700px) {
  .msg-actions { opacity: 1; }
}
/* DM : bouton ✕ inline dans la bulle (sender uniquement) */
.btn-dm-del {
  background: none; border: none; cursor: pointer;
  padding: 2px 6px; border-radius: 6px;
  font-size: 12px; color: var(--muted);
  opacity: 0.4; transition: all 0.15s;
  align-self: flex-start;
}
.btn-dm-del:hover { opacity: 1; color: var(--red); background: var(--hover); }
@media (hover: none) { .btn-dm-del { opacity: 1; } }
.msg-actions button {
  background: none; border: none; cursor: pointer;
  padding: 3px 8px; border-radius: 6px;
  font-size: 11px; color: var(--muted); font-weight: 500;
  transition: all 0.1s;
}
.msg-actions button:hover { background: var(--hover); color: var(--text); }
.msg-actions .btn-del:hover { color: var(--red); }
.msg-body { font-size: 14px; line-height: 1.65; word-break: break-word; }
.msg-img {
  /* min(px, 100%) : ne dépasse JAMAIS le conteneur/viewport (les images en
     max-width px FIXE débordaient hors écran sur mobile). height:auto garde
     le ratio quand la largeur est contrainte. */
  max-width: min(380px, 100%); max-height: 280px; height: auto;
  border-radius: 10px; object-fit: cover;
  cursor: pointer; display: block; margin-top: 10px;
  transition: opacity 0.15s;
  /* Ombre DOUCE (était rgba(0,0,0,0.3) = halo noir dur, vilain sur fond clair).
     Subtile, fondue dans le fond — surchargée par thème ci-dessous. */
  box-shadow: 0 2px 10px rgba(0,0,0,0.12);
}
.msg-img:hover { opacity: 0.88; }
.msg-file {
  display: flex; align-items: center; gap: 10px;
  background: var(--bg3); border: 1px solid var(--border);
  border-radius: 10px; padding: 10px 14px;
  margin-top: 8px; max-width: 300px;
  transition: border-color 0.15s;
}
.msg-file:hover { border-color: var(--border2); }
.msg-file-icon { font-size: 22px; }
.msg-file-info { flex: 1; min-width: 0; }
.msg-file-name { font-size: 12px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.msg-file-size { font-size: 11px; color: var(--muted); margin-top: 1px; }

/* Inline PDF viewer */
.msg-pdf-wrap {
  margin-top: 8px;
  border: 1px solid var(--border);
  border-radius: 10px; overflow: hidden;
  background: var(--bg3);
}
.msg-pdf-header {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 12px;
  border-bottom: 1px solid var(--border);
}
.msg-pdf-header .msg-file-name { flex: 1; font-size: 12px; font-weight: 600; }
.btn-pdf-toggle {
  background: none; border: none; cursor: pointer;
  color: var(--muted); font-size: 11px; font-weight: 600;
  padding: 2px 8px; border-radius: 6px;
  transition: all 0.15s;
}
.btn-pdf-toggle:hover { background: var(--hover); color: var(--text); }
.msg-pdf-frame {
  width: 100%; height: 480px;
  border: none; display: block;
  background: #fff;
}

/* DM bubbles */
.dm-row { display: flex; gap: 10px; align-items: flex-end; animation: fadeUp 0.15s ease; margin-bottom: 6px; padding: 0 8px; }
.dm-row.sent { flex-direction: row-reverse; }
/* Entrée système centrée (appel manqué éphémère 24h) */
.dm-row.dm-system { justify-content: center; align-items: center; }
.dm-missed-call {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 5px 13px; border-radius: 14px;
  background: var(--bg3); border: 1px solid var(--border2);
  color: var(--text); font-size: 13px; opacity: 0.92;
}
.dm-missed-call svg { width: 16px; height: 16px; color: #e0564d; flex: 0 0 auto; }
.dm-missed-call .dm-missed-call-time { color: var(--muted); font-variant-numeric: tabular-nums; }
[data-theme="big"] .dm-missed-call { font-size: 18px; padding: 8px 16px; border-color: var(--border); }
[data-theme="big"] .dm-missed-call svg { width: 22px; height: 22px; }
/* Carte système centrée dans un canal (appel de groupe manqué éphémère 24h) */
.msg-card.msg-system {
  display: flex; justify-content: center; align-items: center;
  background: none; border: none; box-shadow: none; padding: 6px 0; gap: 0;
}
.msg-card.msg-system::before, .msg-card.msg-system::after { content: none; }
.dm-content { max-width: 72%; min-width: 60px; display: flex; flex-direction: column; }
.dm-row.sent .dm-content { align-items: flex-end; }
.dm-row.received .dm-content { align-items: flex-start; }
.dm-bubble {
  background: var(--bg3);
  border: 1px solid var(--border2);
  border-radius: 18px; padding: 10px 16px;
  font-size: 14px; line-height: 1.55;
  word-break: break-word; white-space: pre-wrap;
}
.dm-row.sent .dm-bubble {
  background: var(--accent); color: white;
  border-color: var(--accent);
  border-radius: 18px 18px 4px 18px;
  box-shadow: 0 3px 12px var(--accent-glow);
}
.dm-row.received .dm-bubble { border-radius: 18px 18px 18px 4px; }

/* Bulle ne contenant QU'UN MÉDIA (image / vidéo / audio / lottie, SANS légende
   .msg-media-caption) : on retire le « chrome » de bulle (fond accent foncé,
   bordure, ombre, padding). Le média se suffit à lui-même → fini le gros cadre
   sombre (« bordure noire ») autour des images/vidéos envoyées (retour user
   2026-06-11). Convention WhatsApp/iMessage/Telegram. S'applique sent + reçu.
   Avec une légende, le fond est conservé (le texte a besoin du contraste). */
/* Spécificité .dm-row .dm-content .dm-bubble (0,5,0) pour battre la règle paper
   [data-theme="paper"] .dm-row.sent .dm-bubble { background:#2A1A14 !important }
   (0,4,0) — sinon le fond sombre reste malgré le !important. */
.dm-row .dm-content .dm-bubble:has(.dm-img):not(:has(.msg-media-caption)),
.dm-row .dm-content .dm-bubble:has(.msg-video-wrap):not(:has(.msg-media-caption)),
.dm-row .dm-content .dm-bubble:has(.msg-audio-wrap):not(:has(.msg-media-caption)),
.dm-row .dm-content .dm-bubble:has(.msg-lottie):not(:has(.msg-media-caption)) {
  background: transparent !important;
  border-color: transparent !important;
  box-shadow: none !important;
  padding: 0 !important;
}
.dm-ts { font-size: 10px; color: var(--muted); margin-top: 3px; padding: 0 4px; display: flex; gap: 6px; align-items: center; }
.dm-row.sent .dm-ts { text-align: right; justify-content: flex-end; }
.dm-status { font-size: 10px; color: var(--muted); }
.dm-status:has([title="Livré"]) { color: var(--accent); }
.dm-img { max-width: min(260px, 100%); max-height: 220px; height: auto; border-radius: 12px; object-fit: cover; cursor: pointer; display: block; margin-top: 4px; }

/* Transfer progress */
.transfer-wrap { margin-top: 8px; }
.transfer-bar-bg { height: 3px; background: var(--hover); border-radius: 3px; overflow: hidden; }
.transfer-bar { height: 100%; background: var(--accent); border-radius: 3px; transition: width 0.2s; }
.transfer-label { font-size: 10px; color: var(--muted); margin-top: 3px; }

/* ── Composer ── */
#composer {
  border-top: 1px solid var(--border);
  background: var(--bg2);
  padding: 8px 12px 10px;
  padding-bottom: max(10px, env(safe-area-inset-bottom));
  flex-shrink: 0;
}
.security-tagline {
  text-align: center;
  font-size: 10px;
  color: var(--text);
  opacity: 0.75;
  margin-top: 5px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  letter-spacing: 0.02em;
}
.composer-toolbar {
  display: flex; align-items: center; gap: 6px;
  margin-bottom: 8px;
}
.composer-toolbar-right { display: flex; align-items: center; gap: 2px; margin-left: auto; }
.expiry-label { font-size: 11px; color: var(--muted); margin-right: 10px; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; }
.expiry-selector { display: flex; align-items: center; gap: 4px; flex: 1; justify-content: center; position: relative; }
.expiry-btn {
  background: var(--bg3); border: 1px solid var(--border);
  color: var(--text2); padding: 4px 12px;
  border-radius: 14px; font-size: 11px; font-weight: 600;
  cursor: pointer; transition: all 0.15s;
}
.expiry-btn:hover { border-color: var(--accent); color: var(--accent); }
.expiry-btn.active {
  background: rgba(124,106,247,0.14);
  border-color: var(--accent); color: var(--accent);
}
/* ── Sélecteur d'expiration condensé (v420) : trigger + popover ── */
.expiry-trigger {
  background: var(--bg3); border: 1px solid var(--border);
  color: var(--text2); padding: 4px 12px;
  border-radius: 14px; font-size: 11px; font-weight: 600;
  cursor: pointer; transition: all 0.15s;
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 46px; min-height: 26px; line-height: 1;
}
.expiry-trigger:hover { border-color: var(--accent); color: var(--accent); }
.expiry-trigger.is-viewonce {
  color: var(--accent); border-color: var(--accent);
  background: rgba(124,106,247,0.14);
}
.expiry-trigger.is-viewonce svg { width: 16px; height: 16px; display: block; }
.expiry-popover {
  position: absolute; bottom: calc(100% + 6px); left: 50%; transform: translateX(-50%);
  display: flex; flex-direction: column; gap: 4px;
  padding: 6px; z-index: 1060; min-width: 130px;
  background: var(--bg2); border: 1px solid var(--border2);
  border-radius: 12px; box-shadow: 0 12px 40px rgba(0,0,0,0.45);
  animation: fadeIn 0.12s ease;
}
.expiry-popover.hidden { display: none; }
.expiry-popover .expiry-btn {
  width: 100%; display: inline-flex; align-items: center; justify-content: center;
  gap: 6px; white-space: nowrap;
}
.expiry-popover .expiry-btn.hidden { display: none; }
.expiry-popover .expiry-opt-label { font-size: 11px; }
.composer-main {
  display: flex; align-items: flex-end; gap: 8px;
  background: var(--bg3);
  border: 1.5px solid var(--border);
  border-radius: var(--radius-xl);
  /* Cursor text sur toute la zone : clique n'importe où dans le bandeau →
     ça ressemble visuellement à un input cliquable, et avec le handler JS
     on focusera le textarea (un seul clic au lieu de plusieurs). */
  cursor: text;
  padding: 8px 8px 8px 14px;
  transition: border-color 0.2s, box-shadow 0.2s;
}
.composer-main:focus-within {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-glow);
}
.btn-attach {
  background: none; border: none; color: var(--muted);
  cursor: pointer; padding: 6px; border-radius: 6px;
  transition: color 0.15s; flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px;
}
.btn-attach:hover { color: var(--accent); }
.btn-attach svg { width: 20px; height: 20px; display: block; }
/* Icône SVG dans btn-send (avion en papier) */
.btn-send svg { width: 18px; height: 18px; display: block; }
/* Push-to-talk : bouton Envoyer en mode MICRO (champ vide) + état enregistrement. */
.btn-send.mode-record { opacity: 0.92; }
.btn-send.recording {
  background: #e0564d !important; color: #fff !important;
  box-shadow: 0 0 0 4px rgba(224,86,77,0.25);
  animation: audio-pulse 1s ease-in-out infinite;
}
/* Chip « mémo audio prêt — appuie sur Envoyer ». */
.voice-pending-chip {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 10px; margin: 0 10px 6px; border-radius: 10px;
  background: var(--bg3); border: 1px solid var(--border);
  font-size: 12px; color: var(--text2);
}
.voice-pending-chip .vpc-ico { font-size: 14px; flex: 0 0 auto; }
.voice-pending-chip .vpc-label { flex: 1 1 auto; min-width: 0; }
.voice-pending-chip .vpc-cancel { background: none; border: none; color: var(--muted); cursor: pointer; font-size: 14px; line-height: 1; flex: 0 0 auto; }
.voice-pending-chip .vpc-cancel:hover { color: var(--red); }
/* Icône SVG dans le bouton visibilité (œil) — alignement inline avec le texte */
.btn-visibility-icon { width: 14px; height: 14px; vertical-align: -2px; margin-right: 2px; }
/* Mode View Once : icône œil inline dans expiry-selector */
.expiry-btn.expiry-viewonce svg { width: 16px; height: 16px; display: block; }
/* Drop overlay : icône grande */
.drop-icon svg { width: 64px; height: 64px; display: block; color: var(--accent); }
/* Tagline sécurité : icônes inline lock + shield */
.security-tagline .tagline-icon {
  width: 13px; height: 13px;
  display: inline-block;
  vertical-align: -2px;
  margin-right: 1px;
}
.mic-active { color: #e53e3e !important; animation: mic-pulse 1s ease-in-out infinite; }
@keyframes mic-pulse { 0%,100% { opacity:1; } 50% { opacity:.4; } }
#message-input {
  flex: 1; background: none; border: none;
  color: var(--text); font-size: 14px;
  outline: none; resize: none;
  font-family: inherit; line-height: 1.5;
  max-height: 120px; overflow-y: auto;
}
#message-input::placeholder { color: var(--muted); }
.btn-send {
  background: var(--accent); border: none; color: white;
  width: 34px; height: 34px; border-radius: 10px;
  cursor: pointer; display: flex; align-items: center; justify-content: center;
  flex-shrink: 0; transition: all 0.15s;
  box-shadow: 0 2px 10px var(--accent-glow);
}
.btn-send:hover:not(:disabled) {
  background: var(--accent2);
  transform: scale(1.06);
  box-shadow: 0 4px 14px var(--accent-glow);
}
.btn-send:disabled {
  background: var(--hover); color: var(--muted);
  cursor: not-allowed; box-shadow: none;
}

#file-preview {
  margin-top: 10px; padding: 10px 12px;
  background: var(--bg3); border: 1px solid var(--border);
  border-radius: 12px;
  display: flex; align-items: center; gap: 10px;
}
#file-preview img { max-height: 56px; max-width: 72px; border-radius: 6px; object-fit: cover; }
.fp-info { flex: 1; min-width: 0; }
.fp-name { font-size: 12px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fp-size { font-size: 11px; color: var(--muted); margin-top: 1px; }
.btn-rm-file { background: none; border: none; color: var(--muted); cursor: pointer; font-size: 17px; padding: 2px 4px; line-height: 1; transition: color 0.15s; }
.btn-rm-file:hover { color: var(--red); }

/* Multi-fichiers en file d'attente — liste compacte verticale */
#file-preview .fp-multi { width: 100%; display: flex; flex-direction: column; gap: 6px; }
#file-preview .fp-multi-header {
  font-size: 12px; font-weight: 600; color: var(--text2);
  padding-bottom: 6px; border-bottom: 1px solid var(--border);
}
#file-preview .fp-multi-list { display: flex; flex-direction: column; gap: 4px; max-height: 160px; overflow-y: auto; }
#file-preview .fp-item {
  display: flex; align-items: center; gap: 8px;
  padding: 5px 8px; border-radius: 8px;
  background: rgba(255,255,255,0.03);
  font-size: 12px;
}
#file-preview .fp-item-icon { font-size: 16px; flex-shrink: 0; }
#file-preview .fp-item-name { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#file-preview .fp-item-size { font-size: 11px; color: var(--muted); flex-shrink: 0; }
#file-preview .fp-item-rm {
  background: none; border: none; color: var(--muted);
  cursor: pointer; font-size: 14px; padding: 0 4px; line-height: 1;
  flex-shrink: 0; transition: color 0.15s;
}
#file-preview .fp-item-rm:hover { color: var(--red); }

/* ── Drag & Drop overlay (removed — drop zone is now #messages-area) ── */
#drop-overlay { display: none !important; }

#modal-overlay {
  position: fixed; inset: 0;
  background: rgba(0,0,0,0.78);
  display: flex; align-items: center; justify-content: center;
  z-index: 100;
  backdrop-filter: blur(10px);
}
.modal {
  background: var(--bg2);
  border: 1px solid var(--border2);
  border-radius: 20px;
  padding: 24px 26px;
  width: 400px; max-width: 92vw;
  /* Toujours scrollable si le contenu dépasse la fenêtre — sinon les modales
     riches (création de canal, settings) cachent le bas (boutons OK/Annuler)
     sur desktop comme sur mobile. */
  max-height: 92vh; overflow-y: auto; overscroll-behavior: contain;
  animation: modalIn 0.2s cubic-bezier(0.34, 1.56, 0.64, 1);
  box-shadow: 0 24px 64px rgba(0,0,0,0.55), 0 0 0 1px rgba(255,255,255,0.04);
}
/* Sticky bouton-bar en bas pour modales riches — toujours visible pendant
   le scroll. Le gradient évite que le contenu coupe sec sous la barre. */
.modal-actions {
  position: sticky;
  bottom: 0;
  background: linear-gradient(180deg, transparent, var(--bg2) 35%);
  padding-top: 16px;
  z-index: 1;
}
/* Petit polish scrollbar pour que ça reste discret */
.modal::-webkit-scrollbar { width: 8px; }
.modal::-webkit-scrollbar-thumb { background: var(--border2); border-radius: 4px; }
.modal::-webkit-scrollbar-thumb:hover { background: var(--muted); }
@keyframes modalIn { from { opacity: 0; transform: scale(0.9) translateY(-12px); } to { opacity: 1; transform: scale(1) translateY(0); } }
.modal-title { font-size: 18px; font-weight: 700; margin-bottom: 18px; letter-spacing: -0.3px; }
.modal-body { display: flex; flex-direction: column; gap: 14px; }
.form-group { display: flex; flex-direction: column; gap: 6px; }
.form-label { font-size: 11px; font-weight: 700; color: var(--text2); text-transform: uppercase; letter-spacing: 0.08em; }
.form-input {
  background: var(--bg3);
  border: 1.5px solid var(--border);
  border-radius: 10px; color: var(--text);
  padding: 10px 13px; font-size: 14px;
  outline: none; transition: all 0.15s;
  font-family: inherit;
}
.form-input:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-glow); }
.form-hint { font-size: 11px; color: var(--muted); }
.form-error { font-size: 12px; color: var(--red); font-weight: 500; }

/* Anti-régression : cache le bloc "Authentication required" / Your login /
   Your password de la modale Create channel. Même si une version cachée
   du JS (SW non encore réactivé) génère encore ce bloc, on le masque
   visuellement et on l'enlève du tab order. */
[name="creationLogin"],
[name="creationPassword"],
.form-group:has([name="creationLogin"]),
.form-group:has([name="creationPassword"]),
#creation-auth-error {
  display: none !important;
}
/* Le wrapper avec border violet contient l'icône clé + ces deux inputs.
   :has() permet de cibler exactement ce div sans risquer d'autres modales. */
div:has(> .form-group > [name="creationLogin"]),
div:has(> .form-group > [name="creationPassword"]) {
  display: none !important;
}
.modal-actions { display: flex; gap: 8px; justify-content: flex-end; margin-top: 18px; }
.modal-create-header {
  text-align: center; padding: 8px 0 20px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 20px; margin-top: -4px;
}
.modal-create-icon {
  font-size: 36px; margin-bottom: 8px;
  filter: drop-shadow(0 4px 10px rgba(124,106,247,0.4));
}
.modal-create-title {
  font-size: 20px; font-weight: 800; letter-spacing: -0.4px;
  background: linear-gradient(135deg, var(--text), var(--accent));
  -webkit-background-clip: text; -webkit-text-fill-color: transparent;
  background-clip: text;
}
.modal-create-subtitle { font-size: 12px; color: var(--muted); margin-top: 4px; }
.modal-actions.centered { justify-content: center; gap: 12px; }
.modal-actions.centered .btn-primary {
  padding: 11px 32px; font-size: 14px;
  background: linear-gradient(135deg, var(--accent), #a78bfa);
  box-shadow: 0 4px 18px var(--accent-glow);
}
.btn {
  padding: 9px 18px; border-radius: 10px;
  font-size: 13px; font-weight: 600;
  cursor: pointer; transition: all 0.15s;
  border: none; font-family: inherit;
  letter-spacing: 0.01em;
}
.btn-primary {
  background: var(--accent); color: white;
  box-shadow: 0 2px 10px var(--accent-glow);
}
.btn-primary:hover {
  background: var(--accent2);
  box-shadow: 0 4px 14px var(--accent-glow);
  transform: translateY(-1px);
}
.btn-secondary {
  background: var(--bg3); color: var(--text2);
  border: 1px solid var(--border2);
}
.btn-secondary:hover { border-color: var(--text2); color: var(--text); background: var(--hover); }
.btn-danger { background: var(--red); color: white; }
.btn-danger:hover { opacity: 0.85; transform: translateY(-1px); }

/* ── Toasts ── */
#toast-container {
  position: fixed; bottom: 20px; right: 20px;
  display: flex; flex-direction: column; gap: 8px;
  z-index: 999; pointer-events: none;
}
.toast {
  background: var(--bg2);
  border: 1px solid var(--border2);
  border-radius: 12px; padding: 12px 16px;
  font-size: 13px; font-weight: 500;
  display: flex; align-items: center; gap: 8px;
  max-width: 320px;
  animation: slideR 0.25s ease, fadeOut 0.3s ease 2.7s forwards;
  box-shadow: 0 8px 28px rgba(0,0,0,0.45), 0 0 0 1px rgba(255,255,255,0.04);
}
.toast.success { border-left: 3px solid var(--green); }
.toast.error { border-left: 3px solid var(--red); }
.toast.info { border-left: 3px solid var(--accent); }
@keyframes slideR { from { opacity: 0; transform: translateX(80px); } to { opacity: 1; transform: translateX(0); } }
@keyframes fadeOut { from { opacity: 1; } to { opacity: 0; } }

/* ── Lightbox ── */
#lightbox {
  position: fixed; inset: 0;
  background: rgba(0,0,0,0.95);
  display: flex; align-items: center; justify-content: center;
  z-index: 200; cursor: zoom-out;
  backdrop-filter: blur(12px);
}
#lightbox img {
  max-width: 92vw; max-height: 92vh;
  border-radius: 12px; object-fit: contain;
  box-shadow: 0 24px 60px rgba(0,0,0,0.6);
}

/* ── Visibility toggle ── */
.btn-visibility {
  background: none; border: 1px solid var(--border);
  color: var(--text2); cursor: pointer;
  font-size: 11px; font-weight: 500; padding: 3px 10px;
  border-radius: 12px; margin-top: 3px;
  transition: all 0.15s;
}
.btn-visibility:hover { border-color: var(--accent); color: var(--accent); background: rgba(124,106,247,0.08); }
.btn-visibility.visibility-off { border-color: var(--muted); color: var(--muted); opacity: 0.65; }

.btn-push-toggle {
  background: none; border: 1px solid var(--border);
  color: var(--text2); cursor: pointer;
  font-size: 13px; padding: 2px 6px;
  border-radius: 10px; flex-shrink: 0;
  line-height: 1; transition: all 0.15s;
}
.btn-push-toggle:hover { border-color: var(--accent); background: rgba(124,106,247,0.08); }
.btn-push-toggle.push-active { border-color: var(--accent); color: var(--accent); }
.btn-push-toggle.push-tor-disabled {
  border-color: #5a3d8a;
  color: #b298ff;
  background: rgba(90,61,138,0.08);
  cursor: not-allowed;
  opacity: 0.85;
}
.btn-push-toggle.push-tor-disabled:hover { background: rgba(90,61,138,0.08); }

/* Install PWA — bouton pleine largeur dans le footer sidebar, juste au-dessus
   du theme switcher. Mis en avant pour pousser l'install (mode app natif). */
.btn-install-pwa {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  width: calc(100% - 24px); margin: 8px 12px 4px 12px;
  padding: 10px 14px; border-radius: 10px;
  background: linear-gradient(180deg, rgba(61,214,140,0.14), rgba(61,214,140,0.06));
  border: 1px solid rgba(61,214,140,0.35);
  color: #3dd68c; cursor: pointer;
  font-size: 14px; font-weight: 600; line-height: 1;
  transition: all 0.15s;
}
.btn-install-pwa:hover {
  background: linear-gradient(180deg, rgba(61,214,140,0.22), rgba(61,214,140,0.10));
  border-color: rgba(61,214,140,0.6);
  transform: translateY(-1px);
  box-shadow: 0 4px 14px rgba(61,214,140,0.15);
}
.btn-install-pwa:active { transform: translateY(0); }
.btn-install-icon { font-size: 18px; line-height: 1; }
.btn-install-label { white-space: nowrap; }

/* Modal d'instructions PWA pour iOS Safari (pas d'API d'install programmatique). */
#pwa-install-overlay {
  position: fixed; inset: 0; z-index: 2147483646;
  background: rgba(8,10,14,.92); backdrop-filter: blur(6px);
  display: flex; align-items: center; justify-content: center;
  padding: 20px; font-family: 'Inter', system-ui, sans-serif;
}
#pwa-install-overlay .pwa-card {
  position: relative; max-width: 420px; width: 100%;
  padding: 28px 26px; border-radius: 14px;
  background: linear-gradient(180deg, #14181f, #0e1115);
  border: 1px solid rgba(255,255,255,.07);
  box-shadow: 0 30px 80px rgba(0,0,0,.55);
  color: #e9eef5;
}
#pwa-install-overlay .pwa-close {
  position: absolute; top: 10px; right: 10px;
  background: none; border: none; color: #a9b3c2; cursor: pointer;
  font-size: 18px; line-height: 1; padding: 6px;
}
#pwa-install-overlay .pwa-close:hover { color: #fff; }
#pwa-install-overlay .pwa-icon { font-size: 36px; margin-bottom: 8px; text-align: center; }
#pwa-install-overlay .pwa-title {
  font-size: 18px; font-weight: 700; text-align: center; margin-bottom: 18px;
}
#pwa-install-overlay .pwa-steps {
  padding-left: 22px; margin: 0 0 16px 0;
  font-size: 14px; line-height: 1.6; color: #d5dbe5;
}
#pwa-install-overlay .pwa-steps li + li { margin-top: 6px; }
#pwa-install-overlay .pwa-share {
  display: inline-block; font-size: 16px; vertical-align: -1px;
}
#pwa-install-overlay .pwa-hint {
  font-size: 12px; color: #8b94a3; line-height: 1.5;
  border-top: 1px solid rgba(255,255,255,.07); padding-top: 12px;
}

/* ── Media in messages ── */
.msg-video {
  max-width: 400px; width: 100%;
  border-radius: 10px; display: block; margin-top: 8px;
  background: #000;
  box-shadow: 0 2px 10px rgba(0,0,0,0.12);
}
.msg-video-wrap {
  position: relative; display: inline-block;
  max-width: 400px; width: 100%; margin-top: 8px;
}
.msg-video-wrap .msg-video { margin-top: 0; }

/* Boutons overlay (en haut-droite) : plein écran + ouvrir dans onglet.
   Visibles au hover pour ne pas surcharger l'image. */
.msg-video-expand,
.msg-video-open {
  position: absolute; top: 8px;
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px;
  border-radius: 8px;
  background: rgba(0,0,0,0.55);
  color: #fff; border: none; cursor: pointer;
  font-size: 15px; line-height: 1;
  text-decoration: none;
  opacity: 0; transition: opacity 0.15s, background 0.15s, transform 0.1s;
  backdrop-filter: blur(4px);
}
.msg-video-expand { right: 8px; }
.msg-video-open   { right: 44px; }
.msg-video-wrap:hover .msg-video-expand,
.msg-video-wrap:hover .msg-video-open,
.msg-video-wrap:focus-within .msg-video-expand,
.msg-video-wrap:focus-within .msg-video-open { opacity: 1; }
.msg-video-expand:hover,
.msg-video-open:hover { background: rgba(0,0,0,0.78); transform: scale(1.05); }

/* Touch devices : pas de hover → toujours visibles */
@media (hover: none) {
  .msg-video-expand,
  .msg-video-open { opacity: 0.85; }
}

/* ── TikTok-style Video Viewer ── */
#video-viewer {
  position: fixed; inset: 0; z-index: 2000;
  background: #000;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  touch-action: none; user-select: none;
}
#video-viewer.hidden { display: none; }
#video-viewer-player {
  max-width: 100%; max-height: 100dvh;
  width: 100%; object-fit: contain;
  outline: none;
}
#video-viewer-close {
  position: absolute; top: 16px; right: 16px;
  background: rgba(0,0,0,0.55); color: #fff;
  border: none; font-size: 18px; cursor: pointer;
  z-index: 2001; padding: 6px 11px; border-radius: 50%;
  line-height: 1;
}
#video-viewer-counter {
  position: absolute; top: 16px; left: 50%; transform: translateX(-50%);
  color: #fff; font-size: 13px; font-weight: 600;
  background: rgba(0,0,0,0.5); padding: 4px 14px; border-radius: 20px;
  pointer-events: none;
}
.video-nav-hint {
  position: absolute; left: 50%; transform: translateX(-50%);
  color: rgba(255,255,255,0.55); font-size: 22px;
  pointer-events: none; transition: opacity 0.2s;
}
.video-nav-hint.up { top: 52px; }
.video-nav-hint.down { bottom: 14px; }
.video-nav-hint.disabled { opacity: 0.15; }
/* swipe animation */
@keyframes swipeUp { from { transform: translateY(0); opacity:1 } to { transform: translateY(-60px); opacity:0 } }
@keyframes swipeDown { from { transform: translateY(0); opacity:1 } to { transform: translateY(60px); opacity:0 } }
.video-viewer-anim-up { animation: swipeUp 0.25s ease forwards; }
.video-viewer-anim-down { animation: swipeDown 0.25s ease forwards; }

/* <audio controls> natif : le browser contrôle son propre rendering
   (Chrome auto dark/light mode). On NE force PAS de background — sinon
   on empile une couche light sur la couche browser dark = bizarre. */
.msg-audio {
  width: 100%;
  max-width: 100%;
  min-height: 32px;
  display: block;
  accent-color: var(--accent);
  box-sizing: border-box;
}

/* ── CSV table ── */
.msg-csv-wrap { margin-top: 8px; }
.msg-csv-label { font-size: 12px; color: var(--text2); margin-bottom: 6px; display: flex; align-items: center; gap: 8px; font-weight: 500; }
.btn-dl-inline { color: var(--accent); text-decoration: none; font-size: 12px; font-weight: 600; }
.btn-dl-inline:hover { text-decoration: underline; }
.msg-csv-scroll { overflow-x: auto; max-height: 220px; border-radius: 8px; border: 1px solid var(--border); }
.msg-csv-table { border-collapse: collapse; font-size: 12px; min-width: 100%; }
.msg-csv-table th {
  background: var(--bg3); padding: 7px 12px;
  text-align: left; font-weight: 700;
  color: var(--text2); border-bottom: 1px solid var(--border);
  white-space: nowrap; position: sticky; top: 0;
}
.msg-csv-table td { padding: 6px 12px; border-bottom: 1px solid var(--border); color: var(--text); white-space: nowrap; }
.msg-csv-table tr:last-child td { border-bottom: none; }
.msg-csv-table tr:hover td { background: rgba(255,255,255,0.025); }

/* ── TXT preview ── */
.msg-txt-wrap { margin-top: 8px; }
.msg-txt {
  background: var(--bg3); border: 1px solid var(--border);
  border-radius: 8px; padding: 12px;
  font-size: 12px; line-height: 1.6; color: var(--text2);
  overflow-x: auto; max-height: 200px; overflow-y: auto;
  white-space: pre-wrap; word-break: break-word;
  font-family: 'JetBrains Mono', 'Fira Code', 'Courier New', monospace;
}

/* ── PDF / file download ── */
.btn-dl {
  color: var(--accent); text-decoration: none;
  font-size: 12px; font-weight: 600;
  padding: 4px 10px;
  border: 1px solid rgba(124,106,247,0.4);
  border-radius: 7px; white-space: nowrap;
  transition: all 0.15s;
}
.btn-dl:hover { background: var(--accent); color: white; border-color: var(--accent); }

/* ── Channel header extras ── */
.badge-readonly {
  font-size: 11px; font-weight: 600;
  background: rgba(255,179,64,0.12); color: var(--yellow);
  padding: 3px 10px; border-radius: 12px;
  display: inline-flex; align-items: center; gap: 4px;
}
.badge-readonly-icon { width: 13px; height: 13px; display: block; }
.members-chip-icon { width: 14px; height: 14px; display: inline-block; flex-shrink: 0; }
.ch-max { font-size: 12px; color: var(--muted); }
.btn-settings {
  background: none; border: 1px solid var(--border);
  color: var(--text2); padding: 5px 10px;
  border-radius: 8px; font-size: 14px;
  cursor: pointer; transition: all 0.15s;
}
.btn-settings:hover { border-color: var(--accent); color: var(--accent); background: rgba(124,106,247,0.08); }

/* ── Channel header with inline members ── */
.ch-channel { padding: 10px 20px 0; display: flex; flex-direction: column; gap: 0; }
.ch-channel-top { display: flex; align-items: center; gap: 8px; padding-bottom: 8px; flex-wrap: wrap; }
.ch-channel-name { font-weight: 700; font-size: 15px; letter-spacing: -0.2px; }
.ch-member-count { font-size: 12px; color: var(--muted); margin-right: auto; }
.ch-actions { display: flex; align-items: center; gap: 6px; }

/* ── Sidebar channel item — actions + members ── */
.channel-item-actions {
  display: flex; gap: 4px; align-items: center;
  margin-left: auto; flex-shrink: 0;
  padding: 0;
}
.ch-action-btn {
  background: var(--bg3); border: 1px solid var(--border);
  color: var(--text2); font-size: 13px; border-radius: 7px;
  width: 28px; height: 28px;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer; transition: all 0.12s; flex-shrink: 0;
  padding: 0;
}
.ch-action-btn:hover { background: var(--hover); border-color: var(--border2); color: var(--text); }
.ch-action-btn.leave { border-color: rgba(255,85,114,0.3); color: var(--red); }
.ch-action-btn.leave:hover { background: rgba(255,85,114,0.12); border-color: var(--red); }
.ch-action-btn.delete { border-color: rgba(255,85,114,0.3); color: var(--red); }
.ch-action-btn.delete:hover { background: rgba(255,85,114,0.12); border-color: var(--red); }
.ch-action-btn.disabled { opacity: 0.45; cursor: not-allowed; }
.ch-action-share svg { width: 14px; height: 14px; }
.ch-action-share:hover { color: var(--accent); border-color: var(--accent); }
/* ⚙ avec messages signalés détectés (audit flag cache) : pastille rouge en
   coin — l'audit a quitté la sidebar mais le signal de sécurité reste visible. */
.ch-action-flagged { position: relative; border-color: rgba(224,108,108,0.5); }
.ch-action-flagged::after {
  content: ''; position: absolute; top: -3px; right: -3px;
  width: 8px; height: 8px; border-radius: 50%;
  background: #e06c6c; box-shadow: 0 0 0 2px var(--bg2, #fff);
}

.channel-item-members {
  display: flex; flex-direction: column; gap: 1px;
  padding: 4px 8px 8px;
  border-top: 1px solid rgba(124,106,247,0.12);
  margin: 0 4px;
}
.ch-sidebar-member {
  display: flex; align-items: center; gap: 7px;
  padding: 4px 6px; border-radius: 6px;
  cursor: pointer; font-size: 12px; color: var(--text2);
  transition: all 0.1s;
}
.ch-sidebar-member:hover { background: rgba(124,106,247,0.1); color: var(--accent); }
/* Membre avec qui je suis EN APPEL 1-to-1 : highlight vert « live » persistant. */
.ch-sidebar-member.member-in-call {
  background: linear-gradient(135deg, rgba(61,214,140,0.18), rgba(61,214,140,0.06));
  box-shadow: inset 0 0 0 1px rgba(61,214,140,0.5);
  color: var(--green, #3dd68c);
}
.ch-sidebar-member.member-in-call:hover { background: linear-gradient(135deg, rgba(61,214,140,0.28), rgba(61,214,140,0.1)); }
.ch-sidebar-member.member-in-call::after {
  content: '📞'; margin-left: auto; font-size: 11px; flex: 0 0 auto;
  animation: channel-call-pulse 1.6s ease-in-out infinite;
}
/* Pastille de présence sur le coin de l'avatar (vert=en ligne, gris=hors-ligne). */
.ch-member-av-wrap { position: relative; display: inline-flex; flex: 0 0 auto; }
.member-presence-dot {
  position: absolute; right: -2px; bottom: -2px;
  width: 9px; height: 9px; border-radius: 50%;
  border: 2px solid var(--bg2); box-sizing: border-box;
}
.member-presence-dot.online { background: #38c172; box-shadow: 0 0 4px rgba(56,193,114,0.6); }
.member-presence-dot.offline { background: #e0564d; }
/* Badge « appel en absence » sur un membre (sidebar) — 📞 rouge pulsé. */
.ch-member-missed-call {
  flex: 0 0 auto; font-size: 12px; line-height: 1; margin-left: 2px;
  filter: drop-shadow(0 0 3px rgba(224,86,77,0.9));
  animation: channel-call-pulse 1.6s ease-in-out infinite;
}
/* Onglet DM avec appel manqué : liseré rouge + pastille 📞. */
.tab.tab-missed-call { box-shadow: inset 0 0 0 1px rgba(224,86,77,0.6); }
.tab-missed-dot { font-size: 11px; line-height: 1; flex: 0 0 auto; filter: drop-shadow(0 0 3px rgba(224,86,77,0.8)); }
.ch-sidebar-member.me { cursor: default; color: var(--text); font-weight: 500; }
.ch-sidebar-member.me:hover { background: transparent; color: var(--text); }
.ch-sidebar-member-name { flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ch-sidebar-me { color: var(--muted); font-weight: 400; font-size: 10px; }

/* ── Simplified channel header ── */
.ch-channel-simple {
  display: flex; align-items: center; gap: 8px;
  padding: 12px 20px;
  flex-wrap: nowrap; /* tout sur 1 ligne, jamais de wrap (sinon meta cluster
                        passe à la ligne et le header devient verbeux) */
}
.ch-channel-simple .ch-channel-name { font-weight: 700; font-size: 15px; letter-spacing: -0.2px; }
.ch-channel-meta {
  display: inline-flex; align-items: center; gap: 8px;
  flex-shrink: 0; flex-wrap: nowrap;
}
.ch-channel-meta .members-chip {
  display: inline-flex; align-items: center; gap: 4px;
  white-space: nowrap;
  color: var(--text2);
  font: 600 12px/1 'Geist', 'Manrope', system-ui, sans-serif;
}
.ch-member-chip {
  display: flex; align-items: center; gap: 5px;
  background: var(--bg3); border: 1px solid var(--border);
  border-radius: 20px; padding: 3px 10px 3px 3px;
  font-size: 12px; transition: border-color 0.12s;
  cursor: default;
}
.ch-member-chip:hover { border-color: var(--border2); }
.ch-member-chip.me { border-color: rgba(124,106,247,0.35); background: rgba(124,106,247,0.08); }
.ch-chip-name { color: var(--text2); white-space: nowrap; }
.ch-member-chip.me .ch-chip-name { color: var(--text); font-weight: 600; }
.ch-chip-me { color: var(--muted); font-weight: 400; font-size: 11px; }
.ch-chip-dot { width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0; }
.ch-chip-dot.owner { background: var(--accent); box-shadow: 0 0 4px var(--accent-glow); }
.ch-chip-dot.admin { background: #a78bfa; }
.ch-member-crown {
  font-size: 11px; margin-left: 4px;
  color: #f5c518;
  filter: drop-shadow(0 1px 3px rgba(245,197,24,0.5));
  flex-shrink: 0;
}

/* Pill rôle dans la sidebar membres — visible et lisible. */
.ch-role-pill {
  font-size: 9.5px; font-weight: 700; letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 2px 7px; border-radius: 10px;
  flex-shrink: 0; white-space: nowrap;
  display: inline-flex; align-items: center; gap: 3px;
}
.ch-role-pill.owner {
  background: transparent;
  box-shadow: none;
  padding: 0;
  font-size: 14px;
  line-height: 1;
  filter: drop-shadow(0 1px 2px rgba(245,197,24,0.55));
}
.ch-role-pill.admin {
  background: rgba(167,139,250,0.18);
  color: #c4b5fd;
  border: 1px solid rgba(167,139,250,0.4);
}

/* Ligne membre owner mise en évidence — fond légèrement doré + bordure
   accent à gauche pour repérage rapide. */
.ch-sidebar-member.is-owner {
  background: linear-gradient(90deg, rgba(245,197,24,0.10), rgba(245,197,24,0.02));
  border-left: 2px solid #f5c518;
  padding-left: 8px;
}
.ch-sidebar-member.is-owner:hover {
  background: linear-gradient(90deg, rgba(245,197,24,0.18), rgba(245,197,24,0.05));
}
.ch-sidebar-member.is-admin {
  border-left: 2px solid rgba(167,139,250,0.6);
  padding-left: 8px;
}

/* ── Members panel — hidden, kept for DOM ── */
#members-panel { display: none !important; }

/* ── Channel settings modal ── */
.settings-section { background: var(--bg3); border-radius: 10px; padding: 14px 16px; border: 1px solid var(--border); }
.settings-title { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: var(--muted); margin-bottom: 10px; }

/* ── Channel settings modal v2 — layout compact 5 sections ─────────────
   Hiérarchie : titre 13px accent au lieu de 11px uppercase muted.
   Density : rows resserrées, descriptions secondaires en text-xs muted.
   Save global pour les toggles "Comportement" (un seul bouton).         */
.ch-settings { display: flex; flex-direction: column; gap: 12px; }
.ch-settings-section {
  background: var(--bg3);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 12px 14px;
}
.ch-settings-title {
  font-size: 13px;
  font-weight: 700;
  color: var(--accent);
  margin-bottom: 10px;
  letter-spacing: 0.01em;
  display: flex;
  align-items: center;
  gap: 6px;
}
.ch-settings-row {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 6px 0;
  cursor: pointer;
  border-radius: 6px;
  transition: background 120ms;
}
.ch-settings-row:hover { background: var(--bg4, rgba(0,0,0,0.03)); }
.ch-settings-row + .ch-settings-row { border-top: 1px dashed var(--border); }
.ch-settings-row input[type="checkbox"] { margin-top: 3px; flex-shrink: 0; }
.ch-settings-label { flex: 1; min-width: 0; }
.ch-settings-label-main {
  font-size: 13px;
  font-weight: 500;
  color: var(--text);
  line-height: 1.3;
}
.ch-settings-label-desc {
  font-size: 11px;
  color: var(--muted);
  margin-top: 2px;
  line-height: 1.35;
}
.ch-settings-row-input {
  align-items: center;
  cursor: default;
}
.ch-settings-row-input:hover { background: transparent; }
.ch-settings-input-sm {
  max-width: 100px;
  font-size: 13px;
}
.ch-settings-save {
  margin-top: 10px;
  width: 100%;
  justify-content: center;
}
.ch-settings-pwd-group { margin-bottom: 12px; }
.ch-settings-pwd-group:last-of-type { margin-bottom: 8px; }
.ch-settings-state {
  font-size: 11px;
  font-weight: 400;
  color: var(--text3);
  margin-left: 4px;
}
.ch-settings-inline-row {
  display: flex;
  gap: 6px;
  margin-top: 4px;
}
.ch-settings-hint {
  font-size: 11px;
  color: var(--muted);
  margin-top: 6px;
  line-height: 1.4;
}
.ch-settings-hint-italic { font-style: italic; color: var(--text3); }
.ch-settings-divider {
  height: 1px;
  background: var(--border);
  margin: 12px 0;
}
.ch-settings-cred-list { display: flex; flex-direction: column; gap: 6px; margin: 6px 0; }
.ch-settings-cred-form {
  display: flex;
  flex-direction: column;
  gap: 6px;
  background: var(--bg2);
  border-radius: 8px;
  padding: 10px;
  margin-top: 8px;
}
.ch-settings-cred-form-title {
  font-size: 12px;
  font-weight: 600;
  color: var(--text2);
}
.ch-settings-action-btn {
  width: 100%;
  justify-content: center;
  margin-top: 4px;
}
.ch-settings-action-btn + .ch-settings-hint + .ch-settings-action-btn { margin-top: 10px; }
.btn-sm { font-size: 12px; padding: 4px 12px; }
.members-list { display: flex; flex-direction: column; gap: 6px; max-height: 320px; overflow-y: auto; }
/* Member row : flex-wrap pour que les boutons d'action (rename/hide/kick)
   passent à la ligne quand la modale est étroite — évite la troncature de
   "Kick" qu'on avait avant (overflow horizontal). */
.member-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 8px;
  padding: 8px 10px;
  border-radius: 8px;
  background: var(--bg4, color-mix(in srgb, var(--accent) 4%, transparent));
  border: 1px solid var(--border);
  transition: border-color 0.15s;
}
@supports not (color: color-mix(in srgb, red, blue)) {
  .member-row { background: rgba(124,106,247,0.04); }
}
.member-row:hover { border-color: var(--border2); }
/* Le nom prend tout l'espace dispo, pousse les actions à droite. */
.member-row .member-name { flex: 1 1 80px; }
/* Les boutons d'action restent groupés à droite — premier bouton avec
   margin-left:auto pour pousser, les suivants collés. */
.member-row .btn-rename { margin-left: auto; }
.member-name {
  font-size: 13px; font-weight: 500;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  min-width: 0; flex: 1 1 80px;
}
.role-badge {
  font-size: 10px; padding: 2px 8px; border-radius: 8px;
  font-weight: 700; white-space: nowrap; letter-spacing: 0.04em;
}
.role-badge.owner { background: transparent; padding: 0; font-size: 14px; filter: drop-shadow(0 1px 2px rgba(245,197,24,0.55)); }
.role-badge.admin { background: rgba(167,139,250,0.15); color: #a78bfa; }
.role-badge.member {
  background: color-mix(in srgb, var(--accent) 8%, transparent);
  color: var(--text2);
}
.vis-badge {
  font-size: 13px;
  opacity: 0.85;
}
.vis-badge.muted {
  color: #e0a766;
  filter: drop-shadow(0 1px 2px rgba(224, 167, 102, 0.35));
}
.btn-toggle-mute {
  padding: 2px 8px;
  border-radius: 6px;
  border: 1px solid var(--border, #2a3142);
  background: transparent;
  color: var(--text2);
  font-size: 11px;
  font-weight: 600;
  cursor: pointer;
}
.btn-toggle-mute:hover {
  background: rgba(224, 167, 102, 0.10);
  border-color: #e0a766;
  color: #e0a766;
}
/* Bouton actions membre : style soft outlined paper, taille compact 11px,
   plus de "Renommer" dark gray par défaut du browser. Cohérent avec .btn-kick. */
.btn-rename,
.btn-toggle-vis {
  background: transparent;
  border: 1px solid var(--border2, var(--border));
  color: var(--text2);
  font-family: inherit;
  font-size: 11px;
  font-weight: 600;
  padding: 3px 10px;
  border-radius: 7px;
  cursor: pointer;
  transition: all 0.15s;
  white-space: nowrap;
}
.btn-rename:hover {
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  border-color: color-mix(in srgb, var(--accent) 35%, var(--border));
  color: var(--accent);
}
.btn-toggle-vis:hover {
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  border-color: color-mix(in srgb, var(--accent) 35%, var(--border));
  color: var(--accent);
}
@supports not (color: color-mix(in srgb, red, blue)) {
  .btn-rename:hover, .btn-toggle-vis:hover {
    background: rgba(124,106,247,0.10);
    border-color: rgba(124,106,247,0.3);
    color: var(--accent);
  }
}
.btn-kick {
  background: transparent;
  border: 1px solid rgba(255,85,114,0.3);
  color: var(--red);
  font-family: inherit;
  font-size: 11px; font-weight: 600;
  padding: 3px 10px; border-radius: 7px;
  cursor: pointer; transition: all 0.15s; white-space: nowrap;
}
.btn-kick:hover { background: var(--red); color: white; border-color: var(--red); }

/* ── Members panel ── */
#members-panel {
  width: 220px; min-width: 220px;
  background: var(--bg2);
  border-left: 1px solid var(--border);
  display: flex; flex-direction: column; gap: 12px;
  padding: 16px; overflow-y: auto;
}
.mp-title { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.12em; color: var(--muted); }

/* ── TradingView Widget ── */
.tv-widget-wrap {
  width: 100%; height: 500px;
  margin-top: 10px; border-radius: var(--radius);
  overflow: hidden; border: 1px solid var(--border);
}
.tv-widget-wrap iframe { width: 100%; height: 100%; border: none; display: block; }

/* ── Link preview ── */
.msg-link { color: var(--accent); text-decoration: none; word-break: break-all; }
.msg-link:hover { text-decoration: underline; }

/* Mentions @user dans les messages. .mention-self est appliqué quand le
   pseudo mentionné = mon pseudo → couleur accent + bordure soulignée pour
   attirer l'œil. Cohérent avec les conventions Discord/Slack. */
.mention {
  display: inline-block;
  padding: 0 4px;
  border-radius: 3px;
  background: rgba(124, 58, 237, 0.12);
  color: var(--accent, #7c3aed);
  font-weight: 500;
  text-decoration: none;
}
.mention-self {
  background: var(--accent, #7c3aed);
  color: #fff;
  font-weight: 600;
}

/* ═══════════════════════════════════════════════════════════════════════════
   Reply/quote — Discord/Slack style
   - .msg-reply-parent : bubble compacte affichée AU-DESSUS du contenu du
     message qui est une réponse. Barre verticale accent + auteur + preview.
   - .composer-reply-banner : bandeau au-dessus du composer quand on prépare
     une réponse, avec bouton ✕ pour annuler.
   - .btn-reply / .btn-dm-reply : icône ↩ dans les actions du message
   - .msg-highlight-pulse : flash quand on scroll au msg parent
   ═══════════════════════════════════════════════════════════════════════════ */

.msg-reply-parent {
  display: flex;
  align-items: stretch;
  gap: 8px;
  margin: 4px 0 6px;
  padding: 6px 10px 6px 0;
  border-radius: 6px;
  background: rgba(0, 0, 0, 0.04);
  cursor: pointer;
  transition: background 120ms ease;
  font-size: 12px;
  line-height: 1.4;
  max-width: 100%;
  overflow: hidden;
}
.msg-reply-parent:hover { background: rgba(0, 0, 0, 0.08); }
[data-theme="paper"] .msg-reply-parent { background: rgba(156, 58, 46, 0.06); }
[data-theme="paper"] .msg-reply-parent:hover { background: rgba(156, 58, 46, 0.12); }
.msg-reply-parent .msg-reply-bar {
  width: 3px;
  background: var(--accent, #7c3aed);
  border-radius: 2px;
  flex-shrink: 0;
}
.msg-reply-parent .msg-reply-content {
  display: flex;
  flex-direction: column;
  min-width: 0;
  flex: 1;
}
.msg-reply-parent .msg-reply-author {
  font-weight: 600;
  font-size: 11px;
  color: var(--accent, #7c3aed);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.msg-reply-parent .msg-reply-preview {
  color: var(--text2);
  font-style: italic;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  opacity: 0.85;
}

/* Composer banner */
.composer-reply-banner {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  margin: 0 12px;
  background: var(--bg2);
  border: 1px solid var(--border);
  border-bottom: none;
  border-radius: 10px 10px 0 0;
  font-size: 13px;
  animation: replyBannerSlideIn 200ms ease;
}
@keyframes replyBannerSlideIn {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: translateY(0); }
}
.composer-reply-banner .banner-bar {
  width: 3px;
  align-self: stretch;
  background: var(--accent);
  border-radius: 2px;
}
.composer-reply-banner .banner-content {
  display: flex;
  flex-direction: column;
  min-width: 0;
  flex: 1;
}
.composer-reply-banner .banner-label {
  font-size: 12px;
  color: var(--accent);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.composer-reply-banner .banner-label strong { font-weight: 600; }
.composer-reply-banner .banner-preview {
  color: var(--text2);
  font-style: italic;
  font-size: 12px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  opacity: 0.9;
}
.composer-reply-banner .banner-cancel {
  background: transparent;
  border: none;
  color: var(--text2);
  cursor: pointer;
  font-size: 14px;
  padding: 4px 8px;
  border-radius: 4px;
  flex-shrink: 0;
}
.composer-reply-banner .banner-cancel:hover {
  background: var(--bg3);
  color: var(--text);
}

/* Reply button (action menu of each message) */
.btn-reply, .btn-dm-reply {
  background: transparent;
  border: none;
  color: var(--text2);
  cursor: pointer;
  font-size: 14px;
  padding: 2px 6px;
  border-radius: 4px;
  opacity: 0.55;
  transition: opacity 120ms, background 120ms, color 120ms;
}
.btn-reply:hover, .btn-dm-reply:hover {
  opacity: 1;
  background: var(--bg3);
  color: var(--accent);
}

/* Highlight pulse when scrolling to parent message */
@keyframes msgHighlightPulse {
  0%, 100% { box-shadow: 0 0 0 0 var(--accent-glow); }
  50%      { box-shadow: 0 0 0 6px var(--accent-glow); }
}
.msg-highlight-pulse {
  animation: msgHighlightPulse 1.5s ease-in-out;
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 8px;
}

/* ── Édition de message ────────────────────────────────────────────────── */
.btn-edit, .btn-dm-edit {
  background: transparent;
  border: none;
  color: var(--text2);
  cursor: pointer;
  font-size: 13px;
  padding: 2px 6px;
  border-radius: 4px;
  opacity: 0.55;
  transition: opacity 120ms, background 120ms, color 120ms;
}
.btn-edit:hover, .btn-dm-edit:hover {
  opacity: 1;
  background: var(--bg3);
  color: var(--accent);
}

/* Badge "(modifié)" à côté du timestamp — italic small text-2 */
.msg-edited-badge {
  font-style: italic;
  font-size: 10px;
  color: var(--text2);
  opacity: 0.7;
  margin-left: 2px;
}

/* Banner composer édition (réutilise le pattern du reply banner) */
.composer-edit-banner {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  margin: 0 12px;
  background: var(--bg2);
  border: 1px solid var(--border);
  border-bottom: none;
  border-radius: 10px 10px 0 0;
  font-size: 13px;
  animation: replyBannerSlideIn 200ms ease;
}
.composer-edit-banner .banner-bar {
  width: 3px;
  align-self: stretch;
  background: var(--yellow, #C58A2A);
  border-radius: 2px;
}
.composer-edit-banner .banner-content {
  display: flex;
  flex-direction: column;
  min-width: 0;
  flex: 1;
}
.composer-edit-banner .banner-label {
  font-size: 12px;
  color: var(--yellow, #C58A2A);
  font-weight: 500;
  white-space: nowrap;
}
.composer-edit-banner .banner-preview {
  color: var(--text2);
  font-size: 11px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  opacity: 0.8;
}
.composer-edit-banner .banner-cancel {
  background: transparent;
  border: none;
  color: var(--text2);
  cursor: pointer;
  font-size: 14px;
  padding: 4px 8px;
  border-radius: 4px;
  flex-shrink: 0;
}
.composer-edit-banner .banner-cancel:hover {
  background: var(--bg3);
  color: var(--text);
}

/* ── Mentions @user — dropdown autocomplete ────────────────────────────── */
.mention-dropdown {
  background: var(--bg2, #1a1a25);
  border: 1px solid var(--border, rgba(255,255,255,.12));
  border-radius: 8px;
  box-shadow: 0 8px 20px -4px rgba(0,0,0,.40);
  max-height: 280px;
  overflow-y: auto;
  z-index: 1000;
  min-width: 200px;
  padding: 4px 0;
  font-family: inherit;
  animation: mentionDropdownIn 120ms ease;
}
@keyframes mentionDropdownIn {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: translateY(0); }
}
.mention-dropdown .mention-header {
  padding: 6px 12px 4px;
  font-size: 10px;
  color: var(--text2);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  border-bottom: 1px solid var(--border);
  margin-bottom: 2px;
}
.mention-dropdown .mention-item {
  padding: 8px 14px;
  cursor: pointer;
  font-size: 13px;
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--text);
  transition: background 80ms ease;
  user-select: none;
}
.mention-dropdown .mention-item:hover,
.mention-dropdown .mention-item-active {
  background: var(--accent, #7c3aed);
  color: #fff;
}
.mention-dropdown .mention-item-active .mention-at,
.mention-dropdown .mention-item:hover .mention-at { opacity: 0.85; color: #fff; }
.mention-dropdown .mention-at {
  opacity: 0.6;
  font-weight: 500;
}

/* ── Pin message — section intégrée au mur, sticky top ─
   Les épinglés sont rendus comme des bulles complètes en haut. La copie
   chronologique est masquée par CSS (anti-doublon, sélecteur ci-dessous).
   Sticky top:0 → la section reste constamment visible quand on scroll.
   Fond bg2 opaque (pas de blur) pour qu'on lise par-dessus le chrono. */
.pinned-section {
  position: sticky;
  top: 0;
  z-index: 5;
  background: var(--bg2);
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 8px 0 10px;
  margin-bottom: 12px;
  border-bottom: 1px dashed var(--border);
}
/* Anti-doublon : la copie chronologique d'un msg épinglé est masquée.
   Seule la copie dans .pinned-section (qui a .msg-card-pinned) reste. */
#messages-area > .msg-card[data-pinned="true"]:not(.msg-card-pinned) {
  display: none;
}

/* ── Barre de recherche dans la conversation ─────────────────────────── */
/* Insérée dynamiquement au-dessus de #messages-area au clic sur 🔍.
   Filter mode : les cards/rows qui ne matchent pas reçoivent .search-hidden. */
.msg-search-bar {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 12px;
  background: var(--bg2);
  border-bottom: 1px solid var(--border);
  position: sticky; top: 0; z-index: 6;
}
.msg-search-icon {
  color: var(--muted);
  display: inline-flex; align-items: center;
}
.msg-search-input {
  flex: 1;
  background: var(--bg3);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 6px 10px;
  font: 400 13px/1.3 'Geist', 'Manrope', system-ui, sans-serif;
  color: var(--text);
  min-width: 0;
}
.msg-search-input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 2px var(--accent-glow);
}
.msg-search-count {
  font-size: 11px;
  color: var(--muted);
  white-space: nowrap;
  font-weight: 500;
}
.msg-search-count.no-result { color: #c44a2c; }
.msg-search-close {
  width: 24px; height: 24px;
  border-radius: 6px;
  background: none; border: none;
  color: var(--muted);
  cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 14px;
  transition: background 120ms, color 120ms;
}
.msg-search-close:hover { background: var(--hover); color: var(--text); }
/* Filtrage : on cache via classe (pas !important pour pouvoir override
   via mode admin/debug si besoin). Compat anti-doublon pinned : ne pas
   se battre avec le sélecteur, l'order CSS suffit. */
.search-hidden { display: none; }

/* ── Bloqué (user banni localement) ────────────────────────────────────── */
.msg-card-blocked {
  background: var(--bg3);
  border: 1px dashed var(--border);
  padding: 8px 12px;
  border-radius: 8px;
  margin: 4px 0;
  display: flex; align-items: center; gap: 10px;
  opacity: 0.65;
}
.msg-blocked-label {
  font-size: 12px;
  color: var(--muted);
  font-style: italic;
  flex: 1;
}
.msg-blocked-unblock {
  background: none; border: none;
  color: var(--accent);
  font-size: 11px;
  cursor: pointer;
  padding: 2px 8px;
  border-radius: 6px;
  transition: background 120ms;
}
.msg-blocked-unblock:hover { background: var(--accent-glow); }
.btn-danger {
  background: rgba(196, 74, 44, 0.08);
  border: 1px solid rgba(196, 74, 44, 0.30);
  color: #c44a2c;
}
.btn-danger:hover {
  background: rgba(196, 74, 44, 0.18);
  border-color: rgba(196, 74, 44, 0.55);
}

/* ── Markdown inline (gras / italique / code) ──────────────────────────── */
.md-code {
  font-family: 'Geist Mono', ui-monospace, 'SF Mono', monospace;
  font-size: 0.92em;
  background: var(--bg3);
  border: 1px solid var(--border);
  padding: 1px 5px;
  border-radius: 4px;
  white-space: nowrap;
}

/* ── Audio bubble : player + toolbar (vitesse + transcrire) ─────────────── */
.msg-audio-wrap {
  display: flex; flex-direction: column;
  gap: 4px;
  align-items: stretch;
  /* Largeur EXPLICITE (pas seulement max-width) : sinon le wrap rétrécit à la
     largeur intrinsèque du <audio> → lecteur tassé (retour user 2026-06-11).
     Borné au viewport ; max-width:100% l'empêche de déborder du bubble. */
  width: min(320px, calc(100vw - 100px));
  max-width: 100%;
  box-sizing: border-box;
}
.msg-audio-toolbar {
  display: inline-flex; align-items: center; gap: 4px;
  flex-wrap: wrap;
}
/* Boutons toolbar audio (1× / 📝) : style cohérent, compact, semi-transparent
   pour s'intégrer aux bubbles de toute couleur (claire OU sombre = sent
   bubble accent). Pas de fond opaque qui flotterait au-dessus du bubble. */
.btn-audio-speed,
.btn-transcribe {
  font: 600 11px/1 'Geist Mono', ui-monospace, monospace;
  background: rgba(255, 255, 255, 0.10);
  border: 1px solid rgba(255, 255, 255, 0.20);
  color: inherit;
  padding: 3px 9px;
  border-radius: 999px;
  cursor: pointer;
  transition: background 120ms, border-color 120ms;
  white-space: nowrap;
  text-align: center;
  backdrop-filter: blur(4px);
}
.btn-audio-speed { min-width: 34px; }
.btn-transcribe {
  font-family: 'Geist', 'Manrope', system-ui, sans-serif;
  font-weight: 500;
}
.btn-audio-speed:hover,
.btn-transcribe:hover {
  background: rgba(255, 255, 255, 0.20);
  border-color: rgba(255, 255, 255, 0.35);
}
/* Bubbles received (clair) : on inverse pour rester lisible. */
.dm-row.received .btn-audio-speed,
.dm-row.received .btn-transcribe,
.msg-card .btn-audio-speed,
.msg-card .btn-transcribe {
  background: rgba(0, 0, 0, 0.06);
  border-color: rgba(0, 0, 0, 0.14);
  color: var(--text2);
}
.dm-row.received .btn-audio-speed:hover,
.dm-row.received .btn-transcribe:hover,
.msg-card .btn-audio-speed:hover,
.msg-card .btn-transcribe:hover {
  background: rgba(0, 0, 0, 0.12);
  border-color: rgba(0, 0, 0, 0.24);
}
@media (max-width: 700px) {
  /* Audio plus large sur mobile (l'ancien cap 240px le tassait — retour user
     2026-06-11). Borné au viewport pour ne jamais déborder ; la largeur du
     bubble parent (dm-content élargi ci-dessous) le contient de toute façon. */
  .msg-audio-wrap { max-width: min(320px, calc(100vw - 72px)); gap: 3px; }
  .msg-audio-toolbar { gap: 3px; }
  .btn-audio-speed, .btn-transcribe { padding: 3px 9px; font-size: 11px; }
}

/* ── Responsive chat : disposition des bulles sur petit écran ────────────────
   Sur mobile, .dm-content à 72% (calculé APRÈS l'avatar) tombait à ~190px de
   texte → 2-3 mots/ligne, illisible (retour user 2026-06-11). Convention des
   messageries (WhatsApp/iMessage/Telegram) : la bulle occupe ~85-88% de la
   ligne sur téléphone. On élargit + on récupère de la place (padding réduits)
   + on borne les médias au viewport (anti-débordement). */
@media (max-width: 700px) {
  .dm-content { max-width: 88%; }
  /* Les bulles MÉDIA (audio / image / vidéo) veulent plus de largeur que le
     texte — convention messageries. On leur donne ~94% pour que le lecteur
     audio et les images respirent (sinon le cap texte 88% les bridait). */
  .dm-content:has(.msg-audio-wrap),
  .dm-content:has(.dm-img),
  .dm-content:has(.msg-video-wrap) { max-width: 94%; }
  .dm-row { gap: 7px; padding: 0 6px; }
  .dm-bubble { padding: 9px 13px; }
  .msg-card { padding: 10px 11px; }
  /* Audio mobile : largeur explicite bornée au viewport (cohérent avec le cap
     desktop), remplit la bulle média élargie. */
  .msg-audio-wrap { width: min(330px, calc(100vw - 64px)); }
  /* Médias : jamais plus larges que la ligne (déjà min(px,100%) ; on remonte
     un peu la hauteur max puisque la largeur est contrainte sur mobile). */
  .msg-img, .dm-img { max-height: 340px; }
}
@media (max-width: 400px) {
  .dm-content { max-width: 92%; } /* très petits écrans : encore plus de place */
}
.btn-transcribe {
  font: 500 11px/1 'Geist', 'Manrope', system-ui, sans-serif;
  background: var(--bg3);
  border: 1px solid var(--border);
  color: var(--text2);
  padding: 4px 10px;
  border-radius: 999px;
  cursor: pointer;
  transition: background 120ms, border-color 120ms, color 120ms;
  white-space: nowrap;
}
.btn-transcribe:hover:not(:disabled) {
  background: var(--accent-glow);
  border-color: rgba(156, 58, 46, 0.32);
  color: var(--accent);
}
.btn-transcribe:disabled { opacity: 0.6; cursor: progress; }
.msg-transcript {
  background: var(--bg3);
  border-left: 3px solid var(--accent);
  padding: 8px 10px;
  border-radius: 4px;
  font: 400 12.5px/1.45 'Geist', 'Manrope', system-ui, sans-serif;
  color: var(--text);
  white-space: pre-wrap;
  word-break: break-word;
  margin-top: 4px;
}
.msg-transcript.hidden { display: none; }

/* ── View Once (voir une fois) ──────────────────────────────────────────── */
/* Bouton 👁 dans expiry-selector : état actif = jaune doré (cohérent
   avec le filtre pin et l'esprit "warning soft"). */
.expiry-btn.expiry-viewonce {
  font-size: 14px;
}
.expiry-btn.expiry-viewonce.active {
  background: #f5c518;
  color: #1a1500;
  border-color: #e0a800;
  box-shadow: 0 0 0 2px rgba(245, 197, 24, 0.30);
}
/* Teaser cliquable côté receiver : grand bouton qui invite à révéler */
.msg-viewonce-teaser {
  display: flex; align-items: center; gap: 12px;
  background: linear-gradient(135deg, rgba(245,197,24,0.10), rgba(245,197,24,0.04));
  border: 1.5px dashed rgba(245, 197, 24, 0.45);
  border-radius: 10px;
  padding: 12px 14px;
  width: 100%;
  min-width: 220px;
  cursor: pointer;
  color: var(--text);
  text-align: left;
  font: 500 13px/1.3 'Geist', 'Manrope', system-ui, sans-serif;
  transition: background 120ms, border-color 120ms, transform 80ms;
}
.msg-viewonce-teaser:hover {
  background: linear-gradient(135deg, rgba(245,197,24,0.16), rgba(245,197,24,0.08));
  border-color: #e0a800;
}
.msg-viewonce-teaser:active { transform: scale(0.98); }
.msg-viewonce-icon { font-size: 22px; flex-shrink: 0; }
.msg-viewonce-text { display: flex; flex-direction: column; gap: 2px; }
.msg-viewonce-label { font-weight: 600; }
.msg-viewonce-hint { font-size: 11px; color: var(--muted); }
/* Placeholder "déjà vu" : aspect terne, non-cliquable */
.msg-viewonce-consumed {
  display: inline-flex; align-items: center; gap: 8px;
  background: var(--bg3);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 8px 12px;
  color: var(--muted);
  font-size: 12px;
  font-style: italic;
}
/* Modale plein-écran : affiche le contenu, fermeture = wipe */
.viewonce-modal {
  position: fixed; inset: 0;
  background: rgba(0, 0, 0, 0.90);
  z-index: 9999;
  display: flex; align-items: center; justify-content: center;
  padding: 20px;
}
.viewonce-modal-inner {
  background: var(--bg2);
  border-radius: 12px;
  max-width: 90vw;
  max-height: 90vh;
  display: flex; flex-direction: column;
  overflow: hidden;
  box-shadow: 0 20px 60px rgba(0,0,0,0.5);
}
.viewonce-modal-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 10px 14px;
  background: linear-gradient(90deg, rgba(245,197,24,0.12), transparent 60%);
  border-bottom: 1px solid var(--border);
}
.viewonce-modal-label {
  font: 600 12px/1 'Geist', 'Manrope', system-ui, sans-serif;
  color: #8a6a00;
  letter-spacing: 0.02em;
}
.viewonce-modal-close {
  background: none; border: none;
  color: var(--muted);
  font-size: 16px;
  cursor: pointer;
  padding: 4px 8px;
  border-radius: 6px;
}
.viewonce-modal-close:hover { background: var(--hover); color: var(--text); }
.viewonce-modal-content {
  display: flex; align-items: center; justify-content: center;
  padding: 16px;
  max-height: calc(90vh - 56px);
  overflow: hidden;
}
.viewonce-img {
  max-width: 100%;
  max-height: 70vh;
  object-fit: contain;
  border-radius: 6px;
}
.viewonce-video {
  max-width: 100%;
  max-height: 70vh;
  border-radius: 6px;
}
.viewonce-audio {
  width: 320px;
  max-width: 100%;
}
.viewonce-unsupported {
  color: var(--muted);
  font-size: 13px;
  padding: 40px 20px;
  text-align: center;
}

/* ── Forward modal (transfert d'un message) ─────────────────────────────── */
.forward-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; }
.forward-header h3 { margin: 0; font-size: 15px; font-weight: 600; }
.forward-header .btn-cancel-modal {
  background: none; border: none; color: var(--muted);
  font-size: 16px; cursor: pointer; padding: 4px 8px; border-radius: 6px;
}
.forward-header .btn-cancel-modal:hover { background: var(--hover); color: var(--text); }
.forward-preview {
  background: var(--bg3);
  border-radius: 8px;
  padding: 10px 12px;
  margin-bottom: 12px;
  font-size: 12px;
  color: var(--text2);
  max-height: 80px; overflow: hidden;
  border-left: 3px solid var(--accent);
}
.forward-preview-text { line-height: 1.4; white-space: pre-wrap; word-break: break-word; }
.forward-preview-file { font-weight: 500; }
.forward-list {
  display: flex; flex-direction: column;
  gap: 4px;
  max-height: 320px; overflow-y: auto;
  padding-right: 4px;
}
.forward-dest {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 12px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 8px;
  color: var(--text);
  font: 500 13px/1 'Geist', 'Manrope', system-ui, sans-serif;
  cursor: pointer;
  text-align: left;
  transition: background 120ms, border-color 120ms;
}
.forward-dest:hover {
  background: var(--hover);
  border-color: var(--border);
}
.forward-dest-icon {
  width: 24px; height: 24px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--accent-glow);
  border-radius: 6px;
  color: var(--accent);
  font-weight: 700;
  flex-shrink: 0;
}
.forward-dest-label { flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.forward-empty {
  text-align: center;
  padding: 20px;
  color: var(--muted);
  font-size: 12px;
}

/* Bouton ↪ Transférer dans les actions msg-card et dm-row */
.btn-forward, .btn-dm-forward, .btn-dm-copy {
  background: none; border: none;
  color: var(--muted);
  cursor: pointer;
  padding: 2px 6px;
  border-radius: 5px;
  font-size: 13px;
  line-height: 1;
  transition: background 120ms, color 120ms;
}
.btn-forward:hover, .btn-dm-forward:hover, .btn-dm-copy:hover {
  background: var(--hover);
  color: var(--accent);
}

/* ── Voice message overlay ────────────────────────────────────────────── */
/* Apparaît au-dessus du composer pendant enregistrement, puis preview.
   Pas de overlay modal — c'est inline pour rester non-disruptif. */
.voice-overlay {
  display: flex; align-items: center; gap: 12px;
  background: var(--bg2);
  border-top: 1px solid var(--border);
  padding: 10px 16px;
  font: 500 13px/1.3 'Geist', 'Manrope', system-ui, sans-serif;
}
.voice-overlay-recording {
  background: linear-gradient(90deg, rgba(196,74,44,0.06), transparent 40%);
}
.voice-overlay-preview {
  background: linear-gradient(90deg, rgba(22,168,95,0.06), transparent 40%);
}
.voice-rec-dot {
  width: 10px; height: 10px;
  background: #c44a2c; border-radius: 50%;
  animation: voice-pulse 1.2s ease-in-out infinite;
  flex-shrink: 0;
}
@keyframes voice-pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.4; transform: scale(0.75); }
}
.voice-rec-label {
  color: var(--text);
  font-weight: 600;
}
.voice-rec-timer {
  font-family: 'Geist Mono', ui-monospace, monospace;
  color: var(--accent);
  font-weight: 600;
  margin-left: auto;
}
.voice-preview-audio {
  flex: 1;
  height: 36px;
  min-width: 0;
}
.voice-preview-duration {
  font-size: 11px;
  color: var(--muted);
  font-family: 'Geist Mono', ui-monospace, monospace;
  white-space: nowrap;
}
.voice-btn {
  width: 36px; height: 36px;
  border-radius: 8px;
  background: var(--bg3);
  border: 1px solid var(--border);
  color: var(--text);
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer;
  font-size: 16px;
  padding: 0;
  transition: background 120ms, border-color 120ms, transform 80ms;
  flex-shrink: 0;
}
.voice-btn:hover { background: var(--hover); }
.voice-btn:active { transform: scale(0.95); }
.voice-btn.voice-cancel,
.voice-btn.voice-discard {
  color: #c44a2c;
  border-color: rgba(196, 74, 44, 0.22);
  background: rgba(196, 74, 44, 0.06);
}
.voice-btn.voice-cancel:hover,
.voice-btn.voice-discard:hover {
  background: rgba(196, 74, 44, 0.14);
  border-color: rgba(196, 74, 44, 0.44);
}
.voice-btn.voice-stop,
.voice-btn.voice-send {
  color: #0C7A41;
  border-color: rgba(22, 168, 95, 0.30);
  background: rgba(22, 168, 95, 0.08);
}
.voice-btn.voice-stop:hover,
.voice-btn.voice-send:hover {
  background: #16A85F;
  color: #fff;
  border-color: #16A85F;
}

/* Base : boutons header canal (PQ, search, pin-filter, badge-readonly).
   Style ghost transparent, fond léger uniquement au hover. Override les
   browser-defaults moches en dark theme + paper theme garde sa teinte. */
.pq-icon-btn,
.btn-search,
.btn-share-channel {
  width: 32px; height: 32px;
  border-radius: 8px;
  background: transparent;
  border: 1px solid transparent;
  color: var(--text2);
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer;
  padding: 0;
  transition: background 120ms, border-color 120ms, color 120ms, transform 80ms;
  flex-shrink: 0;
}
.pq-icon-btn:hover,
.btn-search:hover,
.btn-share-channel:hover {
  background: var(--hover);
  border-color: var(--border);
  color: var(--accent);
}
.pq-icon-btn:active,
.btn-search:active,
.btn-share-channel:active { transform: scale(0.95); }
.pq-icon-btn svg,
.btn-search svg,
.btn-share-channel svg { width: 18px; height: 18px; }

/* Menu overflow ⋯ : regroupe recherche/partage/épinglés/sonnerie pour
   désengorger la barre d'en-tête (2026-06-04). */
.header-more-wrap { position: relative; display: inline-flex; }
.btn-header-more {
  width: 32px; height: 32px;
  border-radius: 8px;
  background: transparent;
  border: 1px solid transparent;
  color: var(--text2);
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer; padding: 0;
  font-size: 20px; line-height: 1;
  transition: background 120ms, border-color 120ms, color 120ms, transform 80ms;
  flex-shrink: 0;
}
.btn-header-more:hover { background: var(--hover); border-color: var(--border); color: var(--accent); }
.btn-header-more:active { transform: scale(0.95); }
/* Pastille discrète quand il y a des messages épinglés (signal conservé
   même si le bouton 📌 N est passé dans le menu). */
.btn-header-more.has-pins::after {
  content: ''; position: absolute; top: 5px; right: 5px;
  width: 6px; height: 6px; border-radius: 50%;
  background: #f5c518; box-shadow: 0 0 0 2px var(--bg2, #fff);
}
.header-more-menu {
  position: absolute; top: calc(100% + 6px); right: 0;
  min-width: 184px; z-index: 1200;
  background: var(--bg2); border: 1px solid var(--border);
  border-radius: 12px; padding: 6px;
  box-shadow: 0 12px 32px rgba(0,0,0,0.18);
  display: flex; flex-direction: column; gap: 2px;
}
.header-more-menu.hidden { display: none; }
.hm-item {
  display: flex; align-items: center; gap: 9px;
  width: 100%; padding: 9px 10px;
  background: transparent; border: 0; border-radius: 8px;
  color: var(--text); cursor: pointer; text-align: left;
  font: 500 13px/1.1 'Geist', 'Manrope', system-ui, sans-serif;
  transition: background 100ms;
}
.hm-item:hover { background: var(--hover); }
.hm-item svg { width: 17px; height: 17px; flex-shrink: 0; color: var(--text2); }
.hm-item span { white-space: nowrap; }
/* Bouton 📌 N (filtre épinglés) : base ghost, pill */
.btn-pin-filter {
  height: 28px;
  display: inline-flex; align-items: center; gap: 5px;
  padding: 0 10px;
  border-radius: 999px;
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text2);
  font: 600 11.5px/1 'Geist', 'Manrope', system-ui, sans-serif;
  letter-spacing: 0.02em;
  cursor: pointer;
  white-space: nowrap;
  transition: background 120ms, border-color 120ms, color 120ms, transform 80ms;
}
.btn-pin-filter:hover {
  background: var(--hover);
  border-color: var(--border2);
  color: var(--text);
}
.btn-pin-filter:active { transform: scale(0.96); }
.btn-pin-filter svg { vertical-align: middle; }
.btn-pin-filter .pin-count { display: inline-block; font-weight: 700; }
.pinned-section-icon svg { vertical-align: middle; }
.msg-pinned-badge svg { vertical-align: -1px; }
.btn-pin-filter.active {
  background: rgba(245, 197, 24, 0.15);
  border-color: rgba(245, 197, 24, 0.45);
  color: #d4a700;
}
/* Bouton 🔍 paper theme : garde la teinte accent légère */
[data-theme="paper"] .btn-search {
  width: 32px; height: 32px;
  border-radius: 8px;
  background: rgba(124, 106, 247, 0.06);
  border: 1px solid rgba(124, 106, 247, 0.16);
  color: var(--accent);
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer;
  padding: 0;
  transition: background 120ms, border-color 120ms, transform 80ms;
  flex-shrink: 0;
}
[data-theme="paper"] .btn-search:hover {
  background: rgba(124, 106, 247, 0.14);
  border-color: rgba(124, 106, 247, 0.36);
}
[data-theme="paper"] .btn-search:active { transform: scale(0.95); }
.pinned-section-label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent);
  padding: 2px 0 6px;
}
.pinned-section-icon { font-size: 13px; }
/* Petit accent à gauche des bulles épinglées — signale subtilement le
   statut sans dénaturer l'apparence msg-card. */
.msg-card-pinned {
  border-left: 3px solid #f5c518;
  padding-left: 9px;
  background: linear-gradient(90deg, rgba(245,197,24,0.05), transparent 40%);
  border-radius: 4px;
}
/* Compat : ancien banner sticky (référencé par d'autres parties éventuelles) */
.pinned-banner { display: none; }
.pinned-banner-header { display: none; }
.pinned-items {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.pinned-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 6px;
  border-radius: 4px;
  cursor: pointer;
  font-size: 12px;
  line-height: 1.4;
  min-width: 0;
  transition: background 120ms;
}
.pinned-item:hover { background: var(--bg3); }
.pinned-item-author {
  font-weight: 600;
  color: var(--accent);
  flex-shrink: 0;
}
.pinned-item-preview {
  color: var(--text2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
  flex: 1;
}
/* Thumbnail image dans le bandeau pin — preview visuelle du contenu épinglé. */
.pinned-item-thumb {
  flex-shrink: 0;
  border-radius: 4px;
  border: 1px solid var(--border);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
img.pinned-item-thumb {
  width: 56px;
  height: 56px;
  object-fit: cover;
  cursor: zoom-in;
  transition: transform 120ms ease;
}
img.pinned-item-thumb:hover { transform: scale(1.08); }

/* ── Image épinglée mise en avant — style "menu/recommandation" ──────────
   Image affichée à sa taille naturelle (largeur container, hauteur libre),
   capée à 60vh pour ne pas hijacker la zone de chat. */
.pinned-item-featured {
  flex-direction: column;
  align-items: stretch;
  gap: 6px;
  padding: 8px;
  background: var(--bg3);
  border: 1px solid var(--border);
}
.pinned-feature-header {
  display: flex;
  align-items: center;
  gap: 6px;
}
.pinned-feature-img {
  display: block;
  width: 100%;
  height: auto;
  max-height: 60vh;
  object-fit: contain;
  border-radius: 4px;
  cursor: zoom-in;
  background: var(--bg1);
}
.pinned-feature-caption {
  font-size: 12px;
  color: var(--text2);
  line-height: 1.4;
  white-space: pre-wrap;
  word-break: break-word;
}
/* Sticker Lottie épinglé : preview centré, animation joue en boucle dans le banner.
   Taille raisonnable pour ne pas hijacker la zone de chat. */
.pinned-feature-lottie {
  width: 140px;
  height: 140px;
  margin: 0 auto;
  display: block;
}
.pinned-feature-lottie svg { width: 100% !important; height: 100% !important; display: block; }
.pinned-sticker-label {
  font-size: 11px;
  color: var(--text2);
  opacity: 0.7;
  margin-left: auto;
}
.pinned-item-sticker {
  align-items: center;
}

/* Bouton dépinglage sur preview pin (top-right header) — UX directe sans
   devoir naviguer au message d'origine. */
.pinned-unpin-btn {
  margin-left: auto;
  background: none;
  border: none;
  color: var(--muted);
  font-size: 14px;
  line-height: 1;
  width: 24px;
  height: 24px;
  border-radius: 6px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background 120ms, color 120ms, transform 120ms;
  flex-shrink: 0;
  padding: 0;
}
.pinned-unpin-btn:hover {
  background: var(--hover);
  color: var(--text);
  transform: scale(1.1);
}
.pinned-thumb-video, .pinned-thumb-audio {
  font-size: 11px;
  padding: 4px 8px;
  color: var(--text2);
  background: var(--bg3);
  max-width: 200px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.pinned-more {
  font-size: 11px;
  color: var(--text2);
  font-style: italic;
  padding: 4px 6px;
  opacity: 0.7;
}

/* ── Pinned sidebar (nouveau modèle) ─────────────────────────────────────
   Barre verticale fine à droite du mur — vignettes scrollables verticalement
   de tous les msgs épinglés. Clic = ouverture en grand (lightbox/modal).
   Remplace l'ancienne .pinned-section (cards complètes en haut du mur). */

#messages-wrap {
  flex: 1;
  display: flex;
  flex-direction: row;
  min-height: 0;
  position: relative;
}
#messages-wrap > #messages-area {
  flex: 1;
  min-width: 0;
}

.pinned-sidebar {
  width: 72px;
  flex-shrink: 0;
  overflow-y: auto;
  overflow-x: hidden;
  padding: 12px 8px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  border-left: 1px solid var(--border);
  background: var(--bg2);
  scrollbar-width: thin;
}
.pinned-sidebar:empty { display: none; }
.pinned-sidebar::-webkit-scrollbar { width: 4px; }
.pinned-sidebar::-webkit-scrollbar-thumb { background: var(--border); border-radius: 2px; }

.pinned-thumb-mini {
  position: relative;
  width: 56px;
  height: 56px;
  border-radius: 8px;
  background: var(--bg3);
  border: 1px solid var(--border);
  cursor: grab;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 22px;
  color: var(--text2);
  flex-shrink: 0;
  transition: transform 120ms ease, border-color 120ms ease, box-shadow 120ms ease;
  /* Touch : permet scroll vertical normal mais le long-press 350ms
     déclenche le drag (géré en JS). */
  touch-action: pan-y;
  user-select: none;
  -webkit-user-select: none;
}
.pinned-thumb-mini:active { cursor: grabbing; }
/* Sidebar read-only (non-admin) : vignettes cliquables (zoom-in) mais
   pas de drag — le cursor "grab" trompeur est retiré. */
.pinned-sidebar-readonly .pinned-thumb-mini { cursor: zoom-in; touch-action: pan-y; }
.pinned-sidebar-readonly .pinned-thumb-mini:active { cursor: zoom-in; }
.pinned-thumb-mini.pinned-thumb-dragging {
  opacity: 0.85;
  cursor: grabbing;
  z-index: 50;
  box-shadow: 0 8px 20px rgba(0,0,0,0.35);
  transition: none;
  border-color: var(--accent);
}
.pinned-thumb-mini-placeholder {
  width: 56px;
  height: 56px;
  border-radius: 8px;
  background: rgba(124,106,247,0.15);
  border: 2px dashed var(--accent);
  flex-shrink: 0;
}
@media (max-width: 700px) {
  .pinned-thumb-mini-placeholder { width: 44px; height: 44px; }
}
.pinned-thumb-mini:hover {
  transform: scale(1.08);
  border-color: var(--accent);
  box-shadow: 0 2px 8px rgba(124,106,247,0.20);
}
.pinned-thumb-mini > img,
.pinned-thumb-mini > video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  /* user-drag: none + pointer-events: none : empêche le drag natif HTML5
     de l'img (Chrome/Safari) qui intercepterait pointermove et tuerait
     notre DnD pinned. pointer-events: none fait passer les events au
     wrap .pinned-thumb-mini (qui a le listener pointerdown). */
  -webkit-user-drag: none;
  user-drag: none;
  pointer-events: none;
  user-select: none;
}
.pinned-thumb-mini .pinned-thumb-icon {
  pointer-events: none;
}
.pinned-thumb-mini .pinned-thumb-mini-lottie {
  width: 100%;
  height: 100%;
  display: block;
}
.pinned-thumb-mini .pinned-thumb-mini-lottie svg {
  width: 100% !important;
  height: 100% !important;
  display: block;
}
.pinned-thumb-mini .pinned-thumb-mini-text {
  font-size: 9px;
  line-height: 1.2;
  padding: 4px;
  color: var(--text);
  text-align: center;
  word-break: break-word;
  display: -webkit-box;
  -webkit-line-clamp: 4;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.pinned-thumb-mini .pinned-thumb-mini-unpin {
  position: absolute;
  top: 2px;
  right: 2px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: rgba(0,0,0,0.55);
  color: #fff;
  border: none;
  cursor: pointer;
  font-size: 11px;
  line-height: 1;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 0;
}
.pinned-thumb-mini:hover .pinned-thumb-mini-unpin { display: inline-flex; }
.pinned-thumb-mini-author {
  position: absolute;
  bottom: 0; left: 0; right: 0;
  background: linear-gradient(180deg, transparent, rgba(0,0,0,0.65));
  color: #fff;
  font-size: 9px;
  line-height: 1;
  padding: 8px 4px 3px;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  pointer-events: none;
}

/* Mobile (≤700px) : sidebar plus étroite */
@media (max-width: 700px) {
  .pinned-sidebar {
    width: 52px;
    padding: 8px 4px;
    gap: 6px;
  }
  .pinned-thumb-mini {
    width: 44px;
    height: 44px;
    font-size: 18px;
  }
  .pinned-thumb-mini-author { font-size: 8px; padding: 6px 2px 2px; }
}

/* Modale plein écran — grille de tous les pinned (depuis le bouton 📌 N) */
.pinned-grid-modal {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.85);
  z-index: 9999;
  display: flex;
  flex-direction: column;
  animation: pinned-modal-fade-in 180ms ease;
}
@keyframes pinned-modal-fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}
.pinned-grid-modal-header {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px 20px;
  background: var(--bg2);
  border-bottom: 1px solid var(--border);
}
.pinned-grid-modal-title {
  font-weight: 600;
  font-size: 16px;
  color: var(--text);
}
/* Classes pour remplacer les style= inline (bloqués par la CSP style-src self). */
.pinned-grid-modal-pin { font-size: 20px; }
.pinned-grid-modal-count { color: var(--text2); font-weight: 400; font-size: 13px; }
.pinned-grid-card-nocaption { color: var(--text2); font-style: italic; }
.pinned-grid-modal-close {
  margin-left: auto;
  background: none;
  border: none;
  color: var(--text);
  font-size: 24px;
  cursor: pointer;
  width: 36px;
  height: 36px;
  border-radius: 8px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.pinned-grid-modal-close:hover { background: var(--hover); }
.pinned-grid-modal-body {
  flex: 1;
  overflow-y: auto;
  padding: 20px;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 16px;
  align-content: start;
  background: var(--bg1);
}
.pinned-grid-card {
  background: var(--bg2);
  border: 1px solid var(--border);
  border-radius: 12px;
  overflow: hidden;
  cursor: zoom-in;
  display: flex;
  flex-direction: column;
  transition: transform 120ms ease, border-color 120ms ease;
}
.pinned-grid-card:hover {
  transform: translateY(-2px);
  border-color: var(--accent);
}
.pinned-grid-card-media {
  width: 100%;
  height: 140px;
  background: var(--bg3);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 38px;
  color: var(--text2);
  overflow: hidden;
}
.pinned-grid-card-media > img,
.pinned-grid-card-media > video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.pinned-grid-card-media-lottie { width: 100%; height: 100%; }
.pinned-grid-card-media-lottie svg { width: 100% !important; height: 100% !important; }
.pinned-grid-card-meta {
  padding: 10px 12px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.pinned-grid-card-author {
  font-size: 12px;
  font-weight: 600;
  color: var(--accent);
}
.pinned-grid-card-preview {
  font-size: 12px;
  color: var(--text2);
  line-height: 1.4;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  word-break: break-word;
}
/* 🗑 Bouton « retirer l'épingle » — coin haut-droit de chaque carte (le clic
   est intercepté par la modale, n'ouvre pas la vue large). Toujours visible
   (utile en mobile : pas de hover requis). */
.pinned-grid-card { position: relative; }
.pinned-grid-card-unpin {
  position: absolute; top: 6px; right: 6px; z-index: 2;
  border: none; cursor: pointer;
  background: rgba(0, 0, 0, 0.55); color: #fff;
  border-radius: 8px; padding: 5px 9px; font-size: 13px; font-weight: 600;
  line-height: 1; display: inline-flex; align-items: center; gap: 4px;
  backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px);
  transition: background 0.12s;
}
.pinned-grid-card-unpin:hover { background: var(--red, #B83A3A); }
/* Carte « épingle indisponible » (clé manquante) : pas de zoom, contenu grisé,
   bouton Supprimer en clair sous le texte. */
.pinned-grid-card-ghost { cursor: default; }
.pinned-grid-card-ghost:hover { transform: none; border-color: var(--border); }
.pinned-grid-card-ghost .pinned-grid-card-media { font-size: 30px; opacity: 0.55; }
.pinned-grid-card-ghost .pinned-grid-card-author { color: var(--text2); }
.pinned-grid-card-ghost .pinned-grid-card-unpin {
  position: static; align-self: flex-start;
  margin: 0 12px 12px; background: var(--red, #B83A3A);
}
.pinned-grid-modal-empty {
  grid-column: 1 / -1;
  text-align: center;
  color: var(--text2);
  font-style: italic;
  padding: 60px 20px;
}

/* Modale plein écran — un seul pinned ouvert en grand (image/video/lottie/text) */
.pinned-large-modal {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.92);
  z-index: 10000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 40px;
  animation: pinned-modal-fade-in 180ms ease;
}
.pinned-large-modal-close {
  position: absolute;
  top: 16px;
  right: 16px;
  background: rgba(255,255,255,0.1);
  color: #fff;
  border: none;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  cursor: pointer;
  font-size: 20px;
}
.pinned-large-modal-close:hover { background: rgba(255,255,255,0.2); }
.pinned-large-modal-inner {
  max-width: 100%;
  max-height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
}
.pinned-large-modal-inner > img,
.pinned-large-modal-inner > video {
  max-width: 100%;
  max-height: 80vh;
  border-radius: 8px;
  display: block;
}
.pinned-large-modal-inner > audio {
  width: min(480px, 90vw);
}
.pinned-large-modal-inner .pinned-large-modal-lottie {
  width: min(360px, 80vw);
  height: min(360px, 80vw);
}
.pinned-large-modal-inner .pinned-large-modal-lottie svg {
  width: 100% !important;
  height: 100% !important;
}
.pinned-large-modal-inner .pinned-large-modal-text {
  max-width: min(640px, 90vw);
  color: #fff;
  font-size: 16px;
  line-height: 1.6;
  white-space: pre-wrap;
  word-break: break-word;
  padding: 24px;
  background: rgba(255,255,255,0.05);
  border-radius: 12px;
}
.pinned-large-modal-inner .pinned-large-modal-caption {
  color: rgba(255,255,255,0.8);
  font-size: 13px;
  text-align: center;
  max-width: min(640px, 90vw);
}
.pinned-large-modal-inner .pinned-large-modal-meta {
  color: rgba(255,255,255,0.55);
  font-size: 12px;
}

/* Badge 📌 inline dans le header de la bulle quand pinned */
.msg-pinned-badge {
  font-size: 11px;
  opacity: 0.7;
}

/* Bouton pin/unpin dans les actions */
.btn-pin {
  background: transparent;
  border: none;
  color: var(--text2);
  cursor: pointer;
  font-size: 13px;
  padding: 2px 6px;
  border-radius: 4px;
  opacity: 0.55;
  transition: opacity 120ms, background 120ms;
}
.btn-pin:hover {
  opacity: 1;
  background: var(--bg3);
}

/* ── Typing indicator ──────────────────────────────────────────────────── */
.typing-indicator {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 16px;
  margin: 0 12px;
  font-size: 12px;
  color: var(--text2);
  font-style: italic;
  animation: typingSlideIn 200ms ease;
}
@keyframes typingSlideIn {
  from { opacity: 0; transform: translateY(2px); }
  to   { opacity: 1; transform: translateY(0); }
}
.typing-indicator .typing-label strong {
  font-style: normal;
  font-weight: 600;
  color: var(--text);
}
.typing-indicator .typing-dots {
  display: inline-flex;
  align-items: center;
  gap: 3px;
}
.typing-indicator .typing-dots span {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--accent);
  animation: typingBounce 1.2s ease-in-out infinite;
}
.typing-indicator .typing-dots span:nth-child(2) { animation-delay: 0.15s; }
.typing-indicator .typing-dots span:nth-child(3) { animation-delay: 0.30s; }
@keyframes typingBounce {
  0%, 60%, 100% { transform: translateY(0); opacity: 0.4; }
  30%           { transform: translateY(-4px); opacity: 1; }
}

.link-preview {
  display: flex; align-items: stretch;
  margin-top: 10px; max-width: 460px;
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: 10px; overflow: hidden;
  text-decoration: none; color: inherit;
  transition: border-color 0.15s, background 0.15s;
  background: var(--bg3);
}
.link-preview:hover { border-color: var(--accent); background: var(--hover); }

.lp-img {
  width: 110px; min-height: 80px;
  object-fit: cover; flex-shrink: 0;
  border-right: 1px solid var(--border);
}
.lp-info {
  padding: 10px 12px;
  display: flex; flex-direction: column; gap: 3px;
  flex: 1; min-width: 0;
}
.lp-site { font-size: 10px; color: var(--accent); text-transform: uppercase; letter-spacing: 0.07em; font-weight: 700; }
.lp-title { font-size: 13px; font-weight: 600; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lp-desc { font-size: 12px; color: var(--text2); line-height: 1.4; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.lp-url { font-size: 11px; color: var(--muted); margin-top: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.link-preview-yt {
  display: block;
  border-left: 3px solid #ff0000;
  max-width: 480px; aspect-ratio: 16/9;
  padding: 0;
}
.link-preview-yt iframe { width: 100%; height: 100%; display: block; border: none; }

/* ── Share button states ── */
.btn-share { background: none; border: 1px solid var(--border); color: var(--text2); padding: 5px 10px; border-radius: 8px; font-size: 13px; cursor: pointer; transition: all 0.15s; }
.btn-share:hover { border-color: var(--accent); color: var(--accent); background: rgba(124,106,247,0.08); }
.btn-share-locked { opacity: 0.35; cursor: not-allowed !important; }
.btn-share-locked:hover { border-color: var(--border) !important; color: var(--text2) !important; background: none !important; }

/* ── Channel owner badge ── */
.channel-owner-badge {
  font-size: 13px;
  line-height: 1;
  flex-shrink: 0;
  filter: drop-shadow(0 0 4px rgba(245,197,24,0.55));
}
.chan-member-count {
  font-size: 11px; color: var(--muted);
  margin-left: auto; flex-shrink: 0;
  white-space: nowrap;
  display: inline-flex; align-items: center; gap: 3px;
}
/* Icône buste (à la place de l'emoji 👤) + nombre, alignés. */
.chan-member-count .members-chip-icon { width: 13px; height: 13px; flex-shrink: 0; }
.chan-member-count .cmc-n { font-variant-numeric: tabular-nums; }

/* ── Clickable member chip ── */
.ch-member-chip.clickable { cursor: pointer; }
.ch-member-chip.clickable:hover {
  border-color: var(--accent);
  background: rgba(124,106,247,0.12);
  transform: translateY(-1px);
  box-shadow: 0 2px 8px var(--accent-glow);
}
.ch-member-chip.clickable:hover .ch-chip-name { color: var(--accent); }

/* ── Responsive Sidebar ── */
@media (max-width: 700px) {
  /* Header DM mobile : gagne de la place en masquant le mot "Online"
     (on garde le point vert ● comme indicateur visuel) et le texte
     "Vérifier" (on garde 🔐). Demande user — ces éléments verbaux
     encombrent le header sur petits écrans sans apporter d'info critique. */
  .ch-dm-status-label { display: none; }
  .btn-verify-dm .btn-verify-dm-label { display: none; }
  .btn-verify-dm { padding: 4px 8px; }

  #sidebar {
    position: fixed; left: 0; top: 0; bottom: 0;
    transform: translateX(-100%);
    /* Tiroir mobile : s'adapte à la taille du téléphone (large mais jamais
       débordant), donne plus de place au contenu — demande user 2026-06-04. */
    width: min(88vw, 330px) !important; min-width: min(88vw, 330px) !important;
    transition: transform 0.3s cubic-bezier(0.4,0,0.2,1);
    border-right: 1px solid var(--border) !important;
    z-index: 10;
  }
  #sidebar.collapsed { transform: translateX(-100%); }
  #main-ui.sidebar-mobile-open #sidebar { transform: translateX(0); }
  #main-ui.sidebar-mobile-open #sidebar-backdrop { display: block; }
  #content { width: 100%; }

  /* Hamburger: inline in tab-bar on mobile */
  #btn-sidebar-toggle {
    position: static;
    background: transparent;
    border-radius: 8px;
    min-width: 40px; min-height: 40px;
    flex-shrink: 0;
  }
  /* Show close button inside sidebar on mobile */
  .btn-sidebar-close { display: flex; }
  /* Hide hamburger when sidebar is open (close btn takes over) */
  #main-ui.sidebar-mobile-open #btn-sidebar-toggle { opacity: 0; pointer-events: none; }
  #tab-bar { padding-left: 4px; height: 40px; min-height: 40px; }
  /* Brand richesse (icône+texte gradient) remplace l'ancien logo img sur mobile. */
  .tabbar-brand { display: inline-flex; order: 0; }
  #btn-sidebar-toggle { order: 1; }
  .tabbar-logo { display: none; }

  /* Modals: slide up from bottom */
  #modal-overlay { align-items: flex-end; padding: 0; }
  .modal {
    max-width: 100% !important; width: 100%;
    border-radius: var(--radius-xl) var(--radius-xl) 0 0;
    max-height: 92vh; overflow-y: auto;
    padding: 20px 16px 32px;
  }

  /* Channel header: compact */
  .ch-channel { padding: 6px 12px; flex-wrap: wrap; gap: 4px; }
  .ch-wall { padding: 6px 12px; }
  .ch-dm { padding: 6px 12px; }
  .ch-channel-name { font-size: 13px; }
  .ch-dm-name { font-size: 13px; }
  .btn-leave, .btn-del-chan { padding: 4px 10px; font-size: 11px; min-height: 32px; }

  /* Composer — compact new layout */
  #composer { padding: 6px 10px 8px; }
  .composer-toolbar { margin-bottom: 5px; gap: 4px; }
  .expiry-btn { padding: 3px 8px; font-size: 10px; min-height: 28px; }
  .btn-attach { min-width: 36px; min-height: 36px; font-size: 17px; padding: 2px; }
  .composer-main { padding: 6px 6px 6px 10px; gap: 4px; }
  #btn-send { min-width: 38px; min-height: 38px; width: 38px; height: 38px; }
  #message-input { font-size: 16px; padding: 4px 2px; max-height: 80px; }

  /* Message cards */
  .msg-card { padding: 8px 10px; margin: 2px 6px; }
  .msg-author { font-size: 12px; }
  .msg-time { font-size: 10px; }
  .msg-text { font-size: 14px; line-height: 1.45; }

  /* Sidebar items — bigger tap targets */
  .channel-item { min-height: 40px; padding: 8px 10px; font-size: 13px; }
  .ch-sidebar-member { min-height: 38px; padding: 5px 8px; }
  .tab { padding: 5px 10px; font-size: 12px; min-height: 32px; }
  .tab-close { opacity: 1; min-width: 24px; min-height: 24px; font-size: 14px; }

  /* DM rows */
  .dm-row { padding: 8px 10px; }
  .dm-bubble { font-size: 14px; padding: 10px 13px; }

  /* Profile in sidebar */
  .sidebar-profile { padding: 10px 12px; min-height: 56px; }

  /* Call panel */
  #call-panel { height: 260px; }

  /* Incoming call: full width at top */
  #incoming-call { top: 8px; right: 8px; left: 8px; min-width: unset; }

  /* Group call banner */
  #group-call-banner { flex-direction: column; align-items: flex-start; gap: 6px; margin: 6px 8px 0; }

  /* Prevent horizontal overflow */
  body { overflow-x: hidden; }
}

/* ── Very small screens (≤ 400px) ── */
@media (max-width: 400px) {
  :root { --sidebar: 240px; }

  .modal { padding: 16px 12px 28px; }
  .modal-title { font-size: 16px; }
  .msg-card { margin: 2px 4px; }
  #call-panel { height: 200px; }
  .btn-group-call-video, .btn-group-call-audio { font-size: 14px; padding: 3px 6px; }
  .expiry-btn { padding: 3px 7px; font-size: 10px; }
  .call-panel-actions { gap: 4px; }
  .call-panel-btn { padding: 0 8px; font-size: 11px; }
}

/* ── Call overlay ── */
/* ── Call panel (embedded in content) ── */
#call-panel {
  flex-shrink: 0;
  display: flex; flex-direction: column;
  height: 500px; min-height: 44px; max-height: 85vh;
  border-bottom: 1px solid rgba(255,255,255,0.08);
  background: #0d0d14;
  position: relative;
  /* no transition during resize, only for minimize */
}
#call-panel.animating { transition: height 0.25s ease; }
#call-panel.hidden { display: none !important; }
#call-panel.minimized { height: 44px; }
#call-panel.minimized #jitsi-container { display: none; }
#call-panel.minimized #call-resize-handle { display: none; }

/* Floating mode : panel détaché du flow, draggable via la barre.
   Position initiale + bornes gérées en JS (call-1to1.js _initCallDetach). */
#call-panel.floating {
  position: fixed !important;
  width: 360px;
  height: 240px !important;
  max-height: 80vh;
  border-radius: 12px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  box-shadow: 0 20px 60px -10px rgba(0, 0, 0, 0.6);
  z-index: 1500;
  overflow: hidden;
}
#call-panel.floating #call-panel-bar {
  cursor: grab;
  user-select: none;
  -webkit-user-select: none;
}
#call-panel.floating #call-panel-bar:active { cursor: grabbing; }
#call-panel.floating #call-resize-handle { display: none; }

/* Plein écran 1-to-1 (parité avec le gc-size du groupe) : overlay viewport. */
#call-panel.call-fullscreen {
  position: fixed !important; inset: 0 !important;
  width: 100% !important; height: 100vh !important; max-height: none !important;
  z-index: 2000; border-radius: 0; border: none;
}
#call-panel.call-fullscreen #call-resize-handle { display: none; }

/* Boutons call-panel toggles : visuel disabled + active. */
.call-panel-btn.disabled {
  background: rgba(232, 70, 70, 0.20);
  border-color: rgba(232, 70, 70, 0.45);
}
.call-panel-btn.active {
  background: rgba(60, 200, 120, 0.30);
  border-color: rgba(60, 200, 120, 0.55);
}
@media (max-width: 700px) {
  #call-panel.floating {
    width: calc(100vw - 24px) !important;
    left: 12px !important;
  }
}

/* Audio call mode: stays collapsed, bar has a live indicator */
#call-panel.audio-mode #call-panel-bar { background: rgba(30,15,60,0.95); border-bottom: 2px solid var(--accent); }
#call-panel.audio-mode #call-status::before {
  content: '●';
  color: #48bb78;
  margin-right: 5px;
  animation: audio-pulse 1.2s ease-in-out infinite;
}
@keyframes audio-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.25; }
}
#call-resize-handle {
  position: absolute; bottom: 0; left: 0; right: 0;
  height: 9px; cursor: ns-resize;
  background: transparent;
  z-index: 10;
  display: flex; align-items: center; justify-content: center;
}
/* Petite barre VISIBLE → indique clairement que la bande est draguable. */
#call-resize-handle::before {
  content: ''; width: 46px; height: 3px; border-radius: 3px;
  background: rgba(255,255,255,0.5);
  transition: width 0.12s, background 0.12s, opacity 0.12s;
}
#call-resize-handle:hover::before, #call-resize-handle.dragging::before {
  width: 64px; background: rgba(99,179,237,0.95);
}
#call-panel-bar {
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 12px; height: 44px; flex-shrink: 0;
  background: rgba(0,0,0,0.6); gap: 12px;
}
#call-info {
  display: flex; align-items: center; gap: 10px; color: white; min-width: 0; flex: 1;
}
#call-peer-name { font-size: 14px; font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#call-status { font-size: 12px; color: rgba(255,255,255,0.55); }
#call-duration { font-size: 12px; color: rgba(255,255,255,0.45); font-variant-numeric: tabular-nums; }
/* P2.8 — pastille bouclier de vérification dans le panneau d'appel. */
.call-verify-badge {
  flex-shrink: 0; border: 0; cursor: pointer; padding: 0 2px;
  line-height: 0; background: transparent;
  color: currentColor; opacity: 0.6;
  transition: opacity 0.12s, color 0.12s, transform 0.08s;
  display: inline-flex; align-items: center;
}
.call-verify-badge svg { width: 15px; height: 15px; display: block; }
.call-verify-badge.verified { color: #4ade80; opacity: 1; }   /* vérifié = bouclier vert */
.call-verify-badge.unverified { opacity: 0.55; }
.call-verify-badge:hover { transform: scale(1.12); opacity: 1; }
.call-verify-badge:active { transform: scale(0.95); }
/* Bannière « non vérifié » sous la barre d'appel. */
#call-verify-banner {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 6px 12px; font-size: 11.5px; line-height: 1.35;
  background: rgba(245, 197, 24, 0.14); color: #d4a700;
  border-bottom: 1px solid rgba(245, 197, 24, 0.28);
}
#call-verify-banner.hidden { display: none; }
.call-verify-link {
  border: 1px solid currentColor; background: transparent; color: inherit;
  border-radius: 999px; padding: 2px 9px; font-size: 11px; cursor: pointer;
  white-space: nowrap; transition: background 0.12s;
}
.call-verify-link:hover { background: rgba(245, 197, 24, 0.18); }
.call-panel-actions { display: flex; gap: 8px; align-items: center; flex-shrink: 0; }
.call-panel-btn {
  height: 32px; border-radius: 16px; padding: 0 12px;
  border: none; cursor: pointer; font-size: 12px; font-weight: 600;
  display: flex; align-items: center; gap: 5px;
  background: rgba(255,255,255,0.12); color: white;
  transition: all 0.2s; white-space: nowrap;
}
.call-panel-btn:hover { background: rgba(255,255,255,0.22); }
.call-panel-btn svg { width: 20px; height: 20px; display: block; }
[data-theme="big"] .call-panel-btn svg { width: 24px; height: 24px; }
.call-panel-btn.danger { background: #e53e3e; color: #fff; }
.call-panel-btn.danger:hover { background: #c53030; }
/* Hangup = "téléphone fixe posé" → SVG phone tilté 135° (raccrochage). */
.btn-hangup svg {
  transform: rotate(135deg);
  transition: transform 120ms ease;
}
.btn-hangup:hover svg { transform: rotate(135deg) scale(1.08); }
#jitsi-container { flex: 1; width: 100%; min-height: 0; }
#jitsi-container iframe { width: 100%; height: 100%; border: none; }

/* Call 1-to-1 WebRTC natif — MÊME STYLE que l'appel de groupe : tuiles égales
   .gc-tile (remote + local) en grille, badge nom, halo « parle », 📷 si pas de
   vidéo, tuile masquée en audio (gc-novideo) + indice audio. Piloté par
   data-mode="1to1" sur #call-panel. */
#call-1to1-container { display: none; position: relative; flex: 1; width: 100%; min-height: 0; background: transparent; overflow: hidden; }
#call-panel[data-mode="1to1"] #jitsi-container { display: none; }
#call-panel[data-mode="1to1"] #call-1to1-container { display: block; }
#call-panel[data-mode="1to1"].minimized #call-1to1-container { display: none; }
/* Tuiles dimensionnées par la HAUTEUR (comme la bande compacte du groupe) → quand
   on réduit le panneau (drag du resize), les vidéos rétrécissent vraiment au lieu
   de rester larges (avant : grille 2×1fr → taille pilotée par la largeur, donc
   « trop grandes » en panneau court). flex-shrink autorisé → 2 tuiles s'ajustent. */
#call-1to1-grid {
  height: 100%; min-height: 0;
  display: flex; flex-direction: row; flex-wrap: nowrap;
  align-items: center; justify-content: center;
  gap: 8px; padding: 8px;
  overflow: hidden;
}
/* Tuile — copie fidèle de .groupcall-panel .gc-tile, mais height-driven. */
#call-1to1-container .gc-tile {
  position: relative; background: #11151c; border-radius: 12px;
  overflow: hidden;
  flex: 0 1 auto; height: 100%; width: auto; max-width: 100%;
  aspect-ratio: 16 / 10;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid rgba(255, 255, 255, 0.06);
  transition: box-shadow 0.12s ease, border-color 0.12s ease;
}
#call-1to1-container .gc-tile.gc-local { border-color: var(--accent, #5b8cff); }
#call-1to1-container .gc-tile video { width: 100%; height: 100%; object-fit: cover; background: #11151c; display: block; }
#call-1to1-container .gc-tile.gc-speaking {
  border-color: #4ade80;
  box-shadow: 0 0 0 3px #4ade80, 0 0 18px 2px rgba(74, 222, 128, 0.55);
}
#call-1to1-container .gc-name {
  position: absolute; left: 8px; bottom: 8px;
  padding: 2px 8px; border-radius: 8px;
  background: rgba(0, 0, 0, 0.55); color: #fff;
  font-size: 12px; font-weight: 600; max-width: 80%;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
#call-1to1-container .gc-speak-dot {
  position: absolute; top: 8px; right: 8px;
  font-size: 13px; opacity: 0; transition: opacity 0.12s;
  filter: drop-shadow(0 0 4px rgba(74, 222, 128, 0.9));
}
#call-1to1-container .gc-tile.gc-speaking .gc-speak-dot { opacity: 1; }
/* Tuile sans vidéo (audio / cam coupée) → masquée, comme le groupe. */
#call-1to1-container .gc-tile.gc-novideo { display: none !important; }
/* Indice « audio seul » centré quand aucune vidéo n'est visible. */
#call-1to1-container .gc-audio-hint { display: none; }
#call-1to1-container.gc-audio-only .gc-audio-hint {
  display: flex; align-items: center; justify-content: center;
  grid-column: 1 / -1; min-height: 60px;
  color: var(--muted, #9aa); font-size: 13px; font-weight: 600;
  letter-spacing: 0.02em; opacity: 0.85;
}

/* ── Appel 1-to-1 : MÊME DISPOSITION que l'appel de groupe (cf. capture) ──────
   Plus de barre solide en haut : l'info du pair FLOTTE en haut-gauche (pilule)
   et les contrôles FLOTTENT en pilule bas-centre, superposés aux tuiles — comme
   .gc-channel / .gc-bar du groupe. La barre devient un overlay click-through
   (les clics passent vers la vidéo pour le pointeur ; seuls label + contrôles
   sont interactifs). */
#call-panel[data-mode="1to1"] #call-panel-bar {
  position: absolute; inset: 0; z-index: 6;
  display: block; height: auto; padding: 0; gap: 0;
  background: transparent; border: none; box-shadow: none;
  pointer-events: none;
}
#call-panel[data-mode="1to1"] #call-info {
  position: absolute; top: 8px; left: 10px; z-index: 4;
  flex: 0 0 auto; min-width: 0; max-width: 60%;
  display: flex; align-items: center; gap: 7px; pointer-events: auto;
  padding: 4px 10px; border-radius: 16px; cursor: grab;
  background: rgba(0, 0, 0, 0.45); color: #fff;
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
}
#call-panel[data-mode="1to1"] #call-peer-name { font-size: 12px; }
#call-panel[data-mode="1to1"] #call-status,
#call-panel[data-mode="1to1"] #call-duration { font-size: 11px; }
/* Contrôles flottants bas-centre (pilule translucide, façon .gc-bar). */
#call-panel[data-mode="1to1"] .call-panel-actions {
  position: absolute; bottom: 12px; left: 50%; transform: translateX(-50%);
  z-index: 6; pointer-events: auto;
  display: flex; flex-wrap: nowrap; justify-content: center; align-items: center;
  gap: 8px; padding: 6px 10px;
  background: rgba(0, 0, 0, 0.5); border-radius: 26px;
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.35);
  max-width: calc(100% - 24px); overflow-x: auto;
}
/* Boutons ronds translucides (façon .gc-btn). */
#call-panel[data-mode="1to1"] .call-panel-btn {
  width: 40px; height: 40px; padding: 0; border-radius: 50%;
  font-size: 16px; gap: 0; justify-content: center; flex: 0 0 auto;
  background: rgba(255, 255, 255, 0.16); color: #fff;
}
#call-panel[data-mode="1to1"] .call-panel-btn:hover { background: rgba(255, 255, 255, 0.28); }
#call-panel[data-mode="1to1"] .call-panel-btn.active { background: var(--accent, #5b8cff); color: #fff; }
#call-panel[data-mode="1to1"] .call-panel-btn.danger { background: #c0392b; color: #fff; }
#call-panel[data-mode="1to1"] .call-panel-btn.danger:hover { background: #d6442f; }
/* Bannière « non vérifié » → overlay sous l'info (ne pousse plus la mise en page). */
#call-panel[data-mode="1to1"] #call-verify-banner {
  position: absolute; top: 46px; left: 10px; right: 10px; z-index: 5;
  border-radius: 10px; border: 1px solid rgba(245, 197, 24, 0.28);
  pointer-events: auto;
}
/* Minimisé (appel audio compact) : pilule de contrôles centrée verticalement. */
#call-panel[data-mode="1to1"].minimized .call-panel-actions {
  bottom: auto; top: 50%; transform: translate(-50%, -50%);
}
/* ── Appel AUDIO 1-to-1 (aucune vidéo live) → barre ULTRA-FINE ─────────────────
   Pas de zone vidéo vide : le panneau se réduit à un bandeau d'~56px avec le nom
   du pair à gauche et les contrôles en ligne à droite. Piloté par
   _refreshCallTiles (visible===0). S'agrandit automatiquement à l'escalade vidéo
   (la classe est retirée dès qu'une tuile porte une vidéo live). */
#call-panel[data-mode="1to1"].call-audio-compact {
  height: 56px !important; min-height: 56px; max-height: 56px;
}
#call-panel[data-mode="1to1"].call-audio-compact #call-1to1-container { display: none !important; }
#call-panel[data-mode="1to1"].call-audio-compact #call-resize-handle { display: none; }
#call-panel[data-mode="1to1"].call-audio-compact #call-verify-banner { display: none !important; }
/* La barre redevient un vrai bandeau EN LIGNE (plus d'overlay inset:0). */
#call-panel[data-mode="1to1"].call-audio-compact #call-panel-bar {
  position: static; inset: auto; height: 56px; padding: 0 14px;
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  background: rgba(20,12,40,0.96); border-bottom: 2px solid var(--accent);
  pointer-events: auto;
}
#call-panel[data-mode="1to1"].call-audio-compact #call-info {
  position: static; inset: auto; flex: 1; min-width: 0; max-width: none;
  padding: 0; border-radius: 0; cursor: default;
  background: transparent; backdrop-filter: none; -webkit-backdrop-filter: none;
}
#call-panel[data-mode="1to1"].call-audio-compact .call-panel-actions {
  position: static; inset: auto; transform: none;
  padding: 0; gap: 6px; overflow: visible;
  background: transparent; box-shadow: none;
  backdrop-filter: none; -webkit-backdrop-filter: none;
}
#call-panel[data-mode="1to1"].call-audio-compact .call-panel-btn {
  width: 34px; height: 34px; font-size: 14px;
}
/* ── Thème paper : la barre d'appel 1-to-1 suit le template clair (parité avec
   le panneau de groupe, cf. [data-theme="paper"] .groupcall-panel). Le conteneur
   + le bandeau audio-compact passent en surface claire avec textes encre. Les
   pilules flottantes SUR la vidéo restent sombres translucides (lisibilité par
   dessus la vidéo), exactement comme .gc-bar du groupe → on ne les touche pas. */
[data-theme="paper"] #call-panel {
  background: var(--bg2);
  border-bottom-color: var(--border);
}
[data-theme="paper"] #call-panel[data-mode="1to1"].call-audio-compact #call-panel-bar {
  background: var(--bg2);
  border-bottom: 2px solid var(--accent);
}
[data-theme="paper"] #call-panel[data-mode="1to1"].call-audio-compact #call-info,
[data-theme="paper"] #call-panel[data-mode="1to1"].call-audio-compact #call-peer-name {
  color: var(--text);
}
[data-theme="paper"] #call-panel[data-mode="1to1"].call-audio-compact #call-status,
[data-theme="paper"] #call-panel[data-mode="1to1"].call-audio-compact #call-duration {
  color: var(--text2);
}
[data-theme="paper"] #call-panel[data-mode="1to1"].call-audio-compact .call-panel-btn {
  background: rgba(42, 26, 20, 0.10); color: var(--text);
}
[data-theme="paper"] #call-panel[data-mode="1to1"].call-audio-compact .call-panel-btn:hover {
  background: rgba(42, 26, 20, 0.18);
}
[data-theme="paper"] #call-panel[data-mode="1to1"].call-audio-compact .call-panel-btn.active {
  background: var(--accent); color: #fff;
}
[data-theme="paper"] #call-panel[data-mode="1to1"].call-audio-compact .call-panel-btn.danger {
  background: var(--red); color: #fff;
}
/* In-call modal buttons (Accept/Reject) — scoped à #incoming-call pour ne
   pas entrer en collision avec les .call-btn du header de canal/DM (qui
   utilisent le style design system v2 — pill verte, cf. règles plus haut). */
#incoming-call .call-btn {
  height: 38px; border-radius: 20px; padding: 0 16px;
  border: none; cursor: pointer; font-size: 14px; font-weight: 600;
  display: flex; align-items: center; gap: 6px;
  background: rgba(255,255,255,0.15); color: white;
  transition: all 0.2s; flex-shrink: 0; white-space: nowrap;
}
#incoming-call .call-btn:hover { background: rgba(255,255,255,0.25); transform: scale(1.08); }
#incoming-call .call-btn.danger { background: #e53e3e; }
#incoming-call .call-btn.danger:hover { background: #c53030; }
#incoming-call .call-btn.accept { background: #38a169; width: auto; border-radius: 24px; padding: 0 18px; font-size: 14px; font-weight: 600; height: 44px; }
#incoming-call .call-btn.accept:hover { background: #2f855a; }
#incoming-call .call-btn.off { background: rgba(255,100,100,0.3); }

/* ── Incoming call panel ── */
#incoming-call {
  position: fixed; top: 20px; right: 20px; z-index: 1100;
  background: var(--bg2, #1a1a2e); border: 1px solid rgba(255,255,255,0.15);
  border-radius: 16px; padding: 20px;
  display: flex; flex-direction: column; align-items: center; gap: 12px;
  min-width: 220px; box-shadow: 0 8px 40px rgba(0,0,0,0.5);
  animation: slideInRight 0.3s ease;
}
#incoming-call.hidden { display: none !important; }
@keyframes slideInRight { from { transform: translateX(120%); opacity: 0; } to { transform: translateX(0); opacity: 1; } }
#incoming-name { font-size: 17px; font-weight: 700; color: var(--text, white); }
#incoming-type { font-size: 12px; color: var(--muted, #aaa); }
#incoming-actions { display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; }

/* ── DM call buttons ──
   Hérite du style green .call-btn (déclaré L265) — pas d'override du
   background/color/border. On garde juste la taille SVG. */
.btn-call-video svg, .btn-call-audio svg { width: 16px; height: 16px; }

/* Boutons appel/vidéo de GROUPE = VERTS comme le 1-to-1 (demande user v433).
   Avant : lilas (rgba 124,106,247). Aligné sur .call-btn (Skype-tier green). */
.btn-group-call-video, .btn-group-call-audio {
  background: rgba(22, 168, 95, 0.10); border: 1px solid rgba(22, 168, 95, 0.22);
  cursor: pointer; font-size: 16px; padding: 4px 8px; border-radius: 8px;
  transition: background 0.15s, color 0.15s, border-color 0.15s; color: #0C7A41; margin-left: 4px;
}
.btn-group-call-video:hover, .btn-group-call-audio:hover {
  background: #16A85F; color: #fff; border-color: #16A85F;
}

#group-call-banner {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  background: linear-gradient(90deg, rgba(72,187,120,0.15), rgba(72,187,120,0.08));
  border: 1px solid rgba(72,187,120,0.35); border-radius: 8px;
  margin: 6px 16px 0; padding: 8px 14px; font-size: 13px;
}
#group-call-banner strong { color: var(--text); }
.btn-join-group-call {
  background: #48bb78; color: #fff; border: none; border-radius: 6px;
  padding: 5px 14px; font-size: 12px; font-weight: 600; cursor: pointer;
  transition: background 0.15s; white-space: nowrap;
}
.btn-join-group-call:hover { background: #38a169; }

/* ── Channel iframe embed ── */
.btn-iframe-toggle {
  display: inline-flex; align-items: center; gap: 6px;
  margin-top: 8px; padding: 5px 12px;
  background: var(--bg3, rgba(255,255,255,0.07)); border: 1px solid var(--border, rgba(255,255,255,0.12));
  border-radius: 8px; cursor: pointer; font-size: 12px; color: var(--text2, #aaa);
  transition: background 0.15s, color 0.15s;
}
.btn-iframe-toggle:hover { background: var(--hover); color: var(--text); }
.msg-iframe-wrap { margin-top: 8px; border-radius: 10px; overflow: hidden; border: 1px solid var(--border, rgba(255,255,255,0.12)); }
.msg-iframe-wrap.hidden { display: none; }
.msg-iframe { width: 100%; height: 480px; border: none; display: block; background: #fff; }

/* ── DM bubble reaction button ── */
.dm-bubble-wrap {
  position: relative; display: inline-flex; align-items: flex-end; gap: 4px;
  max-width: 100%;
}
.btn-dm-react {
  background: none; border: none; cursor: pointer;
  font-size: 14px; padding: 2px 3px; border-radius: 6px;
  color: var(--muted); opacity: 0; flex-shrink: 0;
  transition: opacity 0.15s, background 0.15s; line-height: 1;
  align-self: center;
}
.dm-row:hover .btn-dm-react { opacity: 1; }
.btn-dm-react:hover { background: var(--hover); }
.dm-reactions {
  display: flex; flex-wrap: wrap; gap: 3px; margin-top: 4px;
}
.dm-reactions .reaction-chip { font-size: 12px; padding: 1px 6px; }

/* ── Composer Emoji Picker ── */
.composer-emoji-picker {
  position: fixed; z-index: 1050;
  background: var(--bg2); border: 1px solid var(--border2);
  border-radius: 14px; box-shadow: 0 12px 40px rgba(0,0,0,0.55);
  width: 310px; overflow: hidden;
  animation: fadeIn 0.12s ease;
}
.cep-tabs {
  display: flex; gap: 2px; padding: 8px 8px 0;
  border-bottom: 1px solid var(--border);
  overflow-x: auto; flex-shrink: 0;
}
.cep-tabs::-webkit-scrollbar { height: 2px; }
.cep-tab {
  background: none; border: none; cursor: pointer;
  font-size: 18px; padding: 5px 7px; border-radius: 8px 8px 0 0;
  transition: background 0.1s; flex-shrink: 0; line-height: 1;
}
.cep-tab:hover { background: var(--hover); }
.cep-tab.active { background: var(--bg3); border-bottom: 2px solid var(--accent); }
.cep-body { padding: 6px; max-height: 200px; overflow-y: auto; }
.cep-cat { display: flex; flex-wrap: wrap; gap: 1px; }
.cep-emoji {
  background: none; border: none; cursor: pointer;
  font-size: 20px; padding: 4px 5px; border-radius: 6px;
  transition: background 0.1s, transform 0.1s; line-height: 1.2;
}
.cep-emoji:hover { background: var(--hover); transform: scale(1.2); }

/* ── Stickers Picker (animated Lottie + WebP) ── */
.sp-panel {
  background: var(--bg2); border: 1px solid var(--border2);
  border-radius: 14px; box-shadow: 0 12px 40px rgba(0,0,0,0.55);
  width: 100%; max-width: 360px; overflow: hidden;
  animation: fadeIn 0.12s ease;
}
.sp-panel.docked {
  margin: 0 auto 6px; /* dock au-dessus du composer */
}
.sp-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 6px 8px 0; border-bottom: 1px solid var(--border);
}
.sp-tabs {
  display: flex; gap: 2px; overflow-x: auto; flex: 1;
}
.sp-tabs::-webkit-scrollbar { height: 2px; }
.sp-tab {
  background: none; border: none; cursor: pointer;
  font-size: 18px; padding: 5px 8px; border-radius: 8px 8px 0 0;
  transition: background 0.1s; flex-shrink: 0; line-height: 1;
}
.sp-tab:hover { background: var(--hover); }
.sp-tab.active { background: var(--bg3); border-bottom: 2px solid var(--accent); }
.sp-close {
  background: none; border: none; cursor: pointer;
  color: var(--muted); font-size: 16px; padding: 4px 8px;
  border-radius: 6px; line-height: 1;
}
.sp-close:hover { background: var(--hover); color: var(--text); }
.sp-grid {
  padding: 8px;
  max-height: 240px; overflow-y: auto;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(72px, 1fr)); gap: 6px;
}
.sp-tile {
  background: var(--bg3); border: 1px solid transparent;
  border-radius: 10px; cursor: pointer; padding: 4px;
  aspect-ratio: 1 / 1;
  display: flex; align-items: center; justify-content: center;
  transition: border-color 0.1s, transform 0.1s;
}
.sp-tile:hover { border-color: var(--accent); transform: scale(1.05); }
.sp-tile-inner {
  width: 100%; height: 100%;
  display: flex; align-items: center; justify-content: center;
}
.sp-tile-inner img { max-width: 100%; max-height: 100%; object-fit: contain; }
.sp-tile-inner svg { width: 100%; height: 100%; }
.sp-loading, .sp-empty, .sp-error {
  grid-column: 1 / -1;
  text-align: center; padding: 18px;
  color: var(--muted); font-size: 13px;
}
.sp-error { color: #e57373; }

/* ── Picker emoji : barre de mode Emoji | Stickers (v420.1) + volet stickers ── */
.cep-modebar { display: flex; gap: 4px; padding: 8px 8px 0; }
.cep-mode {
  flex: 1; background: var(--bg3); border: 1px solid var(--border);
  color: var(--text2); font-size: 12px; font-weight: 600;
  padding: 6px 8px; border-radius: 9px; cursor: pointer;
  transition: all 0.12s;
}
.cep-mode:hover { color: var(--accent); border-color: var(--accent); }
.cep-mode.active { background: rgba(124,106,247,0.16); color: var(--accent); border-color: var(--accent); }
.composer-emoji-picker.cep-on-stickers .cep-body { max-height: none; padding: 0; overflow: visible; }
.cep-cat.cep-stickers:not(.hidden) { display: block; }
.cep-cat.cep-stickers .sp-tabs { padding: 6px 6px 0; border-bottom: 1px solid var(--border); }
.cep-cat.cep-stickers .sp-grid { max-height: 220px; grid-template-columns: repeat(auto-fill, minmax(62px, 1fr)); }

/* Sticker dans la bulle de message (Lottie animé)
   Style Telegram/Signal : pas de bulle autour, juste le sticker qui flotte.
   On retire bg/padding/border/shadow sur le wrapper bubble quand il contient un sticker. */
.msg-lottie {
  width: 160px; height: 160px;
  display: block;
  pointer-events: none; /* clics passent aux boutons reply/del derrière */
}
.msg-lottie svg { width: 100% !important; height: 100% !important; display: block; }
.msg-lottie-err {
  color: var(--muted); font-size: 13px; font-style: italic;
  padding: 8px;
}
/* DM bubble : transparente quand sticker dedans (pas de :has fallback pour vieux navigateurs : on tag aussi la bubble via JS si besoin) */
.dm-bubble:has(.msg-lottie),
.msg-card .msg-content:has(.msg-lottie),
.msg-card:has(.msg-lottie) .msg-content {
  background: transparent !important;
  border: none !important;
  box-shadow: none !important;
  padding: 0 !important;
}
/* Wrapper de la bubble : on enlève juste le bg, on laisse le layout */
.dm-bubble-wrap:has(.msg-lottie) .dm-bubble {
  background: transparent !important;
  border: none !important;
  box-shadow: none !important;
  padding: 0 !important;
}

/* ── Credentials management ── */
.cred-row { transition: background 0.15s; }
.cred-row:hover { background: var(--hover) !important; }

/* ── Emoji Reactions ── */
.msg-reactions {
  display: flex; flex-wrap: wrap; gap: 4px;
  margin-top: 6px; min-height: 0;
}
.reaction-chip {
  display: inline-flex; align-items: center; gap: 4px;
  background: var(--bg3); border: 1px solid var(--border);
  border-radius: 12px; padding: 2px 8px;
  font-size: 13px; cursor: pointer; color: var(--text2);
  transition: all 0.15s; line-height: 1.4;
}
.reaction-chip:hover { border-color: var(--accent); background: var(--hover); }
.reaction-chip.mine {
  background: rgba(124,106,247,0.15);
  border-color: rgba(124,106,247,0.5);
  color: var(--accent);
}
.reaction-chip span { font-size: 11px; font-weight: 600; }
.btn-react {
  background: none; border: none; cursor: pointer;
  font-size: 15px; padding: 2px 4px; border-radius: 6px;
  color: var(--muted); opacity: 0;
  transition: opacity 0.15s, background 0.15s;
  line-height: 1;
}
.msg-card:hover .btn-react { opacity: 1; }
.btn-react:hover { background: var(--hover); }
.reaction-picker {
  background: var(--bg2); border: 1px solid var(--border2);
  border-radius: 12px; padding: 6px 8px;
  display: flex; gap: 4px; z-index: 500;
  box-shadow: 0 8px 32px rgba(0,0,0,0.5);
  animation: fadeIn 0.1s ease;
}
.reaction-picker button {
  background: none; border: none; cursor: pointer;
  font-size: 22px; padding: 4px 6px; border-radius: 8px;
  transition: background 0.1s, transform 0.1s; line-height: 1;
}
.reaction-picker button:hover {
  background: var(--hover); transform: scale(1.25);
}

/* a11y — masque visuellement mais garde accessible aux lecteurs d'écran */
.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0);
  white-space: nowrap; border: 0;
}

/* ──────────────────────────────────────────────────────────────────────────
   Utility classes — Phase 6 CSP hardening (2026-05-24)
   Remplacent les style="..." inline pour permettre de retirer
   'unsafe-inline' du Content-Security-Policy style-src. Inspirées Tailwind
   mais ad-hoc — uniquement les patterns réellement utilisés dans le code.
   ──────────────────────────────────────────────────────────────────────── */

/* — Margin / padding */
.u-m-0  { margin: 0; }
.u-mt-1 { margin-top: 4px; }
.u-mt-2 { margin-top: 8px; }
.u-mt-3 { margin-top: 10px; }
.u-mt-4 { margin-top: 12px; }
.u-mt-5 { margin-top: 14px; }
.u-mt-6 { margin-top: 16px; }
.u-mb-2 { margin-bottom: 8px; }
.u-mb-3 { margin-bottom: 10px; }
.u-mb-4 { margin-bottom: 12px; }
.u-mb-6 { margin-bottom: 16px; }
.u-ml-1 { margin-left: 4px; }
.u-p-2  { padding: 8px; }
.u-p-3  { padding: 10px; }
.u-p-4  { padding: 14px; }
.u-py-2 { padding-top: 8px; padding-bottom: 8px; }
.u-px-3 { padding-left: 10px; padding-right: 10px; }

/* — Flex */
.u-flex            { display: flex; }
.u-flex-col        { display: flex; flex-direction: column; }
.u-flex-row        { display: flex; flex-direction: row; }
.u-flex-1          { flex: 1; }
.u-flex-row-center { display: flex; flex-direction: row; align-items: center; gap: 10px; }
.u-items-center    { align-items: center; }
.u-items-start     { align-items: flex-start; }
.u-justify-end     { justify-content: flex-end; }
.u-justify-between { justify-content: space-between; }
.u-justify-start   { justify-content: flex-start; }
.u-gap-1 { gap: 4px; }
.u-gap-2 { gap: 6px; }
.u-gap-3 { gap: 8px; }
.u-gap-4 { gap: 10px; }
.u-gap-5 { gap: 12px; }
.u-grow  { flex: 1; }
.u-shrink-0 { flex-shrink: 0; }
.u-text-left { text-align: left; }
.u-text-center { text-align: center; }

/* — Typo */
.u-text-xs   { font-size: 11px; }
.u-text-sm   { font-size: 12px; }
.u-text-md   { font-size: 13px; }
.u-text-base { font-size: 14px; }
.u-font-mono   { font-family: 'JetBrains Mono', monospace; }
.u-font-bold   { font-weight: 600; }
.u-font-medium { font-weight: 500; }
.u-leading-relaxed { line-height: 1.5; }
.u-leading-loose   { line-height: 1.6; }
.u-leading-tight   { line-height: 1.4; }

/* — Couleurs (utilisent les CSS vars du thème courant) */
.u-text-muted   { color: var(--muted, #888); }
.u-text-accent  { color: var(--accent, #7c3aed); }
.u-text-text2   { color: var(--text2, #a9b3c2); }
.u-text-text3   { color: var(--text3, #888); }
.u-text-rust    { color: var(--rust-1, #8A2E25); }
.u-text-gold    { color: var(--gold, #b89aff); }
.u-text-success { color: #4d9c5e; }
.u-text-warn    { color: #ffb340; }
.u-text-danger  { color: #d9534f; }

/* — Background / borders */
.u-bg-bg2 { background: var(--bg2, rgba(255,255,255,.02)); }
.u-bg-bg3 { background: var(--bg3, rgba(255,255,255,.05)); }
.u-border-hairline { border: 1px solid var(--hairline, rgba(255,255,255,.1)); }
.u-rounded   { border-radius: 4px; }
.u-rounded-md { border-radius: 6px; }
.u-rounded-lg { border-radius: 8px; }

/* — Cursor / interactions */
.u-cursor-pointer      { cursor: pointer; }
.u-cursor-not-allowed  { cursor: not-allowed; }
.u-no-select           { user-select: none; }
.u-select-all          { user-select: all; }

/* — Opacity */
.u-op-40 { opacity: 0.4; }
.u-op-60 { opacity: 0.6; }
.u-op-80 { opacity: 0.8; }

/* — Dimensions */
.u-w-full  { width: 100%; }
.u-h-full  { height: 100%; }
.u-min-w-0 { min-width: 0; }
.u-max-w-200 { max-width: 200px; }

/* — Patterns spécifiques observés en JS */
.u-checkbox-accent { width: 16px; height: 16px; accent-color: var(--accent); }
.u-link-clean { text-decoration: none; display: inline-flex; align-items: center; justify-content: center; }
.u-word-break { word-break: break-word; }
.u-hidden { display: none; }
.u-visible { display: ''; } /* placeholder pour cohérence — préférer retrait de .u-hidden */

/* — Widths et tailles spécifiques observés */
.u-w-28 { width: 28px; }
.u-w-30 { width: 30px; }
.u-w-80 { width: 80px; }
.u-w-100 { width: 100px; }
.u-w-110 { width: 110px; }
.u-w-140 { width: 140px; }

/* — Padding/margin shorthand spécifiques */
.u-p-4-wide { padding: 14px; }
.u-py-2-px-3 { padding: 8px 10px; }
.u-ml-1 { margin-left: 4px; }
.u-mt-px2 { margin-top: 2px; }

/* — Font weights manquants */
.u-font-normal { font-weight: normal; }

/* — Couleurs avec valeurs fallback hardcodées (legacy avant CSS vars) */
.u-text-muted-fallback { color: #a9b3c2; }
.u-accent-color { accent-color: var(--accent); }
.u-bg-bg3-card { background: var(--bg3); color: var(--text2); border: 1px solid var(--border); }
.u-input-default {
  width: 100%;
  padding: 8px 10px;
  border: 1px solid var(--hairline);
  border-radius: 4px;
  background: var(--bg2);
  font-family: inherit;
}

/* — Boutons modale standard (cohérents avec les modales custom existantes) */
.u-modal-btn-primary {
  padding: 8px 16px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  background: var(--accent, #5a3d8a);
  color: #fff;
}
.u-modal-btn-outline {
  padding: 8px 16px;
  border: 1px solid var(--hairline);
  border-radius: 4px;
  cursor: pointer;
  background: none;
}
.u-modal-btn-success {
  padding: 8px 16px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  background: #2d8a3a;
  color: #fff;
}
.u-modal-btn-success-outline {
  padding: 8px 16px;
  border: 1px solid #2d8a3a;
  color: #2d8a3a;
  border-radius: 4px;
  cursor: pointer;
  background: none;
}
.u-modal-btn-danger {
  padding: 8px 16px;
  border: none;
  border-radius: 4px;
  background: #d9534f;
  color: #fff;
}
.u-modal-btn-danger-outline {
  padding: 8px 16px;
  border: 1px solid #d9534f;
  color: #d9534f;
  border-radius: 4px;
  cursor: pointer;
  background: none;
}

/* ──────────────────────────────────────────────────────────────────────────
   Tier 2 — Passphrase unlock overlay (passphrase-ui.js)
   Affiché au boot quand WeeAirPassphrase est activé. Bloque toute
   interaction tant que l'user n'a pas saisi le bon PIN/passphrase.
   ──────────────────────────────────────────────────────────────────────── */
#t2-overlay {
  position: fixed; inset: 0; z-index: 2147483646;
  background: rgba(8, 10, 14, .96); backdrop-filter: blur(8px);
  display: flex; align-items: center; justify-content: center;
  font-family: 'Inter', system-ui, sans-serif; color: #e9eef5;
}
#t2-overlay .t2-card {
  max-width: 360px; width: calc(100% - 32px);
  padding: 32px 28px; border-radius: 16px;
  background: linear-gradient(180deg, #14181f, #0e1115);
  border: 1px solid rgba(255,255,255,.08);
  box-shadow: 0 30px 80px rgba(0,0,0,.55);
  text-align: center;
}
#t2-overlay .t2-icon { font-size: 38px; margin-bottom: 12px; }
#t2-overlay .t2-title {
  font-size: 20px; font-weight: 700; margin-bottom: 6px;
}
#t2-overlay .t2-sub {
  font-size: 13px; color: #a9b3c2; margin-bottom: 20px;
}
#t2-overlay .t2-input {
  width: 100%; box-sizing: border-box;
  padding: 14px 16px; font-size: 18px; text-align: center;
  font-family: 'JetBrains Mono', monospace; letter-spacing: 4px;
  background: #0a0c10; border: 1px solid rgba(255,255,255,.12);
  border-radius: 10px; color: #F4ECE0; outline: none;
  margin-bottom: 12px;
}
#t2-overlay .t2-input:focus { border-color: #c9a45c; }
#t2-overlay .t2-input:disabled { opacity: .4; }
#t2-overlay .t2-submit {
  width: 100%; padding: 13px; font-size: 15px; font-weight: 600;
  background: #c9a45c; color: #14181f;
  border: none; border-radius: 10px; cursor: pointer;
  transition: filter .1s ease;
}
#t2-overlay .t2-submit:hover { filter: brightness(1.05); }
#t2-overlay .t2-submit:disabled { opacity: .4; cursor: not-allowed; }
#t2-overlay .t2-error {
  font-size: 13px; color: #ff7a7a; margin-bottom: 12px; min-height: 18px;
}
#t2-overlay .t2-countdown {
  margin-top: 14px; font-size: 13px; color: #ffb340;
}

/* ──────────────────────────────────────────────────────────────────────────
   Single-tab overlay — déplacé depuis single-tab.js injectStyles() pour
   éviter <style> tags dynamiques bloqués par CSP style-src 'self'.
   ──────────────────────────────────────────────────────────────────────── */
#single-tab-overlay {
  position: fixed; inset: 0; z-index: 2147483647;
  background: rgba(8,10,14,.92); backdrop-filter: blur(6px);
  display: flex; align-items: center; justify-content: center;
  font-family: 'Inter', system-ui, sans-serif; color: #e9eef5;
}
#single-tab-overlay .st-card {
  max-width: 420px; padding: 28px 26px; border-radius: 14px;
  background: linear-gradient(180deg, #14181f, #0e1115);
  border: 1px solid rgba(255,255,255,.07);
  box-shadow: 0 30px 80px rgba(0,0,0,.55);
  text-align: center;
}
#single-tab-overlay .st-icon { font-size: 32px; margin-bottom: 10px; }
#single-tab-overlay .st-title {
  font-size: 18px; font-weight: 700; margin-bottom: 10px; letter-spacing:.2px;
}
#single-tab-overlay .st-text {
  font-size: 14px; line-height: 1.5; color: #a9b3c2; margin-bottom: 20px;
}
#single-tab-overlay .st-btn {
  appearance: none; border: none; cursor: pointer;
  padding: 11px 18px; border-radius: 10px;
  background: #c9a45c; color: #14181f; font-weight: 700;
  font-size: 14px; transition: transform .1s ease, filter .1s ease;
}
#single-tab-overlay .st-btn:hover { filter: brightness(1.05); }
#single-tab-overlay .st-btn:active { transform: translateY(1px); }

/* ══ BIG / ACCESSIBLE THEME ════════════════════════════════════════════════
   Thème opt-in « gros boutons ». Objectifs :
   - Contraste WCAG AAA (texte ≥ 7:1 sur fond).
   - Cibles tactiles ≥ 48px (recommandation WCAG 2.5.5).
   - Police base 17px (vs 14px par défaut), lisible sans zoom.
   - Bordures visibles (2px) sur TOUS les éléments interactifs : un bouton
     doit ressembler à un bouton, pas à un mot souligné.
   - Focus ring 3px épais + accent vif (utilisable au clavier).
   - Layout responsive : mêmes règles mobile + desktop. */
[data-theme="big"] {
  /* PALETTE PAPER (= 1er thème, demande user) MAIS sizing accessible « gros
     boutons » conservé. On reprend les couleurs cream/maroon du :root paper.
     Les bordures sont un cran PLUS FONCÉES que le paper d'origine (--border2/
     un tan ambré) pour garder une délimitation nette des grands boutons/cadres
     (lisibilité = but du thème), sans casser l'aspect éditorial paper. */
  --bg:          #F4ECE0;      /* paper-200 — canvas */
  --bg-glass:    rgba(244, 236, 224, 0.92);
  --bg2:         #FBF4E8;      /* paper-100 — surfaces */
  --bg2-glass:   rgba(251, 244, 232, 0.92);
  --bg3:         #EDE3D2;      /* paper-300 — sunken */
  --bg3-glass:   rgba(237, 227, 210, 0.95);
  --bg4:         #E0D3BD20;
  --hover:       #E0D3BD;      /* paper-400 — hover/active */
  --accent:      #8A2E25;      /* maroon-600 */
  --accent2:     #7A2E2E;      /* maroon-700 */
  --accent-glow: rgba(156, 58, 46, 0.18);
  --text:        #2A1A14;      /* ink-700 */
  --text2:       #7A6B5C;      /* ink-300 */
  --muted:       #A89A8B;      /* ink-200 */
  --border:      #C9B49A;      /* tan ambré (plus net que le paper #E0D3BD) */
  --border2:     #B7A081;      /* hairline plus foncé pour cadres « gros » */
  --green:       #16A85F;
  --red:         #B83A3A;
  --yellow:      #C58A2A;
}

[data-theme="big"] html, [data-theme="big"] body {
  font-size: 17px;
  line-height: 1.55;
  background: var(--bg);
  color: var(--text);
}

/* Cache le canvas matrix-rain en thème big (visible par défaut sur dark
   et matrix). Sans ça, fond noir avec lettres japonaises traverse l'UI. */
[data-theme="big"] #matrix-bg { display: none !important; }

/* Tous les éléments interactifs : cible tactile minimale 48px. */
[data-theme="big"] button,
[data-theme="big"] .btn,
[data-theme="big"] .btn-primary,
[data-theme="big"] .btn-secondary,
[data-theme="big"] .btn-send,
[data-theme="big"] .btn-attach,
[data-theme="big"] .btn-theme,
[data-theme="big"] .btn-lang-toggle,
[data-theme="big"] .btn-sidebar-toggle,
[data-theme="big"] .btn-sidebar-close,
[data-theme="big"] .btn-install-pwa,
[data-theme="big"] .expiry-btn,
[data-theme="big"] .btn-verify-dm,
[data-theme="big"] .btn-recovery-small {
  min-height: 52px;
  min-width: 52px;
  font-size: 16px;
  font-weight: 700;
  padding: 14px 20px;
  border-radius: 12px;
  border: 2px solid var(--border) !important;
  background: var(--bg2);
  color: var(--text);
  cursor: pointer;
  line-height: 1.2;
}
[data-theme="big"] .btn-primary,
[data-theme="big"] .btn-send {
  background: var(--accent) !important;
  color: #fff !important;
  border-color: var(--accent2) !important;
}
[data-theme="big"] button:hover,
[data-theme="big"] .btn:hover {
  background: var(--hover);
  border-color: var(--accent) !important;
}
[data-theme="big"] .btn-primary:hover,
[data-theme="big"] .btn-send:hover {
  background: var(--accent2) !important;
}
[data-theme="big"] button:focus-visible,
[data-theme="big"] .btn:focus-visible,
[data-theme="big"] input:focus-visible,
[data-theme="big"] textarea:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 2px;
}

/* Composer : zone de saisie principale très agrandie. */
[data-theme="big"] #composer {
  padding: 16px 16px 18px;
  background: var(--bg2);
  border-top: 2px solid var(--border);
}
[data-theme="big"] .composer-main {
  border: 2.5px solid var(--border);
  border-radius: 14px;
  padding: 10px 12px;
  background: var(--bg);
  min-height: 60px;
}
[data-theme="big"] .composer-main:focus-within {
  border-color: var(--accent);
  box-shadow: 0 0 0 4px var(--accent-glow);
}
[data-theme="big"] #message-input,
[data-theme="big"] input,
[data-theme="big"] textarea {
  font-size: 17px !important;
  line-height: 1.5;
  color: var(--text);
}
[data-theme="big"] input:not([type="checkbox"]):not([type="radio"]),
[data-theme="big"] textarea {
  min-height: 52px;
  padding: 14px 16px;
  border: 2px solid var(--border);
  border-radius: 12px;
  background: var(--bg);
}

/* Sidebar : items canaux/users avec grosse zone tap. */
[data-theme="big"] .channel-item,
[data-theme="big"] .user-item {
  padding: 14px 16px !important;
  min-height: 56px;
  font-size: 16px;
  border-radius: 10px;
  margin-bottom: 4px;
  border: 2px solid transparent;
}
[data-theme="big"] .channel-item:hover,
[data-theme="big"] .user-item:hover {
  background: var(--hover);
  border-color: var(--border);
}
[data-theme="big"] .channel-item.active,
[data-theme="big"] .user-item.active {
  background: var(--accent-glow);
  border-color: var(--accent);
  color: var(--text);
  font-weight: 700;
}
[data-theme="big"] .channel-name,
[data-theme="big"] .user-name {
  font-size: 16px !important;
  font-weight: 600;
}
[data-theme="big"] .channel-prefix { font-size: 18px !important; }

/* Tabs : barre de navigation plus haute, plus claire. */
[data-theme="big"] .tab {
  padding: 14px 20px !important;
  font-size: 15px !important;
  font-weight: 700 !important;
  min-height: 52px;
  border-radius: 10px;
  border: 2px solid transparent;
}
[data-theme="big"] .tab.active {
  background: var(--accent-glow);
  border-color: var(--accent);
  color: var(--accent2) !important;
}

/* Avatars : un peu plus gros pour cohérence visuelle. */
[data-theme="big"] .avatar { width: 44px; height: 44px; font-size: 16px; }
[data-theme="big"] .avatar.lg { width: 52px; height: 52px; font-size: 18px; }
[data-theme="big"] .avatar.sm { width: 36px; height: 36px; font-size: 14px; }

/* Bulles de message : plus de padding, texte plus grand. */
[data-theme="big"] .msg-bubble,
[data-theme="big"] .dm-bubble {
  padding: 14px 18px !important;
  font-size: 20px !important;          /* texte des messages plus GRAND */
  line-height: 1.55 !important;
  border-radius: 16px !important;
  border: 1.5px solid var(--border);
  color: var(--text) !important;       /* plus FONCÉ (noir pur) */
}
/* Texte des messages de CANAL (.msg-body) : 14px de base → trop petit en big.
   Plus grand + noir franc (demande accessibilité). */
[data-theme="big"] .msg-body {
  font-size: 20px !important;
  line-height: 1.6 !important;
  color: var(--text) !important;
}
/* Bouton réglages (⚙) en haut : le bouton fait 52px mais le glyphe ⚙ (emoji
   texte) restait à 14px → on agrandit la police du bouton. */
[data-theme="big"] #btn-open-settings {
  font-size: 28px !important;
  line-height: 1 !important;
}

/* Modales : actions principales très visibles. */
[data-theme="big"] .modal-content,
[data-theme="big"] .modal {
  font-size: 16px;
}
[data-theme="big"] .modal-actions button {
  min-height: 56px;
  font-size: 17px;
  padding: 16px 24px;
}

/* Theme bar : 4 boutons à la place de 3, espace réduit mais visible. */
[data-theme="big"] .sidebar-theme-bar {
  padding: 12px 12px 14px;
  gap: 6px;
}
[data-theme="big"] .btn-theme {
  min-height: 48px;
  min-width: 0;
  padding: 8px;
  font-size: 20px;
  border-width: 2.5px !important;
}
[data-theme="big"] .btn-theme.active {
  border-color: var(--accent) !important;
  background: var(--accent-glow);
}

/* Tagline sécurité sous le composer : lisible en theme big. */
[data-theme="big"] .security-tagline {
  font-size: 13px;
  opacity: 1;
  font-weight: 600;
}

/* En-tête conversation : titre + sous-titre lisibles. */
[data-theme="big"] .ch-title,
[data-theme="big"] .ch-channel-name,
[data-theme="big"] .ch-dm-name { font-size: 19px !important; }
[data-theme="big"] .ch-sub,
[data-theme="big"] .ch-members,
[data-theme="big"] .ch-dm-status { font-size: 14px !important; }

/* Pseudo et badges : tailles cohérentes. */
[data-theme="big"] .pseudo-display { font-size: 16px !important; }
[data-theme="big"] .btn-edit-pseudo,
[data-theme="big"] .btn-push-toggle { font-size: 16px !important; }

/* ── BIG THEME — Tuning v2 (feedback user) ──────────────────────────────── */

/* Sidebar plus large (265 → 340). */
[data-theme="big"] {
  --sidebar: 340px;
}

/* Burger menu beaucoup plus gros. */
[data-theme="big"] #btn-sidebar-toggle {
  width: 60px !important;
  height: 60px !important;
  min-width: 60px !important;
  padding: 0 !important;
  display: inline-flex !important;
  align-items: center;
  justify-content: center;
}
[data-theme="big"] .hamburger-icon,
[data-theme="big"] .hamburger-icon::before,
[data-theme="big"] .hamburger-icon::after {
  width: 28px;
  height: 4px;
  background: var(--text);
  border-radius: 2px;
}
[data-theme="big"] .hamburger-icon::before { top: -9px !important; }
[data-theme="big"] .hamburger-icon::after  { bottom: -9px !important; }

/* Onglets (tab-bar) : nettement plus grands. */
[data-theme="big"] #tab-bar {
  min-height: 72px;
  padding: 8px 10px;
  gap: 6px;
}
[data-theme="big"] .tab {
  padding: 18px 26px !important;
  font-size: 17px !important;
  min-height: 60px !important;
  border-radius: 14px !important;
  border-width: 2.5px !important;
}
[data-theme="big"] .tab-close {
  font-size: 22px !important;
  margin-left: 8px !important;
  opacity: 1 !important;
  padding: 2px 6px !important;
}
[data-theme="big"] .tabbar-logo { height: 44px !important; width: auto !important; }

/* Bouton "Vérifier" : on cache le label, on garde l'icône + carré gros. */
[data-theme="big"] .btn-verify-dm-label { display: none !important; }
[data-theme="big"] .btn-verify-dm {
  width: 60px;
  min-width: 60px;
  padding: 14px !important;
}
[data-theme="big"] .btn-verify-dm-icon { font-size: 24px !important; }

/* Statut DM "● Online" → on garde le point, on cache le mot. */
[data-theme="big"] .ch-dm-status {
  font-size: 0 !important;
  line-height: 0 !important;
}
[data-theme="big"] .ch-dm-status::before {
  content: "●";
  font-size: 22px;
  color: var(--green);
  display: inline-block;
  line-height: 1;
}

/* Sélecteur de durée (1min / 1h / 24h) : design segmented control unifié.
   Au lieu de 3 boutons séparés, ça ressemble à un select. */
[data-theme="big"] .expiry-selector {
  border: 2.5px solid var(--border);
  border-radius: 14px;
  background: var(--bg);
  padding: 4px !important;
  gap: 2px !important;
  min-height: 56px;
  /* overflow:visible OBLIGATOIRE : le popover d'expiration s'ouvre AU-DESSUS du
     sélecteur (position:absolute, bottom:100%) → un overflow:hidden le coupait
     entièrement (bug user : « quand je clique 1h, je ne vois pas le sélecteur »).
     L'ancien hidden datait de l'époque où les options étaient INLINE (v420). */
  overflow: visible;
}
/* Le popover lui-même sur fond clair (paper) : ombre + bordure nettes pour
   ressortir au-dessus des messages (l'ombre sombre par défaut suffit moins ici). */
[data-theme="big"] .expiry-popover {
  border: 2px solid var(--border2);
  box-shadow: 0 10px 30px rgba(42, 26, 20, 0.22);
}

/* ── Boutons de CONTRÔLE D'APPEL en thème big ────────────────────────────────
   Bug user : « des boutons tout petits au niveau des appels ». Le sélecteur
   universel `[data-theme="big"] button` les rendait carrés (border-radius 12px)
   avec un SVG resté petit, et la barre audio fine (48px) les écrasait. On les
   force RONDS, plus GRANDS, avec un SVG agrandi, et on agrandit les barres
   d'appel audio pour les accueillir. Couvre groupe (.gc-btn) + 1-to-1
   (.call-panel-btn), barres fines incluses. */
[data-theme="big"] .gc-btn,
[data-theme="big"] #call-panel[data-mode="1to1"] .call-panel-btn {
  width: 50px !important; height: 50px !important;
  min-width: 50px !important; min-height: 50px !important;
  border-radius: 50% !important;
  padding: 0 !important;
  border-width: 2px !important;
}
[data-theme="big"] .gc-btn svg,
[data-theme="big"] .call-panel-btn svg { width: 26px !important; height: 26px !important; }
/* Les barres d'appel AUDIO fines doivent accueillir des boutons 50px. */
[data-theme="big"] .groupcall-panel.gc-compact.gc-audio-only {
  height: 64px; min-height: 64px; flex-basis: 64px;
}
[data-theme="big"] #call-panel[data-mode="1to1"].call-audio-compact {
  height: 66px !important; min-height: 66px; max-height: 66px;
}
[data-theme="big"] #call-panel[data-mode="1to1"].call-audio-compact #call-panel-bar { height: 66px; }
[data-theme="big"] .expiry-btn {
  border: none !important;
  border-radius: 10px !important;
  background: transparent !important;
  min-height: 44px !important;
  min-width: 0 !important;
  padding: 8px 16px !important;
  font-size: 15px !important;
  font-weight: 700 !important;
  color: var(--text2) !important;
  flex: 1;
  transition: background 0.15s, color 0.15s;
}
[data-theme="big"] .expiry-btn:hover {
  background: var(--hover) !important;
  border: none !important;
  color: var(--text) !important;
}
[data-theme="big"] .expiry-btn.active {
  background: var(--accent) !important;
  color: #fff !important;
  border: none !important;
}

/* Icônes du panneau canal actif (sidebar) : ⚙ ⌕ 🔍 plus grosses. */
[data-theme="big"] .ch-action-btn {
  width: 48px !important;
  height: 48px !important;
  min-width: 48px !important;
  min-height: 48px !important;
  padding: 0 !important;   /* sinon padding 14×20 universel écrase le SVG */
  font-size: 22px !important;
  border-radius: 12px !important;
  border: 2px solid var(--border) !important;
  display: inline-flex !important;
  align-items: center;
  justify-content: center;
}
/* SVG des boutons d'action canal (partager ⤴) + épingle readonly agrandis. */
[data-theme="big"] .ch-action-share svg,
[data-theme="big"] .ch-action-btn svg {
  width: 24px !important;
  height: 24px !important;
}
[data-theme="big"] .channel-lock svg {
  width: 22px !important;
  height: 22px !important;
}
/* Item de canal ACTIF : le gradient violet en dur (rgba 124,106,247) ignorait
   la palette haut-contraste → fond lavande. On le passe en gris clair franc
   (la bordure noire + le gras de l'outer indiquent l'état actif). */
[data-theme="big"] .channel-item.active > .channel-item-main {
  background: var(--bg3) !important;
}
[data-theme="big"] .ch-context-icon { font-size: 26px !important; }
[data-theme="big"] .channel-prefix { font-size: 22px !important; }
[data-theme="big"] .channel-lock { font-size: 16px !important; }

/* Badge OWNER : plus lisible. */
[data-theme="big"] .owner-badge,
[data-theme="big"] [class*="owner"] { font-size: 12px !important; padding: 4px 8px !important; }

/* ── BIG THEME — Tuning v3 ───────────────────────────────────────────────── */

/* Cacher complètement le canal WiFi (mur) en mode accessible. */
[data-theme="big"] .wifi-channel-item { display: none !important; }

/* Compteur membres + emoji canal (🔥 2 👤) : visible. */
[data-theme="big"] .chan-member-count {
  font-size: 18px !important;
  line-height: 1.2;
  font-weight: 700;
}
[data-theme="big"] .ch-member-count,
[data-theme="big"] .ch-members { font-size: 17px !important; }

/* Couronne 👑 next to channel name. */
[data-theme="big"] .channel-owner-badge { font-size: 24px !important; }

/* Pill OWNER/ADMIN dans la liste des membres du canal. */
[data-theme="big"] .ch-role-pill {
  font-size: 14px !important;
  font-weight: 800 !important;
  padding: 6px 12px !important;
  border-radius: 10px !important;
}

/* Nom du canal "1" plus visible (en plus du # prefix déjà 22px). */
[data-theme="big"] .channel-name { font-size: 20px !important; font-weight: 700; }

/* Tag "wall" à côté du nom canal. */
[data-theme="big"] .channel-wall-tag {
  font-size: 13px !important;
  padding: 4px 10px !important;
  font-weight: 700 !important;
}

/* Tag "(me)" pour s'identifier dans la liste. */
[data-theme="big"] .ch-sidebar-me { font-size: 14px !important; opacity: 0.7; }

/* Items membres dans le panneau canal : plus de padding, avatars OK. */
[data-theme="big"] .ch-sidebar-member {
  padding: 10px 12px !important;
  gap: 10px !important;
  min-height: 56px;
  font-size: 16px !important;
}

/* ── BIG THEME — Tuning v4 ───────────────────────────────────────────────── */

/* Bouton Options : cache le mot, garde juste l'icône ⚙ grosse. */
[data-theme="big"] .btn-options-label { display: none !important; }
[data-theme="big"] .btn-options-icon { font-size: 24px !important; line-height: 1; }
[data-theme="big"] #btn-open-settings {
  width: 60px !important; min-width: 60px !important; height: 60px !important;
  padding: 0 !important; border-radius: 14px !important;
  display: inline-flex !important; align-items: center; justify-content: center;
}

/* Pill OWNER : on affiche juste la 👑 (le mot "OWNER" est dans le texte
   du span — on tue le font-size puis ::before injecte l'emoji). */
[data-theme="big"] .ch-role-pill.owner {
  font-size: 0 !important;
  width: 52px !important; min-width: 52px !important; height: 52px !important;
  padding: 0 !important;
  border-radius: 14px !important;
  display: inline-flex !important;
  align-items: center; justify-content: center;
}
[data-theme="big"] .ch-role-pill.owner::before {
  content: "👑";
  font-size: 28px;
  line-height: 1;
}

/* Header "CHANNELS" : largement plus visible (10px → 15px). */
[data-theme="big"] .section-header {
  padding: 14px 18px !important;
  font-size: 15px !important;
  letter-spacing: 0.18em !important;
  color: var(--text2) !important;
}
[data-theme="big"] .btn-icon {
  width: 48px !important; height: 48px !important;
  font-size: 24px !important;
  border-radius: 12px !important;
}

/* Crayon ✎ d'édition pseudo : caché — on clique directement sur le nom
   (handler déjà branché sur .pseudo-name-row dans ui.js). */
[data-theme="big"] .btn-edit-pseudo { display: none !important; }
[data-theme="big"] .pseudo-name-row {
  cursor: pointer !important;
  padding: 8px 10px;
  border-radius: 10px;
  transition: background 0.15s;
}
[data-theme="big"] .pseudo-name-row:hover { background: var(--hover); }

/* ── Boutons d'appel style Skype : ronds, SVG line-art, propres ────────── */
[data-theme="big"] .btn-call-video,
[data-theme="big"] .btn-call-audio,
[data-theme="big"] .btn-verify-dm {
  width: 60px !important; height: 60px !important;
  min-width: 60px !important; min-height: 60px !important;
  border-radius: 50% !important;
  border: 2px solid var(--border) !important;
  background: var(--bg) !important;
  padding: 0 !important;
  font-size: 0 !important;          /* cache l'emoji original */
  position: relative;
  display: inline-flex !important;
  align-items: center; justify-content: center;
  flex-shrink: 0;
  opacity: 1 !important;            /* override u-op-40 */
}
[data-theme="big"] .btn-call-video:not(:disabled):hover,
[data-theme="big"] .btn-call-audio:not(:disabled):hover,
[data-theme="big"] .btn-verify-dm:hover {
  background: var(--hover) !important;
  border-color: var(--accent) !important;
}
[data-theme="big"] .btn-call-video::before,
[data-theme="big"] .btn-call-audio::before {
  content: '';
  width: 30px; height: 30px;
  background-position: center;
  background-repeat: no-repeat;
  background-size: contain;
}
[data-theme="big"] .btn-call-video::before {
  /* Icône caméra Feather/Lucide */
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230a0908' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polygon points='23 7 16 12 23 17 23 7'/><rect x='1' y='5' width='15' height='14' rx='2' ry='2'/></svg>");
}
[data-theme="big"] .btn-call-audio::before {
  /* Icône téléphone Feather/Lucide (audio call = phone, plus standard) */
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230a0908' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z'/></svg>");
}
/* Verify : cache aussi le 🔐 emoji et utilise un bouclier propre. */
[data-theme="big"] .btn-verify-dm .btn-verify-dm-icon { font-size: 0 !important; }
[data-theme="big"] .btn-verify-dm::before {
  content: '';
  width: 30px; height: 30px;
  background-position: center;
  background-repeat: no-repeat;
  background-size: contain;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230a0908' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z'/></svg>");
}
/* État vérifié : icône verte avec check ajouté. */
[data-theme="big"] .btn-verify-dm[data-state="verified"] {
  border-color: var(--green) !important;
  background: rgba(26,110,42,0.08) !important;
}
[data-theme="big"] .btn-verify-dm[data-state="verified"]::before {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%231a6e2a' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><path d='M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z'/><polyline points='9 12 11 14 15 10'/></svg>");
}
/* État mismatch : rouge. */
[data-theme="big"] .btn-verify-dm[data-state="mismatch"] {
  border-color: var(--red) !important;
  background: rgba(181,29,29,0.08) !important;
}
[data-theme="big"] .btn-verify-dm[data-state="mismatch"]::before {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23b51d1d' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><path d='M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z'/><line x1='9' y1='9' x2='15' y2='15'/><line x1='15' y1='9' x2='9' y2='15'/></svg>");
}

/* ── BIG THEME — Tuning v5 ───────────────────────────────────────────────── */

/* Options : forcer la taille (le base flex:1 le faisait s'étirer). */
[data-theme="big"] .profile-recovery-row { justify-content: flex-start; }
[data-theme="big"] #btn-open-settings {
  flex: 0 0 60px !important;
  width: 60px !important; max-width: 60px !important;
}

/* Install PWA repositionné en haut à côté de EN, juste l'icône.
   Le position:relative est scopé desktop : sur mobile (max-width: 700px),
   le sidebar est en position:fixed (overlay) — surcharge à cet endroit
   cassait le slide-in/out du sidebar mobile. */
@media (min-width: 701px) {
  [data-theme="big"] #sidebar { position: relative; }
  /* Sur desktop : le branding "DoraCom" est dans le sidebar header → on
     cache .tabbar-brand pour éviter le doublon. SAUF si le sidebar est
     collapsed (user a fermé via le burger) : alors on réaffiche le
     satellite top-left pour conserver l'identité visuelle. */
  .tabbar-brand { display: none !important; }
  #main-ui:has(#sidebar.collapsed) .tabbar-brand { display: inline-flex !important; }
}
[data-theme="big"] #btn-install-pwa {
  position: absolute !important;
  top: 14px !important;
  right: 84px !important;     /* laisse place au bouton EN à droite */
  width: 60px !important;
  height: 60px !important;
  min-width: 60px !important;
  min-height: 60px !important;
  padding: 0 !important;
  margin: 0 !important;
  border-radius: 14px !important;
  z-index: 12;
  display: inline-flex !important;
  align-items: center; justify-content: center;
  box-shadow: none !important;  /* override base big-bouncy style */
}
[data-theme="big"] .btn-install-label { display: none !important; }
[data-theme="big"] .btn-install-icon {
  font-size: 26px !important;
  margin: 0 !important;
}

/* ── BIG THEME — Tuning v6 ───────────────────────────────────────────────── */

/* Shield/icônes call : centrage explicite via translate (le flex centering
   peut shifter visuellement avec strokes Feather). */
[data-theme="big"] .btn-call-video::before,
[data-theme="big"] .btn-call-audio::before,
[data-theme="big"] .btn-verify-dm::before {
  position: absolute !important;
  top: 50% !important; left: 50% !important;
  transform: translate(-50%, -50%) !important;
  width: 28px !important; height: 28px !important;
}

/* Composer mic (#btn-mic) : utilise la même SVG micro propre que j'avais
   créé pour btn-call-audio v1. Garde la couleur d'origine quand non-actif. */
[data-theme="big"] #btn-mic {
  width: 56px !important; height: 56px !important;
  min-width: 56px !important; min-height: 56px !important;
  border-radius: 12px !important;
  border: 2px solid var(--border) !important;
  background: var(--bg) !important;
  padding: 0 !important;
  font-size: 0 !important;
  position: relative;
  display: inline-flex !important;
  align-items: center; justify-content: center;
}
[data-theme="big"] #btn-mic::before {
  content: '';
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: 28px; height: 28px;
  background-position: center;
  background-repeat: no-repeat;
  background-size: contain;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230a0908' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z'/><path d='M19 10v2a7 7 0 0 1-14 0v-2'/><line x1='12' y1='19' x2='12' y2='23'/><line x1='8' y1='23' x2='16' y2='23'/></svg>");
}
[data-theme="big"] #btn-mic.mic-active { border-color: var(--red) !important; }
[data-theme="big"] #btn-mic.mic-active::before {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23b51d1d' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z'/><path d='M19 10v2a7 7 0 0 1-14 0v-2'/><line x1='12' y1='19' x2='12' y2='23'/><line x1='8' y1='23' x2='16' y2='23'/></svg>");
}

/* Options ⚙ en thème big : position absolute sur .sidebar-profile.
   Marche peu importe où le bouton est dans le DOM (.profile-recovery-row
   ou .pseudo-name-row), donc robuste face aux états du SW/JS.            */
[data-theme="big"] .sidebar-profile {
  position: relative;
  flex-direction: row !important;
  flex-wrap: nowrap !important;
  align-items: center !important;
}
[data-theme="big"] .profile-info {
  /* Laisse de l'espace à droite pour Options absolute (52 + 16 right). */
  padding-right: 68px;
  min-width: 0;
}
[data-theme="big"] #btn-open-settings {
  position: absolute !important;
  top: 50% !important;
  right: 16px !important;
  transform: translateY(-50%) !important;
  flex: 0 0 52px !important;
  width: 52px !important; max-width: 52px !important;
  height: 52px !important; min-height: 52px !important;
  min-width: 52px !important;
  border: 2px solid var(--border) !important;
  border-radius: 12px !important;
  background: var(--bg) !important;
  padding: 0 !important;
  margin: 0 !important;
  display: inline-flex !important;
  align-items: center; justify-content: center;
}
[data-theme="big"] #btn-open-settings .btn-options-icon {
  font-size: 22px !important;
}
/* PAS de display:none sur .profile-recovery-row : Options est dedans et
   position:absolute ne fonctionne pas si un parent est display:none.
   La row apparaît à hauteur 0 car son seul enfant est out-of-flow. */

/* ── BIG THEME — Actions message (X / ↻) reveal comme smiley ──
   Mobile inclus : opacity:0 par défaut, le tap déclenche :hover/:focus
   (comportement iOS standard) → reveal. Tap ailleurs = fade out.        */
/* Accessibilité : actions message TOUJOURS visibles (une personne âgée ne
   "survole" pas pour découvrir), grosses et en NOIR FRANC. On ANNULE la règle
   universelle big (52px + bordure 2px) pour ces glyphes — sinon 6 énormes
   boutons bordés par message. Glyphe 22px, noir, sans bordure. */
[data-theme="big"] .msg-actions {
  opacity: 1 !important;
  gap: 4px;
}
[data-theme="big"] .msg-actions button,
[data-theme="big"] .btn-dm-reply,
[data-theme="big"] .btn-dm-forward,
[data-theme="big"] .btn-dm-copy,
[data-theme="big"] .btn-dm-edit,
[data-theme="big"] .btn-dm-del {
  min-width: 0 !important;
  min-height: 0 !important;
  width: auto !important;
  height: auto !important;
  padding: 4px 8px !important;
  border: none !important;
  background: none !important;
  font-size: 22px !important;
  font-weight: 400 !important;
  color: var(--text) !important;   /* noir pur, haut contraste */
  opacity: 1 !important;
}
[data-theme="big"] .msg-actions button svg,
[data-theme="big"] .btn-dm-reply svg,
[data-theme="big"] .btn-dm-forward svg,
[data-theme="big"] .btn-dm-copy svg {
  width: 24px !important;
  height: 24px !important;
}
[data-theme="big"] .msg-actions .btn-del,
[data-theme="big"] .btn-dm-del { color: var(--red) !important; }

/* Liseré de contexte sous l'en-tête → NOIR en thème big (monochrome total,
   demande « tout l'ensemble »). Avant : violet/orange/vert par contexte. */
[data-theme="big"] #content-header[data-context] { --ctx-color: #000 !important; }

/* ── BIG THEME — Trombone composer (#btn-attach) en SVG Feather ─────── */
[data-theme="big"] #btn-attach,
[data-theme="big"] #btn-pay,
[data-theme="big"] #btn-sticker,
[data-theme="big"] #btn-emoji {
  width: 56px !important; height: 56px !important;
  min-width: 56px !important; min-height: 56px !important;
  border-radius: 12px !important;
  border: 2px solid var(--border) !important;
  background: var(--bg) !important;
  padding: 0 !important;   /* SANS padding : sinon le SVG 30px est écrasé */
  display: inline-flex !important;
  align-items: center; justify-content: center;
  flex-shrink: 0;
}
[data-theme="big"] #btn-attach {
  font-size: 0 !important;
  color: transparent !important;
  position: relative;
}
[data-theme="big"] #btn-emoji {
  font-size: 26px !important;     /* garde l'emoji 😊 visible */
  line-height: 1;
}

/* Composer-main big : UNE SEULE LIGNE — textarea + boutons (mic/vocal/envoi)
   en RANGÉE (demande accessibilité). Avant : grid avec textarea forcée à
   116px (≈4 lignes) + mic empilé au-dessus de send. */
[data-theme="big"] .composer-main {
  display: flex !important;
  flex-direction: row;
  align-items: center;
  gap: 8px;
  padding: 8px !important;
}
[data-theme="big"] .composer-main #message-input {
  flex: 1 1 auto;
  width: auto;
  min-height: 56px !important;   /* démarre sur 1 ligne */
  max-height: 132px;             /* grandit modérément si message long */
  align-self: center;
  resize: none;
}
[data-theme="big"] .composer-main #btn-mic,
[data-theme="big"] .composer-main #btn-voice-msg,
[data-theme="big"] .composer-main #btn-send {
  flex: 0 0 auto;
  align-self: center;
  width: 56px !important;
  height: 56px !important;
  min-width: 56px !important;
  min-height: 56px !important;
  padding: 0 !important;
  border-radius: 12px !important;
  font-size: 20px !important;
}

/* ── Reset universel pour les emojis de pickers + réactions ──
   Le rule universal [data-theme="big"] button { 52px / border 2px / padding
   14×20 } cassait les emojis du picker composer (.cep-*), le smiley de
   réaction (.btn-react), le quick-picker (.reaction-picker), et les chips
   d'emoji déjà placés. On annule ces overrides — les emojis doivent rester
   à leur taille naturelle (compactes).                                    */
[data-theme="big"] .btn-react,
[data-theme="big"] .cep-tab,
[data-theme="big"] .cep-emoji,
[data-theme="big"] .reaction-picker button,
[data-theme="big"] .reaction-chip {
  min-width: 0 !important;
  min-height: 0 !important;
  width: auto !important;
  height: auto !important;
  padding: 6px 8px !important;
  border: none !important;
  border-radius: 8px !important;
  background: none !important;
  font-size: 22px !important;
  font-weight: 400 !important;
}
[data-theme="big"] .reaction-chip {
  border: 1px solid var(--border) !important;
  background: var(--bg3) !important;
  font-size: 16px !important;
  padding: 4px 10px !important;
}
[data-theme="big"] #btn-attach::before {
  content: '';
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%) rotate(-45deg);
  width: 28px; height: 28px;
  background-position: center;
  background-repeat: no-repeat;
  background-size: contain;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230a0908' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48'/></svg>");
}

/* ── BIG THEME — glyphes SVG du composer agrandis (accessibilité) ─────────
   Les boutons font 52-56px mais le SVG générique reste à 20px (send 18px) →
   icône minuscule dans un gros bouton. On agrandit les glyphes à 30px pour
   les doigts délicats / la vue. #btn-attach exclu : il rend son icône via
   ::before (background-image) ci-dessus, pas via <svg>. */
[data-theme="big"] #btn-pay svg,
[data-theme="big"] #btn-sticker svg,
[data-theme="big"] #btn-mic svg,
[data-theme="big"] #btn-voice-msg svg,
[data-theme="big"] .composer-main #btn-send svg,
[data-theme="big"] .expiry-viewonce svg {
  width: 30px !important;
  height: 30px !important;
}
/* Bouton « voir une fois » (œil) : carré sans padding pour que son SVG 30px
   ne soit pas écrasé (même cause que pay/sticker). */
[data-theme="big"] .expiry-viewonce {
  width: 56px !important;
  min-width: 56px !important;
  padding: 0 !important;
  display: inline-flex !important;
  align-items: center;
  justify-content: center;
}

/* ── BIG THEME — icônes d'en-tête de canal agrandies (accessibilité) ───────
   🛡 PQ, 👥 membres, 📞 appel audio, 📹 vidéo, ⋯ menu. Base = boutons ~32px /
   glyphes 14-18px → trop petits. Boutons 48px (un peu < composer pour tenir
   dans l'en-tête), glyphes/SVG 26px. */
[data-theme="big"] #content-header .call-btn,
[data-theme="big"] #content-header .pq-icon-btn,
[data-theme="big"] #content-header .btn-header-more {
  width: 48px !important;
  height: 48px !important;
  min-width: 48px !important;
  min-height: 48px !important;
  padding: 0 !important;
  border-radius: 12px !important;
  display: inline-flex !important;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
[data-theme="big"] #content-header .call-btn svg {
  width: 26px !important;
  height: 26px !important;
}
/* 🛡 et ⋯ sont du texte/emoji (pas de SVG) → on agrandit la police. */
[data-theme="big"] #content-header .pq-icon-btn,
[data-theme="big"] #content-header .btn-header-more {
  font-size: 26px !important;
  line-height: 1;
}
/* 👥 chip membres : pastille + compteur agrandis. */
[data-theme="big"] #content-header .members-chip {
  min-height: 48px;
  padding: 6px 14px !important;
  font-size: 20px !important;
  border-radius: 12px !important;
}
[data-theme="big"] #content-header .members-chip .members-chip-icon,
[data-theme="big"] #content-header .members-chip-icon {
  width: 24px !important;
  height: 24px !important;
}

/* ── BIG THEME — X (delete) DM : reveal au hover de la row, comme le smiley
   .btn-dm-react. Sans cette règle, le selector universel `button { min 52px
   + border 2px }` rend le X très voyant et l'opacity 0.4 base le laisse
   visible en permanence (et opacity 1 sur mobile). On force opacity:0 par
   défaut et reveal uniquement sur :hover/:focus-within de la .dm-row. */
[data-theme="big"] .btn-dm-del {
  opacity: 0 !important;
  transition: opacity 0.15s !important;
}
[data-theme="big"] .dm-row:hover .btn-dm-del,
[data-theme="big"] .dm-row:focus-within .btn-dm-del {
  opacity: 1 !important;
}

/* ── BIG THEME — Cache le sous-titre canal "Canal — N membres · chiffré..."
   Bruit visuel inutile en mode accessible (les badges E2E + member count
   sont déjà visibles ailleurs). Le sous-titre DM "Message privé — chiffré
   bout-en-bout" reste visible (utile pour l'utilisateur novice). */
[data-theme="big"] #content-header[data-context="channel"] .ch-context-sub {
  display: none !important;
}

/* Tab-bar brand : on garde seulement l'icône 📡 (le texte "DoraCom"
   reste visible dans la sidebar header pour préserver l'identité visuelle). */
.tabbar-brand-text { display: none !important; }
/* Si Options est déplacé hors de la profile-row, cache la row vide. */
[data-theme="big"] .profile-recovery-row:empty { display: none !important; }

/* ── BIG THEME — Tuning v7 ───────────────────────────────────────────────── */

/* Install PWA et EN : mêmes dimensions exactes (carrés 60×60). */
[data-theme="big"] #btn-lang-toggle {
  width: 60px !important;
  height: 60px !important;
  min-width: 60px !important;
  min-height: 60px !important;
  padding: 0 !important;
  font-size: 18px !important;
  border-radius: 14px !important;
  display: inline-flex !important;
  align-items: center; justify-content: center;
}

/* ── Panneau canal actif : layout 1 ligne épurée ─────────────────────────
   [# nom-du-canal ............................. ⚙]
   - audit 🔍, count 2👤, couronne 👑, tag "wall" → cachés (dans modal Options)
   - settings ⚙ poussé à droite                                            */
[data-theme="big"] .channel-item.active .channel-item-main {
  display: flex !important;
  align-items: center;
  gap: 10px;
  padding: 14px !important;
  flex-wrap: wrap;
}
[data-theme="big"] .channel-item.active .channel-prefix {
  font-size: 36px !important;
  font-weight: 700;
  line-height: 1;
  flex-shrink: 0;
}
[data-theme="big"] .channel-item.active .channel-name-wrap {
  display: inline-flex !important;
  align-items: center;
  gap: 10px;
  flex: 1 1 auto;
  min-width: 0;
}
[data-theme="big"] .channel-item.active .channel-name {
  font-size: 26px !important;
  font-weight: 700 !important;
  letter-spacing: -0.3px;
  overflow: hidden;
  text-overflow: ellipsis;
}
[data-theme="big"] .channel-item.active .channel-lock {
  font-size: 22px !important;
  align-self: center;
  flex-shrink: 0;
}
/* Actions : seulement ⚙ Settings, poussé à droite. */
[data-theme="big"] .channel-item.active .channel-item-actions {
  margin-left: auto;
  display: flex !important;
  gap: 8px;
  flex-shrink: 0;
}

/* ── Éléments cachés en thème big (déplacés dans le modal Options) ───── */
[data-theme="big"] .channel-wall-tag,
[data-theme="big"] .channel-owner-badge,
[data-theme="big"] .chan-member-count,
[data-theme="big"] .ch-action-audit { display: none !important; }

/* ── Édition inline du nom de canal (tous thèmes, owner uniquement) ───── */
.channel-name-editable {
  cursor: text;
  border-bottom: 1px dashed transparent;
  transition: border-color 0.15s, color 0.15s;
}
.channel-name-editable:hover {
  border-bottom-color: var(--accent);
  color: var(--accent);
}
.channel-name-edit {
  font: inherit;
  color: inherit;
  background: var(--bg);
  border: 2px solid var(--accent);
  border-radius: 6px;
  padding: 2px 6px;
  outline: none;
  width: 12em;
  max-width: 100%;
}
[data-theme="big"] .channel-name-edit {
  font-size: 26px !important;
  font-weight: 700;
  padding: 6px 10px;
  border-radius: 10px;
}

/* ══ MODALE PARTAGER LE CANAL (showShareModal) ══════════════════════════════
   Redesign clean : sections "Lien" et "QR code" clairement séparées,
   couleurs intégrées au thème, gros boutons cliquables, URL en monospace
   avec ellipsis propre. */

.share-modal-body {
  display: flex;
  flex-direction: column;
  gap: 18px;
  padding: 4px 0;
  max-width: 420px;
  margin: 0 auto;
}

.share-section {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.share-section-label {
  font-size: 12px;
  font-weight: 600;
  color: var(--text2);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.share-url-box {
  position: relative;
  background: var(--bg2);
  border: 1px solid var(--border, var(--bg4));
  border-radius: 10px;
  padding: 0;
  overflow: hidden;
}

.share-url-input {
  width: 100%;
  background: transparent;
  border: none;
  outline: none;
  padding: 12px 14px;
  font-family: var(--font-mono, ui-monospace, "SF Mono", Menlo, Consolas, monospace);
  font-size: 13px;
  color: var(--text);
  text-overflow: ellipsis;
  white-space: nowrap;
  user-select: all;
}

.share-url-input:focus {
  background: var(--bg3, rgba(0,0,0,0.04));
}

.share-actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.share-btn-copy,
.share-btn-native {
  flex: 1;
  min-width: 140px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 11px 16px;
  font-weight: 600;
  border-radius: 10px;
  transition: background 0.15s, transform 0.1s, border-color 0.15s;
}

.share-btn-icon {
  font-size: 15px;
  line-height: 1;
}

.share-btn-copy.copied {
  background: var(--green, #2d8a4a) !important;
  border-color: var(--green, #2d8a4a) !important;
  color: #fff !important;
}

.share-divider {
  display: flex;
  align-items: center;
  gap: 12px;
  color: var(--muted);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  margin: 4px 0;
}

.share-divider::before,
.share-divider::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--border, var(--bg4));
}

.share-divider span {
  flex-shrink: 0;
}

.share-qr-wrap {
  display: flex;
  justify-content: center;
  padding: 6px 0 2px 0;
}

.share-qr-container {
  background: #ffffff;
  padding: 12px;
  border-radius: 12px;
  border: 1px solid var(--border, var(--bg4));
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
  display: inline-block;
  line-height: 0;
}

/* Force le canvas/img QR à se centrer proprement. Toujours fond blanc +
   QR noir pour garantir la lisibilité par n'importe quelle caméra
   (les QR colorés ont un taux de scan dégradé). */
.share-qr-container canvas,
.share-qr-container img {
  display: block;
  margin: 0 auto;
  border-radius: 4px;
}

.share-qr-hint {
  font-size: 12px;
  color: var(--muted);
  text-align: center;
  margin-top: 8px;
  padding: 0 8px;
  line-height: 1.5;
}

/* Big theme : agrandir les boutons partage (cible tactile 48+) */
[data-theme="big"] .share-btn-copy,
[data-theme="big"] .share-btn-native {
  min-height: 52px;
  font-size: 16px;
}
[data-theme="big"] .share-url-input {
  font-size: 15px;
  padding: 14px 16px;
}
[data-theme="big"] .share-qr-container {
  padding: 16px;
}

/* ── Audit modal — layout propre, sans inline styles ─────────────────── */
.audit-status {
  color: var(--text2);
  font-size: 12px;
  padding: 4px 0 10px;
}
.audit-flagged-banner {
  display: none;
  background: rgba(224, 108, 108, 0.10);
  border-left: 3px solid #e06c6c;
  padding: 10px 12px;
  margin-bottom: 12px;
  border-radius: 0 6px 6px 0;
  font-size: 12px;
}
.audit-flagged-banner .audit-flagged-title {
  color: #e06c6c;
  font-weight: 700;
  margin-bottom: 6px;
  letter-spacing: 0.02em;
}
.audit-flagged-banner .audit-flagged-pill {
  display: inline-block;
  background: rgba(224, 108, 108, 0.18);
  color: #e06c6c;
  padding: 3px 9px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  margin: 3px 5px 3px 0;
}

.audit-toolbar {
  display: flex;
  gap: 10px;
  align-items: center;
  margin-bottom: 10px;
  flex-wrap: wrap;
}
.audit-filters {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  flex: 1 1 auto;
  min-width: 0;
}
.audit-filter-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 11px;
  border-radius: 999px;
  border: 1px solid var(--border, #2a3142);
  background: transparent;
  color: var(--text2);
  font: 600 11px/1 'Geist', 'Manrope', system-ui, sans-serif;
  letter-spacing: 0.02em;
  cursor: pointer;
  transition: background 120ms, border-color 120ms, color 120ms, transform 80ms;
  white-space: nowrap;
}
.audit-filter-pill:hover {
  background: var(--hover);
  border-color: var(--border2);
  color: var(--text);
}
.audit-filter-pill:active { transform: scale(0.96); }
.audit-filter-icon { font-size: 12px; line-height: 1; }
.audit-filter-label { line-height: 1; }
.audit-filter-count {
  background: rgba(255, 255, 255, 0.06);
  color: var(--text2);
  padding: 2px 7px;
  border-radius: 999px;
  font-size: 10.5px;
  font-weight: 700;
  min-width: 18px;
  text-align: center;
}

/* Couleur d'accent par catégorie + état actif */
.audit-filter-all.is-active     { background: rgba(138, 147, 166, 0.14); border-color: #8a93a6; color: #c8cdd6; }
.audit-filter-pos.is-active     { background: rgba(102, 217, 167, 0.14); border-color: #66d9a7; color: #66d9a7; }
.audit-filter-pos.is-active .audit-filter-count { background: rgba(102, 217, 167, 0.18); color: #66d9a7; }
.audit-filter-neutral.is-active { background: rgba(138, 147, 166, 0.14); border-color: #8a93a6; color: #c8cdd6; }
.audit-filter-neg.is-active     { background: rgba(224, 167, 102, 0.14); border-color: #e0a766; color: #e0a766; }
.audit-filter-neg.is-active .audit-filter-count { background: rgba(224, 167, 102, 0.18); color: #e0a766; }
.audit-filter-flag.is-active    { background: rgba(224, 108, 108, 0.14); border-color: #e06c6c; color: #e06c6c; }
.audit-filter-flag.is-active .audit-filter-count { background: rgba(224, 108, 108, 0.18); color: #e06c6c; }

/* Indicateur ML — passif (plus un toggle), juste un badge d'état */
.audit-ml-status {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 5px 11px;
  border-radius: 999px;
  border: 1px solid var(--border, #2a3142);
  background: transparent;
  color: #9dc6ff;
  font: 600 11px/1 'Geist', 'Manrope', system-ui, sans-serif;
  letter-spacing: 0.02em;
  white-space: nowrap;
  user-select: none;
}
.audit-ml-status.loading { color: #e0a766; border-color: rgba(224, 167, 102, 0.45); }
.audit-ml-status.ready   { color: #66d9a7; border-color: rgba(102, 217, 167, 0.45); }
.audit-ml-status.error   { color: #e06c6c; border-color: rgba(224, 108, 108, 0.45); }

.audit-ml-progress {
  display: none;
  font-size: 11px;
  color: #9dc6ff;
  margin-bottom: 8px;
  padding: 6px 10px;
  background: rgba(157, 198, 255, 0.06);
  border-radius: 6px;
}
.audit-ml-progress.visible { display: block; }

/* Caption sous un média (image/video/audio/lottie/viewOnce) */
.msg-media-caption {
  margin-top: 6px;
  font-size: 13.5px;
  line-height: 1.42;
  white-space: pre-wrap;
  word-break: break-word;
  color: inherit;
  opacity: 0.95;
}

.audit-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-height: 50vh;
  overflow-y: auto;
  padding: 10px;
  background: var(--bg2, #0f1218);
  border: 1px solid var(--border, #2a3142);
  border-radius: 8px;
}

/* Indicateur de version (coin bas-gauche) — vérif visuelle de la version chargée.
   CSP-safe (classe CSS, pas de style inline). pointer-events:none = non bloquant. */
#build-version {
  position: fixed;
  bottom: 6px;
  right: 8px;
  z-index: 99999;
  font-family: ui-monospace, monospace;
  font-size: 10px;
  line-height: 1;
  letter-spacing: 0.5px;
  color: rgba(130, 130, 140, 0.6);
  background: rgba(127, 127, 127, 0.10);
  padding: 2px 6px;
  border-radius: 5px;
  pointer-events: none;
  user-select: none;
}

/* Logo B2 Atom : bulle+serrure en encre (CSP-safe, remplace inline style retiré). Orbites = accent via presentation attr. */
.kb-atom { color: var(--text); }

/* ── Appel de groupe MESH E2E (WeeAirGroupCall) ────────────────────────────── */
/* Panneau ANCRÉ EN HAUT : laisse le bas de l'écran (chat + composer) visible
   et utilisable pendant l'appel. */
.groupcall-panel {
  position: fixed; top: 0; left: 0; right: 0;
  height: 32vh; z-index: 9000;            /* considérablement réduit */
  display: flex; flex-direction: column;
  /* Fond quasi-retiré : très transparent + fort flou (verre dépoli) pour
     s'intégrer au thème. Les tuiles vidéo et les boutons ont leur propre
     fond → restent lisibles malgré la transparence du panneau. */
  background: rgba(12, 15, 22, 0.26);
  backdrop-filter: blur(22px) saturate(1.25);
  -webkit-backdrop-filter: blur(22px) saturate(1.25);
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 0 0 16px 16px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.25);
  transition: height 0.18s ease;
}
/* Thème paper (clair) : verre dépoli CLAIR + textes sombres, sinon le panneau
   sombre jurait sur le fond papier. */
[data-theme="paper"] .groupcall-panel {
  background: rgba(247, 240, 230, 0.45);
  border-color: rgba(42, 26, 20, 0.12);
  box-shadow: 0 10px 30px rgba(42, 26, 20, 0.12);
}
/* Hauteur de la bande vidéo horizontale compacte. */
:root { --gc-strip-h: 150px; }

/* Mode COMPACT : BANDE HORIZONTALE en flux, insérée dans #content juste sous les
   onglets / l'en-tête (barre violette) et au-dessus des messages. Vidéos alignées
   sur une rangée en PLEINE LARGEUR ; contrôles en pilule FLOTTANTE en bas ;
   hauteur RÉGLABLE par glisser (poignée en bas). Le chat se décale dessous. */
.groupcall-panel.gc-compact {
  position: relative; top: auto; right: auto; bottom: auto; left: auto;
  width: 100%; height: var(--gc-strip-h);
  /* Hauteur réglable (axe PRINCIPAL d'un flex column #content) : on la pilote en
     longhands valides — flex-basis + min-height = la var (le raccourci
     `flex: 0 0 var()` est invalide et serait ignoré). */
  flex-grow: 0; flex-shrink: 0; flex-basis: var(--gc-strip-h);
  min-height: var(--gc-strip-h);
  z-index: 5;
  flex-direction: row; align-items: stretch;
  background: var(--bg2);
  backdrop-filter: none; -webkit-backdrop-filter: none;
  border: none; border-bottom: 1px solid var(--border);
  border-radius: 0; box-shadow: none;
}
/* En-tête « 📞 #canal » FLOTTANT en haut-gauche (ne mange pas la largeur). */
.groupcall-panel.gc-compact .gc-channel {
  position: absolute; top: 6px; left: 8px; z-index: 4;
  padding: 3px 9px; font-size: 11px; font-weight: 700;
  color: #fff; letter-spacing: 0.01em;
  background: rgba(0,0,0,0.45); border-radius: 14px;
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  max-width: 50%;
}
.groupcall-panel.gc-compact .gc-channel-ico { color: #ff7a6e; }
/* Rangée de vidéos HORIZONTALE PLEINE LARGEUR (scroll-x si beaucoup). */
.groupcall-panel.gc-compact .gc-grid {
  display: flex; flex-direction: row; flex-wrap: nowrap;
  overflow-x: auto; overflow-y: hidden;
  align-items: center; justify-content: center;
  flex: 1 1 auto; min-width: 0;
  padding: 8px 10px 10px; gap: 8px;
  scrollbar-width: thin;
}
.groupcall-panel.gc-compact .gc-grid::-webkit-scrollbar { height: 4px; }
.groupcall-panel.gc-compact .gc-grid::-webkit-scrollbar-thumb { background: var(--border); border-radius: 2px; }
.groupcall-panel.gc-compact .gc-tile {
  flex: 0 0 auto; height: calc(var(--gc-strip-h) - 18px); width: auto; aspect-ratio: 4 / 3;
  border-radius: 10px; border: 1px solid var(--border);
}
.groupcall-panel.gc-compact .gc-name { font-size: 10px; padding: 1px 6px; }
/* Contrôles FLOTTANTS en bas-centre (pilule translucide, superposée aux vidéos)
   → libère toute la largeur pour les vidéos. */
.groupcall-panel.gc-compact .gc-bar {
  position: absolute; bottom: 10px; left: 50%; transform: translateX(-50%);
  display: flex; flex-wrap: nowrap; justify-content: center; align-items: center;
  padding: 6px 10px; gap: 8px; flex: 0 0 auto; z-index: 6;
  background: rgba(0,0,0,0.5); border-radius: 24px;
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  box-shadow: 0 4px 14px rgba(0,0,0,0.35);
  border: none; max-width: calc(100% - 24px); overflow-x: auto;
}
/* Mode RÉDUIT (minimiser) : fine barre, vidéos masquées ; contrôles + label
   restent visibles. Parité avec le minimiser du 1-to-1. */
.groupcall-panel.gc-compact.gc-collapsed {
  height: 42px; min-height: 42px; flex-basis: 42px;
}
.groupcall-panel.gc-compact.gc-collapsed .gc-grid,
.groupcall-panel.gc-compact.gc-collapsed .gc-resize { display: none; }
.groupcall-panel.gc-compact.gc-collapsed .gc-bar {
  bottom: auto; top: 50%; transform: translate(-50%, -50%);
}
/* ── Appel de GROUPE AUDIO (aucune vidéo live) → bande ULTRA-FINE ──────────────
   Même esprit que le 1-to-1 : pas de rangée vidéo vide, juste le label du canal
   et les contrôles sur un bandeau d'~48px. Piloté par _refreshVideoTiles
   (gc-audio-only). S'agrandit dès qu'une vidéo apparaît. */
.groupcall-panel.gc-compact.gc-audio-only {
  height: 48px; min-height: 48px; flex-basis: 48px;
  align-items: center; gap: 8px; padding: 0 10px;
}
.groupcall-panel.gc-compact.gc-audio-only .gc-grid,
.groupcall-panel.gc-compact.gc-audio-only .gc-resize { display: none; }
/* DÉBORDEMENT MOBILE (titre du canal qui dépassait / chevauchait les contrôles) :
   on abandonne l'empilement en position:absolute (label à gauche + pilule centrée
   se chevauchaient sur écran étroit) au profit d'un VRAI flex en ligne — label qui
   tronque (min-width:0 + ellipsis) à gauche, contrôles poussés à droite. */
.groupcall-panel.gc-compact.gc-audio-only .gc-channel {
  position: static; top: auto; left: auto; transform: none;
  flex: 0 1 auto; min-width: 0; max-width: none;
  background: transparent; backdrop-filter: none; -webkit-backdrop-filter: none;
  padding: 0; color: var(--text);   /* lisible sur le fond clair (était #fff) */
}
.groupcall-panel.gc-compact.gc-audio-only .gc-bar {
  position: static; top: auto; left: auto; bottom: auto; transform: none;
  margin-left: auto; flex: 0 0 auto;
  background: transparent; box-shadow: none; padding: 0;
  backdrop-filter: none; -webkit-backdrop-filter: none;
  max-width: none; overflow: visible;
}
/* Mobile étroit : boutons + serrés pour laisser de la place au label. */
@media (max-width: 560px) {
  .groupcall-panel.gc-compact.gc-audio-only { gap: 6px; padding: 0 8px; }
  .groupcall-panel.gc-compact.gc-audio-only .gc-bar { gap: 6px; }
  .groupcall-panel.gc-compact.gc-audio-only .gc-btn { width: 32px; height: 32px; }
}
/* La pilule de contrôles devient transparente sur le fond clair (var(--bg2)) du
   panneau → les icônes blanches d'origine disparaissaient. On repasse en couleurs
   THÉMATISÉES : fond gris doux (var(--hover)) + icône texte (var(--text)) → lisible
   sur paper ET sur les thèmes sombres. Actif = accent, raccrocher = rouge. */
.groupcall-panel.gc-compact.gc-audio-only .gc-btn {
  background: var(--hover); color: var(--text);
}
.groupcall-panel.gc-compact.gc-audio-only .gc-btn:hover { background: var(--muted); color: var(--bg2); }
.groupcall-panel.gc-compact.gc-audio-only .gc-btn.gc-on { background: var(--accent); color: #fff; }
.groupcall-panel.gc-compact.gc-audio-only .gc-btn.gc-hangup { background: #c0392b; color: #fff; }
.groupcall-panel.gc-compact.gc-audio-only .gc-btn.gc-hangup:hover { background: #d6442f; color: #fff; }
/* Poignée de redimensionnement : bord bas, glisser vertical pour agrandir. */
.groupcall-panel.gc-compact .gc-resize {
  position: absolute; left: 0; right: 0; bottom: 0; height: 8px;
  cursor: ns-resize; z-index: 7;
  display: flex; align-items: center; justify-content: center;
}
.groupcall-panel.gc-compact .gc-resize::before {
  content: ''; width: 44px; height: 3px; border-radius: 3px;
  background: var(--border2, #888); opacity: 0.55; transition: opacity 0.12s, width 0.12s;
}
.groupcall-panel.gc-compact .gc-resize:hover::before { opacity: 0.9; width: 60px; }
.groupcall-panel.gc-compact.gc-resizing { user-select: none; }
.groupcall-panel.gc-compact.gc-resizing .gc-grid { pointer-events: none; }
/* La poignée n'a de sens qu'en compact : masquée en plein écran. */
.groupcall-panel.gc-fullscreen .gc-resize { display: none; }
.groupcall-panel.gc-compact .gc-btn {
  width: 36px; height: 36px; font-size: 15px;
  background: rgba(255,255,255,0.14); color: #fff;
}
.groupcall-panel.gc-compact .gc-btn:hover { background: rgba(255,255,255,0.26); }
.groupcall-panel.gc-compact .gc-btn.gc-on { background: var(--accent, #5b8cff); color: #fff; }
.groupcall-panel.gc-compact .gc-btn.gc-hangup { background: #c0392b; color: #fff; }
.groupcall-panel.gc-compact .gc-btn.gc-hangup:hover { background: #d6442f; }
/* Bouton désactivé (ex. partage d'écran non supporté → iOS). */
.groupcall-panel .gc-btn.gc-disabled { opacity: 0.4; }

/* Plaque LOGO DoraCom à gauche de la bande vidéo (branding « bien joué »). */
.groupcall-panel .gc-brand {
  display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 2px;
  flex: 0 0 auto;
  color: #eef2f8;            /* bulle + serrure claires sur fond sombre */
  --bg2: #0b0f16;            /* découpe de la serrure = fond sombre du panneau */
}
.groupcall-panel .gc-brand .gc-brand-mark { display: inline-flex; filter: drop-shadow(0 0 7px rgba(91, 140, 255, 0.5)); }
.groupcall-panel .gc-brand svg { width: 38px; height: 38px; display: block; }
.groupcall-panel .gc-brand-text {
  font-size: 8.5px; font-weight: 700; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--accent, #5b8cff);
}
.groupcall-panel.gc-compact .gc-brand {
  flex-direction: row; gap: 6px;
  width: 100%; height: auto; padding: 10px 8px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
  background: radial-gradient(circle at 50% 50%, rgba(91, 140, 255, 0.13), transparent 72%);
}
.groupcall-panel.gc-compact .gc-brand svg { width: 30px; height: 30px; }
/* Label du CANAL de l'appel : « 📞 #nom-du-canal » pour ne pas être perdu. */
.groupcall-panel .gc-channel {
  display: flex; align-items: center; gap: 6px;
  flex: 0 0 auto; min-width: 0;
  padding: 7px 10px; font-size: 11.5px; font-weight: 700;
  color: #d4ddea; letter-spacing: 0.01em;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}
.groupcall-panel .gc-channel-ico { display: inline-flex; flex: 0 0 auto; color: var(--accent, #5b8cff); }
.groupcall-panel .gc-channel-ico svg { width: 14px; height: 14px; display: block; }
.groupcall-panel .gc-channel-name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Bouton RETOUR : caché hors plein écran ; en plein écran, pastille en haut à
   gauche pour quitter le mode vidéos plein écran / spotlight (parité Échap). */
/* .gc-btn.gc-back (0,3,0) pour battre `.groupcall-panel .gc-btn{display:flex}`
   défini plus bas (même spécificité 0,2,0, source plus tardive sinon gagnante). */
.groupcall-panel .gc-btn.gc-back { display: none; }
.groupcall-panel.gc-fullscreen .gc-back {
  display: flex;
  position: absolute; top: 14px; left: 14px; z-index: 7;
  background: rgba(0, 0, 0, 0.5);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.4);
}
.groupcall-panel.gc-fullscreen .gc-back:hover { background: rgba(0, 0, 0, 0.7); }
/* Plein écran : pilule centrée en haut, fond sombre autonome (lisible sur vidéo). */
.groupcall-panel.gc-fullscreen .gc-channel {
  position: absolute; top: 14px; left: 50%; transform: translateX(-50%); z-index: 5;
  border: none; border-radius: 20px; padding: 5px 14px;
  background: rgba(0, 0, 0, 0.45); color: #fff;
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  max-width: 60%;
}
.groupcall-panel.gc-fullscreen .gc-brand {
  position: absolute; top: 14px; left: 18px; z-index: 4;
  flex-direction: row; gap: 7px; opacity: 0.9; background: none;
}
.groupcall-panel.gc-fullscreen .gc-brand svg { width: 30px; height: 30px; }
.groupcall-panel.gc-fullscreen .gc-brand-text { font-size: 12px; }
.groupcall-panel .gc-grid {
  flex: 1; min-height: 0;
  display: grid;
  grid-template-columns: repeat(var(--gc-cols, 1), 1fr);
  gap: 8px; padding: 12px;
  align-content: center; justify-items: stretch;
}
.groupcall-panel .gc-tile {
  position: relative; background: #11151c; border-radius: 14px;
  overflow: hidden; aspect-ratio: 16 / 10;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid rgba(255, 255, 255, 0.06);
  cursor: pointer;
  transition: box-shadow 0.12s ease, border-color 0.12s ease;
}
/* Quelqu'un PARLE → bordure verte qui s'allume. */
.groupcall-panel .gc-tile.gc-speaking {
  border-color: #4ade80;
  box-shadow: 0 0 0 3px #4ade80, 0 0 18px 2px rgba(74, 222, 128, 0.55);
}
.groupcall-panel .gc-speak-dot {
  position: absolute; top: 8px; right: 8px;
  font-size: 13px; opacity: 0; transition: opacity 0.12s;
  filter: drop-shadow(0 0 4px rgba(74, 222, 128, 0.9));
}
/* Bouton pointeur actif + curseur "viseur" sur les vidéos en mode pointeur. */
.groupcall-panel .gc-btn.gc-on { background: #ff3b30; color: #fff; }
.groupcall-panel.gc-pointer-mode .gc-tile { cursor: crosshair; }
/* En mode pointeur : vidéos en `contain` → toute la frame partagée est visible
   (pas de rognage), et la projection du clic est exacte (anti-décalage). */
.groupcall-panel.gc-pointer-mode .gc-tile video { object-fit: contain; background: #000; }
/* Point rouge réseau (laser) — fixe à l'écran, fondu. */
.gc-pointer-dot {
  position: fixed; z-index: 2147483646; width: 18px; height: 18px;
  margin: -9px 0 0 -9px; border-radius: 50%; pointer-events: none;
  background: var(--gc-pt-color, #ff3b30);
  border: 2px solid #fff;
  box-shadow: 0 0 0 2px var(--gc-pt-color, #ff3b30), 0 0 12px 3px var(--gc-pt-color, #ff3b30);
  animation: gc-pointer-fade 2.5s ease-out forwards;
}
.gc-pointer-name {
  position: absolute; left: 50%; top: 22px; transform: translateX(-50%);
  white-space: nowrap; font-size: 11px; font-weight: 700; color: #fff;
  background: var(--gc-pt-color, #ff3b30); padding: 1px 6px; border-radius: 6px;
  text-shadow: 0 1px 2px rgba(0,0,0,.4);
}
@keyframes gc-pointer-fade {
  0%   { transform: scale(2.2); opacity: 0; }
  12%  { transform: scale(1); opacity: 1; }
  70%  { opacity: 1; }
  100% { opacity: 0; }
}
.groupcall-panel .gc-tile.gc-speaking .gc-speak-dot { opacity: 1; }
/* Caméra coupée → fond + pictogramme. */
.groupcall-panel .gc-tile.gc-camoff video { display: none; }
.groupcall-panel .gc-tile.gc-camoff::after {
  content: '📷'; position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: 40px; opacity: 0.4;
}
/* Appel audio / caméra coupée → tuile MASQUÉE (pas de vignette vide). On
   n'affiche une tuile que quand une vidéo est réellement active. */
.groupcall-panel .gc-tile.gc-novideo { display: none !important; }
/* Indice « audio seul » centré dans la grille quand aucune vidéo n'est visible
   (sinon la bande serait vide). Caché dès qu'une caméra s'active. */
.gc-audio-hint { display: none; }
.groupcall-panel.gc-audio-only .gc-audio-hint {
  display: flex; align-items: center; justify-content: center;
  grid-column: 1 / -1; min-height: 60px;
  color: var(--muted, #9aa); font-size: 13px; font-weight: 600;
  letter-spacing: 0.02em; opacity: 0.85;
}
/* ── Spotlight : une tuile agrandie + les autres en miniatures ──────────────── */
/* Spotlight : uniquement en plein écran. Sélecteur scopé `.gc-fullscreen` →
   spécificité plus forte que `.gc-fullscreen .gc-grid` (sinon la grille
   l'écraserait). Tuile en avant en haut, les autres en miniatures dessous. */
.groupcall-panel.gc-fullscreen .gc-grid.gc-spotlight-mode {
  display: flex; flex-wrap: wrap; align-content: flex-start;
  gap: 8px; padding: 12px;
}
.groupcall-panel.gc-fullscreen .gc-grid.gc-spotlight-mode .gc-tile {
  flex: 0 0 170px; aspect-ratio: 16 / 10;
}
.groupcall-panel.gc-fullscreen .gc-grid.gc-spotlight-mode .gc-tile.gc-spot {
  flex: 1 1 100%; order: -1; aspect-ratio: auto;
  height: calc(100% - 130px); min-height: 0;
}
/* Tuile mise en avant : on montre TOUT le cadre (pas de crop déformant). */
.groupcall-panel .gc-tile.gc-spot video { object-fit: contain; background: #000; }

/* ── Mode VIDÉOS PLEIN ÉCRAN (toggle « onglet léger ») ──────────────────────── */
.groupcall-panel.gc-fullscreen {
  height: 100vh; border-radius: 0;
}
.groupcall-panel.gc-fullscreen .gc-grid {
  display: grid;
  grid-template-columns: repeat(var(--gc-cols, 1), 1fr);
  gap: 10px; padding: 16px;
  align-content: center; justify-items: stretch;
}

.groupcall-panel .gc-tile.gc-local { border-color: var(--accent, #5b8cff); }
.groupcall-panel .gc-tile video {
  width: 100%; height: 100%; object-fit: cover; background: #11151c;
}
.groupcall-panel .gc-name {
  position: absolute; left: 8px; bottom: 8px;
  padding: 2px 8px; border-radius: 8px;
  background: rgba(0, 0, 0, 0.55); color: #fff;
  font-size: 12px; font-weight: 600; max-width: 80%;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Barre de commandes FLOTTANTE superposée sur les vidéos (pilule centrée bas). */
.groupcall-panel .gc-bar {
  position: absolute; bottom: 10px; left: 50%; transform: translateX(-50%);
  display: flex; gap: 10px; align-items: center;
  padding: 7px 12px; border-radius: 30px;
  background: rgba(0, 0, 0, 0.5);
  backdrop-filter: blur(6px);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.4);
  z-index: 6;
}
.groupcall-panel .gc-btn {
  width: 42px; height: 42px; border-radius: 50%;
  border: none; cursor: pointer; font-size: 18px;
  background: #232a36; color: #fff;
  display: flex; align-items: center; justify-content: center;
  transition: background 0.15s, transform 0.1s;
}
.groupcall-panel .gc-btn svg { width: 20px; height: 20px; display: block; }
.groupcall-panel.gc-compact .gc-btn svg { width: 17px; height: 17px; }
.groupcall-panel .gc-btn:hover { background: #2e3744; }
.groupcall-panel .gc-btn:active { transform: scale(0.94); }
.groupcall-panel .gc-btn.gc-off { background: #4a3a12; }
.groupcall-panel .gc-btn.gc-on { background: var(--accent, #5b8cff); }
.groupcall-panel .gc-btn.gc-hangup { background: #c0392b; }
.groupcall-panel .gc-btn.gc-hangup:hover { background: #d6442f; }
@media (max-width: 640px) {
  .groupcall-panel .gc-grid { grid-template-columns: repeat(var(--gc-cols, 1), 1fr); padding: 6px; gap: 6px; }
  .groupcall-panel .gc-btn { width: 48px; height: 48px; font-size: 20px; }
}

/* Neutralisation (shadow-mute) : marqueur de message visible des admins. */
.msg-neutralized-badge {
  font-size: 10px; padding: 1px 6px; border-radius: 6px;
  background: rgba(224, 108, 108, 0.15); color: #e06c6c;
  font-weight: 600; margin-left: 4px; white-space: nowrap;
}
.msg-card-neutralized { border-left: 2px solid rgba(224, 108, 108, 0.5); }

/* Aide modération (channel settings → membres) : encart repliable owner/admin. */
.mod-help {
  margin: 6px 0 10px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: color-mix(in srgb, var(--accent) 5%, transparent);
}
.mod-help-summary {
  cursor: pointer;
  padding: 8px 12px;
  font-size: 12px;
  font-weight: 600;
  color: var(--accent);
  user-select: none;
  list-style: none;
}
.mod-help-summary::-webkit-details-marker { display: none; }
.mod-help-summary::before { content: '▸ '; }
.mod-help[open] .mod-help-summary::before { content: '▾ '; }
.mod-help-body {
  padding: 4px 12px 10px;
  font-size: 12px;
  line-height: 1.5;
  color: var(--text2, var(--text));
}
.mod-help-body p { margin: 0 0 8px; }
.mod-help-body p:last-child { margin-bottom: 0; }
.mod-help-body strong { color: var(--text); }
.mod-help-note { font-style: italic; opacity: 0.8; }
@supports not (color: color-mix(in srgb, red, blue)) {
  .mod-help { background: rgba(124,106,247,0.05); }
}

/* Canal / onglet qui CLIGNOTE quand un appel de groupe y arrive (qui appelle). */
@keyframes gc-call-blink {
  0%, 100% { background-color: transparent; }
  50% { background-color: rgba(74, 222, 128, 0.22); }
}
.channel-item.channel-calling {
  animation: gc-call-blink 1s ease-in-out infinite;
  border-radius: 8px;
  box-shadow: inset 3px 0 0 #4ade80;
}
.channel-item.channel-calling::after {
  content: '📞';
  margin-left: auto;
  font-size: 13px;
  animation: gc-call-blink 1s ease-in-out infinite;
}
.tab.tab-calling {
  animation: gc-call-blink 1s ease-in-out infinite;
  box-shadow: inset 0 -2px 0 #4ade80;
}

/* ── Paiements P2P : carte de paiement (DM + canaux) ─────────────────────────── */
.dcpay-card {
  border: 1px solid var(--border);
  border-radius: 12px;
  background: color-mix(in srgb, var(--accent) 6%, var(--bg2, transparent));
  padding: 12px 14px;
  max-width: 320px;
  font-size: 13px;
}
.dcpay-card.is-paid { opacity: 0.85; border-color: #4ade80; }
.dcpay-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.dcpay-rail { font-weight: 700; color: var(--text); }
.dcpay-dir { font-size: 11px; color: var(--text2, var(--muted)); text-transform: uppercase; letter-spacing: 0.05em; }
.dcpay-amount { font-size: 22px; font-weight: 800; color: var(--text); margin: 6px 0 2px; }
.dcpay-memo { font-size: 12px; color: var(--text2, var(--muted)); margin-bottom: 6px; font-style: italic; }
.dcpay-to {
  font-family: ui-monospace, "JetBrains Mono", monospace; font-size: 11px;
  color: var(--text2, var(--muted)); background: rgba(0,0,0,0.18);
  border-radius: 6px; padding: 5px 8px; margin-bottom: 8px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.dcpay-actions { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.dcpay-btn {
  font-size: 12px; font-weight: 600; padding: 6px 12px; border-radius: 8px;
  border: 1px solid var(--border); cursor: pointer; text-decoration: none;
  display: inline-flex; align-items: center; line-height: 1;
}
.dcpay-pay { background: var(--accent, #5b8cff); color: #fff; border-color: transparent; }
.dcpay-pay:hover { filter: brightness(1.08); }
.dcpay-ghost { background: transparent; color: var(--text); }
.dcpay-ghost:hover { background: color-mix(in srgb, var(--accent) 12%, transparent); }
.dcpay-status.paid { color: #4ade80; font-weight: 700; font-size: 12px; }
.dcpay-warn { font-size: 10.5px; color: var(--text3, var(--muted)); margin-top: 8px; line-height: 1.4; opacity: 0.85; }
@supports not (color: color-mix(in srgb, red, blue)) {
  .dcpay-card { background: rgba(124,106,247,0.06); }
}
/* Compositeur */
.dcpay-seg { display: flex; gap: 14px; margin-bottom: 6px; font-size: 13px; }
.dcpay-amt-row { display: flex; gap: 10px; }
.dcpay-amt { flex: 1.4; min-width: 0; } .dcpay-cur { flex: 1; min-width: 0; }
.dcpay-amt-row .form-input { width: 100%; box-sizing: border-box; }
.dcpay-savecheck { display: flex; align-items: center; gap: 7px; font-size: 12px; color: var(--text2, var(--muted)); margin: 4px 0 2px; cursor: pointer; }
.dcpay-qrbox { display: flex; justify-content: center; padding: 14px; background: #fff; border-radius: 10px; margin: 6px 0; }
.dcpay-qruri { font-family: ui-monospace, monospace; font-size: 10px; word-break: break-all; color: var(--text2, var(--muted)); text-align: center; }
/* Note auto-confirmation Lightning sur la carte */
.dcpay-auto { font-size: 11px; color: var(--accent, #7c6af7); margin-top: 6px; font-weight: 600; }
/* Accusé « paiement reçu » (message dcpay-paid) */
.dcpay-paidnote { font-size: 12.5px; font-weight: 600; color: #1a8d4a; display: inline-flex; align-items: center; gap: 6px; padding: 4px 2px; }
/* Réglages paiement (Options → Paiements) */
.dcpay-settings { gap: 18px; }
.dcpay-set-section { display: flex; flex-direction: column; gap: 8px; }
.dcpay-set-head { font-size: 13px; font-weight: 700; color: var(--text); }
.dcpay-set-desc { font-size: 11.5px; color: var(--text2, var(--muted)); line-height: 1.45; }
.dcpay-set-row { display: flex; align-items: center; gap: 8px; padding: 7px 0; border-bottom: 1px solid var(--hairline, rgba(255,255,255,.07)); }
.dcpay-set-rail { font-size: 12px; font-weight: 600; flex-shrink: 0; min-width: 92px; }
.dcpay-set-val { flex: 1; min-width: 0; font-family: ui-monospace, monospace; font-size: 11px; color: var(--text2, var(--muted)); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dcpay-set-empty { font-size: 11.5px; color: var(--text2, var(--muted)); line-height: 1.45; font-style: italic; }
.dcpay-set-status { font-size: 12px; color: var(--text2, var(--muted)); }
.dcpay-set-btns { display: flex; gap: 8px; flex-wrap: wrap; }

/* ── Sonneries custom (mémo vocal) ── */
.rt-status { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; }
.rt-row { display: flex; justify-content: space-between; align-items: center; gap: 10px;
  padding: 8px 10px; border: 1px solid var(--hairline, rgba(255,255,255,.08));
  border-radius: 8px; background: var(--bg2, rgba(255,255,255,.02)); font-size: 13px; }
.rt-row .rt-state { color: var(--text2, var(--muted)); font-size: 12px; white-space: nowrap; }
.rt-actions { display: flex; flex-direction: column; gap: 8px; }
.rt-actions .btn { justify-content: flex-start; gap: 8px; }
.rt-toggle { display: flex; align-items: center; gap: 8px; cursor: pointer; font-weight: 600; }
.rt-toggle input { flex-shrink: 0; }
.rt-del { background: none; border: none; color: var(--red, #e0245e); cursor: pointer;
  font-size: 13px; padding: 0 4px; margin-left: 6px; }
.rt-del:hover { opacity: 0.7; }
.btn-ringtone { font-size: 15px; line-height: 1; }
