:root {
  --bg-rail: #1b1d23;
  --bg-sidebar: #23262e;
  --bg-chat: #2c2f37;
  --bg-input: #393c45;
  --bg-hover: #353841;
  --bg-active: #41444e;
  --bg-mention: rgba(250, 166, 26, 0.1);
  --border: #1f2128;
  --text: #e3e5ea;
  --text-muted: #9a9ea8;
  --text-strong: #ffffff;
  --accent: #5b6cf0;
  --accent-hover: #4a5ad8;
  --danger: #ed4245;
  --online: #3ba55d;
  --link: #3fa9f5;
  /* More of the palette as tokens, so the Light theme (client/appearance.css) can swap them. */
  --bg-panel: #1f2128; /* user panel and voice panel under the channel list */
  --warning: #faa61a; /* connecting, relayed, Push to Talk warnings, the mention bar */
  --status-idle: #f0b232;
  --status-offline: #80848e;
  --mention-bg: rgba(91, 108, 240, 0.3); /* @mention and in-app link pills */
  --mention-text: #c9cdfb;
  --overlay-subtle: rgba(255, 255, 255, 0.08); /* faint chips on the chat background */
  --spoiler-hidden: #18191d;
  --spoiler-hidden-hover: #121316;
  --text-faint: rgba(154, 158, 168, 0.45); /* muted channels */
  --auth-glow: #3a3f8f;
  --radius: 8px;
  font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
  font-size: 15px;
  color-scheme: dark;
}

* { box-sizing: border-box; }
html, body { height: 100%; margin: 0; }
body { background: var(--bg-rail); color: var(--text); display: flex; flex-direction: column; overflow: hidden; }
[hidden] { display: none !important; }
button { font: inherit; color: inherit; cursor: pointer; }
a { color: var(--link); }
.muted { color: var(--text-muted); }
.small { font-size: 12.5px; }
.strong { color: var(--text-strong); font-weight: 600; }
.error { color: var(--danger); font-size: 13px; min-height: 1em; margin: 4px 0; }

