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

:root {
  --bg: #f5f7fa;
  --sidebar-bg: #ffffff;
  --header-bg: #ffffff;
  --msg-bg: #eef1f5;
  --mine-bg: #cfe3f8;
  --accent: #3b7dd8;
  --accent-hover: #2f68b8;
  --success: #16a34a;
  --success-hover: #15803d;
  --danger: #dc2626;
  --danger-hover: #b91c1c;
  --text: #1f2937;
  --muted: #6b7280;
  --input-bg: #f0f2f5;
  --border: #e0e4e9;
  --online: #16a34a;
  --radius: 12px;
  --sidebar-w: 260px;
  /* safe area insets (0 on desktop, non-zero on notch devices) */
  /* How wide a picture in a message is, and therefore how wide its caption
     wraps: the two must match or the bubble looks broken. */
  --media-w: 250px;
  --sat: env(safe-area-inset-top, 0px);
  --sab: env(safe-area-inset-bottom, 0px);
}

/* ── Base ─────────────────────────────────────────── */

/* iOS Safari, and the reason the send button ends up half off the screen.
 *
 * Reported as: on the iPhone web version there is a little horizontal scroll,
 * and tapping send sometimes does nothing because the button is just past the
 * edge; pinching out fixes it.
 *
 * Nothing is actually too wide. Safari on iOS ZOOMS THE WHOLE PAGE IN when a
 * text field with a font smaller than 16px is focused — and it does not zoom
 * back out afterwards. The layout viewport is then wider than the screen, so
 * the page can be panned sideways and whatever sits at the right-hand end of a
 * row (the send button) is off it. That is why it happens after typing, why it
 * looks like "a little horizontal scroll", and why pinching to unzoom is the
 * cure people find.
 *
 * The fix is one number: every field somebody can focus is at least 16px.
 *
 * This rule is only the FLOOR, for fields added later. It cannot rescue a
 * field that sets its own size — `#msg-input { font-size: 0.95rem }` further
 * down this file has a higher specificity and would win — so each such rule
 * carries the 16px itself, and test/webViewport.test.js reads them all back
 * out of this file and fails on any that does not.
 */
input:not([type=checkbox]):not([type=radio]):not([type=file]),
textarea,
select {
  font-size: 16px;
}

/* Nothing in a column may make the page wider than the phone. A row that
 * cannot fit scrolls inside itself; the page itself never does. */
html, body { width: 100%; max-width: 100%; overflow-x: hidden; }

html, body {
  height: 100%;
  overflow: hidden;
  overscroll-behavior: none;
}
/* Track the visual viewport so the input bar stays above the on-screen
   keyboard on mobile browsers. */
@supports (height: 100dvh) {
  html, body { height: 100dvh; }
}
html {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  background: var(--bg);
  color: var(--text);
}

.screen { display: flex; flex-direction: column; }
.hidden { display: none !important; }

/* ── Auth ─────────────────────────────────────────── */
#auth-screen {
  position: fixed;
  inset: 0;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  padding: max(24px, var(--sat)) 16px max(24px, var(--sab));
  overflow-y: auto;
}

#apk-banner {
  display: flex; align-items: center; gap: 12px;
  width: 100%; max-width: 380px;
  background: var(--sidebar-bg); border: 1px solid var(--border);
  border-radius: 14px; padding: 12px 16px;
  text-decoration: none; color: var(--text);
  box-shadow: 0 4px 16px rgba(0,0,0,.06);
  transition: border-color .15s, transform .15s;
}
#apk-banner:hover { border-color: var(--accent); transform: translateY(-1px); }
.apk-banner-icon { font-size: 1.5rem; }
.apk-banner-text { flex: 1; display: flex; flex-direction: column; gap: 1px; }
.apk-banner-text b { font-size: 0.9rem; }
.apk-banner-text small { color: var(--muted); font-size: 0.75rem; }
.apk-banner-cta {
  background: var(--accent); color: #fff; border-radius: 8px;
  padding: 8px 12px; font-size: 0.8rem; font-weight: 700; white-space: nowrap;
}
.auth-card {
  width: 100%; max-width: 380px;
  background: var(--sidebar-bg);
  border: 1px solid var(--border);
  border-radius: 20px;
  padding: 36px 28px;
  box-shadow: 0 20px 60px rgba(0,0,0,.5);
}
.auth-logo { text-align: center; font-size: 2.8rem; margin-bottom: 8px; }
.auth-card h1 { text-align: center; font-size: 1.6rem; color: var(--text); font-weight: 700; margin-bottom: 4px; }
.auth-sub { text-align: center; font-size: 0.83rem; color: var(--muted); margin-bottom: 24px; line-height: 1.45; }

.field { margin-bottom: 14px; }
.field label { display: block; font-size: 0.78rem; color: var(--muted); margin-bottom: 5px; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; }
.field input { width: 100%; padding: 11px 14px; background: var(--input-bg); border: 1px solid var(--border); border-radius: 10px; color: var(--text); font-size: 16px; transition: border-color .15s; -webkit-appearance: none; }
.field input:focus { outline: none; border-color: var(--accent); }

.btn-primary { width: 100%; padding: 13px; border: none; border-radius: 10px; font-size: 0.97rem; font-weight: 600; cursor: pointer; background: var(--accent); color: #fff; transition: background .15s; margin-top: 6px; -webkit-appearance: none; letter-spacing: .01em; }
.btn-success { width: 100%; padding: 13px; border: none; border-radius: 10px; font-size: 0.97rem; font-weight: 600; cursor: pointer; background: var(--success); color: #fff; transition: background .15s; margin-top: 6px; -webkit-appearance: none; }
.btn-danger  { width: 100%; padding: 13px; border: none; border-radius: 10px; font-size: 0.97rem; font-weight: 600; cursor: pointer; background: var(--danger); color: #fff; transition: background .15s; -webkit-appearance: none; }
.btn-primary:hover { background: var(--accent-hover); }
.btn-success:hover { background: var(--success-hover); }
.btn-danger:hover  { background: var(--danger-hover); }
.btn-primary:disabled { opacity: .6; cursor: default; }

.error   { color: var(--danger);  font-size: 0.83rem; margin-top: 10px; min-height: 18px; }
.auth-hint { display: block; color: var(--muted); font-size: 0.75rem; margin-top: 6px; }
.success { color: var(--success); font-size: 0.83rem; margin-top: 10px; min-height: 18px; }
.req { color: var(--muted); font-weight: 400; font-size: 0.75rem; }

/* ── App layout ───────────────────────────────────── */
#app-screen {
  position: fixed;
  inset: 0;
  flex-direction: row;
  overflow: hidden;
}

/* ── Sidebar overlay ──────────────────────────────── */
#sidebar-overlay { display: none; position: fixed; inset: 0; background: rgba(0,0,0,.5); z-index: 10; }

/* ── Sidebar ──────────────────────────────────────── */
#sidebar {
  width: var(--sidebar-w);
  background: var(--sidebar-bg);
  border-right: 1px solid var(--border);
  display: flex; flex-direction: column; flex-shrink: 0;
  transition: width .25s ease, transform .25s ease;
  z-index: 20; overflow: hidden;
  /* top safe area on desktop is 0, fine to always apply */
  padding-top: var(--sat);
}
#sidebar.collapsed { width: 54px; }
#sidebar.collapsed .sidebar-username,
#sidebar.collapsed .room-create,
#sidebar.collapsed .room-label,
#sidebar.collapsed .room-actions { display: none; }
#sidebar.collapsed .sidebar-header { padding: 10px 0; justify-content: center; cursor: default; }
#sidebar.collapsed #room-list li { padding: 13px 0; justify-content: center; }

.sidebar-header { display: flex; align-items: center; gap: 10px; padding: 12px 14px; border-bottom: 1px solid var(--border); cursor: pointer; transition: background .15s; flex-shrink: 0; }
.sidebar-header:hover { background: rgba(0,0,0,.035); }
.sidebar-username { flex: 1; font-weight: 600; font-size: 0.9rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.avatar { width: 34px; height: 34px; border-radius: 50%; background: var(--accent); color: #fff; display: flex; align-items: center; justify-content: center; font-size: 0.85rem; font-weight: 700; flex-shrink: 0; text-transform: uppercase; }

.room-create { display: flex; gap: 6px; padding: 10px; border-bottom: 1px solid var(--border); flex-shrink: 0; }
.room-create input { flex: 1; min-width: 0; background: var(--input-bg); border: 1px solid var(--border); border-radius: 8px; color: var(--text); padding: 7px 10px; font-size: 16px; -webkit-appearance: none; }
.room-create input:focus { outline: none; border-color: var(--accent); }
.room-create button { background: var(--accent); border: none; color: #fff; border-radius: 8px; padding: 7px 13px; cursor: pointer; font-size: 1.1rem; flex-shrink: 0; }

#room-list { list-style: none; overflow-y: auto; flex: 1; -webkit-overflow-scrolling: touch; }

#room-list li {
  padding: 10px 14px; cursor: pointer; border-bottom: 1px solid var(--border);
  transition: background .15s; font-size: 0.9rem; white-space: nowrap;
  overflow: hidden; display: flex; align-items: center; gap: 8px;
}
#room-list li .room-icon { flex-shrink: 0; color: var(--muted); }
#room-list li .room-label { flex: 1; overflow: hidden; text-overflow: ellipsis; }
#room-list li:hover { background: var(--input-bg); }
#room-list li.active { background: var(--accent); color: #fff; }
#room-list li.active .room-icon { color: #fff; }

/* DM divider */
#room-list li.dm-divider {
  padding: 8px 14px 4px; font-size: 0.7rem; color: var(--muted); font-weight: 600;
  text-transform: uppercase; letter-spacing: .05em; cursor: default;
  border-top: 1px solid var(--border); margin-top: 2px; background: none !important;
}

/* Unread badge */
.unread-badge {
  background: var(--online); color: #fff;
  border-radius: 10px; padding: 1px 7px;
  font-size: 0.7rem; font-weight: 700;
  flex-shrink: 0; min-width: 18px; text-align: center;
  line-height: 16px;
}

/* Room owner action buttons */
.room-actions { display: none; gap: 2px; flex-shrink: 0; }
#room-list li:hover .room-actions:not(.not-owner) { display: flex; }
.room-action-btn { background: none; border: none; cursor: pointer; padding: 4px 6px; font-size: 0.8rem; border-radius: 6px; color: var(--muted); line-height: 1; -webkit-tap-highlight-color: transparent; }
.room-action-btn:hover, .room-action-btn:active { background: var(--border); color: var(--text); }
.room-action-btn.del:hover, .room-action-btn.del:active { color: var(--danger); }

/* ── Chat area ────────────────────────────────────── */
#chat-area {
  flex: 1; display: flex; flex-direction: column;
  min-width: 0; max-width: 100%; overflow: hidden;
  height: 100%; position: relative;
}

/* The drop target. Only visible while a file is actually over the chat, and
   pointer-events:none so it can never become the thing that swallows the drop
   it is advertising. */
#drop-overlay {
  position: absolute; inset: 10px; z-index: 120;
  display: flex; align-items: center; justify-content: center;
  border: 2px dashed var(--accent); border-radius: 16px;
  background: rgba(59,125,216,.10);
  backdrop-filter: blur(2px);
  pointer-events: none;
}
#drop-overlay-inner { text-align: center; color: var(--text); }
#drop-overlay .drop-icon { font-size: 2.6rem; }
#drop-overlay .drop-title { font-size: 1.15rem; font-weight: 700; margin-top: 6px; }
#drop-overlay .drop-sub { font-size: .85rem; opacity: .75; margin-top: 2px; }

