/*
 * ============================================================
 * style_chat.css — Chat Container, Message List, and Input Bar
 * ============================================================
 *
 * STATUS: UPGRADED — Adaptive Liquid Glass Architecture (2026)
 * 
 * UPGRADE APPLIED:
 *   WHAT: Complete re-architecture of message bubbles and interactions.
 *         - Implemented "Adaptive Layered Glass" using oklch colors.
 *         - Added multi-layered backdrop filters (32px blur) for depth.
 *         - Enhanced text legibility via "Adaptive Shielding" (text-shadow).
 *         - Fixed container scrolling and modern scrollbar aesthetics.
 *         - Added premium interaction UI (Material Symbols context menu).
 * 
 *   WHY:  Previous glassmorphism was failing legibility against bright
 *         backgrounds/videos. Scrolling was unreliable, and interaction
 *         was limited.
 * 
 *   DESIGN PHILOSOPHY: 
 *         Maximum transparency combined with high-contrast substrate
 *         layering ensures the UI feels "alive" on top of media content
 *         while remaining 100% accessible and readable.
 * ============================================================
 */

:root {
  --chat-bg-blur: 0px;
  --chat-input-blur: 30px;

  --chat-bg-image-desktop: linear-gradient(to right,
      rgba(0, 0, 0, 0.6),
      rgba(0, 0, 0, 0.3),
      rgba(0, 0, 0, 0));
  --chat-input-bg-color: rgba(50, 50, 50, 0.9);

  --chat-font-size: 16px;
  --chat-font-weight: bold;

  --chat-input-icons-inflate: 120%;
  --message-input-inflate: 102%;
}

/*
 * Chat shell — position:fixed so it tracks the visual viewport on mobile,
 * flex column so the composer stays pinned and the list scrolls independently.
 * The viewport meta `interactive-widget=resizes-content` resizes the layout
 * viewport on Chromium Android, and keyboard_insets.js surfaces iOS keyboard
 * height via --kb. Combined with `max(env(keyboard-inset-height,0px), var(--kb,0px))`
 * below, the composer is never hidden behind the virtual keyboard.
 */
.chat-container {
  position: fixed;
  border-radius: var(--corner-radius);
  z-index: 500;
  display: flex;
  flex-direction: column;
  min-height: 0;           /* allow flex child (chat-list) to shrink + scroll */
  overflow: hidden;
}

.gradient-mask {
  z-index: 400;
  position: fixed;         /* matches .chat-container positioning base */
  pointer-events: none;
  border-radius: var(--corner-radius);
}

/* Message list — owns the flex-grow space; its own scroll, never the body's.
 *
 * Scroll note: `justify-content: flex-end` + `overflow-y: auto` is a classic
 * broken combo — when content overflows the container, older items get
 * clipped off the top and become unreachable via scroll in several browsers
 * (notably desktop Chromium at certain viewport heights). The fix is to keep
 * `justify-content` at its default (flex-start) and push the first child
 * downward with `margin-top: auto`: when content is short, the spacer
 * collapses to fill the available space (same visual as flex-end); when
 * content overflows, `margin-top: auto` resolves to 0 and scroll works
 * normally in every engine.
 */
.chat-list {
  flex: 1 1 auto;
  min-height: 0;
  width: 100%;
  background-color: var(--transparent-bg);
  border-radius: var(--corner-radius);

  display: flex;
  flex-direction: column;
  align-items: stretch;

  overflow-y: auto;
  overflow-x: hidden;
  overscroll-behavior: contain;
  /* Keep last message above composer when keyboard opens */
  scroll-padding-block-end: 12px;

  padding: 10px 8px;
  gap: 2px;
  scroll-behavior: smooth;

  /* Modern thin scrollbar */
  scrollbar-width: thin;
  scrollbar-color: rgba(0, 255, 255, 0.2) transparent;
}
.chat-list > *:first-child { margin-top: auto; }

.chat-list::-webkit-scrollbar {
  width: 6px;
  display: block;
}

.chat-list::-webkit-scrollbar-track {
  background: transparent;
}

.chat-list::-webkit-scrollbar-thumb {
  background: oklch(0.7 0.2 200 / 0.15);
  border-radius: 10px;
  border: 1.5px solid oklch(1 0 0 / 0.05);
}

.chat-list::-webkit-scrollbar-thumb:hover {
  background: oklch(0.7 0.2 200 / 0.3);
}

/* ═══════════════════════════════════════════════════════════════════
 * Y LIQUID GLASS MESSAGE BUBBLES — Advanced Visual System
 *
 * KEY: No mask, no border-image, no clip-path on bubbles.
 * All overflow (quick reactions, emojis) remains fully visible.
 * Border glow via box-shadow + real border (works with border-radius).
 * ═══════════════════════════════════════════════════════════════════ */

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

@keyframes msg-self-glow {
  0%, 100% {
    box-shadow:
      0 2px 12px rgba(0,0,0,0.3),
      0 0 16px rgba(0,255,255,0.06),
      inset 0 1px 0 rgba(0,255,255,0.1);
  }
  50% {
    box-shadow:
      0 2px 12px rgba(0,0,0,0.3),
      0 0 24px rgba(0,255,255,0.12),
      inset 0 1px 0 rgba(0,255,255,0.15);
  }
}