button.primary { background: var(--accent); border: 0; border-radius: 4px; padding: 10px 16px; color: #fff; font-weight: 600; }
button.primary:hover { background: var(--accent-hover); }
.icon-button { background: none; border: 0; color: var(--text-muted); font-size: 18px; padding: 6px; border-radius: 4px; }
.icon-button:hover { background: var(--bg-hover); color: var(--text); }

/* --- custom titlebar (desktop shell only; the window is frameless like Discord's) --- */
#titlebar { height: 28px; display: flex; align-items: stretch; background: var(--bg-rail); flex: none; }
.titlebar-drag { flex: 1; -webkit-app-region: drag; display: flex; align-items: center; padding-left: 12px; font-size: 12px; font-weight: 700; color: var(--text-muted); }
.titlebar-controls { display: flex; -webkit-app-region: no-drag; }
.titlebar-controls button { width: 46px; background: none; border: 0; color: var(--text-muted); }
.titlebar-controls button:hover { background: var(--bg-hover); color: var(--text); }
.titlebar-controls button.close:hover { background: var(--danger); color: #fff; }

/* macOS supplies the native traffic lights; keep their hit area clear of the drag region. */
.desktop-mac #titlebar { height: 36px; padding-left: 80px; }
.desktop-mac .titlebar-drag { padding-left: 8px; }
.desktop-mac .titlebar-controls { display: none; }

/* --- auth --- */
.auth { flex: 1; display: grid; place-items: center; background: radial-gradient(circle at 30% 20%, var(--auth-glow), var(--bg-rail) 60%); }
.auth-card { background: var(--bg-sidebar); padding: 32px; border-radius: var(--radius); width: min(440px, 92vw); display: flex; flex-direction: column; gap: 12px; box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4); }
.auth-card h1 { margin: 0; text-align: center; color: var(--text-strong); font-size: 24px; }
.auth-card > p { margin: 0; text-align: center; }
.auth-card label { display: flex; flex-direction: column; gap: 6px; font-size: 12px; font-weight: 700; text-transform: uppercase; color: var(--text-muted); }
input, textarea { font: inherit; color: var(--text); background: var(--bg-rail); border: 0; border-radius: 4px; padding: 10px; outline: none; }
input:focus, textarea:focus { box-shadow: 0 0 0 2px var(--accent); }

/* --- app layout --- */
.app { flex: 1; display: grid; grid-template-columns: 72px 240px 1fr 240px; min-height: 0; }

.guild-rail { background: var(--bg-rail); display: flex; flex-direction: column; align-items: center; gap: 8px; padding: 12px 0; overflow-y: auto; }
.guild-icon { position: relative; width: 48px; height: 48px; border-radius: 50%; border: 0; background: var(--bg-chat); color: var(--text); font-weight: 600; font-size: 16px; display: grid; place-items: center; transition: border-radius 0.15s, background 0.15s; flex: none; }
.guild-icon:hover, .guild-icon.active { border-radius: 16px; background: var(--accent); color: #fff; }
.guild-icon.action { color: var(--online); font-size: 24px; }
.guild-icon.action:hover { background: var(--online); color: #fff; }
.guild-icon::before { content: ''; position: absolute; left: -16px; width: 8px; border-radius: 0 4px 4px 0; background: var(--text-strong); height: 0; transition: height 0.15s; }
.guild-icon.unread::before { height: 8px; }
.guild-icon:hover::before { height: 20px; }
.guild-icon.active::before { height: 40px; }
.rail-separator { width: 32px; height: 2px; background: var(--bg-active); border-radius: 1px; flex: none; }

.sidebar { background: var(--bg-sidebar); display: flex; flex-direction: column; min-height: 0; }
.sidebar-header { height: 48px; padding: 0 16px; display: flex; align-items: center; justify-content: space-between; border-bottom: 1px solid var(--border); font-weight: 700; color: var(--text-strong); flex: none; }
.sidebar-header .icon-button { font-size: 14px; }
.channel-list { flex: 1; overflow-y: auto; padding: 12px 8px; }
.channel-category { display: flex; justify-content: space-between; align-items: center; padding: 4px 8px; font-size: 12px; font-weight: 700; text-transform: uppercase; color: var(--text-muted); }
.channel { display: flex; align-items: center; gap: 6px; width: 100%; text-align: left; padding: 6px 8px; margin: 1px 0; border: 0; border-radius: 4px; background: none; color: var(--text-muted); }
.channel .icon { opacity: 0.7; flex: none; }
.channel:hover { background: var(--bg-hover); color: var(--text); }
.channel.active { background: var(--bg-active); color: var(--text-strong); }
.channel.unread { color: var(--text-strong); font-weight: 600; }
.empty-state { padding: 24px; text-align: center; }

.user-panel { height: 56px; display: flex; align-items: center; gap: 8px; padding: 0 8px; background: var(--bg-panel); flex: none; }
.user-panel-names { flex: 1; min-width: 0; }
.user-panel-names div { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.avatar { width: 32px; height: 32px; border-radius: 50%; display: grid; place-items: center; font-weight: 700; color: #fff; flex: none; position: relative; }
.avatar.large { width: 40px; height: 40px; }
.avatar .status { position: absolute; right: -2px; bottom: -2px; width: 12px; height: 12px; border-radius: 50%; border: 3px solid var(--bg-sidebar); background: var(--status-offline); }
.avatar .status.online { background: var(--online); }

/* --- chat --- */
.chat { background: var(--bg-chat); display: flex; flex-direction: column; min-width: 0; min-height: 0; }
.chat-header { height: 48px; display: flex; align-items: center; gap: 8px; padding: 0 16px; border-bottom: 1px solid var(--border); flex: none; min-width: 0; }
.chat-header .channel-title { font-weight: 700; color: var(--text-strong); white-space: nowrap; }
.chat-header .channel-title::before { content: '# '; color: var(--text-muted); }
.chat-header .topic { border-left: 1px solid var(--bg-active); padding-left: 8px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.messages { flex: 1; overflow-y: auto; padding: 16px 0 8px; outline: none; }
.channel-start { padding: 16px; margin-bottom: 8px; }
.channel-start h2 { color: var(--text-strong); margin: 0 0 4px; font-size: 28px; }
.channel-retention { margin-top: 4px; font-size: 13px; } /* "Messages here are kept for 6 months." (client/js/retention.js) */
.message { position: relative; display: grid; grid-template-columns: 56px minmax(0, 1fr); padding: 2px 48px 2px 16px; } /* minmax: a wide code block scrolls in its box, not the whole list */
.message.group-start { margin-top: 16px; }
.message:hover { background: rgba(0, 0, 0, 0.08); }
.message.mentioned { background: var(--bg-mention); box-shadow: inset 2px 0 0 var(--warning); }
.message .gutter { display: flex; justify-content: flex-start; }
.message .gutter time { visibility: hidden; font-size: 11px; color: var(--text-muted); padding-top: 4px; }
.message:hover .gutter time { visibility: visible; }
.message .meta { display: flex; align-items: baseline; gap: 8px; }
.message .author { font-weight: 600; color: var(--text-strong); }
.message .meta time { font-size: 12px; color: var(--text-muted); }
.message .content { white-space: pre-wrap; overflow-wrap: anywhere; line-height: 1.375; } /* long links wrap instead of widening the list */
.message .edited { font-size: 11px; color: var(--text-muted); margin-left: 4px; }
.message .actions { position: absolute; right: 16px; top: -12px; display: none; background: var(--bg-sidebar); border: 1px solid var(--border); border-radius: 4px; }
.message:hover .actions { display: flex; }
.message .actions button { background: none; border: 0; padding: 4px 8px; color: var(--text-muted); font-size: 13px; }
.message .actions button:hover { color: var(--text); background: var(--bg-hover); }
.message .actions button.danger:hover { color: var(--danger); }
.message textarea.edit { width: 100%; resize: none; background: var(--bg-input); }
.message .edit-hint { font-size: 12px; }
.content code { background: var(--bg-rail); border-radius: 3px; padding: 1px 4px; font-family: Consolas, monospace; font-size: 85%; }
.content pre { background: var(--bg-rail); border: 1px solid var(--border); border-radius: 4px; padding: 8px; margin: 4px 0; overflow-x: auto; }
.content pre code { background: none; padding: 0; }
.content .mention { background: var(--mention-bg); color: var(--mention-text); border-radius: 3px; padding: 0 2px; font-weight: 500; }

.composer-wrap { padding: 0 16px 4px; flex: none; }
.composer { display: flex; align-items: flex-start; background: var(--bg-input); border-radius: var(--radius); }
.composer textarea { flex: 1; resize: none; max-height: 40vh; max-height: 40dvh; background: transparent; padding: 12px 16px 12px 4px; line-height: 1.375; }
.composer textarea:focus { box-shadow: none; }
.attach-button { background: none; border: 0; color: var(--text-muted); padding: 10px 12px; display: grid; place-items: center; }
.attach-button:hover { color: var(--text); }
.attach-button:disabled { opacity: 0.4; cursor: not-allowed; }
.attach-button:disabled:hover { color: var(--text-muted); }
.typing { height: 20px; padding: 2px 4px; }
.typing strong { color: var(--text); }

/* --- members --- */
.member-list { background: var(--bg-sidebar); overflow-y: auto; padding: 16px 8px; }
.member-group { padding: 16px 8px 4px; font-size: 12px; font-weight: 700; text-transform: uppercase; color: var(--text-muted); }
.member-group:first-child { padding-top: 0; }
.member { display: flex; align-items: center; gap: 12px; padding: 6px 8px; border-radius: 4px; }
.member:hover { background: var(--bg-hover); }
.member.offline { opacity: 0.4; }
.member .crown { color: var(--warning); font-size: 12px; }

/* --- misc --- */
.connection-banner { position: fixed; top: 36px; left: 50%; transform: translateX(-50%); background: var(--danger); color: #fff; padding: 6px 14px; border-radius: 4px; font-size: 13px; font-weight: 600; z-index: 10; }
.modal { background: var(--bg-sidebar); color: var(--text); border: 0; border-radius: var(--radius); padding: 24px; width: min(440px, 92vw); }
.modal::backdrop { background: rgba(0, 0, 0, 0.7); }
.modal h2 { margin-top: 0; color: var(--text-strong); }
.modal input { width: 100%; }
.modal input[readonly] { user-select: all; }
.modal-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 16px; }
.modal-actions button:not(.primary) { background: none; border: 0; padding: 10px 16px; }

@media (max-width: 1000px) {
  .app { grid-template-columns: 72px 220px 1fr; }
  .member-list { display: none; }
}

/* --- shared --- */
.icon { display: block; }
.toasts { position: fixed; bottom: 24px; left: 50%; transform: translateX(-50%); display: flex; flex-direction: column; gap: 8px; z-index: 20; }
.toast { background: var(--bg-rail); border: 1px solid var(--bg-active); border-left: 4px solid var(--danger); padding: 10px 14px; border-radius: 6px; box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4); max-width: 480px; }
.toast.info { border-left-color: var(--accent); }

/* --- uploads in the composer --- */
.pending-uploads { display: flex; gap: 8px; overflow-x: auto; background: var(--bg-input); border-radius: var(--radius) var(--radius) 0 0; padding: 12px 12px 4px; border-bottom: 1px solid var(--bg-active); }
.pending-uploads:not([hidden]) + .composer { border-radius: 0 0 var(--radius) var(--radius); }
.pending { position: relative; width: 160px; flex: none; background: var(--bg-sidebar); border-radius: 6px; padding: 8px; display: flex; flex-direction: column; gap: 6px; }
.pending .preview { height: 96px; border-radius: 4px; background: var(--bg-rail); display: grid; place-items: center; overflow: hidden; color: var(--text-muted); }
.pending .preview img, .pending .preview video { width: 100%; height: 100%; object-fit: cover; }
.pending .name { font-size: 12.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pending progress { width: 100%; height: 4px; appearance: none; border: 0; background: var(--bg-active); border-radius: 2px; }
.pending progress::-webkit-progress-bar { background: var(--bg-active); border-radius: 2px; }
.pending progress::-webkit-progress-value { background: var(--accent); border-radius: 2px; }
.pending.failed progress::-webkit-progress-value { background: var(--danger); }
.pending .remove { position: absolute; top: -6px; right: -6px; width: 22px; height: 22px; border-radius: 50%; border: 0; background: var(--danger); color: #fff; display: grid; place-items: center; padding: 0; }

.drop-overlay { position: absolute; inset: 0; background: rgba(91, 108, 240, 0.85); display: grid; place-items: center; z-index: 5; pointer-events: none; }
.drop-card { border: 2px dashed rgba(255, 255, 255, 0.7); border-radius: 12px; padding: 32px 48px; display: flex; flex-direction: column; align-items: center; gap: 6px; color: #fff; font-size: 18px; }
.drop-card .muted { color: rgba(255, 255, 255, 0.85); font-size: 14px; }
.chat { position: relative; }

/* --- attachments and embeds in messages --- */
.attachments { display: flex; flex-direction: column; gap: 6px; margin-top: 4px; align-items: flex-start; }
.attachment-image { max-width: min(400px, 100%); max-height: 300px; border-radius: 6px; cursor: zoom-in; display: block; background: var(--bg-rail); }
.attachment-video { max-width: min(480px, 100%); max-height: 360px; border-radius: 6px; background: #000; display: block; }
.file-card { display: flex; align-items: center; gap: 12px; background: var(--bg-sidebar); border: 1px solid var(--border); border-radius: 6px; padding: 10px 12px; width: min(420px, 100%); }
.file-card .icon { color: var(--link); flex: none; }
.file-card .meta-col { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.file-card .file-name { color: var(--link); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-decoration: none; }
.file-card .file-name:hover { text-decoration: underline; }
.file-card audio { width: 100%; margin-top: 8px; height: 36px; }
.file-card.audio { flex-wrap: wrap; }
.file-card .download { color: var(--text-muted); }
.file-card .download:hover { color: var(--text); }

.embed { margin-top: 6px; background: var(--bg-sidebar); border-left: 4px solid var(--bg-active); border-radius: 4px; padding: 10px 14px 14px; max-width: 432px; display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 6px 14px; overflow-wrap: anywhere; } /* a long word wraps inside the card; the first column starts at 0, so a 400px player can't widen it past a narrow card */
.embed > * { grid-column: 1; min-width: 0; }
.embed .provider { font-size: 12px; color: var(--text-muted); }
.embed .author { font-size: 13.5px; font-weight: 600; color: var(--text-strong); }
.embed .title { font-weight: 600; color: var(--link); text-decoration: none; }
.embed .title:hover { text-decoration: underline; }
.embed .description { font-size: 13.5px; color: var(--text); white-space: pre-line; }
.embed .thumb { grid-column: 2; grid-row: 1 / span 4; width: 80px; height: 80px; object-fit: cover; border-radius: 4px; }
/* A preview's media, every kind (a direct link's image, GIF or video; a card's image, GIF, video or
   player), is at most 400px wide and never wider than the room the preview has. The cap is on the
   box in the card, at the start of its row rather than stretched across it; a GIF's frame takes
   it and its image fills it, so the still drawn over the frame is the image. A bare embed is its
   media's frame: it repeats the cap as a length (a block is never wider than its container),
   which a spoiler sizing itself to the content counts, where it leaves percentages out. */
.embed > :is(.media, .gif-frame, .embed-player) { grid-column: 1 / -1; justify-self: start; max-width: min(400px, 100%); }
.embed .media { max-height: 300px; border-radius: 4px; display: block; }
.embed > .gif-frame { border-radius: 4px; }
.embed > .gif-frame > .media { max-width: 100%; }
.embed.bare { padding: 0; background: none; border: 0; display: block; max-width: 400px; }
/* chat auto-play: GIF images show a still frame while auto-play is off or Parley is unfocused */
.gif-frame { position: relative; display: inline-block; max-width: 100%; vertical-align: top; border-radius: 6px; overflow: hidden; } /* its corners clip the image and the still */
/* An attachment GIF's 400px cap goes on its frame: the frame sizes to the image, and a cap that
   only the image had would leave the frame (and the still drawn over it) at the natural width. */
.attachments > .gif-frame { max-width: min(400px, 100%); }
.attachments > .gif-frame > .attachment-image { max-width: 100%; }
.gif-still, .gif-badge { display: none; position: absolute; pointer-events: none; }
.gif-still { inset: 0; width: 100%; height: 100%; }
.gif-badge { top: 6px; left: 6px; padding: 1px 6px; border-radius: 4px; background: rgb(0 0 0 / 60%); color: #fff; font-size: 12px; font-weight: 700; }
.gif-frame.frozen .gif-still, .gif-frame.frozen .gif-badge { display: block; }
.gif-frame.frozen:not(:hover) img { visibility: hidden; }
.gif-frame.frozen:hover .gif-still, .gif-frame.frozen:hover .gif-badge { display: none; }
.embed-player { position: relative; width: 400px; aspect-ratio: 16 / 9; border-radius: 4px; overflow: hidden; background: #000; }
.embed-player img { width: 100%; height: 100%; object-fit: cover; display: block; }
.embed-player iframe { width: 100%; height: 100%; border: 0; display: block; }
.embed-player .play { position: absolute; inset: 0; margin: auto; width: 56px; height: 56px; border-radius: 50%; border: 0; background: rgba(0, 0, 0, 0.7); color: #fff; display: grid; place-items: center; }
.embed-player .play:hover { background: rgba(0, 0, 0, 0.85); transform: scale(1.05); }

/* The media viewer (#lightbox) is styled in client/media-viewer.css. */

/* --- voice channels in the sidebar --- */
.voice-users { display: flex; flex-direction: column; gap: 2px; margin: 0 0 6px 28px; }
.voice-user { display: flex; align-items: center; gap: 8px; padding: 3px 6px; border-radius: 4px; color: var(--text-muted); font-size: 14px; }
.voice-user .avatar { width: 24px; height: 24px; font-size: 12px; }
.voice-user .name { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.voice-user .flags { display: flex; gap: 4px; align-items: center; color: var(--text-muted); }
.voice-user .flags .off { color: var(--danger); }
.speaking .avatar, .tile.speaking { box-shadow: 0 0 0 2px var(--online); }
.live-badge { background: var(--danger); color: #fff; font-size: 10px; font-weight: 800; padding: 1px 5px; border-radius: 8px; letter-spacing: 0.04em; }

.voice-panel { border-top: 1px solid var(--border); background: var(--bg-panel); padding: 8px 10px; display: flex; flex-direction: column; gap: 8px; flex: none; }
.voice-panel .status { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.voice-panel .status-text { min-width: 0; }
.voice-panel .connected { color: var(--online); font-weight: 700; font-size: 13.5px; }
.voice-panel .connected.connecting { color: var(--warning); }
.voice-panel .where { font-size: 12px; color: var(--text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.voice-panel .controls { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.voice-panel .controls button { background: var(--bg-sidebar); border: 0; border-radius: 4px; padding: 6px; display: flex; align-items: center; justify-content: center; gap: 6px; font-size: 13px; color: var(--text); }
.voice-panel .controls button:hover { background: var(--bg-hover); }
.voice-panel .controls button.on { color: var(--online); }
.user-panel-controls { display: flex; }
.icon-button .off { color: var(--danger); }

/* --- call view --- */
.call-view { flex: 1; min-height: 0; background: #000; display: flex; flex-direction: column; }
/* Grid and focus layouts (client/js/callLayout.js). In grid mode layoutGrid sets --tile-w and
   --tile-h to the largest 16:9 size that fits; in focus mode one tile fills the stage and the
   rest sit in the strip (112 px high 16:9 tiles, 8 px apart, scrolling sideways). */
.call-grid { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.call-stage { flex: 1; min-height: 0; position: relative; padding: 16px 16px 8px; }
.call-stage.grid { display: flex; flex-wrap: wrap; justify-content: center; align-content: center; gap: 8px; padding-bottom: 16px; }
.call-stage.grid > .tile { flex: none; width: var(--tile-w, 320px); height: var(--tile-h, 180px); }
.call-stage.focus { display: flex; }
.call-stage.focus > .tile { flex: 1; min-width: 0; }
.call-stage.focus > .tile video { object-fit: contain; }
.call-grid.no-strip .call-stage, .call-grid.strip-hidden .call-stage { padding-bottom: 16px; }
.call-strip { flex: none; display: flex; gap: 8px; overflow-x: auto; overflow-y: hidden; padding: 4px 16px 8px; scrollbar-width: thin; }
.call-strip:empty, .call-grid.strip-hidden .call-strip { display: none; }
.call-strip > .tile { flex: none; height: 112px; width: calc(112px * 16 / 9); min-width: 124px; }
/* Centre the strip while it fits, without cutting off its start once it scrolls. */
.call-strip > :first-child { margin-left: auto; }
.call-strip > :last-child { margin-right: auto; }
.strip-toggle { position: absolute; left: 50%; bottom: 16px; transform: translateX(-50%); display: flex; align-items: center; gap: 4px; border: 0; border-radius: 16px; padding: 4px 12px 4px 8px; background: rgba(0, 0, 0, 0.7); color: #fff; font-size: 12px; font-weight: 600; opacity: 0; transition: opacity 0.15s; }
.call-stage:hover .strip-toggle, .strip-toggle:focus-visible, .strip-hidden .strip-toggle { opacity: 1; }
.strip-toggle:hover { background: rgba(0, 0, 0, 0.85); }
/* Tiles are size containers so avatars, labels and buttons scale down in small tiles. */
.tile { position: relative; background: var(--bg-sidebar); border-radius: 8px; overflow: hidden; display: grid; place-items: center; container-type: size; cursor: pointer; }
.tile:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.tile:fullscreen { cursor: default; }
.tile:fullscreen video { object-fit: contain; }
.tile video { width: 100%; height: 100%; object-fit: cover; position: absolute; inset: 0; background: #000; }
.tile.screen video { object-fit: contain; }
.tile.mirror video { transform: scaleX(-1); }
.tile .avatar { width: clamp(32px, 38cqh, 128px); height: clamp(32px, 38cqh, 128px); font-size: clamp(14px, 15cqh, 52px); }
.tile .label { position: absolute; left: 8px; bottom: 8px; max-width: calc(100% - 16px); background: rgba(0, 0, 0, 0.6); color: #fff; padding: 3px 8px; border-radius: 4px; font-size: 13px; display: flex; gap: 6px; align-items: center; }
.tile .label .name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tile .label > :not(.name) { flex: none; }
.tile .label .off { color: var(--danger); }
.tile .state { position: absolute; right: 8px; top: 8px; font-size: 11px; color: var(--warning); background: rgba(0, 0, 0, 0.6); padding: 2px 6px; border-radius: 4px; }
.tile .fullscreen-btn { position: absolute; right: 8px; bottom: 8px; background: rgba(0, 0, 0, 0.6); color: #fff; border: 0; border-radius: 4px; padding: 4px; display: none; }
.tile:hover .fullscreen-btn { display: block; }
/* Small tiles (the strip): tighter labels, badges and buttons; very narrow ones show icons only. */
@container (max-height: 140px) {
  .tile .label { left: 4px; bottom: 4px; max-width: calc(100% - 8px); padding: 2px 6px; font-size: 11px; gap: 4px; }
  .tile .label svg { width: 12px; height: 12px; }
  .tile .live-badge { font-size: 8px; padding: 0 4px; }
  .tile .state { right: 4px; top: 4px; font-size: 10px; padding: 1px 4px; }
  .tile .fullscreen-btn { right: 4px; bottom: 4px; padding: 2px; }
  .tile .fullscreen-btn svg { width: 14px; height: 14px; display: block; }
}
@container (max-width: 150px) {
  .tile .label .name { display: none; }
  .tile .label:not(:has(> :not(.name))) { display: none; }
}
.call-bar { display: flex; justify-content: center; gap: 12px; padding: 12px 0 20px; }
.call-bar button { width: 52px; height: 52px; border-radius: 50%; border: 0; background: var(--bg-active); color: var(--text-strong); display: grid; place-items: center; }
.call-bar button:hover { filter: brightness(1.2); }
.call-bar button.on { background: #fff; color: #000; }
.call-bar button.active-off { background: var(--danger); color: #fff; }
.call-bar button.hangup { background: var(--danger); color: #fff; }
.call-join { display: flex; flex-direction: column; align-items: center; gap: 16px; padding: 48px; color: var(--text); margin: auto; }
.call-join h2 { margin: 0; color: var(--text-strong); }
.call-join button.primary { background: var(--online); }

.voice-panel button.where { background: none; border: 0; padding: 0; cursor: pointer; text-align: left; max-width: 100%; display: block; }
.voice-panel button.where:hover { color: var(--text); text-decoration: underline; }
.chat-header .channel-title.voice::before { content: none; }
.chat-header .icon { color: var(--text-muted); }
.empty-state.welcome { margin: auto; max-width: 420px; padding-top: 12vh; padding-top: 12dvh; display: flex; flex-direction: column; align-items: center; gap: 8px; }
.empty-state.welcome h2 { color: var(--text-strong); margin: 0; }
.welcome-actions { display: flex; gap: 12px; margin-top: 12px; flex-wrap: wrap; justify-content: center; }
button.secondary { background: var(--bg-active); border: 0; border-radius: 4px; padding: 10px 16px; color: var(--text-strong); font-weight: 600; }
button.secondary:hover { background: var(--bg-hover); }
.member .member-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.member .mod-actions { display: none; gap: 4px; }
.member:hover .mod-actions { display: flex; }
.member .mod-actions button { background: var(--bg-active); border: 0; border-radius: 3px; padding: 2px 6px; font-size: 11.5px; color: var(--text); }
.member .mod-actions button.danger:hover { background: var(--danger); color: #fff; }

/* --- avatars, status --- */
.avatar { overflow: visible; }
.avatar .avatar-img { width: 100%; height: 100%; border-radius: 50%; object-fit: cover; display: block; }
.avatar .status.idle { background: var(--status-idle); }
.avatar .status.idle::after { content: ''; position: absolute; width: 6px; height: 6px; border-radius: 50%; background: var(--bg-sidebar); top: -1px; left: -1px; }
.avatar .status.dnd { background: var(--danger); }
.avatar .status.dnd::after { content: ''; position: absolute; width: 6px; height: 2px; border-radius: 1px; background: var(--bg-sidebar); top: 2px; left: 0; }
.avatar .status.invisible, .avatar .status.offline { background: var(--status-offline); }
.avatar .status.invisible::after { content: ''; position: absolute; width: 4px; height: 4px; border-radius: 50%; background: var(--bg-sidebar); top: 1px; left: 1px; }
.clickable { cursor: pointer; }
.author.clickable:hover { text-decoration: underline; }
.member { cursor: pointer; }
.member .member-text { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.member .member-status { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.voice-user { cursor: pointer; }
.voice-user:hover { background: var(--bg-hover); }
.user-panel-names #user-panel-username { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* --- popout (profile card, status menu) --- */
.popout { position: fixed; z-index: 30; filter: drop-shadow(0 8px 24px rgba(0, 0, 0, 0.5)); }
.profile-card { width: 300px; background: var(--bg-rail); border-radius: 10px; overflow: hidden; position: relative; }
.profile-card.loading { padding: 24px; }
.profile-card.themed .profile-body { background: rgba(0, 0, 0, 0.35); }
.profile-banner { height: 105px; background: var(--accent); }
.profile-banner img { width: 100%; height: 100%; object-fit: cover; display: block; }
.profile-avatar-wrap { position: absolute; top: 60px; left: 16px; padding: 5px; border-radius: 50%; background: var(--bg-rail); }
.profile-card.themed .profile-avatar-wrap { background: rgba(0, 0, 0, 0.6); }
.profile-avatar-wrap .avatar.large { width: 80px; height: 80px; font-size: 32px; }
.profile-avatar-wrap .avatar .status { width: 18px; height: 18px; border-width: 4px; border-color: var(--bg-rail); }
.profile-body { margin: 52px 12px 12px; padding: 12px; border-radius: 8px; background: var(--bg-sidebar); display: flex; flex-direction: column; gap: 4px; }
.profile-name { font-size: 20px; font-weight: 700; color: var(--text-strong); word-break: break-word; }
.profile-username { font-size: 14px; }
.profile-custom-status { margin-top: 6px; font-size: 14px; }
.profile-section-title { margin-top: 12px; font-size: 12px; font-weight: 700; text-transform: uppercase; color: var(--text-muted); }
.profile-bio { white-space: pre-wrap; word-break: break-word; font-size: 14px; }
.profile-since { font-size: 14px; }
.profile-edit { margin-top: 12px; }
.status-menu { width: 240px; background: var(--bg-rail); border-radius: 8px; padding: 6px; display: flex; flex-direction: column; }
.status-option { display: grid; grid-template-columns: 14px 1fr; column-gap: 10px; align-items: center; text-align: left; background: none; border: 0; padding: 8px; border-radius: 4px; color: var(--text); }
.status-option > .small { grid-column: 2; }
.status-option:not(:has(> .status-dot, > .icon)) { display: block; } /* a text-only row (Set a custom status) */
.status-option:hover { background: var(--accent); color: #fff; }
.status-option.current { font-weight: 700; }
.status-dot { width: 10px; height: 10px; border-radius: 50%; background: var(--status-offline); }
.status-dot.online { background: var(--online); }
.status-dot.idle { background: var(--status-idle); }
.status-dot.dnd { background: var(--danger); }
.menu-separator { height: 1px; background: var(--bg-active); margin: 4px 6px; }
.link-button { background: none; border: 0; color: var(--link); padding: 4px 6px; }
.link-button:hover { text-decoration: underline; }

/* --- settings --- */
.settings { width: min(960px, 96vw); height: min(680px, 92vh); height: min(680px, 92dvh); padding: 0; border: 0; border-radius: var(--radius); background: var(--bg-chat); color: var(--text); }
.settings::backdrop { background: rgba(0, 0, 0, 0.75); }
.settings-layout { display: grid; grid-template-columns: 200px 1fr; height: 100%; }
.settings-nav { background: var(--bg-sidebar); padding: 24px 8px; display: flex; flex-direction: column; gap: 2px; }
.settings-nav .profile-section-title { padding: 0 10px 6px; margin: 0; }
.settings-nav button { text-align: left; background: none; border: 0; padding: 8px 10px; border-radius: 4px; color: var(--text-muted); }
.settings-nav button:hover { background: var(--bg-hover); color: var(--text); }
.settings-nav button.active { background: var(--bg-active); color: var(--text-strong); }
.settings-content { padding: 24px 32px; overflow-y: auto; }
.settings-content h2 { margin-top: 0; color: var(--text-strong); }
.settings-close { position: absolute; top: 12px; right: 12px; }
.settings-split { display: grid; grid-template-columns: minmax(0, 1fr) 300px; gap: 32px; align-items: start; }
.settings-form { display: flex; flex-direction: column; gap: 16px; }
.settings-field { display: flex; flex-direction: column; gap: 6px; }
.settings-field > span:first-child { font-size: 12px; font-weight: 700; text-transform: uppercase; color: var(--text-muted); }
.settings-field textarea { resize: vertical; }
.settings-row { display: flex; align-items: center; gap: 10px; }
.settings-row input[type='color'] { width: 44px; height: 32px; padding: 2px; background: var(--bg-rail); border: 0; border-radius: 4px; }
.settings-form > button.primary { align-self: flex-start; }
.settings-preview .profile-section-title { margin: 0 0 8px; }
.sound-list { display: flex; flex-direction: column; gap: 2px; margin-top: 8px; }
.sound-row { display: flex; justify-content: space-between; align-items: center; padding: 6px 8px; border-radius: 4px; }
.sound-row:hover { background: var(--bg-hover); }
.settings-toggle { display: flex; align-items: center; gap: 8px; color: var(--text-strong); cursor: pointer; }
.settings-field input[type='range'] { width: min(360px, 100%); }

@media (max-width: 760px) {
  .settings-layout { grid-template-columns: 1fr; }
  .settings-nav { flex-direction: row; padding: 12px; }
  .settings-split { grid-template-columns: 1fr; }
}
.settings-nav button.danger-text { color: var(--danger); }
.settings-nav button.danger-text:hover { background: rgba(237, 66, 69, 0.12); color: var(--danger); }

/* --- voice settings --- */
.choice { display: flex; align-items: flex-start; gap: 10px; padding: 8px 10px; border-radius: 4px; background: var(--bg-sidebar); cursor: pointer; }
.choice:hover { background: var(--bg-hover); }
.choice input { margin-top: 3px; }
.choice > span { display: flex; flex-direction: column; gap: 2px; }
.choice strong { color: var(--text-strong); font-weight: 600; }
.mic-meter { flex: 1; max-width: 320px; height: 8px; border-radius: 4px; background: var(--bg-rail); overflow: hidden; }
.mic-meter-fill { height: 100%; width: 0%; background: var(--online); transition: width 50ms linear; }

/* --- large file transfers (client/js/transfers.js) --- */
.attach-menu { width: 280px; }
.attach-menu .status-option { grid-template-columns: 20px 1fr; }
.attach-menu .status-option .icon { color: var(--text-muted); }
.attach-menu .status-option:hover .icon { color: #fff; }
.transfer-picker { width: 320px; max-height: min(480px, 80vh); max-height: min(480px, 80dvh); background: var(--bg-rail); border-radius: 8px; padding: 12px; display: flex; flex-direction: column; gap: 8px; }
.transfer-picker-title { font-weight: 700; color: var(--text-strong); }
.transfer-picker-files { display: flex; flex-direction: column; gap: 4px; max-height: 148px; overflow-y: auto; flex: none; }
.transfer-picker-file { display: flex; align-items: center; gap: 10px; background: var(--bg-sidebar); border-radius: 6px; padding: 8px; }
.transfer-picker-file .name, .transfer .name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text-strong); }
.transfer-picker-file > div { min-width: 0; }
.transfer-picker p { margin: 0; }
.transfer-search { background: var(--bg-sidebar); }
.transfer-recipients { overflow-y: auto; display: flex; flex-direction: column; gap: 2px; min-height: 0; }
.transfer-recipient { display: grid; grid-template-columns: 32px 1fr auto; align-items: center; gap: 10px; background: none; border: 0; border-radius: 4px; padding: 6px 8px; text-align: left; }
.transfer-recipient:hover { background: var(--bg-hover); }
.transfer-recipient .avatar .status { border-color: var(--bg-rail); }
.transfer-recipient:hover .avatar .status { border-color: var(--bg-hover); }
.transfer-empty { padding: 8px; }
.transfers-dock { position: fixed; right: 16px; bottom: 16px; z-index: 25; display: flex; align-items: center; gap: 6px; background: var(--bg-rail); border: 1px solid var(--bg-active); border-radius: 18px; padding: 6px 12px; color: var(--text); box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4); }
.transfers-dock:hover, .transfers-dock.open { background: var(--bg-hover); }
.transfers-count { background: var(--accent); color: #fff; border-radius: 9px; min-width: 18px; padding: 0 5px; font-size: 12px; font-weight: 700; text-align: center; }
.transfers-panel { position: fixed; right: 16px; bottom: 60px; z-index: 25; width: min(380px, calc(100vw - 32px)); max-height: 60vh; max-height: 60dvh; display: flex; flex-direction: column; background: var(--bg-rail); border: 1px solid var(--bg-active); border-radius: 8px; box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5); }
.transfers-panel > header { display: flex; align-items: center; justify-content: space-between; padding: 8px 8px 8px 14px; border-bottom: 1px solid var(--bg-active); }
.transfers-list { overflow-y: auto; padding: 6px; display: flex; flex-direction: column; gap: 4px; }
.transfer { display: grid; grid-template-columns: 22px 1fr auto; align-items: center; gap: 10px; padding: 8px; border-radius: 6px; background: var(--bg-sidebar); }
.transfer > .icon { color: var(--text-muted); }
.transfer.incoming.offered > .icon { color: var(--accent); }
.transfer.completed > .icon { color: var(--online); }
.transfer.failed > .icon, .transfer.cancelled > .icon, .transfer.expired > .icon, .transfer.declined > .icon { color: var(--danger); }
.transfer-body { min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.transfer progress { width: 100%; height: 4px; appearance: none; border: 0; background: var(--bg-active); border-radius: 2px; }
.transfer progress::-webkit-progress-bar { background: var(--bg-active); border-radius: 2px; }
.transfer progress::-webkit-progress-value { background: var(--accent); border-radius: 2px; }
.transfer-actions { display: flex; gap: 6px; }
.transfer-actions button.primary, .transfer-actions button.secondary { padding: 6px 10px; font-size: 13px; }
/* Without the member list the chat column reaches the right edge: lift the dock (and the panel
   it opens) clear of the composer, whose height app.js keeps in --composer-height. */
@media (max-width: 1000px) {
  .transfers-dock { bottom: calc(var(--composer-height, 96px) + 8px); }
  .transfers-panel { bottom: calc(var(--composer-height, 96px) + 52px); max-height: min(60vh, calc(100vh - var(--composer-height, 96px) - 68px)); max-height: min(60dvh, calc(100dvh - var(--composer-height, 96px) - 68px)); }
}

/* --- emoji (client/js/emoji.js): native glyphs, custom images, picker, autocomplete --- */
.emoji, .ep-emoji, .ep-tab, .ep-tone, .ep-tone-option, .ep-preview-glyph { font-family: 'Segoe UI Emoji', 'Apple Color Emoji', 'Noto Color Emoji', 'Segoe UI', sans-serif; }
.content .emoji { font-size: 1.375em; line-height: 1; vertical-align: -0.2em; }
.content img.emoji { width: 1.375em; height: 1.375em; object-fit: contain; vertical-align: -0.3em; }
/* Messages that are only emoji (at most 30) show them large, as on Discord. */
.content.jumbo { line-height: 1.25; }
.content.jumbo .emoji { font-size: 48px; vertical-align: bottom; }
.content.jumbo img.emoji { width: 48px; height: 48px; }

.emoji-button { background: none; border: 0; color: var(--text-muted); padding: 10px 12px; display: grid; place-items: center; }
.emoji-button:hover { color: var(--text); }
.composer-wrap { position: relative; }
.emoji-autocomplete { position: absolute; left: 16px; right: 16px; bottom: 100%; margin-bottom: 4px; z-index: 5; max-height: 360px; overflow-y: auto; background: var(--bg-sidebar); border: 1px solid var(--border); border-radius: var(--radius); padding: 6px; box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4); }
.emoji-ac-title { font-size: 12px; font-weight: 700; text-transform: uppercase; color: var(--text-muted); padding: 4px 8px 6px; }
.emoji-ac-title strong { text-transform: none; color: var(--text); }
.emoji-ac-item { display: flex; align-items: center; gap: 10px; width: 100%; background: none; border: 0; border-radius: 4px; padding: 6px 8px; text-align: left; }
.emoji-ac-item.active, .emoji-ac-item:hover { background: var(--bg-active); }
.emoji-ac-item .emoji { font-size: 22px; line-height: 1; width: 24px; height: 24px; display: grid; place-items: center; object-fit: contain; }
.emoji-ac-label { flex: 1; color: var(--text-strong); }

.emoji-picker { width: 424px; max-width: calc(100vw - 16px); height: 440px; max-height: calc(100vh - 16px); max-height: calc(100dvh - 16px); display: flex; flex-direction: column; background: var(--bg-sidebar); border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; }
.ep-header { position: relative; display: flex; align-items: center; gap: 8px; padding: 10px; border-bottom: 1px solid var(--border); }
.ep-search { flex: 1; min-width: 0; padding: 8px 10px; }
.ep-tone, .ep-tone-option { background: none; border: 0; border-radius: 4px; font-size: 22px; line-height: 1; padding: 4px; }
.ep-tone:hover, .ep-tone-option:hover, .ep-tone-option.current { background: var(--bg-active); }
.ep-tones { position: absolute; top: 8px; right: 8px; z-index: 2; display: flex; gap: 2px; padding: 2px; background: var(--bg-rail); border: 1px solid var(--border); border-radius: 6px; }
.ep-main { flex: 1; display: flex; min-height: 0; }
.ep-tabs { flex: none; width: 48px; display: flex; flex-direction: column; gap: 2px; padding: 6px 4px; background: var(--bg-rail); overflow: hidden auto; scrollbar-width: none; }
.ep-tab { flex: none; height: 32px; display: grid; place-items: center; background: none; border: 0; border-radius: 6px; font-size: 20px; line-height: 1; filter: grayscale(1); opacity: 0.7; }
.ep-tab:hover, .ep-tab.active { filter: none; opacity: 1; background: var(--bg-active); }
.ep-tab img { width: 22px; height: 22px; object-fit: contain; }
.ep-body { position: relative; flex: 1; overflow-y: auto; padding: 0 8px 8px; }
.ep-section-title { position: sticky; top: 0; z-index: 1; margin: 0; padding: 8px 4px 6px; font-size: 12px; font-weight: 700; text-transform: uppercase; color: var(--text-muted); background: var(--bg-sidebar); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ep-grid { display: grid; grid-template-columns: repeat(auto-fill, 40px); gap: 2px; }
.ep-emoji { width: 40px; height: 40px; display: grid; place-items: center; padding: 0; background: none; border: 0; border-radius: 6px; font-size: 28px; line-height: 1; }
.ep-emoji:hover, .ep-emoji:focus-visible { background: var(--bg-active); outline: none; }
.ep-emoji img { width: 32px; height: 32px; object-fit: contain; }
.ep-empty { padding: 24px 8px; text-align: center; }
.ep-footer { flex: none; display: flex; align-items: center; gap: 10px; min-height: 52px; padding: 8px 12px; border-top: 1px solid var(--border); background: var(--bg-rail); }
.ep-preview-glyph { width: 32px; height: 32px; display: grid; place-items: center; font-size: 28px; line-height: 1; object-fit: contain; }
.ep-preview-text { display: flex; flex-direction: column; min-width: 0; }
.ep-preview-text strong { color: var(--text-strong); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* server settings: Emoji */
.emoji-requirements { margin: 0 0 16px; padding-left: 18px; line-height: 1.6; }
.emoji-slots { font-size: 13px; }
.emoji-admin-list { margin-top: 16px; display: flex; flex-direction: column; border-top: 1px solid var(--border); }
.emoji-admin-row { display: grid; grid-template-columns: 48px minmax(0, 1fr) 80px 36px; align-items: center; gap: 12px; padding: 8px 4px; border-bottom: 1px solid var(--border); }
.emoji-admin-img { width: 32px; height: 32px; object-fit: contain; }
.emoji-admin-name { display: flex; align-items: center; gap: 2px; color: var(--text-muted); }
.emoji-admin-name input { flex: 0 1 280px; min-width: 0; padding: 6px 8px; }
.emoji-delete:hover { color: var(--danger); }

/* --- reactions (client/js/reactions.js): chips under a message, Add Reaction, tooltip --- */
.reactions { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; margin: 4px 0 2px; }
.reaction { display: inline-flex; align-items: center; gap: 6px; height: 26px; padding: 2px 6px; border-radius: 8px; border: 1px solid transparent; background: var(--bg-input); color: var(--text-muted); font-size: 14px; font-weight: 600; line-height: 1; }
.reaction:hover { border-color: var(--text-muted); }
.reaction[aria-disabled="true"] { cursor: default; }
.reaction[aria-disabled="true"]:hover { border-color: transparent; }
.reaction.me[aria-disabled="true"]:hover { border-color: var(--accent); }
.reaction.me { background: rgba(91, 108, 240, 0.18); border-color: var(--accent); color: var(--text-strong); }
.reaction .emoji { font-size: 16px; line-height: 1; }
.reaction img.emoji { width: 16px; height: 16px; object-fit: contain; }
.reaction-count { min-width: 9px; text-align: center; font-variant-numeric: tabular-nums; }
.reaction.reaction-add { visibility: hidden; padding: 2px 8px; }
.message:hover .reaction.reaction-add, .reaction.reaction-add:focus-visible { visibility: visible; }
.reaction.reaction-add:hover { color: var(--text); }
.message .actions button.add-reaction { display: grid; place-items: center; padding: 4px 6px; }
.reaction-tooltip { position: fixed; z-index: 40; display: flex; align-items: center; gap: 8px; max-width: 280px; padding: 8px 12px; background: var(--bg-rail); color: var(--text); border-radius: 6px; font-size: 14px; line-height: 1.3; box-shadow: 0 8px 24px rgba(0, 0, 0, 0.45); pointer-events: none; }
.reaction-tooltip .emoji { font-size: 32px; line-height: 1; flex: none; }
.reaction-tooltip img.emoji { width: 32px; height: 32px; object-fit: contain; }
.reaction-tooltip-text { min-width: 0; overflow-wrap: anywhere; }

/* --- desktop app downloads and updates --- */
.guild-icon.update-ready { background: var(--online); color: #fff; }
.guild-icon.update-ready:hover { border-radius: 16px; }
.download-list { display: flex; flex-wrap: wrap; gap: 8px; margin: 4px 0; }
a.download-button { display: inline-flex; align-items: baseline; gap: 6px; background: var(--accent); color: #fff; border-radius: 4px; padding: 10px 16px; font-weight: 600; text-decoration: none; }
a.download-button:hover { background: var(--accent-hover); text-decoration: none; }
a.download-button .small { font-weight: 400; opacity: 0.85; }
.settings-field.spellcheck-field { margin: 24px 0; }

/* --- text chat in voice channels (client/js/voiceChat.js) --- */
/* The chat bubble on a voice channel row shows on hover, on the open channel, and while unread. */
.voice-channel-row { position: relative; }
.voice-channel-row .channel { padding-right: 36px; }
.voice-channel-row .channel-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.voice-chat-button { position: absolute; right: 4px; top: 50%; transform: translateY(-50%); display: grid; place-items: center; width: 28px; height: 28px; border: 0; border-radius: 4px; background: none; color: var(--text-muted); opacity: 0; }
.voice-channel-row:hover .voice-chat-button, .voice-chat-button:focus-visible, .voice-chat-button.on, .voice-chat-button.unread { opacity: 1; }
.voice-chat-button:hover, .voice-chat-button.on { color: var(--text-strong); }
.voice-chat-button.unread { color: var(--text-strong); }
/* Unread: a dot on the bubble; mentions: the count instead. */
.voice-chat-button.unread::after { content: ''; position: absolute; right: 3px; top: 4px; width: 8px; height: 8px; border-radius: 50%; background: var(--text-strong); box-shadow: 0 0 0 2px var(--bg-sidebar); }
.voice-chat-button:has(.mention-badge)::after { content: none; }
.voice-chat-button .mention-badge { position: absolute; right: -2px; top: 0; min-width: 16px; height: 16px; padding: 0 4px; border-radius: 8px; background: var(--danger); color: #fff; font-size: 11px; font-weight: 700; line-height: 16px; text-align: center; box-shadow: 0 0 0 2px var(--bg-sidebar); }
.chat-header .voice-chat-toggle { margin-left: auto; position: relative; display: grid; place-items: center; }
.chat-header .voice-chat-toggle.on, .chat-header .voice-chat-toggle.on .icon { color: var(--text-strong); }
.chat-header .voice-chat-toggle.unread::after { content: ''; position: absolute; right: 3px; top: 3px; width: 8px; height: 8px; border-radius: 50%; background: var(--text-strong); box-shadow: 0 0 0 2px var(--bg-chat); }
/* Chat open: the call on the left, the channel's messages and composer docked on the right. The
   member list makes room, as in Discord's call view. */
.app.voice-chat-open { grid-template-columns: 72px 240px minmax(0, 1fr); }
.app.voice-chat-open .member-list { display: none; }
.chat.with-voice-chat { display: grid; grid-template-columns: minmax(0, 1fr) clamp(300px, 38%, 440px); grid-template-rows: auto minmax(0, 1fr) auto; grid-template-areas: 'header header' 'call messages' 'call composer'; }
.chat.with-voice-chat > .chat-header { grid-area: header; }
.chat.with-voice-chat > .call-view { grid-area: call; }
.chat.with-voice-chat > .messages { grid-area: messages; border-left: 1px solid var(--border); }
.chat.with-voice-chat > .composer-wrap { grid-area: composer; border-left: 1px solid var(--border); padding-top: 8px; }
@media (max-width: 1000px) {
  .app.voice-chat-open { grid-template-columns: 72px 220px minmax(0, 1fr); }
}

/* --- context menus (client/js/contextMenu.js) --- */
.context-menu-layer { position: fixed; inset: 0 auto auto 0; z-index: 40; }
.context-menu { position: fixed; min-width: 188px; max-width: 320px; max-height: calc(100vh - 16px); max-height: calc(100dvh - 16px); overflow-y: auto; padding: 6px 8px; background: var(--bg-rail); border: 1px solid var(--border); border-radius: 6px; box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5); outline: none; font-size: 14px; }
.context-menu-item { display: flex; align-items: center; gap: 8px; min-height: 32px; padding: 6px 8px; margin: 2px 0; border-radius: 3px; color: var(--text); cursor: pointer; outline: none; user-select: none; }
.context-menu-item:focus { background: var(--accent); color: #fff; }
.context-menu-item.danger { color: var(--danger); }
.context-menu-item.danger:focus { background: var(--danger); color: #fff; }
.context-menu-item.disabled { opacity: 0.5; cursor: not-allowed; }
.context-menu-item.disabled:focus { background: none; color: var(--text); }
.context-menu-text { flex: 1; min-width: 0; }
.context-menu-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.context-menu-hint { font-size: 12px; color: var(--text-muted); }
.context-menu-item:focus .context-menu-hint { color: inherit; opacity: 0.85; }
.context-menu-icon { display: flex; flex: none; }
.context-menu-check { display: grid; place-items: center; width: 18px; height: 18px; border: 1px solid var(--text-muted); border-radius: 4px; }
.context-menu-check.on { background: var(--accent); border-color: var(--accent); color: #fff; }
.context-menu-separator { height: 1px; margin: 4px 4px; background: var(--bg-active); }
.context-menu-custom { padding: 6px 8px; }
.clipboard-scratch { position: fixed; top: -1000px; left: -1000px; opacity: 0; }

/* --- message actions, jump-to-message, date dividers (client/js/messageNav.js) --- */
.message .actions button.more-actions { display: grid; place-items: center; padding: 4px 6px; }
.message.menu-target { background: rgba(0, 0, 0, 0.08); }
.message.menu-target .actions { display: flex; }
.message.jump-flash { animation: jump-flash 2s ease-out; }
@keyframes jump-flash {
  0%, 30% { background: rgba(91, 108, 240, 0.28); }
  100% { background: transparent; }
}
.date-divider { display: flex; align-items: center; gap: 8px; margin: 24px 16px 8px; color: var(--text-muted); font-size: 12px; font-weight: 600; }
.date-divider::before, .date-divider::after { content: ''; flex: 1; height: 1px; background: var(--bg-active); }
.date-divider + .message.group-start { margin-top: 0; }
.jump-bar { position: sticky; bottom: 0; z-index: 2; display: flex; align-items: center; justify-content: space-between; gap: 12px; margin: 8px 16px 0; padding: 6px 8px 6px 14px; background: var(--accent); color: #fff; border-radius: 8px; font-size: 14px; font-weight: 600; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.35); }
.jump-bar .jump-present { background: none; border: 0; color: #fff; font-weight: 600; padding: 4px 8px; border-radius: 4px; }
.jump-bar .jump-present:hover { background: rgba(255, 255, 255, 0.15); }
a.app-link { display: inline-flex; align-items: center; gap: 2px; padding: 0 3px; border-radius: 3px; background: var(--mention-bg); color: var(--mention-text); font-weight: 500; text-decoration: none; vertical-align: baseline; }
a.app-link:hover { background: var(--accent); color: #fff; }
.app-link .app-link-sep { opacity: 0.8; margin: 0 1px; }
@media (prefers-reduced-motion: reduce) {
  .message.jump-flash { animation: none; background: rgba(91, 108, 240, 0.2); }
}

/* ---- mentions and read states (client/js/mentions.js, client/js/readState.js) ---- */
.content .mention.clickable { cursor: pointer; }
.content .mention.clickable:hover, .content .mention.clickable:focus-visible { background: var(--accent); color: #fff; outline: none; }
.content .mention.channel-mention { display: inline-flex; align-items: center; gap: 1px; vertical-align: baseline; }
.content .mention.channel-mention .icon { flex: none; }
.content .mention.channel-mention.unknown { background: var(--overlay-subtle); color: var(--text-muted); }
.content .mention.everyone-mention { cursor: default; }
.mention-autocomplete .mention-ac-item .avatar { width: 24px; height: 24px; font-size: 12px; }
.mention-autocomplete .mention-ac-item > .icon { width: 24px; flex: none; color: var(--text-muted); }
.mention-ac-at { width: 24px; height: 24px; border-radius: 50%; display: grid; place-items: center; flex: none; background: var(--bg-active); color: var(--text-strong); font-weight: 700; }
.mention-autocomplete .mention-ac-item .muted.small { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 55%; }
.new-messages-divider { display: flex; align-items: center; margin: 12px 16px 4px; height: 0; border-top: 1px solid var(--danger); position: relative; }
.new-messages-divider span { position: absolute; right: 0; top: -9px; background: var(--danger); color: #fff; font-size: 10px; font-weight: 700; line-height: 16px; padding: 0 6px; border-radius: 0 3px 3px 0; text-transform: uppercase; letter-spacing: 0.02em; }
.new-messages-divider + .message.group-start { margin-top: 8px; }
.unread-bar { position: sticky; top: 0; z-index: 3; display: flex; align-items: stretch; margin: 0 16px; background: var(--accent); color: #fff; border-radius: 0 0 8px 8px; font-size: 13px; font-weight: 600; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); overflow: hidden; }
.unread-bar button { background: none; border: 0; color: #fff; font-weight: 600; padding: 6px 12px; }
.unread-bar .unread-bar-jump { flex: 1; text-align: left; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.unread-bar button:hover, .unread-bar button:focus-visible { background: rgba(255, 255, 255, 0.15); outline: none; }
.channel-mention-badge, .guild-mention-badge { min-width: 16px; height: 16px; padding: 0 4px; border-radius: 8px; background: var(--danger); color: #fff; font-size: 11px; font-weight: 700; line-height: 16px; text-align: center; }
.channel .channel-mention-badge { margin-left: auto; flex: none; }
.guild-icon .guild-mention-badge { position: absolute; right: -4px; bottom: -4px; min-width: 20px; height: 20px; line-height: 20px; border-radius: 10px; font-size: 12px; box-shadow: 0 0 0 3px var(--bg-rail, #1e1f22); pointer-events: none; }

/* --- replies (client/js/replies.js) --- */
.reply-preview { grid-column: 1 / -1; position: relative; display: flex; align-items: center; gap: 4px; min-width: 0; margin: 0 0 2px 56px; font-size: 13px; line-height: 1.2; color: var(--text-muted); cursor: pointer; }
/* The spine from the avatar up to the preview. */
.reply-preview::before { content: ''; position: absolute; left: -36px; top: 50%; width: 30px; height: 10px; border-left: 2px solid var(--bg-active); border-top: 2px solid var(--bg-active); border-top-left-radius: 6px; box-sizing: border-box; }
.reply-preview .reply-preview-avatar { width: 16px; height: 16px; font-size: 8px; }
.reply-preview .reply-preview-avatar .status { display: none; }
.reply-preview-name { flex: none; font-weight: 600; color: var(--text-strong); opacity: 0.9; white-space: nowrap; }
.reply-preview-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.reply-preview-text.attachment { font-style: italic; display: inline-flex; align-items: center; gap: 4px; }
.reply-preview:hover .reply-preview-text, .reply-preview:focus-visible .reply-preview-text { color: var(--text); }
.reply-preview:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; border-radius: 3px; }
.reply-preview.deleted { cursor: default; font-style: italic; }
.reply-preview-icon { display: grid; place-items: center; width: 16px; height: 16px; border-radius: 50%; background: var(--bg-active); flex: none; }
.message .actions button.reply-action { display: grid; place-items: center; padding: 4px 6px; }
.reply-bar { display: flex; align-items: center; gap: 8px; padding: 6px 8px 6px 16px; background: var(--bg-sidebar); border-radius: var(--radius) var(--radius) 0 0; font-size: 13px; color: var(--text-muted); min-width: 0; }
.reply-bar-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.reply-bar-name { color: var(--text); }
.reply-bar-controls { display: flex; align-items: center; gap: 4px; flex: none; }
.reply-mention-toggle { background: none; border: 0; padding: 2px 6px; border-radius: 4px; font-weight: 700; font-size: 13px; color: var(--text-muted); cursor: pointer; }
.reply-mention-toggle span { margin-left: 2px; }
.reply-mention-toggle.on { color: var(--link); }
.reply-mention-toggle:hover { background: var(--bg-hover); }
.reply-bar-close { background: none; border: 0; padding: 2px; border-radius: 50%; color: var(--text-muted); display: grid; place-items: center; cursor: pointer; }
.reply-bar-close:hover { color: var(--text); background: var(--bg-hover); }
.composer-wrap.replying .reply-bar + .pending-uploads:not([hidden]) { border-radius: 0; }
.composer-wrap.replying .reply-bar ~ .composer { border-top-left-radius: 0; border-top-right-radius: 0; }

/* --- pins (client/js/pins.js) --- */
.chat-header .pins-button { margin-left: auto; display: grid; place-items: center; }
.chat-header .voice-chat-toggle ~ .pins-button { margin-left: 0; }
.chat-header .pins-button:hover .icon { color: var(--text); }
.pins-popout { width: min(420px, calc(100vw - 32px)); max-height: min(70vh, 640px); max-height: min(70dvh, 640px); display: flex; flex-direction: column; background: var(--bg-sidebar); border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; }
.pins-header { display: flex; align-items: center; gap: 8px; padding: 12px 16px; background: var(--bg-rail); color: var(--text-strong); flex: none; }
.pins-header h3 { margin: 0; font-size: 16px; }
.pins-list { overflow-y: auto; padding: 8px; display: flex; flex-direction: column; gap: 8px; }
.pins-list.pins-empty { align-items: center; text-align: center; padding: 24px 24px 28px; color: var(--text-muted); gap: 4px; }
.pins-list.pins-empty > .icon { color: var(--text-muted); opacity: 0.6; margin-bottom: 8px; }
.pins-list.pins-empty p { margin: 4px 0; }
.pin-item { position: relative; display: flex; gap: 12px; align-items: flex-start; padding: 10px 12px; background: var(--bg-chat); border: 1px solid var(--border); border-radius: 6px; }
.pin-body { flex: 1; min-width: 0; }
.pin-meta { display: flex; align-items: baseline; gap: 8px; }
.pin-meta .author { font-weight: 600; color: var(--text-strong); }
.pin-body .content { white-space: pre-wrap; overflow-wrap: anywhere; line-height: 1.375; max-height: 12em; overflow: hidden; }
.pin-attachments { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 4px; }
.pin-thumb { max-width: 160px; max-height: 120px; border-radius: 4px; object-fit: cover; }
.pin-file { display: inline-flex; align-items: center; gap: 4px; font-size: 13px; color: var(--text-muted); }
.pin-controls { position: absolute; right: 8px; top: 8px; display: none; gap: 4px; }
.pin-item:hover .pin-controls, .pin-item:focus-within .pin-controls { display: flex; }
.pin-jump { padding: 2px 8px; font-size: 12px; border-radius: 4px; background: var(--bg-active); color: var(--text); border: 0; }
.pin-jump:hover { background: var(--accent); color: #fff; }
.pin-unpin { background: var(--bg-active); border: 0; border-radius: 50%; width: 22px; height: 22px; display: grid; place-items: center; color: var(--text-muted); padding: 0; }
.pin-unpin:hover { color: var(--danger); }
.pins-footer { padding: 8px 16px; border-top: 1px solid var(--border); flex: none; }
.pin-confirm-preview { display: flex; gap: 12px; padding: 10px 12px; margin: 8px 0; background: var(--bg-chat); border: 1px solid var(--border); border-radius: 6px; max-height: 40vh; max-height: 40dvh; overflow: hidden; }
.pin-confirm-tip { margin-top: 4px; }
/* The "<name> pinned a message to this channel." line. */
.message.system-message { align-items: center; color: var(--text-muted); }
.message.system-message .system-icon { justify-content: center; padding-right: 16px; color: var(--text-muted); }
.message.system-message .system-body { line-height: 1.375; overflow-wrap: anywhere; }
.message.system-message .author { font-weight: 600; color: var(--text-strong); }
.message.system-message .author:hover { text-decoration: underline; }
.system-link { background: none; border: 0; padding: 0; font: inherit; font-weight: 600; color: var(--text-strong); cursor: pointer; }
.system-link:hover, .system-link:focus-visible { text-decoration: underline; }
.system-time { margin-left: 8px; font-size: 12px; color: var(--text-muted); }
.message.reply-target { background: rgba(91, 108, 240, 0.1); box-shadow: inset 2px 0 0 var(--accent); }

/* DM calls (client/js/dmCalls.js): header buttons, the call above a DM's messages, the incoming call card, call messages */
.chat-header .dm-call-buttons { margin-left: auto; display: flex; align-items: center; gap: 4px; }
.chat-header .dm-call-buttons ~ .pins-button { margin-left: 0; }
.chat-header .dm-call-button { display: grid; place-items: center; }
.chat-header .dm-call-button .icon { color: var(--text-muted); }
.chat-header .dm-call-button:hover .icon { color: var(--text); }
.dm-join-call { display: inline-flex; align-items: center; gap: 6px; background: var(--online); color: #fff; border: 0; border-radius: 4px; padding: 6px 12px; font-weight: 600; }
.dm-join-call:hover { filter: brightness(1.1); }
.dm-join-call .icon { color: #fff; }
.chat.dm-call > .chat-header { order: -2; }
.chat.dm-call > .call-view { order: -1; flex: none; height: clamp(240px, 45%, 520px); border-bottom: 1px solid var(--border); }
.incoming-call { position: fixed; top: 72px; left: 50%; transform: translateX(-50%); z-index: 60; width: 248px; padding: 24px 16px 20px; border-radius: var(--radius); background: var(--bg-rail); box-shadow: 0 8px 32px rgba(0, 0, 0, 0.55); display: flex; flex-direction: column; align-items: center; gap: 6px; text-align: center; }
.incoming-call-ring { border-radius: 50%; padding: 6px; margin-bottom: 8px; animation: incoming-call-pulse 1.3s ease-out infinite; }
.incoming-call .incoming-call-avatar { width: 80px; height: 80px; font-size: 32px; }
.incoming-call-name { font-size: 18px; font-weight: 700; color: var(--text-strong); max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.incoming-call-status { font-size: 14px; }
.incoming-call-actions { display: flex; gap: 16px; margin-top: 16px; }
.incoming-call-button { width: 48px; height: 48px; border-radius: 50%; border: 0; display: grid; place-items: center; color: var(--text-strong); background: var(--bg-active); }
.incoming-call-button:hover { filter: brightness(1.15); }
.incoming-call-button.decline { color: #fff; background: var(--danger); }
.incoming-call-button.accept { color: #fff; background: var(--online); }
@keyframes incoming-call-pulse {
  0% { box-shadow: 0 0 0 0 rgba(59, 165, 93, 0.6); }
  100% { box-shadow: 0 0 0 18px rgba(59, 165, 93, 0); }
}
@media (prefers-reduced-motion: reduce) {
  .incoming-call-ring { animation: none; box-shadow: 0 0 0 4px rgba(59, 165, 93, 0.6); }
}
.message.call-message .system-icon { color: var(--online); }
.message.call-message.missed .system-icon { color: var(--danger); }
.call-join-link { color: var(--online); }
/* Password reset (client/js/passwordReset.js) */
.auth-card .auth-forgot { align-self: flex-start; margin-top: -6px; color: var(--link); font-size: 13px; }
.reset-modal .reset-form { display: flex; flex-direction: column; gap: 12px; }
.reset-modal h2, .reset-modal p { margin: 0; }
.reset-modal .reset-subtitle { margin: 4px 0 0; font-size: 16px; color: var(--text-strong); }