#scroll-fab {
  position: absolute; right: 18px; bottom: 132px;
  width: 42px; height: 42px; border-radius: 50%;
  background: var(--accent); color: #fff; border: none;
  font-size: 1.1rem; cursor: pointer; z-index: 50;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 4px 14px rgba(0,0,0,.35);
  transition: background .15s, transform .15s;
}
#scroll-fab:hover { background: var(--accent-hover); transform: scale(1.05); }
#scroll-fab.hidden { display: none !important; }

#chat-header {
  padding: 12px 16px;
  /* push content below the notch/status bar */
  padding-top: calc(12px + var(--sat));
  background: var(--header-bg);
  border-bottom: 1px solid var(--border);
  display: flex; align-items: center; gap: 10px;
  font-weight: 600; flex-shrink: 0;
}
#room-title { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#menu-btn { display: none; font-size: 1.3rem; }

/* ── Connection banner ────────────────────────────── */
/* Floating connection-status pill, centered at the top over everything */
#connection-banner {
  position: fixed;
  top: max(10px, var(--sat, 0px));
  left: 50%;
  transform: translateX(-50%);
  background: #7c3a00;
  color: #fbbf24;
  text-align: center;
  font-size: 0.8rem;
  font-weight: 600;
  padding: 6px 16px;
  border-radius: 20px;
  box-shadow: 0 4px 14px rgba(0,0,0,.35);
  letter-spacing: .02em;
  z-index: 1000;
  display: flex;
  align-items: center;
  gap: 7px;
  white-space: nowrap;
  animation: conn-pop .2s ease both;
}
#connection-banner.hidden { display: none; }
#connection-banner.online { background: #14532d; color: #86efac; }
#connection-banner .conn-dot {
  width: 8px; height: 8px; border-radius: 50%; background: currentColor;
}
#connection-banner:not(.online) .conn-dot { animation: conn-pulse 1s ease-in-out infinite; }
@keyframes conn-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.25; } }
@keyframes conn-pop { from { opacity: 0; transform: translate(-50%, -8px); } to { opacity: 1; transform: translate(-50%, 0); } }

.online-badge { background: rgba(74,222,128,.15); border: 1px solid var(--online); color: var(--online); border-radius: 20px; padding: 3px 10px; font-size: 0.75rem; font-weight: 600; cursor: pointer; white-space: nowrap; flex-shrink: 0; transition: background .15s; }
.online-badge:hover { background: rgba(74,222,128,.25); }

#online-panel { position: fixed; top: 54px; right: 12px; background: var(--sidebar-bg); border: 1px solid var(--border); border-radius: 12px; min-width: 180px; box-shadow: 0 8px 24px rgba(0,0,0,.4); z-index: 200; overflow: hidden; }
.online-panel-title { padding: 10px 14px 6px; font-size: 0.75rem; color: var(--muted); font-weight: 600; text-transform: uppercase; letter-spacing: .04em; }
#online-list { list-style: none; padding-bottom: 8px; }
#online-list li { display: flex; align-items: center; gap: 8px; padding: 8px 14px; font-size: 0.88rem; cursor: pointer; transition: background .12s; }
#online-list li:hover { background: var(--input-bg); }
#online-list li::before { content: ''; width: 7px; height: 7px; border-radius: 50%; background: var(--online); flex-shrink: 0; }

/* Messages */
#messages {
  flex: 1; min-height: 0; overflow-y: auto; overflow-x: hidden;
  padding: 12px 16px 8px;
  display: flex; flex-direction: column; gap: 6px;
  -webkit-overflow-scrolling: touch;
}

/* ── Typing bar — bottom center above input ───────── */
#typing-bar {
  flex-shrink: 0;
  padding: 4px 16px 2px;
  display: flex; align-items: center; justify-content: center; gap: 6px;
  font-size: 0.78rem; color: var(--success); font-weight: 500;
  min-height: 22px;
}
.typing-dots { display: flex; gap: 3px; align-items: center; }
.typing-dots span { width: 4px; height: 4px; border-radius: 50%; background: var(--success); animation: tdot 1.2s infinite ease-in-out; }
.typing-dots span:nth-child(2) { animation-delay: .2s; }
.typing-dots span:nth-child(3) { animation-delay: .4s; }
@keyframes tdot { 0%,60%,100% { transform: translateY(0); opacity:.35; } 30% { transform: translateY(-3px); opacity:1; } }

/* ── Edit banner ──────────────────────────────────── */
#edit-banner { display: flex; align-items: center; gap: 8px; padding: 6px 14px; background: rgba(82,136,193,.12); border-top: 1px solid var(--accent); font-size: 0.82rem; color: var(--accent); flex-shrink: 0; }
#edit-banner button { margin-left: auto; background: none; border: none; color: var(--muted); cursor: pointer; font-size: 1rem; padding: 2px 6px; }

/* ── Reply bar ────────────────────────────────────── */
#reply-bar {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 14px;
  background: rgba(82,136,193,.08);
  border-top: 1px solid var(--accent);
  flex-shrink: 0;
}
.reply-bar-icon { color: var(--accent); font-size: 1rem; flex-shrink: 0; }
.reply-bar-body { flex: 1; min-width: 0; }
#reply-bar-user { display: block; font-size: 0.72rem; font-weight: 700; color: var(--accent); margin-bottom: 1px; }
#reply-bar-text { display: block; font-size: 0.8rem; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#reply-bar button { background: none; border: none; color: var(--muted); cursor: pointer; font-size: 1rem; padding: 4px 6px; }

/* ── Reply quote inside bubble ────────────────────── */
.reply-quote {
  display: flex; flex-direction: column; gap: 1px;
  border-left: 3px solid var(--accent);
  padding: 5px 8px; border-radius: 4px;
  background: rgba(0,0,0,.18); margin-bottom: 6px;
  cursor: pointer;
}
.reply-quote:hover { background: rgba(0,0,0,.28); }
.reply-quote-user { font-size: 0.7rem; font-weight: 700; color: var(--accent); }
.reply-quote-text { font-size: 0.8rem; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 220px; }

.msg-highlight .msg-bubble {
  animation: msg-highlight-flash 1.5s ease;
}
@keyframes msg-highlight-flash {
  0% { box-shadow: 0 0 0 2px var(--accent); }
  70% { box-shadow: 0 0 0 2px var(--accent); }
  100% { box-shadow: none; }
}