/* ── Base Message Bubble — Adaptive Layered Glass ───────────────── */
.message-container {
  width: auto;
  min-width: 100px;
  max-width: 85%;
  height: fit-content;
  margin: 1px 10px;
  padding: 8px 12px;
  display: flex;
  flex-direction: row-reverse;
  align-items: flex-start;
  gap: 8px;
  text-align: right;
  position: relative;
  overflow: visible;

  /* Adaptive Liquid Glass (2026 Standard) */
  background:
    radial-gradient(circle at 0% 0%, oklch(1 0 0 / 0.08) 0%, transparent 50%),
    oklch(0.2 0.02 240 / 0.12);
  
  backdrop-filter: blur(28px) saturate(160%);
  -webkit-backdrop-filter: blur(28px) saturate(160%);

  border: 1px solid oklch(1 0 0 / 0.1);
  border-radius: 14px 14px 4px 14px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.25);

  animation: msg-enter 0.25s cubic-bezier(0.23, 1, 0.32, 1) both;
  transition: transform 0.2s cubic-bezier(0.34, 1.56, 0.64, 1);
  user-select: none;
  cursor: default;
}

/* Sender + Timestamp Row */
.msg-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 2px;
  width: 100%;
}

.msg-sender-name {
  font-size: 11px;
  font-weight: 800;
  color: oklch(0.7 0.2 200);
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

.msg-timestamp {
  font-size: 9px;
  color: oklch(1 0 0 / 0.4);
  font-variant-numeric: tabular-nums;
  font-weight: 500;
}

/* Message Content - 5 line limit */
.message-content {
  color: oklch(0.98 0.01 240);
  font-size: 13.5px;
  line-height: 1.4;
  padding: 0;
  word-wrap: break-word;
  white-space: pre-wrap;
  position: relative;
  z-index: 2;
  text-shadow: 0 1px 1px rgba(0, 0, 0, 0.15);

  display: -webkit-box;
  -webkit-line-clamp: 5;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.message-content.is-expanded {
  -webkit-line-clamp: unset;
  overflow: visible;
}

/* Inner gloss highlight layer */
.message-container::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: linear-gradient(
    145deg,
    oklch(1 0 0 / 0.08) 0%,
    transparent 40%,
    oklch(0.5 0.1 240 / 0.03) 100%
  );
  pointer-events: none;
  z-index: 0;
}

/* Hover elevation */
.message-container:hover {
  transform: translateY(-2px) scale(1.01);
  border-color: oklch(1 0 0 / 0.25);
  box-shadow:
    0 12px 32px -4px rgba(0, 0, 0, 0.4),
    0 0 0 1px oklch(0.6 0.2 250 / 0.05),
    inset 0 1px 2px oklch(1 0 0 / 0.15);
}

/* ── Self Messages — Cyan-tinted Glass ──────────────────────────── */
.message-self {
  flex-direction: row;
  text-align: left;
  align-self: flex-start;
  background:
    radial-gradient(circle at 100% 0%, oklch(0.9 0.1 190 / 0.12) 0%, transparent 50%),
    radial-gradient(circle at 0% 100%, oklch(0.7 0.2 200 / 0.06) 0%, transparent 50%),
    oklch(0.2 0.04 200 / 0.15);
  border-color: oklch(0.8 0.15 190 / 0.2);
  border-radius: 20px 20px 20px 4px;
  animation: msg-enter 0.35s cubic-bezier(0.23, 1, 0.32, 1) both, msg-self-glow 5s ease-in-out infinite;
}

.message-self::before {
  background: linear-gradient(
    145deg,
    oklch(0.9 0.1 190 / 0.1) 0%,
    transparent 45%
  );
}

.message-self:hover {
  border-color: oklch(0.8 0.2 190 / 0.4);
  box-shadow:
    0 12px 32px -4px rgba(0, 0, 0, 0.4),
    0 0 25px oklch(0.8 0.2 190 / 0.12),
    inset 0 1px 2px oklch(0.9 0.1 190 / 0.15);
}

/* Remote messages alignment */
.message-container:not(.message-self) {
  align-self: flex-end;
}

/* ── Legacy profile picture ─────────────────────────────────────── */
.profile-picture {
  width: 30px;
  height: 30px;
  background-image: url("./assets/did_eclipse.png");
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
  flex-shrink: 0;
}

/* ── Avatar — Frosted Glass Circle ──────────────────────────────── */
.msg-avatar {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  font-weight: 700;
  flex-shrink: 0;
  letter-spacing: 0.5px;
  position: relative;
  z-index: 1;
  transition: transform 0.2s ease;
  overflow: hidden;
}

.msg-avatar-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 50%;
  display: block;
}

.msg-avatar-self {
  background: linear-gradient(135deg, rgba(0,255,255,0.28), rgba(0,200,255,0.14));
  color: cyan;
  box-shadow: 0 0 8px rgba(0,255,255,0.15);
}

.msg-avatar-remote {
  background: linear-gradient(135deg, rgba(255,255,255,0.14), rgba(200,210,255,0.07));
  color: rgba(255,255,255,0.9);
}

.message-container:hover .msg-avatar {
  transform: scale(1.05);
}

/* ── Sender Name ────────────────────────────────────────────────── */
.msg-sender-name {
  font-size: 10px;
  color: rgba(255,255,255,0.4);
  margin-bottom: 2px;
  font-weight: 600;
  letter-spacing: 0.3px;
  position: relative;
  z-index: 1;
}

/* ── Mobile responsive — smaller bubbles on small screens ───────── */
@media (max-width: 600px) {
  .message-container {
    min-width: 80px;
    max-width: 90%;
    margin: 6px 6px;
    padding: 8px 10px;
    gap: 8px;
    border-radius: 14px 14px 3px 14px;
  }
  .message-self {
    border-radius: 14px 14px 14px 3px;
  }
  .msg-avatar {
    width: 26px;
    height: 26px;
    font-size: 10px;
  }
  .message-content {
    font-size: 13px;
    line-height: 1.4;
  }
  .msg-sender-name {
    font-size: 9px;
  }
}

