/* AUTO-GENERATED by tools/build_css_bundle.py — do not edit by hand. */
/* Source files: 70 */
@import url("https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;500;600;700&family=IBM+Plex+Mono:wght@400;500&family=Press+Start+2P&display=swap");

/* === base.css === */

/* === core/tokens.css === */
/* ==========================================================
   Structural tokens. Palette lives in themes/bobrovaya-*.css.
   ========================================================== */

:root {
  /* Шрифты */
  --font-sans: "IBM Plex Sans", "Segoe UI", system-ui, sans-serif;
  --font-mono: "IBM Plex Mono", "JetBrains Mono", "Consolas", "Courier New", monospace;

  /* Spacing scale (4px base) */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;

  /* Type scale */
  --text-xs: 11px;
  --text-sm: 13px;
  --text-md: 15px;
  --text-lg: 17px;
  --text-xl: 22px;

  /* Radius scale — flat geometry (никаких 10/14/18/20/22) */
  --radius-sm: 4px;
  --radius-md: 8px;
  --radius-lg: 12px;
  --radius-pill: 999px;
  --radius: 16px; /* legacy alias used by .form-card etc. */

  /* Special — для пузырей и чат-айтемов */
  --radius-bubble: 18px;
  --radius-bubble-tight: 6px; /* angle on the joining side for grouped/last bubbles */
  --radius-chat-item: 2px;

  /* Hard cap для медиа в чате */
  --cap-img-w: 420px;
  --cap-img-h: 480px;

  /* Right-docked profile/group side panel (Tier 2) — 4th grid lane width. */
  --side-panel-width: 480px;

  /* Default avatar (бобёр) — fallback вместо букв-инициалов */
  --avatar-default: url("/static/icons/beaver.png");

  /* Z-index scale */
  --z-base: 1;
  --z-message-meta: 1;
  --z-message-actions: 10;
  --z-dropdown: 100;
  --z-fab: 200;
  --z-peek: 700;
  --z-lightbox: 800;
  --z-modal: 1000;
  --z-toast: 2000;
  --z-titlebar: 3000;

  --keyboard-offset: 0px;
}

body.is-tauri {
  --glass-bg: color-mix(in srgb, var(--panel) 78%, transparent);
  --glass-stroke: color-mix(in srgb, var(--stroke) 82%, transparent);
  --glass-blur: blur(12px) saturate(1.15);
  --glass-shadow: 0 6px 18px rgba(0, 0, 0, 0.18), 0 1px 3px rgba(0, 0, 0, 0.08);
}

/* === core/foundation.css === */
* {
  box-sizing: border-box;
  -webkit-tap-highlight-color: transparent;
}

*:focus-visible {
  outline: 2px solid color-mix(in srgb, var(--accent) 70%, transparent);
  outline-offset: 2px;
}

html,
body {
  height: 100%;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
}

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

.message-text,
.message-sender,
.forward-author,
.profile-name,
.profile-bio-text,
.profile-handle {
  user-select: text;
  -webkit-user-select: text;
}

.chat-item,
.chat-item *,
.user-menu-trigger,
.user-menu-trigger *,
.title-bar,
.title-bar * {
  user-select: none;
  -webkit-user-select: none;
}

body {
  margin: 0;
  min-height: 100vh;
  height: 100dvh;
  min-height: 100svh;
  font-family: "IBM Plex Sans", "Segoe UI", sans-serif;
  color: var(--text);
  background-color: var(--bg);
  background-image: none;
  overflow: hidden;
  transition:
    background 0.15s ease-out,
    color 0.15s ease-out,
    background-color 0.15s ease-out;
}

button,
input,
textarea,
select,
.form-card,
.sidebar,
.header {
  transition:
    background-color 0.15s ease-out,
    border-color 0.15s ease-out,
    color 0.15s ease-out,
    box-shadow 0.15s ease-out;
}

.modal-card {
  transition-property: background-color, border-color, color, box-shadow, height;
  transition-duration: 0.15s, 0.15s, 0.15s, 0.15s, var(--anim-slow, 0.3s);
  transition-timing-function: ease-out, ease-out, ease-out, ease-out, var(--ease-smooth, ease);
}

:root[data-mode="light"] body {
  background-color: var(--bg);
  background-image: none;
}

@media (prefers-color-scheme: light) {
  :root:not([data-mode]) body {
    background-color: var(--bg);
    background-image: none;
  }
}

body::before,
body::after {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  opacity: 0;
}

/* Removed vignette gradient */
body::after {
  display: none;
}

:root[data-mode="light"] body::after {
  display: none;
}

@media (prefers-color-scheme: light) {
  :root:not([data-mode]) body::after {
    display: none;
  }
}

a {
  color: var(--link);
  text-decoration: none;
}

a:hover {
  color: var(--accent);
}

/* === core/auth.css === */
.shell {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 48px var(--space-6);
}

.form-card {
  width: min(460px, 100%);
  background-color: var(--panel);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  border: 1px solid var(--stroke);
  padding: 40px;
}

.brand-header {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin-bottom: 32px;
  text-align: center;
}

.brand-logo {
  width: 80px;
  height: 80px;
  margin-bottom: var(--space-4);
  filter: drop-shadow(0 8px 20px rgba(0, 0, 0, 0.3));
}

.brand-title {
  font-size: 32px;
  font-weight: 800;
  color: var(--text);
  letter-spacing: -0.02em;
  margin: 0;
}

.auth-tabs {
  display: flex;
  background: var(--panel-2);
  padding: var(--space-1);
  border-radius: 12px;
  margin-bottom: var(--space-6);
  position: relative;
  border: 1px solid var(--stroke);
}

.download-shell {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 48px var(--space-6);
  background: radial-gradient(
    circle at center,
    color-mix(in srgb, var(--accent) 5%, transparent),
    var(--bg)
  );
  position: relative;
}

.download-card {
  position: relative;
  z-index: 2;
  width: min(460px, 100%);
  background-color: var(--panel);
  border-radius: var(--radius);
  border: 1px solid var(--stroke);
  box-shadow:
    var(--shadow),
    0 0 60px color-mix(in srgb, var(--accent) 12%, transparent);
  padding: 40px;
  text-align: center;
}

.download-logo {
  width: 96px;
  height: 96px;
  margin: 0 auto var(--space-4);
  filter: drop-shadow(0 8px 20px rgba(0, 0, 0, 0.25));
}

.download-title {
  font-family: "IBM Plex Sans", system-ui, sans-serif;
  font-size: 28px;
  font-weight: 800;
  letter-spacing: -0.02em;
  color: var(--text);
  margin: 0 0 var(--space-5);
}

.download-lede {
  color: var(--text);
  margin: 0 0 var(--space-2);
  font-size: 15px;
  line-height: 1.5;
}

.download-sub {
  margin: 0 0 var(--space-6);
  font-size: 13px;
}

.download-cta {
  width: 100%;
  text-decoration: none;
}

.download-cta .icon {
  width: 18px;
  height: 18px;
}

.download-alt {
  display: flex;
  gap: var(--space-4);
  justify-content: center;
  flex-wrap: wrap;
  margin-top: var(--space-5);
}

.download-alt-link {
  color: var(--muted);
  font-size: 13px;
  text-decoration: none;
  transition: color 0.12s ease-out;
}

.download-alt-link:hover {
  color: var(--accent);
}

.auth-tab {
  flex: 1;
  padding: 10px;
  text-align: center;
  font-size: 14px;
  font-weight: 600;
  color: var(--muted);
  cursor: pointer;
  z-index: 2;
  transition:
    color 0.3s ease,
    text-shadow 0.3s ease;
}

.auth-tab:not(.active):hover {
  color: var(--text);
  text-shadow: 0 0 10px color-mix(in srgb, var(--accent) 40%, transparent);
}

.auth-tab.active {
  color: var(--accent-contrast);
}

.auth-slider {
  position: absolute;
  top: 4px;
  left: 4px;
  width: calc(50% - 4px);
  height: calc(100% - 8px);
  background-color: var(--panel-2);
  border-radius: 9px;
  z-index: 1;
  transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.auth-tabs[data-active="register"] .auth-slider {
  transform: translateX(100%);
}

/* Validation Island */
.validation-island {
  position: absolute;
  background: var(--panel-2);
  border: 1px solid var(--danger);
  padding: 8px 12px;
  border-radius: 10px;
  font-size: 12px;
  color: var(--danger);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2);
  z-index: 100;
  pointer-events: none;
  opacity: 0;
  transform: translateY(10px);
  transition:
    opacity 0.2s,
    transform 0.2s;
  max-width: 240px;
}

.validation-island.is-visible {
  opacity: 1;
  transform: translateY(0);
}

.input-invalid {
  border-color: var(--danger) !important;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--danger) 20%, transparent) !important;
}

.field-inline-error {
  margin-top: 6px;
  font-size: 12px;
  color: var(--danger);
  line-height: 1.25;
  letter-spacing: 0.01em;
}

.auth-form-container {
  position: relative;
}

.auth-form-container > div {
  transition:
    opacity 0.3s ease,
    transform 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}

.auth-form-container > div[hidden] {
  display: block !important;
  opacity: 0;
  transform: translateY(10px);
  pointer-events: none;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
}

.auth-nav-ready .form-card,
.auth-nav-ready .reset-card {
  transition:
    opacity 0.2s ease,
    transform 0.2s ease,
    filter 0.2s ease;
}

.auth-nav-leaving .form-card,
.auth-nav-leaving .reset-card {
  opacity: 0;
  transform: translateY(10px) scale(0.99);
  filter: blur(2px);
}

@supports (view-transition-name: auth-card) {
  .form-card,
  .reset-card {
    view-transition-name: auth-card;
  }

  ::view-transition-old(auth-card),
  ::view-transition-new(auth-card) {
    animation-duration: 220ms;
    animation-timing-function: cubic-bezier(0.2, 0.65, 0.3, 1);
  }
}

@media (prefers-reduced-motion: reduce) {
  .auth-nav-ready .form-card,
  .auth-nav-ready .reset-card {
    transition: none;
  }

  .auth-nav-leaving .form-card,
  .auth-nav-leaving .reset-card {
    opacity: 1;
    transform: none;
    filter: none;
  }
}

.form-card h1 {
  margin: 0 0 var(--space-6);
  font-weight: 600;
  font-size: 20px;
  color: var(--text);
  text-align: center;
  position: relative;
}

.form-card h1::after {
  content: "";
  position: absolute;
  bottom: -8px;
  left: 50%;
  transform: translateX(-50%);
  width: 40px;
  height: 2px;
  background: var(--accent);
  border-radius: 2px;
  opacity: 0.6;
}

.form-card label {
  display: block;
  margin-bottom: 6px;
  font-size: var(--text-sm);
  color: var(--muted);
}

.form-card input {
  width: 100%;
  padding: 12px 14px;
  border-radius: 12px;
  border: 1px solid transparent;
  background: var(--panel-2);
  color: var(--text);
  font-size: var(--text-md);
  margin-bottom: 18px;
}

.form-card input:focus {
  outline: none;
  border-color: color-mix(in srgb, var(--accent) 50%, transparent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 20%, transparent);
}

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: 100%;
  padding: var(--space-3) var(--space-4);
  border-radius: 12px;
  border: none;
  cursor: pointer;
  font-weight: 600;
  font-size: var(--text-md);
  color: var(--accent-contrast);
  background-color: var(--accent);
  transition:
    transform 0.15s ease-out,
    background-color 0.15s ease-out,
    box-shadow 0.15s ease-out;
  position: relative;
  overflow: hidden;
}

.button:hover {
  background-color: color-mix(in srgb, var(--accent) 85%, #000);
}

.button:active {
  transform: scale(0.98);
}

.button.secondary {
  background: var(--panel-2);
  color: var(--text);
  border: 1px solid var(--stroke);
}

.button.secondary:hover {
  background: color-mix(in srgb, var(--panel-2) 90%, var(--text) 10%);
}

.inline-link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: var(--muted);
  font-size: 14px;
  margin-top: 14px;
}

.forgot-password-link {
  display: inline-block;
  color: var(--link);
  font-size: 13px;
  padding: 0 0 2px;
  margin: -8px 0 14px;
  text-align: left;
  text-decoration: none;
}

.forgot-password-link:hover {
  color: var(--accent);
  text-decoration: underline;
}

.recovery-flow {
  margin-top: 0;
  padding: 14px;
  border-radius: 14px;
  border: 1px solid var(--stroke);
  background: color-mix(in srgb, var(--panel-2) 80%, transparent);
  animation: slideDownFadeLogin 0.25s ease;
}

.reset-card {
  width: min(700px, 100%);
  max-height: min(88dvh, 860px);
  display: flex;
  flex-direction: column;
  padding: 22px 22px 22px;
  border-radius: 20px;
  background-color: var(--panel);
  border: 1px solid var(--stroke);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
}

.reset-shell {
  align-items: center;
  justify-content: center;
  padding: 20px 16px;
}

.reset-shell .brand-header {
  margin-bottom: 12px;
}

.reset-shell .brand-logo {
  width: 58px;
  height: 58px;
  margin-bottom: 6px;
}

.reset-shell .brand-title {
  font-size: 32px;
  letter-spacing: -0.02em;
}

.reset-scroll {
  overflow-y: auto;
  overflow-x: hidden;
  padding-right: 4px;
  margin-right: -4px;
  min-height: 0;
}

.recovery-flow.is-standalone {
  margin: 0 auto;
  width: min(640px, 100%);
  padding: 16px 14px 20px;
  border-radius: 16px;
  border: 1px solid var(--stroke);
  background-color: var(--panel-2);
  animation: none;
}

@keyframes slideDownFadeLogin {
  from {
    opacity: 0;
    transform: translateY(-8px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.recovery-flow h2 {
  margin: 2px 0 8px;
  font-size: 20px;
  line-height: 1.25;
  font-weight: 600;
  letter-spacing: -0.02em;
  text-align: center;
}

.recovery-flow p {
  margin: 0 0 12px;
  text-align: center;
  font-size: 13px;
}

.recovery-flow form + form {
  margin-top: 10px;
}

.recovery-flow label[for="recovery-username"] {
  display: block;
  margin-bottom: 6px;
  font-size: 13px;
  color: var(--muted);
}

#recovery-username {
  margin-bottom: 0;
}

.recovery-words-inputs {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 8px;
  margin-top: 9px;
}

.recovery-word-field {
  position: relative;
  display: block;
  margin: 0;
}

.recovery-word-number {
  position: absolute;
  z-index: 1;
  left: 11px;
  top: 50%;
  transform: translateY(-50%);
  font-size: 16px;
  font-weight: 500;
  color: color-mix(in srgb, var(--muted) 72%, var(--text) 28%);
  font-family: "IBM Plex Mono", monospace;
  letter-spacing: 0;
  pointer-events: none;
  transition:
    opacity 0.18s ease,
    transform 0.18s ease;
}

.recovery-word-number::after {
  content: "\2014";
  margin-left: 6px;
  color: color-mix(in srgb, var(--muted) 70%, transparent);
}

.recovery-word-field.has-value .recovery-word-number {
  opacity: 0;
  transform: translateY(-50%) scale(0.92);
}

.recovery-word-field input {
  margin-bottom: 0;
  font-family: "IBM Plex Mono", monospace;
  font-size: 15px;
  padding: 10px 12px 10px 42px;
  min-height: 44px;
  border-radius: 12px;
  border: 1px solid var(--stroke);
  background-color: var(--panel);
  color: var(--text);
}

.recovery-word-field .field-inline-error {
  margin-top: 4px;
  font-size: 11px;
  padding-left: 4px;
}

.recovery-flow #recovery-verify-btn,
.recovery-flow #recovery-reset-btn {
  display: block;
  width: min(340px, 100%);
  margin: 12px auto 0;
}

.recovery-flow .inline-link {
  justify-content: center;
  width: 100%;
  margin-top: 14px;
}

.recovery-flow #recovery-status {
  margin-top: 10px;
  min-height: 20px;
  text-align: center;
}

#recovery-reset-form label {
  display: block;
  margin-bottom: 6px;
  font-size: 13px;
  color: var(--muted);
}

.mt-3 {
  margin-top: 12px;
}

@media (max-width: 640px) {
  .reset-card {
    max-height: calc(100dvh - 12px);
    padding: 16px 12px 16px;
    width: min(760px, calc(100% - 6px));
  }

  .reset-shell {
    padding: 8px 6px;
  }

  .reset-shell .brand-header {
    margin-bottom: 10px;
  }

  .reset-shell .brand-logo {
    width: 50px;
    height: 50px;
    margin-bottom: 4px;
  }

  .reset-shell .brand-title {
    font-size: 30px;
  }

  .recovery-flow.is-standalone {
    padding: 12px 10px 16px;
  }

  .recovery-flow h2 {
    font-size: 18px;
    margin-bottom: 6px;
  }

  .recovery-flow p {
    margin-bottom: 12px;
    font-size: 12px;
  }

  .recovery-words-inputs {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 8px;
  }

  .recovery-word-number {
    left: 10px;
    font-size: 14px;
  }

  .recovery-word-number::after {
    margin-left: 6px;
  }

  .recovery-word-field input {
    padding-left: 38px;
    min-height: 42px;
    font-size: 14px;
  }
}

@media (max-width: 420px) {
  .recovery-words-inputs {
    grid-template-columns: 1fr;
  }
}

.error {
  padding: 10px 12px;
  background: color-mix(in srgb, var(--danger) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--danger) 35%, transparent);
  border-radius: 12px;
  margin-bottom: 16px;
  color: var(--danger);
  font-size: 14px;
}

/* === core/login-redesign.css === */
/* ==========================================================
   Login redesign — split-hero layout (v2).
   Scoped under .login-shell-v2 so the legacy auth.css styles
   keep working for reset / csrf_error / download pages.
   ========================================================== */

.login-shell-v2 {
  /* Override the legacy .shell rule which sets flex+padding for the
     classic single-card login. The redesign owns its own layout. */
  min-height: 100dvh;
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  align-items: stretch;
  justify-content: stretch;
  padding: 0;
  background: var(--bg);
  color: var(--text);
  position: relative;
  overflow: hidden;
}

/* === LEFT: hero =========================================== */
.login-shell-v2 .login-hero {
  position: relative;
  padding: clamp(28px, 4vw, 64px);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: clamp(18px, 2vw, 28px);
  isolation: isolate;
  background: linear-gradient(
    135deg,
    color-mix(in srgb, var(--bg) 100%, transparent) 0%,
    color-mix(in srgb, var(--bg-2) 88%, var(--bg) 12%) 100%
  );
}

/* Beaver-tile background — PNG used as a mask so the fill color follows
   the active theme. background-color paints the visible color, the PNG
   alpha-channel cuts the silhouette. Tilted ~-12deg with overscale to
   avoid bald corners when rotated.
   Two mask layers are intersected: the beaver tile (carves silhouettes)
   AND a horizontal gradient (fades out toward the right so the pattern
   doesn't end with a hard edge against the form column). */
.login-shell-v2 .login-hero-pattern {
  position: absolute;
  inset: -20%;
  z-index: -1;
  pointer-events: none;
  background-color: var(--accent);
  opacity: 0.05;
  -webkit-mask-image:
    url("/static/icons/beaver_google_512.png"),
    linear-gradient(to right, #000 0%, #000 55%, transparent 95%);
  -webkit-mask-repeat: repeat, no-repeat;
  -webkit-mask-size:
    110px 110px,
    100% 100%;
  -webkit-mask-position:
    0 0,
    0 0;
  -webkit-mask-composite: source-in;
  mask-image:
    url("/static/icons/beaver_google_512.png"),
    linear-gradient(to right, #000 0%, #000 55%, transparent 95%);
  mask-repeat: repeat, no-repeat;
  mask-size:
    110px 110px,
    100% 100%;
  mask-position:
    0 0,
    0 0;
  mask-composite: intersect;
  transform: rotate(-12deg);
  transform-origin: center;
  /* Slow current: drift the beaver tile layer by exactly one tile so the
     repeat loops seamlessly. Only the tile layer moves — the fade gradient
     (2nd mask layer) stays pinned at 0 0. */
  animation: login-hero-river 18s linear infinite;
}

/* Beaver tile is 110px; vertical shift is also one tile so both axes loop
   without a seam. The -12deg rotation turns this into a gentle down-stream
   diagonal — beavers paddling along like a river. */
@keyframes login-hero-river {
  to {
    -webkit-mask-position: -110px 110px, 0 0;
    mask-position: -110px 110px, 0 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .login-shell-v2 .login-hero-pattern {
    animation: none;
  }
}

:root[data-mode="dark"] .login-shell-v2 .login-hero-pattern {
  opacity: 0.07;
}

.login-shell-v2 .login-hero-brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  color: var(--text);
  align-self: flex-start;
  border-radius: var(--radius-sm);
  padding: 4px 6px;
  margin-left: -6px;
  transition: transform var(--anim-fast, 0.15s) ease-out;
}

.login-shell-v2 .login-hero-brand:hover .login-hero-brand-img {
  transform: rotate(-6deg) scale(1.06);
}

.login-shell-v2 .login-hero-brand-img {
  width: 36px;
  height: 36px;
  object-fit: contain;
  user-select: none;
  -webkit-user-drag: none;
  transition: transform var(--anim-fast, 0.15s) ease-out;
}

.login-shell-v2 .login-hero-brand-text {
  font-weight: 700;
  font-size: 22px;
  letter-spacing: -0.02em;
  line-height: 1;
}

.login-shell-v2 .login-hero-slogan {
  margin: 0;
  font-weight: 700;
  font-size: clamp(44px, 6.4vw, 88px);
  line-height: 1.02;
  letter-spacing: -0.035em;
  color: var(--text);
  display: flex;
  flex-direction: column;
  gap: 0;
}

.login-shell-v2 .login-hero-slogan em {
  color: var(--accent);
  font-style: normal;
}

/* Clock-flip rotator. Viewport clips vertically, mask fades the top and
   bottom edges so phrases blur out softly as they enter/leave.
   Phrases are absolutely stacked — only one is .is-active at a time. */
.login-shell-v2 .login-hero-slogan-rotate {
  position: relative;
  display: block;
  height: 1.02em;
  overflow: hidden;
  /* Slight horizontal padding so descender-bearing letters (д, у, р) don't
     get clipped by the mask edges in some fonts. */
  padding-bottom: 0.12em;
  mask-image: linear-gradient(to bottom, transparent 0%, #000 22%, #000 78%, transparent 100%);
  -webkit-mask-image: linear-gradient(
    to bottom,
    transparent 0%,
    #000 22%,
    #000 78%,
    transparent 100%
  );
}

.login-shell-v2 .login-hero-slogan-phrase {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  display: block;
  opacity: 0;
  transform: translateY(110%);
  filter: blur(6px);
  transition:
    transform 0.7s cubic-bezier(0.22, 1.18, 0.36, 1),
    opacity 0.55s ease-out,
    filter 0.6s ease-out;
  will-change: transform, opacity, filter;
}

.login-shell-v2 .login-hero-slogan-phrase.is-active {
  opacity: 1;
  transform: translateY(0);
  filter: blur(0);
}

.login-shell-v2 .login-hero-slogan-phrase.is-leaving {
  opacity: 0;
  transform: translateY(-110%);
  filter: blur(6px);
  /* Outgoing phrase uses standard ease (no overshoot) so it doesn't
     "snap back" as it exits. */
  transition:
    transform 0.65s cubic-bezier(0.4, 0, 0.2, 1),
    opacity 0.5s ease-in,
    filter 0.55s ease-in;
}

/* === RIGHT: form zone ===================================== */
.login-shell-v2 .login-form-zone {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: clamp(28px, 4vw, 56px);
  background: linear-gradient(
    135deg,
    color-mix(in srgb, var(--bg-2) 60%, var(--bg) 40%) 0%,
    var(--bg-2) 100%
  );
}

.login-shell-v2 .form-card-v2 {
  width: min(420px, 100%);
  padding: 0;
  border: none;
  background: transparent;
  box-shadow: none;
}

.login-shell-v2 .form-card-v2 h1 {
  display: none;
}

.login-shell-v2 .auth-tabs {
  background: var(--panel);
  padding: 6px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--stroke);
  margin-bottom: clamp(20px, 2.4vw, 32px);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.03);
}

.login-shell-v2 .auth-tab {
  padding: 11px 16px;
  font-size: 15px;
  font-weight: 600;
}

.login-shell-v2 .auth-tab.active {
  color: var(--text);
  text-shadow: none;
}

.login-shell-v2 .auth-slider {
  background: var(--bg);
  border-radius: var(--radius-pill);
  box-shadow:
    0 1px 3px rgba(42, 34, 24, 0.1),
    0 1px 2px rgba(42, 34, 24, 0.06);
  top: 6px;
  left: 6px;
  width: calc(50% - 6px);
  height: calc(100% - 12px);
}

.login-shell-v2 .form-card-v2 label {
  font-size: 14px;
  font-weight: 500;
  color: var(--muted);
  margin-bottom: 8px;
  margin-left: 2px;
}

.login-shell-v2 .form-card-v2 input[type="text"],
.login-shell-v2 .form-card-v2 input[type="password"] {
  padding: 14px 18px;
  border-radius: var(--radius-pill);
  background: var(--panel);
  border: 1px solid var(--stroke);
  font-size: 15px;
  margin-bottom: 18px;
  transition:
    border-color 0.15s ease,
    box-shadow 0.15s ease,
    background 0.15s ease;
}

.login-shell-v2 .form-card-v2 input:focus {
  background: var(--panel);
  border-color: color-mix(in srgb, var(--accent) 55%, transparent);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 14%, transparent);
}

.login-shell-v2 .forgot-password-link {
  display: block;
  text-align: right;
  margin: -8px 4px 18px 0;
  font-size: 13px;
}

.login-shell-v2 .form-card-v2 .button {
  padding: 16px 20px;
  border-radius: var(--radius-pill);
  font-size: 16px;
  font-weight: 600;
  letter-spacing: -0.005em;
  background: var(--accent);
  color: var(--accent-contrast);
  box-shadow: 0 4px 14px color-mix(in srgb, var(--accent) 28%, transparent);
}

.login-shell-v2 .form-card-v2 .button:hover {
  background: color-mix(in srgb, var(--accent) 88%, #000);
  box-shadow: 0 6px 18px color-mix(in srgb, var(--accent) 34%, transparent);
}

.login-shell-v2 .button-arrow {
  display: inline-block;
  margin-left: 2px;
  transition: transform 0.18s ease-out;
}

.login-shell-v2 .form-card-v2 .button:hover .button-arrow {
  transform: translateX(3px);
}

.login-shell-v2 .button-ghost.passkey-cta {
  display: block;
  width: 100%;
  margin: 14px 0 0;
  padding: 8px 12px;
  background: transparent;
  border: none;
  color: var(--muted);
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  text-align: center;
  font-family: inherit;
  transition: color 0.15s ease;
}

.login-shell-v2 .button-ghost.passkey-cta::before {
  content: "или через ";
  color: var(--muted);
}

.login-shell-v2 .button-ghost.passkey-cta::after {
  content: "Passkey";
  color: var(--accent);
  font-weight: 600;
  text-decoration: underline;
  text-decoration-color: color-mix(in srgb, var(--accent) 40%, transparent);
  text-underline-offset: 3px;
}

/* Hide the real button label so the ::before/::after pseudo content
   reads as the visible label (button text is replaced visually, but
   the accessible name stays via aria-label fallback in markup). */
.login-shell-v2 .button-ghost.passkey-cta {
  font-size: 0;
}
.login-shell-v2 .button-ghost.passkey-cta::before,
.login-shell-v2 .button-ghost.passkey-cta::after {
  font-size: 14px;
}

.login-shell-v2 .button-ghost.passkey-cta:hover::after {
  color: color-mix(in srgb, var(--accent) 75%, var(--text));
  text-decoration-color: var(--accent);
}

.login-shell-v2 .form-status {
  font-size: 13px;
  color: var(--muted);
  margin-top: 10px;
  text-align: center;
  min-height: 0;
}

.login-shell-v2 .form-status.error {
  color: var(--danger);
}

.login-shell-v2 .error {
  margin-bottom: 18px;
}

/* === Theme toggle (mode only — palette stays beaver) ======= */
.login-shell-v2 .login-theme-toggle {
  position: absolute;
  top: clamp(16px, 2.2vw, 28px);
  right: clamp(16px, 2.2vw, 28px);
  z-index: 10;
  display: inline-flex;
  gap: 2px;
  padding: 4px;
  border-radius: var(--radius-pill);
  background: color-mix(in srgb, var(--panel) 82%, transparent);
  border: 1px solid var(--stroke);
  box-shadow: 0 1px 2px rgba(42, 34, 24, 0.06);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  /* Self-contained fade — independent of the JS-driven .is-entered hook so
     the control is usable even if the entrance script never fires. */
  animation: login-theme-fade 0.5s ease 0.35s both;
}

@keyframes login-theme-fade {
  from {
    opacity: 0;
    transform: translateY(-6px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.login-shell-v2 .login-theme-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 0;
  border: none;
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  transition:
    background 0.15s ease,
    color 0.15s ease;
  --icon-size: 17px;
}

.login-shell-v2 .login-theme-btn:hover {
  color: var(--text);
  background: color-mix(in srgb, var(--text) 7%, transparent);
}

.login-shell-v2 .login-theme-btn.is-active {
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 14%, transparent);
}

.login-shell-v2 .login-theme-btn:focus-visible {
  outline: 2px solid color-mix(in srgb, var(--accent) 55%, transparent);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  .login-shell-v2 .login-theme-toggle {
    animation: none;
  }
}

/* === Entrance animation ==================================== */
.login-shell-v2 .login-hero-brand,
.login-shell-v2 .login-hero-slogan-line,
.login-shell-v2 .login-hero-slogan-rotate,
.login-shell-v2 .form-card-v2 {
  opacity: 0;
  transform: translateY(14px);
  transition:
    opacity 0.55s cubic-bezier(0.2, 0.65, 0.3, 1),
    transform 0.55s cubic-bezier(0.2, 0.65, 0.3, 1);
}

.login-shell-v2 .form-card-v2 {
  transform: translateX(20px);
  transition-duration: 0.6s;
  transition-delay: 0.05s;
}

.login-shell-v2.is-entered .login-hero-brand {
  opacity: 1;
  transform: translateY(0);
  transition-delay: 0.05s;
}

.login-shell-v2.is-entered .login-hero-slogan-line-1 {
  opacity: 1;
  transform: translateY(0);
  transition-delay: 0.15s;
}

.login-shell-v2.is-entered .login-hero-slogan-line-2 {
  opacity: 1;
  transform: translateY(0);
  transition-delay: 0.25s;
}

.login-shell-v2.is-entered .login-hero-slogan-rotate {
  opacity: 1;
  transform: translateY(0);
  transition-delay: 0.35s;
}

.login-shell-v2.is-entered .form-card-v2 {
  opacity: 1;
  transform: translateX(0);
  transition-delay: 0.18s;
}

@media (prefers-reduced-motion: reduce) {
  .login-shell-v2 .login-hero-brand,
  .login-shell-v2 .login-hero-slogan-line,
  .login-shell-v2 .login-hero-slogan-rotate,
  .login-shell-v2 .form-card-v2 {
    opacity: 1;
    transform: none;
    transition: none;
  }
  .login-shell-v2 .login-hero-slogan-phrase {
    transition: none;
    filter: none;
  }
}

/* === Mobile: hide hero, single-column form ================= */
@media (max-width: 880px) {
  .login-shell-v2 {
    grid-template-columns: 1fr;
  }
  .login-shell-v2 .login-hero {
    display: none;
  }
  .login-shell-v2 .login-form-zone {
    background: var(--bg);
    padding: 32px 20px;
    min-height: 100dvh;
  }
  .login-shell-v2 .form-card-v2 {
    width: min(420px, 100%);
  }
}

/* === Loading Spinner for buttons === */
.loading-spinner {
  display: inline-block;
  width: 20px;
  height: 20px;
  border: 2px solid rgba(255, 255, 255, 0.3);
  border-radius: 50%;
  border-top-color: var(--accent-contrast, #fff);
  animation: spin 0.8s linear infinite;
  vertical-align: middle;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

.form-card-v2 .button:disabled {
  opacity: 0.85;
  cursor: not-allowed;
}

/* === Transition/Animation for forms === */
#login-2fa-section:not([hidden]) {
  animation: loginFormFadeIn 0.35s cubic-bezier(0.2, 0.65, 0.3, 1) both;
}

@keyframes loginFormFadeIn {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* === core/ui.css === */
/* Global Toggle Switch */
.toggle {
  display: flex;
  align-items: center;
  gap: 12px;
  cursor: pointer;
  font-size: 14px;
  user-select: none;
}

.toggle input {
  appearance: none;
  margin: 0;
  width: 44px;
  height: 24px;
  background: var(--panel-2);
  border-radius: 999px;
  border: 1px solid var(--stroke);
  position: relative;
  cursor: pointer;
  transition:
    background 0.2s ease,
    border-color 0.2s ease;
}

.toggle input::after {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--muted);
  transition:
    transform 0.2s cubic-bezier(0.4, 0, 0.2, 1),
    background 0.2s ease;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}

.toggle input:checked {
  background: color-mix(in srgb, var(--accent) 15%, transparent);
  border-color: color-mix(in srgb, var(--accent) 60%, transparent);
}

.toggle input:checked::after {
  transform: translateX(20px);
  background: var(--accent);
  box-shadow: 0 2px 8px color-mix(in srgb, var(--accent) 40%, transparent);
}

.toggle:hover input {
  border-color: color-mix(in srgb, var(--accent) 40%, transparent);
}

.confirm-card {
  max-width: 320px;
  text-align: center;
}

.confirm-card .modal-header {
  justify-content: center;
  border-bottom: none;
  padding-bottom: 0;
}

.confirm-card .modal-body {
  padding-top: 8px;
  padding-bottom: 24px;
  color: var(--muted);
}

.confirm-card .modal-footer {
  display: flex;
  flex-direction: row;
  gap: 12px;
  justify-content: center;
  margin-top: 0;
}

.confirm-card .button {
  flex: 1;
  margin: 0;
  min-width: 0;
}

@keyframes popover-in {
  from {
    opacity: 0;
    transform: scale(0.95);
  }

  to {
    opacity: 1;
    transform: scale(1);
  }
}

/* Delete Popover */
.delete-popover {
  position: absolute;
  z-index: 1000;
  background-color: var(--panel);
  border: 1px solid var(--stroke);
  border-radius: 12px;
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);
  display: flex;
  flex-direction: column;
  min-width: 180px;
  overflow: hidden;
  animation: popover-in 0.15s cubic-bezier(0.16, 1, 0.3, 1);
}

.delete-popover button {
  background: none;
  border: none;
  border-radius: 0;
  color: var(--text);
  padding: 12px 16px;
  text-align: left;
  font-size: 14px;
  cursor: pointer;
  transition: background-color 0.1s;
  display: flex;
  align-items: center;
  gap: 8px;
}

.delete-popover button:hover {
  background-color: var(--bg-2);
}

.delete-popover button.danger {
  color: var(--danger);
}

.delete-popover button.danger:hover {
  background-color: color-mix(in srgb, var(--danger) 10%, transparent);
}

.delete-popover-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 999;
  background: transparent;
}

/* Passkey Island */
.passkey-status-island {
  margin-top: 12px;
  background: var(--panel-2);
  border: 1px solid var(--accent);
  color: var(--text);
  padding: 10px 16px;
  border-radius: 20px;
  text-align: center;
  font-size: 13px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  animation: popIn 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}

.passkey-status-island:empty {
  display: none;
}

@keyframes popIn {
  from {
    transform: scale(0.9);
    opacity: 0;
  }

  to {
    transform: scale(1);
    opacity: 1;
  }
}

/* Form Tooltip */
.field-error-tooltip {
  position: absolute;
  bottom: 100%;
  left: 50%;
  transform: translateX(-50%) translateY(-8px);
  background: var(--danger);
  color: #fff;
  padding: 6px 10px;
  border-radius: 8px;
  font-size: 12px;
  white-space: nowrap;
  pointer-events: none;
  z-index: 10;
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);
  animation: floatUp 0.2s ease-out;
}

.field-error-tooltip::after {
  content: "";
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  border-width: 5px;
  border-style: solid;
  border-color: var(--danger) transparent transparent transparent;
}

@keyframes floatUp {
  from {
    opacity: 0;
    transform: translateX(-50%) translateY(0);
  }

  to {
    opacity: 1;
    transform: translateX(-50%) translateY(-8px);
  }
}

/* === core/icon-button.css === */
.icon-button {
  width: 28px;
  height: 28px;
  border-radius: 8px;
  border: 1px solid var(--stroke);
  background: var(--panel);
  color: var(--text);
  cursor: pointer;
  font-size: 16px;
  display: grid;
  place-items: center;
  line-height: 1;
  padding: 0;
}

.icon-button:hover {
  border-color: color-mix(in srgb, var(--accent) 50%, transparent);
}

/* === core/menus.css === */
/* Glassmorphism Menu Style */
.glass-menu {
  background: color-mix(in srgb, var(--panel) 45%, transparent);
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
  border: 1px solid color-mix(in srgb, var(--stroke) 40%, transparent);
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.25);
}

/* Context Menu (Generic) — flat plate */
.context-menu {
  position: fixed;
  z-index: 9999;
  background: var(--panel);
  border: 1px solid var(--stroke);
  box-shadow: var(--shadow);
  border-radius: var(--radius-sm);
  padding: 6px;
  min-width: 180px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  overflow: visible;
  opacity: 0;
  transform: scale(0.95);
  pointer-events: none;
  transition:
    opacity 0.2s,
    transform 0.2s;
}

.context-menu.with-reaction-picker {
  gap: 6px;
  padding-top: 12px;
}

.context-reaction-picker {
  align-self: flex-start;
  margin: -10px 6px 0;
  padding: 4px 5px;
  border-radius: 999px;
  border: none;
  background: transparent;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  box-shadow: none;
  max-width: min(360px, calc(100vw - 24px));
}

.context-reaction-picker.is-expanded {
  border: none;
}

.context-reaction-row {
  display: grid;
  grid-template-columns: repeat(6, 36px);
  grid-auto-rows: 36px;
  gap: 4px;
  align-items: center;
}

.context-reaction-picker.is-expanded .context-reaction-row {
  grid-template-columns: repeat(6, 36px);
}

.context-reaction-btn {
  appearance: none;
  -webkit-appearance: none;
  width: 36px;
  min-width: 36px;
  height: 36px;
  border-radius: var(--radius-sm);
  border: none;
  background: transparent;
  color: var(--text);
  cursor: pointer;
  display: grid;
  place-items: center;
  font-size: 20px;
  font-family: "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", sans-serif;
  line-height: 1;
  padding: 0;
  transition:
    transform var(--anim-fast) var(--ease-out),
    background-color var(--anim-fast) var(--ease-out);
}

.context-reaction-btn .context-reaction-glyph {
  display: block;
  transform: translateY(2px);
}

.context-reaction-btn:hover {
  transform: translateY(-1px) scale(1.03);
  background-color: color-mix(in srgb, var(--accent) 10%, transparent);
}

.context-reaction-btn:active {
  transform: scale(0.96);
}

.context-reaction-btn:focus-visible {
  outline: 2px solid color-mix(in srgb, var(--accent) 72%, transparent);
  outline-offset: -1px;
}

.context-reaction-btn.context-reaction-more {
  font-size: 0;
  color: var(--muted);
}

.context-reaction-btn.context-reaction-more .icon {
  --icon-size: 18px;
}

.context-reaction-picker.is-expanded .context-reaction-btn {
  animation: reactionBtnIn 0.18s ease-out;
}

@keyframes reactionBtnIn {
  from {
    opacity: 0;
    transform: scale(0.88);
  }

  to {
    opacity: 1;
    transform: scale(1);
  }
}

.context-menu.is-open {
  pointer-events: auto;
  opacity: 1;
  transform: scale(1);
  animation: menuFadeIn 0.2s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}

.context-menu.is-closing {
  animation: menuFadeOut 0.15s ease-in forwards;
  pointer-events: none;
}

@keyframes menuFadeIn {
  from {
    opacity: 0;
    transform: scale(0.95);
  }

  to {
    opacity: 1;
    transform: scale(1);
  }
}

@keyframes menuFadeOut {
  from {
    opacity: 1;
    transform: scale(1);
  }

  to {
    opacity: 0;
    transform: scale(0.95);
  }
}

.context-menu-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  border-radius: var(--radius-sm);
  cursor: pointer;
  color: var(--text);
  font-size: 13px;
  transition:
    background 0.15s,
    color 0.15s,
    transform 0.1s;
  background: transparent;
  border: none;
  width: 100%;
  text-align: left;
}

.context-menu-item .menu-label {
  flex: 1;
  min-width: 0;
}

.menu-shortcut {
  margin-left: auto;
  padding-left: var(--space-3);
  font-family: var(--font-mono);
  font-size: 11px;
  line-height: 1;
  color: var(--muted);
  letter-spacing: 0.02em;
  white-space: nowrap;
  flex-shrink: 0;
}

.context-menu-item:hover .menu-shortcut {
  color: var(--text);
}

.context-menu-item.danger .menu-shortcut {
  color: color-mix(in srgb, var(--danger) 60%, var(--muted));
}

.context-menu-item:hover {
  background: color-mix(in srgb, var(--accent) 15%, transparent);
}

.context-menu-item:active {
  transform: scale(0.97);
}

.context-menu-item.danger {
  color: var(--danger);
}

.context-menu-item.danger:hover {
  background: color-mix(in srgb, var(--danger) 10%, transparent);
}

.context-menu-separator {
  height: 1px;
  background: color-mix(in srgb, var(--stroke) 60%, transparent);
  margin: 3px 8px;
}

.context-menu-reaction-separator {
  display: none;
}

/* Expanded Delete Menu */

.delete-container {
  display: grid;
  grid-template-rows: auto 0fr;
  transition: grid-template-rows 0.32s cubic-bezier(0.4, 0, 0.2, 1);
}

.delete-container.open {
  grid-template-rows: auto 1fr;
}

.delete-options-expand {
  display: grid;
  grid-template-rows: 0fr;
  opacity: 0;
  transition:
    grid-template-rows 0.32s cubic-bezier(0.4, 0, 0.2, 1),
    opacity 0.2s ease;
}

.delete-options-expand.open {
  grid-template-rows: 1fr;
  opacity: 1;
}

.delete-main-btn {
  overflow: hidden;
  max-height: 44px;
  opacity: 1;
  transform: scaleY(1);
  transform-origin: top;
  transition:
    max-height 0.24s cubic-bezier(0.4, 0, 0.2, 1),
    opacity 0.18s ease,
    transform 0.24s cubic-bezier(0.4, 0, 0.2, 1),
    padding 0.2s ease;
}

.delete-main-btn.is-collapsed {
  max-height: 0;
  opacity: 0;
  transform: scaleY(0.94);
  pointer-events: none;
  padding-top: 0;
  padding-bottom: 0;
}

.delete-options-expand > div {
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

/* === core/utilities.css === */
.mirror-x {
  transform: scaleX(-1);
}

[hidden],
.hidden {
  display: none !important;
}

/* === scrollbar.css === */
/* Custom scrollbar styles - works with all themes via CSS variables */

/* Firefox */
* {
  scrollbar-width: thin;
  scrollbar-color: color-mix(in srgb, var(--muted) 40%, transparent) transparent;
}

/* Webkit (Chrome, Safari, Edge) */
::-webkit-scrollbar {
  width: 8px;
  height: 8px;
}

::-webkit-scrollbar-track {
  background: transparent;
  border-radius: 4px;
}

::-webkit-scrollbar-thumb {
  background: color-mix(in srgb, var(--muted) 35%, transparent);
  border-radius: 4px;
  border: 2px solid transparent;
  background-clip: padding-box;
  transition: background 0.2s ease;
}

::-webkit-scrollbar-thumb:hover {
  background: color-mix(in srgb, var(--muted) 55%, transparent);
  background-clip: padding-box;
}

::-webkit-scrollbar-thumb:active {
  background: color-mix(in srgb, var(--accent) 50%, transparent);
  background-clip: padding-box;
}

::-webkit-scrollbar-corner {
  background: transparent;
}

/* Specific scrollable containers - show scrollbar on hover */
.chat-list,
.messages,
.settings-content,
.select-options,
.invite-list,
.group-members-list,
.group-add-list,
.profile-modal-messages,
.modal-body {
  scrollbar-gutter: stable;
}

/* Make scrollbar more visible when actively scrolling */
.chat-list::-webkit-scrollbar-thumb,
.messages::-webkit-scrollbar-thumb,
.settings-content::-webkit-scrollbar-thumb {
  background: color-mix(in srgb, var(--muted) 30%, transparent);
  background-clip: padding-box;
}

.chat-list:hover::-webkit-scrollbar-thumb,
.messages:hover::-webkit-scrollbar-thumb,
.settings-content:hover::-webkit-scrollbar-thumb {
  background: color-mix(in srgb, var(--muted) 50%, transparent);
  background-clip: padding-box;
}

/* Thin scrollbar for smaller containers */
.select-options::-webkit-scrollbar,
.group-members-list::-webkit-scrollbar,
.group-add-list::-webkit-scrollbar {
  width: 6px;
}

/* === icons.css === */
.icon {
  display: inline-block;
  width: var(--icon-size, 16px);
  height: var(--icon-size, 16px);
  background-color: currentColor;
  mask: var(--icon) no-repeat center / contain;
  -webkit-mask: var(--icon) no-repeat center / contain;
  flex: 0 0 auto;
}

.icon-plus {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox=%220%200%2024%2024%22%20xmlns=%22http://www.w3.org/2000/svg%22%20fill=%22none%22%20stroke=%22black%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%20%3Cpath%20d=%22M12%205v14%22%20/%3E%20%3Cpath%20d=%22M5%2012h14%22%20/%3E%20%3C/svg%3E");
}

.icon-paperclip {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox=%220%200%2024%2024%22%20xmlns=%22http://www.w3.org/2000/svg%22%20fill=%22none%22%20stroke=%22black%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%20%3Cpath%20d=%22M21.44%2011.05l-9.19%209.19a6%206%200%200%201-8.49-8.49l9.19-9.19a4%204%200%200%201%205.66%205.66l-9.2%209.19a2%202%200%200%201-2.83-2.83l8.49-8.48%22%20/%3E%20%3C/svg%3E");
}

.icon-close {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox=%220%200%2024%2024%22%20xmlns=%22http://www.w3.org/2000/svg%22%20fill=%22none%22%20stroke=%22black%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%20%3Cpath%20d=%22M6%206l12%2012%22%20/%3E%20%3Cpath%20d=%22M6%2018L18%206%22%20/%3E%20%3C/svg%3E");
}

.icon-phone {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox=%220%200%2024%2024%22%20xmlns=%22http://www.w3.org/2000/svg%22%20fill=%22none%22%20stroke=%22black%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%20%3Cpath%20d=%22M22%2016.92v3a2%202%200%200%201-2.18%202%2019.79%2019.79%200%200%201-8.63-3.07%2019.5%2019.5%200%200%201-6-6%2019.79%2019.79%200%200%201-3.07-8.67A2%202%200%200%201%204.11%202h3a2%202%200%200%201%202%201.72%2012.84%2012.84%200%200%200%20.7%202.81%202%202%200%200%201-.45%202.11L8.09%209.91a16%2016%200%200%200%206%206l1.27-1.27a2%202%200%200%201%202.11-.45%2012.84%2012.84%200%200%200%202.81.7A2%202%200%200%201%2022%2016.92z%22%20/%3E%20%3C/svg%3E");
}

.icon-video {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox=%220%200%2024%2024%22%20xmlns=%22http://www.w3.org/2000/svg%22%20fill=%22none%22%20stroke=%22black%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%20%3Crect%20x=%223%22%20y=%227%22%20width=%2213%22%20height=%2210%22%20rx=%222%22%20/%3E%20%3Cpath%20d=%22M16%2010l5-3v10l-5-3z%22%20/%3E%20%3C/svg%3E");
}

.icon-mic {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox=%220%200%2024%2024%22%20xmlns=%22http://www.w3.org/2000/svg%22%20fill=%22none%22%20stroke=%22black%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%20%3Crect%20x=%229%22%20y=%223%22%20width=%226%22%20height=%2211%22%20rx=%223%22%20/%3E%20%3Cpath%20d=%22M5%2011v1a7%207%200%200%200%2014%200v-1%22%20/%3E%20%3Cpath%20d=%22M12%2019v2%22%20/%3E%20%3C/svg%3E");
}

.icon-mic-off {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox=%220%200%2024%2024%22%20xmlns=%22http://www.w3.org/2000/svg%22%20fill=%22none%22%20stroke=%22black%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%20%3Crect%20x=%229%22%20y=%223%22%20width=%226%22%20height=%2211%22%20rx=%223%22%20/%3E%20%3Cpath%20d=%22M5%2011v1a7%207%200%200%200%2014%200v-1%22%20/%3E%20%3Cpath%20d=%22M12%2019v2%22%20/%3E%20%3Cline%20x1=%223%22%20y1=%223%22%20x2=%2221%22%20y2=%2221%22%20/%3E%20%3C/svg%3E");
}

.icon-camera {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox=%220%200%2024%2024%22%20xmlns=%22http://www.w3.org/2000/svg%22%20fill=%22none%22%20stroke=%22black%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%20%3Cpath%20d=%22M4%207h4l2-2h4l2%202h4v11H4z%22%20/%3E%20%3Ccircle%20cx=%2212%22%20cy=%2213%22%20r=%223%22%20/%3E%20%3C/svg%3E");
}

.icon-screen {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox=%220%200%2024%2024%22%20xmlns=%22http://www.w3.org/2000/svg%22%20fill=%22none%22%20stroke=%22black%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%20%3Crect%20x=%223%22%20y=%224%22%20width=%2218%22%20height=%2212%22%20rx=%222%22%20/%3E%20%3Cpath%20d=%22M8%2020h8%22%20/%3E%20%3Cpath%20d=%22M12%2016v4%22%20/%3E%20%3C/svg%3E");
}

.icon-headset {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox=%220%200%2024%2024%22%20xmlns=%22http://www.w3.org/2000/svg%22%20fill=%22none%22%20stroke=%22black%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%20%3Cpath%20d=%22M4%2012a8%208%200%200%201%2016%200%22%20/%3E%20%3Crect%20x=%223%22%20y=%2212%22%20width=%224%22%20height=%227%22%20rx=%222%22%20/%3E%20%3Crect%20x=%2217%22%20y=%2212%22%20width=%224%22%20height=%227%22%20rx=%222%22%20/%3E%20%3C/svg%3E");
}

.icon-headset-off {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox=%220%200%2024%2024%22%20xmlns=%22http://www.w3.org/2000/svg%22%20fill=%22none%22%20stroke=%22black%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%20%3Cpath%20d=%22M4%2012a8%208%200%200%201%2016%200%22%20/%3E%20%3Crect%20x=%223%22%20y=%2212%22%20width=%224%22%20height=%227%22%20rx=%222%22%20/%3E%20%3Crect%20x=%2217%22%20y=%2212%22%20width=%224%22%20height=%227%22%20rx=%222%22%20/%3E%20%3Cline%20x1=%223%22%20y1=%223%22%20x2=%2221%22%20y2=%2221%22%20/%3E%20%3C/svg%3E");
}

.icon-layout-top {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox=%220%200%2024%2024%22%20xmlns=%22http://www.w3.org/2000/svg%22%20fill=%22none%22%20stroke=%22black%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%20%3Crect%20x=%223%22%20y=%223%22%20width=%2218%22%20height=%2218%22%20rx=%222%22%20/%3E%20%3Cpath%20d=%22M3%209h18%22%20/%3E%20%3Cpath%20d=%22M6%206h6%22%20/%3E%20%3C/svg%3E");
}

.icon-layout-half {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox=%220%200%2024%2024%22%20xmlns=%22http://www.w3.org/2000/svg%22%20fill=%22none%22%20stroke=%22black%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%20%3Crect%20x=%223%22%20y=%223%22%20width=%2218%22%20height=%2218%22%20rx=%222%22%20/%3E%20%3Cpath%20d=%22M3%2012h18%22%20/%3E%20%3C/svg%3E");
}

.icon-gear {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox=%220%200%2024%2024%22%20xmlns=%22http://www.w3.org/2000/svg%22%20fill=%22none%22%20stroke=%22black%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%20%3Cpath%20d=%22M12.22%202h-.44a2%202%200%200%200-2%202v.18a2%202%200%200%201-1%201.73l-.43.25a2%202%200%200%201-2%200l-.15-.08a2%202%200%200%200-2.73.73l-.22.38a2%202%200%200%200%20.73%202.73l.15.1a2%202%200%200%201%201%201.72v.51a2%202%200%200%201-1%201.74l-.15.09a2%202%200%200%200-.73%202.73l.22.38a2%202%200%200%200%202.73.73l.15-.08a2%202%200%200%201%202%200l.43.25a2%202%200%200%201%201%201.73V20a2%202%200%200%200%202%202h.44a2%202%200%200%200%202-2v-.18a2%202%200%200%201%201-1.73l.43-.25a2%202%200%200%201%202%200l.15.08a2%202%200%200%200%202.73-.73l.22-.39a2%202%200%200%200-.73-2.73l-.15-.08a2%202%200%200%201-1-1.74v-.5a2%202%200%200%201%201-1.74l.15-.09a2%202%200%200%200%20.73-2.73l-.22-.38a2%202%200%200%200-2.73-.73l-.15.08a2%202%200%200%201-2%200l-.43-.25a2%202%200%200%201-1-1.73V4a2%202%200%200%200-2-2z%22%20/%3E%20%3Ccircle%20cx=%2212%22%20cy=%2212%22%20r=%223%22%20/%3E%20%3C/svg%3E");
}

.icon-qr {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22currentColor%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%20%3Crect%20x=%223%22%20y=%223%22%20width=%227%22%20height=%227%22%20rx=%221%22%3E%3C/rect%3E%20%3Crect%20x=%2214%22%20y=%223%22%20width=%227%22%20height=%227%22%20rx=%221%22%3E%3C/rect%3E%20%3Crect%20x=%223%22%20y=%2214%22%20width=%227%22%20height=%227%22%20rx=%221%22%3E%3C/rect%3E%20%3Cpath%20d=%22M14%2014h3v3%22%3E%3C/path%3E%20%3Cpath%20d=%22M21%2014v7h-7%22%3E%3C/path%3E%20%3Cpath%20d=%22M17%2021v.01%22%3E%3C/path%3E%20%3C/svg%3E");
}

.icon-logout {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22currentColor%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%20%3Cpath%20d=%22M9%2021H5a2%202%200%200%201-2-2V5a2%202%200%200%201%202-2h4%22%3E%3C/path%3E%20%3Cpolyline%20points=%2216%2017%2021%2012%2016%207%22%3E%3C/polyline%3E%20%3Cline%20x1=%2221%22%20y1=%2212%22%20x2=%229%22%20y2=%2212%22%3E%3C/line%3E%20%3C/svg%3E");
}

.icon-expand {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox=%220%200%2024%2024%22%20xmlns=%22http://www.w3.org/2000/svg%22%20fill=%22none%22%20stroke=%22black%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%20%3Cpath%20d=%22M3%209V3h6%22%20/%3E%20%3Cpath%20d=%22M21%209V3h-6%22%20/%3E%20%3Cpath%20d=%22M3%2015v6h6%22%20/%3E%20%3Cpath%20d=%22M21%2015v6h-6%22%20/%3E%20%3C/svg%3E");
}

.icon-hangup {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox=%220%200%2024%2024%22%20xmlns=%22http://www.w3.org/2000/svg%22%20fill=%22none%22%20stroke=%22black%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%20%3Cpath%20d=%22M2%2010s3-3%2010-3%2010%203%2010%203l-2.5%203.5-3.5-1v-2c-2-1-6-1-8%200v2l-3.5%201L2%2010z%22%20/%3E%20%3C/svg%3E");
}

.icon-reply {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox=%220%200%2024%2024%22%20xmlns=%22http://www.w3.org/2000/svg%22%20fill=%22none%22%20stroke=%22black%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%20%3Cpath%20d=%22M10%209l-4%204%204%204%22%20/%3E%20%3Cpath%20d=%22M6%2013h9a4%204%200%200%201%204%204v1%22%20/%3E%20%3C/svg%3E");
}

.icon-edit {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox=%220%200%2024%2024%22%20xmlns=%22http://www.w3.org/2000/svg%22%20fill=%22none%22%20stroke=%22black%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%20%3Cpath%20d=%22M17%203a2.828%202.828%200%201%201%204%204L7.5%2020.5%202%2022l1.5-5.5L17%203z%22%20/%3E%20%3C/svg%3E");
}

.icon-trash {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox=%220%200%2024%2024%22%20xmlns=%22http://www.w3.org/2000/svg%22%20fill=%22none%22%20stroke=%22black%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%20%3Cpath%20d=%22M4%207h16%22%20/%3E%20%3Cpath%20d=%22M9%207V5h6v2%22%20/%3E%20%3Crect%20x=%226%22%20y=%227%22%20width=%2212%22%20height=%2213%22%20rx=%222%22%20/%3E%20%3Cpath%20d=%22M10%2011v6%22%20/%3E%20%3Cpath%20d=%22M14%2011v6%22%20/%3E%20%3C/svg%3E");
}

.icon-check {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22currentColor%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%20%3Cpath%20d=%22M5%2012l4%204%2010-10%22%20/%3E%20%3C/svg%3E");
}

.icon-check-double {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22currentColor%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%20%3Cpath%20d=%22M3.5%2012.5l4%204%208.5-8.5%22%20/%3E%20%3Cpath%20d=%22M9%2012.5l4%204%207.5-7.5%22%20/%3E%20%3C/svg%3E");
}

.icon-copy {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20width=%2224%22%20height=%2224%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22currentColor%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%3Crect%20x=%229%22%20y=%229%22%20width=%2213%22%20height=%2213%22%20rx=%222%22%20ry=%222%22%3E%3C/rect%3E%3Cpath%20d=%22M5%2015H4a2%202%200%200%201-2-2V4a2%202%200%200%201%202-2h9a2%202%200%200%201%202%202v1%22%3E%3C/path%3E%3C/svg%3E");
}

.icon-download {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%3E%20%3Cpath%20d=%22M12%203V14%22%20stroke=%22currentColor%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22/%3E%20%3Cpath%20d=%22M7%2010.5L12%2015.5L17%2010.5%22%20stroke=%22currentColor%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22/%3E%20%3Cpath%20d=%22M4%2018.5H20%22%20stroke=%22currentColor%22%20stroke-width=%222%22%20stroke-linecap=%22round%22/%3E%20%3C/svg%3E");
}

.icon-search {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22currentColor%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%3Ccircle%20cx=%2211%22%20cy=%2211%22%20r=%228%22%3E%3C/circle%3E%3Cline%20x1=%2221%22%20y1=%2221%22%20x2=%2216.65%22%20y2=%2216.65%22%3E%3C/line%3E%3C/svg%3E");
}

.icon-send {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox=%220%200%2024%2024%22%20xmlns=%22http://www.w3.org/2000/svg%22%20fill=%22none%22%20stroke=%22black%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%20%3Cpath%20d=%22M22%202L11%2013%22%20/%3E%20%3Cpath%20d=%22M22%202l-7%2020-4-9-9-4%2020-7z%22%20/%3E%20%3C/svg%3E");
}

.icon-play {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox=%220%200%2024%2024%22%20xmlns=%22http://www.w3.org/2000/svg%22%20fill=%22none%22%20stroke=%22black%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%20%3Cpolygon%20points=%225%203%2019%2012%205%2021%205%203%22%20/%3E%20%3C/svg%3E");
}

.icon-pause {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox=%220%200%2024%2024%22%20xmlns=%22http://www.w3.org/2000/svg%22%20fill=%22none%22%20stroke=%22black%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%20%3Crect%20x=%226%22%20y=%224%22%20width=%224%22%20height=%2216%22%20/%3E%20%3Crect%20x=%2214%22%20y=%224%22%20width=%224%22%20height=%2216%22%20/%3E%20%3C/svg%3E");
}

.icon-mixer {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox=%220%200%2024%2024%22%20xmlns=%22http://www.w3.org/2000/svg%22%20fill=%22none%22%20stroke=%22black%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%20%3Cpath%20d=%22M11%205h10M11%2019h10M11%2012h10M3%205h4M3%2019h4M3%2012h4%22%20/%3E%20%3Ccircle%20cx=%229%22%20cy=%225%22%20r=%222%22%20/%3E%20%3Ccircle%20cx=%229%22%20cy=%2219%22%20r=%222%22%20/%3E%20%3Ccircle%20cx=%229%22%20cy=%2212%22%20r=%222%22%20/%3E%20%3C/svg%3E");
}

.icon-volume {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox=%220%200%2024%2024%22%20xmlns=%22http://www.w3.org/2000/svg%22%20fill=%22none%22%20stroke=%22black%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%20%3Cpath%20d=%22M11%205%206%209H2v6h4l5%204z%22%20/%3E%20%3Cpath%20d=%22M15.5%208.5a5%205%200%200%201%200%207%22%20/%3E%20%3Cpath%20d=%22M19%205a9%209%200%200%201%200%2014%22%20/%3E%20%3C/svg%3E");
}

.icon-volume-low {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox=%220%200%2024%2024%22%20xmlns=%22http://www.w3.org/2000/svg%22%20fill=%22none%22%20stroke=%22black%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%20%3Cpath%20d=%22M11%205%206%209H2v6h4l5%204z%22%20/%3E%20%3Cpath%20d=%22M15.5%208.5a5%205%200%200%201%200%207%22%20/%3E%20%3C/svg%3E");
}

.icon-volume-mute {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox=%220%200%2024%2024%22%20xmlns=%22http://www.w3.org/2000/svg%22%20fill=%22none%22%20stroke=%22black%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%20%3Cpath%20d=%22M11%205%206%209H2v6h4l5%204z%22%20/%3E%20%3Cline%20x1=%2216%22%20y1=%229%22%20x2=%2222%22%20y2=%2215%22%20/%3E%20%3Cline%20x1=%2222%22%20y1=%229%22%20x2=%2216%22%20y2=%2215%22%20/%3E%20%3C/svg%3E");
}

.icon-collapse {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox=%220%200%2024%2024%22%20xmlns=%22http://www.w3.org/2000/svg%22%20fill=%22none%22%20stroke=%22black%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%20%3Cpath%20d=%22M9%203v6H3%22%20/%3E%20%3Cpath%20d=%22M21%209h-6V3%22%20/%3E%20%3Cpath%20d=%22M3%2015h6v6%22%20/%3E%20%3Cpath%20d=%22M15%2021v-6h6%22%20/%3E%20%3C/svg%3E");
}

.icon-more {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22currentColor%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%3Ccircle%20cx=%2212%22%20cy=%2212%22%20r=%221%22%3E%3C/circle%3E%3Ccircle%20cx=%2212%22%20cy=%225%22%20r=%221%22%3E%3C/circle%3E%3Ccircle%20cx=%2212%22%20cy=%2219%22%20r=%221%22%3E%3C/circle%3E%3C/svg%3E");
}

.icon-info {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22currentColor%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%3Ccircle%20cx=%2212%22%20cy=%2212%22%20r=%2210%22%3E%3C/circle%3E%3Cline%20x1=%2212%22%20y1=%2216%22%20x2=%2212%22%20y2=%2212%22%3E%3C/line%3E%3Cline%20x1=%2212%22%20y1=%228%22%20x2=%2212.01%22%20y2=%228%22%3E%3C/line%3E%3C/svg%3E");
}

.icon-pin {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox=%220%200%2024%2024%22%20xmlns=%22http://www.w3.org/2000/svg%22%20fill=%22none%22%20stroke=%22black%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%20%3Cpath%20d=%22M12%2017v5%22%20/%3E%20%3Cpath%20d=%22M9%2010.76a2%202%200%200%201-1.11%201.79l-1.78.9A2%202%200%200%200%205%2015.24V16a1%201%200%200%200%201%201h12a1%201%200%200%200%201-1v-.76a2%202%200%200%200-1.11-1.79l-1.78-.9A2%202%200%200%201%2015%2010.76V7a1%201%200%200%201%201-1%202%202%200%200%200%200-4H8a2%202%200%200%200%200%204%201%201%200%200%201%201%201z%22%20/%3E%20%3C/svg%3E");
}

.icon-pin-off {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox=%220%200%2024%2024%22%20xmlns=%22http://www.w3.org/2000/svg%22%20fill=%22none%22%20stroke=%22black%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%20%3Cpath%20d=%22M12%2017v5%22%20/%3E%20%3Cpath%20d=%22M15%209.34V7a1%201%200%200%201%201-1%202%202%200%200%200%200-4H7.89%22%20/%3E%20%3Cpath%20d=%22M9%209v1.76a2%202%200%200%201-1.11%201.79l-1.78.9A2%202%200%200%200%205%2015.24V16a1%201%200%200%200%201%201h11%22%20/%3E%20%3Cpath%20d=%22m2%202%2020%2020%22%20/%3E%20%3C/svg%3E");
}

.icon-rotate-cw {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox=%220%200%2024%2024%22%20xmlns=%22http://www.w3.org/2000/svg%22%20fill=%22none%22%20stroke=%22black%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%20%3Cpath%20d=%22M21%2012a9%209%200%201%201-3.51-7.13%22%20/%3E%20%3Cpolyline%20points=%2221%203%2021%209%2015%209%22%20/%3E%20%3C/svg%3E");
}

.icon-chevron-down {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22currentColor%22%20stroke-width=%222.6%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%20%3Cpath%20d=%22M6%209.5L12%2015.5L18%209.5%22%20/%3E%20%3C/svg%3E");
}

.icon-chevron-left {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22currentColor%22%20stroke-width=%222.6%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%20%3Cpath%20d=%22M6%209.5L12%2015.5L18%209.5%22%20/%3E%20%3C/svg%3E");
  transform: rotate(90deg);
}

.icon-chevron-right {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22currentColor%22%20stroke-width=%222.6%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%20%3Cpath%20d=%22M6%209.5L12%2015.5L18%209.5%22%20/%3E%20%3C/svg%3E");
  transform: rotate(-90deg);
}

.icon-dots-horizontal {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%200%2024%2024%22%3E%20%3Ccircle%20cx=%225%22%20cy=%2212%22%20r=%222%22%20/%3E%20%3Ccircle%20cx=%2212%22%20cy=%2212%22%20r=%222%22%20/%3E%20%3Ccircle%20cx=%2219%22%20cy=%2212%22%20r=%222%22%20/%3E%20%3C/svg%3E");
}

.icon-user-plus {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22currentColor%22%20stroke-width=%221.9%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%20%3Cpath%20d=%22M15.5%2020a5.5%205.5%200%200%200-11%200%22%20/%3E%20%3Ccircle%20cx=%2210%22%20cy=%228%22%20r=%223.5%22%20/%3E%20%3Cpath%20d=%22M19%207v6%22%20/%3E%20%3Cpath%20d=%22M16%2010h6%22%20/%3E%20%3C/svg%3E");
}

.icon-user-minus {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22currentColor%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%20%3Cpath%20d=%22M16%2021v-2a4%204%200%200%200-4-4H5a4%204%200%200%200-4%204v2%22%3E%3C/path%3E%20%3Ccircle%20cx=%228.5%22%20cy=%227%22%20r=%224%22%3E%3C/circle%3E%20%3Cline%20x1=%2223%22%20y1=%2211%22%20x2=%2217%22%20y2=%2211%22%3E%3C/line%3E%20%3C/svg%3E");
}

.icon-user {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20width=%2224%22%20height=%2224%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22currentColor%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%20%3Ccircle%20cx=%2212%22%20cy=%228%22%20r=%224%22%20/%3E%20%3Cpath%20d=%22M5%2020a7%207%200%200%201%2014%200%22%20/%3E%20%3C/svg%3E");
}

.icon-device-otp {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20width=%2224%22%20height=%2224%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22currentColor%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%20%3Crect%20x=%226%22%20y=%222%22%20width=%2212%22%20height=%2220%22%20rx=%222.5%22%20/%3E%20%3Cpath%20d=%22M9.5%2011.2%2011%2012.7%2014.5%209.2%22%20/%3E%20%3Cpath%20d=%22M10.5%2018.5h3%22%20/%3E%20%3C/svg%3E");
}

.icon-passkey {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20width=%2224%22%20height=%2224%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22currentColor%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%20%3Cpath%20d=%22M2%2012C2%206.5%206.5%202%2012%202a10%2010%200%200%201%208%204%22%20/%3E%20%3Cpath%20d=%22M5%2019.5C5.5%2018%206%2015%206%2012a6%206%200%200%201%20.34-2%22%20/%3E%20%3Cpath%20d=%22M17.29%2021.02c.12-.6.43-2.3.5-3.02%22%20/%3E%20%3Cpath%20d=%22M12%2010a2%202%200%200%200-2%202c0%201.02-.1%202.51-.26%204%22%20/%3E%20%3Cpath%20d=%22M8.65%2022c.21-.66.45-1.32.57-2%22%20/%3E%20%3Cpath%20d=%22M14%2013.12c0%202.38%200%206.38-1%208.88%22%20/%3E%20%3Cpath%20d=%22M2%2016h.01%22%20/%3E%20%3Cpath%20d=%22M21.8%2016c.2-2%20.131-5.354%200-6%22%20/%3E%20%3Cpath%20d=%22M9%206.8a6%206%200%200%201%209%205.2v2%22%20/%3E%20%3C/svg%3E");
}

.icon-shield-lock {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22currentColor%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%20%3Cpath%20d=%22M12%2022s8-4%208-10V5l-8-3-8%203v7c0%206%208%2010%208%2010z%22%3E%3C/path%3E%20%3Crect%20x=%229%22%20y=%2211%22%20width=%226%22%20height=%224%22%20rx=%221%22%3E%3C/rect%3E%20%3Cpath%20d=%22M10%2011V9a2%202%200%201%201%204%200v2%22%3E%3C/path%3E%20%3C/svg%3E");
}

.icon-key-change {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20width=%2224%22%20height=%2224%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22currentColor%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%20%3Crect%20x=%223%22%20y=%2211%22%20width=%2218%22%20height=%2211%22%20rx=%222%22%20/%3E%20%3Cpath%20d=%22M7%2011V7a5%205%200%200%201%2010%200v4%22%20/%3E%20%3Ccircle%20cx=%2212%22%20cy=%2216%22%20r=%221.5%22%20/%3E%20%3Cpath%20d=%22M12%2017.5v1.5%22%20/%3E%20%3C/svg%3E");
}

.icon-devices {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20width=%2224%22%20height=%2224%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22currentColor%22%20stroke-width=%221.5%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%20%3Crect%20x=%222%22%20y=%223%22%20width=%2220%22%20height=%2214%22%20rx=%222%22%20ry=%222%22%3E%3C/rect%3E%20%3Cpath%20d=%22M8%2021h8%22%3E%3C/path%3E%20%3Cpath%20d=%22M12%2017v4%22%3E%3C/path%3E%20%3Crect%20x=%2217%22%20y=%2214%22%20width=%226%22%20height=%2210%22%20rx=%221%22%20stroke=%22currentColor%22%20fill=%22var(--bg)%22%3E%3C/rect%3E%20%3C/svg%3E");
}

.icon-palette {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22currentColor%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%20%3Ccircle%20cx=%2213.5%22%20cy=%226.5%22%20r=%22.5%22%20fill=%22currentColor%22%3E%3C/circle%3E%20%3Ccircle%20cx=%2217.5%22%20cy=%2210.5%22%20r=%22.5%22%20fill=%22currentColor%22%3E%3C/circle%3E%20%3Ccircle%20cx=%228.5%22%20cy=%227.5%22%20r=%22.5%22%20fill=%22currentColor%22%3E%3C/circle%3E%20%3Ccircle%20cx=%226.5%22%20cy=%2212.5%22%20r=%22.5%22%20fill=%22currentColor%22%3E%3C/circle%3E%20%3Cpath%20d=%22M12%202C6.5%202%202%206.5%202%2012s4.5%2010%2010%2010c.926%200%201.648-.746%201.648-1.688%200-.437-.18-.835-.437-1.125-.29-.289-.438-.652-.438-1.125a1.64%201.64%200%200%201%201.668-1.668h1.996c3.051%200%205.555-2.503%205.555-5.554C21.965%206.012%2017.461%202%2012%202z%22%3E%3C/path%3E%20%3C/svg%3E");
}

.icon-sun {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20width=%2224%22%20height=%2224%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22currentColor%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%3Ccircle%20cx=%2212%22%20cy=%2212%22%20r=%224%22/%3E%3Cpath%20d=%22M12%202v2%22/%3E%3Cpath%20d=%22M12%2020v2%22/%3E%3Cpath%20d=%22M4.93%204.93l1.41%201.41%22/%3E%3Cpath%20d=%22M17.66%2017.66l1.41%201.41%22/%3E%3Cpath%20d=%22M2%2012h2%22/%3E%3Cpath%20d=%22M20%2012h2%22/%3E%3Cpath%20d=%22M4.93%2019.07l1.41-1.41%22/%3E%3Cpath%20d=%22M17.66%206.34l1.41-1.41%22/%3E%3C/svg%3E");
}

.icon-moon {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20width=%2224%22%20height=%2224%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22currentColor%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%3Cpath%20d=%22M12%203a6%206%200%200%200%209%209%209%209%200%201%201-9-9Z%22/%3E%3C/svg%3E");
}

.icon-star {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20width=%2224%22%20height=%2224%22%20viewBox=%220%200%2024%2024%22%20fill=%22currentColor%22%3E%20%3Cpath%20d=%22M12%202l3.09%206.26L22%209.27l-5%204.87%201.18%206.88L12%2017.77l-6.18%203.25L7%2014.14%202%209.27l6.91-1.01L12%202z%22/%3E%20%3C/svg%3E");
}

.icon-star-outline {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20width=%2224%22%20height=%2224%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22currentColor%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%20%3Cpath%20d=%22M12%202l3.09%206.26L22%209.27l-5%204.87%201.18%206.88L12%2017.77l-6.18%203.25L7%2014.14%202%209.27l6.91-1.01L12%202z%22/%3E%20%3C/svg%3E");
}

.icon-crown {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20width=%2224%22%20height=%2224%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22currentColor%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%20%3Cpath%20d=%22m2%204%203%2012h14l3-12-6%207-4-7-4%207-6-7zm3%2016h14%22/%3E%20%3C/svg%3E");
}

.icon-mobile {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20width=%2224%22%20height=%2224%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22currentColor%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%3Crect%20x=%225%22%20y=%222%22%20width=%2214%22%20height=%2220%22%20rx=%222%22%20ry=%222%22%3E%3C/rect%3E%3Cline%20x1=%2212%22%20y1=%2218%22%20x2=%2212.01%22%20y2=%2218%22%3E%3C/line%3E%3C/svg%3E");
}

.icon-bell-off {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22currentColor%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%20%3Cpath%20d=%22M13.73%2021a2%202%200%200%201-3.46%200%22%3E%3C/path%3E%20%3Cpath%20d=%22M18.63%2013A17.89%2017.89%200%200%201%2018%208%22%3E%3C/path%3E%20%3Cpath%20d=%22M6.26%206.26A5.86%205.86%200%200%200%206%208c0%207-3%209-3%209h14%22%3E%3C/path%3E%20%3Cpath%20d=%22M18%208a6%206%200%200%200-9.33-5%22%3E%3C/path%3E%20%3Cline%20x1=%221%22%20y1=%221%22%20x2=%2223%22%20y2=%2223%22%3E%3C/line%3E%20%3C/svg%3E");
}

.icon-desktop {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22currentColor%22%20stroke-width=%221.8%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%20%3Crect%20x=%223%22%20y=%224%22%20width=%2218%22%20height=%2212%22%20rx=%222%22/%3E%20%3Cpath%20d=%22M12%2016v4%22/%3E%20%3Cpath%20d=%22M8%2020h8%22/%3E%20%3C/svg%3E");
}

.icon-list {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20width=%2224%22%20height=%2224%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22currentColor%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%3Crect%20x=%223%22%20y=%225%22%20width=%226%22%20height=%226%22%20rx=%221%22%3E%3C/rect%3E%3Cpath%20d=%22m3%2017%202%202%204-4%22%3E%3C/path%3E%3Cpath%20d=%22M13%206h8%22%3E%3C/path%3E%3Cpath%20d=%22M13%2012h8%22%3E%3C/path%3E%3Cpath%20d=%22M13%2018h8%22%3E%3C/path%3E%3C/svg%3E");
}

.icon-button,
.attach-button,
.modal-close,
.call-control,
.message-action,
.call-icon {
  --icon-size: 16px;
}

.call-control {
  --icon-size: 18px;
}

.attach-button {
  --icon-size: 18px;
}

.message-action {
  --icon-size: 12px;
}

.modal-close {
  --icon-size: 14px;
  display: grid;
  place-items: center;
}

.call-icon {
  --icon-size: 16px;
}

.call-icons .icon {
  --icon-size: 12px;
}

/* === toasts.css === */
.toast-stack {
  position: fixed;
  top: 18px;
  right: 18px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  z-index: 90;
  pointer-events: none;
}

.toast {
  width: min(340px, 92vw);
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 12px 14px;
  border-radius: 16px;
  border: 1px solid var(--glass-stroke);
  background: var(--glass-bg);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  color: var(--text);
  box-shadow: var(--glass-shadow);
  cursor: pointer;
  pointer-events: auto;
  text-align: left;
  font-family: inherit;
  animation: toastIn var(--anim-fast) var(--ease-out);
}

.toast.is-leaving {
  animation: toastOut var(--anim-fast) var(--ease-in-out) forwards;
}

.toast.error {
  border-color: color-mix(in srgb, var(--danger) 45%, transparent);
  background: color-mix(in srgb, var(--danger) 12%, transparent);
}

.toast-avatar {
  width: 36px;
  height: 36px;
  border-radius: 12px;
  border: 1px solid var(--stroke);
  background: var(--panel-2);
  display: grid;
  place-items: center;
  font-weight: 600;
  flex: 0 0 auto;
  overflow: hidden;
}

.toast-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.toast-content {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}

.toast-title {
  font-size: 13px;
  font-weight: 600;
  line-height: 1.2;
}

.toast-body {
  font-size: 12px;
  color: var(--muted);
  line-height: 1.4;
  word-break: break-word;
}

.toast-meta {
  font-size: 11px;
  color: var(--muted);
}

@keyframes toastIn {
  from {
    opacity: 0;
    transform: translateY(-6px) scale(0.98);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

@keyframes toastOut {
  from {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
  to {
    opacity: 0;
    transform: translateY(-6px) scale(0.98);
  }
}

/* === themes.css === */
/* === v2 redesign themes — основные === */

/* === themes/bobrovaya-light.css === */
/* ==========================================================
   Бобровая светлая — основная тема.
   Применяется когда data-mode="light" или нет data-mode при
   светлой системной теме. Тёплый бежевый + орех/мех акценты.
   ========================================================== */

:root {
  --bg: #f4efe4;
  --bg-2: #efe7d8;
  --panel: #fffbf3;
  --panel-2: #f4ecdb;
  --stroke: rgba(42, 34, 24, 0.1);
  --text: #2a2218;
  --muted: #786558;
  --accent: #7a4b2a; /* тёмное дерево */
  --accent-2: #c97a4b; /* мех — для совместимости со старыми селекторами */
  --highlight: #c97a4b; /* активные элементы (link, status warn) */
  --bubble-out-bg: color-mix(in srgb, var(--accent) 22%, var(--panel-2));
  --accent-contrast: #fffbf3;
  --danger: #9c2a2a;
  --success: #5c7a2e;
  --link: var(--accent);
  --status-offline: #9a8775;
  --status-good: #5c7a2e;
  --status-warn: #c97a4b;
  --status-bad: #9c2a2a;
  --overlay: rgba(42, 34, 24, 0.55);
  --shadow: 0 1px 2px rgba(42, 34, 24, 0.08), 0 4px 12px rgba(42, 34, 24, 0.06);

  /* Glass — минимальный, остался только для лайтбокса/видео-оверлея. */
  --glass-bg: color-mix(in srgb, var(--panel) 72%, transparent);
  --glass-stroke: color-mix(in srgb, var(--stroke) 50%, transparent);
  --glass-blur: blur(20px) saturate(1.15);
  --glass-shadow: 0 8px 24px rgba(42, 34, 24, 0.12), 0 1px 3px rgba(42, 34, 24, 0.06);
}

/* === themes/bobrovaya-dark.css === */
/* ==========================================================
   Бобровая тёмная — зеркало светлой.
   Применяется когда data-mode="dark" или нет data-mode при
   тёмной системной теме. Тёплый угольный + мех/зубы.
   ========================================================== */

:root[data-mode="dark"] {
  --bg: #1b1714;
  --bg-2: #221c18;
  --panel: #2a211a;
  --panel-2: #34281f;
  --stroke: rgba(237, 226, 208, 0.08);
  --text: #ede2d0;
  --muted: #9a8775;
  --accent: #c97a4b; /* мех — в темноте яркий */
  --accent-2: #e8b563; /* зубы — для совместимости */
  --highlight: #e8b563; /* активные элементы (link, status warn) */
  --bubble-out-bg: color-mix(in srgb, var(--accent) 40%, var(--panel-2));
  --accent-contrast: #1b1714;
  --danger: #e07070;
  --success: #95c76a;
  --link: var(--highlight);
  --status-offline: #786558;
  --status-good: #95c76a;
  --status-warn: #e8b563;
  --status-bad: #e07070;
  --overlay: rgba(15, 11, 8, 0.78);
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.28), 0 4px 12px rgba(0, 0, 0, 0.18);

  --glass-bg: color-mix(in srgb, var(--panel) 78%, transparent);
  --glass-stroke: color-mix(in srgb, var(--stroke) 80%, transparent);
  --glass-blur: blur(16px) saturate(1.05);
  --glass-shadow: 0 6px 18px rgba(0, 0, 0, 0.36);
}

/* Системная тёмная (без явно выбранного режима) */
@media (prefers-color-scheme: dark) {
  :root:not([data-mode]) {
    --bg: #1b1714;
    --bg-2: #221c18;
    --panel: #2a211a;
    --panel-2: #34281f;
    --stroke: rgba(237, 226, 208, 0.08);
    --text: #ede2d0;
    --muted: #9a8775;
    --accent: #c97a4b;
    --accent-2: #e8b563;
    --highlight: #e8b563;
    --bubble-out-bg: color-mix(in srgb, var(--accent) 40%, var(--panel-2));
    --accent-contrast: #1b1714;
    --danger: #e07070;
    --success: #95c76a;
    --link: var(--highlight);
    --status-offline: #786558;
    --status-good: #95c76a;
    --status-warn: #e8b563;
    --status-bad: #e07070;
    --overlay: rgba(15, 11, 8, 0.78);
    --shadow: 0 1px 2px rgba(0, 0, 0, 0.28), 0 4px 12px rgba(0, 0, 0, 0.18);

    --glass-bg: color-mix(in srgb, var(--panel) 78%, transparent);
    --glass-stroke: color-mix(in srgb, var(--stroke) 80%, transparent);
    --glass-blur: blur(16px) saturate(1.05);
    --glass-shadow: 0 6px 18px rgba(0, 0, 0, 0.36);
  }
}


/* === Эксперименты — селекторы [data-theme="8bit"] / [data-theme="terminal"]
   активируются только когда пользователь явно выбрал. Импорт безвреден. === */

/* === themes/_experiments/terminal.css === */
:root[data-theme="terminal"] {
  --bg: #0d0f0a;
  --bg-2: #0b0e08;
  --panel: #141a12;
  --panel-2: #1b2216;
  --stroke: rgba(255, 255, 255, 0.08);
  --text: #d7f5c8;
  --muted: #8da38a;
  --accent: #8fd16a;
  --accent-2: #62d196;
  --accent-contrast: #0b0f0a;
  --danger: #ff5f56;
  --success: #8fd16a;
  --link: var(--accent-2);
  --status-offline: #6f7f6e;
  --status-good: var(--success);
  --status-warn: #d5b24a;
  --status-bad: var(--danger);
  --overlay: rgba(5, 8, 4, 0.85);
  --shadow: 0 20px 55px rgba(0, 0, 0, 0.45);
}

:root[data-theme="terminal"][data-mode="light"] {
  --bg: #f4f9ef;
  --bg-2: #e6efe0;
  --panel: #ffffff;
  --panel-2: #e9f1e3;
  --stroke: rgba(27, 34, 26, 0.12);
  --text: #1b221a;
  --muted: #4e5b4c;
  --accent: #2f8f5b;
  --accent-2: #3cbfae;
  --accent-contrast: #f6fff2;
  --danger: #b54141;
  --success: #2f8f5b;
  --link: var(--accent-2);
  --status-offline: #6a7668;
  --status-good: var(--success);
  --status-warn: #c09635;
  --status-bad: var(--danger);
  --overlay: rgba(5, 8, 4, 0.6);
  --shadow: 0 20px 55px rgba(15, 20, 14, 0.18);
}

@media (prefers-color-scheme: light) {
  :root[data-theme="terminal"]:not([data-mode]) {
    --bg: #f4f9ef;
    --bg-2: #e6efe0;
    --panel: #ffffff;
    --panel-2: #e9f1e3;
    --stroke: rgba(27, 34, 26, 0.12);
    --text: #1b221a;
    --muted: #4e5b4c;
    --accent: #2f8f5b;
    --accent-2: #3cbfae;
    --accent-contrast: #f6fff2;
    --danger: #b54141;
    --success: #2f8f5b;
    --link: var(--accent-2);
    --status-offline: #6a7668;
    --status-good: var(--success);
    --status-warn: #c09635;
    --status-bad: var(--danger);
    --overlay: rgba(5, 8, 4, 0.6);
    --shadow: 0 20px 55px rgba(15, 20, 14, 0.18);
  }
}

/* === themes/_experiments/8bit.css === */
/* 8-Bit Theme Implementation */
:root[data-theme="8bit"] {
  --bg: #000000;
  --panel: #000000;
  --panel-2: #0a0a0a;
  --surface: #000000;
  --stroke: #00ff00;
  --text: #00ff00;
  --muted: #008f00;
  --accent: #00ff00;
  --accent-2: #00ff00;
  --danger: #ff0000;
  --warning: #ffff00;
  --success: #00ff00;
  --overlay: rgba(0, 20, 0, 0.9);
  --shadow: 6px 6px 0px var(--muted);

  --font-main: "Courier New", Courier, monospace;
  --anim-fast: 0s;
  --anim-med: 0s;
  --anim-slow: 0s;
}

/* Light Mode (Paper Style) */
:root[data-theme="8bit"][data-mode="light"] {
  --bg: #ffffff;
  --panel: #ffffff;
  --panel-2: #f0f0f0;
  --surface: #ffffff;
  --stroke: #000000;
  --text: #000000;
  --muted: #666666;
  --accent: #000000;
  --accent-2: #333333;
  --danger: #ff0000;
  --warning: #ffa500;
  --success: #00aa00;
  --overlay: rgba(255, 255, 255, 0.9);
  --shadow: 6px 6px 0px #999;
}

/* Scanlines Effect (Green for dark, Grey for light) */
:root[data-theme="8bit"] body::after {
  content: " ";
  display: block;
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  background:
    linear-gradient(rgba(18, 16, 16, 0) 50%, rgba(0, 0, 0, 0.25) 50%),
    linear-gradient(90deg, rgba(255, 0, 0, 0.06), rgba(0, 255, 0, 0.02), rgba(0, 0, 255, 0.06));
  z-index: 9999;
  background-size:
    100% 2px,
    3px 100%;
  pointer-events: none;
  mix-blend-mode: normal;
  opacity: 0.4;
}

:root[data-theme="8bit"][data-mode="light"] body::after {
  background: linear-gradient(rgba(255, 255, 255, 0) 50%, rgba(0, 0, 0, 0.1) 50%);
  background-size: 100% 3px;
  opacity: 0.15;
}

/* Force everything to be sharp and pixelated */
:root[data-theme="8bit"] * {
  border-radius: 0 !important;
  box-shadow: none;
  text-transform: uppercase;
  letter-spacing: 1px;
  font-weight: bold;
}

/* Thick borders for that NES feel */
:root[data-theme="8bit"] .modal-card,
:root[data-theme="8bit"] .button,
:root[data-theme="8bit"] .user-menu-dropdown,
:root[data-theme="8bit"] .context-menu,
:root[data-theme="8bit"] .message,
:root[data-theme="8bit"] input,
:root[data-theme="8bit"] textarea,
:root[data-theme="8bit"] .toggle input {
  border: 4px solid var(--stroke) !important;
  box-shadow: 6px 6px 0px var(--shadow) !important;
}

:root[data-theme="8bit"] .button:active {
  transform: translate(4px, 4px);
  box-shadow: 2px 2px 0px var(--shadow) !important;
}

:root[data-theme="8bit"] input,
:root[data-theme="8bit"] textarea,
:root[data-theme="8bit"] select {
  font-family: var(--font-main);
  font-size: 12px !important;
  background: var(--bg) !important;
  color: var(--text) !important;
}

:root[data-theme="8bit"] input:focus,
:root[data-theme="8bit"] textarea:focus {
  border-color: var(--text) !important;
  box-shadow: 6px 6px 0px var(--text) !important;
}

/* Make avatars pixelated and monochrome */
:root[data-theme="8bit"] .avatar,
:root[data-theme="8bit"] img,
:root[data-theme="8bit"] video {
  image-rendering: pixelated;
  filter: grayscale(100%) contrast(1.5) brightness(1.2);
  border: 4px solid var(--stroke);
}

:root[data-theme="8bit"] .message-bubble {
  border-width: 4px;
}

:root[data-theme="8bit"] ::-webkit-scrollbar {
  width: 16px;
  background: var(--bg);
}

:root[data-theme="8bit"] ::-webkit-scrollbar-thumb {
  background: var(--stroke);
  border: 4px solid var(--bg);
}

:root[data-theme="8bit"] .chat-item.active {
  background: var(--stroke) !important;
  color: var(--bg) !important;
}

:root[data-theme="8bit"] .chat-item.active * {
  color: var(--bg) !important;
  border-color: var(--bg) !important;
}

/* Remove glow effects */
:root[data-theme="8bit"] .message-highlight {
  animation: none;
  background: var(--muted);
}

/* Custom Toggle for 8bit */
:root[data-theme="8bit"] .toggle input {
  border-radius: 0 !important;
  background: var(--bg);
}

:root[data-theme="8bit"] .toggle input::after {
  border-radius: 0 !important;
  background: var(--stroke);
  box-shadow: none !important;
  width: 14px;
  height: 14px;
  top: 1px;
  left: 1px;
}

:root[data-theme="8bit"] .toggle input:checked {
  background: var(--bg);
}

:root[data-theme="8bit"] .toggle input:checked::after {
  background: var(--text);
  transform: translateX(20px);
}


:root[data-theme]:not([data-theme="default"]) body {
  background: var(--bg);
}

:root[data-theme]:not([data-theme="default"]) body::before,
:root[data-theme]:not([data-theme="default"]) body::after {
  display: none;
}

/* === animations.css === */
:root {
  --ease-out: cubic-bezier(0.22, 0.61, 0.36, 1);
  --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
  --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
  --ease-smooth: cubic-bezier(0.25, 0.1, 0.25, 1);
  --anim-fast: 180ms;
  --anim-med: 260ms;
  --anim-slow: 380ms;
}

@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
    scroll-behavior: auto !important;
  }
}

@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@keyframes modalIn {
  from {
    opacity: 0;
    transform: translateY(10px) scale(0.98);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

@keyframes menuIn {
  from {
    opacity: 0;
    transform: translateY(6px) scaleY(0.9);
  }
  to {
    opacity: 1;
    transform: translateY(0) scaleY(1);
  }
}

@keyframes menuOut {
  from {
    opacity: 1;
    transform: translateY(0) scaleY(1);
  }
  to {
    opacity: 0;
    transform: translateY(6px) scaleY(0.92);
  }
}

@keyframes bannerIn {
  from {
    opacity: 0;
    transform: translateY(-6px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes messagePop {
  0% {
    opacity: 0;
    transform: translateY(12px) scale(0.97);
  }
  60% {
    opacity: 1;
    transform: translateY(-3px) scale(1.01);
  }
  80% {
    transform: translateY(1px) scale(1);
  }
  100% {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

@keyframes messageSlideIn {
  from {
    opacity: 0;
    transform: translateX(-16px);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}

@keyframes chatPanelEnter {
  from {
    opacity: 0;
    transform: translateX(15px);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}

@keyframes chatPanelExit {
  from {
    opacity: 1;
    transform: translateX(0);
  }
  to {
    opacity: 0;
    transform: translateX(-15px);
  }
}

.chat-panel-enter {
  animation: chatPanelEnter 0.25s cubic-bezier(0.2, 0, 0.2, 1) forwards;
}

.chat-panel-exit {
  animation: chatPanelExit 0.2s cubic-bezier(0.4, 0, 1, 1) forwards;
}

@keyframes messageSlideInOwn {
  from {
    opacity: 0;
    transform: translateX(16px);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}

@keyframes statusPop {
  from {
    opacity: 0.4;
    transform: scale(0.9);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

@keyframes tileIn {
  from {
    opacity: 0;
    transform: scale(0.98);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

@keyframes mediaIn {
  from {
    opacity: 0;
    transform: scale(0.98);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

@keyframes modalOut {
  from {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
  to {
    opacity: 0;
    transform: translateY(12px) scale(0.98);
  }
}

@keyframes fadeOut {
  from {
    opacity: 1;
  }
  to {
    opacity: 0;
  }
}

.modal:not([hidden]) .modal-card {
  animation: modalIn var(--anim-med) var(--ease-out);
}

.modal:not([hidden]) .modal-backdrop {
  animation: fadeIn var(--anim-med) var(--ease-out);
}

.call-modal:not([hidden]) .call-card {
  animation: modalIn var(--anim-med) var(--ease-out);
}

.call-modal.is-leaving .call-card {
  animation: modalOut var(--anim-med) var(--ease-in-out);
}

.user-menu-dropdown:not([hidden]) {
  transform-origin: bottom center;
  animation: menuFadeIn 0.2s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}

.user-menu-dropdown.is-closing {
  transform-origin: bottom center;
  animation: menuFadeOut 0.15s ease-in forwards;
  pointer-events: none;
}

.message.message-enter {
  animation: messageSlideIn var(--anim-med) var(--ease-out);
  will-change: transform, opacity;
}

.message.message-enter.own {
  animation-name: messageSlideInOwn;
}

.status-icon.status-animate .icon {
  animation: statusPop var(--anim-fast) var(--ease-out);
}

.call-participant {
  --flip-x: 0px;
  --flip-y: 0px;
  --tile-scale: 1;
  animation: tileIn var(--anim-med) var(--ease-out);
  transform: translate(var(--flip-x), var(--flip-y)) scale(var(--tile-scale));
  transition:
    transform var(--anim-slow) var(--ease-smooth),
    opacity var(--anim-med) var(--ease-out),
    box-shadow var(--anim-med) var(--ease-smooth),
    left var(--anim-slow) var(--ease-smooth),
    top var(--anim-slow) var(--ease-smooth),
    right var(--anim-slow) var(--ease-smooth),
    bottom var(--anim-slow) var(--ease-smooth),
    width var(--anim-slow) var(--ease-smooth),
    height var(--anim-slow) var(--ease-smooth);
  will-change: transform, opacity;
}

.call-participant.is-focus {
  box-shadow: 0 20px 48px color-mix(in srgb, var(--bg) 65%, transparent);
  --tile-scale: 1.005;
}

.call-participant.is-thumb {
  opacity: 0.94;
  --tile-scale: 0.97;
}

.call-incoming {
  animation: fadeIn var(--anim-med) var(--ease-out);
}

.lightbox {
  animation: fadeIn var(--anim-med) var(--ease-out);
}

.lightbox img,
.lightbox video {
  animation: mediaIn var(--anim-fast) var(--ease-out);
}

.dropdown-item,
.icon-button,
.button,
.call-control,
.message-action {
  transition:
    transform var(--anim-fast) var(--ease-spring),
    box-shadow var(--anim-fast) var(--ease-out),
    border-color var(--anim-fast) var(--ease-out),
    background var(--anim-fast) var(--ease-out);
}

.dropdown-item:active,
.icon-button:active,
.button:active,
.call-control:active,
.message-action:active {
  transform: scale(0.95);
  transition-duration: 80ms;
}

@keyframes buttonBounce {
  0% {
    transform: scale(1);
  }
  40% {
    transform: scale(0.94);
  }
  60% {
    transform: scale(1.02);
  }
  100% {
    transform: scale(1);
  }
}

.button.is-bouncing,
.icon-button.is-bouncing {
  animation: buttonBounce 320ms var(--ease-out);
}

@keyframes shimmer {
  0% {
    background-position: -200% 0;
  }
  100% {
    background-position: 200% 0;
  }
}

.skeleton {
  background: linear-gradient(
    90deg,
    color-mix(in srgb, var(--panel-2) 100%, transparent) 25%,
    color-mix(in srgb, var(--stroke) 60%, var(--panel-2)) 50%,
    color-mix(in srgb, var(--panel-2) 100%, transparent) 75%
  );
  background-size: 200% 100%;
  animation: shimmer 1.5s infinite linear;
  border-radius: 8px;
}

.skeleton-text {
  height: 14px;
  border-radius: 6px;
}

.skeleton-avatar {
  width: 40px;
  height: 40px;
  border-radius: 12px;
  flex-shrink: 0;
}

.skeleton-line {
  height: 12px;
  border-radius: 4px;
}

.skeleton-chat {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
}

.skeleton-chat-content {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.skeleton-chat-content .skeleton-line:first-child {
  width: 60%;
}

.skeleton-chat-content .skeleton-line:last-child {
  width: 40%;
}

.skeleton-media {
  aspect-ratio: 16 / 9;
  border-radius: 12px;
}

.modal-card {
  transition: height var(--anim-slow) var(--ease-smooth);
}

@keyframes bobr-fall {
  0% {
    transform: translateY(-100px) rotate(var(--start-rot)) scale(var(--scale));
    opacity: 0;
  }
  10% {
    opacity: 1;
  }
  90% {
    opacity: 1;
  }
  100% {
    transform: translateY(calc(100vh + 100px)) rotate(var(--end-rot)) scale(var(--scale));
    opacity: 0;
  }
}

.bobropad-container {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 20000;
  overflow: hidden;
}

.bobropad-beaver {
  position: absolute;
  top: -100px;
  width: 64px;
  height: 64px;
  background-size: contain;
  background-repeat: no-repeat;
  will-change: transform, opacity;
  animation: bobr-fall var(--duration) linear forwards;
}

/* === layout.css === */

/* === layout-core/titlebar.css === */
.title-bar {
  height: 32px;
  background: var(--panel);
  border-bottom: 1px solid var(--stroke);
  display: flex;
  align-items: center;
  justify-content: space-between;
  user-select: none;
  z-index: 10000;
  position: relative;
  flex-shrink: 0;
}

.title-bar-drag {
  flex: 1;
  height: 100%;
  display: flex;
  align-items: center;
  padding: 0 14px;
}

.title-bar-icon {
  width: 18px;
  height: 18px;
  margin-right: 10px;
  cursor: default;
}

@keyframes bobr-wiggle {
  0% {
    transform: scale(1.1) rotate(0deg);
  }
  25% {
    transform: scale(1.1) rotate(-8deg);
  }
  75% {
    transform: scale(1.1) rotate(8deg);
  }
  100% {
    transform: scale(1.1) rotate(0deg);
  }
}

/* :hover работает только если иконка вне drag-региона */
.title-bar-icon:hover {
  animation: bobr-wiggle 0.18s infinite ease-in-out;
}

.title-bar-text {
  font-size: 12px;
  font-weight: 700;
  color: color-mix(in srgb, var(--text) 70%, transparent);
  font-family: "IBM Plex Sans", system-ui, sans-serif;
  letter-spacing: -0.01em;
}

.title-bar-actions {
  display: flex;
  height: 100%;
}

.title-bar-button {
  width: 46px;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: none;
  color: var(--text);
  cursor: default;
  transition:
    background 0.12s ease-out,
    color 0.12s ease-out;
}

.title-bar-button:hover {
  background: color-mix(in srgb, var(--text) 8%, transparent);
}

.title-bar-button-close:hover {
  background: #e81123;
  color: white;
}

/* === layout-core/sidebar.css === */
.app-shell {
  display: grid;
  grid-template-columns: var(--sidebar-width, 300px) 18px minmax(0, 1fr);
  padding: var(--space-2);
  height: 100vh;
  min-height: 100svh;
  height: 100dvh;
  overflow: hidden;
}

body.is-desktop .app-shell {
  height: calc(100vh - 32px);
  min-height: calc(100svh - 32px);
  height: calc(100dvh - 32px);
}

.sidebar {
  background: var(--panel);
  border: none;
  border-right: 1px solid var(--stroke);
  border-radius: 0;
  box-shadow: none;
  padding: var(--space-4) 0; /* Только вертикальные паддинги */
  display: flex;
  flex-direction: column;
  min-height: 0;
  min-width: 0;
  position: relative; /* anchor для .sidebar-fab */
}

.sidebar-top-row,
.folder-strip,
.sidebar-logo {
  padding-left: var(--space-4);
  padding-right: var(--space-4);
}

.sidebar-logo {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  width: 100%;
  margin-bottom: var(--space-3);
  padding-top: 4px;
  padding-bottom: 4px;
  background: transparent;
  border: none;
  cursor: pointer;
  color: var(--text);
  text-align: left;
  border-radius: var(--radius-sm);
  transition:
    background var(--anim-fast) var(--ease-out),
    transform var(--anim-fast) var(--ease-out);
}

.sidebar-logo:hover {
  background: color-mix(in srgb, var(--accent) 8%, transparent);
}

.sidebar-logo:hover .sidebar-logo-img {
  transform: rotate(-6deg) scale(1.06);
}

.sidebar-logo:active {
  transform: scale(0.98);
}

.sidebar-logo-img {
  width: 32px;
  height: 32px;
  flex-shrink: 0;
  object-fit: contain;
  user-select: none;
  -webkit-user-drag: none;
  transition: transform var(--anim-fast) var(--ease-out);
}

/* Wordmark — heavier weight, tighter tracking, slight color emphasis on the
   accent half so the name reads as a brand mark rather than a body label. */
.sidebar-logo-text {
  font-weight: 800;
  font-size: 20px;
  letter-spacing: -0.02em;
  line-height: 1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-feature-settings: "ss01", "cv11";
}

.sidebar-logo-text .wordmark-accent {
  color: var(--accent);
}

.folder-strip {
  margin-bottom: var(--space-3);
}

/* === Top row: avatar chip + search === */
.sidebar-top-row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
  position: relative; /* anchor для .user-menu-dropdown */
}

.avatar-chip {
  position: relative;
  flex-shrink: 0;
  width: 36px;
  height: 36px;
  padding: 0;
  border: none;
  background: transparent;
  cursor: pointer;
  border-radius: var(--radius-sm);
  transition: transform var(--anim-fast) var(--ease-out);
}

.avatar-chip:hover {
  transform: scale(1.05);
}

.avatar-chip:active {
  transform: scale(0.96);
}

.avatar-chip-avatar {
  width: 36px;
  height: 36px;
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
}

.avatar-chip-status {
  position: absolute;
  right: -2px;
  bottom: -2px;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: var(--status-good);
  border: 2px solid var(--panel);
  pointer-events: none;
  transition: background 0.2s ease;
}

.avatar-chip-status[data-status="away"] {
  background: var(--status-warn);
}

.avatar-chip-status[data-status="dnd"] {
  background: var(--status-bad);
}

.search-wrap {
  position: relative;
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: 0 var(--space-3);
  border-radius: var(--radius-sm);
  border: 1px solid var(--stroke);
  background: var(--panel-2);
  transition:
    border-color var(--anim-fast) var(--ease-out),
    box-shadow var(--anim-fast) var(--ease-out),
    background-color var(--anim-fast) var(--ease-out);
}

.search-wrap::after {
  content: "Ctrl+K";
  position: absolute;
  right: 8px;
  top: 50%;
  transform: translateY(-50%);
  font-family: var(--font-mono);
  font-size: 10px;
  line-height: 1;
  color: var(--muted);
  background: var(--panel);
  border: 1px solid color-mix(in srgb, var(--stroke) 60%, transparent);
  border-radius: var(--radius-sm);
  padding: 3px 6px;
  pointer-events: none;
  opacity: 0.85;
  transition: opacity var(--anim-fast) var(--ease-out);
}

.search-wrap:focus-within::after {
  opacity: 0;
}

@media (max-width: 720px) {
  .search-wrap::after {
    display: none;
  }
}

.search-wrap .search-icon {
  --icon-size: 14px;
  color: var(--muted);
  flex-shrink: 0;
}

.search-wrap:focus-within {
  border-color: color-mix(in srgb, var(--accent) 50%, transparent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent);
  background: var(--panel);
}

.search-wrap:focus-within .search-icon {
  color: var(--accent);
}

/* === Sidebar FAB (новый чат / группа) === */
.sidebar-fab {
  position: absolute;
  bottom: var(--space-4);
  right: var(--space-4);
  width: 48px;
  height: 48px;
  border-radius: 50%;
  border: none;
  background: var(--accent);
  color: var(--accent-contrast);
  cursor: pointer;
  display: grid;
  place-items: center;
  box-shadow:
    0 8px 24px color-mix(in srgb, var(--accent) 30%, transparent),
    0 2px 6px rgba(0, 0, 0, 0.12);
  transition:
    transform var(--anim-fast) var(--ease-out),
    bottom var(--anim-med) var(--ease-out),
    box-shadow var(--anim-fast) var(--ease-out),
    filter var(--anim-fast) var(--ease-out);
  z-index: var(--z-fab);
}

.sidebar-fab .icon {
  --icon-size: 20px;
  transition: transform var(--anim-med) var(--ease-out);
}

.sidebar-fab:hover {
  transform: scale(1.05);
  box-shadow:
    0 10px 28px color-mix(in srgb, var(--accent) 38%, transparent),
    0 3px 8px rgba(0, 0, 0, 0.16);
  filter: brightness(1.05);
}

.sidebar-fab:active {
  transform: scale(0.95);
}

.sidebar-fab.is-open .icon {
  transform: rotate(45deg);
}

/* Label + kbd hint — рендерятся только под v2 (см. блок ниже).
   В v1 FAB круглый и иконочный, поэтому скрываем. */
.sidebar-fab-label,
.sidebar-fab-kbd {
  display: none;
}

.sidebar-fab-menu {
  position: absolute;
  bottom: calc(var(--space-4) + 48px + var(--space-2));
  right: var(--space-4);
  min-width: 200px;
  background: var(--panel);
  border: 1px solid var(--stroke);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow);
  padding: var(--space-1);
  display: flex;
  flex-direction: column;
  gap: 2px;
  z-index: var(--z-fab);
  animation: menuIn var(--anim-fast) var(--ease-spring);
  transform-origin: bottom right;
}

.sidebar-fab-menu[hidden] {
  display: none;
}

/* === User menu dropdown — позиционирование под avatar-chip === */
.sidebar-top-row .user-menu-dropdown {
  position: absolute;
  top: calc(100% + var(--space-2));
  bottom: auto;
  left: 0;
  right: auto;
  min-width: 264px;
  z-index: var(--z-dropdown);
}

/* === User menu — identity header (avatar + name/handle + bio + chevron) === */
.user-menu-identity {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3);
  margin-bottom: 4px;
  border-radius: var(--radius-sm);
  text-decoration: none;
  color: inherit;
  transition: background var(--anim-fast) var(--ease-out);
}

.user-menu-identity:hover {
  background: color-mix(in srgb, var(--accent) 12%, transparent);
}

.user-menu-card-avatar {
  width: 44px;
  height: 44px;
  flex: none;
  border-radius: var(--radius-sm);
  overflow: hidden;
}

.user-menu-card-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.user-menu-card-text {
  flex: 1;
  min-width: 0;
}

.user-menu-card-name-row {
  display: flex;
  align-items: baseline;
  gap: 6px;
  min-width: 0;
}

.user-menu-card-name {
  min-width: 0;
  font-weight: 700;
  font-size: var(--text-sm);
  color: var(--text);
  letter-spacing: -0.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.user-menu-card-handle {
  flex: none;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--muted);
  white-space: nowrap;
}

.user-menu-card-bio {
  margin-top: 2px;
  font-size: var(--text-xs);
  color: var(--muted);
  line-height: 1.35;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.user-menu-card-chevron {
  --icon-size: 16px;
  flex: none;
  color: var(--muted);
  transition:
    transform var(--anim-fast) var(--ease-out),
    color var(--anim-fast) var(--ease-out);
}

.user-menu-identity:hover .user-menu-card-chevron {
  transform: translateX(2px);
  color: var(--text);
}

/* Primary items group + divider before "Все настройки" */
.user-menu-section {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.user-menu-divider {
  height: 1px;
  margin: 4px 6px;
  background: color-mix(in srgb, var(--stroke) 70%, transparent);
}

/* === Status block: picker (flies out sideways) + custom-status card === */
.user-menu-status-block {
  padding: 0 6px 4px;
}

.user-menu-section-label {
  padding: 6px 6px 4px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}

.status-dot {
  width: 10px;
  height: 10px;
  flex: none;
  border-radius: 50%;
  background: var(--status-good);
}

.status-dot[data-status="away"] {
  background: var(--status-warn);
}

.status-dot[data-status="dnd"] {
  background: var(--status-bad);
}

.status-field {
  position: relative;
}

.status-field-current {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: 8px 10px;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: var(--panel-2);
  cursor: pointer;
  transition:
    background var(--anim-fast) var(--ease-out),
    border-color var(--anim-fast) var(--ease-out);
}

.status-field-current:hover {
  background: color-mix(in srgb, var(--accent) 10%, var(--panel-2));
}

.status-field-current:focus-visible {
  outline: none;
  border-color: var(--accent);
}

.status-current-label {
  flex: 1;
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--text);
}

.status-field-caret {
  --icon-size: 15px;
  flex: none;
  color: var(--muted);
  transition: transform var(--anim-fast) var(--ease-out);
}

.status-field:hover .status-field-caret,
.status-field.is-open .status-field-caret {
  transform: translateX(2px);
  color: var(--text);
}

/* Flyout opens to the side of the popover. The invisible ::before bridges the
   visual gap so the hover region stays contiguous between row and flyout. */
.status-flyout {
  position: absolute;
  left: calc(100% + 8px);
  top: 0;
  min-width: 188px;
  padding: 6px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  border: 1px solid var(--stroke);
  border-radius: var(--radius-md, 12px);
  background: var(--panel);
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.22);
  opacity: 0;
  transform: translateX(-8px) scale(0.97);
  transform-origin: left center;
  pointer-events: none;
  transition:
    opacity var(--anim-fast) var(--ease-out),
    transform var(--anim-fast) var(--ease-out);
  z-index: calc(var(--z-dropdown) + 1);
}

.status-flyout::before {
  content: "";
  position: absolute;
  left: -10px;
  top: 0;
  bottom: 0;
  width: 10px;
}

.status-field:hover > .status-flyout,
.status-field:focus-within > .status-flyout,
.status-field.is-open > .status-flyout,
.status-flyout:hover {
  opacity: 1;
  transform: translateX(0) scale(1);
  pointer-events: auto;
}

.status-option {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: 8px 10px;
  border: none;
  border-radius: var(--radius-sm);
  background: none;
  color: var(--text);
  font-size: var(--text-sm);
  text-align: left;
  cursor: pointer;
  transition: background var(--anim-fast) var(--ease-out);
}

.status-option:hover {
  background: color-mix(in srgb, var(--accent) 12%, transparent);
}

.status-option-label {
  flex: 1;
}

.status-option-check {
  --icon-size: 15px;
  flex: none;
  color: var(--accent);
  opacity: 0;
}

.status-option.is-active .status-option-check {
  opacity: 1;
}

.custom-status-card {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  width: 100%;
  margin-top: 6px;
  padding: 8px 10px;
  border: 1px solid var(--stroke);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--accent) 6%, var(--panel-2));
  text-align: left;
  cursor: pointer;
  transition: background var(--anim-fast) var(--ease-out);
}

.custom-status-card:hover {
  background: color-mix(in srgb, var(--accent) 12%, var(--panel-2));
}

.custom-status-card.is-empty {
  border-left-color: var(--stroke);
  background: var(--panel-2);
}

.custom-status-emoji {
  flex: none;
  font-size: 18px;
  line-height: 1;
}

.custom-status-info {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.custom-status-text {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.custom-status-card.is-empty .custom-status-text {
  font-weight: 500;
  color: var(--muted);
}

.custom-status-sub {
  font-size: var(--text-xs);
  color: var(--muted);
}

.custom-status-edit {
  --icon-size: 15px;
  flex: none;
  color: var(--muted);
}

.custom-status-editor {
  display: flex;
  flex-direction: column;
  gap: 9px;
  margin-top: 6px;
  padding: 10px;
  border: 1px solid var(--stroke);
  border-radius: var(--radius-md, 12px);
  background: var(--panel-2);
  /* Unfold animation each time the editor is shown — the "раскрытие окна". */
  transform-origin: top center;
  animation: cseReveal 0.22s cubic-bezier(0.16, 1, 0.3, 1);
}

.custom-status-editor[hidden] {
  display: none;
}

@keyframes cseReveal {
  from {
    opacity: 0;
    transform: translateY(-8px) scale(0.98);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

/* Input row: emoji trigger on the left, free-text field on the right. */
.cse-input-row {
  display: flex;
  align-items: stretch;
  gap: 6px;
}

.cse-emoji-trigger {
  flex: none;
  width: 38px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--stroke);
  border-radius: var(--radius-sm);
  background: var(--panel);
  cursor: pointer;
  transition:
    border-color var(--anim-fast) var(--ease-out),
    background var(--anim-fast) var(--ease-out);
}

.cse-emoji-trigger:hover {
  border-color: color-mix(in srgb, var(--accent) 55%, var(--stroke));
}

.cse-emoji-trigger[aria-expanded="true"] {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 12%, var(--panel));
}

.cse-emoji-trigger-glyph {
  font-size: 18px;
  line-height: 1;
}

.cse-emoji-trigger.is-placeholder .cse-emoji-trigger-glyph {
  opacity: 0.4;
  filter: grayscale(0.5);
}

.cse-text {
  flex: 1;
  min-width: 0;
  padding: 8px 10px;
  border: 1px solid var(--stroke);
  border-radius: var(--radius-sm);
  background: var(--panel);
  color: var(--text);
  font-size: var(--text-sm);
}

.cse-text:focus {
  outline: none;
  border-color: var(--accent);
}

/* Collapsible emoji picker: grid-rows 0fr→1fr drives a clean height transition.
   The inner wrapper carries the overflow clip so a single track collapses. */
.cse-emoji-picker {
  display: grid;
  grid-template-rows: 0fr;
  opacity: 0;
  transition:
    grid-template-rows 0.22s var(--ease-out),
    opacity 0.18s var(--ease-out);
}

.cse-emoji-picker.is-open {
  grid-template-rows: 1fr;
  opacity: 1;
}

.cse-emoji-picker-inner {
  min-height: 0;
  overflow: hidden;
}

.cse-emoji-grid {
  max-height: 172px;
  overflow-y: auto;
  padding-right: 2px;
}

.cse-emoji-cat {
  position: sticky;
  top: 0;
  padding: 5px 2px 3px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  background: var(--panel-2);
}

.cse-emoji-cat-grid {
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  gap: 2px;
  margin-bottom: 4px;
}

.cse-emoji-cell {
  aspect-ratio: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: none;
  cursor: pointer;
  transition:
    background var(--anim-fast) var(--ease-out),
    transform var(--anim-fast) var(--ease-out);
}

.cse-emoji-cell:hover {
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  transform: scale(1.12);
}

.cse-emoji-cell.is-active {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 18%, transparent);
}

.cse-emoji-clear {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  align-self: flex-start;
  margin-top: 6px;
  padding: 4px 8px;
  --icon-size: 13px;
  border: none;
  border-radius: var(--radius-sm);
  background: none;
  color: var(--muted);
  font-size: var(--text-xs);
  cursor: pointer;
}

.cse-emoji-clear:hover {
  color: var(--text);
  background: color-mix(in srgb, var(--stroke) 40%, transparent);
}

/* Expiry: labeled segmented control — replaces the wrapping pill soup. */
.cse-expiry {
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.cse-expiry-label {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}

.cse-expiry-seg {
  display: flex;
  gap: 2px;
  padding: 3px;
  border: 1px solid var(--stroke);
  border-radius: 999px;
  background: var(--panel);
}

.cse-expiry-opt {
  flex: 1;
  padding: 5px 4px;
  border: none;
  border-radius: 999px;
  background: none;
  color: var(--muted);
  font-size: var(--text-xs);
  font-weight: 500;
  white-space: nowrap;
  cursor: pointer;
  transition:
    background var(--anim-fast) var(--ease-out),
    color var(--anim-fast) var(--ease-out);
}

.cse-expiry-opt:hover {
  color: var(--text);
}

.cse-expiry-opt.is-active {
  background: var(--accent);
  color: var(--accent-contrast);
  font-weight: 600;
}

.cse-actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 6px;
}

.cse-clear {
  margin-right: auto;
  padding: 4px;
  border: none;
  background: none;
  color: var(--status-bad);
  font-size: var(--text-xs);
  cursor: pointer;
}

.cse-save {
  padding: 7px 16px;
  border: none;
  border-radius: var(--radius-sm);
  background: var(--accent);
  color: var(--accent-contrast);
  font-weight: 600;
  font-size: var(--text-sm);
  cursor: pointer;
  transition: filter var(--anim-fast) var(--ease-out);
}

.cse-save:hover {
  filter: brightness(1.05);
}

/* "Все настройки" — trailing chevron pinned to the right edge */
.user-menu-allsettings .user-menu-trail {
  --icon-size: 14px;
  margin-left: auto;
  color: var(--muted);
}

/* Sidebar Resizer */
.sidebar-resizer {
  width: 14px;
  cursor: col-resize;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  transition: opacity 0.15s ease-out;
  opacity: 0;
  z-index: 10;
}

.sidebar-resizer::after {
  content: "";
  width: 4px;
  height: 60px;
  background: var(--stroke);
  border-radius: 4px;
  transition: all 0.15s ease-out;
}

.sidebar-resizer:hover,
.sidebar-resizer.is-dragging {
  opacity: 1;
}

.sidebar-resizer:hover::after,
.sidebar-resizer.is-dragging::after {
  background: var(--accent);
}

/* Compact & Mini States */
.is-sidebar-compact .chat-preview,
.is-sidebar-compact .chat-time,
.is-sidebar-compact .chat-name {
  opacity: 0;
  visibility: hidden;
  width: 0;
  height: 0;
  margin: 0;
  padding: 0;
  pointer-events: none;
}

.is-sidebar-compact .sidebar-logo-text {
  opacity: 0;
  visibility: hidden;
  width: 0;
  margin: 0;
  pointer-events: none;
}

/* === Compact mode: spacious version with full search but tight padding === */
.is-sidebar-compact .sidebar-top-row,
.is-sidebar-compact .sidebar-logo {
  padding-left: var(--space-2);
  padding-right: var(--space-2);
}

.is-sidebar-compact .folder-strip {
  padding-left: var(--space-2);
  padding-right: var(--space-2);
}

/* === Mini mode: only the avatar-chip + chat avatars stack vertically === */
.is-sidebar-mini .search-wrap,
.is-sidebar-mini .folder-strip,
.is-sidebar-mini .chat-meta,
.is-sidebar-mini .sidebar-fab-menu {
  display: none !important;
}

.is-sidebar-mini .sidebar {
  padding: var(--space-5) 0;
  align-items: center;
}

.is-sidebar-mini .sidebar-top-row {
  padding: 0;
  margin-bottom: var(--space-4);
  justify-content: center;
}

.is-sidebar-mini .sidebar-logo {
  padding: 0;
  justify-content: center;
  margin-bottom: var(--space-3);
}

.is-sidebar-mini .sidebar-logo-text {
  display: none;
}

.is-sidebar-mini .sidebar-logo-img {
  width: 36px;
  height: 36px;
}

.is-sidebar-mini .avatar-chip,
.is-sidebar-mini .avatar-chip-avatar {
  width: 44px;
  height: 44px;
}

.is-sidebar-mini .avatar-chip-avatar {
  font-size: var(--text-md);
}

.is-sidebar-mini .sidebar-top-row .user-menu-dropdown {
  left: 50%;
  transform: translateX(-50%);
  min-width: 200px;
}

.is-sidebar-mini .chat-list {
  padding: 0;
  margin-top: var(--space-3);
  align-items: center;
  align-self: stretch;
  scrollbar-width: none;
}

.is-sidebar-mini .chat-list::-webkit-scrollbar {
  display: none;
}

.is-sidebar-mini .chat-item {
  width: 48px;
  height: 48px;
  min-width: 48px;
  min-height: 48px;
  padding: 0;
  margin: 0 auto var(--space-2);
  justify-content: center;
  border: none;
  background: transparent;
  border-radius: var(--radius-md);
}

.is-sidebar-mini .chat-item:hover {
  transform: scale(1.1);
  background: color-mix(in srgb, var(--accent) 10%, transparent);
}

.is-sidebar-mini .chat-item .avatar {
  margin: 0;
  width: 48px;
  height: 48px;
  min-width: 48px;
  min-height: 48px;
  flex-shrink: 0;
  border-radius: var(--radius-md);
}

.is-sidebar-mini .sidebar-fab {
  position: relative;
  bottom: auto;
  right: auto;
  margin: var(--space-3) auto 0;
}

/* Hardcoded hide of search row when ultra-narrow (replaces removed JS hack) */
.is-sidebar-mini .sidebar-top-row {
  gap: 0;
}

/* === Search input — clean inside .search-wrap (no border/bg of its own) === */
.user-search {
  flex: 1;
  min-width: 0;
  padding: 10px 0;
  border: none;
  outline: none;
  background: transparent;
  color: var(--text);
  font-size: var(--text-sm);
}

.user-search::placeholder {
  color: var(--muted);
}

/* === layout-core/sidebar-call-card.css === */
/* Sticky-карточка активного звонка в самом низу sidebar.
   Видна всегда пока юзер в звонке, независимо от текущего чата.
   FAB-кнопка (.sidebar-fab) лежит поверх правого нижнего угла — компенсируем padding-right. */

.sidebar-call-card {
  position: relative;
  margin: var(--space-2) var(--space-3) var(--space-3);
  padding: 10px;
  border-radius: var(--radius-md);
  border: 1px solid var(--stroke);
  background: var(--panel-2);
  display: flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
  transition:
    border-color var(--anim-med) var(--ease-out),
    background-color var(--anim-med) var(--ease-out),
    transform var(--anim-fast) var(--ease-out);
  flex-shrink: 0;
}

.sidebar-call-card:hover {
  background: color-mix(in srgb, var(--accent) 5%, var(--panel-2));
}

.sidebar-call-card:active {
  transform: scale(0.985);
}

.sidebar-call-card[data-quality="good"] {
  border-color: color-mix(in srgb, var(--status-good) 45%, var(--stroke));
}

.sidebar-call-card[data-quality="ok"] {
  border-color: var(--status-warn);
  background: color-mix(in srgb, var(--status-warn) 8%, var(--panel-2));
}

.sidebar-call-card[data-quality="bad"] {
  border-color: var(--status-bad);
  background: color-mix(in srgb, var(--status-bad) 14%, var(--panel-2));
  animation: sidebarCallBadPulse 1.6s ease-in-out infinite;
}

.sidebar-call-card[data-quality="offline"],
.sidebar-call-card[data-quality="reconnecting"] {
  border-color: var(--status-warn);
  background: color-mix(in srgb, var(--status-warn) 10%, var(--panel-2));
}

@keyframes sidebarCallBadPulse {
  0%,
  100% {
    border-color: var(--status-bad);
  }
  50% {
    border-color: color-mix(in srgb, var(--status-bad) 60%, transparent);
  }
}

.sidebar-call-card-avatars {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  flex-wrap: wrap;
  flex-shrink: 0;
}

.sidebar-call-card-avatar {
  position: relative;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: linear-gradient(
    145deg,
    color-mix(in srgb, var(--accent) 40%, transparent),
    color-mix(in srgb, var(--accent-2) 20%, transparent)
  );
  display: grid;
  place-items: center;
  font-weight: 600;
  font-size: 12px;
  color: var(--text);
  overflow: hidden;
  flex-shrink: 0;
  --speech-level: 0;
  transition: box-shadow 0.12s linear;
}

.sidebar-call-card-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.sidebar-call-card-avatar.is-self {
  outline: 2px solid color-mix(in srgb, var(--accent) 70%, transparent);
  outline-offset: 1px;
}

.sidebar-call-card-avatar.is-speaking {
  box-shadow:
    0 0 0 calc(1.5px + 2.5px * var(--speech-level, 0))
      color-mix(in srgb, var(--accent) calc(55% + 45% * var(--speech-level, 0)), transparent),
    0 0 calc(6px + 12px * var(--speech-level, 0))
      color-mix(in srgb, var(--accent) calc(25% + 30% * var(--speech-level, 0)), transparent);
}

.sidebar-call-card-avatar-more {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--text) 10%, transparent);
  display: grid;
  place-items: center;
  font-size: 11px;
  font-weight: 600;
  color: var(--muted);
  flex-shrink: 0;
}

.sidebar-call-card-info {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.sidebar-call-card-title {
  font-size: 12px;
  font-weight: 600;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.sidebar-call-card-subtitle {
  font-size: 11px;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.sidebar-call-card-controls {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  flex-shrink: 0;
  order: 3;
}

.sidebar-call-control {
  width: 28px;
  height: 28px;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  background: transparent;
  color: var(--text);
  cursor: pointer;
  display: grid;
  place-items: center;
  flex-shrink: 0;
  transition:
    background-color var(--anim-fast) var(--ease-out),
    color var(--anim-fast) var(--ease-out),
    transform 80ms var(--ease-out);
}

.sidebar-call-control .icon {
  --icon-size: 14px;
}

.sidebar-call-control:hover {
  background: color-mix(in srgb, var(--text) 10%, transparent);
}

.sidebar-call-control:active {
  transform: scale(0.92);
}

.sidebar-call-control.is-muted,
.sidebar-call-control.is-deafened {
  color: var(--danger);
}

.sidebar-call-control.is-muted:hover,
.sidebar-call-control.is-deafened:hover {
  background: color-mix(in srgb, var(--danger) 14%, transparent);
}

.sidebar-call-control.danger {
  color: var(--danger);
}

.sidebar-call-control.danger:hover {
  background: color-mix(in srgb, var(--danger) 18%, transparent);
}

/* ====== Compact mode для is-sidebar-mini ====== */

.is-sidebar-mini .sidebar-call-card {
  margin: var(--space-3) var(--space-2) calc(56px + var(--space-2));
  padding: var(--space-2);
  padding-right: var(--space-2);
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
}

.is-sidebar-mini .sidebar-call-card-avatars {
  flex-direction: column;
  align-items: center;
}

.is-sidebar-mini .sidebar-call-card-info {
  display: none;
}

.is-sidebar-mini .sidebar-call-card-controls {
  flex-direction: column;
}

.is-sidebar-mini .sidebar-call-control:not(.danger) {
  display: none;
}

.app-shell.has-active-call .sidebar-fab {
  bottom: calc(112px + var(--space-5));
}

.app-shell.has-active-call .chat-list::after {
  height: 128px;
}

.app-shell.is-sidebar-mini.has-active-call .sidebar-fab {
  position: relative;
  bottom: auto;
  right: auto;
}

/* Ping indicator sits inline on the right of the card, just before the call
   controls: a bare dot that reveals the ping value on hover; the history
   popover opens upward since the card is at the bottom of the sidebar. */
.sidebar-call-net {
  order: 2;
  flex-shrink: 0;
}

.sidebar-call-net .net-indicator {
  cursor: pointer;
  font-size: 11px;
}

.sidebar-call-net .net-text {
  max-width: 0;
  overflow: hidden;
  opacity: 0;
  white-space: nowrap;
  transition:
    max-width 0.2s ease,
    opacity 0.2s ease,
    margin 0.2s ease;
}

.sidebar-call-net:hover .net-text,
.sidebar-call-net .net-indicator:focus-visible .net-text {
  max-width: 120px;
  opacity: 1;
  margin-left: 6px;
}

.sidebar-call-net .net-popover {
  top: auto;
  bottom: calc(100% + 8px);
  left: auto;
  right: 0;
}

/* Collapsed icon-rail sidebar: ping/text would just clutter the mini card. */
.is-sidebar-mini .sidebar-call-net {
  display: none;
}

/* === layout-core/chat-header.css === */
.chat-panel {
  background: var(--panel);
  border: none;
  border-radius: 0;
  box-shadow: none;
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
  position: relative; /* Ensure absolute children (search island) are contained */
}

.chat-header {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  padding: 0 24px;
  height: 60px; /* Фиксированная высота для стабильности */
  min-height: 60px;
  border-bottom: 1px solid color-mix(in srgb, var(--stroke) 50%, transparent);
  background: var(--panel);
  flex: 0 0 auto;
  position: relative;
  /* overflow: hidden; -- УБРАЛИ, ЧТОБЫ МЕНЮ НЕ ОБРЕЗАЛОСЬ */
  transition: background-color 0.15s ease-out; /* ПЛАВНОЕ окрашивание фона */
}

.chat-header:hover {
  background-color: color-mix(in srgb, var(--accent) 4%, var(--panel));
}

.chat-header > * {
  position: relative;
  z-index: 1;
}

.chat-header.is-group,
.chat-header.is-direct {
  cursor: pointer;
}

.chat-panel.no-active-chat .chat-header,
.chat-panel.no-active-chat .composer,
.chat-panel.no-active-chat .floating-search-island,
.chat-panel.no-active-chat .chat-call-tiles,
.chat-panel.no-active-chat #call-modal {
  display: none !important;
}

.chat-panel.no-active-chat .messages {
  padding: 0;
}

/* Zen Empty State — beaver + speech bubble (rotation phrase via empty_state.js) */
.zen-empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  gap: var(--space-3);
  user-select: none;
  transition: opacity 0.5s ease;
}

.zen-logo {
  width: 110px;
  height: 110px;
  cursor: pointer;
  animation: bobrFloat 6s ease-in-out infinite alternate;
  transition: transform 120ms ease;
}

.zen-logo:active {
  transform: scale(0.94);
}

.zen-empty-text {
  display: none;
}

.zen-speech-bubble {
  display: inline-block;
  position: relative;
  margin: 0;
  padding: var(--space-3) var(--space-4);
  max-width: 320px;
  background: var(--panel);
  border: 1px solid var(--stroke);
  border-radius: var(--radius-md);
  font-size: 14px;
  line-height: 1.4;
  color: var(--text);
  box-shadow: var(--shadow);
  text-align: center;
}

/* Tail pointing up toward the beaver above. */
.zen-speech-bubble::before {
  content: "";
  position: absolute;
  top: -6px;
  left: 50%;
  width: 10px;
  height: 10px;
  background: var(--panel);
  border-top: 1px solid var(--stroke);
  border-left: 1px solid var(--stroke);
  transform: translateX(-50%) rotate(45deg);
}

@keyframes bobrFloat {
  from {
    transform: translateY(-4px);
  }
  to {
    transform: translateY(4px);
  }
}

.chat-dropdown {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  width: 200px;
  background: var(--panel);
  border: 1px solid var(--stroke);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow);
  padding: 8px;
  z-index: 100;
  display: flex;
  flex-direction: column;
  gap: 4px;
  animation: menu-pop 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275);
  transition: height 0.28s cubic-bezier(0.4, 0, 0.2, 1);
  will-change: height;
}

@keyframes menu-pop {
  from {
    transform: scale(0.9) translateY(-10px);
    opacity: 0;
  }
  to {
    transform: scale(1) translateY(0);
    opacity: 1;
  }
}

.chat-dropdown .dropdown-item.is-active {
  background: color-mix(in srgb, var(--accent) 16%, transparent);
}

.chat-mute-submenu {
  display: grid;
  gap: 4px;
  padding: 4px 0 2px 20px;
  border-left: 1px solid color-mix(in srgb, var(--stroke) 80%, transparent);
}

.chat-mute-submenu .submenu-item {
  font-size: 12px;
  padding-top: 7px;
  padding-bottom: 7px;
}

.chat-mute-submenu .submenu-item-forever {
  color: color-mix(in srgb, #ffb86b 82%, var(--text));
  font-weight: 600;
}

/* Floating Search Island */
.floating-search-island {
  position: absolute;
  top: 130px;
  left: 50%;
  transform: translateX(-50%);
  width: min(480px, 90%);
  background: var(--panel);
  border: 1px solid var(--stroke);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow);
  z-index: 90;
  overflow: hidden;
  display: flex;
  flex-direction: column;

  /* Animation & Stretching */
  opacity: 0;
  pointer-events: none;
  transform: translateX(-50%) translateY(-20px);
  transition:
    opacity 0.25s ease,
    transform 0.25s cubic-bezier(0.175, 0.885, 0.32, 1.275),
    height 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  will-change: transform, opacity;
}

.floating-search-island.is-visible {
  opacity: 1;
  pointer-events: auto;
  transform: translateX(-50%) translateY(0);
}

.search-island-input-wrap {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
}

.search-mute-icon {
  color: var(--muted);
  opacity: 0.6;
}

.search-island-input-wrap input {
  flex: 1;
  background: transparent;
  border: none;
  color: var(--text);
  font-size: 15px;
  outline: none;
}

.search-results-list {
  max-height: 360px;
  overflow-y: auto;
  border-top: 1px solid var(--stroke);
  background: var(--panel-2);
}

.search-result-card {
  display: flex;
  gap: 12px;
  padding: 12px 16px;
  cursor: pointer;
  transition: background 0.2s;
  border-bottom: 1px solid color-mix(in srgb, var(--stroke) 50%, transparent);
}

.search-result-card:hover {
  background: color-mix(in srgb, var(--accent) 15%, transparent);
}

.search-result-avatar {
  width: 36px;
  height: 36px;
  border-radius: var(--radius-sm);
  flex-shrink: 0;
  border: 1px solid var(--stroke);
  overflow: hidden;
  display: flex; /* Для центрирования буквы */
  align-items: center;
  justify-content: center;
  font-weight: 600;
  font-size: 14px;
  background-color: var(--panel-2);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

.search-result-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.search-result-content {
  flex: 1;
  min-width: 0;
}

.search-result-header {
  display: flex;
  justify-content: space-between;
  margin-bottom: 4px;
}

.search-result-name {
  font-weight: 600;
  font-size: 13px;
  color: var(--text);
}

.search-result-time {
  font-size: 11px;
  color: var(--muted);
}

.search-result-snippet {
  font-size: 13px;
  color: var(--muted);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  line-height: 1.4;
}

.search-empty {
  padding: 32px;
  text-align: center;
  color: var(--muted);
  font-size: 14px;
}

.chat-right {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 12px;
}

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

.chat-title {
  display: flex;
  align-items: center;
  gap: 12px;
}

.chat-title h3 {
  margin: 0;
  font-size: 18px;
  font-weight: 600;
}

.chat-header-meta {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.chat-status-area {
  position: relative;
  min-height: 18px; /* Высота строки статуса */
  display: flex;
  align-items: center;
  margin-top: 2px;
}

#chat-subtitle {
  margin: 0;
  color: var(--muted);
  font-size: 12px;
  transition:
    opacity 0.25s ease,
    transform 0.25s ease,
    color 0.3s ease;
  transform-origin: left center;
  white-space: nowrap;
}

#chat-subtitle.is-online {
  color: var(--accent);
  font-weight: 500;
}

#chat-subtitle.is-away {
  color: var(--status-warn);
}

#chat-subtitle.is-dnd {
  color: var(--status-bad);
}

#chat-subtitle.is-hidden {
  opacity: 0;
  transform: translateX(10px);
  pointer-events: none;
}

/* Peer's custom status — inline accent after the presence line, dot-separated.
   The "приколюшка": emoji + short text, truncated, fades out while typing. */
.chat-header-custom {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  min-width: 0;
  max-width: 220px;
  margin-left: 8px;
  padding-left: 9px;
  position: relative;
  font-size: 12px;
  color: var(--muted);
  transition:
    opacity 0.25s ease,
    transform 0.25s ease;
}

.chat-header-custom::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.55;
  transform: translateY(-50%);
}

.chat-header-custom[hidden] {
  display: none;
}

.chat-header-custom.is-hidden {
  opacity: 0;
  transform: translateX(10px);
  pointer-events: none;
}

.chc-emoji {
  flex: none;
  font-size: 13px;
  line-height: 1;
}

.chc-emoji[hidden] {
  display: none;
}

.chc-text {
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Narrow viewports: the name + presence already fill the row — drop the
   custom-status accent rather than let it crowd or overflow. */
@media (max-width: 600px) {
  .chat-header-custom {
    display: none;
  }
}

.typing-indicator {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--accent-2);
  letter-spacing: 0.02em;
  opacity: 0;
  transform: translateX(-15px);
  transition:
    opacity 0.2s ease,
    transform 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275);
  pointer-events: none;
  white-space: nowrap;
}

.typing-indicator.is-visible {
  opacity: 1;
  transform: translateX(0);
}

.typing-indicator:not(.is-visible) {
  transform: translateX(15px);
  opacity: 0;
}

.typing-indicator[hidden] {
  display: none !important;
}

/* Typing dots animation */
.typing-dots {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  margin-left: 2px;
}

.typing-dots span {
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--accent-2);
  animation: typing-bounce 1.2s ease-in-out infinite;
}

.typing-dots span:nth-child(2) {
  animation-delay: 0.15s;
}

.typing-dots span:nth-child(3) {
  animation-delay: 0.3s;
}

@keyframes typing-bounce {
  0%,
  60%,
  100% {
    transform: translateY(0);
    opacity: 0.4;
  }
  30% {
    transform: translateY(-4px);
    opacity: 1;
  }
}

.net-indicator {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--muted);
  white-space: nowrap;
  user-select: none;
}

.net-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--status-offline);
  box-shadow: 0 0 8px color-mix(in srgb, var(--status-offline) 60%, transparent);
}

.net-indicator.good .net-dot {
  background: var(--status-good);
  box-shadow: 0 0 10px color-mix(in srgb, var(--status-good) 60%, transparent);
}

.net-indicator.ok .net-dot {
  background: var(--status-warn);
  box-shadow: 0 0 10px color-mix(in srgb, var(--status-warn) 55%, transparent);
}

.net-indicator.bad .net-dot {
  background: var(--status-bad);
  box-shadow: 0 0 10px color-mix(in srgb, var(--status-bad) 60%, transparent);
}

.net-indicator.offline .net-dot {
  background: var(--status-offline);
  box-shadow: 0 0 8px color-mix(in srgb, var(--status-offline) 60%, transparent);
}

.net-indicator.reconnecting .net-dot {
  background: var(--status-warn);
  box-shadow: 0 0 8px color-mix(in srgb, var(--status-warn) 60%, transparent);
}

/* === layout-core/chat-body.css === */
#chat-subtitle:empty {
  display: none;
}

.messages {
  flex: 1;
  overflow-y: auto;
  padding: 20px 24px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-height: 0;
  scrollbar-gutter: stable;
}

.empty-state {
  margin-top: 40px;
  color: var(--muted);
  text-align: center;
  font-size: 14px;
}

/* === layout-core/desktop-overlay.css === */
/* ── Update banner ────────────────────────────────────────────────── */

.update-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 4px 14px;
  background: color-mix(in srgb, var(--accent, #5865f2) 18%, transparent);
  border-bottom: 1px solid color-mix(in srgb, var(--accent, #5865f2) 35%, transparent);
  font-size: 12px;
  color: var(--text);
  flex-shrink: 0;
  order: -1; /* отображается выше основного контента */
}

.update-banner-actions {
  display: flex;
  gap: 8px;
  align-items: center;
}

.update-banner .update-action {
  padding: 2px 10px;
  border-radius: 999px;
  border: 1px solid var(--accent, #5865f2);
  background: transparent;
  color: var(--accent, #5865f2);
  cursor: pointer;
  font-size: 11px;
  transition: background 0.15s;
}

.update-banner .update-action:hover {
  background: color-mix(in srgb, var(--accent, #5865f2) 20%, transparent);
}

.update-banner .update-dismiss {
  background: transparent;
  border: none;
  color: var(--muted);
  cursor: pointer;
  font-size: 14px;
  padding: 0 2px;
  line-height: 1;
}

.update-banner .update-action:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.update-banner .update-progress {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 1;
  margin: 0 12px;
  min-width: 0;
}

.update-banner .update-progress-bar {
  flex: 1;
  height: 4px;
  background: color-mix(in srgb, var(--accent, #5865f2) 18%, transparent);
  border-radius: 999px;
  overflow: hidden;
  min-width: 60px;
}

.update-banner .update-progress-fill {
  height: 100%;
  width: 0%;
  background: var(--accent, #5865f2);
  transition: width 0.18s ease-out;
}

.update-banner .update-progress-label {
  font-size: 11px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  min-width: 56px;
  text-align: right;
}

/* ── Compact mode overlay ────────────────────────────────────────── */

.compact-overlay {
  display: none;
}

body.is-compact .compact-overlay {
  display: flex;
  position: fixed;
  inset: 0;
  z-index: 99999;
  align-items: center;
  justify-content: center;
  background: var(--panel, #10151e);
  border: 1px solid var(--stroke, rgba(255, 255, 255, 0.1));
  border-radius: 12px;
  cursor: grab;
}

body.is-compact .compact-overlay img {
  width: 40px;
  height: 40px;
  cursor: pointer;
  pointer-events: auto;
}

body.is-compact .title-bar,
body.is-compact .update-banner,
body.is-compact > *:not(.compact-overlay):not(script) {
  display: none !important;
}

/* === users.css === */
.user-list,
.chat-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0;
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  align-items: stretch;
  /* No padding-bottom: Chromium drops trailing padding inside flex+overflow
     scroll containers, so the last row used to slip under the FAB. A real
     spacer child (::after below) is the reliable fix. */
  scroll-padding-bottom: 80px;
}

.chat-list::after,
.user-list::after {
  content: "";
  display: block;
  flex-shrink: 0;
  height: 80px;
  pointer-events: none;
}

.is-sidebar-mini .chat-list::after {
  display: none;
}

.user-item,
.chat-item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  margin: 0;
  width: auto;
  border-radius: 0;
  background: transparent;
  border: none;
  border-bottom: 1px solid color-mix(in srgb, var(--stroke) 60%, transparent);
  cursor: pointer;
  position: relative;
  transition: background-color var(--anim-fast) var(--ease-out);
  box-sizing: border-box;
  content-visibility: auto;
  contain-intrinsic-size: 64px;
}

.chat-list > .chat-item:last-child,
.user-list > .user-item:last-child {
  border-bottom: 1px solid transparent;
}

.user-item:hover,
.chat-item:hover {
  background: color-mix(in srgb, var(--accent) 6%, var(--panel));
}

.user-item.active,
.chat-item.active {
  background: var(--panel-2);
  box-shadow: none;
}

/* Status dot вместо outset glow на аватаре — чтобы не конфликтовать с border-bottom */
.user-item.online .avatar,
.chat-item.online .avatar {
  position: relative;
}

.user-item.online .avatar::after,
.chat-item.online .avatar::after {
  content: "";
  position: absolute;
  right: -2px;
  bottom: -2px;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--status-good);
  border: 2px solid var(--panel);
  pointer-events: none;
}

/* away/dnd recolour the same dot; offline drops the .online class entirely. */
.user-item.online[data-presence="warn"] .avatar::after,
.chat-item.online[data-presence="warn"] .avatar::after {
  background: var(--status-warn);
}

.user-item.online[data-presence="bad"] .avatar::after,
.chat-item.online[data-presence="bad"] .avatar::after {
  background: var(--status-bad);
}

.user-item.unread::after {
  content: "";
  width: 8px;
  height: 8px;
  margin-left: auto;
  border-radius: 50%;
  background: var(--accent-2);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent-2) 20%, transparent);
}

.chat-meta {
  display: flex;
  flex-direction: column;
  gap: 4px;
  flex: 1;
  min-width: 0;
}

.chat-title-row {
  display: flex;
  align-items: center;
  gap: 8px;
}

.chat-name {
  font-size: 14px;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.chat-pin {
  font-size: 12px;
  color: var(--accent);
}

.chat-mute {
  --icon-size: 13px;
  color: #5f636b;
  opacity: 0.95;
}

.chat-time {
  margin-left: auto;
  font-size: 11px;
  color: var(--muted);
}

.chat-preview {
  font-size: 12px;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.chat-unread {
  margin-left: auto;
  min-width: 18px;
  height: 18px;
  border-radius: var(--radius-pill);
  background: var(--accent);
  color: var(--accent-contrast);
  font-size: 11px;
  font-weight: 600;
  display: grid;
  place-items: center;
  padding: 0 6px;
}

.chat-empty {
  padding: 12px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--stroke);
  color: var(--muted);
  text-align: center;
  font-size: 12px;
}

.chat-enter {
  animation: chatFadeIn var(--anim-fast) var(--ease-out);
}

@keyframes chatFadeIn {
  from {
    opacity: 0;
    transform: translateY(6px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.avatar {
  width: 36px;
  height: 36px;
  border-radius: var(--radius-chat-item);
  background: var(--panel-2);
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 600;
  font-size: 14px;
  color: var(--text);
  overflow: hidden;
}

.avatar.has-image {
  background: var(--panel-2);
}

.avatar.is-default {
  background: var(--panel-2);
}

.avatar.is-default img {
  opacity: 0.92;
  padding: 4px;
  box-sizing: border-box;
}

.avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.user-meta {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.user-meta span {
  font-size: 14px;
}

.user-meta small {
  color: var(--muted);
  font-size: 12px;
}

.back-button {
  display: none;
  border: 1px solid var(--stroke);
  background: transparent;
  color: var(--text);
  border-radius: 10px;
  padding: 6px 10px;
  font-size: 12px;
  cursor: pointer;
}

/* === messages.css === */

/* === messages/bubbles.css === */
.message {
  max-width: 70%;
  padding: 8px 12px;
  border-radius: 18px;
  font-size: 14.5px;
  line-height: 1.45;
  background: var(--panel-2);
  border: 1px solid var(--stroke);
  position: relative;
  will-change: transform;
  transition:
    background-color 0.15s ease,
    border-color 0.15s ease,
    color 0.15s ease;
  content-visibility: auto;
  contain-intrinsic-size: 70px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
  margin-bottom: 4px;
}

/* Grouping bubbles & Tails */
.message.incoming {
  align-self: flex-start;
  margin-right: auto;
  margin-left: 8px;
}

/* Incoming Grouping */
.message.incoming + .message.incoming {
  border-top-left-radius: 4px;
  margin-top: -2px;
}
.message.incoming:has(+ .message.incoming) {
  border-bottom-left-radius: 4px;
}

.message.incoming:not(:has(+ .message.incoming)):after {
  content: "";
  position: absolute;
  bottom: 0;
  left: -7px;
  width: 12px;
  height: 18px;
  background: var(--panel-2);
  border-left: 1px solid var(--stroke);
  border-bottom: 1px solid var(--stroke);
  clip-path: polygon(100% 0, 100% 100%, 0 100%);
  z-index: -1;
}

.message.outgoing {
  align-self: flex-end;
  margin-left: auto;
  margin-right: 8px;
  background: color-mix(in srgb, var(--accent) 25%, var(--panel-2));
  border-color: color-mix(in srgb, var(--accent) 30%, var(--stroke));
}

/* Outgoing Grouping */
.message.outgoing + .message.outgoing {
  border-top-right-radius: 4px;
  margin-top: -2px;
}
.message.outgoing:has(+ .message.outgoing) {
  border-bottom-right-radius: 4px;
}

.message.outgoing:not(:has(+ .message.outgoing)):after {
  content: "";
  position: absolute;
  bottom: 0;
  right: -7px;
  width: 12px;
  height: 18px;
  background: color-mix(in srgb, var(--accent) 25%, var(--panel-2));
  border-right: 1px solid var(--stroke);
  border-bottom: 1px solid var(--stroke);
  clip-path: polygon(0 0, 0 100%, 100% 100%);
  z-index: -1;
}

.message:has(.attachment-audio),
.message:has(.attachment-video),
.message:has(.attachment-image),
.message:has(.attachment-grid) {
  max-width: min(720px, 90%);
  padding: 4px;
}

/* Audio track card and voice pill share one fixed footprint so the two
   players read as a matched pair regardless of how long the track title is. */
.message:has(.attachment-audio),
.message:has(.voice-player) {
  width: min(420px, 90%);
}

.message.with-avatar {
  margin-left: 44px;
}

/* Hide avatars for messages that are followed by another message from the same sender */
.message.with-avatar:has(+ .message.incoming) .message-avatar {
  display: none;
}

.message-avatar {
  position: absolute;
  left: -38px;
  bottom: 0;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: linear-gradient(
    145deg,
    color-mix(in srgb, var(--accent) 35%, transparent),
    color-mix(in srgb, var(--accent-2) 20%, transparent)
  );
  display: grid;
  place-items: center;
  font-weight: 600;
  font-size: 12px;
  color: var(--text);
  overflow: hidden;
  cursor: pointer;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.message-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.message.system {
  align-self: center;
  margin: 12px auto;
  max-width: 85%;
  color: var(--muted);
  font-size: 12.5px;
  text-align: center;
  padding: 5px 12px;
  background: var(--panel-2);
  border: 1px solid var(--stroke);
  border-radius: var(--radius-sm);
  box-shadow: none;
}

.message-sender {
  font-size: 12px;
  font-weight: 600;
  /* Цвет назначается inline-стилем по hash(sender_id) в messages/render.js.
     Fallback: акцент (если userId не передан). */
  color: var(--accent-2);
  margin-bottom: 2px;
  letter-spacing: 0.01em;
}

.message-text {
  display: block;
  white-space: normal;
  word-break: break-word;
  overflow-wrap: anywhere;
}

.message-text:empty {
  display: none;
}

.message-text p {
  margin: 0 0 4px;
}

.message-text p:last-child {
  margin-bottom: 0;
}

.message-text ul,
.message-text ol {
  margin: 4px 0 6px 18px;
  padding: 0;
}

.message-text li {
  margin: 2px 0;
}

.message-text code {
  font-family: "IBM Plex Mono", monospace;
  font-size: 12px;
  background: var(--panel);
  padding: 2px 6px;
  border-radius: 6px;
}

.message-text pre {
  margin: 6px 0;
  padding: 10px 12px;
  border-radius: 12px;
  background: var(--panel);
  overflow-x: auto;
  font-family: "IBM Plex Mono", monospace;
  font-size: 12px;
  line-height: 1.5;
}

.message-text pre code {
  background: transparent;
  padding: 0;
  font-size: inherit;
}

.message-text .code-block {
  margin: 6px 0;
  border-radius: 12px;
  border: 1px solid var(--stroke);
  background: var(--panel);
  overflow: hidden;
}

.message-text .code-block .code-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 6px 10px;
  border-bottom: 1px solid var(--stroke);
  background: color-mix(in srgb, var(--panel) 85%, transparent);
}

.message-text .code-block .code-lang {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted);
}

.message-text .code-block .code-copy {
  border: 1px solid var(--stroke);
  background: var(--panel-2);
  color: var(--text);
  font-size: 11px;
  padding: 4px 8px;
  border-radius: 8px;
  cursor: pointer;
}

.message-text .code-block pre {
  margin: 0;
  padding: 10px 12px;
  background: transparent;
  border-radius: 0;
}

.message-text a {
  color: var(--link);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.call-log {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  font-weight: 500;
}

.call-log .call-icon {
  display: inline-flex;
  align-items: center;
}

.call-log .call-text {
  font-size: 13px;
}

.call-log.missed {
  color: var(--danger);
}

.call-log:not(.missed) {
  color: var(--success);
}

/* Soft-tinted outgoing bubble keeps the green/red call colors readable —
   no override needed anymore. */

.message .message-actions {
  position: absolute;
  bottom: calc(100% + 4px);
  right: 0;
  display: flex;
  gap: 4px;
  opacity: 0;
  transform: translateY(4px);
  transition:
    opacity 0.15s ease,
    transform 0.15s ease;
  z-index: 100;
  pointer-events: none;
}

.message.incoming .message-actions {
  left: 0;
  right: auto;
}

.message:hover .message-actions,
.message:focus-within .message-actions,
.message.context-menu-active .message-actions {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}

.message .message-action {
  width: 32px;
  height: 32px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--stroke);
  background: var(--panel);
  color: var(--text);
  cursor: pointer;
  display: grid;
  place-items: center;
  font-size: 14px;
  box-shadow: var(--shadow);
  transition:
    background 0.2s ease,
    transform 0.1s active;
}

.message .message-action:hover {
  background: var(--panel-2);
}

.message .message-action:active {
  transform: scale(0.9);
}

.message .message-action.delete {
  color: var(--danger);
}

.message .reply-pill {
  padding: 6px 10px;
  margin-bottom: 4px;
  border-radius: 12px;
  background: color-mix(in srgb, var(--accent) 10%, var(--panel));
  border-left: 3px solid var(--accent);
  font-size: 12px;
  color: var(--text);
  cursor: pointer;
  opacity: 0.9;
}

.message-reactions {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-top: 6px;
}

.message-reaction-pill {
  border: 1px solid color-mix(in srgb, var(--stroke) 50%, transparent);
  background: color-mix(in srgb, var(--panel) 90%, transparent);
  color: var(--text);
  border-radius: 12px;
  min-height: 24px;
  padding: 2px 6px;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  cursor: pointer;
  transition: all 0.15s ease;
}

.message-reaction-pill:hover {
  background: var(--panel);
  transform: translateY(-1px);
}

.message-reaction-pill.is-own {
  background: color-mix(in srgb, var(--accent) 15%, var(--panel));
  border-color: var(--accent);
}

.reaction-avatars-inline {
  display: inline-flex;
  align-items: center;
  gap: 0;
}

.reaction-avatar-inline {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  overflow: hidden;
  border: 1px solid var(--panel);
  background: var(--panel-2);
  display: grid;
  place-items: center;
  font-size: 8px;
  margin-left: -6px;
}

.reaction-avatar-inline:first-child {
  margin-left: 0;
}

.reaction-avatar-inline img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.reaction-users-tooltip {
  position: fixed;
  z-index: 10020;
  min-width: 190px;
  max-width: 270px;
  padding: 8px;
  border-radius: 12px;
  border: 1px solid color-mix(in srgb, var(--stroke) 72%, transparent);
  background: color-mix(in srgb, var(--panel) 95%, transparent);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  box-shadow: 0 14px 30px rgba(0, 0, 0, 0.32);
  display: flex;
  flex-direction: column;
  gap: 4px;
  pointer-events: none;
  opacity: 0;
  transform: translateY(4px) scale(0.98);
  transition:
    opacity 0.14s ease,
    transform 0.14s ease;
}

.reaction-users-tooltip.is-visible {
  pointer-events: auto;
  opacity: 1;
  transform: translateY(0) scale(1);
}

.reaction-user-row {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 28px;
  padding: 4px 6px;
  border-radius: 8px;
  width: 100%;
  border: none;
  background: transparent;
  color: inherit;
  text-align: left;
  cursor: pointer;
  transition: background var(--anim-fast) var(--ease-out);
}

.reaction-user-row:hover {
  background: color-mix(in srgb, var(--accent) 14%, transparent);
}

.reaction-user-avatar {
  width: 20px;
  height: 20px;
  border-radius: 999px;
  overflow: hidden;
  flex: 0 0 auto;
}

.reaction-user-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.reaction-user-name {
  font-size: 12px;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.reaction-user-more {
  padding: 2px 6px 4px;
  font-size: 11px;
  color: var(--muted);
}

.message-meta {
  display: flex;
  align-items: center;
  gap: 4px;
  float: right;
  margin: 4px -4px -2px 8px;
  padding: 1px 4px;
  border-radius: 8px;
  position: relative;
  z-index: 10;
}

.message-meta time {
  font-size: 10px;
  color: var(--muted);
  font-weight: 500;
}

.message .status-icon {
  display: flex;
  align-items: center;
  color: var(--muted);
  font-size: 14px;
}

.message .status-icon.is-read {
  color: var(--accent);
}

.message:after {
  content: "";
  display: table;
  clear: both;
}

.message .message-readers {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-left: 2px;
  color: var(--accent);
  position: relative;
  line-height: 1;
  z-index: 8;
}

.message .message-readers .icon {
  --icon-size: 12px;
}

.message .message-readers .readers-count {
  font-size: 10px;
}

.message-highlight {
  animation: messageHighlight 2.4s ease-out;
}

@keyframes messageHighlight {
  0% {
    background: color-mix(in srgb, var(--accent) 30%, var(--panel-2));
  }
  100% {
    background: var(--panel-2);
  }
}

.message.big-emoji {
  background: transparent !important;
  border: none !important;
  box-shadow: none !important;
  padding: 0 !important;
  font-size: 48px !important;
  line-height: 1;
  overflow: visible;
}

.message.big-emoji .message-meta {
  background: rgba(0, 0, 0, 0.4);
  backdrop-filter: blur(4px);
  padding: 2px 6px;
  border-radius: 8px;
  margin-top: 4px;
  float: none;
  display: inline-flex;
}

.message.big-emoji.outgoing .message-meta {
  margin-left: auto;
}

.date-divider {
  align-self: center;
  padding: 2px 10px;
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--muted);
  font-size: var(--text-xs);
  font-weight: 500;
  letter-spacing: 0.04em;
  margin: var(--space-4) 0 var(--space-2);
}

.new-message-banner {
  margin: 8px auto;
  padding: 6px 12px;
  border-radius: 999px;
  background: var(--accent);
  color: #fff;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
}

/* ==========================================================
   Flat bubbles
   .message is a transparent flex column container; the visible
   plate moves into .message-bubble (created in messages/render.js).
   System messages and big-emoji skip the bubble.
   ========================================================== */

.message {
  background: transparent;
  border: none;
  box-shadow: none;
  padding: 0;
  border-radius: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

.message.outgoing {
  align-items: flex-end;
  /* kill the v1 wrapper background — it has higher specificity than
     the .message reset above and otherwise paints a coloured rim
     around the bubble (visible as a square strip on short outgoing
     bubbles and as a top/bottom line around media-only messages). */
  background: transparent;
  border-color: transparent;
}

/* Disable v1 tails (they live on .message::after) */
.message.incoming:not(:has(+ .message.incoming))::after,
.message.outgoing:not(:has(+ .message.outgoing))::after {
  display: none;
}

/* The bubble itself */
.message-bubble {
  position: relative;
  padding: 8px 12px;
  border-radius: var(--radius-bubble);
  background: var(--panel-2);
  color: var(--text);
  max-width: 100%;
  word-break: break-word;
  overflow-wrap: anywhere;
}

.message-bubble:empty {
  display: none;
}

/* Outgoing — themed soft tint via --bubble-out-bg.
   Each theme picks its own mix so light stays beige and dark
   stays warm-gold instead of muddy brown. */
.message.outgoing .message-bubble {
  background: var(--bubble-out-bg, color-mix(in srgb, var(--accent) 22%, var(--panel-2)));
  color: var(--text);
}

/* Tile grouping: adjacent messages from the same sender
   get a softer corner on the joining side (no sharp 2px notch). */
.message.incoming + .message.incoming .message-bubble {
  border-top-left-radius: var(--radius-bubble-tight);
}
.message.incoming:has(+ .message.incoming) .message-bubble {
  border-bottom-left-radius: var(--radius-bubble-tight);
}
.message.outgoing + .message.outgoing .message-bubble {
  border-top-right-radius: var(--radius-bubble-tight);
}
.message.outgoing:has(+ .message.outgoing) .message-bubble {
  border-bottom-right-radius: var(--radius-bubble-tight);
}

/* Flat plates — no tails. Kept disabled rules to override the v1
   ::after clip-path tail that lives on .message itself. */
.message.incoming:not(:has(+ .message.incoming)) .message-bubble::after,
.message.outgoing:not(:has(+ .message.outgoing)) .message-bubble::after {
  content: none;
  display: none;
}

/* Reply-pill inside the bubble — flat, thin accent edge */
.message-bubble .reply-pill {
  border-radius: var(--radius-bubble);
  border-left: 2px solid var(--accent);
  background: color-mix(in srgb, var(--text) 6%, transparent);
  margin-bottom: 6px;
}

.message.outgoing .message-bubble .reply-pill {
  border-left-color: var(--accent);
  background: color-mix(in srgb, var(--text) 6%, transparent);
  color: inherit;
}

/* Forward header inside the bubble */
.message-bubble .forward-header {
  font-size: 11px;
  color: var(--muted);
  margin-bottom: 4px;
}

.message.outgoing .message-bubble .forward-header {
  color: var(--muted);
}

/* Sender label in groups */
.message-bubble .message-sender {
  margin-bottom: 2px;
}

/* Meta — outside the bubble, flat, no float (default) */
.message-meta {
  float: none;
  display: inline-flex;
  margin: 2px 4px 0;
  padding: 0;
  background: transparent;
  border-radius: 0;
}

/* Meta inside the bubble — anchored to the bottom-right corner via an
   inline-flow spacer (.message-meta-spacer) injected by render.js at the
   end of the last text-bearing element. The spacer floats right with a
   width matched to whatever the meta carries (time / time+status /
   time+status+readers); the bubble grows to fit the last line + spacer,
   the absolute meta overlays the spacer area, and no padding strip is
   reserved when content is short or fixed-width. */
.message-meta-spacer {
  display: inline-block;
  float: right;
  width: 42px;
  height: 14px;
  margin: 0 0 0 8px;
  pointer-events: none;
}

.message-bubble:has(> .message-meta > .status-icon) .message-meta-spacer {
  width: 56px;
}

.message-bubble:has(> .message-meta > .message-readers:not([hidden])) .message-meta-spacer {
  width: 78px;
}

.message-bubble > .message-meta {
  position: absolute;
  right: 10px;
  bottom: 5px;
  margin: 0;
  padding: 0;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  line-height: 1;
  z-index: 2;
  background: transparent;
}

.message-bubble > .message-meta time {
  font-size: 10px;
  color: var(--muted);
  font-weight: 500;
}

.message-bubble > .message-meta .status-icon {
  font-size: 12px;
}

.message-bubble > .message-meta .status-icon .icon {
  --icon-size: 12px;
}

.message.outgoing .message-meta,
.message.outgoing .message-meta time,
.message.outgoing .status-icon {
  color: var(--muted);
  opacity: 1;
}

.message.outgoing .status-icon.is-read {
  color: var(--accent);
}

/* Big-emoji meta — no glass */
.message.big-emoji .message-meta {
  background: transparent;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  padding: 0;
}

/* Deleted message — muted plate with dashed border and italic
   text, distinct from a live message. Applies to both incoming
   and outgoing (overrides --highlight with the muted bg). */
.message.deleted .message-bubble {
  background: var(--panel-2);
  color: var(--muted);
  border: 1px dashed color-mix(in srgb, var(--muted) 40%, transparent);
  font-style: italic;
  opacity: 0.85;
}

.message.outgoing.deleted .message-bubble {
  background: var(--panel-2);
  color: var(--muted);
}

/* No tail for deleted bubbles — the dashed muted plate stands
   alone instead of leaking the live-bubble tail past its edge. */
.message.deleted .message-bubble::after {
  display: none;
}

.message.deleted .deleted-text {
  font-style: italic;
}

/* Attachments still live inside .message under v2 — neutralize
   v1 overrides on max-width/padding. */
.message:has(.attachment-audio),
.message:has(.attachment-video),
.message:has(.attachment-image),
.message:has(.attachment-grid) {
  padding: 0;
}

/* messageHighlight keyframes use panel-2 — the token swaps
   automatically from bobrovaya-light/dark.css, no extra rules. */

/* Floating "scroll to bottom" pill, anchored to .chat-panel
   (which is position: relative). Hidden via the [hidden] attr
   from main.js; .is-visible is just a hook for future fade-in. */
.scroll-to-bottom-button {
  position: absolute;
  right: 18px;
  bottom: 88px;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 1px solid var(--stroke);
  background: var(--panel);
  color: var(--text);
  cursor: pointer;
  display: grid;
  place-items: center;
  padding: 0;
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.12);
  z-index: 20;
  transition:
    background-color var(--anim-fast) var(--ease-out),
    transform var(--anim-fast) var(--ease-out);
}

.scroll-to-bottom-button .icon {
  --icon-size: 16px;
}

.scroll-to-bottom-button:hover {
  background: var(--panel-2);
}

.scroll-to-bottom-button:active {
  transform: scale(0.94);
}

/* === messages/selection.css === */
/* Multi-select mode for messages. Active when body.is-selecting-messages
   is present; selection-bar fixes itself at the top of the chat panel. */

.selection-bar {
  position: sticky;
  top: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  /* Match .chat-header height so swapping header → bar doesn't jump the layout. */
  min-height: 60px;
  padding: var(--space-2) var(--space-4);
  background: var(--panel);
  border-bottom: 1px solid var(--stroke);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
}

.selection-bar[hidden] {
  display: none;
}

.selection-bar-info {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-width: 0;
}

.selection-bar-count {
  font-weight: 600;
  font-size: var(--text-md);
  color: var(--text);
}

.selection-bar-actions {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--space-1);
}

.selection-bar-button {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-1) var(--space-2);
  background: transparent;
  border: none;
  border-radius: var(--radius-sm);
  cursor: pointer;
  color: var(--text);
  font-size: var(--text-sm);
  transition: background var(--anim-fast) var(--ease-out);
}

.selection-bar-button:hover {
  background: color-mix(in srgb, var(--accent) 12%, transparent);
}

.selection-bar-button.is-danger {
  color: var(--danger, #e25555);
}

.selection-bar-button.is-danger:hover {
  background: color-mix(in srgb, var(--danger, #e25555) 14%, transparent);
}

.selection-bar-button[disabled],
.selection-bar-button.is-disabled {
  opacity: 0.4;
  cursor: not-allowed;
  pointer-events: none;
}

.selection-bar-delete-menu {
  position: absolute;
  right: 0;
  top: calc(100% + 4px);
  min-width: 200px;
  background: var(--panel);
  border: 1px solid var(--stroke);
  border-radius: var(--radius-md);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
  padding: var(--space-1);
  z-index: 40;
}

.selection-bar-delete-menu[hidden] {
  display: none;
}

.selection-bar-delete-menu .dropdown-item {
  width: 100%;
  text-align: left;
  background: transparent;
  border: none;
  padding: var(--space-2);
  border-radius: var(--radius-sm);
  cursor: pointer;
  color: var(--text);
  font-size: var(--text-sm);
}

.selection-bar-delete-menu .dropdown-item:hover:not([disabled]) {
  background: color-mix(in srgb, var(--accent) 12%, transparent);
}

.selection-bar-delete-menu .dropdown-item.is-danger {
  color: var(--danger, #e25555);
}

.selection-bar-delete-menu .dropdown-item[disabled],
.selection-bar-delete-menu .dropdown-item.is-disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

/* Selected message: a LOUD full-width band runs the whole row and the bubble
   flips to a solid contrasting plate — not a subtle darken. The goal is that a
   selection is unmistakable from across the screen. Colours come from the
   brand palette (--accent-2 is the brightest tone) so it's bold, not foreign.
   Tweak the band % / swap to a dedicated neon var if you want it even louder. */
.message.is-selected {
  position: relative;
  z-index: 0; /* own stacking context so the band sits behind the content */
}

/* Full-width highlight band. ::before is free on .message (tails live on
   ::after); the wide negative insets are clipped to the scroller below, so the
   band runs edge to edge and adjacent selected rows merge into one ribbon. */
.message.is-selected::before {
  content: "";
  position: absolute;
  top: -6px;
  bottom: -6px;
  left: -100vw;
  right: -100vw;
  z-index: -1;
  background: color-mix(in srgb, var(--accent-2) 65%, transparent);
  pointer-events: none;
}

/* Solid accent plate with inverted text — a different colour, not a dimmer
   version of the normal bubble. High contrast against the band behind it. */
.message.is-selected .message-bubble {
  background: var(--accent);
  color: var(--accent-contrast);
}

.message.is-selected .message-bubble .message-text,
.message.is-selected .message-bubble .deleted-text,
.message.is-selected .message-bubble .message-sender {
  color: var(--accent-contrast);
}

/* Media keeps its pixels (no darkening) and instead gets a bright accent ring,
   so it reads as picked without dimming the actual content. */
.message.is-selected .message-attachments {
  outline: 3px solid var(--accent-2);
  outline-offset: 3px;
  border-radius: var(--radius-md);
}

/* Clip the band's overscan so it never spawns a horizontal scrollbar. */
body.is-selecting-messages .messages {
  overflow-x: hidden;
}

/* The selection bar replaces the header — hide the header (and with it the
   kebab menu + call buttons) so the two never stack into a double bar, and the
   kebab dropdown can't open over the selection actions. */
body.is-selecting-messages .chat-header {
  display: none;
}

/* In selection mode the per-message hover toolbar gets in the way; hide it. */
body.is-selecting-messages .message-actions {
  display: none !important;
}

/* Whole bubble is a tap target in selection mode — no text-selection drag,
   no native zoom on long-press for touch users. */
body.is-selecting-messages .message {
  cursor: pointer;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
}

/* Block hover/focus visual cues from media inside a selected message so the
   user doesn't get a misleading "click to play / open" affordance. */
body.is-selecting-messages .message .attachment-image,
body.is-selecting-messages .message .attachment-file,
body.is-selecting-messages .message .audio-player,
body.is-selecting-messages .message video {
  cursor: pointer;
}

/* === messages/pinned-bar.css === */
/* Telegram-style pinned-message bar that sits directly under the chat header.
   Shows the current pin; clicking cycles through pins and jumps to each in the
   lenta. The right-side button opens the full "all pinned" panel. */

.pinned-bar {
  display: flex;
  align-items: stretch;
  gap: 4px;
  flex: 0 0 auto;
  padding: 4px 8px 4px 12px;
  background: var(--panel);
  border-bottom: 1px solid var(--stroke);
  box-shadow: var(--shadow);
  position: relative;
  z-index: 4;
  animation: pinned-bar-in 0.18s ease;
}

.pinned-bar[hidden] {
  display: none;
}

@keyframes pinned-bar-in {
  from {
    opacity: 0;
    transform: translateY(-6px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.pinned-bar-main {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 4px 8px;
  background: transparent;
  border: none;
  border-radius: 8px;
  cursor: pointer;
  text-align: left;
  color: inherit;
  transition: background 0.14s ease;
}

.pinned-bar-main:hover {
  background: color-mix(in srgb, var(--accent) 8%, transparent);
}

.pinned-bar-main:active {
  background: color-mix(in srgb, var(--accent) 14%, transparent);
}

/* Vertical segmented rail on the left — one segment per pin, active one lit.
   Collapses to a single solid bar when there's a single pin. */
.pinned-bar-rail {
  flex: 0 0 auto;
  width: 3px;
  align-self: stretch;
  min-height: 30px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  border-radius: 3px;
  overflow: hidden;
}

.pinned-bar-rail .seg {
  flex: 1 1 0;
  min-height: 3px;
  border-radius: 3px;
  background: color-mix(in srgb, var(--accent) 28%, transparent);
  transition: background 0.16s ease;
}

.pinned-bar-rail .seg.active {
  background: var(--accent);
}

.pinned-bar-body {
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-width: 0;
  gap: 1px;
}

.pinned-bar-title {
  font-size: 13px;
  font-weight: 600;
  line-height: 1.25;
  color: var(--accent);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.pinned-bar-text {
  font-size: 13px;
  line-height: 1.25;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.pinned-bar-list-btn {
  flex: 0 0 auto;
  align-self: center;
}

/* "All pinned" panel — dropdown anchored top-right, dismissed via overlay. */
.pins-overlay {
  position: fixed;
  inset: 0;
  z-index: 60;
  background: transparent;
}

.pins-panel {
  position: fixed;
  z-index: 61;
  width: min(360px, calc(100vw - 24px));
  max-height: min(420px, calc(100vh - 120px));
  display: flex;
  flex-direction: column;
  background: var(--panel);
  border: 1px solid var(--stroke);
  border-radius: 12px;
  box-shadow: var(--shadow);
  overflow: hidden;
  transform-origin: top right;
  animation: pins-panel-in 0.16s ease;
}

@keyframes pins-panel-in {
  from {
    opacity: 0;
    transform: scale(0.96) translateY(-4px);
  }
  to {
    opacity: 1;
    transform: scale(1) translateY(0);
  }
}

.pins-panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 12px 14px;
  border-bottom: 1px solid var(--stroke);
}

.pins-panel-head .pins-panel-title {
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
}

.pins-panel-clear {
  background: transparent;
  border: none;
  color: var(--danger);
  font-size: 13px;
  cursor: pointer;
  padding: 4px 6px;
  border-radius: 6px;
  transition: background 0.14s ease;
}

.pins-panel-clear:hover {
  background: color-mix(in srgb, var(--danger) 12%, transparent);
}

.pins-panel-list {
  overflow-y: auto;
  padding: 6px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.pins-panel-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  border-radius: 8px;
  cursor: pointer;
  transition: background 0.14s ease;
}

.pins-panel-item:hover {
  background: color-mix(in srgb, var(--accent) 8%, transparent);
}

.ppi-body {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
  border-left: 2px solid color-mix(in srgb, var(--accent) 50%, transparent);
  padding-left: 8px;
}

.ppi-author {
  font-size: 12px;
  font-weight: 600;
  color: var(--accent);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ppi-text {
  font-size: 13px;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ppi-unpin {
  flex: 0 0 auto;
  background: transparent;
  border: none;
  color: var(--muted);
  cursor: pointer;
  padding: 6px;
  border-radius: 6px;
  display: inline-flex;
  transition:
    background 0.14s ease,
    color 0.14s ease;
}

.ppi-unpin:hover {
  background: color-mix(in srgb, var(--danger) 12%, transparent);
  color: var(--danger);
}


.messages {
  transition:
    filter 0.3s ease,
    opacity 0.3s ease;
}

.messages.is-searching {
  filter: blur(2px);
  opacity: 0.5;
  pointer-events: none;
}

/* Media info popup — opened from ПКМ → "Инфо о медиа".
   Small modal with key/value rows so file metadata stays out of
   the bubble itself. */
.media-info-modal .modal-card {
  gap: 12px;
}

.media-info-modal .media-info-name {
  font-family: var(--font-mono, monospace);
  font-size: 12px;
  color: var(--muted);
  word-break: break-all;
  overflow-wrap: anywhere;
}

.media-info-modal .modal-body {
  display: flex;
  flex-direction: column;
  gap: 0;
}

.media-info-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  padding: 8px 0;
  border-bottom: 1px dashed color-mix(in srgb, var(--stroke) 80%, transparent);
}

.media-info-row:last-child {
  border-bottom: none;
}

.media-info-key {
  font-size: 11px;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  flex-shrink: 0;
}

.media-info-value {
  font-size: 13px;
  color: var(--text);
  font-family: var(--font-mono, monospace);
  text-align: right;
  word-break: break-all;
  overflow-wrap: anywhere;
}

/* === composer.css === */
.composer {
  display: flex;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-5) var(--space-5);
  border-top: 1px solid var(--stroke);
  align-items: center;
  flex: 0 0 auto;
  flex-wrap: wrap;
  row-gap: var(--space-2);
  transition: border-top-color var(--anim-fast) var(--ease-out);
}

.composer:focus-within {
  border-top-color: color-mix(in srgb, var(--accent) 30%, var(--stroke));
}

.composer.dragging > :not(.drop-zone) {
  display: none;
}

.drop-zone {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 12px 14px;
  border-radius: 12px;
  border: 1px dashed color-mix(in srgb, var(--accent-2) 60%, transparent);
  background: var(--panel-2);
  color: var(--muted);
  font-size: 14px;
}

.drop-zone-icon {
  width: 40px;
  height: 40px;
  border-radius: 10px;
  border: 1px solid var(--stroke);
  display: grid;
  place-items: center;
  font-size: 11px;
  letter-spacing: 0.08em;
}

.drop-zone-text {
  font-size: 14px;
  color: var(--text);
}

.composer input,
.composer textarea {
  flex: 1;
  border-radius: var(--radius-pill);
  border: 1px solid transparent;
  background: var(--panel-2);
  color: var(--text);
  font-family: "IBM Plex Sans", "Segoe UI", sans-serif;
  padding: var(--space-3) var(--space-4);
  font-size: var(--text-md);
  line-height: 1.4;
  transition:
    border-color var(--anim-fast) var(--ease-out),
    background-color var(--anim-fast) var(--ease-out);
}

.composer textarea {
  resize: none;
  min-height: 42px;
  max-height: 40vh;
  overflow-y: hidden;
}

/* Multi-line: pill становится скругленным rectangle, чтоб не выглядело как сосиска */
.composer textarea.is-multiline {
  border-radius: var(--radius-md);
}

.composer input:focus,
.composer textarea:focus {
  outline: none;
  background: var(--panel);
  border-color: color-mix(in srgb, var(--accent) 50%, transparent);
}

/* Generic submit button reset (используется только когда .composer-send отсутствует) */
.composer button[type="submit"] {
  border: none;
  cursor: pointer;
  font-family: inherit;
}

/* Круглая send-кнопка — paper-plane, solid accent, без градиентов */
.composer .composer-send {
  width: 42px;
  height: 42px;
  min-width: 42px;
  border-radius: 50%;
  padding: 0;
  display: grid;
  place-items: center;
  background: var(--accent);
  color: var(--accent-contrast);
  box-shadow: 0 4px 12px color-mix(in srgb, var(--accent) 25%, transparent);
  transition:
    transform var(--anim-fast) var(--ease-out),
    filter var(--anim-fast) var(--ease-out),
    background-color var(--anim-fast) var(--ease-out),
    box-shadow var(--anim-fast) var(--ease-out);
}

.composer .composer-send .icon {
  --icon-size: 18px;
  /* Лёгкий сдвиг для оптической балансировки paper-plane */
  transform: translateX(-1px);
}

.composer .composer-send:hover:not(:disabled) {
  filter: brightness(1.08);
  transform: scale(1.04);
  box-shadow: 0 6px 16px color-mix(in srgb, var(--accent) 32%, transparent);
}

.composer .composer-send:active:not(:disabled) {
  transform: scale(0.94);
}

.composer .composer-send:disabled {
  background: var(--panel-2);
  color: var(--muted);
  box-shadow: none;
  cursor: not-allowed;
}

.attachment-actions {
  position: relative;
  flex-shrink: 0;
}

.composer-toggle {
  width: 32px;
  height: 32px;
  border-radius: 10px;
  border: 1px solid var(--stroke);
  background: var(--panel);
  color: var(--muted);
  cursor: pointer;
  display: grid;
  place-items: center;
  padding: 0;
  transition:
    background-color var(--anim-fast) var(--ease-out),
    color var(--anim-fast) var(--ease-out),
    border-color var(--anim-fast) var(--ease-out);
}

.composer-toggle .icon {
  --icon-size: 16px;
}

.composer-toggle:hover:not(:disabled) {
  background: var(--panel-2);
  color: var(--text);
}

.composer-toggle[data-active="true"],
.attachment-menu-trigger[data-has-selection="true"] {
  background: color-mix(in srgb, var(--accent) 18%, var(--panel));
  border-color: color-mix(in srgb, var(--accent) 45%, var(--stroke));
  color: var(--accent);
}

.composer-toggle[data-active="true"]:hover:not(:disabled),
.attachment-menu-trigger[data-has-selection="true"]:hover:not(:disabled) {
  background: color-mix(in srgb, var(--accent) 28%, var(--panel));
}

.composer-toggle:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

/* Attachment kebab menu — fixed positioning so it escapes the
   attachment-list overflow container; coordinates come from JS so
   the menu sits above and right-aligned with the trigger. */
.attachment-menu {
  position: fixed;
  min-width: 220px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 4px;
  background: var(--panel);
  border: 1px solid var(--stroke);
  border-radius: 10px;
  box-shadow: 0 8px 22px rgba(0, 0, 0, 0.18);
  z-index: 200;
}

.attachment-menu-item {
  display: grid;
  grid-template-columns: 16px 1fr 14px;
  gap: 10px;
  align-items: center;
  padding: 8px 10px;
  border-radius: 8px;
  border: none;
  background: transparent;
  color: var(--text);
  cursor: pointer;
  font-size: 13px;
  text-align: left;
  transition:
    background-color var(--anim-fast) var(--ease-out),
    color var(--anim-fast) var(--ease-out);
}

.attachment-menu-item:hover:not(:disabled) {
  background: var(--panel-2);
}

.attachment-menu-item .icon {
  --icon-size: 14px;
  color: var(--muted);
}

.attachment-menu-item .label {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.attachment-menu-item .check {
  --icon-size: 14px;
  color: var(--accent);
  visibility: hidden;
}

.attachment-menu-item[data-active="true"] {
  background: color-mix(in srgb, var(--accent) 10%, transparent);
}

.attachment-menu-item[data-active="true"] .icon:not(.check) {
  color: var(--accent);
}

.attachment-menu-item[data-active="true"] .check {
  visibility: visible;
}

.attachment-menu-item:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.composer .attach-button {
  width: 42px;
  height: 42px;
  border-radius: 12px;
  border: 1px solid var(--stroke);
  background: var(--panel);
  color: var(--text);
  font-size: 0;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  line-height: 1;
}

.composer .attach-button .icon {
  flex-shrink: 0;
}

.file-input {
  display: none;
}

.attachment-preview {
  padding: 8px 22px 0;
}

.attachment-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-height: 320px;
  overflow-y: auto;
  padding-right: 6px;
}

.reply-preview {
  padding: 8px 22px 0;
}

.edit-preview {
  padding: 8px 22px 0;
}

/* Tighten the gap between reply/edit/attachment preview rails and the
   composer — the previews already breathe internally, double padding
   on the composer just pushed it visually to the next county. */
.chat-panel:has(.reply-preview:not([hidden])) .composer,
.chat-panel:has(.edit-preview:not([hidden])) .composer,
.chat-panel:has(.attachment-preview:not([hidden])) .composer {
  padding-top: 6px;
}

/* Reply / edit composer cards — same layout, accent bar on the left,
   author + clamped body in the middle, close button on the right. */
.preview-card {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--panel);
  border: 1px solid var(--stroke);
  border-radius: 12px;
  padding: 6px 8px 6px 0;
  min-height: 38px;
  width: 100%;
  position: relative;
  overflow: hidden;
}

.preview-card .preview-bar {
  width: 3px;
  align-self: stretch;
  margin: 4px 0;
  border-radius: 2px;
  background: var(--accent);
  flex-shrink: 0;
}

.edit-card.preview-card {
  background: color-mix(in srgb, var(--accent) 8%, var(--panel));
}

.edit-card.preview-card .preview-bar {
  background: var(--accent-2, var(--accent));
}

.preview-card .preview-content {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.preview-card .preview-author {
  font-size: 12px;
  font-weight: 600;
  color: var(--accent);
  letter-spacing: 0.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.edit-card.preview-card .preview-author {
  color: var(--accent-2, var(--accent));
}

.preview-card .preview-text {
  font-size: 13px;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.preview-card .preview-close {
  width: 28px;
  height: 28px;
  border-radius: 8px;
  border: 1px solid transparent;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  display: grid;
  place-items: center;
  flex-shrink: 0;
  margin-right: 4px;
  transition:
    background-color var(--anim-fast) var(--ease-out),
    color var(--anim-fast) var(--ease-out);
}

.preview-card .preview-close .icon {
  --icon-size: 14px;
}

.preview-card .preview-close:hover {
  background: var(--panel-2);
  color: var(--text);
}

/* Attachment card — compact 80px row: 64x64 thumb on the left with
   inset close-cross, name+size in the middle, action toggles on the
   right. Progress bar slides under the meta column when uploading. */
.attachment-card {
  display: grid;
  grid-template-columns: 64px 1fr auto;
  align-items: center;
  gap: 12px;
  background: var(--panel);
  border: 1px solid var(--stroke);
  border-radius: 12px;
  padding: 8px;
}

.attachment-thumb {
  position: relative;
  width: 64px;
  height: 64px;
}

.attachment-thumb.is-clickable {
  cursor: zoom-in;
}

.attachment-thumb.is-clickable:hover img {
  filter: brightness(1.05);
}

.attachment-thumb img,
.attachment-thumb .attachment-icon {
  width: 64px;
  height: 64px;
  object-fit: cover;
  border-radius: 8px;
  border: 1px solid var(--stroke);
}

.attachment-thumb .attachment-icon {
  display: grid;
  place-items: center;
  font-size: 11px;
  color: var(--muted);
  background: var(--panel-2);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.attachment-card .attachment-remove {
  position: absolute;
  top: -6px;
  right: -6px;
  width: 22px;
  height: 22px;
  margin: 0;
  padding: 0;
  border-radius: 50%;
  border: 1px solid var(--stroke);
  background: var(--panel);
  color: var(--text);
  cursor: pointer;
  display: grid;
  place-items: center;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.18);
  transition:
    background-color var(--anim-fast) var(--ease-out),
    color var(--anim-fast) var(--ease-out);
}

.attachment-card .attachment-remove .icon {
  --icon-size: 12px;
}

.attachment-card .attachment-remove:hover {
  background: var(--danger);
  color: #fff;
  border-color: transparent;
}

.attachment-card .attachment-meta {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.attachment-card .attachment-name {
  color: var(--text);
  font-size: 13px;
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.attachment-card .attachment-info {
  font-size: 12px;
  color: var(--muted);
}

.attachment-progress {
  grid-column: 2 / -1;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.attachment-progress .bar {
  width: 100%;
  height: 4px;
  border-radius: 999px;
  background: var(--panel-2);
  overflow: hidden;
}

.attachment-progress .bar span {
  display: block;
  height: 100%;
  width: 0%;
  background: var(--accent);
  transition: width 0.1s ease;
}

.attachment-progress .stats {
  font-size: 11px;
  color: var(--muted);
}

/* When no chat is selected, hide the composer entirely instead of
   leaving a dimmed bar at the bottom. */
.composer.disabled {
  display: none;
}

/* === voice.css === */
/* ============================================================
   Voice messages
   - composer recording/preview modes
   - inline player rendered inside message bubbles
   ============================================================ */

/* --- Send <-> mic morph animation --------------------------------------- */

/* The composer submit button hosts a single `.icon` we re-class between
   icon-send and icon-mic. A transient `.voice-morphing` class collapses
   the icon out, JS swaps the class, then the icon scales back in. */
.composer-send .icon,
#message-send .icon {
  transition:
    transform 0.16s ease,
    opacity 0.16s ease;
  will-change: transform, opacity;
}

.composer-send .icon.voice-morphing,
#message-send .icon.voice-morphing {
  transform: scale(0.35) rotate(45deg);
  opacity: 0;
}

/* --- Composer modes ------------------------------------------------------ */

.composer.voice-active {
  gap: 8px;
}

.voice-recording-row,
.voice-preview-row {
  display: flex;
  flex: 1;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

/* Hold gesture writes --voice-slide-x / --voice-cancel-progress while the
   finger drags. The row slides left and tints toward danger as the user
   approaches the cancel threshold. */
.voice-recording-row {
  position: relative;
  transform: translateX(var(--voice-slide-x, 0));
  transition:
    transform 0.08s linear,
    background 0.15s ease;
  border-radius: 18px;
}

.voice-recording-row.voice-cancel-armed {
  background: color-mix(in srgb, var(--danger) 18%, transparent);
  animation: voice-cancel-shake 0.32s ease-in-out;
}

@keyframes voice-cancel-shake {
  0%,
  100% {
    transform: translateX(var(--voice-slide-x, 0));
  }
  25% {
    transform: translateX(calc(var(--voice-slide-x, 0) - 6px));
  }
  75% {
    transform: translateX(calc(var(--voice-slide-x, 0) + 6px));
  }
}

.voice-cancel-btn,
.voice-stop-btn,
.voice-preview-delete,
.voice-preview-send {
  width: 36px;
  height: 36px;
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: 50%;
  background: var(--panel-2);
  color: var(--text);
  cursor: pointer;
  transition:
    background 0.15s ease,
    transform 0.1s ease,
    filter 0.15s ease;
}

.voice-cancel-btn:hover,
.voice-preview-delete:hover {
  background: var(--danger);
  color: var(--accent-contrast);
}

.voice-stop-btn,
.voice-preview-send {
  background: var(--accent);
  color: var(--accent-contrast);
}

.voice-stop-btn:hover,
.voice-preview-send:hover {
  filter: brightness(1.1);
}

.voice-preview-send:disabled {
  opacity: 0.6;
  cursor: progress;
}

/* Recording row: pulsing red dot + timer */

.voice-recording-indicator {
  display: flex;
  flex: 1;
  align-items: center;
  gap: 10px;
  min-width: 0;
  padding: 0 12px;
}

.voice-recording-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--danger);
  flex: 0 0 auto;
  animation: voice-pulse 1.2s ease-in-out infinite;
}

@keyframes voice-pulse {
  0%,
  100% {
    opacity: 1;
    transform: scale(1);
  }
  50% {
    opacity: 0.45;
    transform: scale(0.85);
  }
}

.voice-recording-timer {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  color: var(--text);
  min-width: 3.5ch;
}

.voice-recording-row.voice-warn .voice-recording-timer {
  color: var(--danger);
}

.voice-recording-hint {
  color: var(--muted);
  font-size: 13px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  opacity: calc(1 - var(--voice-cancel-progress, 0));
  transition: opacity 0.1s linear;
}

/* --- Lock chip (coarse-pointer only) ----------------------------------- */

.voice-lock-chip {
  display: none;
  position: absolute;
  right: 10px;
  top: -64px;
  width: 36px;
  min-height: 56px;
  border-radius: 18px;
  background: var(--panel-2);
  border: 1px solid var(--stroke);
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  padding: 8px 0;
  color: var(--muted);
  pointer-events: none;
  opacity: calc(0.45 + 0.55 * var(--voice-lock-progress, 0));
  transform: translateY(calc(-10px * var(--voice-lock-progress, 0)));
  transition:
    opacity 0.12s ease,
    transform 0.12s ease,
    background 0.15s ease,
    color 0.15s ease;
}

.voice-lock-chip-arrow {
  font-size: 10px;
  line-height: 1;
  opacity: 0.7;
}

@media (pointer: coarse) {
  .voice-recording-row:not(.voice-locked) .voice-lock-chip {
    display: flex;
  }
}

/* When the user crosses the lock threshold the chip flashes accent before the
   gesture detaches and JS adds the .voice-locked class. */
.voice-recording-row:not(.voice-locked) .voice-lock-chip[data-near="1"] {
  background: var(--accent);
  color: var(--accent-contrast);
}

/* Preview row: play + waveform + timer */

.voice-preview-player {
  display: flex;
  flex: 1;
  align-items: center;
  gap: 10px;
  min-width: 0;
  padding: 0 8px;
}

.voice-preview-play {
  width: 32px;
  height: 32px;
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: 50%;
  background: var(--accent);
  color: var(--accent-contrast);
  cursor: pointer;
  transition: filter 0.15s ease;
}

.voice-preview-play:hover {
  filter: brightness(1.1);
}

.voice-preview-waveform {
  display: flex;
  flex: 1;
  align-items: center;
  height: 28px;
  gap: 1.5px;
  cursor: pointer;
  min-width: 0;
}

.voice-preview-time {
  font-variant-numeric: tabular-nums;
  color: var(--muted);
  min-width: 3.5ch;
  text-align: right;
}

/* --- Inline player in chat bubbles -------------------------------------- */

.voice-player {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  background: color-mix(in srgb, var(--panel-2) 80%, transparent);
  border: 1px solid var(--stroke);
  border-radius: 18px;
  /* Width is pinned at the message level so the voice pill and the audio
     track card read as a matched pair; just fill that box here. */
  width: 100%;
  max-width: 420px;
}

/* Inside our own bubble, swap to a softer accent tint so the player reads
   as part of the bubble rather than a foreign card. */
.bubble.own .voice-player,
.message.own .voice-player {
  background: color-mix(in srgb, var(--accent-contrast) 18%, transparent);
  border-color: color-mix(in srgb, var(--accent-contrast) 30%, transparent);
}

.voice-player-play {
  width: 36px;
  height: 36px;
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: 50%;
  background: var(--accent);
  color: var(--accent-contrast);
  cursor: pointer;
  transition: filter 0.15s ease;
}

.voice-player-play:hover {
  filter: brightness(1.1);
}

/* The play polygon is geometrically left-weighted; nudge it for optical
   centering inside the round button. The pause glyph is symmetric. */
.voice-player-play .icon-play,
.voice-preview-play .icon-play {
  transform: translateX(1.5px);
}

.voice-player-waveform {
  display: flex;
  flex: 1;
  align-items: center;
  height: 28px;
  gap: 2px;
  cursor: pointer;
  min-width: 80px;
}

.voice-player-time {
  font-variant-numeric: tabular-nums;
  color: var(--muted);
  font-size: 12px;
  min-width: 3ch;
}

.voice-player-speed {
  border: none;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  font-size: 12px;
  font-weight: 600;
  padding: 2px 8px;
  border-radius: 999px;
  transition:
    background 0.15s ease,
    color 0.15s ease;
}

.voice-player-speed:hover {
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  color: var(--text);
}

/* --- Waveform bars (shared between composer preview and inline player) -- */

.voice-waveform-bar {
  flex: 1 1 0;
  min-width: 1.5px;
  /* No max-width: flex distributes the row width evenly across all bars.
     Density is controlled by the rendered bar count, not the bar's cap. */
  height: calc(8px + 18px * var(--peak, 0.1));
  background: color-mix(in srgb, var(--text) 35%, transparent);
  border-radius: 2px;
  transition: background 0.1s linear;
}

.voice-waveform-bar[data-played="1"] {
  background: var(--accent);
}

/* Played bars in our own bubble use the contrast color to pop against
   the accent-tinted background. */
.bubble.own .voice-waveform-bar,
.message.own .voice-waveform-bar {
  background: color-mix(in srgb, var(--accent-contrast) 55%, transparent);
}

.bubble.own .voice-waveform-bar[data-played="1"],
.message.own .voice-waveform-bar[data-played="1"] {
  background: var(--accent-contrast);
}

/* --- Coarse pointer adjustments ---------------------------------------- */

@media (pointer: coarse) {
  .voice-cancel-btn,
  .voice-stop-btn,
  .voice-preview-delete,
  .voice-preview-send {
    width: 44px;
    height: 44px;
  }

  .voice-preview-play {
    width: 40px;
    height: 40px;
  }

  /* The mic button needs to feel like a real target during hold; suppress the
     synthetic tap highlight Android draws on long press. */
  .composer-send {
    -webkit-tap-highlight-color: transparent;
    touch-action: none;
  }
}

/* === media.css === */
.message .attachment-image {
  margin-top: 0;
  display: block;
  width: auto;
  max-width: var(--cap-img-w);
  height: auto;
  max-height: var(--cap-img-h);
  object-fit: contain;
  border-radius: var(--radius-sm);
  border: none;
  cursor: zoom-in;
}

.message .attachment-item {
  position: relative;
  margin-top: 6px;
  overflow: hidden;
  border-radius: var(--radius-sm);
}

/* When the backend gives us width/height, we render the wrap at the exact
   final size — blurhash canvas fills it from frame 0, image fades in on
   top, no layout shift. Legacy rows without dims fall through to the
   intrinsic-size path above. */
.message .attachment-item--sized {
  width: var(--ai-w);
  max-width: 100%;
  aspect-ratio: var(--ai-ar);
}

.message .attachment-item--sized .attachment-image {
  width: 100%;
  height: 100%;
  max-width: 100%;
  max-height: 100%;
  object-fit: cover;
}

/* Album grid: 2+ images in one message render side-by-side instead of
   stacking. Cells crop with object-fit: cover, so we don't need real
   image dimensions yet — the grid alone reserves space and kills CLS for
   multi-image messages.
   Standalone albums (no forward/reply bubble around them) carry their
   own tinted frame so the photos don't bleed into the chat background
   and the unit reads as "multiple photos". */
.message .attachment-grid {
  display: grid;
  gap: 3px;
  margin-top: 6px;
  padding: 3px;
  width: 100%;
  max-width: var(--cap-img-w);
  border-radius: var(--radius-sm);
  background: var(--panel-2);
  overflow: hidden;
}

.message.outgoing .attachment-grid {
  background: var(--bubble-out-bg, color-mix(in srgb, var(--accent) 22%, var(--panel-2)));
}

/* Inside a bubble (forward/reply) the bubble itself is the frame —
   drop the album's own padding/bg so we don't double-frame. The
   .message prefix is needed to match the specificity of the
   outgoing/incoming colour rules above. */
.message .message-attachments--in-bubble .attachment-grid {
  margin-top: 6px;
  padding: 0;
  background: transparent;
}

.message .attachment-grid .attachment-item {
  margin-top: 0;
  border-radius: 0;
  width: 100%;
  height: 100%;
}

.message .attachment-grid .attachment-image {
  width: 100%;
  height: 100%;
  max-width: none;
  max-height: none;
  object-fit: cover;
  border-radius: 0;
}

.message .attachment-grid .attachment-blurhash {
  border-radius: 0;
}

.message .attachment-grid[data-count="2"] {
  grid-template-columns: 1fr 1fr;
  aspect-ratio: 2 / 1;
}

/* 3 images: one big left, two stacked right. */
.message .attachment-grid[data-count="3"] {
  grid-template-columns: 1.6fr 1fr;
  grid-template-rows: 1fr 1fr;
  aspect-ratio: 4 / 3;
}
.message .attachment-grid[data-count="3"] .attachment-item:nth-child(1) {
  grid-row: span 2;
}

.message .attachment-grid[data-count="4"] {
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 1fr 1fr;
  aspect-ratio: 1 / 1;
}

.message .attachment-grid[data-count="5"],
.message .attachment-grid[data-count="6"] {
  grid-template-columns: 1fr 1fr 1fr;
  aspect-ratio: 3 / 2;
}

.message .attachment-grid[data-count="7"],
.message .attachment-grid[data-count="8"],
.message .attachment-grid[data-count="9"] {
  grid-template-columns: 1fr 1fr 1fr;
  aspect-ratio: 1 / 1;
}

/* Messages that contain an album: drop the inner padding like single-image
   bubbles already do, so the grid bleeds to the bubble edge. */
.message:has(.attachment-grid) {
  padding: 0;
}

/* Blurhash placeholder: stays inside the image bounds (no scale-up,
   no blur tail). Image renders on top at full size, no fade-in —
   we want media to take its final shape immediately. */
.message .attachment-blurhash {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border-radius: var(--radius-sm);
  z-index: 1;
}

.message .attachment-image.with-blurhash {
  position: relative;
  z-index: 2;
  opacity: 0;
  transition: opacity 220ms ease-out;
}

.message .attachment-image.with-blurhash.is-loaded {
  opacity: 1;
}

.message .attachment-video {
  position: relative;
  margin-top: 8px;
}

/* The size caps live on .video-container (calls/video.css) as an aspect-box;
   the <video> just fills it. Kept in sync here so neither rule wins by load
   order. */
.message .attachment-video video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border: none;
  background: #000;
}

.message .attachment-video .media-download {
  position: absolute;
  top: 8px;
  right: 8px;
  border: 1px solid var(--stroke);
  background: var(--panel);
  color: var(--text);
  border-radius: var(--radius-sm);
  padding: 6px 8px;
  font-size: 12px;
  text-decoration: none;
}

.message .attachment-spoiler {
  position: relative;
  border-radius: var(--radius-sm);
  overflow: hidden;
  cursor: pointer;
}

.message .attachment-spoiler .attachment-image,
.message .attachment-spoiler video {
  filter: blur(22px) saturate(1.15);
  transform: scale(1.03);
  transition:
    filter 0.35s ease,
    transform 0.35s ease;
}

.message .attachment-spoiler::before,
.message .attachment-spoiler::after {
  content: "";
  position: absolute;
  inset: -30%;
  background-image:
    radial-gradient(
      circle at 20% 30%,
      color-mix(in srgb, var(--text) 35%, transparent),
      transparent 45%
    ),
    radial-gradient(
      circle at 80% 20%,
      color-mix(in srgb, var(--accent) 45%, transparent),
      transparent 50%
    ),
    radial-gradient(
      circle at 30% 80%,
      color-mix(in srgb, var(--danger) 35%, transparent),
      transparent 50%
    ),
    radial-gradient(
      circle at 70% 70%,
      color-mix(in srgb, var(--accent-2) 45%, transparent),
      transparent 50%
    );
  opacity: 0.45;
  mix-blend-mode: screen;
  animation: spoilerDrift 6s linear infinite;
  pointer-events: none;
}

.message .attachment-spoiler::after {
  animation-duration: 9s;
  opacity: 0.3;
}

.message .attachment-spoiler.is-revealed .attachment-image,
.message .attachment-spoiler.is-revealed video {
  filter: blur(0);
  transform: scale(1);
}

.message .attachment-spoiler.is-revealed::before,
.message .attachment-spoiler.is-revealed::after {
  opacity: 0;
}

@keyframes spoilerDrift {
  0% {
    transform: translate3d(-6%, -4%, 0) rotate(0deg);
  }
  50% {
    transform: translate3d(6%, 8%, 0) rotate(5deg);
  }
  100% {
    transform: translate3d(-4%, 6%, 0) rotate(0deg);
  }
}

.message .attachment-file {
  margin-top: 8px;
  display: inline-flex;
  align-items: center;
  gap: 12px;
  max-width: min(420px, 100%);
  padding: 10px 14px 10px 10px;
  border-radius: var(--radius-md, 14px);
  background: var(--panel-2);
  border: 1px solid var(--stroke);
  color: var(--text);
  font-size: var(--text-sm);
  text-decoration: none;
  transition:
    background var(--anim-fast) var(--ease-out),
    border-color var(--anim-fast) var(--ease-out);
}

.message .attachment-file:hover {
  background: color-mix(in srgb, var(--accent) 8%, var(--panel-2));
  border-color: color-mix(in srgb, var(--accent) 35%, var(--stroke));
}

.message .attachment-file__icon {
  flex: 0 0 auto;
  width: 40px;
  height: 44px;
  border-radius: 8px;
  display: grid;
  place-items: center;
  position: relative;
  background: color-mix(in srgb, var(--accent) 22%, var(--panel));
  color: var(--accent-contrast, #fff);
  /* Folded-corner notch — gives the icon a "document" feel. */
  clip-path: polygon(0 0, 70% 0, 100% 25%, 100% 100%, 0 100%);
}

.message .attachment-file__icon::after {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  width: 30%;
  height: 25%;
  background: color-mix(in srgb, var(--accent) 40%, var(--panel-2));
}

.message .attachment-file__badge {
  position: relative;
  z-index: 1;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.04em;
  line-height: 1;
  margin-top: 6px; /* nudge below the folded corner */
}

/* Tinting per kind — stays within the warm bobr palette by mixing
   against --panel-2 rather than introducing saturated colors. */
.message .attachment-file[data-kind="archive"] .attachment-file__icon {
  background: color-mix(in srgb, #c97a4b 55%, var(--panel-2));
}
.message .attachment-file[data-kind="pdf"] .attachment-file__icon {
  background: color-mix(in srgb, #b34a3a 55%, var(--panel-2));
}
.message .attachment-file[data-kind="doc"] .attachment-file__icon,
.message .attachment-file[data-kind="text"] .attachment-file__icon {
  background: color-mix(in srgb, #7a4b2a 65%, var(--panel-2));
}
.message .attachment-file[data-kind="sheet"] .attachment-file__icon {
  background: color-mix(in srgb, #6a7a3a 60%, var(--panel-2));
}
.message .attachment-file[data-kind="slides"] .attachment-file__icon {
  background: color-mix(in srgb, #c46a3a 55%, var(--panel-2));
}
.message .attachment-file[data-kind="code"] .attachment-file__icon {
  background: color-mix(in srgb, #5a4a6a 60%, var(--panel-2));
}
.message .attachment-file[data-kind="image"] .attachment-file__icon {
  background: color-mix(in srgb, #6a8a7a 60%, var(--panel-2));
}
.message .attachment-file[data-kind="audio"] .attachment-file__icon {
  background: color-mix(in srgb, #a8693f 55%, var(--panel-2));
}
.message .attachment-file[data-kind="video"] .attachment-file__icon {
  background: color-mix(in srgb, #5a6a8a 60%, var(--panel-2));
}

.message .attachment-file__meta {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.message .attachment-file__name {
  display: flex;
  align-items: baseline;
  min-width: 0;
  font-weight: 500;
  color: var(--text);
  line-height: 1.25;
}

.message .attachment-file__stem {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}

.message .attachment-file__ext {
  flex: 0 0 auto;
  color: var(--muted);
}

.message .attachment-file__sub {
  font-size: 12px;
  color: var(--muted);
  line-height: 1.2;
}

.message .attachment-file--error {
  color: color-mix(in srgb, var(--danger, #b33) 80%, var(--text));
  padding: 8px 12px;
}

/* ── Music / audio-file track card (Telegram-style) ──
   Round play button, performer/title from the filename, a thin seekable
   progress bar and elapsed/total time. No waveform — that's voice-only. */
.message .attachment-audio {
  margin-top: 8px;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px 10px 10px;
  border-radius: var(--radius-md, 14px);
  border: 1px solid var(--stroke);
  background: var(--panel-2);
  width: 100%;
  min-width: min(260px, 100%);
  max-width: 420px;
  transition: border-color var(--anim-fast) var(--ease-out);
}

.message .attachment-audio.is-playing {
  border-color: color-mix(in srgb, var(--accent) 45%, var(--stroke));
}

/* Round filled play/pause button — the visual anchor of the card. */
.message .attachment-audio .audio-play {
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: none;
  background: var(--accent);
  color: var(--accent-contrast);
  display: grid;
  place-items: center;
  cursor: pointer;
  transition:
    filter var(--anim-fast) var(--ease-out),
    transform var(--anim-fast) var(--ease-out);
}

.message .attachment-audio .audio-play:hover {
  filter: brightness(1.08);
}

.message .attachment-audio .audio-play:active {
  transform: scale(0.94);
}

.message .attachment-audio .audio-play .icon {
  --icon-size: 18px;
}

/* The play polygon is geometrically left-weighted; nudge it for optical
   centering. The pause glyph is symmetric and stays put. */
.message .attachment-audio .audio-play .icon-play {
  transform: translateX(1.5px);
}

.message .attachment-audio .audio-body {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.message .attachment-audio .audio-info {
  display: flex;
  align-items: baseline;
  gap: 10px;
}

.message .attachment-audio .audio-title {
  flex: 1;
  min-width: 0;
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text);
  line-height: 1.25;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.message .attachment-audio .audio-artist {
  font-weight: 500;
  color: var(--muted);
}

.message .attachment-audio .audio-time {
  flex: 0 0 auto;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  color: var(--muted);
}

/* Thin seekable progress bar */
.message .attachment-audio .audio-track {
  position: relative;
  height: 4px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--muted) 35%, transparent);
  cursor: pointer;
  touch-action: none;
}

.message .attachment-audio .audio-track-fill {
  position: absolute;
  inset: 0 auto 0 0;
  width: 0;
  border-radius: 999px;
  background: var(--accent);
}

.message .attachment-audio .audio-track-thumb {
  position: absolute;
  top: 50%;
  left: 0;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--accent);
  transform: translate(-50%, -50%);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--anim-fast) var(--ease-out);
}

.message .attachment-audio:hover .audio-track-thumb,
.message .attachment-audio.is-playing .audio-track-thumb {
  opacity: 1;
}

.lightbox {
  position: fixed;
  inset: 0;
  background: var(--overlay);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: var(--z-lightbox);
  backdrop-filter: blur(8px);
  touch-action: none;
}

.lightbox.is-video {
  touch-action: auto;
}

.lightbox-slot {
  display: contents;
}

.lightbox-nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 48px;
  height: 48px;
  border-radius: 50%;
  border: none;
  background: rgba(0, 0, 0, 0.45);
  color: rgba(255, 255, 255, 0.9);
  cursor: pointer;
  display: grid;
  place-items: center;
  z-index: 25;
  transition:
    background-color var(--anim-fast) var(--ease-out),
    color var(--anim-fast) var(--ease-out);
}

.lightbox-nav:hover {
  background: rgba(0, 0, 0, 0.65);
  color: #fff;
}

.lightbox-nav[hidden] {
  display: none;
}

.lightbox-nav .icon {
  --icon-size: 26px;
  background-color: currentColor;
}

.lightbox-nav--prev {
  left: 24px;
}

.lightbox-nav--next {
  right: 24px;
}

@media (max-width: 640px) {
  .lightbox-nav {
    width: 40px;
    height: 40px;
  }
  .lightbox-nav--prev {
    left: 10px;
  }
  .lightbox-nav--next {
    right: 10px;
  }
}

.lightbox img {
  max-width: 92vw;
  max-height: 90vh;
  border-radius: 16px;
  border: 1px solid var(--stroke);
  transform: translate(var(--tx, 0px), var(--ty, 0px)) scale(var(--scale, 1))
    rotate(var(--rot, 0deg));
  transition: transform 0.18s ease;
  cursor: zoom-in;
  background: color-mix(in srgb, var(--bg) 80%, #000 20%);
}

/* Quarter-turn rotations: swap viewport caps so the rotated image still fits. */
.lightbox.is-rot-90 img,
.lightbox.is-rot-270 img {
  max-width: 90vh;
  max-height: 92vw;
}

/* ── Custom video player in the lightbox ──
   Fill the viewport box (88vh tall, 92vw wide cap) while keeping the real
   aspect — the aspect-ratio comes from .video-container.is-sized, so small
   clips scale UP to fit instead of sitting tiny in the middle. */
.lightbox .attachment-video {
  width: auto;
  max-width: 92vw;
  justify-content: center;
  align-items: center;
}

.lightbox .attachment-video .video-container {
  width: auto;
  height: 88vh;
  max-width: 92vw;
  max-height: 88vh;
  margin: 0;
  border-radius: 16px;
  border: 1px solid rgba(255, 255, 255, 0.08);
  box-shadow: 0 16px 48px rgba(0, 0, 0, 0.4);
}

.lightbox .attachment-video .video-container video {
  width: 100%;
  height: 100%;
  max-width: none;
  max-height: none;
  object-fit: contain;
  border-radius: 16px;
}

.lightbox .attachment-video .video-controls-overlay {
  border-radius: 16px;
}

.lightbox.is-zoomed img {
  cursor: grab;
}

.lightbox.is-dragging img {
  cursor: grabbing;
  transition: none;
}

.lightbox .toolbar {
  position: absolute;
  top: 18px;
  right: 20px;
  display: flex;
  align-items: center;
  gap: 12px;
}

.lightbox-kebab-wrap {
  position: relative;
}

.lightbox-kebab {
  width: 36px;
  height: 36px;
  border: none;
  background: transparent;
  color: rgba(255, 255, 255, 0.85);
  cursor: pointer;
  display: grid;
  place-items: center;
  border-radius: 50%;
  transition:
    background-color var(--anim-fast) var(--ease-out),
    color var(--anim-fast) var(--ease-out);
}

.lightbox-kebab .icon {
  --icon-size: 20px;
  background-color: currentColor;
}

.lightbox-kebab:hover,
.lightbox-kebab[aria-expanded="true"] {
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
}

.lightbox-menu {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  min-width: 200px;
  background: var(--panel);
  border: 1px solid var(--stroke);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow);
  padding: var(--space-1);
  display: flex;
  flex-direction: column;
  gap: 2px;
  z-index: 25;
  animation: menuIn var(--anim-fast) var(--ease-spring);
  transform-origin: top right;
}

.lightbox-menu[hidden] {
  display: none;
}

.lightbox-menu-item {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: 8px 10px;
  border: none;
  background: transparent;
  color: var(--text);
  font-size: var(--text-sm);
  text-align: left;
  cursor: pointer;
  border-radius: var(--radius-sm);
  transition: background-color var(--anim-fast) var(--ease-out);
}

.lightbox-menu-item:hover {
  background: color-mix(in srgb, var(--accent) 14%, transparent);
}

.lightbox-menu-item .icon {
  --icon-size: 16px;
  flex-shrink: 0;
}

/* Фэн-шуй для видео-плеера */
.video-container.controls-bar-hidden .video-controls-bottom {
  display: none;
}

/* В полноэкранном режиме ВСЕГДА показываем контролы, даже если они были скрыты */
.video-container:fullscreen .video-controls-bottom,
.video-container:-webkit-full-screen .video-controls-bottom {
  display: flex !important;
}

/* Тулбар лайтбокса поверх видеоплеера */
.lightbox .toolbar {
  z-index: 20;
}

/* Outgoing side: caption / file-link under the highlight bubble
   reads against the default panel; no need to inherit color since
   these elements are siblings of the bubble, not children. */

/* === mobile.css === */
@media (max-width: 900px) {
  .app-shell {
    grid-template-columns: 1fr;
    grid-template-rows: 1fr;
    padding: 12px;
    gap: 0;
  }

  .sidebar-resizer {
    display: none;
  }

  .app-shell:not(.mobile-chat-open) .chat-panel {
    display: none;
  }

  .app-shell.mobile-chat-open .sidebar {
    display: none;
  }
}

@media (max-width: 720px) {
  .app-shell {
    padding: 0;
    grid-template-rows: 1fr;
    height: 100svh;
    height: 100dvh;
  }

  .sidebar {
    padding: 16px;
    height: 100%;
    border-radius: 0;
    border: none;
  }

  .chat-panel {
    height: 100%;
    border-radius: 0;
    border: none;
  }

  .back-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }

  .sidebar {
    max-height: none;
    overflow: visible;
  }

  .chat-list {
    gap: 8px;
    padding: 8px 0;
  }

  .user-item,
  .chat-item {
    margin: 0 8px;
    padding: 12px;
  }

  .folder-scroll {
    display: none;
  }

  .chat-header {
    padding: 12px 16px;
    height: auto;
    min-height: 70px;
    flex-direction: row;
    align-items: center;
    gap: 12px;
  }

  .chat-header-meta {
    gap: 2px;
  }

  .chat-title h3 {
    font-size: 16px;
  }

  .chat-right {
    margin-left: auto;
  }

  .messages {
    padding: 12px 16px;
    scroll-behavior: smooth;
  }

  .floating-search-island {
    top: 80px;
    width: 94%;
  }

  .message {
    max-width: 85%;
  }

  .composer {
    padding: 10px 12px;
    padding-bottom: calc(10px + env(safe-area-inset-bottom) + var(--keyboard-offset, 0px));
    background: var(--panel);
    border-top: 1px solid var(--stroke);
    gap: 8px;
    /* We use padding-bottom instead of transform for better stability with fixed headers */
    transition: padding-bottom var(--anim-fast) var(--ease-out);
  }

  .composer input,
  .composer textarea {
    font-size: 16px; /* Prevent auto-zoom on iOS */
  }

  .message-actions {
    display: none;
  }

  .reaction-jump-banner {
    right: 14px;
    bottom: calc(166px + env(safe-area-inset-bottom) + var(--keyboard-offset, 0px));
    max-width: calc(100% - 28px);
  }

  .reaction-jump-text {
    max-width: 160px;
  }

  .scroll-to-bottom-button {
    right: 14px;
    bottom: calc(222px + env(safe-area-inset-bottom) + var(--keyboard-offset, 0px));
    width: 56px;
    height: 56px;
  }
}

/* === settings.css === */

/* === settings/base.css === */
/* Shared settings foundation */
.sidebar-footer {
  margin-top: auto;
  padding-top: 16px;
  position: relative;
}

.footer-divider {
  height: 1px;
  background: var(--stroke);
  margin-bottom: 12px;
}

.user-menu-trigger {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  border-radius: 16px;
  border: 1px solid var(--stroke);
  background: var(--panel-2);
  color: var(--text);
  cursor: pointer;
  text-align: left;
  transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
}

.user-menu-trigger:hover {
  background: color-mix(in srgb, var(--accent) 8%, var(--panel-2));
  border-color: color-mix(in srgb, var(--accent) 30%, var(--stroke));
  transform: translateY(-1px);
}

.user-menu-trigger .avatar {
  width: 38px;
  height: 38px;
  border-radius: 12px;
  font-size: 14px;
  flex-shrink: 0;
  border: 1px solid color-mix(in srgb, var(--text) 10%, transparent);
}

.user-menu-meta {
  display: flex;
  flex-direction: column;
  min-width: 0;
  flex: 1;
}

.user-menu-meta span {
  font-weight: 600;
  font-size: 14px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.user-menu-meta small {
  color: var(--muted);
  font-size: 12px;
}

.user-menu-trigger .chevron {
  color: var(--muted);
  --icon-size: 14px;
  transition:
    transform 0.2s,
    color 0.2s;
  margin-left: 8px;
  transform: rotate(0deg);
}

.user-menu-trigger:hover .chevron {
  color: var(--text);
}

.user-menu-trigger.is-open .chevron {
  transform: rotate(180deg);
}

.user-menu-dropdown {
  position: absolute;
  bottom: calc(100% + 8px);
  left: 20px;
  right: 20px;
  background: var(--glass-bg);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  border: 1px solid var(--glass-stroke);
  border-radius: 14px;
  padding: 6px;
  box-shadow: var(--glass-shadow);
  z-index: 1001;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.user-menu-dropdown {
  background: var(--panel);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  border: 1px solid var(--stroke);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow);
}

.dropdown-item {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  border-radius: 10px;
  border: none;
  background: transparent;
  color: var(--text);
  font-size: 13px;
  cursor: pointer;
  transition:
    background 0.15s,
    color 0.15s,
    transform 0.1s;
  text-decoration: none;
}

.dropdown-item:hover {
  background: color-mix(in srgb, var(--accent) 15%, transparent);
}

.dropdown-item:active {
  transform: scale(0.97);
}

.dropdown-item .icon {
  --icon-size: 14px;
}

.dropdown-item .menu-emoji {
  font-size: 14px;
}

.dropdown-item.danger {
  color: var(--danger);
}

.dropdown-item.danger:hover {
  background: color-mix(in srgb, var(--danger) 10%, transparent);
}

.dropdown-item.premium-item {
  color: var(--accent);
  font-weight: 600;
  padding-bottom: 8px;
  margin-bottom: 2px;
  border-bottom: 1px solid color-mix(in srgb, var(--stroke) 60%, transparent);
  border-radius: 10px 10px 0 0;
}

.dropdown-item.premium-item:hover {
  background: color-mix(in srgb, var(--accent) 12%, transparent);
}

.modal {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: var(--z-modal);
}

.modal-backdrop {
  position: absolute;
  inset: 0;
  background: var(--overlay);
  backdrop-filter: blur(6px);
}

.modal-card {
  position: relative;
  width: min(760px, 92vw);
  max-height: min(78vh, 720px);
  background: var(--glass-bg);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  border-radius: 18px;
  border: 1px solid var(--glass-stroke);
  box-shadow: var(--glass-shadow);
  padding: 22px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  overflow: hidden;
}

.modal-card.small {
  width: min(420px, 92vw);
}

.modal-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 16px;
}

.modal-header h3 {
  margin: 0;
  font-size: 20px;
}

.modal-header p {
  margin: 4px 0 0;
  color: var(--muted);
  font-size: 13px;
}

.modal-close {
  border: 1px solid var(--stroke);
  background: transparent;
  color: var(--text);
  border-radius: 12px;
  width: 36px;
  height: 36px;
  cursor: pointer;
  font-size: 18px;
}

.modal-body {
  display: flex;
  flex-direction: column;
  gap: 18px;
  min-height: 0;
}

.notify-actions {
  display: flex;
  gap: 12px;
  margin-top: 6px;
}

.notify-actions .button {
  flex: 1;
}

.notify-actions .button.secondary {
  margin-top: 0;
}

.notify-hint {
  font-size: 12px;
  color: var(--muted);
  text-align: center;
}

.settings-body {
  display: grid;
  grid-template-columns: 1fr 180px;
  gap: 18px;
  min-height: 0;
}

.settings-nav {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.settings-tab {
  border: 1px solid var(--stroke);
  border-radius: 12px;
  background: color-mix(in srgb, var(--panel-2) 60%, transparent);
  color: var(--muted);
  padding: 10px 12px;
  font-size: 13px;
  cursor: pointer;
  text-align: left;
}

.settings-tab.is-active {
  border-color: color-mix(in srgb, var(--accent) 60%, transparent);
  color: var(--text);
  background: color-mix(in srgb, var(--accent) 12%, transparent);
}

.settings-content {
  overflow-y: auto;
  padding-right: 6px;
  position: relative;
}

.settings-panel {
  display: flex;
  flex-direction: column;
  gap: 18px;
  opacity: 0;
  transform: translateY(10px);
  visibility: hidden;
  position: absolute;
  inset: 0;
  width: 100%;
  pointer-events: none;
  transition:
    opacity var(--anim-med) var(--ease-out),
    transform var(--anim-med) var(--ease-out),
    visibility var(--anim-med);
}

.settings-panel.is-active {
  opacity: 1;
  transform: translateY(0);
  visibility: visible;
  position: relative;
  pointer-events: auto;
}

.settings-panel.is-leaving {
  opacity: 0;
  transform: translateY(-8px);
}

.settings-panel h4 {
  margin: 0;
  font-size: 16px;
}

.panel-block {
  background: color-mix(in srgb, var(--panel-2) 40%, transparent);
  border: 1px solid var(--stroke);
  border-radius: 14px;
  padding: 14px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.panel-block h5 {
  margin: 0;
  font-size: 14px;
}

.privacy-blocked-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.privacy-row {
  display: flex;
  align-items: center;
  gap: 10px;
  border: 1px solid color-mix(in srgb, var(--stroke) 82%, transparent);
  background: color-mix(in srgb, var(--panel) 74%, transparent);
  border-radius: 12px;
  padding: 10px 10px 10px 12px;
}

.privacy-user-link {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: 1;
  min-width: 0;
  padding: 0;
  margin: 0;
  border: none;
  background: transparent;
  color: inherit;
  text-align: left;
  cursor: pointer;
}

.privacy-user-link:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 45%, transparent);
  border-radius: 10px;
}

.privacy-row .avatar {
  width: 34px;
  height: 34px;
  border-radius: 10px;
  font-size: 12px;
}

.privacy-row-meta {
  min-width: 0;
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.privacy-row-name {
  font-size: 13px;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.privacy-row-handle {
  font-size: 11px;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.privacy-unblock-btn {
  flex: 0 0 auto;
  width: auto;
  margin: 0;
  padding: 6px 11px;
  border: 1px solid color-mix(in srgb, var(--stroke) 82%, transparent);
  border-radius: 10px;
  background: color-mix(in srgb, var(--panel-2) 64%, transparent);
  color: var(--text);
  font-size: 12px;
  font-weight: 500;
  white-space: nowrap;
  cursor: pointer;
  transition:
    background 0.2s ease,
    border-color 0.2s ease,
    transform 0.15s ease;
}

.privacy-unblock-btn:hover {
  background: color-mix(in srgb, var(--accent) 16%, var(--panel-2));
  border-color: color-mix(in srgb, var(--accent) 32%, transparent);
}

.privacy-unblock-btn:active {
  transform: translateY(1px);
}

.privacy-empty {
  border: 1px dashed var(--stroke);
  border-radius: 12px;
  padding: 12px;
  text-align: center;
  font-size: 12px;
  color: var(--muted);
}

.inline-form {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}

.inline-form input {
  flex: 1;
  min-width: 180px;
}

.stack {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.modal input {
  border-radius: 12px;
  border: 1px solid transparent;
  background: var(--panel-2);
  color: var(--text);
  padding: 10px 12px;
  font-size: 14px;
}

.settings-select {
  border-radius: 12px;
  border: 1px solid transparent;
  background: var(--panel-2);
  color: var(--text);
  padding: 10px 12px;
  font-size: 14px;
}

.settings-select:disabled {
  opacity: 0.6;
}

.modal textarea {
  border-radius: 12px;
  border: 1px solid transparent;
  background: var(--panel-2);
  color: var(--text);
  padding: 10px 12px;
  font-size: 14px;
  resize: vertical;
  min-height: 84px;
}

.modal input:focus {
  outline: none;
  border-color: color-mix(in srgb, var(--accent) 50%, transparent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 20%, transparent);
}

.settings-select:focus {
  outline: none;
  border-color: color-mix(in srgb, var(--accent) 50%, transparent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 20%, transparent);
}

.modal textarea:focus {
  outline: none;
  border-color: color-mix(in srgb, var(--accent) 50%, transparent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 20%, transparent);
}

.button.small {
  padding: 8px 12px;
  font-size: 13px;
}

.button.secondary {
  background: transparent;
  border: 1px solid var(--stroke);
  color: var(--text);
  margin-top: 10px;
}

.form-status {
  font-size: 12px;
  color: var(--muted);
}

.form-status.error {
  color: var(--danger);
}
#settings-modal .modal-card {
  will-change: height;
}
.muted {
  color: var(--muted);
  font-size: 12px;
}
.d-block {
  display: block;
}
.text-center {
  text-align: center;
}
.mt-2 {
  margin-top: 8px;
}
.mt-4 {
  margin-top: 16px;
}
.mb-2 {
  margin-bottom: 8px;
}
.mb-4 {
  margin-bottom: 16px;
}

/* === settings/panel-profile.css === */
/* =============================================================
   Account section v2 — hero card + notify card + bento grid.
   Old .profile-grid styles are kept at the bottom for fallback.
   ============================================================= */

/* Widen the section body when the account v2 page is mounted —
   bento grid needs more horizontal room than the default 640px. */
.settings-main:has(.account-page) .settings-section-body {
  max-width: 880px;
}

.account-page {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

/* ---------- Hero card --------------------------------------- */

.account-hero {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: var(--space-5);
  padding: var(--space-5);
  background: var(--panel);
  border: 1px solid var(--stroke);
  border-radius: var(--radius-md);
  position: relative;
  overflow: hidden;
}

.account-hero::before {
  /* Soft accent wash behind the avatar — subtle warmth, no visual noise. */
  content: "";
  position: absolute;
  top: -40%;
  left: -10%;
  width: 280px;
  height: 280px;
  background: radial-gradient(
    closest-side,
    color-mix(in srgb, var(--accent) 14%, transparent),
    transparent 80%
  );
  pointer-events: none;
  z-index: 0;
}

.account-hero > * {
  position: relative;
  z-index: 1;
}

.account-hero-avatar .avatar.large {
  width: 96px;
  height: 96px;
  border-radius: 24px;
  font-size: 32px;
  box-shadow: 0 6px 18px color-mix(in srgb, var(--accent) 22%, transparent);
  border: 1px solid var(--stroke);
}

.account-hero-info {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}

.account-hero-name {
  font-size: 22px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--text);
  line-height: 1.2;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.account-hero-handle-row {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  align-self: flex-start;
}

.account-hero-handle {
  font-family: var(--font-mono, monospace);
  font-size: 13px;
  color: var(--muted);
  background: var(--panel-2);
  border: 1px solid var(--stroke);
  border-radius: var(--radius-sm);
  padding: 3px 8px;
  user-select: text;
}

.account-hero-copy {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: var(--radius-sm);
  background: transparent;
  border: 1px solid transparent;
  color: var(--muted);
  cursor: pointer;
  transition:
    background 0.15s ease,
    color 0.15s ease,
    border-color 0.15s ease;
}

.account-hero-copy:hover {
  background: var(--panel-2);
  color: var(--text);
  border-color: var(--stroke);
}

.account-hero-copy .icon {
  --icon-size: 14px;
}

.account-hero-copy.is-copied {
  background: color-mix(in srgb, var(--accent) 18%, transparent);
  color: var(--accent);
  border-color: color-mix(in srgb, var(--accent) 40%, transparent);
}

.account-hero-bio {
  margin: 4px 0 0;
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--text);
  max-width: 48ch;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.account-hero-bio.is-empty {
  color: var(--muted);
  font-style: italic;
}

.account-hero-actions {
  align-self: center;
}

.account-hero-edit {
  background: var(--accent);
  color: var(--accent-contrast, #fff);
  border: none;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-weight: 500;
}

.account-hero-edit:hover {
  background: color-mix(in srgb, var(--accent) 88%, #000);
}

.account-hero-edit:hover .account-hero-edit-arrow {
  transform: translateX(3px);
}

.account-hero-edit-arrow {
  transition: transform 0.18s var(--ease-out, ease-out);
  font-size: 13px;
}

/* ---------- Notify card ------------------------------------- */

.account-notify-card {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  column-gap: var(--space-4);
  row-gap: 6px;
  padding: var(--space-4) var(--space-5);
  background: var(--panel);
  border: 1px solid var(--stroke);
  border-radius: var(--radius-md);
}

.account-notify-text h5 {
  margin: 0;
  font-size: 14px;
  font-weight: 600;
}

.account-notify-text p {
  margin: 2px 0 0;
  font-size: 12.5px;
}

.account-notify-toggle {
  /* Reverse the default toggle layout: label first, then the switch. */
  flex-direction: row-reverse;
  justify-content: flex-end;
  gap: 12px;
  padding: 0;
}

.account-notify-toggle-label {
  font-size: 13px;
  color: var(--muted);
}

.account-notify-card .form-status {
  grid-column: 1 / -1;
}

.account-notify-card .form-status:empty {
  display: none;
}

/* ---------- Bento grid -------------------------------------- */

.account-bento-head {
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  padding: 0 4px;
}

.account-bento-head h5 {
  margin: 0;
  font-size: 14px;
  font-weight: 600;
}

.account-bento-head .muted {
  font-size: 12.5px;
}

.account-bento-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--space-3);
  margin-top: var(--space-3);
}

.account-bento-tile {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-4);
  background: var(--panel);
  border: 1px solid var(--stroke);
  border-radius: var(--radius-md);
  color: var(--text);
  text-decoration: none;
  transition:
    transform 0.18s var(--ease-out, ease-out),
    border-color 0.18s ease,
    background 0.18s ease,
    box-shadow 0.18s ease;
}

.account-bento-tile:hover {
  transform: translateY(-2px);
  border-color: color-mix(in srgb, var(--accent) 35%, var(--stroke));
  box-shadow: 0 8px 22px color-mix(in srgb, var(--accent) 12%, transparent);
}

.account-bento-tile:hover .account-bento-tile-arrow {
  transform: translateX(3px);
  color: var(--accent);
}

.account-bento-tile-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--accent) 12%, var(--panel-2));
  color: var(--accent);
}

.account-bento-tile-icon .icon {
  --icon-size: 18px;
}

.account-bento-tile-body {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.account-bento-tile-label {
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.005em;
  color: var(--text);
}

.account-bento-tile-hint {
  font-size: 12px;
  color: var(--muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.account-bento-tile-arrow {
  color: var(--muted);
  font-size: 16px;
  transition:
    transform 0.18s var(--ease-out, ease-out),
    color 0.18s ease;
}

/* ---------- Edit modal -------------------------------------- */

.account-edit-card {
  width: min(520px, calc(100vw - 32px));
  max-height: calc(100vh - 64px);
  display: flex;
  flex-direction: column;
}

.account-edit-body {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--space-5);
  align-items: start;
  overflow-y: auto;
}

.account-edit-avatar-block {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  text-align: center;
}

.account-edit-avatar-preview {
  width: 112px;
  height: 112px;
  border-radius: 24px;
  font-size: 36px;
  border: 1px solid var(--stroke);
}

.account-edit-fields {
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-width: 0;
}

.account-edit-fields label.muted {
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: -4px;
}

/* @username field: a fixed "@" sits inside the input's left padding. */
.profile-username-field {
  position: relative;
  display: flex;
  align-items: center;
}

.profile-username-at {
  position: absolute;
  left: 12px;
  color: var(--muted);
  pointer-events: none;
  font-size: 14px;
}

.profile-username-field #profile-nickname {
  flex: 1;
  min-width: 0;
  padding-left: 26px;
}

.account-edit-fields .profile-handle {
  font-family: var(--font-mono, monospace);
  font-size: 12px;
  color: var(--muted);
  background: var(--panel-2);
  border: 1px solid var(--stroke);
  border-radius: var(--radius-sm);
  padding: 4px 8px;
  width: fit-content;
  margin-top: -2px;
}

/* Doubles as the live username-validation hint. */
.account-edit-fields .profile-handle.error {
  color: var(--danger, #e5484d);
  border-color: var(--danger, #e5484d);
  background: color-mix(in srgb, var(--danger, #e5484d) 12%, transparent);
}

.account-edit-fields .profile-handle[hidden] {
  display: none;
}

.account-edit-fields #profile-bio-count {
  text-align: right;
  font-size: 11px;
}

.account-edit-footer .form-status {
  flex: 1;
  text-align: left;
  font-size: 12px;
}

.account-edit-footer .form-status:empty {
  display: none;
}

/* ---------- Mobile ------------------------------------------ */

@media (max-width: 720px) {
  .settings-main:has(.account-page) .settings-section-body {
    max-width: none;
  }

  .account-hero {
    grid-template-columns: 1fr;
    text-align: left;
    gap: var(--space-3);
    padding: var(--space-4);
  }

  .account-hero-avatar {
    justify-self: start;
  }

  .account-hero-avatar .avatar.large {
    width: 80px;
    height: 80px;
    border-radius: 20px;
    font-size: 28px;
  }

  .account-hero-name {
    font-size: 19px;
  }

  .account-hero-actions {
    align-self: stretch;
  }

  .account-hero-edit {
    width: 100%;
    justify-content: center;
  }

  .account-notify-card {
    grid-template-columns: 1fr;
  }

  .account-notify-toggle {
    justify-self: flex-end;
  }

  .account-bento-grid {
    grid-template-columns: 1fr;
  }

  .account-edit-body {
    grid-template-columns: 1fr;
    gap: var(--space-4);
  }

  .account-edit-avatar-block {
    align-items: flex-start;
    text-align: left;
  }
}

/* =============================================================
   Legacy .profile-grid — kept for any other consumer.
   ============================================================= */
.profile-grid {
  display: grid;
  grid-template-columns: 160px 1fr;
  gap: 24px;
}

.profile-avatar-block {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  text-align: center;
}

.profile-avatar-block .avatar.large {
  width: 120px;
  height: 120px;
  border-radius: 32px;
  font-size: 42px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2);
}

.profile-fields {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.profile-fields label {
  margin-bottom: -4px;
  font-weight: 500;
}

.profile-handle {
  font-family: var(--font-mono, monospace);
  font-size: 13px;
  color: var(--muted);
  background: var(--panel-2);
  padding: 4px 8px;
  border-radius: 6px;
  display: inline-block;
  width: fit-content;
}

#profile-bio-count {
  text-align: right;
}

/* === settings/panel-audio.css === */
/* Audio panel styles */
.settings-audio-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 14px;
}

.settings-audio-field {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.settings-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: 1px solid var(--stroke);
  border-radius: 999px;
  padding: 6px 12px;
  font-size: 12px;
  color: var(--muted);
  background: var(--panel-2);
}

.settings-chip input {
  accent-color: var(--accent-2);
}

.settings-chip.is-active {
  color: var(--text);
  border-color: color-mix(in srgb, var(--accent) 60%, transparent);
  background: color-mix(in srgb, var(--accent) 12%, transparent);
}
.settings-sensitivity {
  display: grid;
  gap: 12px;
}

.settings-sensitivity-modes {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
}

.settings-sensitivity-value {
  margin-left: auto;
  font-size: 12px;
  color: var(--muted);
}

.settings-sensitivity-track {
  position: relative;
  display: flex;
  align-items: center;
  min-height: 20px;
}

.settings-sensitivity-track::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: 5px;
  transform: translateY(-50%);
  border-radius: 999px;
  background: color-mix(in srgb, var(--panel-2) 80%, transparent);
  box-shadow: inset 0 0 0 1px var(--stroke);
  z-index: 0;
}

.settings-sensitivity-level {
  position: absolute;
  left: 0;
  top: 50%;
  height: 5px;
  width: calc(var(--level, 0) * 100%);
  transform: translateY(-50%);
  background: color-mix(in srgb, var(--accent) 70%, transparent);
  box-shadow: 0 0 12px color-mix(in srgb, var(--accent) 35%, transparent);
  border-radius: 999px;
  pointer-events: none;
  opacity: 0.75;
  z-index: 1;
}

.settings-sensitivity-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
}

.settings-sensitivity-actions .muted {
  flex: 1 1 200px;
}
.settings-range {
  width: 100%;
  appearance: none;
  height: 18px;
  border-radius: 999px;
  border: none;
  background: transparent;
  position: relative;
  z-index: 2;
}

.settings-range::-webkit-slider-thumb {
  appearance: none;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--accent) 75%, var(--text));
  border: 2px solid color-mix(in srgb, var(--panel) 70%, transparent);
  box-shadow: 0 2px 8px color-mix(in srgb, var(--accent) 30%, transparent);
  cursor: pointer;
}

.settings-range::-webkit-slider-runnable-track {
  height: 6px;
  border-radius: 999px;
  background: transparent;
  border: none;
}

.settings-range::-moz-range-thumb {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--accent) 75%, var(--text));
  border: 2px solid color-mix(in srgb, var(--panel) 70%, transparent);
  box-shadow: 0 2px 8px color-mix(in srgb, var(--accent) 30%, transparent);
  cursor: pointer;
}

.settings-range::-moz-range-track {
  height: 6px;
  border-radius: 999px;
  background: transparent;
  border: none;
}

/* Ringtone section (moved from interface.html) */
.ringtone-controls {
  display: flex;
  flex-wrap: nowrap;
  gap: 10px;
  align-items: center;
  margin-top: var(--space-2);
}

.ringtone-controls .button {
  width: auto;
  flex: 1 1 0;
  margin-bottom: 0;
}

.ringtone-controls .button.secondary {
  margin-top: 0;
}

#ringtone-volume {
  width: 100%;
}

.glass-slider-wrap {
  margin-top: 8px;
  padding: var(--space-3);
  background: color-mix(in srgb, var(--panel-2) 72%, transparent);
  border: 1px solid var(--stroke);
  border-radius: var(--radius-md);
}

.glass-range {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 6px;
  background: color-mix(in srgb, var(--text) 12%, transparent);
  border-radius: 3px;
  outline: none;
  cursor: pointer;
}

.glass-range::-webkit-slider-runnable-track {
  width: 100%;
  height: 6px;
  background: color-mix(in srgb, var(--text) 12%, transparent);
  border-radius: 3px;
}

.glass-range::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 16px;
  height: 16px;
  background: color-mix(in srgb, var(--accent) 84%, var(--text));
  border-radius: 50%;
  box-shadow: 0 2px 8px color-mix(in srgb, #000 24%, transparent);
  cursor: pointer;
  margin-top: -5px;
  transition:
    background var(--anim-fast) var(--ease-out),
    transform var(--anim-fast) var(--ease-out),
    box-shadow var(--anim-fast) var(--ease-out);
  border: none;
}

.glass-range:hover::-webkit-slider-thumb {
  background: var(--accent);
  box-shadow: 0 0 12px color-mix(in srgb, var(--accent) 45%, transparent);
  transform: scale(1.1);
}

.glass-range::-moz-range-track {
  width: 100%;
  height: 6px;
  background: color-mix(in srgb, var(--text) 12%, transparent);
  border-radius: 3px;
}

.glass-range::-moz-range-thumb {
  width: 16px;
  height: 16px;
  background: color-mix(in srgb, var(--accent) 84%, var(--text));
  border-radius: 50%;
  box-shadow: 0 2px 8px color-mix(in srgb, #000 24%, transparent);
  cursor: pointer;
  border: none;
}

.glass-range:hover::-moz-range-thumb {
  background: var(--accent);
  box-shadow: 0 0 12px color-mix(in srgb, var(--accent) 45%, transparent);
  transform: scale(1.1);
}

/* === settings/panel-security.css === */

/* === settings/security/overview.css === */
/* Security panel styles */
/* Security Grid & Cards - Billion Dollar Edition */
.security-view {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

/* Each overview zone: a labelled group of cards (login & protection) or the
   folded-in privacy block. */
.security-section {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.security-section-head {
  display: flex;
  align-items: center;
  gap: 8px;
}

.security-section-head h5 {
  margin: 0;
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -0.005em;
}

.security-section-head .muted {
  margin-left: auto;
}

.security-section-head .icon {
  --icon-size: 16px;
  color: var(--muted);
}

.security-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-4);
}

@media (max-width: 560px) {
  .security-grid {
    grid-template-columns: 1fr;
  }
}

.security-card {
  position: relative;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-5);
  background: var(--panel);
  border: 1px solid var(--stroke);
  border-radius: var(--radius-lg);
  cursor: pointer;
  text-align: left;
  transition:
    background var(--anim-fast) var(--ease-out),
    border-color var(--anim-fast) var(--ease-out);
}

/* Hover doesn't move the card — it just lifts the border/fill so the affordance
   reads without a layout-shifting transform. */
.security-card:hover {
  background: color-mix(in srgb, var(--accent) 5%, var(--panel));
  border-color: color-mix(in srgb, var(--accent) 35%, var(--stroke));
}

.security-card:focus-visible {
  outline: 2px solid color-mix(in srgb, var(--accent) 60%, transparent);
  outline-offset: 2px;
}

.security-card-content {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  text-align: left;
  min-width: 0;
}

.security-card-icon {
  width: 44px;
  height: 44px;
  min-width: 44px;
  flex-shrink: 0;
  border-radius: var(--radius-md);
  background: color-mix(in srgb, var(--accent) 12%, var(--panel-2));
  color: var(--accent);
  display: grid;
  place-items: center;
  transition:
    background var(--anim-fast) var(--ease-out),
    color var(--anim-fast) var(--ease-out);
}

.security-card:hover .security-card-icon {
  background: var(--accent);
  color: var(--accent-contrast);
}

.security-card-icon .icon {
  --icon-size: 22px;
}

.security-card-text h6 {
  margin: 0 0 2px;
  font-size: var(--text-md);
  font-weight: 600;
  color: var(--text);
  letter-spacing: -0.005em;
  line-height: 1.3;
}

.security-card-text p {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--muted);
  line-height: 1.4;
}

.security-card-arrow {
  flex-shrink: 0;
  color: var(--muted);
  font-weight: 600;
  font-size: 16px;
  opacity: 0.6;
  transition:
    color var(--anim-fast) var(--ease-out),
    transform var(--anim-fast) var(--ease-out);
}

.security-card:hover .security-card-arrow {
  color: var(--accent);
  transform: translateX(3px);
}

@media (prefers-reduced-motion: reduce) {
  .security-card,
  .security-card-icon,
  .security-card-arrow {
    transition: none;
  }
  .security-card:hover .security-card-arrow {
    transform: none;
  }
}

/* Security Header & Navigation */
.security-header {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-bottom: 24px;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--stroke);
}

.security-header h5 {
  margin: 0;
  font-size: 20px;
  font-weight: 700;
  letter-spacing: -0.01em;
}

.back-arrow {
  width: 40px;
  height: 40px;
  border-radius: 12px;
  background: transparent;
  color: var(--text);
  border: 1px solid var(--stroke);
  transition: all 0.2s ease;
  display: grid;
  place-items: center;
}

.back-arrow:hover {
  background: var(--panel-2);
  border-color: var(--accent);
  color: var(--accent);
  transform: translateX(-2px);
}

/* Auth Gate - Unlock Screen Style */
.auth-gate-body {
  flex-grow: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  max-width: 360px;
  margin: 0 auto;
  padding: 32px 24px;
  background: linear-gradient(145deg, var(--panel), var(--panel-2));
  border: 1px solid var(--stroke);
  border-radius: 24px;
  box-shadow: 0 12px 32px -12px rgba(0, 0, 0, 0.15);
}

.auth-icon-lock {
  width: 88px;
  height: 88px;
  border-radius: 24px;
  background: linear-gradient(135deg, color-mix(in srgb, var(--accent) 15%, transparent), color-mix(in srgb, var(--accent) 5%, transparent));
  color: var(--accent);
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 auto 24px;
  border: 1px solid color-mix(in srgb, var(--accent) 20%, transparent);
  box-shadow: inset 0 2px 10px rgba(255, 255, 255, 0.1), 0 8px 24px -8px color-mix(in srgb, var(--accent) 40%, transparent);
  animation: authLockPulse 3s ease-in-out infinite;
}

@keyframes authLockPulse {
  0% { box-shadow: inset 0 2px 10px rgba(255, 255, 255, 0.1), 0 8px 24px -8px color-mix(in srgb, var(--accent) 40%, transparent); transform: translateY(0); }
  50% { box-shadow: inset 0 2px 10px rgba(255, 255, 255, 0.1), 0 12px 32px -4px color-mix(in srgb, var(--accent) 60%, transparent); transform: translateY(-3px); }
  100% { box-shadow: inset 0 2px 10px rgba(255, 255, 255, 0.1), 0 8px 24px -8px color-mix(in srgb, var(--accent) 40%, transparent); transform: translateY(0); }
}

.auth-gate-body .muted {
  font-size: 15px;
  line-height: 1.5;
  letter-spacing: -0.01em;
  font-weight: 500;
  color: var(--text);
  opacity: 0.85;
}

.auth-icon-lock .icon {
  --icon-size: 44px;
}

/* Action Views & Wizards */
.passkey-hero {
  background: linear-gradient(180deg, var(--panel-2) 0%, transparent 100%);
  border-radius: var(--radius-lg);
  padding: 40px 32px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 20px;
  border: 1px dashed var(--stroke);
  text-align: center;
}

.hero-icon {
  width: 72px;
  height: 72px;
  border-radius: 50%;
  background: var(--accent);
  color: var(--accent-contrast);
  display: grid;
  place-items: center;
  box-shadow: 0 10px 24px -8px color-mix(in srgb, var(--accent) 50%, transparent);
}

.hero-icon .icon {
  --icon-size: 36px;
}

/* 2FA Status & QR */
.status-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  padding: 24px;
  background: var(--panel-2);
  border-radius: 20px;
  border: 1px solid var(--stroke);
}

.status-card .icon {
  --icon-size: 56px;
  filter: drop-shadow(0 4px 12px rgba(0, 0, 0, 0.1));
}

.qr-card {
  background: white;
  padding: 20px;
  border-radius: 28px;
  box-shadow: 0 20px 60px -10px rgba(0, 0, 0, 0.15);
  display: inline-block;
  position: relative;
  transition: transform 0.3s;
}

.qr-card:hover {
  transform: scale(1.02);
}

.qr-card img {
  display: block;
  width: 220px;
  height: 220px;
}

.secret-code-row {
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--panel-2);
  padding: 8px 8px 8px 16px;
  border-radius: 14px;
  border: 1px solid var(--stroke);
}

.code-font {
  font-family: "IBM Plex Mono", monospace;
  font-size: 16px;
  letter-spacing: 0.05em;
  font-weight: 600;
  color: var(--text);
}

.confirm-island {
  background: color-mix(in srgb, var(--danger) 10%, var(--panel));
  border: 1px solid color-mix(in srgb, var(--danger) 30%, transparent);
  padding: 20px;
  border-radius: 18px;
  text-align: center;
  animation: slideDown 0.3s ease-out;
}

.header-content {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex: 1;
}

/* Utilities */
.centered-block {
  max-width: 380px;
  margin-left: auto;
  margin-right: auto;
  width: 100%;
}

.centered-form {
  width: 100%;
}

.full-width {
  width: 100%;
}

.no-border {
  border: none !important;
  background: transparent !important;
  padding: 0 !important;
}

/* === settings/security/passkey-and-2fa.css === */
@media (max-width: 600px) {
  .security-grid {
    grid-template-columns: 1fr;
  }
}

.passkey-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.passkey-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px;
  border-radius: 12px;
  border: 1px solid var(--stroke);
  background: var(--panel-2);
}

.passkey-item input {
  flex: 1;
}

.passkey-meta {
  display: flex;
  flex-direction: column;
  gap: 4px;
  flex: 1;
  color: var(--muted);
  font-size: 12px;
}

.passkey-actions {
  display: flex;
  gap: 6px;
}

.passkey-actions button {
  border: 1px solid var(--stroke);
  border-radius: 10px;
  padding: 6px 8px;
  font-size: 12px;
  background: transparent;
  color: var(--text);
  cursor: pointer;
}

.passkey-actions .danger {
  color: var(--danger);
  border-color: color-mix(in srgb, var(--danger) 40%, transparent);
}

/* 2FA Styles */
#2fa-status-block {
  display: flex;
  justify-content: space-between;
  align-items: center;
  background: var(--panel);
  border-radius: 12px;
  padding: 12px;
  margin-bottom: 12px;
}

.status-indicator {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  color: var(--text);
}

.success-color {
  color: var(--success, #4caf50);
}

.wizard-container {
  background: var(--panel);
  border-radius: 12px;
  padding: 16px;
  border: 1px solid var(--stroke);
  overflow: hidden;
}

.wizard-step {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.wizard-step h6 {
  margin: 0;
  font-size: 14px;
  color: var(--text);
}

.qr-container {
  background: white;
  padding: 12px;
  border-radius: 12px;
  align-self: center;
  width: 180px;
  height: 180px;
}

.qr-container img {
  width: 100%;
  height: 100%;
  display: block;
}

.secret-code-box {
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--panel-2);
  padding: 8px 12px;
  border-radius: 8px;
  border: 1px dashed var(--stroke);
  justify-content: space-between;
}

.code-font {
  font-family: monospace;
  font-size: 14px;
  letter-spacing: 1px;
}

.icon-btn {
  background: transparent;
  border: none;
  color: var(--muted);
  cursor: pointer;
  padding: 4px;
  border-radius: 6px;
}

.icon-btn:hover {
  color: var(--text);
  background: var(--stroke);
}

/* === settings/security/sessions.css === */
/* Sessions Styles */
.panel-header-inline {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 4px;
}

.danger-text {
  color: var(--danger) !important;
  background: transparent !important;
  border-color: transparent !important;
  font-weight: 600;
}

.danger-text:hover {
  text-decoration: underline;
}

.session-revoke-all-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  border-radius: 10px;
  color: var(--danger);
  border-color: color-mix(in srgb, var(--danger) 35%, var(--stroke));
  background: color-mix(in srgb, var(--danger) 8%, transparent);
  font-weight: 600;
  padding-inline: 12px;
}

.session-revoke-all-btn .icon {
  --icon-size: 13px;
}

.session-revoke-all-btn:hover {
  border-color: color-mix(in srgb, var(--danger) 55%, var(--stroke));
  background: color-mix(in srgb, var(--danger) 14%, transparent);
}

.sessions-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: 10px;
}

.session-item {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  padding: 14px;
  border-radius: 14px;
  border: 1px solid var(--stroke);
  background: color-mix(in srgb, var(--panel) 85%, transparent);
  transition:
    border-color var(--anim-fast),
    background var(--anim-fast);
}

.session-item.is-current {
  border-color: color-mix(in srgb, var(--accent) 35%, var(--stroke));
  background: color-mix(in srgb, var(--accent) 8%, var(--panel));
}

.session-icon {
  width: 42px;
  height: 42px;
  border-radius: 10px;
  background: color-mix(in srgb, var(--panel-2) 80%, transparent);
  display: grid;
  place-items: center;
  color: color-mix(in srgb, var(--accent) 70%, var(--text));
  border: 1px solid color-mix(in srgb, var(--accent) 18%, var(--stroke));
  flex-shrink: 0;
}

.session-icon .icon {
  --icon-size: 20px;
}

.session-info {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}

.session-device {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
  line-height: 1.35;
}

.session-device-title {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.session-meta {
  font-size: 12.5px;
  color: var(--muted);
  line-height: 1.35;
  overflow-wrap: anywhere;
}

.session-current-badge {
  font-size: 10px;
  background: color-mix(in srgb, var(--success, #4caf50) 20%, transparent);
  color: var(--success, #4caf50);
  padding: 3px 7px;
  border-radius: 999px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.02em;
}

.session-revoke-btn {
  border: 1px solid color-mix(in srgb, var(--danger) 38%, var(--stroke));
  background: color-mix(in srgb, var(--danger) 8%, transparent);
  color: var(--danger);
  border-radius: 10px;
  padding: 7px 11px;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  transition:
    background var(--anim-fast),
    border-color var(--anim-fast),
    transform var(--anim-fast);
  display: inline-flex;
  align-items: center;
  gap: 7px;
  white-space: nowrap;
  flex-shrink: 0;
  margin-top: 1px;
}

.session-revoke-btn .icon {
  --icon-size: 12px;
}

.session-revoke-btn:hover {
  background: color-mix(in srgb, var(--danger) 16%, transparent);
  border-color: color-mix(in srgb, var(--danger) 62%, var(--stroke));
  transform: translateY(-1px);
}

@media (max-width: 640px) {
  .session-item {
    gap: 12px;
    padding: 12px;
  }

  .session-device-title {
    white-space: normal;
  }

  .session-revoke-btn {
    padding: 6px 10px;
  }
}

/* Security Blocks (New 2FA Design) */

/* === settings/security/recovery-blocks.css === */
.security-block {
  background: var(--panel-2);
  border: 1px solid var(--stroke);
  border-radius: 16px;
  padding: 20px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  transition: all 0.3s ease;
  overflow: hidden;
}

.security-block-header {
  display: flex;
  align-items: flex-start;
  gap: 16px;
}

.security-block-icon {
  width: 48px;
  height: 48px;
  min-width: 56px; /* Ensure fixed width */
  flex-shrink: 0; /* Prevent shrinking */
  border-radius: 18px;
  background: var(--panel);
  color: var(--accent);
  display: grid;
  place-items: center;
  border: 1px solid var(--stroke);
  flex-shrink: 0;
}

.security-block-icon .icon {
  --icon-size: 24px;
}

.security-block-info h6 {
  margin: 0 0 4px 0;
  font-size: 16px;
  font-weight: 600;
}

.security-block-info p {
  margin: 0;
  font-size: 13px;
  color: var(--muted);
  line-height: 1.4;
}

/* Expanded Content & Animations */
.security-block-content {
  border-top: 1px solid var(--stroke);
  padding-top: 24px; /* Increased padding */
  animation: slideDownFade 0.6s cubic-bezier(0.2, 0.8, 0.2, 1); /* Smoother animation */
}

@keyframes slideDownFade {
  from {
    opacity: 0;
    transform: translateY(-12px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.qr-section {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 20px;
}

.qr-wrapper {
  background: white;
  padding: 12px;
  border-radius: 18px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.qr-wrapper img {
  display: block;
  width: 180px;
  height: 180px;
}

.secret-code-pill {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--panel);
  padding: 6px 6px 6px 12px;
  border-radius: 10px;
  border: 1px dashed var(--stroke);
}

.secret-code-pill .code-font {
  font-size: 14px;
  color: var(--text);
}

.recovery-mandatory-note {
  display: none;
  margin: 0 0 10px;
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
}

#view-2fa.recovery-mandatory-mode #auth-app-block {
  display: none;
}

#view-2fa.recovery-mandatory-mode #backup-codes-block {
  margin-top: 0;
}

#view-2fa.recovery-mandatory-mode #backup-codes-block .security-block-header,
#view-2fa.recovery-mandatory-mode #backup-codes-block .security-block-action {
  display: none;
}

#view-2fa.recovery-mandatory-mode #backup-codes-content {
  display: block !important;
  border-top: none;
  padding-top: 0;
}

#view-2fa.recovery-mandatory-mode .recovery-mandatory-note {
  display: block;
}

#view-2fa.recovery-mandatory-mode .recovery-words-help {
  margin-bottom: 12px;
}

.recovery-words-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px 12px;
  margin-top: 4px;
}

.recovery-word-item {
  display: flex;
  align-items: center;
  gap: 8px;
  border-radius: 10px;
  border: 1px solid var(--stroke);
  background: color-mix(in srgb, var(--panel) 88%, transparent);
  padding: 8px 10px;
  font-size: 13px;
  line-height: 1.3;
}

.recovery-word-index {
  color: var(--muted);
  min-width: 22px;
  text-align: right;
}

.recovery-word-text {
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.recovery-words-actions {
  display: flex;
  justify-content: center;
  gap: 10px;
  flex-wrap: wrap;
}

.recovery-words-actions .button {
  width: auto;
  min-width: 150px;
}

@media (max-width: 640px) {
  .recovery-words-grid {
    grid-template-columns: 1fr;
  }

  .recovery-words-actions .button {
    width: 100%;
  }
}

/* === settings/security/otp-inline.css === */
/* OTP Inputs Grid */
.otp-section {
  margin-top: 24px; /* Added explicit top margin */
}

.otp-digit-inputs {
  display: flex;
  gap: 10px;
  justify-content: center;
  margin-top: 16px;
}

.otp-digit-inputs input {
  width: 48px;
  height: 56px;
  border-radius: 12px;
  border: 1px solid var(--stroke);
  background: var(--panel);
  color: var(--text);
  font-size: 24px;
  font-weight: 700;
  text-align: center;
  caret-color: var(--accent);
  transition: all 0.2s ease;
  padding: 0;
}

.otp-digit-inputs input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 20%, transparent);
  transform: translateY(-2px);
}

/* Validation States */
.otp-digit-inputs.error input {
  border-color: var(--danger);
  color: var(--danger);
  animation: shake 0.15s cubic-bezier(0.36, 0.07, 0.19, 0.97) both;
}

.otp-digit-inputs.success input {
  border-color: var(--success, #4caf50);
  color: var(--success, #4caf50);
  background: color-mix(in srgb, var(--success, #4caf50) 10%, transparent);
}

@keyframes shake {
  10%,
  90% {
    transform: translate3d(-1px, 0, 0);
  }
  20%,
  80% {
    transform: translate3d(2px, 0, 0);
  }
  30%,
  50%,
  70% {
    transform: translate3d(-4px, 0, 0);
  }
  40%,
  60% {
    transform: translate3d(4px, 0, 0);
  }
}

/* Inline Password Form */
.inline-password-form {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) auto;
  gap: 8px;
  align-items: center;
  animation: fadeIn 0.3s ease-out;
}

@keyframes fadeIn {
  from {
    opacity: 0;
    transform: translateY(4px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.inline-password-form #2fa-password-input {
  grid-column: 1 / 3;
}

.inline-password-form.with-otp #2fa-password-input {
  grid-column: 1;
}

.inline-password-form input {
  min-width: 0;
  width: 100%;
}

.inline-password-form .field-inline-error {
  flex-basis: 100%;
  margin-top: 4px;
  position: absolute;
  bottom: -22px;
  left: 0;
}

.inline-password-otp {
  grid-column: 2;
}

.inline-password-otp input {
  margin-bottom: 0;
  text-align: center;
  letter-spacing: 0.08em;
}

.button.icon-only {
  grid-column: 3;
  padding: 10px;
  width: 42px;
  height: 42px;
  border-radius: 12px;
  display: grid;
  place-items: center;
  flex-shrink: 0;
}

@media (max-width: 560px) {
  .inline-password-form {
    grid-template-columns: minmax(0, 1fr);
  }

  .inline-password-form #2fa-password-input,
  .inline-password-form.with-otp #2fa-password-input,
  .inline-password-otp,
  .button.icon-only {
    grid-column: 1;
  }

  .button.icon-only {
    width: 100%;
  }
}

#auth-app-password {
  margin-top: -8px; /* Tweak spacing when replacing button */
}

#security-gate-form .field-inline-error {
  margin-top: -2px;
  margin-bottom: 2px;
}

/* === settings/panel-interface.css === */

/* === settings/interface/layout.css === */
/* Interface panel — appearance (theme mode + palette gallery) plus a docked
   live preview. Ringtone/calls controls live in the Audio section now. */

.interface-header {
  display: flex;
  align-items: center;
  gap: 8px;
}

.interface-header .icon {
  --icon-size: 14px;
  opacity: 0.84;
}

.interface-header h4,
.interface-header h5 {
  margin: 0;
}

.interface-header.small-gap {
  gap: 7px;
}

.appearance-heading {
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.appearance-header h5 {
  font-size: 17px;
  font-weight: 700;
}

.appearance-subtitle {
  margin-left: 22px;
  font-size: 13px;
  font-weight: 520;
  color: color-mix(in srgb, var(--text) 70%, var(--muted) 30%);
}

/* Two columns: appearance controls + a sticky docked preview. Stacks on narrow. */
.interface-redesign {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 300px;
  gap: var(--space-4);
  align-items: start;
}

.appearance-block {
  grid-column: 1;
  gap: 12px;
}

@media (max-width: 920px) {
  .interface-redesign {
    grid-template-columns: 1fr;
  }
}

/* ============================================================
   Theme mode segmented control (system / dark / light)
   ============================================================ */
.theme-mode-row {
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: 5px;
  width: 100%;
  padding: 4px;
  border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--stroke) 78%, transparent);
  background: color-mix(in srgb, var(--panel-2) 72%, transparent);
  box-shadow: inset 0 1px 0 color-mix(in srgb, #fff 4%, transparent);
}

.theme-mode-chip {
  display: inline-flex;
  flex: 1 1 0;
  min-width: 0;
  cursor: pointer;
}

.theme-mode-chip-body {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  min-height: 31px;
  padding: 5px 13px;
  border-radius: 999px;
  border: 1px solid transparent;
  background: transparent;
  color: color-mix(in srgb, var(--text) 72%, var(--muted) 28%);
  font-size: 13px;
  font-weight: 650;
  letter-spacing: 0.01em;
  transition:
    color var(--anim-fast) var(--ease-out),
    border-color var(--anim-fast) var(--ease-out),
    background var(--anim-fast) var(--ease-out),
    box-shadow var(--anim-fast) var(--ease-out);
}

.theme-mode-chip-body .icon {
  --icon-size: 14px;
  opacity: 0.95;
}

.theme-mode-chip:hover .theme-mode-chip-body {
  color: var(--text);
  border-color: color-mix(in srgb, var(--accent) 30%, transparent);
  background: color-mix(in srgb, var(--accent) 10%, transparent);
}

.theme-mode-chip.is-active .theme-mode-chip-body {
  color: var(--text);
  border-color: color-mix(in srgb, var(--accent) 56%, transparent);
  background:
    linear-gradient(145deg,
      color-mix(in srgb, var(--accent) 34%, transparent),
      color-mix(in srgb, var(--accent) 16%, transparent));
  box-shadow:
    0 6px 16px -14px color-mix(in srgb, var(--accent) 86%, transparent),
    inset 0 1px 0 color-mix(in srgb, #fff 18%, transparent);
}

.theme-mode-chip input:focus-visible + .theme-mode-chip-body {
  outline: 2px solid color-mix(in srgb, var(--accent) 60%, transparent);
  outline-offset: 2px;
}

/* ============================================================
   Palette gallery — a wrapping grid (no carousel, no edge mask).
   ============================================================ */
.theme-palette-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 14px;
  margin-top: var(--space-3);
}

.theme-palette {
  position: relative;
  width: 100%;
  height: 200px;
  border-radius: 18px;
  border: 1px solid color-mix(in srgb, var(--stroke) 85%, transparent);
  background: transparent;
  padding: 0;
  cursor: pointer;
  text-align: left;
  overflow: hidden;
  transition:
    transform var(--anim-med) var(--ease-out),
    border-color var(--anim-med) var(--ease-out),
    box-shadow var(--anim-med) var(--ease-out);
}

.theme-palette:hover {
  transform: translateY(-4px);
  border-color: color-mix(in srgb, var(--accent) 42%, transparent);
}

.theme-palette:focus-visible {
  outline: 2px solid color-mix(in srgb, var(--accent) 65%, transparent);
  outline-offset: 3px;
}

.theme-palette.is-active {
  border-color: color-mix(in srgb, var(--accent) 65%, transparent);
  transform: translateY(-6px);
  box-shadow:
    0 0 0 1px color-mix(in srgb, var(--accent) 45%, transparent),
    0 18px 32px -22px color-mix(in srgb, var(--accent) 75%, transparent);
}

.theme-palette-surface {
  position: relative;
  height: 100%;
  padding: 14px;
  display: flex;
  flex-direction: column;
  border-radius: inherit;
  background: linear-gradient(155deg, var(--palette-1), color-mix(in srgb, var(--palette-0) 88%, #000 12%));
}

.theme-palette-nebula {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background:
    radial-gradient(circle at 22% 18%, color-mix(in srgb, var(--palette-2) 55%, transparent), transparent 52%),
    radial-gradient(circle at 76% 82%, color-mix(in srgb, var(--palette-3) 62%, transparent), transparent 48%),
    radial-gradient(circle at 82% 18%, color-mix(in srgb, #fff 20%, transparent), transparent 45%);
  filter: saturate(1.12);
  opacity: 0.82;
  transition: opacity var(--anim-med) var(--ease-out), transform var(--anim-med) var(--ease-out);
}

.theme-palette:hover .theme-palette-nebula,
.theme-palette.is-active .theme-palette-nebula {
  opacity: 1;
  transform: scale(1.03);
}

.theme-palette-header {
  position: relative;
  z-index: 1;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 10px;
}

.theme-palette-title {
  margin: 0;
  color: color-mix(in srgb, #fff 94%, var(--palette-3) 6%);
  font-size: 16px;
  font-weight: 700;
  letter-spacing: 0.01em;
  text-shadow: 0 3px 16px rgba(0, 0, 0, 0.52);
}

.theme-palette-badge {
  font-size: 10px;
  line-height: 1;
  letter-spacing: 0.08em;
  font-weight: 700;
  color: color-mix(in srgb, #fff 74%, var(--palette-3) 26%);
  border: 1px solid color-mix(in srgb, #fff 18%, transparent);
  border-radius: 999px;
  padding: 5px 8px;
  backdrop-filter: blur(4px);
}

/* 8-bit style for the dedicated card */
.theme-palette[data-palette="8bit"] {
  border-radius: 0;
  border: 2px solid #00ff00;
  box-shadow: 4px 4px 0 #005a00;
}

.theme-palette[data-palette="8bit"] .theme-palette-surface {
  border-radius: 0;
  background:
    repeating-linear-gradient(0deg, rgba(0, 255, 0, 0.08) 0 2px, rgba(0, 0, 0, 0.2) 2px 4px),
    linear-gradient(180deg, #001700, #000000);
}

.theme-palette[data-palette="8bit"] .theme-palette-nebula {
  display: none;
}

.theme-palette[data-palette="8bit"] .theme-palette-title {
  font-family: "Press Start 2P", "IBM Plex Mono", monospace;
  font-size: 11px;
  line-height: 1.35;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: #6bff6b;
  text-shadow: none;
}

.theme-palette[data-palette="8bit"] .theme-palette-badge {
  font-family: "Press Start 2P", "IBM Plex Mono", monospace;
  border-radius: 0;
  border: 1px solid #00ff00;
  background: #001400;
  color: #76ff76;
  text-transform: uppercase;
  letter-spacing: 0.12em;
}

.theme-palette[data-palette="8bit"] .theme-palette-cubes {
  gap: 6px;
}

.theme-palette[data-palette="8bit"] .theme-palette-cube {
  border-radius: 0;
  background: var(--cube-color);
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, 0.28),
    2px 2px 0 rgba(0, 0, 0, 0.65);
}

.theme-palette[data-palette="8bit"] .theme-palette-swatches span {
  border-radius: 0;
  border-color: #00ff00;
  height: 10px;
}

.theme-palette[data-palette="8bit"]:hover,
.theme-palette[data-palette="8bit"].is-active {
  transform: translateY(-4px);
  border-color: #5dff5d;
  box-shadow:
    0 0 0 1px #5dff5d,
    4px 4px 0 #005a00;
}

.theme-palette-cubes {
  margin-top: auto;
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
  padding-bottom: 10px;
}

.theme-palette-cube {
  position: relative;
  width: 100%;
  aspect-ratio: 1 / 1;
  border-radius: 9px;
  background: linear-gradient(145deg,
      color-mix(in srgb, var(--cube-color) 75%, #fff 25%),
      color-mix(in srgb, var(--cube-color) 88%, #000 12%));
  box-shadow:
    inset 0 1px 0 color-mix(in srgb, #fff 30%, transparent),
    0 7px 14px -10px rgba(0, 0, 0, 0.8);
  transform: translateY(0);
  transition: transform var(--anim-med) var(--ease-out), filter var(--anim-med) var(--ease-out);
  transition-delay: var(--cube-delay, 0ms);
}

.theme-palette:hover .theme-palette-cube {
  transform: translateY(-2px);
  filter: saturate(1.15);
}

.theme-palette-swatches {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 6px;
}

.theme-palette-swatches span {
  width: 100%;
  height: 12px;
  border-radius: 999px;
  border: 1px solid color-mix(in srgb, #fff 20%, transparent);
  background: var(--swatch);
}

/* ============================================================
   Docked live preview — a sticky mini chat that reflects the
   selected (or hovered) theme. Reuses the .mini-app skeleton.
   ============================================================ */
.theme-dock-preview {
  grid-column: 2;
  position: sticky;
  top: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.theme-dock-label {
  font-weight: 600;
}

@media (max-width: 920px) {
  .theme-dock-preview {
    grid-column: 1;
    order: -1;
    position: static;
    width: 100%;
    max-width: 340px;
  }
}

.theme-preview-frame {
  --preview-bg: #0b0f14;
  --preview-panel: #141b26;
  --preview-panel-alt: #101722;
  --preview-text: #e6edf7;
  --preview-muted: #8ea4c4;
  --preview-accent: #5aa2f2;
  --preview-accent-2: #8cd6f7;
  width: 100%;
  height: 210px;
  border-radius: var(--radius-lg);
  border: 1px solid var(--stroke);
  background: var(--preview-bg);
  overflow: hidden;
  box-shadow: var(--shadow);
}

.theme-preview-frame[data-theme="8bit"] {
  border-radius: 0;
  border: 2px solid #00ff00;
  box-shadow: 4px 4px 0 #005a00;
  font-family: "Press Start 2P", "IBM Plex Mono", monospace;
}

.theme-preview-frame[data-theme="8bit"] .mini-app,
.theme-preview-frame[data-theme="8bit"] .mini-app * {
  border-radius: 0 !important;
  image-rendering: pixelated;
}

.theme-preview-frame[data-theme="8bit"] .mini-sidebar,
.theme-preview-frame[data-theme="8bit"] .mini-main {
  background-image: repeating-linear-gradient(0deg,
      rgba(0, 255, 0, 0.06) 0 2px,
      transparent 2px 4px);
}

.mini-app {
  display: grid;
  grid-template-columns: 34% 1fr;
  height: 100%;
  color: var(--preview-text);
}

.mini-app,
.mini-app * {
  transition:
    background-color 400ms ease,
    border-color 400ms ease,
    color 400ms ease,
    box-shadow 400ms ease;
}

.mini-sidebar {
  background: color-mix(in srgb, var(--preview-panel) 82%, #000 18%);
  border-right: 1px solid color-mix(in srgb, var(--preview-muted) 28%, transparent);
  padding: 10px 8px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.mini-sidebar-header {
  height: 12px;
  border-radius: 5px;
  background: color-mix(in srgb, var(--preview-accent) 48%, transparent);
}

.mini-chat-list {
  display: grid;
  gap: 7px;
}

.mini-chat-item {
  height: 18px;
  border-radius: 8px;
  background: color-mix(in srgb, var(--preview-muted) 30%, transparent);
}

.mini-chat-item.active {
  background: color-mix(in srgb, var(--preview-accent) 42%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--preview-accent) 58%, transparent);
}

.mini-main {
  background: var(--preview-bg);
  padding: 8px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.mini-header {
  height: 22px;
  border-radius: 9px;
  background: color-mix(in srgb, var(--preview-panel-alt) 74%, transparent);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 8px;
}

.mini-header-title {
  width: 46%;
  height: 8px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--preview-text) 56%, transparent);
}

.mini-header-actions {
  display: flex;
  gap: 6px;
}

.mini-action {
  width: 9px;
  height: 9px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--preview-muted) 58%, transparent);
}

.mini-messages {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 6px;
}

/* Real (short) message text so the preview reads as a chat, not grey bars. */
.mini-msg {
  max-width: 80%;
  padding: 4px 7px;
  border-radius: 9px;
  font-size: 8px;
  line-height: 1.3;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.mini-msg.incoming {
  background: color-mix(in srgb, var(--preview-panel-alt) 88%, transparent);
  color: var(--preview-text);
}

.mini-msg.outgoing {
  margin-left: auto;
  background: linear-gradient(135deg,
      color-mix(in srgb, var(--preview-accent) 82%, transparent),
      color-mix(in srgb, var(--preview-accent-2) 76%, transparent));
  color: var(--preview-bg);
}

.mini-composer {
  height: 24px;
  border-radius: 10px;
  background: color-mix(in srgb, var(--preview-panel) 76%, transparent);
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 0 7px;
}

.mini-input {
  flex: 1;
  height: 8px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--preview-muted) 44%, transparent);
}

.mini-button {
  width: 18px;
  height: 12px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--preview-accent) 74%, transparent);
}

@media (prefers-reduced-motion: reduce) {
  .theme-palette,
  .theme-palette-nebula,
  .theme-palette-cube,
  .mini-app,
  .mini-app * {
    transition: none !important;
  }
}

/* === settings/interface/themes.css === */

/* === settings/responsive.css === */
/* Responsive settings styles */
@media (max-width: 720px) {
  .modal-card {
    width: min(92vw, 520px);
    max-height: 85vh;
    padding: 16px; /* Slightly tighter padding on mobile */
  }

  .settings-body {
    grid-template-columns: 1fr;
    position: relative;
  }

  /* Show nav as horizontal tabs when a panel is selected on mobile */
  .modal-card.mobile-panel-active .settings-nav {
    display: flex;
    flex-direction: row;
    width: 100%;
    overflow-x: auto;
    gap: 8px;
    padding-bottom: 12px;
    margin-bottom: 8px;
    border-bottom: 1px solid var(--stroke);
    scrollbar-width: none;
    -ms-overflow-style: none;
    order: -1;
    flex-shrink: 0;
  }

  .modal-card.mobile-panel-active .settings-nav::-webkit-scrollbar {
    display: none;
  }

  .modal-card.mobile-panel-active .settings-tab {
    white-space: nowrap;
    padding: 8px 14px;
    font-size: 13px;
    border-radius: 999px;
    flex-shrink: 0;
  }

  .modal-card.mobile-panel-active .settings-tab::after {
    display: none;
  }

  /* Hide panels when no panel is selected on mobile (initially) */
  .modal-card:not(.mobile-panel-active) .settings-content {
    display: none;
  }

  .modal-card:not(.mobile-panel-active) .settings-nav {
    display: flex;
    flex-direction: column;
    width: 100%;
    order: 1;
    gap: 10px;
  }

  .modal-card.mobile-panel-active .settings-content {
    display: block;
    width: 100%;
    flex: 1;
    min-height: 0;
  }

  .modal-header-left {
    display: flex;
    align-items: center;
    gap: 12px;
  }

  .modal-card.mobile-panel-active #settings-back {
    display: inline-flex;
  }

  .settings-tab {
    padding: 14px 16px;
    font-size: 15px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    transition: all 0.2s ease;
  }

  .modal-card:not(.mobile-panel-active) .settings-tab::after {
    content: "→";
    opacity: 0.5;
  }

  .profile-grid {
    grid-template-columns: 1fr;
    gap: 20px;
  }

  .profile-avatar-block .avatar.large {
    width: 100px;
    height: 100px;
    border-radius: 24px;
  }

  #settings-sidebar-density {
    display: none;
  }

  /* Smoother transitions for settings panels */
  .settings-panel {
    transition:
      opacity 0.2s ease-out,
      transform 0.2s ease-out;
    will-change: opacity, transform;
  }
}
@media (max-width: 720px) {
  .theme-mode-row {
    display: flex;
    width: 100%;
    gap: 4px;
  }

  .theme-mode-chip {
    flex: 1 1 0;
    min-width: 0;
  }

  .theme-mode-chip-body {
    width: 100%;
    justify-content: center;
    padding: 6px 10px;
    font-size: 11px;
  }

  .theme-palette {
    height: 188px;
  }

  .theme-palette.is-active {
    transform: translateY(-4px);
  }
}

@media (prefers-reduced-motion: reduce) {
  .theme-mode-chip-body,
  .theme-palette,
  .theme-palette-nebula,
  .theme-palette-cube,
  .mini-app,
  .mini-app * {
    animation: none !important;
    transition: none !important;
  }
}

/* === settings/page.css === */
/* Settings shell — used inside .settings-overlay (full-screen drawer
   over /chats) and historically as a standalone /settings page. */

.settings-shell {
  display: grid;
  /* nav rail + content, centered as one cluster (Claude-style) rather than
     pinned to the viewport edges. The max-width + margin-inline auto grows the
     left/right gutters symmetrically on wide screens. */
  grid-template-columns: 248px minmax(0, 1fr);
  min-height: 100vh;
  max-width: 1100px;
  margin-inline: auto;
  padding-inline: var(--space-6);
  background: var(--bg);
  color: var(--text);
}

/* Full-screen overlay that mounts inside chat.html so /chats DOM
   (sockets, calls, composer state) stays alive while settings are open. */
.settings-overlay {
  position: fixed;
  inset: 0;
  z-index: 1000;
  background: var(--bg);
  overflow: auto;
  animation: settings-overlay-in 180ms var(--ease-out, ease-out);
}

.settings-overlay[hidden] {
  display: none;
}

.settings-overlay .settings-shell {
  min-height: 100vh;
}

.settings-overlay-error {
  padding: var(--space-5);
  color: var(--danger);
  text-align: center;
}

@keyframes settings-overlay-in {
  from {
    opacity: 0;
    transform: translateY(6px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* ============================================================
   Sidebar
   ============================================================ */

.settings-sidebar {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  padding: 40px var(--space-5) 64px var(--space-2);
  /* The divider is the only thing separating nav from content — no panel fill,
     so the whole cluster reads as one surface split by a line. */
  border-right: 1px solid var(--stroke);
  background: transparent;
}

.settings-back-link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  color: var(--muted);
  font-size: 13px;
  text-decoration: none;
  transition:
    background 0.15s ease,
    color 0.15s ease;
}

.settings-back-link:hover {
  background: var(--panel-2);
  color: var(--text);
}

.settings-back-link .icon {
  --icon-size: 14px;
}

.settings-nav-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.settings-nav-group {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.settings-nav-group-label {
  padding: 0 var(--space-3);
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted);
  margin-bottom: 6px;
}

.settings-nav-item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: 10px var(--space-3);
  min-height: 40px;
  border-radius: var(--radius-md);
  color: var(--text);
  font-size: var(--text-md);
  font-weight: 500;
  line-height: 1.2;
  text-decoration: none;
  transition:
    background var(--anim-fast) var(--ease-out),
    color var(--anim-fast) var(--ease-out);
}

.settings-nav-item .icon {
  --icon-size: 18px;
  color: var(--muted);
  flex-shrink: 0;
  transition: color var(--anim-fast) var(--ease-out);
}

.settings-nav-item:hover {
  background: color-mix(in srgb, var(--accent) 8%, transparent);
}

.settings-nav-item:hover .icon {
  color: var(--text);
}

.settings-nav-item.is-active {
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  color: var(--accent);
  font-weight: 600;
}

.settings-nav-item.is-active .icon {
  color: var(--accent);
}

.settings-nav-item:focus-visible {
  outline: 2px solid color-mix(in srgb, var(--accent) 60%, transparent);
  outline-offset: 2px;
}

/* ============================================================
   Main content area
   ============================================================ */

.settings-main {
  padding: 40px 0 64px var(--space-6);
  width: 100%;
  max-width: 760px;
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

.settings-breadcrumb {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--muted);
  letter-spacing: 0.02em;
}

.settings-breadcrumb-cursor {
  display: inline-block;
  margin-left: 1px;
  color: var(--accent);
  animation: settings-cursor-blink 1.1s steps(1, end) infinite;
}

@keyframes settings-cursor-blink {
  0%,
  50% {
    opacity: 1;
  }
  50.01%,
  100% {
    opacity: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .settings-breadcrumb-cursor {
    animation: none;
  }
}

.settings-head {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.settings-title {
  margin: 0;
  font-size: 22px;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.settings-tagline {
  margin: 0;
  font-size: 13px;
  line-height: 1.4;
  color: var(--muted);
}

.settings-section-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  /* Reading measure now lives on .settings-main; the body fills its column so
     2-col card grids and the theme picker get the full width. */
  max-width: none;
}

.settings-placeholder {
  margin: 0;
  padding: var(--space-5);
  border: 1px dashed var(--stroke);
  border-radius: var(--radius-md);
  color: var(--muted);
  font-size: 14px;
  text-align: center;
}

/* ============================================================
   panel-block — flat v2 card.
   Overrides settings/base.css `.panel-block` (which is a glass-y
   modal card) only inside .settings-shell.
   ============================================================ */

.settings-shell .panel-block {
  background: var(--panel);
  border: 1px solid var(--stroke);
  border-radius: var(--radius-md);
  padding: var(--space-5);
  gap: var(--space-3);
}

.settings-shell .panel-block h5 {
  margin: 0 0 4px;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.005em;
}

.settings-shell .muted {
  font-size: 12px;
  color: var(--muted);
}

/* ============================================================
   Inputs / textareas / selects
   ============================================================ */

.settings-shell input[type="text"],
.settings-shell input[type="password"],
.settings-shell input[type="email"],
.settings-shell textarea,
.settings-shell .settings-select {
  width: 100%;
  padding: 9px 12px;
  background: var(--panel-2);
  border: 1px solid var(--stroke);
  border-radius: var(--radius-sm);
  color: var(--text);
  font: inherit;
  font-size: 14px;
  transition:
    border-color 0.15s ease,
    box-shadow 0.15s ease;
}

.settings-shell textarea {
  resize: vertical;
  min-height: 72px;
  line-height: 1.45;
}

.settings-shell input[type="text"]:focus,
.settings-shell input[type="password"]:focus,
.settings-shell textarea:focus,
.settings-shell .settings-select:focus {
  outline: none;
  border-color: color-mix(in srgb, var(--accent) 60%, var(--stroke));
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent);
}

.settings-shell input[disabled],
.settings-shell input[readonly] {
  opacity: 0.7;
  cursor: not-allowed;
}

.settings-shell label.muted {
  font-size: 11.5px;
  font-weight: 500;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 2px;
}

/* ============================================================
   Buttons — base.css gives .button width: 100%; on the settings
   page we want auto-width by default with .full-width opt-in.
   ============================================================ */

.settings-shell .button {
  width: auto;
  min-height: 36px;
  padding: 8px 16px;
  border-radius: var(--radius-sm);
  font-size: 13.5px;
  font-weight: 500;
  gap: 8px;
}

.settings-shell .button.full-width {
  width: 100%;
}

.settings-shell .button.small {
  min-height: 32px;
  padding: 6px 12px;
  font-size: 13px;
}

/* ============================================================
   Profile / Account section
   ============================================================ */

.settings-shell .profile-grid {
  grid-template-columns: 140px 1fr;
  gap: var(--space-5);
  align-items: start;
}

.settings-shell .profile-avatar-block {
  gap: var(--space-3);
}

.settings-shell .profile-avatar-block .avatar.large {
  width: 112px;
  height: 112px;
  border-radius: var(--radius-md);
  font-size: 36px;
  box-shadow: none;
  border: 1px solid var(--stroke);
}

.settings-shell .profile-fields {
  gap: var(--space-3);
}

.settings-shell .profile-fields label {
  margin-bottom: 0;
}

.settings-shell .profile-handle {
  font-family: var(--font-mono);
  font-size: 12px;
  background: var(--panel-2);
  border: 1px solid var(--stroke);
  border-radius: var(--radius-sm);
  padding: 4px 8px;
  align-self: start;
}

.settings-shell #profile-bio-count {
  font-size: 11px;
  color: var(--muted);
  text-align: right;
  margin-top: -4px;
}

.settings-shell #profile-save {
  align-self: flex-start;
  margin-top: 4px;
}

/* ============================================================
   Toggle (notifications, ringtone-enabled)
   ============================================================ */

.settings-shell .toggle {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) 0;
  cursor: pointer;
  font-size: 13.5px;
}

.settings-shell .toggle input[type="checkbox"] {
  appearance: none;
  width: 36px;
  height: 20px;
  background: var(--panel-2);
  border: 1px solid var(--stroke);
  border-radius: var(--radius-pill);
  position: relative;
  cursor: pointer;
  flex-shrink: 0;
  transition:
    background 0.18s ease,
    border-color 0.18s ease;
}

.settings-shell .toggle input[type="checkbox"]::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 2px;
  width: 14px;
  height: 14px;
  background: var(--text);
  border-radius: 50%;
  transform: translateY(-50%);
  transition:
    left 0.18s ease,
    background 0.18s ease;
}

.settings-shell .toggle input[type="checkbox"]:checked {
  background: var(--accent);
  border-color: color-mix(in srgb, var(--accent) 60%, transparent);
}

.settings-shell .toggle input[type="checkbox"]:checked::after {
  left: calc(100% - 16px);
  background: var(--accent-contrast, #fff);
}

.settings-shell .toggle input[type="checkbox"]:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* ============================================================
   form-status (validation hints under fields)
   ============================================================ */

.settings-shell .form-status {
  font-size: 12px;
  color: var(--muted);
  min-height: 0;
}

.settings-shell .form-status.error {
  color: var(--danger);
}

/* ============================================================
   Privacy block
   ============================================================ */

.settings-shell .privacy-row {
  background: var(--panel-2);
  border-color: var(--stroke);
  border-radius: var(--radius-sm);
  padding: 10px 12px;
}

.settings-shell .privacy-empty {
  border-radius: var(--radius-sm);
}

/* ============================================================
   Mobile
   ============================================================ */

@media (max-width: 720px) {
  .settings-shell {
    grid-template-columns: 1fr;
    max-width: none;
    padding-inline: 0;
  }

  .settings-sidebar {
    border-right: none;
    border-bottom: 1px solid var(--stroke);
    padding: var(--space-3);
    gap: var(--space-3);
  }

  .settings-nav-list {
    flex-direction: row;
    overflow-x: auto;
    gap: var(--space-3);
    scrollbar-width: thin;
  }

  .settings-nav-group {
    flex-direction: row;
    flex-shrink: 0;
    gap: var(--space-2);
  }

  .settings-nav-group-label {
    display: none;
  }

  .settings-nav-item {
    min-height: 44px;
    padding: 10px var(--space-4);
    border-radius: var(--radius-pill);
    background: color-mix(in srgb, var(--panel-2) 60%, transparent);
    white-space: nowrap;
  }

  /* Labels only on the narrow horizontal rail — icons would bloat each pill. */
  .settings-nav-item .icon {
    display: none;
  }

  .settings-main {
    padding: var(--space-4) var(--space-4) var(--space-6);
    max-width: none;
  }

  .settings-shell .profile-grid {
    grid-template-columns: 1fr;
    gap: var(--space-4);
  }

  .settings-shell .profile-avatar-block {
    align-items: flex-start;
  }
}

/* === modals/v2.css === */
/* Phase 7a — flat v2 modal overrides.
   Scoped to so legacy glass stays as fallback
   while the flag is on. Phase 7c will drop the gating selector. */

/* ============================================================
   Backdrop & card
   ============================================================ */

.modal-backdrop {
  background: color-mix(in srgb, var(--bg) 70%, #000 30%);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  opacity: 0.85;
}

.modal-card {
  background: var(--panel);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  border: 1px solid var(--stroke);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow);
  padding: var(--space-5);
  gap: var(--space-4);
}

/* ============================================================
   Header
   ============================================================ */

.modal-header {
  align-items: center;
  gap: var(--space-3);
}

.modal-header h2,
.modal-header h3 {
  font-size: 17px;
  font-weight: 600;
  letter-spacing: -0.01em;
  margin: 0;
}

.modal-header p {
  font-size: 12.5px;
  color: var(--muted);
  margin: 2px 0 0;
}

.modal-close {
  width: 28px;
  height: 28px;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  background: transparent;
  color: var(--muted);
  font-size: 16px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition:
    background 0.15s ease,
    color 0.15s ease,
    border-color 0.15s ease;
}

.modal-close:hover {
  background: var(--panel-2);
  color: var(--text);
  border-color: var(--stroke);
}

.modal-close .icon {
  --icon-size: 14px;
}

/* ============================================================
   Body, footer
   ============================================================ */

.modal-body {
  gap: var(--space-3);
}

.modal-footer {
  display: flex;
  flex-direction: row;
  justify-content: flex-end;
  gap: var(--space-2);
  margin-top: 0 !important;
}

/* ============================================================
   Inputs / textareas / selects inside modal
   ============================================================ */

.modal input[type="text"],
.modal input[type="password"],
.modal input[type="email"],
.modal input.user-search,
.modal textarea,
.modal .settings-select {
  background: var(--panel-2);
  border: 1px solid var(--stroke);
  border-radius: var(--radius-sm);
  padding: 9px 12px;
  font-size: 14px;
  color: var(--text);
  transition:
    border-color 0.15s ease,
    box-shadow 0.15s ease;
}

.modal input:focus,
.modal textarea:focus,
.modal .settings-select:focus {
  outline: none;
  border-color: color-mix(in srgb, var(--accent) 60%, var(--stroke));
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent);
}

/* ============================================================
   Buttons inside modal — auto width by default, flat geometry
   ============================================================ */

.modal .button {
  width: auto;
  min-height: 36px;
  padding: 8px 16px;
  border-radius: var(--radius-sm);
  font-size: 13.5px;
  font-weight: 500;
  gap: 8px;
  border: 1px solid transparent;
}

.modal .button.full-width {
  width: 100%;
}

.modal .button.small {
  min-height: 32px;
  padding: 6px 12px;
  font-size: 13px;
}

.modal .button.secondary {
  background: var(--panel-2);
  border-color: var(--stroke);
  color: var(--text);
  margin-top: 0;
}

.modal .button.secondary:hover {
  background: color-mix(in srgb, var(--panel-2) 60%, var(--text) 8%);
  border-color: color-mix(in srgb, var(--stroke) 60%, var(--text) 20%);
}

.modal .button.danger {
  background: var(--danger);
  color: #fff;
  border-color: var(--danger);
}

.modal .button.danger:hover {
  background: color-mix(in srgb, var(--danger) 88%, #000);
  border-color: color-mix(in srgb, var(--danger) 88%, #000);
}

.modal .icon-button {
  border-radius: var(--radius-sm);
}

/* ============================================================
   Compose-modal-specific tweaks
   ============================================================ */

/* prompt — small dialog, single input, two actions on the right */
#prompt-modal .modal-card.small {
  width: min(440px, 92vw);
}

#prompt-modal .modal-footer {
  margin-top: var(--space-2) !important;
}

/* confirm — keep centred but flat */
.confirm-card {
  max-width: 360px;
  text-align: left;
}

.confirm-card .modal-header {
  justify-content: space-between;
}

.confirm-card .modal-body {
  padding-top: 0;
  padding-bottom: var(--space-3);
}

.confirm-card .modal-footer {
  justify-content: flex-end;
}

.confirm-card .button {
  flex: 0 0 auto;
}

/* notify — actions row, centred hint */
#notify-modal .notify-actions {
  margin-top: var(--space-2);
  gap: var(--space-2);
}

#notify-modal .notify-actions .button {
  flex: 1;
  width: auto;
}

#notify-modal .notify-hint {
  font-size: 11.5px;
  color: var(--muted);
}

/* group_create — keep collapsible structure but flat panels */
.group-create-card {
  width: min(560px, 94vw);
}

.group-modal-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding-top: var(--space-3);
  border-top: 1px solid var(--stroke);
}

.group-modal-footer .button {
  width: auto;
}

/* ============================================================
   Glass-killer inside modals — keeps all panel-blocks / hero /
   group-panels / profile-bio flat instead of glass-y. Targets
   any element that uses --glass-bg / --glass-blur via custom
   prop fallbacks; we override the visible look without touching
   the underlying class.
   ============================================================ */

.modal .panel-block,
.modal .group-panel,
.modal .profile-hero,
.modal .profile-bio-card,
.modal .group-info-hero,
.modal .privacy-row,
.modal .invite-card,
.modal .invite-row {
  background: var(--panel-2);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  border: 1px solid var(--stroke);
  border-radius: var(--radius-md);
  box-shadow: none;
}

/* user_info — center-aligned hero: keep avatar large but flat */
.profile-card {
  width: min(560px, 94vw);
}

.profile-card .modal-header.no-border {
  padding: 0;
  margin-bottom: calc(var(--space-2) * -1);
}

.profile-card .avatar.xlarge {
  border-radius: var(--radius-md);
  box-shadow: none;
  border: 1px solid var(--stroke);
}

.profile-card .profile-handle {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--muted);
  background: var(--panel-2);
  border: 1px solid var(--stroke);
  border-radius: var(--radius-sm);
  padding: 3px 8px;
  align-self: flex-start;
}

/* group_details — same treatment */
.group-details-card {
  width: min(560px, 94vw);
}

.group-details-card .group-info-avatar {
  border-radius: var(--radius-md);
  box-shadow: none;
  border: 1px solid var(--stroke);
}

/* invite — flat list rows */
#invites-modal .modal-card {
  width: min(540px, 94vw);
}

#invites-modal .invite-create-btn {
  border-radius: var(--radius-sm);
  border: 1px solid var(--stroke);
  background: var(--panel-2);
}

#invites-modal .invite-create-btn:hover {
  background: color-mix(in srgb, var(--panel-2) 60%, var(--accent) 12%);
  border-color: color-mix(in srgb, var(--stroke) 60%, var(--accent) 30%);
}

/* Call region lives inline inside .chat-panel, so .call-card no longer
   needs a panel chrome of its own — the surrounding chat-panel provides
   it. Keep only the secondary surfaces (incoming card, audio popover). */

.call-incoming-card {
  background: var(--panel-2);
  border: 1px solid var(--stroke);
  border-radius: var(--radius-md);
  box-shadow: none;
}

.call-audio-panel {
  background: var(--panel-2);
  border: 1px solid var(--stroke);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

.call-control {
  border-radius: var(--radius-sm);
}

/* ============================================================
   Delete popover (right-click delete) — flat
   ============================================================ */

.delete-popover {
  background: var(--panel);
  border: 1px solid var(--stroke);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow);
}

.delete-popover button {
  font-size: 13px;
  padding: 9px 14px;
}

/* === profile.css === */
.profile-card {
  width: min(540px, 92vw) !important;
  border-radius: 28px !important;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  padding: 0 !important;
  gap: 0 !important;
}

/* Sticky Header Bar */
.side-panel-header {
  position: sticky;
  top: 0;
  z-index: 10;
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 60px;
  min-height: 60px;
  padding: 0 16px;
  background: var(--panel);
  border-bottom: 1px solid var(--stroke);
  flex-shrink: 0;
}

.side-panel-title {
  font-size: 15px;
  font-weight: 600;
  color: var(--text);
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  pointer-events: none;
}

.modal-close-btn,
.profile-kebab {
  background: transparent;
  border: none;
  padding: 8px;
  cursor: pointer;
  color: var(--muted);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  transition:
    background-color 0.2s ease,
    color 0.2s ease;
}

.modal-close-btn:hover,
.profile-kebab:hover {
  background-color: var(--panel-2);
  color: var(--text);
}

.modal-close-btn .icon,
.profile-kebab .icon {
  --icon-size: 16px;
}

/* Kebab menu alignment in header */
.header-actions {
  position: relative;
  display: flex;
  align-items: center;
}

.profile-kebab-menu {
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  width: 214px;
  background: var(--bg);
  border: 1px solid var(--glass-stroke);
  border-radius: 14px;
  box-shadow: var(--glass-shadow);
  padding: 6px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  z-index: 30;
  transition:
    height 0.28s cubic-bezier(0.4, 0, 0.2, 1),
    transform 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275),
    opacity 0.15s ease-out;
  transform-origin: top right;
  will-change: height, transform, opacity;
}

.profile-kebab-menu[hidden] {
  display: flex !important;
  pointer-events: none;
  opacity: 0;
  transform: scale(0.95);
  height: 0 !important;
  overflow: hidden;
  border-width: 0;
  padding-top: 0;
  padding-bottom: 0;
}

.profile-kebab-menu:not([hidden]) {
  pointer-events: auto;
  opacity: 1;
  transform: scale(1);
}

.profile-kebab-submenu {
  display: grid;
  gap: 4px;
  padding: 4px 0 2px 20px;
  border-left: 1px solid color-mix(in srgb, var(--stroke) 80%, transparent);
}

.profile-kebab-submenu .submenu-item {
  font-size: 12px;
  padding-top: 7px;
  padding-bottom: 7px;
}

.profile-kebab-submenu .submenu-item-forever {
  color: color-mix(in srgb, #ffb86b 82%, var(--text));
  font-weight: 600;
}

/* Banner override */
.profile-banner {
  position: relative;
  flex-shrink: 0;
  height: 160px;
  overflow: hidden;
  margin: 0 !important;
}

/* Avatar overlap */
.profile-avatar-row {
  display: flex;
  justify-content: flex-start;
  padding-left: 24px;
  margin-top: -64px;
  position: relative;
  z-index: 2;
  margin-bottom: 12px;
}

.avatar.xlarge {
  width: 112px;
  height: 112px;
  border-radius: 50%;
  font-size: 44px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
  border: 4px solid var(--bg);
  background-color: var(--panel-2);
  transition: transform 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}

.avatar.xlarge:hover {
  transform: scale(1.04);
}

/* Name and Subtitle */
.profile-title-block {
  text-align: left;
  margin-bottom: 20px;
  padding: 0 24px;
}

.profile-name-row {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 5px;
}

.profile-name {
  margin: 0;
  font-size: 23px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--text);
}

.profile-meta-subtitle {
  font-size: 13px;
  color: var(--muted);
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 6px;
}

.profile-subtitle-handle {
  font-family: var(--font-mono);
  color: var(--muted);
}

.profile-subtitle-sep {
  color: var(--muted);
  opacity: 0.55;
}

.profile-status-presence {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-weight: 500;
}

.profile-status-presence.is-online {
  color: var(--success, #3fae6b);
}

.profile-status-presence .presence-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--success, #3fae6b);
  flex-shrink: 0;
}

.profile-status-presence[data-presence="warn"] {
  color: var(--status-warn);
}

.profile-status-presence[data-presence="warn"] .presence-dot {
  background: var(--status-warn);
}

.profile-status-presence[data-presence="bad"] {
  color: var(--status-bad);
}

.profile-status-presence[data-presence="bad"] .presence-dot {
  background: var(--status-bad);
}

/* Custom status (emoji + text) under the name. */
.profile-custom-status {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 24px 20px;
  padding: 8px 12px;
  border: 1px solid var(--stroke);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--accent) 6%, var(--panel-2));
}

.profile-custom-status[hidden] {
  display: none;
}

.profile-custom-status-emoji {
  flex: none;
  font-size: 17px;
  line-height: 1;
}

.profile-custom-status-text {
  font-size: 14px;
  color: var(--text);
  overflow-wrap: anywhere;
}

/* Quick Actions Grid */
.profile-actions-grid {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  gap: 8px;
  padding: 0 20px;
  margin-bottom: 24px;
}

.action-grid-btn {
  background: var(--panel-2);
  border: none;
  border-radius: 14px;
  padding: 10px 4px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
  color: var(--text);
  cursor: pointer;
  transition:
    background-color 0.2s ease,
    color 0.2s ease,
    transform 0.1s ease;
  font-family: var(--font-sans);
  text-decoration: none;
}

.action-grid-btn:hover {
  background-color: color-mix(in srgb, var(--accent) 10%, var(--panel-2));
  color: var(--accent);
}

.action-grid-btn:active {
  transform: scale(0.97);
}

.action-grid-btn .icon {
  --icon-size: 18px;
  color: currentColor;
  transition: transform 0.2s ease;
}

.action-grid-btn:hover .icon {
  transform: scale(1.1);
}

.action-grid-label {
  font-size: 11px;
  font-weight: 600;
}

/* Favorite state on action button */
.action-grid-btn.favorite-star.is-active {
  color: #ff9f0a;
}
.action-grid-btn.favorite-star.is-active:hover {
  background-color: color-mix(in srgb, #ff9f0a 10%, var(--panel-2));
}
.action-grid-btn.favorite-star.is-active .icon {
  --icon: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20width=%2224%22%20height=%2224%22%20viewBox=%220%200%2024%2024%22%20fill=%22currentColor%22%3E%20%3Cpath%20d=%22M12%202l3.09%206.26L22%209.27l-5%204.87%201.18%206.88L12%2017.77l-6.18%203.25L7%2014.14%202%209.27l6.91-1.01L12%202z%22/%3E%20%3C/svg%3E");
  background-color: #ff9f0a;
}

/* Details list (Clean list without borders) */
.profile-details-list {
  display: flex;
  flex-direction: column;
  background: var(--panel-2);
  border-radius: 20px;
  margin: 0 20px 24px;
  padding: 6px 16px;
  border: 1px solid var(--stroke);
}

.profile-detail-item {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 12px 0;
  border-bottom: 1px solid color-mix(in srgb, var(--stroke) 40%, transparent);
}

.profile-detail-item:last-child {
  border-bottom: none;
}

.profile-detail-item .detail-label {
  font-size: 10px;
  font-weight: 700;
  color: var(--muted);
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.profile-detail-item .detail-val {
  font-size: 14px;
  color: var(--text);
  font-weight: 500;
  line-height: 1.4;
  overflow-wrap: anywhere;
  word-break: break-word;
}

.profile-detail-item .detail-val a {
  color: var(--accent);
  text-decoration: none;
  font-weight: 600;
}

.profile-detail-item .detail-val a:hover {
  text-decoration: underline;
}

.profile-detail-item .detail-val:empty::after {
  content: "Нет описания";
  font-style: italic;
  opacity: 0.45;
  font-size: 13px;
}

/* Folder Select custom size in detail view */
.profile-detail-item .custom-select {
  width: 100%;
}

.profile-detail-item .custom-select-trigger {
  height: 36px;
  font-size: 13px;
  border-radius: 10px;
  background: var(--bg);
  border: 1px solid var(--stroke);
  padding: 0 12px;
}

/* Common groups overrides */
.profile-common-groups {
  margin-bottom: 24px;
  padding: 0 20px;
}

.profile-section-title {
  font-size: 12px;
  font-weight: 700;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin: 0 4px 8px;
}

.common-groups-list {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.common-group-row {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 6px 8px;
  border: none;
  background: transparent;
  border-radius: 10px;
  cursor: pointer;
  text-align: left;
  color: var(--text);
}

.common-group-row:hover {
  background: color-mix(in srgb, var(--accent) 10%, transparent);
}

.common-group-avatar {
  width: 32px;
  height: 32px;
  border-radius: 9px;
  font-size: 14px;
  flex: 0 0 auto;
}

.common-group-name {
  font-size: 14px;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Main Actions */
.profile-main-actions {
  margin-bottom: 12px;
  display: flex;
  justify-content: center;
}

.profile-chat-btn {
  height: 46px !important;
  width: 85% !important;
  font-size: 15px !important;
  border-radius: 14px !important;
  gap: 10px !important;
}

/* Media Tabs */
.media-tabs {
  display: flex;
  background: var(--panel-2);
  padding: 4px;
  border-radius: 14px;
  margin: 16px 20px 16px;
  border: 1px solid var(--stroke);
}

.tab-btn {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 8px 10px;
  border: none;
  background: transparent;
  color: var(--muted);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  border-radius: 10px;
  transition: all 0.2s ease;
}

.tab-btn:hover {
  color: var(--text);
  background: color-mix(in srgb, var(--accent) 10%, transparent);
}

.tab-btn.is-active {
  background: var(--accent);
  color: var(--accent-contrast);
  box-shadow: 0 4px 10px color-mix(in srgb, var(--accent) 30%, transparent);
}

.tab-count {
  display: block;
  font-size: 11px;
  font-weight: 700;
  min-width: 16px;
  height: 16px;
  padding: 0 5px;
  line-height: 16px;
  text-align: center;
  border-radius: 8px;
  background: color-mix(in srgb, var(--muted) 22%, transparent);
  color: var(--muted);
}

.tab-count[hidden] {
  display: none !important;
}


.tab-btn.is-active .tab-count {
  background: color-mix(in srgb, #fff 26%, transparent);
  color: var(--accent-contrast);
}

/* Media Inline Grid */
.media-inline {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 12px;
  border-radius: 18px;
  border: 1px solid var(--glass-stroke);
  background: var(--glass-bg);
  max-height: 420px;
  overflow-y: auto;
}

.media-inline:not([hidden]) {
  animation: slideUp 0.3s cubic-bezier(0.16, 1, 0.3, 1);
}

@keyframes slideUp {
  from {
    opacity: 0;
    transform: translateY(10px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Multi-page profile navigation */
.profile-card .profile-full-media-view {
  display: none;
}
.profile-card.show-media-gallery .profile-main-view {
  display: none !important;
}
.profile-card.show-media-gallery .profile-full-media-view {
  display: flex !important;
  flex-direction: column;
  flex: 1;
  min-height: 0;
}

/* Back button styling inside header */
.modal-back-btn {
  background: transparent;
  border: none;
  padding: 8px;
  cursor: pointer;
  color: var(--muted);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  transition:
    background-color 0.2s ease,
    color 0.2s ease;
}

.modal-back-btn:hover {
  background-color: var(--panel-2);
  color: var(--text);
}

.modal-back-btn .icon {
  --icon-size: 16px;
}

/* Preview Grid & Show All Button */
.media-preview-wrap {
  display: flex;
  flex-direction: column;
  margin-bottom: 8px;
}

.media-grid-preview {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 4px; /* Reduced gap to match Telegram */
  margin: 0 20px 12px;
}

.media-grid-preview[data-type="file"] {
  grid-template-columns: 1fr;
  gap: 8px;
}

.profile-show-all-btn {
  background: transparent;
  border: none;
  color: var(--accent);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  padding: 8px 20px;
  margin: 8px auto 16px; /* Centered margin horizontally */
  text-align: center;
  width: fit-content;
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 6px;
  transition: opacity 0.2s ease;
  font-family: var(--font-sans);
}

.profile-show-all-btn:hover {
  opacity: 0.8;
}

.profile-card .media-empty {
  font-size: 14px;
  color: var(--muted);
  text-align: center;
  padding: 32px 16px;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-sans);
  grid-column: 1 / -1; /* Spans all grid columns */
}

/* Full Gallery Scroll & Styling overrides */
.media-full-scroll {
  flex: 1;
  overflow-y: auto;
  min-height: 0;
  padding-bottom: 24px;
}

/* Override global .media-grid for profile modal to allow date grouping */
.profile-card .media-grid {
  display: flex !important;
  flex-direction: column !important;
  gap: 16px !important;
}

.media-group-row {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(110px, 1fr));
  gap: 10px;
}

.profile-card .media-group-row {
  grid-template-columns: repeat(3, 1fr) !important; /* Exactly 3 columns in sidebar */
  gap: 4px !important; /* Tiny Telegram-like gap */
  margin: 0 20px !important;
}

.profile-card .media-group-row--file {
  grid-template-columns: 1fr !important;
  gap: 8px !important;
}

.media-date-divider {
  font-size: 12px;
  font-weight: 600;
  color: var(--muted);
  text-align: left;
  padding: 6px 12px;
  position: sticky;
  top: -12px;
  /* Accounting for parent padding */
  background: var(--glass-bg);
  backdrop-filter: blur(12px);
  z-index: 5;
  border-radius: 10px;
  margin-top: 4px;
  border: 1px solid var(--glass-stroke);
}

.profile-card .media-date-divider {
  font-size: 13px !important;
  font-weight: 600 !important;
  color: var(--muted) !important;
  padding: 8px 0 !important;
  background: var(--panel) !important;
  position: sticky !important;
  top: 0 !important;
  z-index: 5 !important;
  margin: 16px 20px 8px !important;
  border: none !important;
  border-radius: 0 !important;
  box-shadow: none !important;
}

.media-item {
  aspect-ratio: 1;
  border-radius: 14px;
  overflow: hidden;
  position: relative;
  background: color-mix(in srgb, var(--panel-2) 60%, transparent);
  cursor: pointer;
  transition:
    transform 0.2s cubic-bezier(0.34, 1.56, 0.64, 1),
    box-shadow 0.2s ease;
  border: 1px solid var(--glass-stroke);
}

.media-item:hover {
  transform: scale(1.04);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
  z-index: 2;
}

/* Disable hover effects, set Telegram border radius and hide date overlays in profile card */
.profile-card .media-item {
  border-radius: 8px !important;
  border: 1px solid var(--stroke) !important;
}

.profile-card .media-item:hover {
  transform: none !important;
  box-shadow: none !important;
  z-index: auto !important;
}

.profile-card .media-item .media-meta,
.profile-card .media-item:hover .media-meta {
  display: none !important;
  opacity: 0 !important;
}

.media-item img,
.media-item video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Ensure images fill 100% height inside profile card and are not cutoff */
.profile-card .media-item img,
.profile-card .media-item video {
  height: 100% !important;
  width: 100% !important;
  object-fit: cover !important;
}

/* Shimmer Skeleton styling */
.media-item-skeleton {
  aspect-ratio: 1;
  border-radius: 8px;
  background: linear-gradient(
    90deg,
    var(--panel-2) 25%,
    color-mix(in srgb, var(--panel-2) 80%, var(--muted) 20%) 50%,
    var(--panel-2) 75%
  );
  background-size: 200% 100%;
  animation: media-shimmer 1.5s infinite linear;
  border: 1px solid var(--stroke);
}

@keyframes media-shimmer {
  0% {
    background-position: 200% 0;
  }
  100% {
    background-position: -200% 0;
  }
}

.media-video-play {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.5);
  backdrop-filter: blur(4px);
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  pointer-events: none;
}

.media-item .media-meta {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  padding: 6px;
  background: linear-gradient(transparent, rgba(0, 0, 0, 0.7));
  color: rgba(255, 255, 255, 0.9);
  font-size: 10px;
  opacity: 0;
  transition: opacity 0.2s;
  pointer-events: none;
}

.media-item:hover .media-meta {
  opacity: 1;
}

.profile-card .media-file {
  display: flex;
  flex-direction: row !important;
  align-items: center;
  gap: 12px;
  padding: 10px 14px 10px 10px;
  border-radius: 14px;
  background: var(--panel-2);
  border: 1px solid var(--stroke);
  color: var(--text);
  text-decoration: none;
  transition: background 0.2s, border-color 0.2s;
  cursor: pointer;
  width: auto;
  aspect-ratio: auto;
  overflow: hidden;
}

.profile-card .media-file:hover {
  background: color-mix(in srgb, var(--accent) 8%, var(--panel-2));
  border-color: color-mix(in srgb, var(--accent) 35%, var(--stroke));
}

.profile-card .media-file-icon {
  flex: 0 0 auto;
  width: 40px;
  height: 44px;
  border-radius: 8px;
  display: grid;
  place-items: center;
  position: relative;
  background: color-mix(in srgb, var(--accent) 22%, var(--panel));
  color: var(--accent-contrast, #fff);
  clip-path: polygon(0 0, 70% 0, 100% 25%, 100% 100%, 0 100%);
  font-size: 10px;
  font-weight: 700;
  padding-top: 4px;
}

.profile-card .media-file-icon::after {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  width: 30%;
  height: 25%;
  background: color-mix(in srgb, var(--accent) 40%, var(--panel-2));
}

.profile-card .media-file-name {
  display: flex;
  flex-direction: column;
  min-width: 0;
  text-align: left;
  flex: 1;
}

.profile-card .media-file-size {
  font-size: 12px;
  color: var(--muted);
}

.profile-card .media-file .media-meta {
  margin-left: auto;
  flex-shrink: 0;
  padding: 0;
  font-size: 11px;
}

.mirror-x {
  transform: scaleX(-1);
}

/* Compact Folder Select Menu Refinement */
#chat-folder-select .custom-select-menu {
  width: 160px !important;
  background: var(--glass-bg);
  backdrop-filter: var(--glass-blur);
  border: 1px solid var(--glass-stroke);
  border-radius: 12px;
  box-shadow: var(--glass-shadow);
}

@media (max-width: 480px) {
  .profile-card {
    width: 100vw !important;
    height: 100vh !important;
    max-height: 100vh !important;
    border-radius: 0 !important;
    margin: 0 !important;
  }
}

/* Bottom action buttons */
.profile-bottom-actions {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 0 20px 24px;
  border-top: 1px solid var(--stroke);
  padding-top: 16px;
  margin-top: 24px;
}

.bottom-action-btn {
  background: transparent;
  border: none;
  outline: none;
  cursor: pointer;
  text-align: left;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 16px;
  width: 100%;
  border-radius: 12px;
  transition:
    background-color 0.2s ease,
    color 0.2s ease;
  font-family: var(--font-sans);
  font-size: 14px;
  font-weight: 600;
  color: var(--muted);
}

.bottom-action-btn:hover {
  background-color: var(--panel-2);
  color: var(--accent);
}

.bottom-action-btn .icon {
  --icon-size: 16px;
  color: currentColor;
}

.bottom-action-btn.danger {
  color: #ff3b30;
}

.bottom-action-btn.danger:hover {
  background-color: color-mix(in srgb, #ff3b30 8%, transparent);
  color: #ff3b30;
}

/* === selects.css === */
.custom-select {
  position: relative;
  min-width: 180px;
  width: 100%;
}

.custom-select-trigger {
  width: 100%;
  padding: 8px 10px;
  border-radius: 10px;
  border: 1px solid var(--stroke);
  background: var(--panel-2);
  color: var(--text);
  font-size: 12px;
  cursor: pointer;
  text-align: left;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.custom-select-trigger::after {
  content: "▾";
  font-size: 12px;
  color: var(--muted);
}

.custom-select.is-open .custom-select-trigger {
  border-color: color-mix(in srgb, var(--accent) 40%, transparent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 15%, transparent);
}

.custom-select-menu {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  right: 0;
  background: var(--panel);
  border: 1px solid var(--stroke);
  border-radius: 12px;
  box-shadow: var(--shadow);
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 6px;
  max-height: 220px;
  overflow-y: auto;
  z-index: 4;
  animation: fadeIn var(--anim-fast) var(--ease-out);
}

.custom-select-option {
  border: 1px solid transparent;
  background: transparent;
  color: var(--text);
  padding: 6px 8px;
  border-radius: 8px;
  cursor: pointer;
  font-size: 12px;
  text-align: left;
}

.custom-select-option:hover {
  border-color: color-mix(in srgb, var(--accent) 40%, transparent);
  background: color-mix(in srgb, var(--accent) 10%, transparent);
}

.custom-select-option[data-disabled="true"] {
  color: var(--muted);
  cursor: not-allowed;
}

/* === invites.css === */
.invite-header {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 16px;
}

.invite-header .form-status {
  font-size: 12px;
  color: var(--muted);
}

.invite-header .form-status.error {
  color: var(--danger);
}

.invite-create-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  border-radius: 10px;
  border: 1px solid var(--stroke);
  background: var(--panel-2);
  color: var(--text);
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  transition:
    border-color var(--anim-fast) var(--ease-out),
    background var(--anim-fast) var(--ease-out);
}

.invite-create-btn:hover {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 8%, var(--panel-2));
}

.invite-create-btn:active {
  transform: scale(0.97);
}

.invite-create-btn .icon {
  --icon-size: 14px;
}

.invite-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-height: 400px;
  overflow-y: auto;
}

.invite-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 14px;
  border-radius: 10px;
  border: 1px solid var(--stroke);
  background: var(--panel-2);
  transition: border-color var(--anim-fast) var(--ease-out);
}

.invite-item:hover {
  border-color: color-mix(in srgb, var(--accent) 30%, var(--stroke));
}

.invite-item.is-new {
  animation: messagePop var(--anim-med) var(--ease-out);
}

.invite-item.is-used {
  opacity: 0.7;
}

.invite-info {
  display: flex;
  align-items: center;
  gap: 16px;
  min-width: 0;
  flex: 1;
}

.invite-code {
  font-family: "IBM Plex Mono", monospace;
  font-size: 14px;
  font-weight: 500;
  letter-spacing: 0.08em;
  white-space: nowrap;
  color: var(--text);
}

.invite-item.is-used .invite-code {
  text-decoration: line-through;
  color: var(--muted);
}

.invite-code.is-rolling {
  letter-spacing: 0.1em;
}

.invite-char {
  display: inline-block;
  min-width: 0.65em;
  text-align: center;
  color: var(--muted);
  transition: color var(--anim-fast) var(--ease-out);
}

.invite-char.is-set {
  color: var(--text);
}

.invite-meta {
  font-size: 12px;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.invite-actions-inline {
  display: flex;
  gap: 6px;
  flex-shrink: 0;
}

.invite-actions-inline button {
  border: 1px solid var(--stroke);
  background: var(--panel);
  color: var(--text);
  padding: 6px 10px;
  border-radius: 8px;
  font-size: 12px;
  cursor: pointer;
  transition:
    border-color var(--anim-fast) var(--ease-out),
    background var(--anim-fast) var(--ease-out);
}

.invite-actions-inline button:hover {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 6%, var(--panel));
}

.invite-actions-inline button:active {
  transform: scale(0.96);
}

.invite-empty {
  font-size: 13px;
  color: var(--muted);
  text-align: center;
  padding: 24px 12px;
}

/* === groups.css === */

/* === groups/core.css === */
.group-section {
  margin-top: 12px;
  padding-top: 10px;
  border-top: 1px solid var(--stroke);
}

.group-section-title {
  font-size: 12px;
  color: var(--muted);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  margin-bottom: 10px;
}

.group-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.group-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border-radius: 14px;
  border: 1px solid transparent;
  background: var(--panel-2);
  cursor: pointer;
}

.group-item.active {
  border-color: color-mix(in srgb, var(--accent) 40%, transparent);
  background: color-mix(in srgb, var(--accent) 12%, transparent);
}

.group-item.unread::after {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--accent-2);
  margin-left: auto;
}

.group-meta {
  display: flex;
  flex-direction: column;
}

.group-meta small {
  color: var(--muted);
  font-size: 11px;
}

/* === groups/folders.css === */
/* Anchor wrapper — keeps the popover positioned relative to the +chip,
   not the scrollable .folder-list (which would clip it). */
.folder-create-anchor {
  position: relative;
  flex-shrink: 0;
}

.folder-create-island {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  left: auto;
  width: 240px;
  background: var(--glass-bg);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  border: 1px solid var(--glass-stroke);
  border-radius: var(--radius-md);
  padding: var(--space-3);
  box-shadow: var(--glass-shadow);
  z-index: var(--z-dropdown);
  transform-origin: top right;
  transition:
    opacity 0.25s cubic-bezier(0.4, 0, 0.2, 1),
    transform 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275),
    visibility 0.25s;
}

.folder-create-island[hidden] {
  display: block !important;
  opacity: 0;
  transform: translateY(-8px) scale(0.96);
  pointer-events: none;
  visibility: hidden;
}

.folder-create-island .island-content {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.folder-create-island input {
  width: 100%;
  padding: 12px 18px;
  border-radius: 16px;
  border: 1px solid var(--stroke);
  background: color-mix(in srgb, var(--panel-2) 60%, transparent);
  color: var(--text);
  font-size: 14px;
  outline: none;
  transition: all 0.2s;
}

.folder-create-island input:focus {
  border-color: color-mix(in srgb, var(--accent) 60%, transparent);
  background: var(--panel-2);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 15%, transparent);
}

.folder-create-island .island-actions {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  padding-top: 4px;
}

.island-button {
  height: 38px;
  padding: 0 16px;
  border-radius: 14px;
  border: 1px solid var(--stroke);
  background: var(--panel-2);
  color: var(--text);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-size: 13px;
  font-weight: 500;
  transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
}

.island-button.primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-contrast);
  flex: 2;
}

.island-button.secondary {
  flex: 1;
}

.island-button.primary:hover {
  background: color-mix(in srgb, var(--accent) 85%, white);
  transform: translateY(-1px);
  box-shadow: 0 6px 16px color-mix(in srgb, var(--accent) 30%, transparent);
}

.island-button.secondary:hover {
  background: var(--panel-2);
  border-color: var(--muted);
  transform: translateY(-1px);
}

/* Context Menu with Live Stretching */
.folder-context-menu {
  position: fixed;
  z-index: 10000;
  min-width: 190px;
  background: var(--glass-bg);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  border: 1px solid var(--glass-stroke);
  border-radius: 22px;
  padding: 8px;
  box-shadow: var(--glass-shadow);
  animation: context-pop 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
  overflow: hidden;
  transition:
    width 0.5s cubic-bezier(0.4, 0, 0.2, 1),
    height 0.5s cubic-bezier(0.4, 0, 0.2, 1),
    opacity 0.3s ease;
  will-change: auto;
}

.folder-context-menu .context-content {
  display: flex;
  flex-direction: column;
  gap: 4px;
  animation: content-fade-in 0.15s ease;
}

@keyframes content-fade-in {
  from {
    opacity: 0;
    transform: translateY(6px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.folder-context-menu .context-item {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  border: none;
  background: transparent;
  color: var(--text);
  font-size: 13px;
  border-radius: 10px;
  cursor: pointer;
  transition:
    background 0.15s,
    color 0.15s,
    transform 0.1s;
  white-space: nowrap;
}

.folder-context-menu .context-item:hover {
  background: color-mix(in srgb, var(--accent) 12%, transparent);
}

.folder-context-menu .context-item:active {
  transform: scale(0.97);
}

.folder-context-menu .context-item.danger:hover {
  background: color-mix(in srgb, var(--danger) 10%, transparent);
  color: var(--danger);
}

.folder-context-menu .context-separator {
  height: 1px;
  background: color-mix(in srgb, var(--stroke) 60%, transparent);
  margin: 3px 8px;
}

.folder-context-menu .context-header {
  padding: 8px 12px 4px;
  font-size: 11px;
  font-weight: 700;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.1em;
}

.folder-context-menu .context-input-wrap {
  padding: 4px 8px 8px;
}

.folder-context-menu .context-input {
  width: 100%;
  padding: 8px 12px;
  border-radius: 12px;
  border: 1px solid var(--stroke);
  background: var(--panel-2);
  color: var(--text);
  font-size: 14px;
  outline: none;
  transition:
    border-color 0.2s,
    box-shadow 0.2s;
}

.folder-context-menu .context-input:focus {
  border-color: color-mix(in srgb, var(--accent) 50%, transparent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 15%, transparent);
}

.folder-context-menu .context-actions-inline {
  display: flex;
  gap: 6px;
  padding: 2px 8px 8px;
}

.folder-context-menu .context-btn-small {
  flex: 1;
  height: 32px;
  border-radius: 10px;
  border: 1px solid var(--stroke);
  background: var(--panel-2);
  color: var(--text);
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
}

.folder-context-menu .context-btn-small.primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-contrast);
}

.folder-context-menu .context-btn-small:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
}

.folder-context-menu .context-btn-small:active {
  transform: translateY(0);
}

.folder-strip {
  position: relative;
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
}

.folder-strip::before,
.folder-strip::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  width: 28px;
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--anim-fast) var(--ease-out);
}

.folder-strip::before {
  left: 0;
  background: linear-gradient(90deg, var(--panel), transparent);
}

.folder-strip::after {
  right: 0;
  background: linear-gradient(270deg, var(--panel), transparent);
}

.folder-strip.has-left::before {
  opacity: 1;
}

.folder-strip.has-right::after {
  opacity: 1;
}

.folder-list {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  overflow-y: hidden;
  padding: 4px 0;
  scroll-behavior: smooth;
  scrollbar-width: none;
  width: 100%;
}

.folder-list::-webkit-scrollbar {
  display: none;
}

.folder-scroll {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 26px;
  height: 26px;
  border-radius: 999px;
  border: 1px solid var(--stroke);
  background: var(--panel);
  color: var(--text);
  display: grid;
  place-items: center;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--anim-fast) var(--ease-out);
}

.folder-scroll.left {
  left: 2px;
}

.folder-scroll.right {
  right: 2px;
}

.folder-strip:hover .folder-scroll {
  opacity: 1;
  pointer-events: auto;
}

.folder-strip:not(.has-left) .folder-scroll.left {
  display: none;
}

.folder-strip:not(.has-right) .folder-scroll.right {
  display: none;
}

.folder-item {
  padding: 6px 14px;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  background: var(--panel-2);
  color: var(--muted);
  font-size: var(--text-sm);
  font-weight: 500;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  white-space: nowrap;
  min-width: 0;
  flex-shrink: 0;
  transition:
    background-color var(--anim-fast) var(--ease-out),
    color var(--anim-fast) var(--ease-out),
    border-color var(--anim-fast) var(--ease-out),
    transform var(--anim-fast) var(--ease-out);
}

.folder-item:hover {
  color: var(--text);
  background: color-mix(in srgb, var(--text) 6%, var(--panel-2));
}

.folder-item:active {
  transform: scale(0.97);
}

.folder-item.active {
  color: var(--text);
  background: var(--panel-2);
  border-color: var(--stroke);
  font-weight: 600;
}

.folder-item.has-unread::after {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent);
  margin-left: var(--space-1);
  flex-shrink: 0;
  box-shadow: none;
}

/* + chip variant — square, smaller, distinct from selectable folder pills */
.folder-item-add {
  width: 32px;
  height: 32px;
  min-width: 32px;
  padding: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  border: 1px dashed color-mix(in srgb, var(--stroke) 80%, transparent);
  color: var(--muted);
}

.folder-item-add:hover {
  background: color-mix(in srgb, var(--accent) 8%, transparent);
  border-color: color-mix(in srgb, var(--accent) 50%, transparent);
  color: var(--accent);
}

.folder-item-add .icon {
  --icon-size: 14px;
}

@media (max-width: 720px) {
  .folder-scroll {
    display: none;
  }

  .folder-list {
    padding: 2px 8px;
    -webkit-overflow-scrolling: touch;
  }

  .folder-strip::before,
  .folder-strip::after {
    width: 16px;
  }
}

/* === groups/modals.css === */
/* ============================================================
   Create group — "Стройка хатки". A wooden scene (beaver mascot +
   the "logs" = picked members) sitting over a cream form. Markup in
   partials/group_create_modal.html, behaviour in groups/create.js.
   ============================================================ */

.hut-card {
  /* Wood palette — deliberately fixed so the "scene" reads the same in
     light and dark; the form area below still uses theme tokens. */
  --wood-tan: #c9b088;
  --wood-tan-2: #b3955f;
  --wood-line: rgba(60, 40, 18, 0.12);
  --wood-log: #5b3d27;
  --wood-log-2: #6f4d31;
  --wood-build: #29220f;
  --wood-cream: #f6ecd9;

  width: min(680px, 95vw);
  max-height: min(92vh, 920px);
  padding: 0;
  gap: 0;
  border-radius: 28px;
  overflow: hidden;
  background: var(--panel);
  box-shadow:
    0 30px 70px rgba(0, 0, 0, 0.45),
    0 0 0 1px var(--glass-stroke);
  display: flex;
  flex-direction: column;
}

/* --- Stage: the wood-plank scene ------------------------------------- */
.hut-stage {
  position: relative;
  padding: 20px;
  min-height: 216px;
  display: flex;
  flex-direction: column;
  background:
    repeating-linear-gradient(to bottom, transparent 0 27px, var(--wood-line) 27px 28px),
    linear-gradient(165deg, var(--wood-tan), var(--wood-tan-2));
  box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
}

.hut-badge {
  position: absolute;
  top: 16px;
  left: 16px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  max-width: 160px;
  padding: 6px 12px 6px 8px;
  border-radius: 999px;
  background: rgba(34, 24, 10, 0.55);
  color: var(--wood-cream);
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  line-height: 1.1;
  backdrop-filter: blur(4px);
}

.hut-badge-beaver {
  font-size: 15px;
}

.hut-close {
  position: absolute;
  top: 14px;
  right: 14px;
  width: 36px;
  height: 36px;
  display: grid;
  place-items: center;
  border: none;
  border-radius: 12px;
  background: rgba(34, 24, 10, 0.45);
  cursor: pointer;
  transition:
    background 0.18s ease,
    transform 0.18s ease;
}

.hut-close:hover {
  background: rgba(34, 24, 10, 0.72);
  transform: rotate(90deg);
}

.hut-close .icon {
  --icon-size: 16px;
  background-color: var(--wood-cream);
}

.hut-beaver {
  align-self: center;
  margin-top: 18px;
  font-size: 82px;
  line-height: 1;
  filter: drop-shadow(0 8px 10px rgba(0, 0, 0, 0.3));
  animation: hut-beaver-bob 3.2s ease-in-out infinite;
}

@keyframes hut-beaver-bob {
  0%,
  100% {
    transform: translateY(0) rotate(-1deg);
  }
  50% {
    transform: translateY(-5px) rotate(1deg);
  }
}

/* The logs row — picked members, stacked like felled timber. */
.hut-logs {
  margin-top: auto;
  padding-top: 16px;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  justify-content: center;
}

.hut-logs-empty {
  margin: 0 auto;
  padding: 8px 14px;
  border-radius: 12px;
  background: rgba(34, 24, 10, 0.32);
  color: var(--wood-cream);
  font-size: 13px;
  font-weight: 600;
}

.hut-log {
  --tilt: 0deg;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 5px 14px 5px 5px;
  border: none;
  border-radius: 999px;
  /* Layered grain: faint diagonal fibres + horizontal growth rings over the
     base log gradient — reads as varnished timber rather than a flat pill. */
  background:
    repeating-linear-gradient(118deg, rgba(255, 255, 255, 0.05) 0 2px, transparent 2px 8px),
    repeating-linear-gradient(0deg, rgba(0, 0, 0, 0.06) 0 3px, transparent 3px 9px),
    linear-gradient(180deg, var(--wood-log-2), var(--wood-log));
  color: var(--wood-cream);
  font-size: 13.5px;
  font-weight: 700;
  cursor: pointer;
  transform: rotate(var(--tilt));
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.2),
    inset 0 -2px 4px rgba(0, 0, 0, 0.28),
    0 4px 9px rgba(0, 0, 0, 0.3);
  transition:
    transform 0.16s ease,
    box-shadow 0.16s ease;
}

/* Each log lies at its own slight angle — felled timber, not a tidy stack. */
.hut-log:nth-of-type(6n + 1) {
  --tilt: -5deg;
}
.hut-log:nth-of-type(6n + 2) {
  --tilt: 3deg;
}
.hut-log:nth-of-type(6n + 3) {
  --tilt: -2deg;
}
.hut-log:nth-of-type(6n + 4) {
  --tilt: 5deg;
}
.hut-log:nth-of-type(6n + 5) {
  --tilt: -3deg;
}
.hut-log:nth-of-type(6n + 6) {
  --tilt: 2deg;
}

.hut-log:hover {
  transform: rotate(var(--tilt)) translateY(-3px) scale(1.03);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.2),
    inset 0 -2px 4px rgba(0, 0, 0, 0.28),
    0 9px 18px rgba(0, 0, 0, 0.34);
}

/* Dropped onto the pile: falls in from above and settles with a little bounce.
   Rotation is held via var(--tilt) so the log keeps its angle the whole way. */
.hut-log.is-entering {
  animation: hut-log-drop 0.34s cubic-bezier(0.34, 1.56, 0.64, 1) both;
}

@keyframes hut-log-drop {
  0% {
    opacity: 0;
    transform: rotate(var(--tilt)) translateY(-16px) scale(0.5);
  }
  60% {
    opacity: 1;
  }
  100% {
    opacity: 1;
    transform: rotate(var(--tilt)) translateY(0) scale(1);
  }
}

@media (prefers-reduced-motion: reduce) {
  .hut-beaver,
  .hut-log.is-entering {
    animation: none;
  }
}

.hut-log .avatar {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  font-size: 11px;
  box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.18);
}

.hut-log-name {
  max-width: 120px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.hut-log-remove {
  font-size: 16px;
  line-height: 1;
  opacity: 0.7;
  margin-left: 1px;
}

.hut-log:hover .hut-log-remove {
  opacity: 1;
}

/* --- Floor: cream form area ------------------------------------------ */
.hut-floor {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 20px 24px 4px;
  overflow-y: auto;
}

.hut-label {
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}

.hut-name-input {
  width: 100%;
  padding: 0;
  border: none;
  background: transparent;
  color: var(--text);
  font-family: var(--font-sans);
  font-size: 27px;
  font-weight: 800;
  letter-spacing: -0.02em;
}

.hut-name-input::placeholder {
  color: color-mix(in srgb, var(--muted) 70%, transparent);
}

.hut-name-input:focus {
  outline: none;
}

.hut-helper {
  margin: 0;
  font-size: 14px;
  color: var(--muted);
  min-height: 20px;
}

.hut-search-row {
  position: relative;
  display: flex;
  align-items: center;
  gap: 10px;
  height: 52px;
  padding: 0 8px 0 16px;
  border-radius: 16px;
  border: 1px solid var(--stroke);
  background: var(--panel-2);
  transition:
    border-color 0.18s ease,
    box-shadow 0.18s ease;
}

.hut-search-row:focus-within {
  border-color: color-mix(in srgb, var(--accent) 60%, var(--stroke));
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent);
}

.hut-search-icon {
  --icon-size: 18px;
  background-color: var(--muted);
  flex: 0 0 auto;
}

.hut-search {
  flex: 1;
  min-width: 0;
  border: none;
  background: transparent;
  color: var(--text);
  font-family: var(--font-sans);
  font-size: 15px;
}

.hut-search:focus {
  outline: none;
}

.hut-free {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 38px;
  padding: 0 12px 0 6px;
  border: none;
  border-radius: 999px;
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  color: color-mix(in srgb, var(--accent) 85%, var(--text));
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
  transition: background 0.18s ease;
}

.hut-free:hover {
  background: color-mix(in srgb, var(--accent) 20%, transparent);
}

.hut-free-avatars {
  display: inline-flex;
}

.hut-free-avatar {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  font-size: 10px;
  margin-left: -8px;
  box-shadow: 0 0 0 2px var(--panel);
}

.hut-free-avatar:first-child {
  margin-left: 0;
}

/* Suggestion list — contacts you haven't dragged in yet. In normal flow
   (not an absolute popover) so the scrollable floor never clips it. */
.hut-suggestions {
  display: flex;
  flex-direction: column;
  gap: 4px;
  max-height: 244px;
  overflow-y: auto;
  margin-top: 2px;
  padding: 6px;
  border-radius: 16px;
  border: 1px solid var(--stroke);
  background: var(--panel-2);
}

.hut-suggestion {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 10px;
  border: none;
  border-radius: 12px;
  background: transparent;
  color: var(--text);
  font-family: var(--font-sans);
  font-size: 15px;
  font-weight: 500;
  text-align: left;
  cursor: pointer;
  transition: background 0.14s ease;
}

.hut-suggestion:hover {
  background: color-mix(in srgb, var(--accent) 10%, transparent);
}

.hut-suggestion .avatar {
  width: 34px;
  height: 34px;
  border-radius: 12px;
  font-size: 13px;
  flex: 0 0 auto;
}

.hut-suggestion-name {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.hut-suggestion-add {
  flex: 0 0 auto;
  width: 26px;
  height: 26px;
  display: grid;
  place-items: center;
  border-radius: 8px;
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  color: var(--accent);
  font-size: 18px;
  line-height: 1;
}

.hut-suggestions-empty {
  padding: 16px 12px;
  text-align: center;
  font-size: 13px;
  color: var(--muted);
}

/* --- Rules ("правила запруды") --------------------------------------- */
.hut-rules {
  margin-top: 2px;
}

.hut-rules-toggle {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 10px 4px;
  border: none;
  background: transparent;
  color: var(--muted);
  font-family: var(--font-sans);
  font-size: 13.5px;
  font-weight: 600;
  cursor: pointer;
}

.hut-rules-toggle:hover {
  color: var(--text);
}

.hut-rules-toggle .icon {
  --icon-size: 16px;
  background-color: currentColor;
}

.hut-rules-toggle-text {
  flex: 1;
  text-align: left;
}

.hut-rules-arrow {
  width: 18px;
  height: 18px;
  display: grid;
  place-items: center;
  transition: transform 0.2s ease;
}

.hut-rules-arrow svg {
  width: 16px;
  height: 16px;
}

.hut-rules.is-open .hut-rules-arrow {
  transform: rotate(180deg);
}

.hut-rules-body {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 4px 4px 8px;
}

.hut-toggle {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 8px 4px;
  cursor: pointer;
}

.hut-toggle input[type="checkbox"] {
  appearance: none;
  flex: 0 0 auto;
  margin-top: 1px;
  width: 38px;
  height: 22px;
  background: var(--panel);
  border: 1px solid var(--stroke);
  border-radius: 999px;
  position: relative;
  cursor: pointer;
  transition:
    background 0.18s ease,
    border-color 0.18s ease;
}

.hut-toggle input[type="checkbox"]::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 2px;
  width: 16px;
  height: 16px;
  background: var(--text);
  border-radius: 50%;
  transform: translateY(-50%);
  transition:
    left 0.18s ease,
    background 0.18s ease;
}

.hut-toggle input[type="checkbox"]:checked {
  background: var(--accent);
  border-color: color-mix(in srgb, var(--accent) 60%, transparent);
}

.hut-toggle input[type="checkbox"]:checked::after {
  left: calc(100% - 18px);
  background: var(--accent-contrast, #fff);
}

.hut-toggle-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.hut-toggle-title {
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
}

.hut-toggle-hint {
  font-size: 12px;
  color: var(--muted);
}

/* --- Footer ---------------------------------------------------------- */
.hut-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 24px 20px;
}

.hut-footer .form-status {
  flex: 1;
  min-height: 16px;
  font-size: 13px;
}

.hut-footer .form-status.error {
  color: var(--danger);
}

.hut-footer-actions {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 10px;
}

.hut-cancel {
  height: 50px;
  padding: 0 20px;
  border: none;
  border-radius: 16px;
  background: transparent;
  color: var(--muted);
  font-family: var(--font-sans);
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
  transition:
    color 0.16s ease,
    background 0.16s ease;
}

.hut-cancel:hover {
  color: var(--text);
  background: var(--panel-2);
}

.hut-build {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  height: 50px;
  padding: 0 22px;
  border: none;
  border-radius: 16px;
  background: var(--wood-build);
  color: var(--wood-cream);
  font-family: var(--font-sans);
  font-size: 15px;
  font-weight: 800;
  cursor: pointer;
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.3);
  transition:
    transform 0.16s ease,
    box-shadow 0.16s ease,
    opacity 0.16s ease;
}

.hut-build:hover:not(:disabled) {
  transform: translateY(-2px);
  box-shadow: 0 12px 26px rgba(0, 0, 0, 0.38);
}

.hut-build:active:not(:disabled) {
  transform: translateY(0);
}

.hut-build:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.hut-build-emoji {
  font-size: 17px;
}

.group-user-list {
  display: grid;
  gap: 12px;
  max-height: 280px;
  overflow-y: auto;
  margin: 16px 0 0;
  padding-right: 8px;
}

.group-user-item {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 12px 16px;
  border-radius: 18px;
  border: 1px solid color-mix(in srgb, var(--stroke) 50%, transparent);
  background: color-mix(in srgb, var(--panel) 60%, transparent);
  transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}

.group-user-item:hover {
  border-color: color-mix(in srgb, var(--accent) 40%, transparent);
  background: color-mix(in srgb, var(--panel-2) 90%, transparent);
  transform: translateX(4px);
}

.group-user-item.is-selected {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 8%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 20%, transparent);
}

.group-user-item label {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  cursor: pointer;
  font-size: 15px;
  font-weight: 500;
}

.group-user-item input[type="checkbox"] {
  accent-color: var(--accent);
  width: 20px;
  height: 20px;
  border-radius: 6px;
  cursor: pointer;
  transition: transform 0.2s;
}

.group-user-item input[type="checkbox"]:hover {
  transform: scale(1.1);
}

.group-user-item .avatar {
  width: 36px;
  height: 36px;
  border-radius: 12px;
  font-size: 14px;
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
}

@media (max-width: 720px) {
  .hut-card {
    width: 100vw;
    max-height: 100vh;
    height: 100dvh;
    border-radius: 0;
  }

  .hut-footer {
    flex-wrap: wrap;
  }

  .hut-footer-actions {
    width: 100%;
  }

  .hut-build {
    flex: 1;
    justify-content: center;
  }
}

/* ============================================================
   Group details — right-docked side panel. Reuses the profile
   card design system (.profile-card + .side-panel-*); only the
   group-specific bits live here. See partials/group_details_modal.html.
   ============================================================ */

/* Name — click the title (or pencil) to edit in place (admins only). */
#group-details-modal .group-name-row {
  display: flex;
  align-items: center;
  gap: 8px;
}

#group-details-modal .group-name-display.is-editable {
  cursor: text;
  border-radius: 8px;
  transition: color 0.15s ease;
}

#group-details-modal .group-name-display.is-editable:hover {
  color: var(--accent);
}

#group-details-modal .group-name-edit {
  flex: 0 0 auto;
  width: 28px;
  height: 28px;
  display: grid;
  place-items: center;
  border: none;
  border-radius: 8px;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  opacity: 0;
  transition:
    opacity 0.15s ease,
    background-color 0.15s ease,
    color 0.15s ease;
}

#group-details-modal .group-name-row:hover .group-name-edit {
  opacity: 1;
}

#group-details-modal .group-name-edit:hover {
  background: var(--panel-2);
  color: var(--accent);
}

#group-details-modal .group-name-edit .icon {
  --icon-size: 15px;
}

#group-details-modal .group-name-input {
  width: 100%;
  margin: 0 0 4px;
  padding: 2px 8px;
  border: 1px solid color-mix(in srgb, var(--accent) 55%, var(--stroke));
  border-radius: 10px;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: 21px;
  font-weight: 700;
  letter-spacing: -0.01em;
}

#group-details-modal .group-name-input:focus {
  outline: none;
  border-color: var(--accent);
}

/* Description — markdown view that admins click to edit as raw text. */
#group-details-modal .group-description-display.is-editable {
  cursor: text;
}

#group-details-modal .group-description-display.is-placeholder {
  color: var(--muted);
  font-style: italic;
}

#group-details-modal .group-description-input {
  width: 100%;
  resize: vertical;
  min-height: 64px;
  padding: 8px 10px;
  border: 1px solid color-mix(in srgb, var(--accent) 55%, var(--stroke));
  border-radius: 10px;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: 14px;
  line-height: 1.4;
}

#group-details-modal .group-description-input:focus {
  outline: none;
  border-color: var(--accent);
}

/* Mute toggle in the action grid lights up when notifications are off. */
#group-details-modal .action-grid-btn.mute-toggle.is-active {
  color: var(--accent);
  background-color: color-mix(in srgb, var(--accent) 12%, var(--panel-2));
}

#group-details-modal .action-grid-btn.mute-toggle.is-active:hover {
  background-color: color-mix(in srgb, var(--accent) 16%, var(--panel-2));
}

/* Members block: section title + live count badge. */
#group-details-modal .group-members-block .profile-section-title {
  display: flex;
  align-items: center;
  gap: 8px;
}

#group-details-modal .group-member-count {
  font-size: 11px;
  font-weight: 700;
  min-width: 18px;
  height: 18px;
  padding: 0 6px;
  line-height: 18px;
  text-align: center;
  border-radius: 9px;
  background: color-mix(in srgb, var(--muted) 22%, transparent);
  color: var(--muted);
}

/* "Добавить участника" affordance (admins only). */
#group-details-modal .group-add-row {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 8px;
  margin-bottom: 4px;
  border: none;
  background: transparent;
  border-radius: 12px;
  cursor: pointer;
  text-align: left;
  color: var(--accent);
  font-family: var(--font-sans);
  font-size: 14px;
  font-weight: 600;
}

#group-details-modal .group-add-row:hover {
  background: color-mix(in srgb, var(--accent) 10%, transparent);
}

#group-details-modal .group-add-row-icon {
  width: 32px;
  height: 32px;
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  border-radius: 9px;
  background: color-mix(in srgb, var(--accent) 14%, transparent);
}

#group-details-modal .group-add-row-icon .icon {
  --icon-size: 16px;
  background-color: var(--accent);
}

/* Collapsible add-members panel. */
#group-details-modal .group-add-panel {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px;
  margin-bottom: 12px;
  border-radius: 16px;
  background: var(--panel-2);
  border: 1px solid var(--stroke);
}

#group-details-modal .group-add-panel .group-user-list {
  margin: 0;
  max-height: 220px;
}

/* === groups/members.css === */
.group-section-collapsible {
  overflow: hidden;
}

.group-section-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  width: 100%;
  padding: 0;
  margin: 0;
  border: none;
  background: transparent;
  cursor: pointer;
  text-align: left;
}

.group-section-toggle:hover .group-section-arrow {
  color: var(--accent);
}

.group-section-toggle:focus-visible {
  outline: 2px solid color-mix(in srgb, var(--accent) 60%, transparent);
  outline-offset: 2px;
  border-radius: 8px;
}

.group-section-title-row {
  display: flex;
  align-items: center;
  gap: 10px;
}

.group-section-toggle h5 {
  margin: 0;
  font-size: 15px;
  font-weight: 600;
  color: var(--text);
}

.group-section-badge {
  font-size: 12px;
  font-weight: 600;
  color: var(--muted);
  background: var(--panel);
  padding: 3px 10px;
  border-radius: 999px;
  border: 1px solid var(--stroke);
}

.group-section-badge.has-items {
  color: var(--accent);
  border-color: color-mix(in srgb, var(--accent) 40%, transparent);
  background: color-mix(in srgb, var(--accent) 10%, transparent);
}

.group-section-arrow {
  width: 20px;
  height: 20px;
  display: grid;
  place-items: center;
  color: var(--muted);
  transition:
    transform 0.25s cubic-bezier(0.4, 0, 0.2, 1),
    color 0.2s;
}

.group-section-arrow svg {
  width: 16px;
  height: 16px;
}

.group-section-collapsible.is-expanded .group-section-arrow {
  transform: rotate(180deg);
}

.group-section-content {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

.group-section-collapsible.is-expanded .group-section-content {
  grid-template-rows: 1fr;
}

.group-section-content-inner {
  overflow: hidden;
}

.group-section-collapsible.is-expanded .group-section-content-inner {
  padding-top: 16px;
}

.group-member-list {
  display: grid;
  gap: 2px;
}

/* Flat, borderless rows to match the profile panel's clean list aesthetic. */
.group-member {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 12px;
  padding: 8px;
  border-radius: 12px;
  background: transparent;
  transition: background 0.18s ease;
  cursor: default;
  user-select: none;
}

.group-member:hover {
  background: color-mix(in srgb, var(--accent) 8%, transparent);
}

.group-member.is-contextable {
  cursor: context-menu;
}

.group-member .avatar {
  width: 38px;
  height: 38px;
  border-radius: 11px;
  font-size: 14px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
  flex-shrink: 0;
}

.group-member-info {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
  min-width: 0;
}

.group-member-name {
  font-size: 14px;
  font-weight: 500;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.group-member-meta {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--muted);
}

.group-member-role {
  font-weight: 500;
}

.group-member-role.is-admin {
  color: var(--accent);
}

.group-member-status {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--muted);
  flex-shrink: 0;
}

.group-member-status.online {
  background: var(--accent-2);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent-2) 20%, transparent);
}

.group-empty-state {
  padding: 20px;
  text-align: center;
  color: var(--muted);
  font-size: 13px;
  background: color-mix(in srgb, var(--panel) 30%, transparent);
  border-radius: 14px;
  border: 1px dashed color-mix(in srgb, var(--stroke) 60%, transparent);
}

/* === gallery.css === */
/* ── Сетка медиа ── */
.media-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: 12px;
}

/* ── Базовая карточка — Glassmorphism ── */
.media-item {
  border-radius: 16px;
  background: rgba(255, 255, 255, 0.04);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border: 1px solid rgba(255, 255, 255, 0.08);
  color: var(--text);
  overflow: hidden;
  transition:
    transform 0.25s cubic-bezier(0.4, 0, 0.2, 1),
    background 0.25s cubic-bezier(0.4, 0, 0.2, 1),
    border-color 0.25s cubic-bezier(0.4, 0, 0.2, 1),
    box-shadow 0.25s cubic-bezier(0.4, 0, 0.2, 1);
  box-shadow:
    0 4px 16px rgba(0, 0, 0, 0.12),
    inset 0 1px 0 rgba(255, 255, 255, 0.05);
}

.media-item:hover {
  background: rgba(255, 255, 255, 0.07);
  border-color: rgba(255, 255, 255, 0.14);
  transform: translateY(-3px);
  box-shadow:
    0 12px 32px rgba(0, 0, 0, 0.22),
    inset 0 1px 0 rgba(255, 255, 255, 0.08);
}

/* ── Фото-карточка ── */
.media-image {
  display: flex;
  flex-direction: column;
  gap: 0;
  cursor: pointer;
  padding: 0;
}

.media-image img {
  width: 100%;
  height: 140px;
  object-fit: cover;
  display: block;
  transition: opacity 0.2s ease;
}

.media-image:hover img {
  opacity: 0.92;
}

/* ── Видео-карточка ── */
.media-video {
  display: flex;
  flex-direction: column;
  gap: 0;
  padding: 0;
}

/* Превью-кнопка видео */
.media-video-thumb {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  border: none;
  background: #000;
  padding: 0;
  cursor: pointer;
}

.media-video-thumb video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  pointer-events: none;
}

/* Кнопка Play на превью — glass circle */
.media-video-play {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.45);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 255, 255, 0.15);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.25s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.media-video-thumb:hover .media-video-play {
  transform: translate(-50%, -50%) scale(1.12);
  background: rgba(0, 0, 0, 0.65);
  border-color: rgba(255, 255, 255, 0.25);
}

.media-video-play .icon {
  --icon-size: 20px;
  background-color: white;
  margin-left: 2px;
}

/* Бейдж длительности */
.media-video-duration {
  position: absolute;
  bottom: 8px;
  right: 8px;
  padding: 3px 8px;
  border-radius: 8px;
  background: rgba(0, 0, 0, 0.65);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  border: 1px solid rgba(255, 255, 255, 0.08);
  color: white;
  font-size: 11px;
  font-weight: 600;
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
}

/* ── Файл-карточка ── */
.media-file {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 14px;
  text-decoration: none;
}

.media-file-name {
  font-size: 13px;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.media-file-link {
  text-decoration: none;
  color: inherit;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

/* ── Общие элементы ── */
.media-meta {
  font-size: 11px;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  padding: 8px 12px;
}

.media-download {
  align-self: flex-end;
  border: 1px solid rgba(255, 255, 255, 0.1);
  background: rgba(255, 255, 255, 0.06);
  color: var(--text);
  border-radius: 10px;
  padding: 6px 12px;
  margin: 0 12px 10px;
  font-size: 12px;
  text-decoration: none;
  transition: all 0.2s ease;
}

.media-download:hover {
  background: rgba(255, 255, 255, 0.1);
  border-color: rgba(255, 255, 255, 0.2);
}

.media-empty {
  font-size: 13px;
  color: var(--muted);
  text-align: center;
  padding: 24px 0;
}

/* === calls.css === */

/* === calls/layout.css === */
/* Inline call region — lives inside .chat-panel right under chat-header.
   Shown when there's an active call in the current conversation; sizing
   depends on the call view (expanded inline region ⇄ collapsed strip), see
   chat-tiles.css. Maximized = full-viewport Discord-style stage (below). */

.call-modal {
  position: relative;
  display: flex;
  flex-direction: column;
  flex: 0 0 auto;
  min-height: 0;
  background: var(--panel);
  border-bottom: 1px solid var(--stroke);
}

/* Maximized = full-viewport overlay. !important on positioning so the
   tiles-position rules (flex sizing, grid placement) can't fight us. */
.call-modal.is-maximized {
  position: fixed !important;
  inset: 0 !important;
  z-index: 11000 !important;
  width: 100vw !important;
  height: 100vh !important;
  height: 100dvh !important;
  max-height: none !important;
  min-height: 0 !important;
  flex: none !important;
}

.call-modal.is-maximized .call-card {
  background: var(--panel);
}

/* === Fullscreen Discord stage ===
   Centre the participants on both axes (kills the avatar-stuck-at-top bug from
   the grid's align-content:start) and let the tiles grow large. Content that
   genuinely overflows (big groups) falls back to top-aligned scroll via the
   `safe` keyword instead of clipping faces off-screen. */
.call-modal.is-maximized .call-body {
  padding: clamp(16px, 3vh, 32px);
}

.call-modal.is-maximized .call-grid {
  display: flex;
  flex-wrap: wrap;
  align-content: safe center;
  align-items: center;
  justify-content: center;
  gap: clamp(16px, 2vw, 28px);
  padding: 0;
  overflow: auto;
}

/* Voice-only tiles: large centred cards with a big avatar. */
.call-modal.is-maximized .call-participant:not(.has-video) {
  flex: 0 1 clamp(220px, 26vw, 360px);
  min-height: clamp(200px, 34vh, 360px);
  background: color-mix(in srgb, var(--panel-2) 70%, transparent);
  border: 1px solid var(--stroke);
  border-radius: var(--radius-lg, 18px);
  padding: var(--space-4);
  gap: var(--space-3);
}

.call-modal.is-maximized .call-participant:not(.has-video) .call-avatar {
  width: clamp(96px, 16vh, 160px);
  font-size: clamp(32px, 6vh, 56px);
}

/* Media tiles (camera / screen-share): take the stage. Screen-share already
   uses object-fit:contain (see grid.css .is-screen) so it's never cropped;
   the tile grows up to a sane cap and keeps its 16:9 box without scrolling. */
.call-modal.is-maximized .call-participant.has-video {
  flex: 1 1 clamp(360px, 60vw, 1100px);
  max-width: 100%;
  max-height: 100%;
  align-self: stretch;
}

/* The collapse-to-strip affordance makes no sense while fullscreen — only the
   maximize button (acting as "exit fullscreen") stays. */
.call-modal.is-maximized .call-collapse {
  display: none;
}

/* Lock body scroll while maximized so a stray wheel event doesn't slide
   messages behind. */
html.call-is-maximized,
html.call-is-maximized body {
  overflow: hidden;
}

.call-modal.is-maximized .call-maximize .icon {
  /* Swap to a collapse-style affordance — still icon-expand but rotated
     so the user gets visual feedback that another click will collapse. */
  transform: rotate(180deg);
}

.call-card {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
  min-height: 0;
  background: transparent;
  border: none;
  border-radius: 0;
  box-shadow: none;
  overflow: hidden;
}

.call-card.incoming-only {
  /* Во время рингтона показываем только incoming-карточку поверх grid+controls,
     прочая структура остаётся, но скрывается селекторами в overlays.css. */
}

.call-header {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-2) var(--space-4);
  border-bottom: 1px solid var(--stroke);
}

/* Slim status line — call type + timer only. The peer name lives in the chat
   header above, so it isn't repeated here. */
.call-status-line {
  margin: 0;
  color: var(--muted);
  font-size: 12px;
  font-weight: 500;
}

.net-indicator-wrap {
  position: relative;
  display: inline-flex;
  align-items: center;
}

.net-popover {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  width: 260px;
  padding: 10px 12px;
  border-radius: 12px;
  background: color-mix(in srgb, var(--panel) 92%, var(--bg));
  border: 1px solid var(--stroke);
  box-shadow: 0 14px 40px color-mix(in srgb, #000 30%, transparent);
  opacity: 0;
  transform: translateY(-8px) scale(0.96);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  pointer-events: none;
  transition:
    opacity 0.22s cubic-bezier(0.16, 1, 0.3, 1),
    transform 0.22s cubic-bezier(0.16, 1, 0.3, 1);
  z-index: 10;
}

.net-popover.is-open {
  opacity: 1;
  transform: translateY(0) scale(1);
  pointer-events: auto;
}

.net-popover-title {
  font-size: 12px;
  font-weight: 600;
  color: var(--text);
  margin-bottom: 8px;
}

.net-chart {
  width: 100%;
  height: 80px;
  display: block;
  background: color-mix(in srgb, var(--panel) 88%, transparent);
  border-radius: 8px;
}

.net-popover-stats {
  margin-top: 8px;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 6px;
  font-size: 11px;
  color: var(--muted);
}

.net-popover-stats div {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
}

.net-popover-stats strong {
  font-size: 12px;
  color: var(--text);
}

.net-popover-stats div:nth-child(1) strong {
  color: var(--accent);
}
.net-popover-stats div:nth-child(2) strong {
  color: var(--accent-2);
}
.net-popover-stats div:nth-child(3) strong {
  color: var(--status-warn);
}

.call-body {
  flex: 1;
  padding: var(--space-3) var(--space-4);
  position: relative;
  overflow: hidden;
  min-height: 0;
}

/* === calls/grid.css === */
.call-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: var(--space-3);
  height: 100%;
  overflow-y: auto;
  align-content: safe center;
  min-height: 0;
  padding: var(--space-2);
}

.call-participant {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-2);
  min-height: 0;
  background: transparent;
  border: none;
  border-radius: var(--radius-md);
  cursor: default;
  --speech-level: 0;
  /* Speaking ring uses a fixed green so "talking" reads unambiguously on any
     theme palette, instead of blending into the beige accent. */
  --call-speaking: #3ba55d;
  overflow: hidden;
}

/* Video tile — rectangular with rounded corners; replaces the circular
   avatar layout when a stream is attached. */
.call-participant.has-video {
  background: color-mix(in srgb, var(--panel) 80%, transparent);
  border: 1px solid var(--stroke);
  justify-content: flex-end;
  align-items: stretch;
  padding: 0;
  aspect-ratio: 16 / 9;
  max-width: 100%;
  max-height: 100%;
  justify-self: center;
  align-self: center;
}

.call-participant.is-speaking:not(.has-video) .call-avatar {
  box-shadow:
    0 0 0 calc(3px + 3px * var(--speech-level, 0)) var(--call-speaking),
    0 0 calc(10px + 16px * var(--speech-level, 0))
      color-mix(in srgb, var(--call-speaking) 55%, transparent);
}

.call-participant.has-video.is-speaking {
  border-color: color-mix(
    in srgb,
    var(--accent) calc(40% + 60% * var(--speech-level, 0)),
    var(--stroke)
  );
  box-shadow: 0 0 calc(6px + 10px * var(--speech-level, 0))
    color-mix(in srgb, var(--accent) calc(30% + 40% * var(--speech-level, 0)), transparent);
}

.call-participant.is-offline {
  opacity: 0.65;
  filter: grayscale(0.2);
}

.call-participant.is-offline .call-video {
  filter: grayscale(0.6) brightness(0.7);
}

.call-participant.is-offline .call-name-text {
  text-decoration: line-through;
  text-decoration-color: color-mix(in srgb, var(--muted) 80%, transparent);
}

.call-grid.is-connection-loss .call-participant {
  opacity: 0.55;
  filter: grayscale(0.3) brightness(0.85);
  transition:
    opacity 0.2s ease,
    filter 0.2s ease;
}

.call-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: none;
  z-index: 1;
}

.call-participant.has-video .call-video {
  display: block;
}

.call-participant.is-screen .call-video {
  object-fit: contain;
  background: color-mix(in srgb, var(--bg) 80%, #000 20%);
}

.call-avatar {
  position: relative;
  width: clamp(56px, 18vh, 96px);
  aspect-ratio: 1 / 1;
  border-radius: clamp(16px, 4vh, 22px);
  background: linear-gradient(
    145deg,
    color-mix(in srgb, var(--accent) 40%, transparent),
    color-mix(in srgb, var(--accent-2) 20%, transparent)
  );
  display: grid;
  place-items: center;
  font-weight: 600;
  font-size: clamp(20px, 4vh, 32px);
  color: var(--text);
  z-index: 2;
  overflow: hidden;
  flex-shrink: 0;
  transition: box-shadow 0.12s linear;
}

.call-avatar-wrap {
  position: relative;
  display: grid;
  place-items: center;
  flex-shrink: 0;
  z-index: 2;
}

/* Video tiles show state in the meta bar, so the avatar + its badge drop out. */
.call-participant.has-video .call-avatar-wrap {
  display: none;
}

.call-tile-badge {
  position: absolute;
  right: -2px;
  bottom: -2px;
  display: none;
  align-items: center;
  gap: 2px;
  padding: 3px;
  border-radius: 999px;
  background: var(--danger);
  border: 2px solid var(--panel);
  pointer-events: none;
  z-index: 3;
}

.call-participant.has-status-badge:not(.has-video) .call-tile-badge {
  display: inline-flex;
}

.call-tile-badge .icon {
  --icon-size: 12px;
  background-color: #fff;
}

.call-tile-badge .badge-mic,
.call-tile-badge .badge-deaf {
  display: none;
}

.call-participant.is-muted .call-tile-badge .badge-mic {
  display: inline-block;
}

.call-participant.is-deafened .call-tile-badge .badge-deaf {
  display: inline-block;
}

.call-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.call-meta {
  position: relative;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-1);
  flex-direction: column;
}

.call-participant.has-video .call-meta {
  position: absolute;
  bottom: var(--space-2);
  left: var(--space-2);
  right: var(--space-2);
  flex-direction: row;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-2);
  background: color-mix(in srgb, var(--panel) 70%, transparent);
  border: 1px solid var(--stroke);
  padding: 4px 8px;
  border-radius: var(--radius-sm);
}

.call-name {
  font-size: 13px;
  font-weight: 600;
  display: flex;
  flex-direction: column;
  gap: 2px;
  align-items: center;
}

.call-participant.has-video .call-name {
  font-size: 12px;
  align-items: flex-start;
  flex-direction: row;
  gap: var(--space-1);
}

.call-name-text {
  display: inline-block;
}

.call-status {
  font-size: 11px;
  font-weight: 500;
  color: var(--muted);
}

.call-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  color: var(--accent-2);
}

.call-badge .icon {
  --icon-size: 12px;
}

.call-icons {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 12px;
  color: var(--muted);
}

/* In avatar-only mode mic/audio state is already conveyed by the speaking
   ring + the avatar's own outline, so the duplicate icon row is hidden. */
.call-participant:not(.has-video) .call-icons {
  display: none;
}

.call-icons .is-muted {
  color: var(--danger);
}

.call-grid.has-focused-tile {
  grid-template-columns: minmax(0, 1fr);
  align-content: stretch;
}

.call-grid.has-focused-tile .call-participant {
  min-height: 84px;
  opacity: 0.72;
}

.call-grid.has-focused-tile .call-participant.is-focused {
  grid-column: 1 / -1;
  min-height: 240px;
  opacity: 1;
}

/* === calls/controls.css === */
.call-controls {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 14px 18px 18px;
  border-top: 1px solid var(--stroke);
}

/* Collapse + fullscreen toggles anchor to the right edge so the primary
   controls stay centred. */
.call-controls-aux {
  position: absolute;
  right: 18px;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  gap: 4px;
}

.call-control {
  width: 44px;
  height: 44px;
  border-radius: 12px;
  border: 1px solid transparent;
  background: transparent;
  color: var(--text);
  cursor: pointer;
  display: grid;
  place-items: center;
  font-size: 18px;
  transition:
    background-color var(--anim-fast) var(--ease-out),
    color var(--anim-fast) var(--ease-out),
    transform 80ms var(--ease-out);
}

.call-control:hover {
  background: color-mix(in srgb, var(--text) 10%, transparent);
}

.call-control:active {
  transform: scale(0.95);
}

.call-control.is-active {
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 14%, transparent);
}

.call-control.is-muted,
.call-control.is-deafened {
  color: var(--danger);
}

.call-control.is-muted:hover,
.call-control.is-deafened:hover {
  background: color-mix(in srgb, var(--danger) 12%, transparent);
}

.call-control.danger {
  background: color-mix(in srgb, var(--danger) 18%, transparent);
  border-color: color-mix(in srgb, var(--danger) 50%, transparent);
  color: var(--danger);
}

.call-control.danger:hover {
  background: color-mix(in srgb, var(--danger) 28%, transparent);
}

/* === calls/overlays.css === */
.call-incoming {
  position: absolute;
  inset: 0;
  background: color-mix(in srgb, var(--overlay) 85%, transparent);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  z-index: 5;
  backdrop-filter: blur(6px);
}

.global-incoming-call {
  position: fixed;
  inset: 0;
  z-index: 12000;
  display: grid;
  place-items: center;
  padding: 24px;
}

.global-incoming-call[hidden] {
  display: none;
}

.global-incoming-backdrop {
  position: absolute;
  inset: 0;
  background: color-mix(in srgb, var(--overlay) 72%, transparent);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

.global-incoming-card {
  z-index: 1;
}

.call-card.incoming-only .call-header,
.call-card.incoming-only .call-controls,
.call-card.incoming-only .call-grid,
.call-card.incoming-only .call-audio-panel {
  display: none;
}

.call-incoming-card {
  position: relative;
  width: min(380px, 90vw);
  padding: 22px;
  border-radius: 22px;
  background: color-mix(in srgb, var(--panel) 90%, transparent);
  border: 1px solid color-mix(in srgb, var(--stroke) 65%, transparent);
  display: grid;
  gap: 14px;
  text-align: center;
  overflow: hidden;
  box-shadow: 0 30px 60px color-mix(in srgb, var(--shadow) 50%, transparent);
}

.call-incoming-card::before {
  content: "";
  position: absolute;
  inset: -20%;
  background-image: var(--incoming-bg);
  background-size: cover;
  background-position: center;
  filter: blur(12px) saturate(1.1);
  opacity: 0.3;
}

.call-incoming-card::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    180deg,
    color-mix(in srgb, var(--panel) 75%, transparent),
    transparent
  );
  opacity: 0.45;
}

.call-incoming-card > * {
  position: relative;
  z-index: 1;
}

.call-incoming-avatar {
  width: 72px;
  height: 72px;
  border-radius: 20px;
  margin: 0 auto;
  border: 1px solid var(--stroke);
  background: var(--panel-2);
  display: grid;
  place-items: center;
  font-size: 26px;
  color: var(--text);
  overflow: hidden;
}

.call-incoming-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.call-incoming-text {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.call-incoming-title {
  font-size: 12px;
  color: var(--muted);
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.call-incoming-name {
  font-size: 20px;
  font-weight: 600;
}

.call-incoming-type {
  font-size: 12px;
  color: var(--muted);
}

.call-incoming-actions {
  display: flex;
  gap: 12px;
  justify-content: center;
}

.call-incoming-actions .button {
  min-width: 140px;
}

.call-incoming-actions .button.secondary {
  margin-top: 0;
}

/* === calls/audio.css === */
.call-audio-panel {
  position: absolute;
  left: 50%;
  bottom: 82px;
  width: min(320px, calc(100vw - 32px));
  max-width: calc(100vw - 40px);
  background: color-mix(in srgb, var(--panel) 88%, transparent);
  border: 1px solid var(--stroke);
  border-radius: 12px;
  padding: 12px;
  display: grid;
  gap: 8px;
  box-shadow: var(--shadow);
  z-index: 2;
  box-sizing: border-box;
  opacity: 0;
  transform: translate(-50%, 12px) scale(0.98);
  pointer-events: none;
  transition:
    opacity 180ms var(--ease-out),
    transform 180ms var(--ease-out);
  backdrop-filter: blur(8px);
}

.call-audio-panel.is-open {
  opacity: 1;
  transform: translate(-50%, 0) scale(1);
  pointer-events: auto;
}

.call-audio-title {
  font-size: 12px;
  color: var(--muted);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.call-audio-subtitle {
  font-size: 11px;
  color: var(--muted);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  margin-top: 6px;
}

.call-audio-section {
  display: grid;
  gap: 8px;
}

.call-audio-option {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
}

.call-audio-check {
  position: relative;
  cursor: pointer;
  user-select: none;
}

.call-audio-check input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.call-audio-checkmark {
  width: 14px;
  height: 14px;
  border-radius: 4px;
  border: 1px solid var(--stroke);
  background: color-mix(in srgb, var(--panel) 85%, transparent);
  display: grid;
  place-items: center;
  transition:
    border-color var(--anim-fast) var(--ease-out),
    background var(--anim-fast) var(--ease-out),
    box-shadow var(--anim-fast) var(--ease-out);
  flex-shrink: 0;
}

.call-audio-checkmark::after {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 2px;
  background: transparent;
  transition: background var(--anim-fast) var(--ease-out);
}

.call-audio-check input:checked + .call-audio-checkmark {
  border-color: color-mix(in srgb, var(--accent) 60%, transparent);
  background: color-mix(in srgb, var(--accent) 20%, transparent);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 20%, transparent);
}

.call-audio-check input:checked + .call-audio-checkmark::after {
  background: color-mix(in srgb, var(--accent) 70%, var(--text));
}

.call-audio-check input:focus-visible + .call-audio-checkmark {
  border-color: color-mix(in srgb, var(--accent) 60%, transparent);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 25%, transparent);
}

.call-audio-divider {
  height: 1px;
  background: var(--stroke);
  margin: 10px 0;
}

.call-audio-users {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 6px;
}

.call-audio-user {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 12px;
  width: 100%;
}

.call-audio-user-name {
  width: 96px;
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  display: flex;
  align-items: center;
  gap: 6px;
}

.call-audio-range {
  flex: 1;
  min-width: 0;
  appearance: none;
  height: 6px;
  border-radius: 999px;
  border: 1px solid var(--stroke);
  background: color-mix(in srgb, var(--panel-2) 80%, transparent);
}

.call-audio-range::-webkit-slider-thumb {
  appearance: none;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--accent) 75%, var(--text));
  border: 2px solid color-mix(in srgb, var(--panel) 70%, transparent);
  box-shadow: 0 2px 8px color-mix(in srgb, var(--accent) 30%, transparent);
  cursor: pointer;
}

.call-audio-range::-moz-range-thumb {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--accent) 75%, var(--text));
  border: 2px solid color-mix(in srgb, var(--panel) 70%, transparent);
  box-shadow: 0 2px 8px color-mix(in srgb, var(--accent) 30%, transparent);
  cursor: pointer;
}

.call-audio-range::-moz-range-track {
  flex: 1;
  min-width: 0;
  height: 6px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--panel-2) 80%, transparent);
  border: 1px solid var(--stroke);
}

.call-audio-user-kind {
  font-size: 10px;
  color: var(--muted);
  border: 1px solid var(--stroke);
  border-radius: 999px;
  padding: 1px 6px;
}

.call-audio-empty {
  font-size: 12px;
  color: var(--muted);
}

.call-audio-hint {
  font-size: 11px;
  color: var(--muted);
}

/* === calls/video.css === */
/* Контейнер для видео и наших кастомных контролов */
.video-container {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #000;
  overflow: hidden;
  z-index: 1;
  container-type: inline-size;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
}

/* Видео в сообщениях - стабильная обертка */
.attachment-video {
  display: flex;
  justify-content: center;
  width: 100%;
}

.attachment-video .video-container {
  position: relative;
  width: var(--cap-img-w, 420px);
  max-width: 100%;
  max-height: var(--cap-img-h, 480px);
  height: auto;
  margin: 4px 0;
  border-radius: 16px;
  background: #000;
  display: block;
  border: 1px solid rgba(255, 255, 255, 0.05);
  overflow: hidden;
}

/* Aspect-box: once the clip ratio is known the container holds it so the
   video fills edge-to-edge — no letterbox bars, and the box size comes from
   the ratio, not the source resolution. The width/max-height caps above turn
   a tall clip narrow instead of letting it eat the whole column. */
.attachment-video.is-sized .video-container {
  aspect-ratio: var(--va-ar);
}

/* Before metadata loads, reserve a neutral 16:9 box so layout doesn't jump. */
.attachment-video:not(.is-sized) .video-container {
  aspect-ratio: 16 / 9;
}

.attachment-video .video-container video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  border-radius: 16px;
}

/* Оверлей для контролов */
.video-controls-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: 12px;
  background: linear-gradient(to top, rgba(0, 0, 0, 0.6) 0%, transparent 50%);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  z-index: 10;
}

.attachment-video .video-controls-overlay {
  border-radius: 16px;
}

.video-container.controls-active .video-controls-overlay {
  opacity: 1;
  pointer-events: auto;
}

/* Фуллскрин — drop the inline aspect-box and size caps so the clip fills the
   whole viewport (contain), instead of staying trapped in the 420px box. */
.video-container:fullscreen {
  width: 100vw;
  height: 100vh;
  max-width: none;
  max-height: none;
  background: #000;
  border-radius: 0;
  border: none;
}

.attachment-video .video-container:fullscreen {
  aspect-ratio: auto;
}

.video-container:fullscreen video {
  width: 100%;
  height: 100%;
  max-width: none;
  max-height: none;
  object-fit: contain;
  border-radius: 0;
}

.video-container:fullscreen .video-controls-overlay {
  border-radius: 0;
  padding: 24px;
}

/* В фуллскрине ВСЕГДА показываем контролы, даже если hideControlsBar */
.video-container:fullscreen.controls-bar-hidden .video-controls-bottom {
  display: flex !important;
  opacity: 1 !important;
  pointer-events: auto !important;
  transform: translateY(0) !important;
}

/* Keep the bar identical to the inline player in fullscreen — only the
   centre play overlay scales up. */
.video-container:fullscreen .video-controls-bottom {
  margin: 0 auto 20px;
}

.video-container:fullscreen .video-play-center {
  width: 80px;
  height: 80px;
}

.video-container:fullscreen .video-play-center .icon {
  --icon-size: 36px;
}

.video-container.is-paused {
  cursor: pointer;
}

.video-container.is-paused {
  cursor: pointer;
}

.video-play-center {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) scale(0.8);
  width: 64px;
  height: 64px;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.5);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 255, 255, 0.15);
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
  cursor: pointer;
  z-index: 5;
  pointer-events: auto;
  /* Теперь кнопка ловит ховер, а клики пробросим в JS или они сами всплывут */
}

.video-container.is-paused .video-play-center {
  opacity: 1;
  transform: translate(-50%, -50%) scale(1);
}

.video-container.is-initial .video-controls-bottom {
  opacity: 0 !important;
  pointer-events: none !important;
  transform: translateY(20px) !important;
}

.video-play-center:hover {
  background: rgba(0, 0, 0, 0.7);
  transform: translate(-50%, -50%) scale(1.1);
}

.video-play-center .icon {
  --icon-size: 28px;
  background-color: white;
  margin-left: 2px;
  /* Визуальная компенсация для треугольника play */
}

.video-container:not(.is-paused) .video-play-center .icon {
  margin-left: 0;
  /* Для паузы отступ не нужен */
}

/* Floating-island control bar — timeline as its own full-width row on top,
   then the button row. Identical layout inline and in fullscreen. */
.video-controls-bottom {
  display: flex;
  flex-direction: column;
  gap: 8px;
  background: rgba(20, 20, 20, 0.85);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 255, 255, 0.1);
  padding: 9px 12px;
  border-radius: 16px;
  width: 100%;
  box-sizing: border-box;
  margin-bottom: 4px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
  transform: translateY(10px);
  transition: transform 0.3s ease;
}

.video-controls-row {
  display: flex;
  align-items: center;
  gap: 10px;
}

/* Left cluster: play · volume · timecode. The shared .fs-toggle margin-left:auto
   (further down) pushes fullscreen to the right edge. */

@container (max-width: 420px) {
  .video-controls-bottom {
    gap: 6px;
    padding: 8px 10px;
    border-radius: 14px;
  }

  .video-control-btn {
    width: 28px;
    height: 28px;
  }

  .video-timecode {
    font-size: 10px;
    min-width: 0;
  }

  .video-play-center {
    width: 48px;
    height: 48px;
  }

  .video-play-center .icon {
    --icon-size: 20px;
  }
}

@container (max-width: 320px) {
  .video-timecode {
    display: none;
  }
}

.video-container.controls-active .video-controls-bottom {
  transform: translateY(0);
}

.video-control-btn {
  width: 32px;
  height: 32px;
  border-radius: 8px;
  background: transparent;
  border: none;
  color: rgba(255, 255, 255, 0.9);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: all 0.2s ease;
  flex-shrink: 0;
}

.video-control-btn:hover {
  background: rgba(255, 255, 255, 0.15);
  color: #fff;
}

.video-control-btn .icon {
  --icon-size: 18px;
  background-color: currentColor;
}

/* Timeline — full-width scrubber on its own row. The filled portion is a
   gradient painted from JS, so the native tracks stay transparent and the
   fill shows identically in WebKit and Firefox. */
.video-timeline {
  width: 100%;
  height: 5px;
  -webkit-appearance: none;
  appearance: none;
  background: rgba(255, 255, 255, 0.25);
  border-radius: 3px;
  cursor: pointer;
  outline: none;
  position: relative;
}

.video-timeline::-webkit-slider-runnable-track {
  height: 5px;
  background: transparent;
  border-radius: 3px;
}

.video-timeline::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 13px;
  height: 13px;
  background: #fff;
  border-radius: 50%;
  cursor: pointer;
  box-shadow: 0 0 6px rgba(0, 0, 0, 0.5);
  margin-top: -4px;
  border: none;
  transition: transform 0.15s ease;
}

.video-timeline:hover::-webkit-slider-thumb,
.video-timeline:active::-webkit-slider-thumb {
  transform: scale(1.15);
}

.video-timeline::-moz-range-track {
  height: 5px;
  background: transparent;
  border-radius: 3px;
}

.video-timeline::-moz-range-thumb {
  width: 13px;
  height: 13px;
  background: #fff;
  border: none;
  border-radius: 50%;
  cursor: pointer;
  box-shadow: 0 0 6px rgba(0, 0, 0, 0.5);
}

/* Таймкод */
.video-timecode {
  font-size: 11px;
  font-weight: 500;
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
  color: rgba(255, 255, 255, 0.9);
  white-space: nowrap;
  flex-shrink: 0;
  min-width: 80px;
  text-align: center;
}

/* Подсказка времени */
.video-seek-tooltip {
  position: absolute;
  bottom: 60px; /* fallback — JS positions it just above the timeline */
  transform: translateX(-50%);
  font-variant-numeric: tabular-nums;
  background: rgba(20, 20, 20, 0.9);
  backdrop-filter: blur(8px);
  color: white;
  padding: 4px 8px;
  border-radius: 6px;
  font-size: 11px;
  font-weight: 500;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.2s ease;
  z-index: 100;
  border: 1px solid rgba(255, 255, 255, 0.1);
  white-space: nowrap;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
}

/* Для звонков */
.video-container .fs-toggle {
  margin-left: auto;
}

.video-call-actions {
  display: flex;
  gap: 8px;
  margin-right: auto;
}

/* Volume — speaker button + a horizontal slider that expands to its right in
   the bar on hover (YouTube-style). Wheel over this control adjusts volume. */
.video-volume {
  display: flex;
  align-items: center;
  flex-shrink: 0;
}

.video-volume-range {
  width: 0;
  height: 4px;
  -webkit-appearance: none;
  appearance: none;
  background: rgba(255, 255, 255, 0.25);
  border-radius: 2px;
  outline: none;
  cursor: pointer;
  opacity: 0;
  margin: 0;
  transition:
    width 0.2s ease,
    opacity 0.2s ease,
    margin 0.2s ease;
}

.video-volume:hover .video-volume-range,
.video-volume:focus-within .video-volume-range {
  width: 70px;
  opacity: 1;
  margin-left: 6px;
}

.video-volume-range::-webkit-slider-runnable-track {
  height: 4px;
  background: transparent;
  border-radius: 2px;
}

.video-volume-range::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 12px;
  height: 12px;
  background: #fff;
  border-radius: 50%;
  margin-top: -4px;
  border: none;
  cursor: pointer;
}

.video-volume-range::-moz-range-track {
  height: 4px;
  background: transparent;
  border-radius: 2px;
}

.video-volume-range::-moz-range-thumb {
  width: 12px;
  height: 12px;
  background: #fff;
  border: none;
  border-radius: 50%;
  cursor: pointer;
}

/* Скрываем дефолтный аватар, если видео активно */
.call-participant.has-video .call-avatar {
  opacity: 0;
  pointer-events: none;
}

/* === calls/responsive.css === */
@media (max-width: 720px) {
  .call-card {
    width: 100%;
    height: 100%;
    border-radius: 0;
  }

  .call-grid {
    grid-template-columns: 1fr;
  }

  .call-grid.is-multi {
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  }

  .call-grid.is-multi .call-participant {
    min-height: 140px;
  }
}

/* === calls/chat-tiles.css === */
/* Two call-presence surfaces inside a chat-panel:

     - chat-call-tiles  — compact strip directly under the chat header
                          (the collapsed call view)
     - call-modal       — inline region above messages with the full
                          participant grid + controls (the expanded view)

   `.chat-panel.call-collapsed` picks the strip; otherwise the inline region
   shows. The user toggles between them from inside the call. Narrow viewports
   force the strip regardless. Visibility is driven by JS toggling [hidden] on
   each element; the rules below enforce mutual exclusion by the view class. */

.chat-call-tiles {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-4);
  border-bottom: 1px solid var(--stroke);
  background: color-mix(in srgb, var(--accent) 5%, var(--panel));
}

.chat-call-tiles-avatars {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  flex-wrap: wrap;
  min-width: 0;
  flex-shrink: 0;
}

/* Type + elapsed label ("Аудио · 0:42") fills the gap between avatars and
   controls, pushing the controls to the right edge. */
.chat-call-tiles-label {
  flex: 1 1 auto;
  min-width: 0;
  font-size: 13px;
  font-weight: 500;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.chat-call-tiles-avatar {
  position: relative;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: linear-gradient(
    145deg,
    color-mix(in srgb, var(--accent) 40%, transparent),
    color-mix(in srgb, var(--accent-2) 20%, transparent)
  );
  display: grid;
  place-items: center;
  font-weight: 600;
  font-size: 13px;
  color: var(--text);
  overflow: hidden;
  flex-shrink: 0;
  --speech-level: 0;
  transition: box-shadow 0.12s linear;
}

.chat-call-tiles-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.chat-call-tiles-avatar.is-self {
  outline: 2px solid color-mix(in srgb, var(--accent) 70%, transparent);
  outline-offset: 1px;
}

.chat-call-tiles-avatar.is-speaking {
  box-shadow:
    0 0 0 calc(2px + 3px * var(--speech-level, 0))
      color-mix(in srgb, var(--accent) calc(55% + 45% * var(--speech-level, 0)), transparent),
    0 0 calc(8px + 14px * var(--speech-level, 0))
      color-mix(in srgb, var(--accent) calc(25% + 30% * var(--speech-level, 0)), transparent);
}

.chat-call-tiles-avatar-more {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--text) 10%, transparent);
  display: grid;
  place-items: center;
  font-size: 12px;
  font-weight: 600;
  color: var(--muted);
  flex-shrink: 0;
}

.chat-call-tiles-controls {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  flex-shrink: 0;
}

.chat-call-tiles-control {
  width: 36px;
  height: 36px;
  border-radius: var(--radius-md);
  border: 1px solid transparent;
  background: transparent;
  color: var(--text);
  cursor: pointer;
  display: grid;
  place-items: center;
  flex-shrink: 0;
  transition:
    background-color var(--anim-fast) var(--ease-out),
    color var(--anim-fast) var(--ease-out),
    transform 80ms var(--ease-out);
}

.chat-call-tiles-control .icon {
  --icon-size: 18px;
}

.chat-call-tiles-control:hover {
  background: color-mix(in srgb, var(--text) 10%, transparent);
}

.chat-call-tiles-control:active {
  transform: scale(0.92);
}

.chat-call-tiles-control.is-active {
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 14%, transparent);
}

.chat-call-tiles-control.is-muted,
.chat-call-tiles-control.is-deafened {
  color: var(--danger);
}

.chat-call-tiles-control.is-muted:hover,
.chat-call-tiles-control.is-deafened:hover {
  background: color-mix(in srgb, var(--danger) 12%, transparent);
}

.chat-call-tiles-control.danger {
  color: var(--danger);
}

.chat-call-tiles-control.danger:hover {
  background: color-mix(in srgb, var(--danger) 18%, transparent);
}

@media (max-width: 720px) {
  .chat-call-tiles {
    flex-wrap: wrap;
    padding: var(--space-2) var(--space-3);
    gap: var(--space-2);
  }
}

/* === Call view switch (expanded inline region ⇄ collapsed strip) === */

/* Expanded (default): the inline call region is a banner above messages and
   the compact strip is hidden. Sizes up when media (camera / screen-share) is
   present so the demo is watchable; stays smaller for voice-only so messages
   keep their share. */
.chat-panel:not(.call-collapsed) > .chat-call-tiles {
  display: none;
}

.chat-panel.has-visible-call:not(.call-collapsed)
  > #call-modal:not([hidden]):not(.is-maximized) {
  flex: 0 0 clamp(180px, 32vh, 380px);
  max-height: 52vh;
  min-height: 180px;
}

.chat-panel.has-visible-call.has-call-media:not(.call-collapsed)
  > #call-modal:not([hidden]):not(.is-maximized) {
  flex: 0 0 clamp(240px, 42vh, 480px);
  max-height: 60vh;
  min-height: 240px;
}

/* Collapsed: the inline region drops out and the compact strip under the chat
   header carries the call. */
.chat-panel.call-collapsed > #call-modal:not(.is-maximized) {
  display: none;
}

.chat-panel.call-collapsed.has-visible-call > .chat-call-tiles {
  display: flex;
}

/* Narrow viewports: vertical space is precious, so force the collapsed strip
   and hide the inline region regardless of the saved view. The maximize
   button still breaks out into full-viewport. */
@media (max-width: 720px) {
  .chat-panel.has-visible-call > .chat-call-tiles {
    display: flex;
  }
  .chat-panel > #call-modal:not(.is-maximized) {
    display: none;
  }
}

/* === side_panel.css === */
/* Side panel — docks the profile / group card as a real 4th grid lane on the
   right (desktop/Tauri): the chat shrinks but stays visible and interactive,
   no dimming backdrop. Mobile (<=900px): full-screen overlay. Reuses the
   existing .modal markup + .hidden lifecycle; only layout/positioning change.
   The grid lane is toggled by .app-shell.side-panel-open (set in profile/modal.js). */

/* ============================================================
   Desktop — grid lane. The 4th column only exists while open.
   ============================================================ */
@media (min-width: 901px) {
  /* The 4th lane is always present (collapsed to 0 while closed) and its width
     is driven by --side-panel-lane. Animating a track's *width* glides; toggling
     the track *count* (3↔4) can only snap — which is why open/close used to jump.
     Both side-panel modals are [hidden] when closed, so nothing flows into the
     empty lane. */
  .app-shell {
    --side-panel-lane: 0px;
    grid-template-columns: var(--sidebar-width, 300px) 18px minmax(0, 1fr) var(
        --side-panel-lane
      );
    transition: grid-template-columns var(--anim-med) var(--ease-in-out);
  }

  .app-shell.side-panel-open {
    --side-panel-lane: var(--side-panel-width, 400px);
  }

  /* While the sidebar resizer is dragged, --sidebar-width changes every frame;
     the grid transition would lag behind the cursor, so disable it (is-resizing
     is toggled in ui/resizer.js). */
  .app-shell.is-resizing {
    transition: none;
  }

  /* Strip the fixed full-viewport overlay behaviour: become a grid item.
     Pin to the 4th lane / row 1 so auto-placement can't misflow it. Keep the
     card placed during .is-closing so its slide-out plays before the lane
     collapses. */
  .app-shell.side-panel-open .modal.side-panel-modal,
  .app-shell .modal.side-panel-modal.is-closing {
    grid-column: 4;
    grid-row: 1;
  }

  .modal.side-panel-modal {
    position: relative;
    inset: auto;
    z-index: var(--z-base);
    display: block;
    min-width: 0;
    min-height: 0;
    overflow: hidden;
  }

  /* No backdrop in lane mode — the chat must stay visible/clickable. */
  .side-panel-modal .modal-backdrop {
    display: none;
  }

  /* Card fills the lane; only the left border separates it from the chat. */
  .side-panel-modal .modal-card {
    width: 100%;
    height: 100%;
    max-height: none;
    border-top: none;
    border-right: none;
    border-bottom: none;
    border-left: 1px solid var(--stroke);
    overflow-x: hidden;
    overflow-y: auto;
    gap: var(--space-3);
  }

  /* Beat the !important width/radius from profile.css for the lane layout. */
  .side-panel-modal .profile-card,
  .side-panel-modal .group-details-card {
    width: 100% !important;
    max-width: none !important;
    border-radius: 0 !important;
    padding: 0 !important;
  }

  /* Slide the card in from the right edge of its lane. */
  .side-panel-modal:not([hidden]) .modal-card {
    animation: sidePanelIn var(--anim-med) var(--ease-out);
  }

  /* Slide it back out before the lane collapses (driven by .is-closing in JS). */
  .side-panel-modal.is-closing .modal-card {
    animation: sidePanelOut var(--anim-fast) var(--ease-in-out) forwards;
  }
}

@keyframes sidePanelIn {
  from {
    transform: translateX(36px);
    opacity: 0;
  }
  to {
    transform: translateX(0);
    opacity: 1;
  }
}

@keyframes sidePanelOut {
  from {
    transform: translateX(0);
    opacity: 1;
  }
  to {
    transform: translateX(28px);
    opacity: 0;
  }
}

/* ============================================================
   Mobile (<=900px) — full-screen overlay (matches the layout's
   own single-column switch). No backdrop; the panel covers all.
   ============================================================ */
@media (max-width: 900px) {
  .modal.side-panel-modal {
    justify-content: stretch;
    align-items: stretch;
  }

  .side-panel-modal .modal-backdrop {
    display: none;
  }

  .side-panel-modal .modal-card,
  .side-panel-modal .profile-card,
  .side-panel-modal .group-details-card {
    width: 100vw !important;
    max-width: none !important;
    height: 100dvh;
    max-height: none !important;
    border: none;
    border-radius: 0 !important;
    overflow-x: hidden;
    overflow-y: auto;
    gap: var(--space-3);
    padding: 0 !important;
  }

  .side-panel-modal:not([hidden]) .modal-card {
    animation: sidePanelIn var(--anim-med) var(--ease-out);
  }

  .side-panel-modal.is-closing .modal-card {
    animation: sidePanelOut var(--anim-fast) var(--ease-in-out) forwards;
  }
}

/* Fade the incoming view in when toggling between the main panel and the full
   media gallery (added/removed by playViewSwitch in utils.js). */
.side-panel-modal .view-switch-enter {
  animation: viewSwitchIn var(--anim-med) var(--ease-out);
}

@keyframes viewSwitchIn {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* ============================================================
   Banner — blurred avatar cover with a gradient fallback.
   --banner-img + .has-image are set in profile/modal.js.
   ============================================================ */

.profile-banner {
  position: relative;
  flex: none;
  height: 200px;
  margin: 0 !important;
  overflow: hidden;
  background: var(--panel-2);
}

.profile-banner.has-image::before {
  content: "";
  position: absolute;
  inset: -25%;
  background-image: var(--banner-img);
  background-size: cover;
  background-position: center;
  filter: blur(28px) saturate(1.3) brightness(0.95);
  transform: scale(1.3);
}

/* Fade the banner into the panel surface so the avatar/name read cleanly. */
.profile-banner::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to bottom,
    transparent 30%,
    color-mix(in srgb, var(--panel) 94%, transparent) 100%
  );
}

/* Close button floats over the banner (top-right). */
.side-panel-modal .modal-header.no-border {
  position: absolute;
  top: var(--space-2);
  right: var(--space-2);
  left: var(--space-2);
  z-index: 5;
  margin: 0;
  padding: 0;
  pointer-events: none;
}

.side-panel-modal .modal-header.no-border .modal-close {
  pointer-events: auto;
  background: color-mix(in srgb, var(--bg) 55%, transparent);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}

/* Pull the avatar up to overlap the banner. */
.side-panel-modal .profile-hero,
.side-panel-modal .group-info-hero {
  margin-top: -60px;
  position: relative;
  z-index: 1;
}

/* ============================================================
   Staggered content reveal on open — the card slides in
   (sidePanelIn) while its key blocks rise in sequence, so the
   profile feels alive instead of popping in flat.
   ============================================================ */
.side-panel-modal:not([hidden]) .profile-avatar-row,
.side-panel-modal:not([hidden]) .profile-title-block,
.side-panel-modal:not([hidden]) .profile-actions-grid,
.side-panel-modal:not([hidden]) .profile-details-list {
  animation: spContentRise var(--anim-med) var(--ease-out) backwards;
}

.side-panel-modal:not([hidden]) .profile-avatar-row {
  animation-delay: 60ms;
}

.side-panel-modal:not([hidden]) .profile-title-block {
  animation-delay: 100ms;
}

.side-panel-modal:not([hidden]) .profile-actions-grid {
  animation-delay: 150ms;
}

.side-panel-modal:not([hidden]) .profile-details-list {
  animation-delay: 200ms;
}

@keyframes spContentRise {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* === peek_card.css === */
/* Floating peek mini-card (Discord-style quick profile). Anchored popover on
   desktop, bottom-sheet on mobile. Host logic lives in js/ui/peek_card.js. */

/* Avatars that open a peek card on click. */
.avatar-peekable {
  cursor: pointer;
}

.peek-overlay {
  position: fixed;
  inset: 0;
  z-index: var(--z-peek, 700);
}

.peek-overlay.is-sheet {
  display: flex;
  align-items: flex-end;
  background: color-mix(in srgb, var(--bg) 55%, #000 45%);
}

.peek-card {
  position: fixed;
  width: 300px;
  max-width: 92vw;
  background: var(--panel);
  border: 1px solid var(--stroke);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow);
  overflow: hidden;
  animation: peekIn var(--anim-fast, 180ms) var(--ease-out);
}

.peek-card-sheet {
  position: relative;
  width: 100%;
  max-width: 100%;
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  border-bottom: none;
  animation: peekSheetIn var(--anim-med, 260ms) var(--ease-out);
}

@keyframes peekIn {
  from {
    opacity: 0;
    transform: translateY(6px) scale(0.98);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

@keyframes peekSheetIn {
  from {
    transform: translateY(100%);
  }
  to {
    transform: translateY(0);
  }
}

/* Banner — blurred avatar cover; gradient fallback set in JS. */
.peek-banner {
  position: relative;
  height: 84px;
  overflow: hidden;
  background: var(--panel-2);
}

.peek-banner.has-image::before {
  content: "";
  position: absolute;
  inset: -25%;
  background-image: var(--banner-img);
  background-size: cover;
  background-position: center;
  filter: blur(22px) saturate(1.3) brightness(0.95);
  transform: scale(1.3);
}

.peek-banner::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to bottom,
    transparent 35%,
    color-mix(in srgb, var(--panel) 92%, transparent) 100%
  );
}

.peek-body {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--space-1);
  padding: 0 var(--space-4) var(--space-4);
}

.peek-avatar {
  width: 72px;
  height: 72px;
  border-radius: var(--radius-md);
  margin-top: -40px;
  border: 3px solid var(--panel);
  box-shadow: var(--shadow);
  font-size: 28px;
  position: relative;
  z-index: 1;
}

.peek-avatar.is-clickable {
  cursor: pointer;
  transition: transform 0.15s ease;
}

.peek-avatar.is-clickable:hover {
  transform: scale(1.04);
}

.peek-name {
  font-size: var(--text-lg);
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--text);
  margin-top: var(--space-2);
}

.peek-handle {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--muted);
  background: var(--panel-2);
  border: 1px solid var(--stroke);
  border-radius: var(--radius-sm);
  padding: 2px 7px;
}

.peek-status {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: var(--text-xs);
  color: var(--muted);
}

.peek-status-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--status-offline);
}

.peek-status[data-presence="good"] {
  color: var(--status-good);
}

.peek-status[data-presence="good"] .peek-status-dot {
  background: var(--status-good);
}

.peek-status[data-presence="warn"] {
  color: var(--status-warn);
}

.peek-status[data-presence="warn"] .peek-status-dot {
  background: var(--status-warn);
}

.peek-status[data-presence="bad"] {
  color: var(--status-bad);
}

.peek-status[data-presence="bad"] .peek-status-dot {
  background: var(--status-bad);
}

/* Custom status (emoji + text) — pill under the name. */
.peek-custom-status {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  max-width: 100%;
  margin-top: var(--space-2);
  padding: 6px 12px;
  border: 1px solid var(--stroke);
  border-radius: 999px;
  background: var(--panel-2);
}

.peek-custom-emoji {
  flex: none;
  font-size: 15px;
  line-height: 1;
}

.peek-custom-text {
  font-size: var(--text-sm);
  color: var(--text);
  overflow-wrap: anywhere;
}

.peek-bio {
  font-size: var(--text-sm);
  line-height: 1.45;
  color: var(--text);
  margin-top: var(--space-2);
  overflow-wrap: anywhere;
  word-break: break-word;
}

.peek-meta {
  font-size: var(--text-xs);
  color: var(--muted);
  margin-top: var(--space-2);
}

.peek-actions {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  width: 100%;
  margin-top: var(--space-3);
}

.peek-action {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: 38px;
  padding: 8px 14px;
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  font-weight: 600;
  cursor: pointer;
  border: 1px solid transparent;
}

.peek-action-ghost {
  background: var(--panel-2);
  border-color: var(--stroke);
  color: var(--text);
}

.peek-action-ghost:hover {
  background: color-mix(in srgb, var(--panel-2) 60%, var(--accent) 12%);
  border-color: color-mix(in srgb, var(--stroke) 60%, var(--accent) 30%);
}

.peek-action .icon {
  --icon-size: 15px;
}

.peek-action-primary {
  background: var(--accent);
  border-color: transparent;
  color: #fff;
}

.peek-action-primary:hover {
  background: color-mix(in srgb, var(--accent) 88%, #000);
}

/* Chat / Call / Video sit in one row: "Чат" stretches, the two call buttons
   stay square icon-only. */
.peek-action-row {
  display: flex;
  gap: var(--space-2);
  width: 100%;
}

.peek-action-row .peek-action {
  flex: 1;
}

.peek-action-icon {
  flex: 0 0 auto;
  width: 40px;
  padding-left: 0;
  padding-right: 0;
}

@media (max-width: 720px) {
  .peek-banner {
    height: 96px;
  }
  .peek-body {
    padding-bottom: max(var(--space-5), env(safe-area-inset-bottom));
  }
}