/* ── Input bar ────────────────────────────────────── */
#input-bar {
  display: flex; align-items: center; gap: 6px;
  padding: 10px 12px;
  padding-bottom: max(10px, calc(var(--sab) + 8px));
  background: var(--header-bg);
  border-top: 1px solid var(--border);
  flex-shrink: 0;
}
#msg-input { flex: 1; min-width: 0; background: var(--input-bg); border: 1px solid var(--border); border-radius: 20px; padding: 10px 16px; color: var(--text); font-size: 16px; outline: none; -webkit-appearance: none; }
#msg-input:focus { border-color: var(--accent); }

.send-btn { background: var(--accent); border: none; color: #fff; border-radius: 50%; width: 42px; height: 42px; cursor: pointer; font-size: 1rem; display: flex; align-items: center; justify-content: center; flex-shrink: 0; -webkit-appearance: none; }
.icon-btn { background: none; border: none; color: var(--text); font-size: 1.2rem; cursor: pointer; padding: 6px; border-radius: 8px; transition: background .15s; display: flex; align-items: center; justify-content: center; flex-shrink: 0; -webkit-tap-highlight-color: transparent; -webkit-appearance: none; }
.icon-btn:hover { background: var(--input-bg); }

#record-btn { position: relative; }

/* ── Recording bar ────────────────────────────────── */
#recording-bar, #preview-bar {
  display: flex; align-items: center; gap: 8px;
  padding: 10px 12px;
  padding-bottom: max(10px, calc(var(--sab) + 8px));
  background: var(--header-bg);
  border-top: 1px solid var(--border);
  flex-shrink: 0;
}

/* Pulsing red dot */
.rec-dot {
  width: 10px; height: 10px; border-radius: 50%;
  background: var(--danger); flex-shrink: 0;
  animation: pulse 1s infinite;
}
@keyframes pulse { 0%,100% { opacity: 1; } 50% { opacity: .3; } }

.rec-timer { font-size: 0.88rem; color: var(--danger); font-weight: 600; font-variant-numeric: tabular-nums; min-width: 34px; }
.rec-stop-btn { color: var(--danger); }
.rec-delete-btn { color: var(--muted); }

/* Live waveform during recording */
.rec-waveform {
  flex: 1; display: flex; align-items: center; gap: 2px;
  height: 32px; overflow: hidden;
}
.rec-waveform .bar {
  width: 3px; border-radius: 2px; background: var(--danger);
  flex-shrink: 0; opacity: 0.7;
  transition: height 0.08s ease;
}

/* ── Voice player (sent messages) ────────────────── */
.voice-player {
  display: flex; align-items: center; gap: 8px;
  width: 220px; max-width: 100%; min-width: 0;
  padding: 4px 2px; box-sizing: border-box;
}
.voice-play-btn {
  width: 36px; height: 36px; border-radius: 50%;
  background: var(--accent); border: none; color: #fff;
  font-size: 0.9rem; cursor: pointer; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  transition: background .15s;
}
.voice-play-btn:hover { background: var(--accent-hover); }
.voice-play-btn.loading::after {
  content: ''; width: 14px; height: 14px; border-radius: 50%;
  border: 2px solid rgba(255,255,255,0.4); border-top-color: #fff;
  animation: spin 0.7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ── Upload / download progress ───────────────────── */
.msg-uploading .msg-bubble { opacity: 0.75; }
.upload-overlay {
  position: absolute; left: 0; right: 0; bottom: 0; height: 4px;
  background: rgba(255,255,255,0.25); border-radius: 0 0 var(--radius) var(--radius); overflow: hidden;
}
.upload-progress-bar { height: 100%; background: var(--accent); transition: width .15s linear; }
.download-spinner {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: 26px; height: 26px; border-radius: 50%;
  border: 3px solid rgba(255,255,255,0.35); border-top-color: #fff;
  animation: spin 0.7s linear infinite; pointer-events: none;
}
.msg-upload-failed .msg-bubble { opacity: 0.85; }
.upload-retry {
  margin-top: 6px; font-size: 0.78rem; color: #f87171; cursor: pointer;
  text-decoration: underline; text-underline-offset: 2px;
}

/* ── Copyable tokens (links, phone/card numbers) ───── */
.msg-bubble.has-copyable { border-left: 3px solid var(--accent); }
.copyable-number {
  font-family: ui-monospace, monospace; font-size: 0.88em;
  background: rgba(59,125,216,0.12); border-radius: 4px; padding: 1px 4px;
}
.copyable-number { cursor: pointer; }
.copyable-number:hover { background: rgba(59,125,216,0.22); }
.copyable-phone {
  color: var(--accent); font-weight: 700; text-decoration: underline;
  text-underline-offset: 2px; cursor: pointer;
}

/* Message text is selectable so a user can copy just part of it. */
.msg-bubble, .msg-text { user-select: text; -webkit-user-select: text; }

/* Non-blocking copy confirmation */
.copy-toast {
  position: fixed; left: 50%; bottom: 84px; transform: translate(-50%, 12px);
  background: rgba(17,24,39,0.94); color: #fff; border-radius: 22px;
  padding: 10px 18px; font-size: 0.9rem; font-weight: 600;
  border: 1px solid rgba(255,255,255,0.15); z-index: 4000;
  opacity: 0; pointer-events: none; transition: opacity .18s, transform .18s;
  max-width: 86vw; text-align: center;
}
.copy-toast.show { opacity: 1; transform: translate(-50%, 0); }

/* Tap-a-token menu (copy vs open/call) */
.token-menu-backdrop {
  position: fixed; inset: 0; background: rgba(0,0,0,0.5); z-index: 3500;
  display: flex; align-items: flex-end; justify-content: center;
}
.token-menu {
  background: var(--sidebar); border-radius: 18px 18px 0 0; width: min(520px, 100%);
  padding: 14px 0 20px; border: 1px solid var(--border); border-bottom: none;
}
.token-menu-preview {
  color: var(--text); font-weight: 600; text-align: center;
  padding: 4px 22px 12px; word-break: break-all;
  border-bottom: 1px solid var(--border); margin-bottom: 6px;
}
.token-menu-row {
  display: block; width: 100%; background: none; border: none; cursor: pointer;
  color: var(--text); font-size: 1rem; text-align: left; padding: 14px 22px;
}
.token-menu-row:hover { background: rgba(128,128,128,0.12); }
.token-menu-cancel {
  display: block; width: calc(100% - 32px); margin: 8px 16px 0;
  background: var(--input-bg); border: none; border-radius: 12px;
  color: var(--muted); font-size: 1rem; font-weight: 600; padding: 13px; cursor: pointer;
}

/* ── Composer options strip ────────────────────────── */
#input-bar { position: relative; }
#composer-plus-btn { font-size: 1.3rem; font-weight: 600; }
#composer-plus-btn.one-time-armed { background: rgba(248,113,113,0.25); border-radius: 8px; }
#composer-strip {
  display: flex; gap: 8px; padding: 6px 12px; flex-shrink: 0;
  border-top: 1px solid rgba(128,128,128,0.2);
  /* Four pills, and on a narrow phone with a large system font they do not
     fit. Scrolling inside the strip keeps the last one reachable; without
     this it was simply cut off at the edge of the screen. */
  overflow-x: auto;
  scrollbar-width: none;
  max-width: 100%;
}
#composer-strip::-webkit-scrollbar { display: none; }
#composer-strip button { flex-shrink: 0; }
#composer-strip button {
  background: rgba(59,125,216,0.10); border: none; color: var(--accent);
  cursor: pointer; font-size: 0.82rem; font-weight: 600;
  padding: 6px 12px; border-radius: 16px;
}
#composer-strip button:hover { background: rgba(59,125,216,0.2); }
#composer-strip button.one-time-armed { background: rgba(248,113,113,0.25); color: #f87171; }
/* ── Quick emoji bar ───────────────────────────────── */
#join-bar {
  display: flex; align-items: center; gap: 10px; flex-shrink: 0;
  padding: 10px 14px; background: var(--sidebar, #1e293b);
  border-top: 1px solid var(--border);
}
#join-bar.hidden { display: none; }
#join-bar span { flex: 1; min-width: 0; color: var(--muted, #94a3b8); font-size: 0.85rem; }
#join-bar button { width: auto; margin-top: 0; padding: 8px 20px; border-radius: 16px; }