/* Extra-small phones */
@media (max-width: 380px) {
  .message-container {
    min-width: 72px;
    max-width: 92%;
    padding: 7px 8px;
    gap: 6px;
  }
  .msg-avatar {
    width: 24px;
    height: 24px;
    font-size: 9px;
  }
  .message-content {
    font-size: 12px;
  }
}

/* ── Body Column ────────────────────────────────────────────────── */
.msg-body {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-width: 0;
  position: relative;
  z-index: 1;
}

/* ── Message Text — High Legibility ────────────────────────────── */
.message-content {
  color: oklch(0.98 0.01 240);
  font-size: 14.5px;
  line-height: 1.55;
  padding: 0;
  word-wrap: break-word;
  white-space: pre-wrap;
  position: relative;
  z-index: 2;
  /* Adaptive text shielding for bright backgrounds */
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
}

.msg-expand-btn {
  background: oklch(1 0 0 / 0.1);
  border: 1px solid oklch(1 0 0 / 0.1);
  border-radius: 4px;
  color: oklch(0.7 0.2 200);
  font-size: 11px;
  font-weight: bold;
  padding: 2px 6px;
  margin-left: 4px;
  cursor: pointer;
  backdrop-filter: blur(4px);
  transition: all 0.2s ease;
}

.msg-expand-btn:hover {
  background: oklch(1 0 0 / 0.2);
  color: oklch(0.8 0.2 200);
  transform: scale(1.05);
}

.message-self .message-content {
  color: oklch(0.98 0.02 200);
}

/* ── Context Menu — Liquid Glass Panel ──────────────────────────── */
.msg-context-menu {
  position: fixed;
  z-index: 10000;
  background:
    radial-gradient(circle at 0% 0%, oklch(1 0 0 / 0.05) 0%, transparent 50%),
    oklch(0.15 0.02 240 / 0.85);
  backdrop-filter: blur(32px) saturate(1.8) contrast(1.1);
  -webkit-backdrop-filter: blur(32px) saturate(1.8) contrast(1.1);
  border: 1px solid oklch(1 0 0 / 0.12);
  border-radius: 18px;
  padding: 8px;
  min-width: 190px;
  box-shadow:
    0 20px 60px -10px rgba(0, 0, 0, 0.6),
    0 0 0 1px oklch(1 0 0 / 0.05),
    inset 0 1px 1px oklch(1 0 0 / 0.1);
  display: none;
  animation: msg-menu-in 0.25s cubic-bezier(0.17, 0.89, 0.32, 1.28);
}

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

.msg-context-menu .ctx-item {
  padding: 12px 16px;
  color: oklch(0.95 0.01 240);
  font-size: 13.5px;
  font-weight: 500;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  transition: 
    background 0.2s ease,
    transform 0.15s cubic-bezier(0.34, 1.56, 0.64, 1);
  margin: 2px 0;
  border-radius: 12px;
}

.msg-context-menu .ctx-item:hover {
  background: oklch(1 0 0 / 0.08);
  transform: scale(1.02) translateX(4px);
  color: oklch(1 0 0 / 1);
}

.msg-context-menu .ctx-item:active {
  transform: scale(0.96);
}

.msg-context-menu .ctx-item .ctx-icon {
  font-size: 18px;
  opacity: 0.8;
}

.msg-context-menu .ctx-sep {
  height: 1px;
  background: linear-gradient(90deg, transparent, oklch(1 0 0 / 0.1), transparent);
  margin: 6px 12px;
}

.msg-context-menu .ctx-item.ctx-danger {
  color: oklch(0.65 0.2 20);
}

.msg-context-menu .ctx-item.ctx-danger:hover {
  background: oklch(0.65 0.2 20 / 0.12);
}

/* ── Reply Quote — Glass Inset ──────────────────────────────────── */
.msg-reply-quote {
  padding: 10px 14px;
  margin-bottom: 10px;
  border-left: 3px solid oklch(0.7 0.2 200 / 0.6);
  background: oklch(1 0 0 / 0.04);
  backdrop-filter: blur(12px);
  border-radius: 10px;
  font-size: 12.5px;
  line-height: 1.4;
  color: oklch(0.9 0.02 240 / 0.7);
  max-height: 60px;
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  cursor: pointer;
  transition: background 0.2s ease, transform 0.15s ease;
  border: 1px solid oklch(1 0 0 / 0.05);
  border-left-width: 3px;
}

.msg-reply-quote:hover {
  background: oklch(1 0 0 / 0.08);
  transform: translateX(2px);
  color: oklch(1 0 0 / 0.9);
}

/* ── Reply Preview Bar ─────────────────────────────────────────── */
.reply-preview {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 16px;
  margin: 4px 8px;
  background: oklch(0.2 0.02 240 / 0.4);
  backdrop-filter: blur(20px);
  border-left: 3px solid oklch(0.7 0.2 200);
  border-radius: 12px;
  font-size: 13px;
  color: oklch(0.9 0.02 240 / 0.8);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
  animation: msg-menu-in 0.25s ease;
}

