/* ══════════════════════════════════════════════════════════════════════════
   XOR v3 — Feuille de style

   Cible : téléphone, en application installée. D'où les partis pris :
     · 100dvh et safe-area-inset, pour ne pas passer sous l'encoche ni sous la
       barre d'accueil iOS
     · transitions en transform/opacity uniquement (composées par le GPU)
     · aucune sélection ni surbrillance tactile par défaut, sauf sur le texte
       des messages et les champs de saisie
   ══════════════════════════════════════════════════════════════════════════ */

:root {
  --bg:        #0b1416;
  --bg2:       #111e21;
  --bg3:       #16282c;
  --bg4:       #1d343a;
  --brd:       #1f3a40;
  --brd2:      #2a4b52;

  --t1:        #eef6f7;
  --t2:        #8fa8ad;
  --t3:        #5d777d;

  --b:         #0a5a63;
  --bl:        #0e7d89;
  --bl2:       #14a3b2;
  --accent:    #14a3b2;

  --mine:      #0d5f68;
  --theirs:    #1b3035;

  --red:       #ff453a;
  --green:     #30d158;
  --amber:     #ffd60a;

  --r-sm:  8px;
  --r-md:  12px;
  --r-lg:  18px;
  --r-xl:  24px;

  --hd:    54px;
  --safe-t: env(safe-area-inset-top, 0px);
  --safe-b: env(safe-area-inset-bottom, 0px);

  --ease:  cubic-bezier(.32, .72, 0, 1);
}

* { margin: 0; padding: 0; box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

html, body {
  height: 100%;
  overflow: hidden;
  overscroll-behavior: none;
}

body {
  background: var(--bg);
  color: var(--t1);
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif;
  font-size: 15px;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
  user-select: none;
  -webkit-user-select: none;
  touch-action: manipulation;
}

input, textarea, [contenteditable] { user-select: text; -webkit-user-select: text; }

button { font-family: inherit; color: inherit; background: none; border: none; cursor: pointer; }

/* `hidden` doit l'emporter sur les `display:flex` posés plus bas, sinon les
   éléments masqués par défaut (zone de réponse, « écrit… ») restent visibles. */
[hidden] { display: none !important; }

/* Un <svg><use/></svg> sans dimensions s'affiche à sa taille intrinsèque, soit
   300×150. On impose donc une taille par défaut.
   Largeur ET hauteur explicites : sur un <svg> dépourvu d'attribut de largeur,
   `width:auto` se résout à 100% du conteneur, ce qui faisait déborder les
   icônes en ligne et écrasait le texte voisin. preserveAspectRatio se charge
   de faire tenir proprement les symboles non carrés (le double-check est 30×24). */
svg { width: 19px; height: 19px; flex: 0 0 auto; display: inline-block; vertical-align: -.18em; }

/* La bibliothèque de symboles ne doit occuper aucune place. */
#icon-sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

::-webkit-scrollbar { width: 0; height: 0; }

/* ── Écrans empilés ────────────────────────────────────────────────────── */
.sc {
  position: fixed;
  inset: 0;
  display: flex;
  flex-direction: column;
  background: var(--bg);
  transform: translateX(100%);
  transition: transform .3s var(--ease);
  will-change: transform;
  z-index: 1;
}
.sc.on   { transform: translateX(0); z-index: 2; }
.sc.back { transform: translateX(-22%); z-index: 1; }
.sc.instant { transition: none; }

/* L'écran de démarrage ne glisse pas comme les autres : il s'efface.
   Un écran de lancement qui part sur le côté trahirait une navigation,
   alors qu'il ne fait que céder la place. */
#sc-boot { transform: none; transition: opacity .28s; }
#sc-boot:not(.on) { opacity: 0; pointer-events: none; }

/* ── En-tête ───────────────────────────────────────────────────────────── */
.hd {
  flex: 0 0 auto;
  height: calc(var(--hd) + var(--safe-t));
  padding: var(--safe-t) 8px 0;
  display: flex;
  align-items: center;
  gap: 6px;
  background: rgba(17, 30, 33, .82);
  backdrop-filter: saturate(180%) blur(20px);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  border-bottom: .5px solid var(--brd);
  position: relative;
  z-index: 5;
}
.hd-title { font-size: 17px; font-weight: 700; letter-spacing: -.2px; }
.hd-sub   { font-size: 11.5px; color: var(--t2); line-height: 1.25; }
.hd-grow  { flex: 1; min-width: 0; }
.hd-txt   { min-width: 0; flex: 1; }
.hd-txt .hd-title { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.ib {
  width: 38px; height: 38px;
  display: grid; place-items: center;
  border-radius: 50%;
  color: var(--t1);
  flex: 0 0 auto;
  transition: background .15s;
}
.ib:active { background: var(--bg4); }
.ib svg { width: 21px; height: 21px; }

/* ── Avatars ───────────────────────────────────────────────────────────── */
.av {
  flex: 0 0 auto;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--b), var(--bl2));
  display: grid; place-items: center;
  font-weight: 650;
  color: #fff;
  overflow: hidden;
  position: relative;
}
/* L'image se superpose aux initiales et n'apparaît qu'une fois chargée :
   pas de carré vide ni d'icône « image cassée » pendant le téléchargement. */