#quick-emoji-bar {
  display: flex; align-items: center; gap: 4px; flex-shrink: 0;
  padding: 4px 10px; background: transparent;
}
#quick-emoji-bar.hidden { display: none; }
#quick-emoji-list { display: flex; flex: 1; gap: 2px; overflow-x: auto; scrollbar-width: none; }
#quick-emoji-list button, #quick-emoji-close {
  background: none; border: none; cursor: pointer; font-size: 1.25rem;
  padding: 3px 6px; border-radius: 8px; line-height: 1;
}
#quick-emoji-list button:hover { background: rgba(59,125,216,0.2); }
#quick-emoji-close {
  width: 22px; height: 22px; border-radius: 11px; flex-shrink: 0; margin-left: 6px;
  background: rgba(239,68,68,0.9); color: #fff; font-size: 0.7rem; font-weight: 800;
  display: flex; align-items: center; justify-content: center; padding: 0;
}
#quick-emoji-close:hover { background: #ef4444; }
/* ⋮ actions button sits beside the bubble (inside edge of the row) */
.bubble-row { display: flex; align-items: center; gap: 4px; max-width: 100%; min-width: 0; }
.msg-wrapper.mine .bubble-row { flex-direction: row-reverse; }
.msg-menu-btn {
  flex-shrink: 0; background: none; border: none; cursor: pointer;
  color: var(--muted); font-size: 1.05rem; font-weight: 700; line-height: 1;
  width: 26px; height: 26px; border-radius: 13px;
  display: flex; align-items: center; justify-content: center;
  opacity: 0.4; transition: opacity .15s, background .15s;
}
.msg-wrapper:hover .msg-menu-btn { opacity: 1; }
.msg-menu-btn:hover { background: rgba(128,128,128,0.18); }
@media (pointer: coarse) { .msg-menu-btn { opacity: 0.6; } }

/* ── Heart burst overlay ───────────────────────────── */
#heart-burst {
  position: fixed; inset: 0; z-index: 900; pointer-events: none;
  background: radial-gradient(circle at 50% 65%, rgba(244,114,182,0.16), rgba(244,114,182,0.05));
  animation: heart-bg 2.5s cubic-bezier(0.4, 0, 0.2, 1) both;
}
#heart-burst.hidden { display: none; }
#heart-burst span {
  position: absolute; bottom: -60px; will-change: transform, opacity;
  animation: heart-rise 2.4s cubic-bezier(0.25, 0.1, 0.25, 1) both;
  filter: drop-shadow(0 2px 6px rgba(244,114,182,0.35));
}
@keyframes heart-bg { 0% { opacity: 0; } 20% { opacity: 1; } 75% { opacity: 1; } 100% { opacity: 0; } }
@keyframes heart-rise {
  0%   { transform: translate(0, 0) scale(0.4) rotate(-6deg); opacity: 0; }
  12%  { opacity: 0.9; }
  30%  { transform: translate(14px, -26vh) scale(0.9) rotate(5deg); }
  55%  { transform: translate(-12px, -48vh) scale(1.05) rotate(-5deg); opacity: 0.85; }
  80%  { transform: translate(10px, -68vh) scale(1.12) rotate(4deg); opacity: 0.5; }
  100% { transform: translate(-6px, -88vh) scale(1.18) rotate(-3deg); opacity: 0; }
}

/* ── Voice played dot ──────────────────────────────── */
.voice-played-dot {
  width: 8px; height: 8px; border-radius: 4px; flex-shrink: 0;
  background: var(--accent); align-self: center;
}
.voice-played-dot.played { background: rgba(128,128,128,0.45); }

/* ── Call log bubble ───────────────────────────────── */
.call-log { display: flex; align-items: center; gap: 8px; font-size: 0.9rem; font-weight: 600; color: var(--text); }
.call-log-bad { color: #f87171; }
#media-preview-bar {
  display: flex; align-items: center; gap: 10px; padding: 8px 14px; flex-shrink: 0;
  background: rgba(59,125,216,0.08); border-top: 1px solid var(--accent);
  overflow-x: auto;
}
.pending-item { position: relative; flex-shrink: 0; }
.pending-item img {
  width: 54px; height: 54px; object-fit: cover; border-radius: 8px;
  cursor: pointer; display: block;
}
.pending-file-box {
  width: 54px; height: 54px; border-radius: 8px; font-size: 1.3rem;
  background: rgba(59,125,216,0.12); display: flex; align-items: center; justify-content: center;
}
.pending-remove {
  position: absolute; top: -5px; right: -5px; width: 18px; height: 18px;
  border-radius: 50%; background: #f87171; color: #fff; border: none;
  font-size: 0.6rem; line-height: 1; cursor: pointer; padding: 0;
}
.pending-add {
  width: 54px; height: 54px; border-radius: 8px; flex-shrink: 0;
  background: rgba(59,125,216,0.12); border: 1px dashed var(--accent);
  color: var(--accent); font-size: 1.3rem; cursor: pointer;
}
.msg-caption { margin-top: 6px; font-size: 0.9rem; max-width: var(--media-w); }
/* ── Calls ─────────────────────────────────────────── */
#incoming-call {
  position: fixed; top: 14px; left: 50%; transform: translateX(-50%); z-index: 200;
  display: flex; align-items: center; gap: 12px; padding: 12px 18px;
  background: var(--panel, #1f2937); border: 1px solid var(--accent);
  border-radius: 14px; box-shadow: 0 10px 30px rgba(0,0,0,0.4); font-size: 0.95rem;
}
#incoming-call button { border: none; border-radius: 10px; padding: 8px 14px; cursor: pointer; font-weight: 700; }
#incoming-call .call-accept { background: #22c55e; color: #fff; }
#incoming-call .call-decline { background: #ef4444; color: #fff; }
#call-overlay {
  position: fixed; inset: auto 14px 90px auto; z-index: 190; width: 260px;
  background: var(--panel, #1f2937); border: 1px solid rgba(255,255,255,0.15);
  border-radius: 16px; padding: 12px; box-shadow: 0 12px 34px rgba(0,0,0,0.45);
  display: flex; flex-direction: column; gap: 10px;
}
/* The two panes. Which element is which is decided by the `swapped` class on
   the panel, so the swap is one class flip rather than moving DOM nodes —
   moving a <video> re-attaches its stream and blinks it black. */
#call-remote-video { width: 100%; border-radius: 10px; background: #000; max-height: 200px; }
#call-local-video {
  position: absolute; top: 18px; right: 18px; width: 72px; border-radius: 8px;
  background: #000; border: 1px solid rgba(255,255,255,0.4);
}
#call-overlay.swapped #call-local-video {
  position: static; top: auto; right: auto; width: 100%;
  border-radius: 10px; max-height: 200px; border: none;
}
#call-overlay.swapped #call-remote-video {
  position: absolute; top: 18px; right: 18px; width: 72px;
  border-radius: 8px; max-height: none; border: 1px solid rgba(255,255,255,0.4);
}
/* Only a pointer when the tap does something. */
#call-overlay.swappable #call-remote-video,
#call-overlay.swappable #call-local-video { cursor: pointer; }
#call-info { text-align: center; }
#call-title { font-weight: 700; font-size: 0.95rem; }
#call-status { font-size: 0.78rem; color: var(--muted); margin-top: 2px; }
#call-controls { display: flex; justify-content: center; gap: 14px; }
#call-min-btn {
  position: absolute; top: 6px; left: 8px;
  background: none; border: none; color: inherit; opacity: .65;
  font-size: 1rem; line-height: 1; cursor: pointer; padding: 4px 6px;
}
#call-min-btn:hover { opacity: 1; }

/* Minimized: one row — who, how long, mute, hang up. Everything that only
   makes sense at full size is out of the flow rather than merely invisible,
   so the bar is the height of its contents. */
#call-overlay.minimized { width: 210px; padding: 8px 10px 8px 26px; gap: 6px; }
#call-overlay.minimized #call-remote-video,
#call-overlay.minimized #call-local-video { display: none; }
#call-overlay.minimized #call-info {
  display: flex; align-items: baseline; gap: 8px; text-align: left; min-width: 0;
}
#call-overlay.minimized #call-title {
  font-size: .85rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
#call-overlay.minimized #call-status { margin-top: 0; white-space: nowrap; }
#call-overlay.minimized #call-controls { gap: 10px; }
#call-controls button {
  width: 44px; height: 44px; border-radius: 50%; border: none; cursor: pointer;
  font-size: 1.15rem; background: rgba(59,125,216,0.18);
}
#call-end-btn { background: #ef4444 !important; }

.gallery-grid { display: flex; flex-wrap: wrap; gap: 4px; max-width: 252px; }
.gallery-grid img {
  width: 122px; height: 122px; object-fit: cover;
  border-radius: 8px; cursor: pointer; display: block;
}