.reply-preview-text {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.reply-preview-close {
  background: none;
  border: none;
  color: rgba(255,255,255,0.4);
  font-size: 16px;
  cursor: pointer;
  padding: 0 4px;
  transition: color 0.15s;
}

.reply-preview-close:hover {
  color: rgba(255,255,255,0.8);
}

/* ── Typing Indicator — Animated Glass Pill ─────────────────────── */
.typing-indicator {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 14px;
  font-size: 11px;
  color: rgba(255,255,255,0.35);
  letter-spacing: 0.2px;
}

.typing-dots {
  display: flex;
  gap: 3px;
}

.typing-dots span {
  width: 5px;
  height: 5px;
  background: rgba(0,255,255,0.6);
  border-radius: 50%;
  animation: typing-bounce 1.2s ease-in-out infinite;
  box-shadow: 0 0 4px rgba(0,255,255,0.3);
}

.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) scale(1); opacity: 0.4; }
  30% { transform: translateY(-5px) scale(1.2); opacity: 1; }
}

/* ── Emoji Picker — Glass Grid ──────────────────────────────────── */
.emoji-btn {
  background: none;
  border: none;
  font-size: 20px;
  cursor: pointer;
  padding: 0 6px;
  opacity: 0.55;
  transition: opacity 0.2s, transform 0.2s;
  flex-shrink: 0;
  line-height: 1;
}

.emoji-btn:hover {
  opacity: 1;
  transform: scale(1.1);
}

.emoji-picker {
  max-height: 200px;
  overflow-y: auto;
  padding: 10px;
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  gap: 2px;
  background:
    linear-gradient(160deg, rgba(18,20,24,0.94), rgba(25,28,35,0.9));
  backdrop-filter: blur(24px) saturate(1.3);
  -webkit-backdrop-filter: blur(24px) saturate(1.3);
  border: 1px solid rgba(255,255,255,0.1);
  border-radius: 14px;
  margin: 0 4px 4px;
  box-shadow:
    0 -12px 32px rgba(0,0,0,0.4),
    inset 0 1px 0 rgba(255,255,255,0.06);
  animation: msg-menu-in 0.2s ease;
}

.emoji-picker button {
  background: none;
  border: none;
  font-size: 22px;
  cursor: pointer;
  padding: 5px;
  border-radius: 8px;
  transition: background 0.12s, transform 0.12s;
  line-height: 1;
}

.emoji-picker button:hover {
  background: rgba(255,255,255,0.1);
  transform: scale(1.15);
}

.emoji-picker button:active {
  transform: scale(0.9);
}

/* Thin glass scrollbar */
.emoji-picker::-webkit-scrollbar { width: 4px; }
.emoji-picker::-webkit-scrollbar-track { background: transparent; }
.emoji-picker::-webkit-scrollbar-thumb {
  background: rgba(0,255,255,0.15);
  border-radius: 2px;
}

/* ── Reduced motion ─────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .message-container {
    animation: none !important;
  }
  .message-self {
    animation: none !important;
  }
  .typing-dots span {
    animation: none !important;
    opacity: 0.6;
  }
}

/* ── Backdrop-filter fallback ───────────────────────────────────── */
@supports not (backdrop-filter: blur(1px)) {
  .message-container {
    background: rgba(25,28,35,0.88);
  }
  .message-self {
    background: rgba(0,40,50,0.85);
  }
  .msg-context-menu {
    background: rgba(18,20,24,0.95);
  }
  .msg-quick-react {
    background: rgba(22,25,30,0.95);
  }
}

/* ── Mobile responsive — context menu, emoji picker, quick react ── */
@media (max-width: 600px) {
  .msg-context-menu {
    min-width: 150px;
    border-radius: 12px;
  }
  .msg-context-menu .ctx-item {
    padding: 12px 14px;
    min-height: 44px;
  }
  .emoji-picker {
    grid-template-columns: repeat(7, 1fr);
    max-height: 150px;
    padding: 6px;
  }
  .emoji-picker button {
    font-size: 16px;
    padding: 4px;
    min-width: 32px;
    min-height: 32px;
  }
  .msg-reaction-badge {
    font-size: 11px;
    padding: 2px 4px;
    min-width: 24px;
    gap: 2px;
  }
  .msg-reaction-badge .reaction-count {
    font-size: 8px;
  }
  .reply-preview {
    padding: 6px 10px;
    font-size: 11px;
  }
}

/*file download link in the document*/
.file-link{
  width: 90%;
  height: 100%;
  color: #00e5ff;
  font-weight:bolder;
  text-decoration:underline;
  font-size:15px;
  padding:3px;
}

/* Composer — last flex child; pinned at the bottom.
   Keyboard-aware padding keeps the input above the iOS & Chromium keyboards. */
.chat-input-bar {
  flex: 0 0 auto;
  width: 100%;
  padding: 8px 10px;
  padding-bottom: calc(
    8px
    + max(env(safe-area-inset-bottom, 0px),
          env(keyboard-inset-height, 0px),
          var(--kb, 0px))
  );

  background-color: var(--transparent-bg);
  border-bottom-left-radius: var(--corner-radius);
  border-bottom-right-radius: var(--corner-radius);

  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 8px;
}

/*
 * The textarea. font-size is locked at 16px at EVERY breakpoint — anything
 * smaller triggers iOS Safari's focus-zoom. Apparent size is adjusted via
 * padding and container scaling elsewhere, never via font-size.
 *
 * field-sizing: content gives native autogrow in Chrome 123+, Safari 17.4+;
 * chat_events.js falls back to scrollHeight-driven height in Firefox.
 */