.av img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover; display: block;
  opacity: 0; transition: opacity .2s;
}
.av img.ready { opacity: 1; }
.av-52 { width: 52px; height: 52px; font-size: 19px; }
.av-38 { width: 38px; height: 38px; font-size: 15px; }
.av-30 { width: 30px; height: 30px; font-size: 12px; }
.av-84 { width: 84px; height: 84px; font-size: 32px; }
.av.grp { background: linear-gradient(135deg, #4a3d8f, #7b5ec7); }

.dot-on {
  position: absolute; right: 0; bottom: 0;
  width: 12px; height: 12px; border-radius: 50%;
  background: var(--green);
  border: 2.5px solid var(--bg);
}

/* ── Liste des conversations ───────────────────────────────────────────── */
.list { flex: 1; overflow-y: auto; -webkit-overflow-scrolling: touch; overscroll-behavior: contain; }
.list-pad { padding-bottom: calc(84px + var(--safe-b)); }

.row {
  display: flex; align-items: center; gap: 12px;
  padding: 9px 14px;
  position: relative;
  transition: background .12s;
}
.row:active { background: var(--bg3); }
.row-main { flex: 1; min-width: 0; }
.row-top  { display: flex; align-items: baseline; gap: 8px; }
.row-name {
  font-weight: 620; font-size: 15.5px; flex: 1;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.row-time { font-size: 11.5px; color: var(--t3); flex: 0 0 auto; }
.row-bot  { display: flex; align-items: center; gap: 6px; margin-top: 2px; }
.row-prev {
  flex: 1; min-width: 0; font-size: 13.5px; color: var(--t2);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.row-prev.locked { color: var(--t3); font-style: italic; }

.badge-n {
  min-width: 20px; height: 20px; padding: 0 6px;
  border-radius: 10px; background: var(--accent); color: #04191c;
  font-size: 11.5px; font-weight: 750;
  display: grid; place-items: center;
  flex: 0 0 auto;
}
.badge-mute { color: var(--t3); }
.badge-mute svg { width: 14px; height: 14px; display: block; }

.vbadge { flex: 0 0 auto; display: inline-flex; vertical-align: middle; margin-left: 4px; }
.vbadge svg { width: 14px; height: 14px; display: block; }

/* Version étiquetée, pour les fiches de profil et de contact. */
.badge-chip {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 10px 3px 7px;
  border-radius: 12px;
  border: 1px solid currentColor;
  font-size: 11.5px; font-weight: 700;
  letter-spacing: .3px; text-transform: uppercase;
  background: rgba(255, 255, 255, .05);
}
.badge-chip svg { width: 13px; height: 13px; display: block; }
.vb-verified { color: var(--bl2); }
.vb-official { color: var(--amber); }
.vb-partner  { color: #bf5af2; }
.vb-KDB      { color: var(--green); }

.pin-i { color: var(--t3); }
.pin-i svg { width: 13px; height: 13px; display: block; }

.sep { height: .5px; background: var(--brd); margin-left: 78px; }

/* ── Fil de discussion ─────────────────────────────────────────────────── */
.thread {
  flex: 1;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  padding: 10px 10px 4px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  background:
    radial-gradient(1200px 600px at 50% -10%, rgba(20, 163, 178, .06), transparent 70%),
    var(--bg);
}

.day {
  align-self: center;
  margin: 12px 0 8px;
  padding: 4px 12px;
  border-radius: 12px;
  background: var(--bg3);
  color: var(--t2);
  font-size: 11.5px;
  font-weight: 600;
}

.msg {
  max-width: 82%;
  display: flex;
  flex-direction: column;
  position: relative;
  transition: transform .18s var(--ease);
}
.msg.mine   { align-self: flex-end; align-items: flex-end; }
.msg.theirs { align-self: flex-start; align-items: flex-start; }
.msg.swipe  { transition: none; }

.msg + .msg.grouped { margin-top: -1px; }
.msg:not(.grouped)  { margin-top: 8px; }

.bub {
  padding: 7px 11px 6px;
  border-radius: var(--r-lg);
  background: var(--theirs);
  font-size: 15px;
  line-height: 1.38;
  word-break: break-word;
  overflow-wrap: anywhere;
  user-select: text; -webkit-user-select: text;
  position: relative;
  box-shadow: 0 1px 1.5px rgba(0, 0, 0, .22);   /* détache la bulle du fond */
}

/* Bulle de texte : l'heure se place au bout de la dernière ligne quand il reste
   de la place, et bascule dessous sinon. Sans cela, un « ok » donnait une bulle
   minuscule surmontant une ligne d'heure isolée. La largeur plancher évite les
   bulles trop étroites pour être lisibles. */
.bub:not(.media) {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  column-gap: 10px;
  row-gap: 1px;
  min-width: 100px;
}
.bub:not(.media) > .txt  { flex: 0 1 auto; min-width: 0; }
.bub:not(.media) > .meta { flex: 0 0 auto; margin-left: auto; }

/* Ces éléments occupent toujours leur propre ligne dans la bulle. */
.bub > .sender-n,
.bub > .reply-q,
.bub > .legacy-tag,
.bub > .under-media { flex: 0 0 100%; }

.mine .bub   { background: var(--mine); }
.mine   .bub { border-bottom-right-radius: 6px; }
.theirs .bub { border-bottom-left-radius: 6px; }

/* Messages consécutifs d'un même auteur : coin resserré côté expéditeur,
   pour que le bloc se lise comme une seule prise de parole. */
.msg.mine.grouped   .bub { border-top-right-radius: 6px; }
.msg.theirs.grouped .bub { border-top-left-radius: 6px; }

.bub.media  { padding: 3px 3px 5px; overflow: hidden; }
/* Photo ou vidéo sans légende : l'heure se pose SUR l'image, comme dans les
   messageries natives. Un fond translucide la garde lisible quel que soit le
   cliché ; sans lui, elle disparaîtrait sur les zones claires. */
.bub.only-media { background: transparent; padding: 0; box-shadow: none; position: relative; }
.bub.only-media > .meta {
  position: absolute; right: 9px; bottom: 9px; margin: 0;
  padding: 2px 8px; border-radius: 11px;
  background: rgba(0, 0, 0, .52);
  backdrop-filter: blur(5px); -webkit-backdrop-filter: blur(5px);
  color: rgba(255, 255, 255, .92);
}
.bub.only-media > .meta .tick-read { color: #7fe3ef; }
/* Légende accompagnant un média : toujours sur sa propre ligne. */
.bub.media > .txt { display: block; margin: 5px 5px 0; }

.sender-n { font-size: 12.5px; font-weight: 680; color: var(--bl2); margin-bottom: 2px; }

.meta {
  display: flex; align-items: center; gap: 4px; justify-content: flex-end;
  margin-top: 2px; font-size: 10.5px; color: var(--t3); line-height: 1;
  /* La bulle autorise la coupure n'importe où (pour les longues URL). Cette
     ligne d'informations, elle, ne doit jamais se casser : sans ce garde-fou,
     un élément trop large la ferait tomber en colonnes d'un caractère. */
  flex-wrap: nowrap; white-space: nowrap;
  overflow-wrap: normal; word-break: normal;
}
.mine .meta { color: rgba(238, 246, 247, .55); }
/* Boîte un peu plus large que haute : le double-check (30×24) y tient sans
   déformer, la coche simple (24×24) s'y centre. */
.meta svg, .row-bot svg { width: 15px; height: 13px; display: block; }
.tick { display: flex; flex: 0 0 auto; }
.tick-read { color: var(--bl2); }

.msg-legacy .bub { border: 1px dashed var(--brd2); }
.legacy-tag {
  display: flex; align-items: center; gap: 4px;
  font-size: 10px; color: var(--amber); opacity: .85; margin-top: 3px;
}
.legacy-tag svg { width: 12px; height: 12px; }

.msg-deleted .bub { background: transparent; border: 1px solid var(--brd); color: var(--t3); font-style: italic; }

.reply-q {
  border-left: 3px solid var(--bl2);
  padding: 3px 8px;
  margin-bottom: 4px;
  background: rgba(0, 0, 0, .18);
  border-radius: 5px;
  font-size: 13px;
}
.reply-q .rq-name { color: var(--bl2); font-weight: 650; font-size: 12px; display: block; }
.reply-q .rq-txt  { color: var(--t2); display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.reacts { display: flex; gap: 4px; margin-top: 3px; flex-wrap: wrap; }
.react {
  display: inline-flex; align-items: center; gap: 3px;
  padding: 2px 7px; border-radius: 11px;
  background: var(--bg3); border: 1px solid var(--brd);
  font-size: 12.5px;
}
.react.mine-r { background: var(--b); border-color: var(--bl2); }

.ttl-tag { display: inline-flex; align-items: center; gap: 3px; color: var(--amber); font-size: 10px; }
.ttl-tag svg { width: 11px; height: 11px; }

/* ── Médias dans une bulle ─────────────────────────────────────────────── */
.mth {
  position: relative;
  border-radius: 15px;
  overflow: hidden;
  background: var(--bg4);
  max-width: 260px;
  min-width: 120px;
  display: block;
}
.mth img { width: 100%; height: auto; display: block; max-height: 340px; object-fit: cover; }
.mth.blurred img { filter: blur(18px); transform: scale(1.06); }

.mth-play {
  position: absolute; inset: 0;
  display: grid; place-items: center;
  background: rgba(0, 0, 0, .25);
}
.mth-play span {
  width: 48px; height: 48px; border-radius: 50%;
  background: rgba(0, 0, 0, .55);
  backdrop-filter: blur(6px);
  display: grid; place-items: center;
}
.mth-play svg { width: 24px; height: 24px; color: #fff; }

.mth-dur {
  position: absolute; right: 6px; bottom: 6px;
  padding: 1px 6px; border-radius: 8px;
  background: rgba(0, 0, 0, .6);
  font-size: 11px; color: #fff;
}

.mth-prog {
  position: absolute; left: 0; right: 0; bottom: 0;
  height: 3px; background: rgba(255, 255, 255, .2);
}
.mth-prog i { display: block; height: 100%; background: var(--bl2); transition: width .2s; }

/* Document / fichier générique */
.doc {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 10px; min-width: 190px;
}
.doc-ic {
  width: 42px; height: 42px; border-radius: 11px;
  background: var(--bg4); display: grid; place-items: center; flex: 0 0 auto;
}
.doc-ic svg { width: 21px; height: 21px; color: var(--bl2); }
.doc-tx { min-width: 0; flex: 1; }
.doc-nm { font-size: 14px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.doc-sz { font-size: 11.5px; color: var(--t2); }

/* Message vocal */
.voice { display: flex; align-items: center; gap: 9px; padding: 6px 4px; min-width: 180px; }
.voice-btn { width: 36px; height: 36px; border-radius: 50%; background: var(--bl); display: grid; place-items: center; flex: 0 0 auto; }
.voice-btn svg { width: 18px; height: 18px; color: #fff; }
.voice-wave { flex: 1; height: 26px; display: flex; align-items: center; gap: 2px; }
.voice-wave i { flex: 1; background: var(--t3); border-radius: 1px; min-height: 3px; }
.voice-wave i.played { background: var(--bl2); }
.voice-dur { font-size: 11.5px; color: var(--t2); flex: 0 0 auto; }

/* ── Zone de saisie ────────────────────────────────────────────────────── */
.composer {
  flex: 0 0 auto;
  padding: 7px 8px calc(7px + var(--safe-b));
  background: rgba(17, 30, 33, .9);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  border-top: .5px solid var(--brd);
}
.comp-row { display: flex; align-items: flex-end; gap: 6px; }

.comp-in {
  flex: 1;
  min-height: 38px; max-height: 132px;
  padding: 8px 13px;
  border-radius: var(--r-xl);
  background: var(--bg3);
  border: 1px solid var(--brd);
  color: var(--t1);
  font-size: 15.5px; font-family: inherit; line-height: 1.35;
  resize: none; outline: none;
  overflow-y: auto;
}
.comp-in:focus { border-color: var(--bl); }
.comp-in::placeholder { color: var(--t3); }

.comp-btn {
  width: 38px; height: 38px; border-radius: 50%;
  display: grid; place-items: center; flex: 0 0 auto;
  color: var(--t2); transition: .15s;
}
.comp-btn svg { width: 22px; height: 22px; }
.comp-btn:active { background: var(--bg4); }
.comp-send { background: linear-gradient(135deg, var(--b), var(--bl2)); color: #fff; }
.comp-send:disabled { opacity: .35; }
.comp-send:active { transform: scale(.92); }

.comp-reply {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 10px; margin-bottom: 6px;
  background: var(--bg3); border-radius: var(--r-md);
  border-left: 3px solid var(--bl2);
}
.comp-reply .cr-tx { flex: 1; min-width: 0; font-size: 13px; }
.comp-reply .cr-nm { color: var(--bl2); font-weight: 650; font-size: 12px; display: block; }
.comp-reply .cr-bd { color: var(--t2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.typing-ind {
  display: flex; align-items: center; gap: 5px;
  padding: 2px 12px 5px; font-size: 12px; color: var(--bl2);
}
.typing-ind i { width: 5px; height: 5px; border-radius: 50%; background: var(--bl2); animation: tdot 1.3s infinite; }
.typing-ind i:nth-child(2) { animation-delay: .18s; }
.typing-ind i:nth-child(3) { animation-delay: .36s; }
@keyframes tdot { 0%, 60%, 100% { opacity: .25; transform: translateY(0); } 30% { opacity: 1; transform: translateY(-3px); } }

/* ── Bouton flottant ───────────────────────────────────────────────────── */
.fab {
  position: absolute;
  right: 18px;
  bottom: calc(20px + var(--safe-b));
  width: 56px; height: 56px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--b), var(--bl2));
  box-shadow: 0 6px 22px rgba(10, 90, 99, .5);
  display: grid; place-items: center;
  color: #fff;
  z-index: 10;
  transition: transform .18s var(--ease);
}
.fab:active { transform: scale(.9); }
.fab svg { width: 25px; height: 25px; }

/* ── Feuilles modales ──────────────────────────────────────────────────── */
.sheet-bg {
  position: fixed; inset: 0;
  background: rgba(0, 0, 0, .55);
  opacity: 0; pointer-events: none;
  transition: opacity .25s;
  z-index: 40;
  backdrop-filter: blur(2px);
}
.sheet-bg.on { opacity: 1; pointer-events: auto; }

.sheet {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  max-height: 88dvh;
  background: var(--bg2);
  border-radius: var(--r-xl) var(--r-xl) 0 0;
  border-top: .5px solid var(--brd2);
  transform: translateY(100%);
  transition: transform .32s var(--ease);
  z-index: 41;
  display: flex; flex-direction: column;
  padding-bottom: var(--safe-b);
}
.sheet.on { transform: translateY(0); }
.sheet.drag { transition: none; }

.sheet-grab { padding: 8px 0 4px; display: grid; place-items: center; flex: 0 0 auto; }
.sheet-grab i { width: 36px; height: 4px; border-radius: 2px; background: var(--brd2); display: block; }

.sheet-hd {
  padding: 4px 18px 12px;
  display: flex; align-items: center; gap: 10px;
  flex: 0 0 auto;
}
.sheet-hd h2 { font-size: 17px; font-weight: 700; flex: 1; }
.sheet-body { overflow-y: auto; -webkit-overflow-scrolling: touch; padding: 0 0 14px; }

.opt {
  display: flex; align-items: center; gap: 13px;
  padding: 13px 18px;
  font-size: 15.5px;
  transition: background .12s;
}
.opt:active { background: var(--bg3); }
.opt svg { width: 21px; height: 21px; color: var(--t2); flex: 0 0 auto; }
.opt-tx { flex: 1; min-width: 0; }
.opt-sub { font-size: 12.5px; color: var(--t2); margin-top: 1px; }
.opt-val { font-size: 13.5px; color: var(--t2); }
.opt.danger, .opt.danger svg { color: var(--red); }

.grp-title {
  padding: 16px 18px 6px;
  font-size: 11.5px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .7px;
  color: var(--t3);
}

/* ── Formulaires ───────────────────────────────────────────────────────── */
.ig { padding: 0 18px 13px; }
.ig label {
  display: block; font-size: 11px; font-weight: 650;
  color: var(--t2); margin-bottom: 5px;
  letter-spacing: .3px; text-transform: uppercase;
}
.ig input, .ig textarea, .ig select {
  width: 100%;
  padding: 12px 14px;
  border-radius: var(--r-md);
  border: 1.5px solid var(--brd);
  background: var(--bg3);
  color: var(--t1);
  font-size: 16px;            /* 16px : empêche iOS de zoomer au focus */
  font-family: inherit;
  outline: none;
  transition: border-color .18s;
}
.ig input:focus, .ig textarea:focus { border-color: var(--bl); }
.ig input::placeholder { color: var(--t3); }
.ig textarea { resize: none; min-height: 78px; }

.bp {
  width: 100%;
  padding: 13px;
  border-radius: var(--r-md);
  background: linear-gradient(135deg, var(--b), var(--bl2));
  color: #fff;
  font-size: 15px; font-weight: 700;
  letter-spacing: .2px;
  transition: transform .12s;
}
.bp:active { transform: scale(.985); }
.bp:disabled { opacity: .45; }
.bs {
  width: 100%; padding: 12px;
  border-radius: var(--r-md);
  background: var(--bg3); border: 1px solid var(--brd);
  font-size: 14.5px; font-weight: 620;
}
.btn-row { padding: 4px 18px 8px; display: flex; gap: 9px; }
.btn-row > * { flex: 1; }

.em {
  margin: 0 18px 12px;
  padding: 9px 12px;
  border-radius: var(--r-sm);
  background: rgba(255, 69, 58, .09);
  border: 1px solid rgba(255, 69, 58, .22);
  color: var(--red);
  font-size: 12.5px; text-align: center;
}
.ok-box {
  margin: 0 18px 12px; padding: 9px 12px;
  border-radius: var(--r-sm);
  background: rgba(48, 209, 88, .09);
  border: 1px solid rgba(48, 209, 88, .22);
  color: var(--green);
  font-size: 12.5px; text-align: center;
}

.switch {
  width: 46px; height: 28px; border-radius: 14px;
  background: var(--bg4); position: relative;
  flex: 0 0 auto; transition: background .2s;
}
.switch i {
  position: absolute; top: 3px; left: 3px;
  width: 22px; height: 22px; border-radius: 50%;
  background: #fff; transition: transform .2s var(--ease);
}
.switch.on { background: var(--bl2); }
.switch.on i { transform: translateX(18px); }

/* ── Authentification ──────────────────────────────────────────────────── */
.auth-wrap {
  flex: 1; display: flex; flex-direction: column; justify-content: center;
  padding: 24px 6px calc(24px + var(--safe-b));
  overflow-y: auto;
}
.auth-logo { text-align: center; margin-bottom: 26px; }
.auth-logo .li {
  width: 62px; height: 62px; margin: 0 auto 12px;
  border-radius: 19px;
  background: linear-gradient(135deg, var(--b), var(--bl2));
  display: grid; place-items: center;
  box-shadow: 0 8px 26px rgba(10, 90, 99, .45);
}
.auth-logo .li svg { width: 31px; height: 31px; color: #fff; }
.auth-logo h1 { font-size: 27px; font-weight: 750; letter-spacing: 3px; }
.auth-logo p  { font-size: 13px; color: var(--t2); margin-top: 3px; }

.auth-toggle { text-align: center; margin-top: 15px; font-size: 13.5px; color: var(--t2); }
.auth-toggle a { color: var(--bl2); font-weight: 650; }
.auth-foot {
  text-align: center; margin-top: 26px;
  font-size: 9.5px; letter-spacing: 1px;
  text-transform: uppercase; color: var(--t3);
}

/* ── Visionneuse plein écran ───────────────────────────────────────────── */
.viewer {
  position: fixed; inset: 0;
  background: #000;
  z-index: 60;
  display: none;
  flex-direction: column;
}
.viewer.on { display: flex; }

.viewer-hd {
  position: absolute; top: 0; left: 0; right: 0;
  padding: calc(var(--safe-t) + 8px) 10px 10px;
  display: flex; align-items: center; gap: 10px;
  background: linear-gradient(rgba(0, 0, 0, .75), transparent);
  z-index: 3;
  transition: opacity .25s;
}
.viewer.immersive .viewer-hd { opacity: 0; pointer-events: none; }
.viewer-nm { flex: 1; min-width: 0; font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.viewer-sub { font-size: 11.5px; color: var(--t2); }

.viewer-body {
  flex: 1;
  display: grid;
  place-items: center;
  overflow: hidden;
  position: relative;
  touch-action: none;
}
.viewer-body img {
  max-width: 100%; max-height: 100%;
  object-fit: contain;
  transform-origin: center center;
  will-change: transform;
}
.viewer-body video { max-width: 100%; max-height: 100%; background: #000; }
.viewer-body iframe { width: 100%; height: 100%; border: 0; background: #fff; }

.viewer-load {
  position: absolute; inset: 0;
  display: grid; place-items: center;
  gap: 10px;
  color: var(--t2);
  font-size: 13px;
}
.ring {
  width: 42px; height: 42px;
  border-radius: 50%;
  border: 3px solid rgba(255, 255, 255, .15);
  border-top-color: var(--bl2);
  animation: spin .9s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ── Menu contextuel sur un message ────────────────────────────────────── */
.ctx-bg { position: fixed; inset: 0; z-index: 50; background: rgba(0, 0, 0, .4); backdrop-filter: blur(3px); }
.ctx {
  position: fixed;
  min-width: 208px;
  background: var(--bg3);
  border: .5px solid var(--brd2);
  border-radius: 15px;
  overflow: hidden;
  z-index: 51;
  box-shadow: 0 14px 44px rgba(0, 0, 0, .6);
  transform-origin: top center;
  animation: pop .16s var(--ease);
}
@keyframes pop { from { transform: scale(.9); opacity: 0; } }
.ctx-it { display: flex; align-items: center; gap: 11px; padding: 12px 15px; font-size: 15px; }
.ctx-it:active { background: var(--bg4); }
.ctx-it svg { width: 19px; height: 19px; color: var(--t2); }
.ctx-it.danger, .ctx-it.danger svg { color: var(--red); }
.ctx-sep { height: .5px; background: var(--brd); }

.ctx-emo { display: flex; gap: 3px; padding: 9px 10px; border-bottom: .5px solid var(--brd); }
.ctx-emo button {
  width: 38px; height: 38px; border-radius: 50%;
  font-size: 22px; display: grid; place-items: center;
  transition: transform .12s;
}
.ctx-emo button:active { transform: scale(1.25); }

/* ── Divers ────────────────────────────────────────────────────────────── */
.empty {
  flex: 1; display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: 10px; padding: 40px 30px; text-align: center;
  color: var(--t3);
}
.empty svg { width: 52px; height: 52px; opacity: .35; }
.empty h3 { font-size: 16px; color: var(--t2); font-weight: 650; }
.empty p  { font-size: 13.5px; line-height: 1.5; }

.toast {
  position: fixed;
  left: 50%; bottom: calc(28px + var(--safe-b));
  transform: translate(-50%, 20px);
  padding: 10px 18px;
  border-radius: 22px;
  background: rgba(29, 52, 58, .96);
  border: .5px solid var(--brd2);
  backdrop-filter: blur(14px);
  font-size: 13.5px;
  z-index: 80;
  opacity: 0;
  transition: opacity .22s, transform .22s var(--ease);
  pointer-events: none;
  max-width: 84vw; text-align: center;
}
.toast.on { opacity: 1; transform: translate(-50%, 0); }
.toast.err { background: rgba(90, 26, 22, .96); border-color: rgba(255, 69, 58, .4); }

.ptr {
  position: absolute; top: calc(var(--hd) + var(--safe-t)); left: 0; right: 0;
  display: grid; place-items: center;
  height: 0; overflow: hidden;
  transition: height .2s;
  color: var(--t2);
}
.ptr .ring { width: 24px; height: 24px; border-width: 2.5px; }

.skel { padding: 9px 14px; display: flex; gap: 12px; align-items: center; }
.skel-c { width: 52px; height: 52px; border-radius: 50%; flex: 0 0 auto; }
.skel-l { flex: 1; }
.skel-b { height: 12px; border-radius: 6px; margin-bottom: 7px; }
.shim {
  background: linear-gradient(90deg, var(--bg3) 25%, var(--bg4) 50%, var(--bg3) 75%);
  background-size: 200% 100%;
  animation: shim 1.3s infinite;
}
@keyframes shim { to { background-position: -200% 0; } }

.chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 11px 6px 6px;
  border-radius: 18px;
  background: var(--bg3);
  border: 1px solid var(--brd);
  font-size: 13.5px;
  margin: 0 6px 6px 0;
}
.chip .x { color: var(--t3); font-size: 16px; line-height: 1; padding: 0 2px; }
.chips { padding: 0 18px 10px; display: flex; flex-wrap: wrap; }

.banner {
  padding: 9px 14px;
  background: rgba(255, 214, 10, .1);
  border-bottom: 1px solid rgba(255, 214, 10, .25);
  color: var(--amber);
  font-size: 12.5px;
  display: flex; align-items: center; gap: 8px;
}
.banner svg { width: 17px; height: 17px; flex: 0 0 auto; }
.banner.info { background: rgba(20, 163, 178, .1); border-color: rgba(20, 163, 178, .28); color: var(--bl2); }

.fp {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 14px; line-height: 1.9; letter-spacing: 1px;
  text-align: center; color: var(--t1);
  padding: 14px 18px; margin: 0 18px 12px;
  background: var(--bg3); border-radius: var(--r-md);
  user-select: text; -webkit-user-select: text;
}

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