/* ── One-time messages ─────────────────────────────── */
.one-time-bubble { border: 1px dashed #f87171; }
.one-time-reveal {
  background: none; border: none; color: #f87171; cursor: pointer;
  font-size: 0.88rem; font-weight: 600; padding: 4px 2px;
}
.one-time-tag { font-size: 0.68rem; color: #f87171; margin-left: 4px; }
.one-time-hide {
  display: block; background: none; border: none; color: var(--muted);
  cursor: pointer; font-size: 0.72rem; margin-top: 4px; padding: 0;
}
.one-time-hide:hover { color: #f87171; }

.lightbox-nav {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 5;
  width: 46px; height: 46px; border-radius: 50%; border: none; cursor: pointer;
  background: rgba(255,255,255,0.15); color: #fff; font-size: 1.6rem; line-height: 1;
}
.lightbox-nav:hover { background: rgba(255,255,255,0.3); }
#lightbox-prev { left: 14px; }
#lightbox-next { right: 14px; }
#lightbox-counter {
  position: absolute; bottom: max(18px, calc(var(--sab) + 10px)); left: 50%; transform: translateX(-50%);
  color: #fff; font-size: 0.85rem; background: rgba(0,0,0,0.5);
  padding: 4px 12px; border-radius: 12px;
}

.voice-waveform {
  flex: 1; position: relative; height: 32px;
  cursor: pointer; min-width: 0; overflow: hidden;
}
.voice-bars {
  display: flex; align-items: center; gap: 1px;
  height: 100%; position: relative; z-index: 1;
  overflow: hidden; width: 100%;
}
.voice-bars .bar {
  flex: 1 1 auto; width: 2px; max-width: 3px; border-radius: 2px;
  background: rgba(31,41,55,0.3); min-width: 1px;
}
.mine .voice-bars .bar { background: rgba(59,125,216,0.3); }
.theirs .voice-bars .bar { background: rgba(31,41,55,0.25); }
.voice-bars .bar.played { background: var(--accent); }
.mine .voice-bars .bar.played { background: var(--accent-hover); }

.voice-progress {
  position: absolute; top: 0; left: 0; height: 100%;
  width: 0%; pointer-events: none; z-index: 0;
}

.voice-meta { display: flex; flex-direction: column; align-items: flex-end; gap: 1px; flex-shrink: 0; }
.voice-duration { font-size: 0.72rem; color: var(--muted); font-variant-numeric: tabular-nums; }
.voice-speed-btn {
  font-size: 0.65rem; font-weight: 700; color: var(--accent);
  background: rgba(82,136,193,.15); border: 1px solid var(--accent);
  border-radius: 4px; padding: 1px 4px; cursor: pointer; line-height: 1.4;
  white-space: nowrap;
}
.voice-speed-btn:hover { background: rgba(82,136,193,.3); }

/* Preview bar waveform */
#preview-waveform .bar { background: var(--accent); opacity: 0.5; }
#preview-waveform .bar.played { opacity: 1; }

/* ── Message bubbles ──────────────────────────────── */
.msg-wrapper { display: flex; flex-direction: column; max-width: 72%; min-width: 0; }
.msg-wrapper.mine { align-self: flex-end; align-items: flex-end; }
.msg-wrapper.theirs { align-self: flex-start; align-items: flex-start; }
.msg-sender {
  font-size: 0.74rem; color: var(--accent); margin-bottom: 3px; padding: 0 4px;
  display: inline-flex; align-items: center; gap: 5px; font-weight: 600;
}
.msg-sender-avatar {
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; border-radius: 50%; font-size: 0.72rem; line-height: 1;
  background: rgba(59,125,216,0.16); flex-shrink: 0;
}
.msg-sender.clickable {
  cursor: pointer;
  padding: 3px 9px 3px 4px; border-radius: 20px; margin-left: 4px;
  background: rgba(59,125,216,0.1);
  transition: background .15s, transform .1s;
}
.msg-sender.clickable:hover { background: rgba(59,125,216,0.2); }
.msg-sender.clickable:active { transform: scale(0.96); background: rgba(59,125,216,0.28); }
.msg-bubble { position: relative; padding: 8px 12px; border-radius: var(--radius); font-size: 0.92rem; line-height: 1.45; word-break: break-word; overflow-wrap: break-word; max-width: 100%; }
.mine .msg-bubble { background: var(--mine-bg); border-bottom-right-radius: 4px; }
.theirs .msg-bubble { background: var(--msg-bg); border-bottom-left-radius: 4px; }
/* A picture with a caption under it.
 *
 * Reported with a screenshot: the bubble looked wrong. A tall screenshot was
 * capped by HEIGHT (180px), which made it about 85px wide, while the caption
 * beside it was free to run to the bubble's full 80% — so the message was a
 * wide box with a stamp-sized picture in the corner. The picture now sets the
 * width, the caption wraps to the same width, and a very tall image is cropped
 * to a sensible shape rather than shrunk to nothing. Tapping still opens the
 * whole thing.
 *
 * Direct children only: gallery grids, link-preview covers and map tiles are
 * images inside a bubble that size themselves. */
.msg-bubble > img {
  width: var(--media-w); max-width: 100%;
  height: auto; max-height: 340px;
  object-fit: cover; object-position: center top;
  border-radius: 8px; display: block; cursor: pointer;
  background: rgba(128,128,128,0.12);
}
.msg-bubble audio { display: block; max-width: 220px; width: 100%; }
.msg-video { display: block; max-width: 260px; max-height: 220px; border-radius: 8px; background: #000; }
.music-player { display: flex; flex-direction: column; gap: 6px; min-width: 220px; max-width: 100%; }
.music-label { font-size: 0.82rem; font-weight: 600; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.music-audio { display: block; width: 100%; max-width: 240px; }
.file-link { display: flex; align-items: center; gap: 8px; color: #93c5fd; text-decoration: none; font-size: 0.88rem; }
.file-link:hover { text-decoration: underline; }
.edited-tag { font-size: 0.65rem; color: var(--muted); margin-left: 4px; }

/* ── Message footer ───────────────────────────────── */
.msg-footer { display: flex; align-items: center; gap: 4px; margin-top: 3px; padding: 0 4px; }
.msg-time { font-size: 0.68rem; color: var(--muted); flex-shrink: 0; }
.msg-status { display: inline-flex; align-items: center; color: var(--muted); flex-shrink: 0; }
.msg-status .ticks { width: 15px; height: 10px; }
.msg-status.seen { color: #4fc3f7; }
.msg-action-btn { background: none; border: none; font-size: 0.75rem; cursor: pointer; padding: 2px 5px; border-radius: 5px; color: var(--muted); line-height: 1; opacity: 0.45; transition: opacity .15s, background .15s; flex-shrink: 0; }
.msg-action-btn:hover, .msg-wrapper:hover .msg-action-btn { opacity: 1; }
.msg-action-btn.delete:hover { color: var(--danger); }
.react-btn { background: none; border: none; font-size: 0.75rem; cursor: pointer; padding: 2px 5px; border-radius: 5px; color: var(--muted); line-height: 1; opacity: 0.45; transition: opacity .15s; }
.msg-wrapper:hover .react-btn { opacity: 1; }

.reactions-row { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 4px; }
.reaction-chip { background: var(--input-bg); border: 1px solid var(--border); border-radius: 20px; padding: 2px 8px; font-size: 0.82rem; cursor: pointer; display: flex; align-items: center; gap: 3px; transition: background .15s; user-select: none; }
.reaction-chip:hover { background: var(--border); }
.reaction-chip.mine { border-color: var(--accent); background: rgba(82,136,193,.15); }
.reaction-chip .count { font-size: 0.75rem; color: var(--muted); }

/* ── Context menu ─────────────────────────────────── */
#ctx-menu { position: fixed; background: var(--sidebar-bg); border: 1px solid var(--border); border-radius: 14px; z-index: 200; box-shadow: 0 12px 32px rgba(0,0,0,.55); min-width: 180px; overflow: hidden; padding: 4px; backdrop-filter: blur(8px); }
#ctx-menu button { display: flex; align-items: center; gap: 10px; width: 100%; padding: 11px 14px; background: none; border: none; border-radius: 9px; color: var(--text); font-size: 0.92rem; cursor: pointer; text-align: left; transition: background .12s; }
#ctx-menu button:hover { background: var(--input-bg); }
#ctx-menu button.danger { color: var(--danger); }
#ctx-menu hr { border: none; border-top: 1px solid var(--border); margin: 0; }

/* ── Emoji picker ─────────────────────────────────── */
#emoji-picker { position: fixed; background: var(--sidebar-bg); border: 1px solid var(--border); border-radius: 12px; padding: 10px; z-index: 300; box-shadow: 0 8px 24px rgba(0,0,0,.4); width: 240px; }
#emoji-list { display: flex; flex-wrap: wrap; gap: 4px; }
#emoji-list span { font-size: 1.4rem; cursor: pointer; padding: 4px; border-radius: 6px; line-height: 1; transition: background .1s; }
#emoji-list span:hover { background: var(--input-bg); }

/* ── Profile modal ────────────────────────────────── */
.modal-overlay { position: fixed; inset: 0; background: rgba(0,0,0,.6); z-index: 500; display: flex; align-items: flex-start; justify-content: center; padding: 16px; padding-bottom: max(16px, var(--sab)); overflow-y: auto; }
.modal-card { background: var(--sidebar-bg); border: 1px solid var(--border); border-radius: 20px; width: 100%; max-width: 400px; box-shadow: 0 20px 60px rgba(0,0,0,.5); overflow: hidden; margin: auto; }
.modal-header { display: flex; align-items: center; justify-content: space-between; padding: 18px 20px; border-bottom: 1px solid var(--border); }
.modal-header h2 { font-size: 1.05rem; font-weight: 700; }
.modal-section { padding: 20px; border-top: 1px solid var(--border); }
.profile-avatar-big { width: 72px; height: 72px; border-radius: 50%; background: var(--accent); color: #fff; display: flex; align-items: center; justify-content: center; font-size: 1.8rem; font-weight: 700; text-transform: uppercase; margin: 20px auto 8px; }
.profile-name { text-align: center; font-weight: 600; font-size: 1rem; margin-bottom: 4px; }

/* ── Lightbox ────────────────────────────────────── */
#lightbox {
  position: fixed; inset: 0;
  background: rgba(0,0,0,.92);
  display: flex; align-items: center; justify-content: center;
  z-index: 2000; cursor: zoom-out;
}
#lightbox.hidden { display: none !important; }
#lightbox img {
  max-width: 92vw; max-height: 92vh;
  object-fit: contain; border-radius: 6px;
  cursor: default; box-shadow: 0 8px 40px rgba(0,0,0,.6);
  transition: transform .05s linear; touch-action: none;
}
.lightbox-close, .lightbox-download {
  /* Reported from an iPhone: only part of these buttons is visible, under the
     top of the screen. The page is laid out with viewport-fit=cover, so a
     fixed element at top:16px sits under the status bar and the notch — the
     safe-area inset is the distance that has to be cleared. */
  position: fixed; top: max(16px, calc(var(--sat) + 10px)); right: 16px;
  background: rgba(255,255,255,.15); border: none; color: #fff;
  font-size: 18px; border-radius: 50%; width: 38px; height: 38px;
  cursor: pointer; display: flex; align-items: center; justify-content: center;
  transition: background .15s; z-index: 2001;
}
.lightbox-download { right: 64px; }
.lightbox-close:hover, .lightbox-download:hover { background: rgba(255,255,255,.25); }

/* ── My Rooms in profile ─────────────────────────── */
.my-rooms-header {
  font-size: 0.72rem; color: var(--muted); font-weight: 700;
  text-transform: uppercase; letter-spacing: .05em; margin-bottom: 10px;
}

/* ── App update section ──────────────────────────── */
.update-hint { font-size: 0.82rem; color: var(--muted); margin: 0 0 10px; }
.update-btn { display: block; text-align: center; text-decoration: none; box-sizing: border-box; }
#my-rooms-list { list-style: none; padding: 0; margin: 0; }
.my-room-item {
  display: flex; align-items: center; gap: 8px;
  padding: 9px 0; border-bottom: 1px solid var(--border);
}
.my-room-item:last-child { border-bottom: none; }
.my-room-name { flex: 1; color: var(--text); font-size: 0.9rem; }
.my-room-empty { color: var(--muted); font-size: 0.85rem; padding: 6px 0; }

/* ── System messages ──────────────────────────────── */
.system-msg { text-align: center; font-size: 0.75rem; color: var(--muted); padding: 4px; }

/* ── Scrollbar ────────────────────────────────────── */
::-webkit-scrollbar { width: 4px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--border); border-radius: 99px; }

/* ── Mobile ───────────────────────────────────────── */
@media (max-width: 640px) {
  #menu-btn { display: flex; }

  #sidebar {
    position: fixed; top: 0; left: 0; bottom: 0;
    width: var(--sidebar-w) !important;
    transform: translateX(-100%);
    padding-top: var(--sat);
  }
  #sidebar.open { transform: translateX(0); box-shadow: 4px 0 20px rgba(0,0,0,.5); }
  #sidebar.collapsed { transform: translateX(-100%); }
  #sidebar-overlay.open { display: block; }

  /* Room owner buttons: always visible on mobile (hover doesn't work on touch) */
  .room-actions:not(.not-owner) { display: flex !important; }

  .msg-wrapper { max-width: 88%; }
  .msg-bubble > img { width: min(var(--media-w), 62vw); }
  .msg-bubble audio { max-width: 100%; }
  #emoji-picker { width: 210px; }

  .msg-action-btn, .react-btn { opacity: 0.7; }

  .auth-card { padding: 28px 18px; }
}

/* Landscape mobile: prevent horizontal scroll */
@media (max-height: 500px) and (max-width: 900px) {
  .msg-bubble audio { max-width: 160px; }
}

/* ── Emoji avatar picker ─────────────────────────── */
#avatar-emoji-grid { display: flex; flex-wrap: wrap; gap: 8px; }
.avatar-emoji-cell {
  width: 42px; height: 42px; border-radius: 10px;
  background: var(--input-bg); border: 2px solid transparent;
  font-size: 1.35rem; cursor: pointer; line-height: 1;
  display: flex; align-items: center; justify-content: center;
  transition: border-color .15s, background .15s;
}
.avatar-emoji-cell:hover { background: rgba(59,125,216,0.1); }
.avatar-emoji-cell.active { border-color: var(--accent); background: rgba(59,125,216,0.12); }
.remove-avatar {
  display: block; margin: 12px auto 0; background: none; border: none;
  color: var(--danger); font-size: 0.82rem; font-weight: 600; cursor: pointer;
}
.emoji-avatar { font-size: 1.3rem !important; }
.profile-avatar-big.emoji-avatar { font-size: 2.6rem !important; }


/* ── Search results / forward / invites / links ───── */
#search-results { border-bottom: 1px solid var(--border); max-height: 240px; overflow-y: auto; background: var(--sidebar-bg); }
.search-result { display: flex; align-items: center; gap: 8px; padding: 9px 14px; cursor: pointer; font-size: 0.88rem; border-bottom: 1px solid var(--border); }
.search-result:hover { background: var(--input-bg); }
.search-result b { flex: 1; font-weight: 600; }
.search-result em { color: var(--accent); font-style: normal; font-size: 0.75rem; font-weight: 700; }
.search-empty { color: var(--muted); font-size: 0.85rem; padding: 12px; text-align: center; }

.forward-list { list-style: none; max-height: 320px; overflow-y: auto; padding: 8px 0; }
.forward-list li { padding: 11px 20px; cursor: pointer; font-size: 0.92rem; }
.forward-list li:hover { background: var(--input-bg); }

.forwarded-label { font-size: 0.72rem; color: var(--muted); font-style: italic; margin-bottom: 4px; }

.msg-link { color: var(--accent); text-decoration: underline; word-break: break-all; }

/* The preview card under a message that contains a link. The stripe down the
   leading edge is what says "this belongs to the message above" rather than
   being a second message of its own. */
.link-card {
  display: block; margin-top: 6px; max-width: 300px;
  border-radius: 10px; overflow: hidden;
  background: rgba(0, 0, 0, 0.18);
  border-left: 3px solid var(--accent);
  text-decoration: none; color: inherit;
}
.link-card:hover { background: rgba(0, 0, 0, 0.26); }
/* A fixed height so the list does not jump as the cover loads. */
.link-card-cover { display: block; width: 100%; height: 140px; object-fit: cover; background: rgba(0, 0, 0, 0.25); }
.link-card-body { padding: 6px 8px; }
.link-card-host { font-size: 0.68rem; color: var(--accent); margin-bottom: 2px; }
.link-card-title { font-size: 0.82rem; font-weight: 600; }
.link-card-desc { font-size: 0.75rem; opacity: 0.75; margin-top: 2px; }
.link-card-play { font-size: 0.72rem; color: var(--accent); font-weight: 600; margin-top: 4px; }
/* A cover you can play says so before it is tapped. */
.link-card-playable .link-card-cover { filter: brightness(0.8); }

/* The embedded player: the platform's own, in a dialog. */
.embed-backdrop {
  position: fixed; inset: 0; z-index: 60; background: rgba(0, 0, 0, 0.85);
  display: flex; align-items: center; justify-content: center;
}
.embed-box { width: min(720px, calc(100vw - 32px)); background: #101418; border-radius: 12px; overflow: hidden; }
.embed-bar { display: flex; align-items: center; gap: 12px; padding: 10px 12px; }
.embed-title { flex: 1; font-size: 0.85rem; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.embed-out, .embed-close { background: none; border: none; color: var(--muted); font-size: 1rem; cursor: pointer; text-decoration: none; }
.embed-frame { display: block; width: 100%; border: 0; background: #000; }

.invite-card { display: flex; flex-direction: column; gap: 6px; min-width: 200px; }
/* Room notices: "X joined the room" / "X was removed" — a centered line
   rather than a chat bubble, with the username clickable. */
.system-notice {
  text-align: center; font-size: 12.5px; color: var(--muted, #94a3b8);
  background: rgba(148,163,184,0.10); border-radius: 12px;
  padding: 5px 12px; margin: 4px auto; display: inline-block; line-height: 1.5;
}
.system-name { font-weight: 700; color: var(--text, #e2e8f0); }

.invite-title { font-weight: 700; font-size: 0.88rem; }
.invite-text { color: var(--muted); font-size: 0.84rem; }
.invite-join-btn { background: var(--accent); color: #fff; border: none; border-radius: 8px; padding: 8px; font-weight: 700; cursor: pointer; margin-top: 4px; }
.invite-join-btn:hover { background: var(--accent-hover); }

.privacy-check { display: flex; gap: 10px; align-items: flex-start; margin: 6px 0 14px; cursor: pointer; font-size: 0.88rem; }
.privacy-check small { color: var(--muted); }

.avatar-emoji-cell.more-toggle { color: var(--muted); font-weight: 700; }

#room-link-btn { font-size: 0.95rem; }


/* ── Room dashboard ──────────────────────────────── */
.room-meta-row { display: flex; justify-content: space-between; padding: 7px 0; font-size: 0.9rem; border-bottom: 1px solid var(--border); }
.room-meta-row:last-child { border-bottom: none; }
.room-meta-label { color: var(--muted); font-weight: 600; font-size: 0.8rem; text-transform: uppercase; letter-spacing: .04em; }
.room-link-row { display: flex; align-items: center; gap: 8px; }
.room-link-row code { flex: 1; background: var(--input-bg); border-radius: 8px; padding: 9px 10px; font-size: 0.8rem; color: var(--accent); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.room-members-list { list-style: none; max-height: 200px; overflow-y: auto; }
.room-members-list li { padding: 8px 4px; font-size: 0.9rem; border-bottom: 1px solid var(--border); }
.room-members-list li:last-child { border-bottom: none; }
.room-invite-row { display: flex; gap: 8px; }
.room-invite-row input { flex: 1; min-width: 0; padding: 10px 12px; background: var(--input-bg); border: 1px solid var(--border); border-radius: 10px; color: var(--text); font-size: 16px; }
.room-invite-row .invite-send-btn { width: auto; margin-top: 0; padding: 10px 18px; }

/* ── Shared content (photos / files / music / links of a chat) ─────────────── */
.media-tabs { display: flex; gap: 4px; padding: 12px 20px 0; }
.media-tab {
  flex: 1; padding: 8px 6px; background: none; border: none; cursor: pointer;
  color: var(--muted, #94a3b8); font-size: 0.85rem; font-weight: 600;
  border-bottom: 2px solid transparent;
}
.media-tab.active { color: var(--accent, #3b7dd8); border-bottom-color: var(--accent, #3b7dd8); }
#media-body { max-height: 60vh; overflow-y: auto; }
.media-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 6px; }
.media-grid img {
  width: 100%; aspect-ratio: 1; object-fit: cover; border-radius: 8px;
  cursor: pointer; background: var(--input-bg, #1e293b);
}
.media-list { display: flex; flex-direction: column; gap: 2px; }
.media-row {
  display: flex; align-items: center; gap: 10px; padding: 10px 8px;
  border-radius: 8px; color: var(--text, #e2e8f0); text-decoration: none;
  font-size: 0.88rem; min-width: 0;
}
.media-row:hover { background: rgba(128, 128, 128, 0.1); }
.media-row span:last-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.media-row audio { width: 100%; height: 34px; }
.media-empty { color: var(--muted, #94a3b8); font-size: 0.88rem; text-align: center; padding: 28px 0; }

/* ── Auth screen ───────────────────────────────────────────────────────────── */
.auth-tabs {
  display: flex; gap: 4px; padding: 4px; margin-bottom: 16px;
  background: var(--input-bg, #1e293b); border-radius: 12px;
}
.auth-tab {
  flex: 1; padding: 9px 6px; border: none; cursor: pointer; border-radius: 9px;
  background: none; color: var(--muted, #94a3b8); font-size: 0.9rem; font-weight: 700;
}
.auth-tab.active { background: var(--accent, #3b7dd8); color: #fff; }

.pw-row { display: flex; align-items: center; gap: 6px; }
.pw-row input { flex: 1; min-width: 0; }
.pw-toggle {
  background: none; border: none; cursor: pointer; font-size: 1.05rem;
  padding: 6px 8px; border-radius: 8px; line-height: 1;
}
.field input.bad { border-color: #ef4444; }

.auth-hint { display: block; color: var(--muted, #94a3b8); font-size: 0.74rem; margin-top: 5px; line-height: 1.45; }
.auth-err { display: block; color: #f87171; font-size: 0.78rem; margin-top: 5px; }
.auth-err:empty { display: none; }
.auth-fa { direction: rtl; text-align: right; }

.strength { display: flex; align-items: center; gap: 9px; margin-top: 8px; }
.strength.hidden { display: none; }
.strength-track { flex: 1; height: 4px; border-radius: 2px; background: var(--border, #334155); overflow: hidden; }
.strength-fill { height: 4px; width: 0; border-radius: 2px; transition: width .15s ease; }
.strength-label { font-size: 0.74rem; font-weight: 700; min-width: 62px; text-align: right; }

.auth-warning {
  margin: 16px 0 4px; padding: 12px 13px; border-radius: 12px;
  background: rgba(245, 158, 11, 0.10); border: 1px solid rgba(245, 158, 11, 0.45);
}
.auth-warning.hidden { display: none; }
.auth-warning-head { color: #f59e0b; font-size: 0.85rem; margin-bottom: 6px; }
.auth-warning p { color: var(--text, #e2e8f0); font-size: 0.79rem; line-height: 1.5; margin: 0; }
.auth-warning p + p { margin-top: 8px; }

/* Location messages */
.loc-card {
  width: 260px; border: 1px solid var(--border); border-radius: 10px;
  overflow: hidden; background: var(--sidebar-bg);
}
.loc-map { display: block; width: 100%; height: 150px; border: 0; }
.loc-foot { display: block; padding: 8px 10px; text-decoration: none; }
.loc-title { font-size: 13px; font-weight: 700; color: var(--text); }
.loc-sub { font-size: 11.5px; color: var(--muted); margin-top: 2px; }

/* Location map built from proxied tiles (foreign map hosts are blocked in Iran) */
.loc-map { display: block; position: relative; width: 100%; height: 150px; overflow: hidden; }
.loc-tile { position: absolute; width: 256px; height: 256px; max-width: none; }
.loc-pin {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -100%);
  font-size: 22px; line-height: 1; filter: drop-shadow(0 1px 2px rgba(0,0,0,.5));
}

/* Disappearing messages: a distinctly different chat, so the mode is obvious */
.disappearing-bar {
  background: #1f2a3a; color: #9fb4d4; font-size: 12px; font-weight: 700;
  text-align: center; padding: 6px 14px; border-bottom: 1px solid #31415a;
}
body.disappearing-on #messages { background: #141a24; }
body.disappearing-on .msg-bubble { background: #1e2836; color: #dbe6f5; }
body.disappearing-on .msg-caption, body.disappearing-on .msg-time { color: #8fa3c0; }
.room-disappearing { margin-left: auto; font-size: 13px; opacity: .85; }

/* ── One person, and what you can do about them ──────────────────────────── */
.peer-head { display: flex; align-items: center; gap: 12px; padding: 6px 18px 12px; }
.peer-avatar {
  width: 46px; height: 46px; border-radius: 50%; background: var(--msg-bg, #eef1f5);
  display: flex; align-items: center; justify-content: center; font-size: 22px; font-weight: 700;
}
.peer-id { display: flex; flex-direction: column; min-width: 0; }
.peer-id b { font-size: 17px; }
.peer-tag { font-size: 12px; color: var(--muted, #6b7280); margin-top: 2px; }
.peer-tag-blocked { color: #dc2626; font-weight: 700; }
.peer-actions { display: flex; flex-direction: column; padding-bottom: 10px; }
.peer-sep { height: 1px; background: var(--border, #e0e4e9); margin: 6px 18px; }
.peer-row {
  display: flex; align-items: center; gap: 12px; width: 100%;
  padding: 12px 18px; background: none; border: 0; text-align: start; cursor: pointer;
  font: inherit; color: inherit;
}
.peer-row:hover { background: rgba(128, 128, 128, 0.08); }
.peer-row-icon { font-size: 19px; width: 24px; text-align: center; }
.peer-row-text { display: flex; flex-direction: column; min-width: 0; }
.peer-row-text b { font-size: 15px; font-weight: 700; }
.peer-row-text em {
  font-style: normal; font-size: 11.5px; color: var(--muted, #6b7280); margin-top: 2px;
}
.peer-row-danger .peer-row-text b { color: #dc2626; }

/* A message of mine the server accepted and never delivered. */
.msg-vanished { opacity: 0.45; }
.msg-vanished .msg-bubble {
  border: 1px dashed var(--muted, #9ca3af);
  background: transparent !important;
}

/* ── Searching inside a chat ─────────────────────────────────────────────── */
.chat-search {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 12px; background: var(--header, #fff);
  border-bottom: 1px solid var(--border, #e0e4e9);
}
.chat-search input {
  /* 16px, like every other field: anything smaller makes iOS zoom the page
     in on focus and never zoom back out. */
  flex: 1; min-width: 0; font: inherit; font-size: 16px;
  padding: 7px 10px; border-radius: 8px;
  border: 1px solid var(--border, #e0e4e9); background: var(--input-bg, #f0f2f5);
  color: inherit;
}
.chat-search-count { font-size: 12.5px; font-weight: 700; color: var(--muted, #6b7280); white-space: nowrap; }
.chat-search-note { font-size: 11px; color: #d97706; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ── Sending a file: numbers, and a way to stop ──────────────────────────── */
.upload-row {
  display: flex; align-items: center; gap: 8px; margin-top: 5px;
  width: 100%; min-width: 0;
}
.upload-status {
  flex: 1; min-width: 0; font-size: 11px; color: var(--muted, #6b7280);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.upload-btn {
  border: 0; background: rgba(0, 0, 0, 0.07); border-radius: 50%;
  width: 24px; height: 24px; cursor: pointer; font-size: 11px; line-height: 1;
  color: inherit; flex: none;
}
.upload-btn:hover { background: rgba(0, 0, 0, 0.14); }

/* ── @mentions ───────────────────────────────────────────────────────────── */
.mention-box {
  position: absolute; bottom: 62px; inset-inline-start: 12px;
  min-width: 180px; max-height: 200px; overflow-y: auto; z-index: 30;
  background: var(--sidebar, #fff); border: 1px solid var(--border, #e0e4e9);
  border-radius: 10px; box-shadow: 0 6px 20px rgba(0, 0, 0, 0.18);
}
.mention-item { padding: 9px 14px; cursor: pointer; font-size: 14px; }
.mention-item.active, .mention-item:hover { background: rgba(59, 125, 216, 0.12); }
.mention-fab {
  position: absolute; inset-inline-end: 16px; bottom: 130px; z-index: 25;
  min-width: 40px; height: 40px; border-radius: 20px; border: 0; cursor: pointer;
  background: var(--accent, #3b7dd8); color: #fff; font-size: 15px; font-weight: 800;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
}

/* ── Choosing where the pin goes ─────────────────────────────────────────── */
.loc-card-modal { width: min(460px, 94vw); }
.loc-picker-hint { padding: 0 18px 8px; font-size: 12px; color: var(--muted, #6b7280); }
/* The map owns every touch that lands on it.
   touch-action:none stops the browser scrolling or zooming the page with a
   gesture meant for the map; overscroll-behavior stops a horizontal drag
   turning into the browser's swipe-to-go-back, which in a single-page app
   closes whatever is open — the reported "swiping the map closes it". */
#loc-map-wrap {
  position: relative; height: 300px; overflow: hidden; background: #e8ecf0;
  touch-action: none; overscroll-behavior: none;
}
#loc-map {
  position: absolute; inset: 0; cursor: grab; user-select: none;
  touch-action: none; overscroll-behavior: none;
}
#loc-map:active { cursor: grabbing; }
.loc-tile { position: absolute; width: 256px; height: 256px; pointer-events: none; }
/* The fix, so it can be told apart from where the pin will land. */
.loc-me {
  position: absolute; width: 14px; height: 14px; margin: -7px 0 0 -7px;
  border-radius: 50%; background: #3b7dd8; border: 2px solid #fff;
  box-shadow: 0 0 0 2px rgba(59, 125, 216, 0.4); pointer-events: none;
}
/* Dead centre, and untouchable — the map slides under it. */
#loc-cross {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  font-size: 30px; pointer-events: none; transform: translateY(-12px);
}
.loc-zoom { position: absolute; inset-inline-end: 10px; bottom: 10px; display: flex; flex-direction: column; gap: 6px; }
.loc-zoom button {
  width: 34px; height: 34px; border-radius: 8px; cursor: pointer;
  border: 1px solid var(--border, #e0e4e9); background: var(--sidebar, #fff);
  font-size: 16px; line-height: 1; color: inherit;
}
.loc-picker-label { padding: 12px 18px 4px; font-size: 13.5px; font-weight: 600; }
.loc-picker-note { padding: 0 18px 4px; font-size: 11.5px; color: #d97706; }
.loc-picker-actions { display: flex; flex-wrap: wrap; gap: 8px; padding: 10px 18px 20px; }
.loc-picker-actions button {
  flex: 1; min-width: 120px; padding: 11px 12px; border-radius: 10px;
  border: 1px solid var(--border, #e0e4e9); cursor: pointer; font: inherit; font-weight: 700;
  background: var(--sidebar, #fff); color: inherit;
}
.loc-picker-actions .loc-send { background: var(--accent, #3b7dd8); color: #fff; border-color: transparent; }

/* Standard / HD, beside the staged photos it applies to. */
.pending-quality {
  align-self: center; margin-inline-start: 4px; padding: 6px 12px;
  border-radius: 14px; cursor: pointer; font: inherit; font-size: 12px; font-weight: 700;
  border: 1px solid var(--border, #e0e4e9); background: var(--sidebar, #fff); color: inherit;
}
.pending-quality.on { background: var(--accent, #3b7dd8); border-color: transparent; color: #fff; }

/* The 🔥 sheet: one-time and disappearing, as rows of chips. */
.chip-row { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
.chip {
  border: 1px solid var(--border); background: var(--input-bg); color: var(--text);
  border-radius: 16px; padding: 6px 14px; font-size: 0.85rem; cursor: pointer;
}
.chip.on { background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 600; }
.fire-hint { font-size: 0.78rem; color: var(--muted); margin: 2px 0 0; }
.fire-error { font-size: 0.78rem; color: var(--danger); margin: 8px 0 0; }

/* Show more / Show less on a long message. */
.fold-toggle {
  display: block; margin-top: 6px; padding: 0;
  background: none; border: none; cursor: pointer;
  color: var(--accent); font-size: 0.82rem; font-weight: 600;
}
.msg-wrapper.mine .fold-toggle { color: #dbeafe; }

/* ── Profile: brought into line with the app's sheet ─────────────────── */
/* The name-level messages sit outside a .modal-section, which is what
   supplies the padding everywhere else in the card. */
#profile-modal > .modal-card > .error,
#profile-modal > .modal-card > .success { padding: 0 20px; margin-top: 4px; text-align: center; }
#profile-modal .profile-name { margin-bottom: 0; }
.profile-name-row { display: flex; justify-content: center; margin-top: -6px; }
.pencil-btn {
  background: none; border: none; cursor: pointer; font-size: 1rem;
  padding: 4px 8px; border-radius: 8px; opacity: .85;
}
.pencil-btn:hover { background: var(--input-bg); opacity: 1; }
.username-editor {
  margin: 8px 16px 0; padding: 12px; border-radius: 12px;
  background: var(--input-bg); border: 1px solid var(--border);
}
.username-editor.hidden { display: none; }
.username-warn { font-size: 0.78rem; color: var(--muted); margin: 0 0 8px; line-height: 1.45; }
.username-editor input {
  width: 100%; padding: 10px 12px; border-radius: 10px;
  border: 1px solid var(--border); background: var(--sidebar-bg); color: var(--text);
}
.username-editor input:disabled { opacity: .5; }
.username-editor-row { display: flex; gap: 8px; margin-top: 10px; }
.username-editor-row .btn-primary, .username-editor-row .btn-ghost { margin-top: 0; }
.btn-ghost {
  flex: 1; padding: 11px; border-radius: 10px; border: 1px solid var(--border);
  background: none; color: var(--text); font-size: 0.95rem; font-weight: 600; cursor: pointer;
}
.username-editor-row .btn-primary { flex: 1; }
.username-editor-row .btn-primary:disabled { opacity: .5; cursor: default; }

/* The app's CURRENT → LATEST boxes. */
.version-row { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.version-box {
  flex: 1; text-align: center; padding: 10px 6px; border-radius: 12px;
  background: var(--input-bg); border: 1px solid var(--border);
}
.version-label { font-size: 0.62rem; letter-spacing: .08em; color: var(--muted); font-weight: 700; }
.version-value { font-size: 1rem; font-weight: 700; margin-top: 2px; }
.version-arrow { color: var(--muted); font-size: 1.1rem; }
.update-error { font-size: 0.78rem; color: var(--danger); margin: 8px 0 0; }
.update-error.hidden { display: none; }

/* ── "Add to Home Screen", for iOS ───────────────────────────────────────── */
/* Above the composer, out of the way of the messages, and pointing at the
   share button which on iOS Safari is at the BOTTOM of the screen. */
.install-hint {
  display: flex; align-items: center; gap: 10px;
  margin: 8px 10px 0; padding: 10px 12px;
  border-radius: 12px; background: var(--input-bg);
  border: 1px solid var(--border);
}
.install-hint.hidden { display: none; }
.install-hint-icon { font-size: 1.4rem; flex-shrink: 0; }
.install-hint-text { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.install-hint-text b { font-size: 0.85rem; }
.install-hint-text small { font-size: 0.75rem; color: var(--muted); margin-top: 2px; }
.install-hint-close {
  background: none; border: none; color: var(--muted); cursor: pointer;
  font-size: 0.9rem; padding: 6px; flex-shrink: 0;
}