.message-input {
  flex: 1 1 auto;
  min-width: 0;
  width: auto;
  max-height: 30svh;
  padding: 10px 14px;

  outline-style: none;
  border-style: none;
  border-radius: 20px;

  font-size: 16px;             /* iOS auto-zoom threshold — do NOT lower */
  line-height: 1.35;
  color: white;
  background-color: var(--chat-input-bg-color);

  resize: none;
  overflow-y: auto;
  font-family: inherit;
  field-sizing: content;
}

.message-input:hover {
  border: var(--cyan-border);
}

.message-input:focus {
  border: 1px solid rgba(0, 255, 255, 0.5);
  box-shadow: 0 0 8px rgba(0, 255, 255, 0.1);
}

/*
 * Chat input bar buttons — send and attach.
 *
 * The PNG icon files are dark-coloured (designed for light backgrounds).
 * The chat container always sits on a dark or semi-transparent background,
 * so without a filter the icons are invisible when the page background is
 * black or very dark.
 *
 * filter: brightness(0) — collapses every pixel to pure black
 * filter: invert(1)     — flips black to white, giving a white silhouette
 *
 * The main control buttons in style_icons.css use SVG files and are
 * therefore unaffected by this rule.
 */
.send-text,
.send-file {
  width: 25px;
  height: 25px;

  background-color: transparent;
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;

  border: none;
  outline: none;

  /* Convert dark PNG icons to white so they remain visible on any dark background. */
  filter: brightness(0) invert(1);
  opacity: 0.75;
  transition: opacity 0.15s ease;
}

.send-text:hover,
.send-file:hover {
  opacity: 1;
}

.send-text {
  background-image: url("./assets/icons/png/send.png");
}

.send-file {
  background-image: url("./assets/icons/png/file_send.png");
}

/*inflate the icons on hover*/
.inflate:hover {
  transform: scale(var(--chat-input-icons-inflate));
}

/* Mobile touch-target tweaks ONLY — font-size stays at 16px (locked above)
   to avoid iOS Safari focus-zoom. Visual size of the input is controlled
   via padding and border-radius, never font-size. */
@media (max-width: 600px) {
  .send-text,
  .send-file {
    width: 32px;
    height: 32px;
    min-width: 40px;
    min-height: 40px;
    padding: 6px;
    flex-shrink: 0;
  }
  .emoji-btn {
    min-width: 40px;
    min-height: 40px;
    font-size: 20px;
    flex-shrink: 0;
  }
  .chat-input-bar {
    gap: 6px;
  }
  .message-input {
    padding: 9px 12px;
    border-radius: 16px;
  }
}

@media (max-width: 380px) {
  .send-text,
  .send-file {
    width: 28px;
    height: 28px;
    min-width: 36px;
    min-height: 36px;
    padding: 5px;
  }
  .emoji-btn {
    min-width: 36px;
    min-height: 36px;
    font-size: 18px;
  }
  .chat-input-bar {
    gap: 4px;
  }
  .message-input {
    padding: 8px 10px;
    border-radius: 14px;
  }
}

/* Desktop layout — chat sits on the left side. Uses svh so the shell is
   defined by the smallest viewport (scrollbar-agnostic) and won't clip. */
@media (min-width: 600px) {
  .chat-container {
    top: var(--layout-margin);
    left: var(--layout-margin);
    width: var(--chat-width-desktop);
    min-width: min(400px, calc(100vw - 2 * var(--layout-margin)));
  }

  .chat-container.standard {
    /* leaves strip height + margin below */
    height: calc(100svh - (16svh + 2 * var(--layout-margin) + 10px));
  }
  .chat-container.full {
    height: calc(100svh - 2 * var(--layout-margin));
  }

  .gradient-mask {
    top: var(--layout-margin);
    left: var(--layout-margin);
    width: var(--chat-width-desktop);
    min-width: min(400px, calc(100vw - 2 * var(--layout-margin)));
    background-image: var(--chat-bg-image-desktop);
  }
  .gradient-mask.standard {
    height: calc(100svh - (16svh + 2 * var(--layout-margin) + 10px));
  }
  /* typo-fixed: was `.gradient-mark.full` */
  .gradient-mask.full {
    height: calc(100svh - 2 * var(--layout-margin));
  }
}

/* Mobile layout — chat fills the viewport. Height shrinks automatically
   when keyboard appears (interactive-widget=resizes-content) or via --kb
   fallback for iOS. */
@media (max-width: 599px) {
  .chat-container {
    top: calc(var(--layout-margin) + env(safe-area-inset-top, 0px));
    left: var(--layout-margin);
    right: var(--layout-margin);
    width: auto;
    max-width: none;
  }

  .chat-container.standard {
    /* leaves the bottom strip visible underneath */
    bottom: calc(16svh + 2 * var(--layout-margin) + 6px);
  }
  .chat-container.full {
    bottom: var(--layout-margin);
  }

  .gradient-mask {
    top: calc(var(--layout-margin) + env(safe-area-inset-top, 0px));
    left: var(--layout-margin);
    right: var(--layout-margin);
    width: auto;
    background-image: var(--chat-bg-image-desktop);
  }
  .gradient-mask.standard {
    bottom: calc(16svh + 2 * var(--layout-margin) + 6px);
  }
  .gradient-mask.full {
    bottom: var(--layout-margin);
  }
}

/* ── FILE TRANSFER PROGRESS BAR ─────────────────────────────────────────────
 *
 * .ft-card           — outer container (same width/margin as .message-container)
 * .ft-header         — flex row: avatar + info + cancel button (gap: 8px)
 * .ft-icon           — DEAD CODE: replaced by .msg-avatar (initials avatar)
 * .ft-info           — column: sender name + filename + filesize
 * .ft-filename       — ellipsis-truncated filename
 * .ft-filesize       — muted size label
 * .ft-cancel-btn     — × dismiss button, pushed to right via margin-left:auto
 * .ft-bar-wrap       — grey track behind the fill
 * .ft-bar            — filled portion; width driven by JS
 * .ft-status         — "X KB / Y MB" byte-count label
 * .ft-preview        — image/video preview shown on completion
 * .ft-dl-btn         — download anchor shown on completion (flex row)
 * .ft-dl-icon        — ↓ down-arrow icon span inside .ft-dl-btn
 * .ft-dl-name        — filename + size text span inside .ft-dl-btn
 * .ft-done-icon      — small check icon shown for non-image receiver completion
 * .ft-sent-label     — "✓ Sent" text shown on sender completion
 *
 * ─────────────────────────────────────────────────────────────────────────── */

.ft-card {
  position: relative;
  width: 95%;
  margin: 4px auto;
  padding: 8px 10px;
  background-color: var(--transparent-bg);
  border-radius: var(--corner-radius);
  display: flex;
  flex-direction: column;
}

/*
 * BUG FIX — added gap: 8px to separate the sender avatar from the file info.
 *
 * The .msg-avatar element (35×35 circle) replaced the old .ft-icon placeholder.
 * Unlike .ft-icon which had margin-right: 8px, .msg-avatar has no margin, so
 * without gap the avatar was pressed directly against the .ft-info column.
 *
 * HOW TO REVERT:
 *   Remove the gap: 8px line.  The avatar will abut the info column with no
 *   spacing (cosmetic only — avatar remains visible).
 */
.ft-header {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 8px;
  margin-bottom: 6px;
}

.ft-icon {
  width: 28px;
  height: 28px;
  flex-shrink: 0;
  background-color: rgba(255, 255, 255, 0.15);
  border-radius: 4px;
  margin-right: 8px;
}

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

.ft-filename {
  color: white;
  font-size: 13px;
  font-weight: bold;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}

.ft-filesize {
  font-size: 11px;
  color: rgba(255, 255, 255, 0.5);
}

.ft-cancel-btn {
  margin-left: auto;
  flex-shrink: 0;
  background: transparent;
  border: none;
  color: rgba(255, 255, 255, 0.6);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  padding: 0 2px;
  outline: none;
}

/* Phase 6 mobile fix: enlarge touch target to 44px (Apple HIG / Material Design
 * minimum).  The previous 18-20px tap area was effectively untappable on
 * touch screens for the 70% mobile portrait user base. */
@media (max-width: 600px) {
  .ft-cancel-btn {
    min-width:  44px;
    min-height: 44px;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 12px;
  }
}

/* Phase 6 portrait guard: belt-and-suspenders protection against any
 * inherited min-width causing overflow on narrow portrait phones. */
@media (max-width: 600px) and (orientation: portrait) {
  .gradient-mask {
    min-width: 0;
    max-width: 100vw;
  }
}

.ft-cancel-btn:hover {
  color: white;
}

.ft-bar-wrap {
  width: 100%;
  height: 8px;
  background-color: rgba(255, 255, 255, 0.15);
  border-radius: 100px;
  overflow: hidden;
  margin-bottom: 4px;
}

.ft-bar {
  height: 100%;
  width: 0%;
  background-color: var(--cyan-color, #00bcd4);
  border-radius: 100px;
  transition: width 0.12s linear;
}

.ft-status {
  color: rgba(255, 255, 255, 0.65);
  font-size: 11px;
}

/*
 * Preview element shown on transfer completion for image/* and video/* files.
 *
 * Applies to both <img> and <video> elements (both use class="ft-preview").
 *   image/* → <img class="ft-preview">
 *   video/* → <video class="ft-preview" controls preload="metadata">
 *
 * object-fit:contain works correctly for both element types:
 *   - <img>   — scales the image proportionally within the box.
 *   - <video> — scales the video frame proportionally, letterboxes if needed.
 *
 * max-height:240px — slightly taller than the original 200px to give the
 * browser-native video controls room without overlapping the first frame.
 *
 * HOW TO REVERT:
 *   Change the comment back to "Image preview on completion (receiver, image MIME type)"
 *   and change max-height back to 200px.
 *   (The CSS rule itself is unchanged except max-height — both img and video
 *   have always been compatible with these properties.)
 */
.ft-preview {
  width: 100%;
  max-height: 240px;
  object-fit: contain;
  border-radius: 6px;
  margin-bottom: 6px;
  display: block;
}

/*
 * BUG FIX — download anchor changed from display:block to display:flex.
 *
 * The anchor now contains two child spans:
 *   <span class="ft-dl-icon">↓</span>
 *   <span class="ft-dl-name">filename (size)</span>
 *
 * display:flex with align-items:center and gap:6px renders the down-arrow as
 * a visually distinct icon to the left of the underlined filename text.
 * Previously the arrow was concatenated into the link text as '\u2193 filename'
 * via anchor.textContent, making it indistinguishable from the filename.
 * text-decoration:none on the anchor prevents double-underline; the underline
 * is applied only to .ft-dl-name so the icon glyph stays clean.
 *
 * HOW TO REVERT:
 *   1. Change display back to block and remove align-items and gap.
 *   2. Add back word-break: break-all to .ft-dl-btn.
 *   3. Delete the .ft-dl-icon and .ft-dl-name rules below.
 *   4. In chat_api.js finalize_file_progress_row(), replace the dlIcon/dlName
 *      span block with: anchor.textContent = '\u2193 ' + filename + ' (' +
 *      _format_bytes(totalBytes) + ')';
 */
.ft-dl-btn {
  display: flex;
  align-items: center;
  gap: 6px;
  color: #00e5ff;
  text-decoration: none;
  font-size: 14px;
  font-weight: bold;
  padding: 4px 0;
}

/* ↓ down-arrow icon span — flex-shrink:0 prevents it from collapsing */
.ft-dl-icon {
  flex-shrink: 0;
  font-size: 16px;
  line-height: 1;
}

/* Filename + size text span — underlined; wraps on narrow screens */
.ft-dl-name {
  flex: 1;
  min-width: 0;
  word-break: break-all;
  text-decoration: underline;
}

/* Small checkmark area for non-image receiver completion */
.ft-done-icon {
  width: 20px;
  height: 20px;
  margin-bottom: 4px;
}

/* "✓ Sent — filename (size)" shown on sender completion */
.ft-sent-label {
  color: rgba(255, 255, 255, 0.7);
  font-size: 13px;
  padding: 4px 0;
}

/* YouTube link card */
.yt-card {
  display: block;
  margin-top: 6px;
  border-radius: 6px;
  overflow: hidden;
  max-width: 240px;
}

.yt-card img {
  width: 100%;
  display: block;
}

/* ═══════════════════════════════════════════════════════════════════
 * Drag-and-drop file sharing — full-viewport glass overlay
 *
 * The overlay is created and controlled by file_events.js. It only
 * receives the `.visible` class while a file drag is active anywhere
 * on the window. `pointer-events` flips with the same class so the
 * backdrop doesn't intercept clicks when hidden.
 * ═══════════════════════════════════════════════════════════════════ */
#file-drop-overlay {
  position: fixed;
  inset: 0;
  z-index: 11000; /* above everything except the native browser chrome */
  display: flex;
  align-items: center;
  justify-content: center;
  background: radial-gradient(
    ellipse at center,
    rgba(0, 200, 220, 0.18) 0%,
    rgba(0, 0, 0, 0.72) 65%
  );
  /* BUG (2026-07-14): backdrop-filter used to live HERE, on the always-present element.
   *
   * A backdrop-filter blurs everything painted behind the element — and it does that
   * whether or not the element itself is visible. With opacity:0 the overlay was invisible
   * but its FILTER was not: it sat at z-index 11000 across the whole viewport, permanently
   * blurring the entire app. That is the "film of haze" over the attendee tiles. It was
   * over the video, the stage and the controls too; the tiles just made it obvious.
   *
   * The fix is to only create the filter when the overlay is actually shown. opacity:0 is
   * not enough — the element must not be a backdrop root at all. */
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.18s ease-out, visibility 0s linear 0.18s;
}
#file-drop-overlay.visible {
  /* The blur exists ONLY while a file is actually being dragged. */
  backdrop-filter: blur(14px) saturate(140%);
  -webkit-backdrop-filter: blur(14px) saturate(140%);
  visibility: visible;
  transition: opacity 0.18s ease-out, visibility 0s linear 0s;
  opacity: 1;
  pointer-events: auto;
}

.file-drop-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  padding: 36px 48px;
  border-radius: 22px;
  background: rgba(14, 16, 22, 0.58);
  border: 1.5px dashed rgba(0, 255, 255, 0.55);
  box-shadow:
    0 24px 80px rgba(0, 0, 0, 0.55),
    0 0 60px rgba(0, 255, 255, 0.18),
    inset 0 1px 0 rgba(255, 255, 255, 0.05);
  color: #fff;
  text-align: center;
  transform: scale(0.97);
  transition: transform 0.22s cubic-bezier(0.2, 0.8, 0.2, 1);
}
#file-drop-overlay.visible .file-drop-inner {
  transform: scale(1);
}

.file-drop-ring {
  width: 96px;
  height: 96px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: cyan;
  background: radial-gradient(
    circle at 30% 30%,
    rgba(0, 255, 255, 0.22),
    rgba(0, 255, 255, 0.04) 70%
  );
  border: 1px solid rgba(0, 255, 255, 0.35);
  box-shadow:
    0 0 24px rgba(0, 255, 255, 0.25),
    inset 0 0 18px rgba(0, 255, 255, 0.15);
  animation: file-drop-pulse 1.8s ease-in-out infinite;
}
@keyframes file-drop-pulse {
  0%, 100% {
    box-shadow:
      0 0 24px rgba(0, 255, 255, 0.25),
      inset 0 0 18px rgba(0, 255, 255, 0.15);
  }
  50% {
    box-shadow:
      0 0 44px rgba(0, 255, 255, 0.45),
      inset 0 0 26px rgba(0, 255, 255, 0.25);
  }
}

.file-drop-title {
  font-size: 18px;
  font-weight: 600;
  letter-spacing: 0.3px;
  text-shadow: 0 1px 8px rgba(0, 0, 0, 0.6);
}
.file-drop-hint {
  font-size: 12px;
  color: rgba(255, 255, 255, 0.65);
  letter-spacing: 0.2px;
}

/* Honour reduced-motion: skip the pulse, keep the static glow. */
@media (prefers-reduced-motion: reduce) {
  .file-drop-ring { animation: none; }
  #file-drop-overlay, .file-drop-inner { transition: none; }
}

/* ── R-P4: PRIVATE MESSAGES — the right-side pane ────────────────────────────
   The mirror of the room chat (left), visibly different: opens from the RIGHT and carries
   the conversation's accent colour (--ypm-h, hashed per attendee/group). Glass throughout. */
.ypm-pane {
  position: fixed;
  top: max(8px, env(safe-area-inset-top, 0px));
  right: 8px;
  bottom: max(8px, env(safe-area-inset-bottom, 0px));
  width: min(340px, calc(100vw - 16px));
  z-index: 940;
  display: none;
  flex-direction: column;
  border-radius: 18px;
  overflow: hidden;
  background: oklch(22% 0.03 calc(var(--ypm-h, 210) * 1deg) / 0.78);
  -webkit-backdrop-filter: blur(20px) saturate(1.5);
  backdrop-filter: blur(20px) saturate(1.5);
  border: 1px solid oklch(70% 0.1 calc(var(--ypm-h, 210) * 1deg) / 0.5);
  box-shadow: inset 0 1px 0 oklch(100% 0 0 / 0.25), 0 24px 60px -20px oklch(0% 0 0 / 0.75);
  color: #fff;
  transform: translateX(16px);
  opacity: 0;
  transition: transform 0.28s cubic-bezier(0.16,1,0.3,1), opacity 0.2s;
}
.ypm-pane.is-open { display: flex; transform: translateX(0); opacity: 1; }
@media (prefers-reduced-motion: reduce) { .ypm-pane { transition: none; } }

.ypm-tabs {
  display: flex; gap: 6px; padding: 8px 8px 0;
  overflow-x: auto; scrollbar-width: none; flex: 0 0 auto;
  touch-action: pan-x;
}
.ypm-tabs::-webkit-scrollbar { display: none; }
.ypm-tab {
  flex: 0 0 auto; max-width: 140px; min-height: 34px;
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 11px; border-radius: 999px; cursor: pointer;
  border: 1px solid oklch(75% 0.12 calc(var(--ypm-h, 210) * 1deg) / 0.55);
  background: oklch(40% 0.08 calc(var(--ypm-h, 210) * 1deg) / 0.4);
  color: #fff; font-size: 12px; font-weight: 650;
  white-space: nowrap;
}
.ypm-tab span:first-child { overflow: hidden; text-overflow: ellipsis; }
.ypm-tab.is-active {
  background: oklch(55% 0.13 calc(var(--ypm-h, 210) * 1deg) / 0.6);
  box-shadow: inset 0 1px 0 oklch(100% 0 0 / 0.35);
}
.ypm-unread {
  min-width: 17px; height: 17px; border-radius: 999px;
  display: inline-grid; place-items: center;
  background: oklch(65% 0.2 25); font-size: 10px; font-weight: 800;
}
.ypm-tabs.is-tab-dragging .ypm-tab { outline: 1px dashed oklch(100% 0 0 / 0.5); }

.ypm-head {
  display: flex; align-items: center; gap: 8px;
  padding: 10px 12px; flex: 0 0 auto;
  font-size: 14px; font-weight: 750;
  border-bottom: 1px solid oklch(100% 0 0 / 0.12);
}
.ypm-dot {
  width: 11px; height: 11px; border-radius: 50%; flex: 0 0 auto;
  background: oklch(65% 0.17 calc(var(--ypm-h, 210) * 1deg));
  box-shadow: 0 0 8px oklch(65% 0.17 calc(var(--ypm-h, 210) * 1deg) / 0.7);
}
.ypm-title { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ypm-x {
  width: 32px; height: 32px; border-radius: 50%; cursor: pointer;
  border: 1px solid oklch(100% 0 0 / 0.3); background: oklch(100% 0 0 / 0.12); color: #fff;
}

.ypm-body { flex: 1 1 auto; min-height: 0; display: flex; overflow: hidden; }
/* The reused room-chat list fills the body; each conversation owns its own instance. */
.ypm-body .chat-list, .ypm-list {
  flex: 1 1 auto; min-height: 0; width: 100%;
  overflow-y: auto; padding: 10px 10px 4px;
  display: flex; flex-direction: column; gap: 2px;
}
/* Dark-pane legibility for the reused message bubbles. */
.ypm-body .msg-sender-name { color: oklch(96% 0 0 / 0.9); }
.ypm-body .msg-timestamp   { color: oklch(96% 0 0 / 0.5); }
.ypm-body .message-content { color: #fff; }
.ypm-body .message-self .message-content { }

.ypm-row { display: flex; gap: 8px; padding: 10px; flex: 0 0 auto; }
.ypm-input {
  flex: 1 1 auto; min-width: 0; min-height: 42px; border-radius: 12px; padding: 0 12px;
  border: 1px solid oklch(100% 0 0 / 0.2); background: oklch(100% 0 0 / 0.1);
  color: #fff; font: inherit; font-size: 14px;
}
.ypm-input::placeholder { color: oklch(100% 0 0 / 0.5); }
.ypm-attach {
  min-width: 42px; min-height: 42px; border-radius: 12px; cursor: pointer; flex: 0 0 auto;
  border: 1px solid oklch(100% 0 0 / 0.2); background: oklch(100% 0 0 / 0.1); color: #fff;
  display: inline-grid; place-items: center;
}
.ypm-attach:hover { background: oklch(100% 0 0 / 0.18); }
.ypm-send {
  min-width: 44px; min-height: 42px; border-radius: 12px; cursor: pointer;
  border: 1px solid oklch(75% 0.12 calc(var(--ypm-h, 210) * 1deg) / 0.6);
  background: oklch(55% 0.13 calc(var(--ypm-h, 210) * 1deg) / 0.6);
  color: #fff; font-size: 15px;
}
