/* ===================================================================
   GrooVVee — Components
   Reusable UI component styles
   =================================================================== */

/* ── Ambient Background Orbs ────────────────────────────────────── */
/* Was the branded illustration (assets/bg.jpg, with its own colorful
   icons + wordmark) — plain neutral base for now, per product direction
   (no color beyond dark grey). Drifting orbs kept for subtle texture/
   motion, recolored to grey instead of blue/green/yellow. */
.ambient-bg {
  position: fixed;
  inset: 0;
  z-index: var(--z-below);
  overflow: hidden;
  pointer-events: none;
  background: var(--bg-base);
}

.orb {
  position: absolute;
  border-radius: 50%;
  filter: blur(80px);
  animation: orb-drift linear infinite;
}

.orb--1 {
  width: 600px;
  height: 600px;
  background: radial-gradient(circle, rgba(28, 28, 30, 0.07) 0%, transparent 70%);
  top: -200px;
  left: -150px;
  animation-duration: 25s;
}

.orb--2 {
  width: 500px;
  height: 500px;
  background: radial-gradient(circle, rgba(28, 28, 30, 0.05) 0%, transparent 70%);
  bottom: -100px;
  right: -100px;
  animation-duration: 32s;
  animation-direction: reverse;
}

.orb--3 {
  width: 400px;
  height: 400px;
  background: radial-gradient(circle, rgba(28, 28, 30, 0.05) 0%, transparent 70%);
  top: 40%;
  left: 60%;
  animation-duration: 20s;
  animation-delay: -10s;
}

@keyframes orb-drift {
  0%, 100% { transform: translate(0, 0) scale(1); }
  25%       { transform: translate(40px, -30px) scale(1.05); }
  50%       { transform: translate(-20px, 50px) scale(0.95); }
  75%       { transform: translate(-50px, -20px) scale(1.03); }
}

/* ── Splash Screen ──────────────────────────────────────────────────
   Shown immediately on load (plain HTML, no JS needed for first paint),
   removed by main.js once bootstrap finishes — see initSplashScreen(). */
.splash-screen {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-4);
  background: var(--bg-base);
  transition: opacity 300ms var(--ease-out), visibility 300ms;
}

.splash-screen__icon {
  border-radius: var(--radius-lg);
}

.splash-screen__wordmark {
  font-size: 1.75rem;
}

.splash-screen--hidden {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}

/* ── Loading Spinner ────────────────────────────────────────────── */
.page-loader {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 60vh;
}

.spinner {
  width: 36px;
  height: 36px;
  border: 3px solid var(--border-default);
  border-top-color: var(--primary-500);
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
}

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

/* ── Buttons ────────────────────────────────────────────────────── */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: 0.625rem var(--space-5);
  border-radius: var(--radius-md);
  font-size: 0.9375rem;
  font-weight: 600;
  line-height: 1;
  transition: all var(--transition-base);
  white-space: nowrap;
  cursor: pointer;
  border: 1px solid transparent;
  position: relative;
  overflow: hidden;
}

.btn svg {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
}

.btn::before {
  content: '';
  position: absolute;
  inset: 0;
  background: rgba(255, 255, 255, 0);
  transition: background var(--transition-fast);
}

.btn:hover::before {
  background: rgba(255, 255, 255, 0.06);
}

.btn:active { transform: scale(0.94); transition: transform 100ms var(--ease-spring); }

/* Primary — the vivid blue→green→yellow→red brand gradient, not solid blue,
   so every primary action reads as the most colorful, "tap me" element. */
.btn--primary {
  background: var(--gradient-mixed);
  background-size: 200% 200%;
  background-position: 0% 50%;
  color: #fff;
  border-color: transparent;
  box-shadow: var(--shadow-glow-sm);
  transition: background-position var(--transition-slow), transform var(--transition-fast), box-shadow var(--transition-fast);
}
.btn--primary:hover {
  background-position: 100% 50%;
  box-shadow: var(--shadow-glow-primary), var(--shadow-glow-accent);
  transform: translateY(-1px);
}
.btn--primary:active { transform: translateY(0) scale(0.98); }

/* Accent */
.btn--accent {
  background: var(--gradient-accent);
  color: var(--text-inverse);
  border-color: transparent;
}
.btn--accent:hover {
  box-shadow: var(--shadow-glow-accent);
  transform: translateY(-1px);
}

/* Secondary / Ghost */
.btn--secondary {
  background: var(--glass-bg);
  color: var(--text-primary);
  border-color: var(--glass-border);
  backdrop-filter: var(--glass-blur);
}
.btn--secondary:hover {
  background: var(--glass-bg-hover);
  border-color: var(--glass-border-hover);
}

/* Ghost */
.btn--ghost {
  background: transparent;
  color: var(--text-secondary);
  border-color: transparent;
}
.btn--ghost:hover {
  background: var(--glass-bg);
  color: var(--text-primary);
}

/* Danger */
.btn--danger {
  background: transparent;
  color: var(--error-500);
  border-color: rgba(239, 68, 68, 0.3);
}
.btn--danger:hover {
  background: rgba(239, 68, 68, 0.1);
  border-color: var(--error-500);
}

/* Sizes */
.btn--sm {
  padding: 0.4375rem var(--space-4);
  font-size: 0.8125rem;
  border-radius: var(--radius-sm);
}
.btn--lg {
  padding: 0.875rem var(--space-7);
  font-size: 1.0625rem;
  border-radius: var(--radius-lg);
}
.btn--xl {
  padding: 1rem var(--space-8);
  font-size: 1.125rem;
  border-radius: var(--radius-lg);
}
.btn--full { width: 100%; }

/* Disabled */
.btn:disabled, .btn[aria-disabled="true"] {
  opacity: 0.4;
  pointer-events: none;
}

/* Icon-only button */
.btn-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--text-secondary);
  transition: all var(--transition-fast);
  flex-shrink: 0;
}
.btn-icon svg {
  width: 20px;
  height: 20px;
}
/* Compact icon row for the default chat input bar (emoji/mic/photo/sticker/send all in one row alongside the
   text field) — five full-size 38px .btn-icon buttons left too little width for the field itself to be usable
   (measured as low as 94px on a real mobile chat panel). Smaller here, in this one context, rather than shrinking
   .btn-icon everywhere else it's used. */
.rci-icon-compact { width: 30px; height: 30px; }
.rci-icon-compact svg { width: 17px; height: 17px; }
.btn-icon:hover {
  background: var(--glass-bg-hover);
  color: var(--text-primary);
}
.btn-icon:active { transform: scale(0.93); }

/* ── Cards ──────────────────────────────────────────────────────── */
.card {
  background: var(--glass-bg);
  border: 1px solid var(--glass-border);
  border-radius: var(--radius-xl);
  backdrop-filter: var(--glass-blur);
  padding: var(--space-6);
  transition: all var(--transition-base);
  position: relative;
  overflow: hidden;
}

.card::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(15,23,42,0.08), transparent);
  pointer-events: none;
}

.card:hover {
  border-color: var(--glass-border-hover);
  background: var(--glass-bg-hover);
  transform: translateY(-2px);
  box-shadow: var(--shadow-lg);
}

/* Snappy tap feedback on touch — subtle enough that it reads fine even on
   cards whose press event bubbled up from an inner button. */
.card:active {
  transform: scale(0.97);
  transition: transform 100ms var(--ease-spring);
}

.card--glow {
  border-color: var(--border-primary);
  box-shadow: var(--shadow-glow-sm);
}

.card--flat {
  background: var(--bg-surface);
  border-color: var(--border-subtle);
  backdrop-filter: none;
}
.card--flat:hover {
  background: var(--bg-elevated);
  transform: translateY(-1px);
}

/* ── Form Inputs ────────────────────────────────────────────────── */
.form-group {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.form-label {
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--text-secondary);
  letter-spacing: 0.01em;
}

.form-input {
  width: 100%;
  padding: 0.75rem var(--space-4);
  background: rgba(15, 23, 42, 0.03);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  color: var(--text-primary);
  font-size: 0.9375rem;
  transition: all var(--transition-fast);
  -webkit-appearance: none;
}

.form-input::placeholder {
  color: var(--text-muted);
}

.form-input:focus {
  border-color: var(--primary-500);
  background: rgba(28, 28, 30, 0.06);
  box-shadow: 0 0 0 3px rgba(28, 28, 30, 0.15);
}

/* :placeholder-shown never matches a <select> (it has no placeholder attribute
   to show), so :not(:placeholder-shown) is always true there — excluding
   select keeps a required-but-unselected dropdown from showing an error
   border before the user has touched it. */
.form-input:not(select):invalid:not(:placeholder-shown) {
  border-color: var(--error-500);
}

.form-hint {
  font-size: 0.8125rem;
  color: var(--text-muted);
}

.form-error {
  font-size: 0.8125rem;
  color: var(--error-500);
  display: flex;
  align-items: center;
  gap: var(--space-1);
}

.form-input--password {
  padding-right: 3rem;
}

.input-wrapper {
  position: relative;
}

.input-wrapper .input-icon {
  position: absolute;
  left: var(--space-4);
  top: 50%;
  transform: translateY(-50%);
  color: var(--text-muted);
  pointer-events: none;
  width: 18px;
  height: 18px;
}

.input-wrapper .form-input {
  padding-left: 2.75rem;
}

.input-wrapper .input-action {
  position: absolute;
  right: var(--space-3);
  top: 50%;
  transform: translateY(-50%);
  color: var(--text-muted);
  cursor: pointer;
  padding: var(--space-1);
  border-radius: var(--radius-sm);
  transition: color var(--transition-fast);
  background: none;
  border: none;
}
.input-wrapper .input-action:hover { color: var(--text-secondary); }
.input-wrapper .input-action svg { width: 18px; height: 18px; display: block; }

/* ── Badges ─────────────────────────────────────────────────────── */
.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 0.2rem var(--space-2);
  border-radius: var(--radius-full);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  line-height: 1;
}

.badge svg { width: 10px; height: 10px; }

/* Text colors here are deliberately the DARK end of each scale (600/700),
   not the light 300/400 shades the original dark theme used — those were
   pastel tones meant to pop against near-black backgrounds and read as
   washed-out, low-contrast text on this app's light background. */
/* Decorative-only badges ("New", role tags) — dark grey, no color right
   now. badge--success/error/warning/live below stay color-coded since
   those convey real status, not brand decoration. */
.badge--primary   { background: rgba(28, 28, 30, 0.08); color: var(--text-primary); border: 1px solid rgba(28, 28, 30, 0.2); }
.badge--accent    { background: rgba(28, 28, 30, 0.08); color: var(--text-primary); border: 1px solid rgba(28, 28, 30, 0.2); }
.badge--success   { background: rgba(34, 197, 94, 0.14); color: var(--success-500); border: 1px solid rgba(34, 197, 94, 0.3); }
.badge--error     { background: rgba(239, 68, 68, 0.14); color: var(--error-500); border: 1px solid rgba(239, 68, 68, 0.3); }
.badge--warning   { background: rgba(234, 179, 8, 0.14); color: var(--warning-500); border: 1px solid rgba(234, 179, 8, 0.3); }
.badge--neutral   { background: var(--glass-bg); color: var(--text-secondary); border: 1px solid var(--glass-border); }
.badge--live      { background: rgba(239, 68, 68, 0.16); color: var(--error-500); border: 1px solid rgba(239, 68, 68, 0.4); animation: pulse-badge 2s ease-in-out infinite; }

@keyframes pulse-badge {
  0%, 100% { opacity: 1; }
  50%       { opacity: 0.6; }
}

/* ── Avatar ─────────────────────────────────────────────────────── */
.avatar {
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-full);
  background: var(--gradient-primary);
  font-weight: 700;
  font-size: 0.875rem;
  color: #fff;
  flex-shrink: 0;
  width: 36px;
  height: 36px;
  letter-spacing: 0.02em;
  border: 2px solid rgba(255,255,255,0.1);
}

.avatar--sm  { width: 28px; height: 28px; font-size: 0.6875rem; }
.avatar--lg  { width: 48px; height: 48px; font-size: 1rem; }
.avatar--xl  { width: 64px; height: 64px; font-size: 1.25rem; }
.avatar--2xl { width: 96px; height: 96px; font-size: 1.75rem; }

/* The profile page's own hero avatar — bigger than every other .avatar--2xl
   use (incoming-call overlays, etc.) since this page is dedicated to one
   person and the avatar is the first thing on it. Declared after
   .avatar--2xl so it wins on elements carrying both classes, without
   touching the shared size everywhere else. */
.avatar--profile-hero { width: 140px; height: 140px; font-size: 2.5rem; }

/* Profile QR code — capped to a fixed size regardless of how many modules
   the encoded profile URL needs (a longer URL means more modules, and
   without this the raw SVG's own pixel dimensions would grow and blow out
   the layout on a phone-width screen). The SVG's viewBox scales the
   pattern proportionally, so this cap never distorts or clips it. */
.profile-qr-box svg { width: 128px; height: 128px; display: block; }

/* Profile QR card + Scan/Share/Save row — matches TikTok's own "My QR
   code" screen: avatar overlapping the card's top edge, name, QR,
   caption, three square icon buttons below. */
.qr-card {
  position: relative;
  text-align: center;
  background: var(--bg-surface-alt, var(--glass-bg));
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-xl);
  padding: calc(var(--space-6) + 20px) var(--space-5) var(--space-6);
}

.qr-card__avatar {
  position: absolute;
  top: 0;
  left: 50%;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  border: 3px solid var(--bg-page, var(--bg-surface));
  line-height: 0;
}

.qr-action-row {
  display: flex;
  gap: var(--space-3);
  margin: var(--space-4) auto 0;
}

.qr-action-btn {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  background: none;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  padding: var(--space-3) var(--space-2);
  color: var(--text-secondary);
  font-size: 0.75rem;
  font-weight: 600;
  cursor: pointer;
  transition: background var(--transition-base);
}

.qr-action-btn svg { width: 20px; height: 20px; }
.qr-action-btn:hover { background: var(--glass-bg); }

/* Gemstone avatar frames (modules/_shared/gemstoneFrame.js) — the wrapped
   img/video/initials keeps its own .avatar(--size) class for font-size
   (initials fallback) but must stretch to fill the frame's clip-path
   shape rather than sit at its class's own fixed width/height. */
.gem-frame-media > * { width: 100%; height: 100%; object-fit: cover; border-radius: 0 !important; border: none !important; background: transparent !important; }

/* Live chat panel card (DM chat, and the live chat used by Streaming,
   Concerts, Contests, Battlesphere, Watch Party — see roomWidgets.js's
   mountChatPanel). Used to be a flat inline `height:480px` (etc.) per
   caller — fine on desktop, but on a phone with the on-screen keyboard
   open that fixed height doesn't shrink, so the message input and Send
   button (at the bottom of the box) end up pushed below the visible
   viewport, invisible until you dismiss the keyboard. `--chat-height`
   (set inline per caller) keeps each screen's original desktop height;
   the mobile rule below caps it to whatever's actually left of the
   dynamic viewport, which shrinks live as the keyboard opens on browsers
   that support `dvh` (current Safari/Chrome on iOS and Android). */
.chat-panel {
  display: flex;
  flex-direction: column;
  padding: var(--space-4);
  height: var(--chat-height, 480px);
}
@media (max-width: 640px) {
  .chat-panel {
    height: min(var(--chat-height, 480px), calc(100vh - 260px));
    height: min(var(--chat-height, 480px), calc(100dvh - 260px));
  }
}

/* ── Chat bubbles (WhatsApp-style shape) ──────────────────────────────
   One shared shape for every chat surface in the app — DM chat
   (modules/social/dmChatPanel.js) and every group/room chat (Battlesphere,
   Contests, Concerts, Watch Party, Streaming, Podcast — all via
   modules/_shared/roomWidgets.js's mountChatPanel). A real WhatsApp bubble
   is a rounded rectangle with ONE corner squared off and a small triangular
   tail growing out of that same corner — built here with a ::after
   pseudo-element clipped into a triangle, not a plain rectangle. Colors
   stay GrooVVee's own (blue for mine / neutral gray for theirs) rather
   than WhatsApp's literal green — this app already avoids recreating
   other platforms' exact branded visuals everywhere else, only ever
   matching the real UX shape/behavior. */
/* ── DM Chat — LinkedIn Messaging style ──────────────────────────────
   LinkedIn's messaging UI:
   - Left panel: conversation list (avatar, name, preview, timestamp)
   - Right panel: chat window — clean white on desktop, dark on our theme
   - Sent bubbles: LinkedIn blue (#0a66c2) right-aligned, no tail
   - Received bubbles: light gray (#e8e8e8 → translated to surface) left, no tail
   - Clean rounded rectangles (18px radius) — no WhatsApp chat tails
   - Sender avatar appears only on received messages (left side)
   - Timestamp appears below the last bubble in a cluster
   - Read receipt "Seen" appears below the last sent message
   ─────────────────────────────────────────────────────────────────── */

/* LinkedIn DM: two-panel layout container */
.dm-layout {
  display: flex;
  height: calc(100vh - var(--topbar-height) - var(--bottom-nav-height) - var(--space-8));
  max-height: 720px;
  background: var(--bg-surface);
  border-radius: var(--radius-xl);
  border: 1px solid var(--border-default);
  overflow: hidden;
  box-shadow: var(--shadow-lg);
}

/* LEFT: Conversation list panel */
.dm-sidebar {
  width: 320px;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  border-right: 1px solid var(--border-default);
  background: var(--bg-surface);
}
.dm-sidebar__header {
  padding: var(--space-4) var(--space-4) var(--space-3);
  border-bottom: 1px solid var(--border-default);
}
.dm-sidebar__title {
  font-size: 1.125rem;
  font-weight: 700;
  color: var(--text-primary);
  margin: 0 0 var(--space-3) 0;
  letter-spacing: -0.01em;
}
.dm-sidebar__search {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  background: var(--bg-elevated);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-full);
  padding: var(--space-2) var(--space-3);
}
.dm-sidebar__search input {
  background: none;
  border: none;
  outline: none;
  color: var(--text-primary);
  font-size: 0.875rem;
  width: 100%;
}
.dm-sidebar__search input::placeholder { color: var(--text-muted); }
.dm-sidebar__search-icon { color: var(--text-muted); flex-shrink: 0; }
.dm-sidebar__list { overflow-y: auto; flex: 1; }

/* Conversation row in the list */
.dm-conv-item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  cursor: pointer;
  transition: background var(--transition-fast);
  position: relative;
  text-decoration: none;
  color: inherit;
}
.dm-conv-item:hover { background: var(--bg-elevated); }
.dm-conv-item--active { background: var(--bg-elevated); }
.dm-conv-item__avatar { flex-shrink: 0; position: relative; }
.dm-conv-item__presence {
  position: absolute;
  bottom: 1px;
  right: 1px;
  width: 11px;
  height: 11px;
  background: #44b700;
  border-radius: 50%;
  border: 2px solid var(--bg-surface);
}
.dm-conv-item__body { flex: 1; min-width: 0; }
.dm-conv-item__name {
  font-weight: 600;
  font-size: 0.875rem;
  color: var(--text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.dm-conv-item__preview {
  font-size: 0.8125rem;
  color: var(--text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-top: 1px;
}
.dm-conv-item__preview--unread { color: var(--text-primary); font-weight: 600; }
.dm-conv-item__meta {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--space-1);
  flex-shrink: 0;
}
.dm-conv-item__time { font-size: 0.6875rem; color: var(--text-muted); }
.dm-conv-item__badge {
  width: 18px;
  height: 18px;
  background: #0a66c2;
  color: #fff;
  border-radius: 50%;
  font-size: 0.6875rem;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* RIGHT: Active chat panel */
.dm-chat-pane {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-width: 0;
  background: var(--bg-base);
}
.dm-chat-pane__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border-default);
  background: var(--bg-surface);
  flex-shrink: 0;
}
.dm-chat-pane__who {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}
.dm-chat-pane__name {
  font-weight: 700;
  font-size: 0.9375rem;
  color: var(--text-primary);
  line-height: 1.2;
}
.dm-chat-pane__status {
  font-size: 0.75rem;
  color: var(--text-muted);
  margin-top: 1px;
}
.dm-chat-pane__status--online { color: #44b700; }
.dm-chat-pane__actions {
  display: flex;
  align-items: center;
  gap: var(--space-1);
}
.dm-chat-pane__btn {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: none;
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background var(--transition-fast), color var(--transition-fast);
}
.dm-chat-pane__btn:hover { background: var(--bg-elevated); color: var(--text-primary); }

/* Mobile-only back button (list ↔ chat toggle below) — hidden on desktop
   where both panes show side by side and there's nothing to go "back" to. */
.dm-chat-pane__back {
  display: none;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: none;
  background: transparent;
  color: var(--text-primary);
  cursor: pointer;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  margin-right: var(--space-1);
}
.dm-chat-pane__back:hover { background: var(--bg-elevated); }

/* ── DM layout on phone screens ────────────────────────────────────
   The 320px fixed sidebar plus the chat pane can't fit side by side on
   a phone — the chat pane would be squeezed to a sliver a few pixels
   wide, so tapping a contact looked like nothing happened. Below 768px
   this becomes a single-panel view that toggles between the
   conversation list and the open chat (`.dm-layout--chat-open`, set by
   modules/social/index.js when a conversation is opened), with the
   back button above returning to the list — the same pattern LinkedIn's
   own mobile app uses. */
@media (max-width: 767px) {
  .dm-layout {
    height: calc(100vh - var(--topbar-height) - var(--bottom-nav-height));
    max-height: none;
    border-radius: 0;
    border: none;
    box-shadow: none;
  }
  .dm-sidebar { width: 100%; border-right: none; }
  .dm-chat-pane { display: none; }
  .dm-layout--chat-open .dm-sidebar { display: none; }
  .dm-layout--chat-open .dm-chat-pane { display: flex; }
  .dm-chat-pane__back { display: flex; }
}

/* Chat bubble area */
.chat-row {
  display: flex;
  align-items: flex-end;
  gap: var(--space-2);
  margin-bottom: 3px;
}
.chat-row--mine { justify-content: flex-end; }

/* LinkedIn-style bubbles — clean rounded rectangles, no tails */
.chat-bubble {
  position: relative;
  max-width: 68%;
  padding: 9px 14px;
  border-radius: 18px;
  font-size: 0.875rem;
  line-height: 1.45;
  overflow-wrap: anywhere;
  white-space: pre-wrap;
  letter-spacing: 0.005em;
}

/* Sent — LinkedIn blue #0a66c2 */
.chat-bubble--mine {
  background: #0a66c2;
  color: #ffffff;
  border-bottom-right-radius: 4px;
}

/* Received — subtle surface, like LinkedIn's light gray on dark */
.chat-bubble--theirs {
  background: var(--bg-surface);
  color: var(--text-primary);
  border-bottom-left-radius: 4px;
  border: 1px solid var(--border-subtle);
}

/* No ::after tail — LinkedIn doesn't use chat tails */
.chat-bubble--mine::after,
.chat-bubble--theirs::after { display: none; }

/* Group/room sender name (DMs don't show this, only group chats) */
.chat-bubble__sender {
  display: block;
  font-weight: 600;
  font-size: 0.75rem;
  color: #0a66c2;
  margin-bottom: 2px;
}

/* Timestamp — LinkedIn shows it below clusters, not inside bubbles */
.chat-bubble__time {
  display: inline-block;
  font-size: 0.6875rem;
  opacity: 0.65;
  margin-left: var(--space-2);
  float: right;
  margin-top: 3px;
  line-height: 1;
}



/* ── Fullscreen Live View (YouTube/IG-Live-style) ─────────────────────
   Shared by Streaming and Concerts' live detail view: the camera/video
   fills the whole screen (not a 16:9 card in the page flow) with overlay
   controls, and chat lives behind a comment-icon toggle instead of an
   always-open docked panel. Deliberately NOT nested inside a `.page-enter`
   wrapper (that class's animation leaves a non-"none" `transform` on its
   element via its `forwards` fill-mode, which — per the CSS spec — turns
   it into a containing block for any `position:fixed` descendant, so the
   fixed overlay would end up confined to that box instead of the real
   viewport). z-index sits at --z-modal so toasts (--z-toast, higher)
   still show above it, but it still covers the app's own sidebar/bottom
   nav (--z-sidebar, lower) the same way a real fullscreen player would. */
.live-fullscreen {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  background: #000;
  overflow: hidden;
}
/* router.js's _renderRoute unconditionally re-adds 'page-enter' to
   #main-content right after every route swap (to retrigger the fade-in
   animation), even if a module removes it — so neutralizing the class
   from inside a module (as this one briefly tried) never sticks. This
   :has() rule reacts to the CONTENT instead of fighting that class
   toggle: whenever #main-content contains a .live-fullscreen child, force
   its transform to the literal `none` (not just an identity matrix),
   which is what actually stops it from being a containing block for
   .live-fullscreen's `position:fixed`. */
#main-content:has(> .live-fullscreen) {
  transform: none !important;
  animation: none !important;
}
.live-fullscreen__media {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
.live-fullscreen__media video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.live-fullscreen__top-bar {
  position: absolute;
  top: 0; left: 0; right: 0;
  padding: var(--space-4);
  padding-top: max(var(--space-4), env(safe-area-inset-top));
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  z-index: 2;
  background: linear-gradient(rgba(0,0,0,0.55), transparent);
}
.live-fullscreen__top-bar .btn-icon,
.live-fullscreen__action-rail button,
.live-fullscreen__controls-bar .btn-icon {
  background: rgba(0,0,0,0.4);
  color: #fff;
  border-color: transparent;
}
/* One flex-column stack instead of several independently bottom:0-anchored
   blocks — .info/.controls-bar/the reaction mount used to all occupy the
   same rectangle and visually collide (title text under the End Stream
   button, reactions floating over both). Order here is visual order:
   reactions float just above the info text, which sits just above the
   owner's control bar (or the viewer's screen-frame/filter controls). */
.live-fullscreen__bottom-overlay {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  padding: var(--space-3) 76px var(--space-3) var(--space-4); /* right padding clears the action rail */
  padding-bottom: max(var(--space-3), env(safe-area-inset-bottom));
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  z-index: 2;
  background: linear-gradient(transparent, rgba(0,0,0,0.8));
}
.live-fullscreen__info h1 { color: #fff; margin: 0; }
.live-fullscreen__info .text-secondary { color: rgba(255,255,255,0.85); }
.live-fullscreen__reactions-row {
  position: relative;
  height: 0;
  align-self: flex-start;
}
.live-fullscreen__action-rail {
  position: absolute;
  right: var(--space-3);
  bottom: var(--space-4);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-4);
  z-index: 3;
}
.live-fullscreen__action-rail button {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  font-size: 0.6875rem;
  padding: var(--space-2);
  border-radius: var(--radius-full);
  min-width: 44px;
  min-height: 44px;
}
.live-fullscreen__controls-bar {
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
}
.live-fullscreen__chat-drawer {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  max-height: 65%;
  min-height: 40%;
  background: var(--bg-surface);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  box-shadow: var(--shadow-xl);
  z-index: 4;
  display: flex;
  flex-direction: column;
  padding: var(--space-3) 0 0;
}
.live-fullscreen__chat-drawer[hidden] { display: none; }
.live-fullscreen__chat-drawer-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 var(--space-4) var(--space-3);
  border-bottom: 1px solid var(--border-subtle);
  flex-shrink: 0;
}

/* Rich chat input (modules/_shared/richChatInput.js) — emoji/sticker
   picker trays, and the mic button's recording state. */
.rich-chat-picker {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
  padding: var(--space-2);
  border-top: 1px solid var(--border-subtle);
  margin-bottom: var(--space-2);
}
.rci-mic-btn--recording {
  background: var(--error-500);
  color: #fff;
  animation: pulse-dot 1.2s ease-in-out infinite;
}

/* Buddy's hands-free voice mode (modules/buddy/index.js) — distinct from the red "listening" pulse above:
   blue means Buddy itself is talking right now, not that the mic is capturing you. */
.rci-mic-btn--speaking {
  background: var(--info-500);
  color: #fff;
  animation: pulse-dot 1.2s ease-in-out infinite;
}

/* Global call overlay (modules/_shared/globalCall.js) — WhatsApp-style
   round controls. Lives on a near-black call background regardless of
   light/dark theme, so colors are hardcoded here rather than themed. */
.gc-round-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  border: none;
  background: rgba(255,255,255,0.16);
  color: #fff;
  cursor: pointer;
  flex-shrink: 0;
}
.gc-round-btn svg { width: 24px; height: 24px; }
.gc-round-btn:hover { background: rgba(255,255,255,0.26); }
.gc-round-btn--sm { width: 38px; height: 38px; }
.gc-round-btn--sm svg { width: 18px; height: 18px; }
.gc-round-btn--active { background: #fff; color: #111; }
.gc-round-btn--danger { background: var(--error-500, #ef4444); }
.gc-round-btn--danger:hover { background: var(--error-600, #dc2626); }
.gc-round-btn--accept { background: var(--success-500, #22c55e); }
.gc-round-btn--accept:hover { background: var(--success-600, #16a34a); }

/* Real presence (services/presenceService.js) — online is the one place
   this app still uses a functional color (green), same as live/error
   status elsewhere; not part of the "no color" decorative palette. */
.presence-dot {
  position: absolute;
  bottom: -1px;
  right: -1px;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--success-500);
  border: 2px solid var(--bg-surface);
}

.avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: inherit;
}

/* Avatar button (clickable) */
.avatar-btn {
  cursor: pointer;
  border: none;
  background: none;
  padding: 2px;
  border-radius: var(--radius-full);
  transition: all var(--transition-fast);
}
.avatar-btn:hover .avatar {
  box-shadow: 0 0 0 3px var(--primary-500);
}

/* ── Search Bar ─────────────────────────────────────────────────── */
.search-bar {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  background: var(--glass-bg);
  border: 1px solid var(--glass-border);
  border-radius: var(--radius-full);
  padding: 0 var(--space-4);
  transition: all var(--transition-fast);
  max-width: 400px;
  width: 100%;
}

.search-bar:focus-within {
  border-color: var(--primary-500);
  background: rgba(28, 28, 30, 0.06);
  box-shadow: 0 0 0 3px rgba(28, 28, 30, 0.12);
}

.search-bar__icon {
  width: 16px;
  height: 16px;
  color: var(--text-muted);
  flex-shrink: 0;
}

.search-bar__input {
  background: transparent;
  border: none;
  color: var(--text-primary);
  font-size: 0.875rem;
  width: 100%;
  height: 38px;
  padding: 0;
}
.search-bar__input::placeholder { color: var(--text-muted); }

.search-bar__mic {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 26px;
  height: 26px;
  margin: 0 -6px 0 0;
  border-radius: 50%;
  border: none;
  background: none;
  color: var(--text-muted);
  cursor: pointer;
  transition: color var(--transition-fast), background var(--transition-fast);
}
.search-bar__mic:hover { color: var(--text-primary); background: var(--glass-bg-hover); }
.search-bar__mic svg { width: 16px; height: 16px; }
.search-bar__mic:disabled { opacity: 0.4; cursor: not-allowed; }
.search-bar__mic--listening {
  color: var(--text-inverse);
  background: var(--text-primary);
  animation: voice-pulse 1.2s ease-in-out infinite;
}

/* ── Toasts ─────────────────────────────────────────────────────── */
.toast-container {
  position: fixed;
  top: calc(var(--topbar-height) + var(--space-4));
  right: var(--space-6);
  z-index: var(--z-toast);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  pointer-events: none;
}

.toast {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  background: var(--bg-elevated);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xl);
  min-width: 280px;
  max-width: 400px;
  pointer-events: all;
  animation: toast-slide-in var(--duration-slow) var(--ease-out) forwards;
  position: relative;
  overflow: hidden;
}

.toast::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 3px;
}

.toast--success::before { background: var(--success-500); }
.toast--error::before   { background: var(--error-500); }
.toast--warning::before { background: var(--warning-500); }
.toast--info::before    { background: var(--info-500); }

.toast__icon {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  margin-top: 1px;
}

.toast--success .toast__icon { color: var(--success-500); }
.toast--error .toast__icon   { color: var(--error-500); }
.toast--warning .toast__icon { color: var(--warning-500); }
.toast--info .toast__icon    { color: var(--info-500); }

.toast__body { flex: 1; min-width: 0; }

.toast__title {
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--text-primary);
  line-height: 1.3;
}

.toast__message {
  font-size: 0.8125rem;
  color: var(--text-secondary);
  margin-top: 2px;
  line-height: 1.5;
}

.toast__close {
  width: 24px;
  height: 24px;
  border-radius: var(--radius-sm);
  color: var(--text-muted);
  cursor: pointer;
  transition: all var(--transition-fast);
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: none;
  padding: 0;
}
.toast__close svg { width: 14px; height: 14px; }
.toast__close:hover { color: var(--text-primary); background: var(--glass-bg); }

.toast--removing {
  animation: toast-slide-out var(--duration-base) var(--ease-in-out) forwards;
}

@keyframes toast-slide-in {
  from {
    opacity: 0;
    transform: translateX(120%) scale(0.95);
  }
  to {
    opacity: 1;
    transform: translateX(0) scale(1);
  }
}

@keyframes toast-slide-out {
  from {
    opacity: 1;
    transform: translateX(0) scale(1);
    max-height: 200px;
    margin-bottom: 0;
  }
  to {
    opacity: 0;
    transform: translateX(120%) scale(0.9);
    max-height: 0;
    margin-bottom: calc(var(--space-3) * -1);
  }
}

/* ── Notification Dot ───────────────────────────────────────────── */
.notification-dot {
  position: absolute;
  top: 5px;
  right: 5px;
  width: 8px;
  height: 8px;
  background: var(--error-500);
  border-radius: 50%;
  border: 2px solid var(--bg-base);
  animation: pulse-dot 2s ease-in-out infinite;
}

@keyframes pulse-dot {
  0%, 100% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.4); }
  50%       { box-shadow: 0 0 0 4px rgba(239, 68, 68, 0); }
}

/* Btn-icon relative positioning for dot */
.btn-icon { position: relative; }

/* Notifications bell badge — same red "count" pill as most apps put on a
   bell icon (e.g. "9+" once it's more than one digit's worth of room). */
.topbar__notif-badge {
  position: absolute;
  top: 2px;
  right: 2px;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: var(--radius-full);
  background: var(--error-500);
  color: #fff;
  font-size: 0.625rem;
  font-weight: 700;
  line-height: 16px;
  text-align: center;
}

/* ── Dropdown Menu ──────────────────────────────────────────────── */
.dropdown {
  position: fixed;
  background: var(--bg-elevated);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-xl);
  padding: var(--space-2);
  min-width: 220px;
  z-index: var(--z-dropdown);
  animation: dropdown-pop var(--duration-base) var(--ease-spring) forwards;
  backdrop-filter: var(--glass-blur);
  /* Grows to fit its content by default (fine for a couple of items), but
     the language list alone now has 10 entries — without a cap it can
     render past the bottom of the screen with no way to reach the rest.
     Capped + scrollable here so every .dropdown (notifications, account,
     language) stays fully reachable regardless of how many items it holds. */
  max-height: min(420px, 70vh);
  overflow-y: auto;
}

/* The account dropdown's trigger lives inside the sidebar now (bottom-left
   footer) — the sidebar's own z-index (200) sits above the base .dropdown
   z-index (100), so without this it opens invisibly behind the sidebar
   panel itself. */
#user-dropdown {
  z-index: var(--z-modal);
}

@keyframes dropdown-pop {
  from { opacity: 0; transform: scale(0.95) translateY(-8px); }
  to   { opacity: 1; transform: scale(1) translateY(0); }
}

.dropdown__header {
  padding: var(--space-3) var(--space-3) var(--space-2);
  position: sticky;
  top: 0;
  background: var(--bg-elevated);
  z-index: 1;
}

.dropdown__header .user-email {
  font-size: 0.75rem;
  color: var(--text-muted);
  margin-top: 2px;
}

.dropdown__header .user-role-badge {
  margin-top: var(--space-2);
}

.dropdown__divider {
  height: 1px;
  background: var(--border-subtle);
  margin: var(--space-2) 0;
}

.dropdown__item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  padding: var(--space-3) var(--space-3);
  border-radius: var(--radius-md);
  font-size: 0.9375rem;
  font-weight: 500;
  color: var(--text-secondary);
  text-align: left;
  cursor: pointer;
  transition: all var(--transition-fast);
  background: none;
  border: none;
}
.dropdown__item svg { width: 18px; height: 18px; flex-shrink: 0; }
.dropdown__item:hover {
  background: var(--glass-bg-hover);
  color: var(--text-primary);
}
.dropdown__item--danger { color: var(--error-500); }
.dropdown__item--danger:hover { background: rgba(239, 68, 68, 0.1); }

/* ── Tabs ───────────────────────────────────────────────────────── */
.tabs {
  display: flex;
  background: var(--glass-bg);
  border-radius: var(--radius-lg);
  padding: 3px;
  border: 1px solid var(--glass-border);
  width: fit-content;
}

.tab-btn {
  padding: 0.5rem var(--space-5);
  border-radius: calc(var(--radius-lg) - 3px);
  font-size: 0.9375rem;
  font-weight: 500;
  color: var(--text-muted);
  transition: all var(--transition-base);
  cursor: pointer;
  background: none;
  border: none;
  white-space: nowrap;
}

.tab-btn.active {
  background: var(--glass-bg-active);
  color: var(--text-primary);
  box-shadow: var(--shadow-sm);
}

.tab-btn:hover:not(.active) {
  color: var(--text-secondary);
}

/* ── Progress Bar ───────────────────────────────────────────────── */
.progress {
  width: 100%;
  height: 4px;
  background: var(--border-subtle);
  border-radius: var(--radius-full);
  overflow: hidden;
}

.progress__bar {
  height: 100%;
  border-radius: inherit;
  background: var(--gradient-primary);
  transition: width var(--duration-slow) var(--ease-out);
}

/* ── Divider ────────────────────────────────────────────────────── */
.divider {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  color: var(--text-muted);
  font-size: 0.8125rem;
}

.divider::before,
.divider::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--border-subtle);
}

/* ── Stat Tile ──────────────────────────────────────────────────── */
.stat-tile {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-5) var(--space-6);
  background: var(--glass-bg);
  border: 1px solid var(--glass-border);
  border-radius: var(--radius-xl);
  backdrop-filter: var(--glass-blur);
  transition: all var(--transition-base);
}

.stat-tile:hover {
  border-color: var(--border-primary);
  box-shadow: var(--shadow-glow-sm);
  transform: translateY(-2px);
}

.stat-tile__label {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.stat-tile__value {
  font-family: 'Times New Roman', Times, serif;
  font-size: 1.875rem;
  font-weight: 800;
  color: var(--text-primary);
  line-height: 1;
  letter-spacing: -0.03em;
}

.stat-tile__sub {
  font-size: 0.8125rem;
  color: var(--success-500);
  display: flex;
  align-items: center;
  gap: var(--space-1);
}

/* ── Module Placeholder (Coming Soon) ───────────────────────────── */
.module-placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: calc(100vh - var(--topbar-height) - var(--space-16));
  padding: var(--space-12) var(--space-6);
  text-align: center;
  gap: var(--space-6);
}

.module-placeholder__icon {
  width: 80px;
  height: 80px;
  /* Tinted to whatever `color` each module sets inline, not a fixed glass
     tone — on the light theme a flat translucent-white box with a generic
     blue glow behind it (the old dark-theme design) washed out badly for
     non-blue icons (e.g. Shop's yellow). currentColor keeps every module's
     icon readable regardless of its accent color. */
  background: color-mix(in srgb, currentColor 14%, var(--bg-surface));
  border: 1.5px solid color-mix(in srgb, currentColor 45%, transparent);
  border-radius: var(--radius-2xl);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--primary-500);
  box-shadow: var(--shadow-sm);
  position: relative;
}

.module-placeholder__icon svg {
  width: 40px;
  height: 40px;
}

.module-placeholder__icon::before {
  content: '';
  position: absolute;
  inset: -2px;
  border-radius: calc(var(--radius-2xl) + 2px);
  background: currentColor;
  z-index: -1;
  opacity: 0.18;
  filter: blur(10px);
}

.module-placeholder__badge-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
  justify-content: center;
}

.module-placeholder__title {
  font-family: 'Times New Roman', Times, serif;
  font-size: clamp(1.75rem, 4vw, 2.5rem);
  font-weight: 800;
  letter-spacing: -0.03em;
  color: var(--text-primary);
}

.module-placeholder__desc {
  font-size: 1.0625rem;
  color: var(--text-secondary);
  max-width: 480px;
  line-height: 1.7;
}

.module-placeholder__features {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  justify-content: center;
  max-width: 560px;
}

.feature-chip {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  background: var(--glass-bg);
  border: 1px solid var(--glass-border);
  border-radius: var(--radius-full);
  font-size: 0.875rem;
  color: var(--text-secondary);
  backdrop-filter: var(--glass-blur);
  transition: all var(--transition-base);
}

.feature-chip:hover {
  border-color: var(--border-primary);
  color: var(--text-primary);
}

.feature-chip svg {
  width: 14px;
  height: 14px;
  color: var(--primary-400);
}

/* ── Page Section ───────────────────────────────────────────────── */
.section {
  padding: var(--space-8) var(--space-8);
}

.section-header {
  display: flex;
  flex-wrap: wrap; /* action buttons drop under the title on a phone instead of running off-screen */
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-6);
}

.section-title {
  font-family: 'Times New Roman', Times, serif;
  font-size: 1.25rem;
  font-weight: 700;
  color: var(--text-primary);
  letter-spacing: -0.02em;
}

.section-subtitle {
  font-size: 0.875rem;
  color: var(--text-muted);
  margin-top: var(--space-1);
}

/* ── Role Badge ─────────────────────────────────────────────────── */
.role-badge--fan     { background: rgba(28, 28, 30, 0.14); color: var(--text-primary); border: 1px solid rgba(28, 28, 30, 0.3); }
.role-badge--creator { background: rgba(28, 28, 30, 0.14); color: var(--text-primary); border: 1px solid rgba(28, 28, 30, 0.3); }
.role-badge--admin   { background: rgba(28, 28, 30, 0.14); color: var(--text-primary); border: 1px solid rgba(28, 28, 30, 0.3); }

/* ── Grid Layouts ───────────────────────────────────────────────── */
.grid-2 { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-5); }
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-5); }
.grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-5); }
.grid-auto { display: grid; grid-template-columns: repeat(auto-fill, minmax(var(--card-min-width), 1fr)); gap: var(--space-5); }

@media (max-width: 1024px) {
  .grid-4 { grid-template-columns: repeat(2, 1fr); }
  .grid-3 { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 640px) {
  .grid-4, .grid-3, .grid-2 { grid-template-columns: 1fr; }
}

/* Two-column detail layouts (streaming/contests/battlesphere/concerts/
   watch-party detail views: media+info beside chat) — stack on phones and
   tablets so the sidebar column never gets squeezed unreadably narrow. */
@media (max-width: 900px) {
  .detail-split-grid { grid-template-columns: 1fr !important; }
}

/* ── Utility flex ───────────────────────────────────────────────── */
.flex         { display: flex; }
.flex-col     { display: flex; flex-direction: column; }
.flex-center  { display: flex; align-items: center; justify-content: center; }
.flex-between { display: flex; align-items: center; justify-content: space-between; }
.items-center { align-items: center; }
.gap-2  { gap: var(--space-2); }
.gap-3  { gap: var(--space-3); }
.gap-4  { gap: var(--space-4); }
.gap-6  { gap: var(--space-6); }

/* ── Page Transition ────────────────────────────────────────────── */
.page-enter {
  animation: page-fade-in 260ms var(--ease-spring) forwards;
}

@keyframes page-fade-in {
  from { opacity: 0; transform: translateY(8px) scale(0.99); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

/* ── Dashboard Widget Grid ──────────────────────────────────────── */
.widget-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-5);
  align-items: start;
}
.widget-wrapper { min-width: 0; }
.widget-wrapper--full   { grid-column: span 4; }
.widget-wrapper--half   { grid-column: span 2; }
.widget-wrapper--third  { grid-column: span 1; }
.widget-wrapper--quarter { grid-column: span 1; }

@media (max-width: 1024px) {
  .widget-grid { grid-template-columns: repeat(2, 1fr); }
  .widget-wrapper--full  { grid-column: span 2; }
  .widget-wrapper--half  { grid-column: span 1; }
  .widget-wrapper--third,
  .widget-wrapper--quarter { grid-column: span 1; }
}
@media (max-width: 640px) {
  .widget-grid { grid-template-columns: minmax(0, 1fr); } /* minmax(0,…) — plain 1fr lets one wide child stretch the column past a 320px screen */
  .widget-wrapper--full,
  .widget-wrapper--half,
  .widget-wrapper--third,
  .widget-wrapper--quarter { grid-column: span 1; }
}

/* ── Widget Cards ───────────────────────────────────────────────── */
.widget-card {
  min-height: 160px;
  position: relative;
  overflow: hidden;
  transition: transform var(--transition-base);
}
.widget-card:hover { transform: translateY(-2px); }
.widget-card__icon {
  width: 40px;
  height: 40px;
  border-radius: var(--radius-md);
  border: 1px solid;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.widget-card__label {
  font-size: 0.9375rem;
  font-weight: 700;
  color: var(--text-primary);
  margin-bottom: var(--space-1);
}
.widget-card__coming-soon {
  font-size: 0.75rem;
  color: var(--text-muted);
  font-style: italic;
}
.widget-card--placeholder {
  background: var(--glass-bg);
}
.widget-loading {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 120px;
}

/* Widget shimmer effect */
.widget-shimmer {
  position: absolute;
  bottom: 0;
  right: 0;
  width: 80px;
  height: 80px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(28, 28, 30,0.06) 0%, transparent 70%);
  pointer-events: none;
}

/* ── Dashboard Banner ───────────────────────────────────────────── */
.dashboard-tier-badge {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-full);
  border: 1px solid;
  font-size: 0.8125rem;
}
.dashboard-tier-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  flex-shrink: 0;
}


/* ── Enterprise Banner ──────────────────────────────────────────── */
.enterprise-banner {
  border-left: 3px solid var(--accent-300);
}

/* ── Role badges — enterprise ───────────────────────────────────── */
.role-badge--enterprise {
  background: rgba(28, 28, 30, 0.14);
  color: var(--accent-700);
  border: 1px solid rgba(28, 28, 30, 0.3);
}

/* ── Room Reaction Float (Contests, Battlesphere, Concerts, Watch Party) ── */
@keyframes reaction-float {
  0%   { opacity: 1; transform: translate(0, 0) scale(1); }
  100% { opacity: 0; transform: translate(0, -60px) scale(1.4); }
}

/* ── AI Studio tool cards ───────────────────────────────────────── */
.tool-card--active {
  border-color: var(--primary-500) !important;
  background: rgba(28, 28, 30, 0.06) !important;
  box-shadow: 0 0 0 1px var(--primary-500), var(--shadow-glow-sm);
}

/* ── Netflix-style horizontal carousel row ─────────────────────────── */
.carousel-row {
  display: flex;
  gap: var(--space-4);
  overflow-x: auto;
  scroll-snap-type: x proximity;
  padding-bottom: var(--space-3);
  scrollbar-width: thin;
}
.carousel-row > * {
  scroll-snap-align: start;
  flex-shrink: 0;
}

/* ── Hero banner ────────────────────────────────────────────────── */
.hero-banner {
  position: relative;
  border-radius: var(--radius-2xl);
  overflow: hidden;
  min-height: 320px;
  display: flex;
  align-items: flex-end;
  padding: var(--space-8);
  background: var(--gradient-mixed);
  box-shadow: var(--shadow-xl);
}
.hero-banner::before {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(0deg, rgba(15,23,42,0.55) 0%, rgba(15,23,42,0.05) 60%);
}
.hero-banner__content { position: relative; z-index: 1; color: #fff; max-width: 560px; }

/* ── Voice Assistant (floating mic) ────────────────────────────────── */
/* Inline in the topbar's icon row now (next to the notification bell),
   not a separate floating button — .btn-icon.topbar__quick-icon (already
   on this element) supplies the sizing/layout, this just supplies the
   explicit orange: the rest of the app stays grey/no-color, this one
   button is a deliberate, requested exception. */
.voice-btn {
  border-radius: var(--radius-full);
  background: linear-gradient(135deg, #FFB86B, #FF922B);
  color: #fff;
  box-shadow: 0 0 12px rgba(255, 146, 43, 0.35);
  transition: transform var(--transition-fast);
}
.voice-btn:hover { transform: scale(1.08); background: linear-gradient(135deg, #FFB86B, #FF922B); }
.voice-btn:disabled { opacity: 0.4; cursor: not-allowed; }
.voice-btn--listening {
  background: var(--gradient-accent);
  animation: voice-pulse 1.2s ease-in-out infinite;
}
@keyframes voice-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(28, 28, 30,0.5); }
  50%      { box-shadow: 0 0 0 10px rgba(28, 28, 30,0); }
}

/* ── Netflix-style browse row (VOD library) ─────────────────────────
   Horizontal-scrolling poster cards that scale up on hover, like Netflix's
   own browse rows — distinct from the TikTok-style vertical feed used for
   Home; a video library suits "browse and pick," not "swipe one at a time." */
.netflix-row {
  display: flex;
  gap: var(--space-3);
  overflow-x: auto;
  padding-bottom: var(--space-2);
  scrollbar-width: thin;
}

.netflix-card {
  flex: 0 0 220px;
  cursor: pointer;
  transition: transform 200ms var(--ease-out), z-index 0s;
  transform-origin: center;
}

.netflix-card:hover {
  transform: scale(1.08);
  z-index: 2;
}

.netflix-card:active {
  transform: scale(1.03);
}

.netflix-card__poster {
  position: relative;
  aspect-ratio: 16/9;
  border-radius: var(--radius-md);
  background: linear-gradient(135deg, #18181b, #000);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  box-shadow: var(--shadow-md);
}

.netflix-card:hover .netflix-card__poster {
  box-shadow: var(--shadow-xl);
}

.netflix-card__duration {
  position: absolute;
  bottom: var(--space-2);
  right: var(--space-2);
}

.netflix-card__hover-play {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0,0,0,0.35);
  color: #fff;
  opacity: 0;
  transition: opacity 150ms var(--ease-out);
}

.netflix-card:hover .netflix-card__hover-play,
.netflix-card:focus-visible .netflix-card__hover-play {
  opacity: 1;
}

.netflix-card__meta {
  padding: var(--space-2) 2px 0;
}

/* TikTok-Live-style floating heart burst — see _burstHeart() in modules/streaming/index.js */
@keyframes live-heart-float {
  0%   { transform: translate(0, 0) scale(0.6); opacity: 0; }
  15%  { transform: translate(-6px, -20px) scale(1.1); opacity: 1; }
  100% { transform: translate(-24px, -160px) scale(0.9); opacity: 0; }
}

/* ── TikTok-style Vertical Feed (Home) ──────────────────────────────
   One item fills the available viewport height; scroll/swipe snaps to
   the next, exactly like TikTok/Reels/Shorts. Colors stay this app's
   own — only the layout is copied. .home-page is a flex column so the
   live status bar (when present) takes only the room it needs and the
   feed fills the rest — no live streams, no bar, feed still fills 100%. */

.home-page {
  display: flex;
  flex-direction: column;
  /* vh first as a fallback for browsers/WebViews that don't support dvh at
     all (an unknown unit makes the whole declaration invalid, not just
     imprecise — without this, .home-page gets no height, its flex:1
     children never get a size to fill, and the grid/scroller falls back to
     normal document scroll instead of its own internal one, a real source
     of janky-feeling mobile scrolling on older Android WebViews). dvh
     second so it wins on anything that does support it (more accurate —
     accounts for the address bar showing/hiding). */
  height: calc(100vh - var(--topbar-height) - var(--bottom-nav-height));
  height: calc(100dvh - var(--topbar-height) - var(--bottom-nav-height));
}

.feed-scroller {
  flex: 1;
  min-height: 0;
  overflow-y: scroll;
  scroll-snap-type: y mandatory;
  scroll-behavior: smooth;
  background: #000;
}

.feed-item {
  position: relative;
  height: 100%;
  width: 100%;
  scroll-snap-align: start;
  scroll-snap-stop: always;
  overflow: hidden;
  cursor: default;
}

.feed-item--live { cursor: pointer; }

.feed-item__bg {
  position: absolute;
  inset: 0;
  background: #000;
}

.feed-item__overlay {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: var(--space-6);
  padding-right: 88px; /* keep clear of the right-side icon rail */
  padding-bottom: var(--space-10);
  background: linear-gradient(to top, rgba(0,0,0,0.65) 0%, rgba(0,0,0,0.15) 40%, transparent 70%);
  pointer-events: none;
}

.feed-item__overlay > * { pointer-events: auto; }

.feed-item__author {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-2);
  cursor: pointer;
  width: fit-content;
}

.feed-item__caption {
  color: #fff;
  font-size: 0.9375rem;
  line-height: 1.4;
  max-width: 480px;
  text-shadow: 0 1px 3px rgba(0,0,0,0.4);
}

.feed-item__mute-btn {
  position: absolute;
  top: var(--space-4);
  right: var(--space-4);
  z-index: 2;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: none;
  background: rgba(0,0,0,0.4);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}

.feed-item__mute-btn svg { width: 18px; height: 18px; }

.feed-item__rail {
  position: absolute;
  right: var(--space-4);
  bottom: var(--space-10);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-5);
  z-index: 2;
}

.feed-item__rail-avatar {
  position: relative;
  margin-bottom: var(--space-2);
  cursor: pointer;
}

.feed-item__rail-avatar .avatar {
  border: 2px solid #fff;
}

.feed-item__follow-btn {
  position: absolute;
  bottom: -8px;
  left: 50%;
  transform: translateX(-50%);
  width: 20px;
  height: 20px;
  border-radius: 50%;
  border: none;
  background: var(--gradient-accent);
  color: #fff;
  font-size: 0.75rem;
  font-weight: 800;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}

.feed-item__follow-btn[data-following="true"] { background: var(--success-500); }

.feed-item__rail-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  background: none;
  border: none;
  cursor: pointer;
  color: #fff;
}

.feed-item__rail-icon {
  display: flex;
  filter: drop-shadow(0 1px 3px rgba(0,0,0,0.5));
  transition: transform 100ms var(--ease-spring);
}

.feed-item__rail-icon svg {
  width: 30px;
  height: 30px;
}

.post-icon {
  display: inline-flex;
  vertical-align: -5px;
}

.post-icon svg {
  width: 16px;
  height: 16px;
}

.feed-item__rail-btn:active .feed-item__rail-icon { transform: scale(1.3); }

/* Social feed — LinkedIn-style home page (condensed profile card, collapsed post composer, and the
   Like/Comment/Repost/Send action row). See modules/social/index.js. */
.li-profile-card,
.li-composer-trigger {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.li-composer-trigger__pill {
  flex: 1;
  min-width: 0;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-full);
  padding: var(--space-3) var(--space-4);
  color: var(--text-muted);
  font-size: 0.9375rem;
}

.li-repost-embed:hover { background: var(--bg-elevated); }

.li-action-btn {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  background: none;
  border: none;
  padding: var(--space-2) 0;
  color: var(--text-muted);
  font-weight: 600;
  font-size: 0.8125rem;
  cursor: pointer;
  border-radius: var(--radius-sm);
}

.li-action-btn:hover { background: var(--bg-overlay); }
.li-action-btn .post-icon svg { width: 18px; height: 18px; }

.feed-item__rail-count {
  font-size: 0.75rem;
  font-weight: 600;
  text-shadow: 0 1px 3px rgba(0,0,0,0.5);
}

.feed-item__comments {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  max-height: 60%;
  background: var(--bg-surface);
  border-radius: var(--radius-2xl) var(--radius-2xl) 0 0;
  box-shadow: var(--shadow-xl);
  z-index: 3;
  display: flex;
  flex-direction: column;
  padding: var(--space-4);
  animation: page-fade-in 200ms var(--ease-spring) forwards;
}

.feed-item__comments-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: var(--space-3);
}

.feed-item__comments-list {
  flex: 1;
  overflow-y: auto;
  margin-bottom: var(--space-3);
}

.feed-item__comment-form {
  display: flex;
  gap: var(--space-2);
}

@media (min-width: 768px) {
  /* width:100% is required here, not just max-width — .feed-scroller is a
     flex item (see .home-page) whose children are all position:absolute,
     so it has no normal-flow content to derive a shrink-to-fit width from;
     without an explicit width, the auto side-margins below collapse it to
     0 instead of centering it. Only Shorts uses .feed-scroller now (Home
     is .video-grid, full width) — .live-status-bar only ever appears
     above the Home grid, so it stays full width too, not capped to match
     a narrow column that isn't there anymore. */
  .feed-scroller { width: 100%; max-width: 480px; margin: 0 auto; }
}

/* ── YouTube-style category chips ────────────────────────────────────
   Sits above the live status bar / feed, same flex-shrink:0 pattern as
   .live-status-bar below so the feed still fills the rest of the column. */

.home-category-bar {
  display: flex;
  gap: var(--space-2);
  padding: 0 var(--space-4) var(--space-3);
  overflow-x: auto;
  background: var(--bg-surface);
  border-bottom: 1px solid var(--border-subtle);
  flex-shrink: 0;
  scrollbar-width: none;
}

.home-category-bar::-webkit-scrollbar { display: none; }

.home-category-chip {
  flex-shrink: 0;
  white-space: nowrap;
  padding: 0.5rem var(--space-4);
  border-radius: var(--radius-full);
  border: none;
  background: var(--bg-overlay);
  color: var(--text-primary);
  font-size: 0.8125rem;
  font-weight: 600;
  cursor: pointer;
  transition: background var(--transition-fast), color var(--transition-fast);
}

.home-category-chip:hover { background: var(--glass-bg-active); }

.home-category-chip.active {
  background: var(--text-primary);
  color: var(--text-inverse);
}

.home-category-chip--custom-feed {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

/* A chip that opens a page (rather than filtering this feed) carries a small arrow */
.home-category-chip--link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

/* A thin rule between the groups in the chip row (Content | Community | genres) */
.home-category-divider {
  flex-shrink: 0;
  align-self: center;
  width: 1px;
  height: 20px;
  background: var(--border-subtle);
}

.home-category-chip__icon {
  display: inline-flex;
  width: 14px;
  height: 14px;
  flex-shrink: 0;
}

/* ── "Your custom feed" builder ──────────────────────────────────────
   Takes over the #feed area (see .feed-scroller--plain below) with a
   plain scrollable panel instead of the vertical snap feed. */

.feed-scroller--plain {
  scroll-snap-type: none;
  background: var(--bg-base);
  display: flex;
  justify-content: center;
}

.custom-feed-builder {
  width: 100%;
  max-width: 480px;
  padding: var(--space-6) var(--space-4) var(--space-10);
}

.custom-feed-builder__title {
  font-family: 'Times New Roman', Times, serif;
  font-weight: 800;
  font-size: 1.75rem;
  line-height: 1.2;
  margin: var(--space-6) 0 var(--space-5);
  color: var(--text-primary);
}

.custom-feed-builder__form {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  background: var(--bg-overlay);
  border-radius: var(--radius-full);
  padding: var(--space-1) var(--space-1) var(--space-1) var(--space-4);
}

.custom-feed-builder__form input {
  flex: 1;
  min-width: 0;
  border: none;
  background: transparent;
  outline: none;
  font-size: 0.9375rem;
  color: var(--text-primary);
  padding: 0.625rem 0;
}

.custom-feed-builder__form input::placeholder { color: var(--text-muted); }

.custom-feed-builder__submit {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  border: none;
  background: var(--text-primary);
  color: var(--text-inverse);
  cursor: pointer;
}

.custom-feed-builder__submit svg { width: 18px; height: 18px; }

.custom-feed-builder__disclaimer {
  font-size: 0.75rem;
  color: var(--text-muted);
  margin: var(--space-3) 0 var(--space-6);
}

.custom-feed-builder__examples {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.custom-feed-builder__example {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  text-align: left;
  background: none;
  border: none;
  padding: 0;
  font-size: 0.9375rem;
  color: var(--text-primary);
  cursor: pointer;
}

.custom-feed-builder__example:hover { color: var(--text-brand); }

.custom-feed-builder__example-icon {
  display: inline-flex;
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  margin-top: 2px;
  color: var(--text-muted);
}

/* ── Live status bar (Instagram/Snapchat-Stories-style) ─────────────
   Persistent, above the scrolling feed — every current live stream as a
   clickable bubble, not something you have to scroll into the feed to
   discover. */

.live-status-bar {
  display: flex;
  gap: var(--space-4);
  padding: var(--space-3) var(--space-4);
  overflow-x: auto;
  background: var(--bg-surface);
  border-bottom: 1px solid var(--border-subtle);
  flex-shrink: 0;
}

.live-status-bar__item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  background: none;
  border: none;
  cursor: pointer;
  flex-shrink: 0;
  width: 68px;
}

.live-status-bar__ring {
  display: block;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  padding: 2.5px;
  background: linear-gradient(135deg, var(--error-500), var(--warning-400));
  position: relative;
}

/* Your own "Go Live" bubble — always leads, same as your own Story bubble on IG */
.live-status-bar__ring--add {
  background: var(--border-default);
}

.live-status-bar__plus {
  position: absolute;
  bottom: -2px;
  right: -2px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--gradient-mixed);
  color: #fff;
  font-size: 0.875rem;
  font-weight: 800;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 2px solid var(--bg-surface);
}

.live-status-bar__ring .avatar {
  width: 100%;
  height: 100%;
  border: 2px solid var(--bg-surface);
}

.live-status-bar__label {
  font-size: 0.6875rem;
  font-weight: 600;
  color: var(--text-secondary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}

/* ── YouTube-style Home grid ──────────────────────────────────────────
   Home used to be the same full-bleed one-at-a-time vertical scroller as
   Shorts (TikTok's model). YouTube's actual home page is a browsable grid
   of thumbnail cards instead — this is that grid; Shorts (below/.feed-*)
   keeps the vertical scroller, since that part of YouTube Shorts really
   is a swipe-through player. */

.video-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: var(--space-6) var(--space-4);
  padding: var(--space-4);
  overflow-y: auto;
  flex: 1;
  min-height: 0;
}

.video-card {
  cursor: pointer;
}

/* a video grid inside an ordinary page (Music, Streaming) instead of Home's full-height scroller */
.video-grid--inline {
  padding: 0;
  overflow: visible;
  flex: none;
}

.video-card__thumb-wrap {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: #000;
}

.video-card__thumb-wrap img,
.video-card__thumb-wrap video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.video-card__poster-fallback {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  background: linear-gradient(135deg, #27272a, #09090b);
}

.video-card__frame-capture {
  position: absolute;
  width: 1px !important;
  height: 1px !important;
  opacity: 0;
  pointer-events: none;
}

.video-card__duration {
  position: absolute;
  right: 6px;
  bottom: 6px;
  background: rgba(0,0,0,0.8);
  color: #fff;
  font-size: 0.6875rem;
  font-weight: 600;
  padding: 1px 5px;
  border-radius: var(--radius-xs);
}

/* Centered over a real captured video thumbnail — see _buildPostGridCard in modules/home/index.js. */
.video-card__play-icon {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 40px;
  height: 40px;
  pointer-events: none;
}

.video-card__live-badge {
  position: absolute;
  left: 6px;
  bottom: 6px;
  background: var(--error-500);
  color: #fff;
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  padding: 2px 6px;
  border-radius: var(--radius-xs);
}

.video-card__meta {
  display: flex;
  gap: var(--space-3);
  margin-top: var(--space-3);
}

.video-card__avatar { flex-shrink: 0; }

.video-card__text { flex: 1; min-width: 0; }

.video-card__title {
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--text-primary);
  line-height: 1.35;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  margin-bottom: 2px;
}

.video-card__channel,
.video-card__stats {
  font-size: 0.8125rem;
  color: var(--text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ── Subscribe pill (YouTube's real button, not a "+" bubble) ────────── */
.subscribe-pill {
  flex-shrink: 0;
  padding: 8px 16px;
  border-radius: var(--radius-full);
  border: none;
  background: var(--text-primary);
  color: var(--bg-surface);
  font-weight: 600;
  font-size: 0.8125rem;
  cursor: pointer;
  white-space: nowrap;
}
.subscribe-pill[data-following="true"] {
  background: var(--bg-elevated);
  color: var(--text-primary);
  border: 1px solid var(--border-default);
}
/* On a dark video background (the Shorts rail) the pill needs to stay
   legible regardless of the light/dark app theme underneath it. */
.subscribe-pill--on-dark {
  background: #fff;
  color: #0f0f0f;
}
.subscribe-pill--on-dark[data-following="true"] {
  background: rgba(255,255,255,0.15);
  color: #fff;
  border: 1px solid rgba(255,255,255,0.4);
}

/* ── Watch overlay — clicking a Home grid card opens this, YouTube's own
   watch-page layout (player, then title/channel/actions/comments below)
   simplified to fit this app (no related-videos sidebar). ────────────── */
.watch-overlay {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  background: var(--bg-base);
  overflow-y: auto;
  animation: page-fade-in 150ms var(--ease-out) forwards;
}

.watch-overlay__header {
  position: sticky;
  top: 0;
  z-index: 1;
  display: flex;
  align-items: center;
  padding: var(--space-3) var(--space-4);
  background: var(--bg-surface);
  border-bottom: 1px solid var(--border-subtle);
}

.watch-overlay__close {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: none;
  background: transparent;
  color: var(--text-primary);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}
.watch-overlay__close:hover { background: var(--bg-elevated); }

.watch-overlay__player-wrap {
  width: 100%;
  background: #000;
  max-height: 70vh;
  display: flex;
  align-items: center;
  justify-content: center;
}
.watch-overlay__player-wrap video,
.watch-overlay__player-wrap img {
  width: 100%;
  max-height: 70vh;
  object-fit: contain;
}

.watch-overlay__body {
  max-width: 900px;
  margin: 0 auto;
  width: 100%;
  padding: var(--space-5) var(--space-4) var(--space-10);
}

.watch-overlay__title {
  font-size: 1.25rem;
  font-weight: 700;
  color: var(--text-primary);
  margin-bottom: var(--space-4);
}

.watch-overlay__channel-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
  flex-wrap: wrap;
}

.watch-overlay__channel-name {
  font-weight: 600;
  color: var(--text-primary);
  cursor: pointer;
}

.watch-overlay__actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-left: auto;
}

.watch-overlay__action-group {
  display: flex;
  align-items: center;
  background: var(--bg-elevated);
  border-radius: var(--radius-full);
  overflow: hidden;
}

.watch-overlay__action-btn {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  border: none;
  background: none;
  color: var(--text-primary);
  cursor: pointer;
  font-size: 0.8125rem;
  font-weight: 600;
}
.watch-overlay__action-group .watch-overlay__action-btn:first-child { border-right: 1px solid var(--border-default); }
.watch-overlay__action-btn svg { width: 20px; height: 20px; }

.watch-overlay__caption {
  background: var(--bg-elevated);
  border-radius: var(--radius-lg);
  padding: var(--space-3) var(--space-4);
  font-size: 0.875rem;
  color: var(--text-primary);
  margin-bottom: var(--space-5);
  white-space: pre-wrap;
}

.watch-overlay__comments-title {
  font-weight: 700;
  margin-bottom: var(--space-4);
}

.watch-overlay__comment-form {
  display: flex;
  gap: var(--space-2);
  margin-bottom: var(--space-5);
}

.watch-overlay__comments-list > div { margin-bottom: var(--space-3); }

/* ── Watch page (modules/_shared/watchPage.js) — the YouTube layout, used by videos, movies AND songs ── */

.watch-page {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-6);
  max-width: 1500px;
  margin: 0 auto;
  padding: var(--space-4);
}
@media (min-width: 1000px) {
  .watch-page { grid-template-columns: minmax(0, 1fr) 400px; }
}

.watch-page__main { min-width: 0; }

.watch-page__player {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  background: #000;
  border-radius: var(--radius-lg);
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}
.watch-page__player > video { width: 100%; height: 100%; object-fit: contain; background: #000; }

.watch-page__below-player { margin-top: var(--space-3); }

.watch-page__title {
  font-size: 1.25rem;
  font-weight: 700;
  line-height: 1.35;
  margin: var(--space-3) 0 var(--space-3);
  color: var(--text-primary);
  overflow-wrap: anywhere;
}

.watch-page__channel-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3) var(--space-4);
  flex-wrap: wrap;
  margin-bottom: var(--space-3);
}
.watch-page__channel { display: flex; align-items: center; gap: var(--space-3); min-width: 0; }
.watch-page__avatar { flex-shrink: 0; }
.watch-page__channel-text { min-width: 0; }
.watch-page__channel-name { font-weight: 600; color: var(--text-primary); cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 220px; }
.watch-page__subs { font-size: 0.75rem; color: var(--text-muted); }

.watch-page__pills { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }

.watch-pill-group { display: inline-flex; align-items: center; background: var(--bg-elevated); border-radius: var(--radius-full); overflow: hidden; }
.watch-pill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 14px;
  border: none; background: none; color: var(--text-primary);
  font-size: 0.8125rem; font-weight: 600; cursor: pointer;
  white-space: nowrap;
}
.watch-pill:hover { background: var(--bg-overlay); }
.watch-pill svg { width: 20px; height: 20px; flex-shrink: 0; }
.watch-pill-group .watch-pill:first-child { border-right: 1px solid var(--border-default); }
.watch-pill--solo { background: var(--bg-elevated); border-radius: var(--radius-full); }
.watch-pill--icon { padding: 8px 10px; }
.watch-pill[data-on="true"] { color: var(--primary-400, var(--text-primary)); }

.watch-menu { position: relative; }
.watch-menu__list {
  position: absolute; right: 0; top: calc(100% + 6px); z-index: var(--z-dropdown, 50);
  min-width: 220px; padding: var(--space-2) 0;
  background: var(--bg-surface); border: 1px solid var(--border-default); border-radius: var(--radius-lg);
  box-shadow: 0 8px 24px rgba(0,0,0,0.25);
}
.watch-menu__list[hidden] { display: none; }
.watch-menu__item {
  display: block; width: 100%; text-align: left;
  padding: 10px var(--space-4); border: none; background: none;
  color: var(--text-primary); font-size: 0.875rem; cursor: pointer;
}
.watch-menu__item:hover { background: var(--bg-elevated); }

.watch-page__description {
  background: var(--bg-elevated);
  border-radius: var(--radius-lg);
  padding: var(--space-3) var(--space-4);
  margin-bottom: var(--space-5);
  font-size: 0.875rem;
  color: var(--text-primary);
}
.watch-page__description-meta { font-weight: 600; margin-bottom: 4px; }
.watch-page__description-details { color: var(--text-secondary); margin-bottom: 4px; }
.watch-page__description-text {
  white-space: pre-wrap; overflow-wrap: anywhere;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.watch-page__description[data-open="true"] .watch-page__description-text { display: block; -webkit-line-clamp: unset; overflow: visible; }
.watch-page__more { border: none; background: none; color: var(--text-muted); font-weight: 600; font-size: 0.8125rem; cursor: pointer; padding: 4px 0 0; }
.watch-page__more[hidden] { display: none; }

.watch-comments__head { display: flex; align-items: center; gap: var(--space-5); margin-bottom: var(--space-4); flex-wrap: wrap; }
.watch-comments__count { font-size: 1.125rem; font-weight: 700; margin: 0; }
.watch-comments__sort { display: inline-flex; align-items: center; gap: var(--space-2); font-size: 0.8125rem; font-weight: 600; color: var(--text-secondary); }
.watch-comments__sort select { width: auto; padding: 4px 8px; font-size: 0.8125rem; }
.watch-comments__form { display: flex; align-items: center; gap: var(--space-3); margin-bottom: var(--space-5); }
.watch-comments__form .form-input { flex: 1; min-width: 0; }
.watch-comments__me { flex-shrink: 0; }
.watch-comments__list { display: flex; flex-direction: column; gap: var(--space-4); }
.watch-comment { display: flex; gap: var(--space-3); }
.watch-comment__avatar { flex-shrink: 0; }
.watch-comment__body { min-width: 0; }
.watch-comment__author { font-weight: 600; font-size: 0.8125rem; }
.watch-comment__time { font-size: 0.75rem; color: var(--text-muted); margin-left: 4px; }
.watch-comment__text { font-size: 0.875rem; white-space: pre-wrap; overflow-wrap: anywhere; }

/* right rail — "Next", filter chips, related list */
.watch-page__rail { min-width: 0; }
.watch-rail__label { font-weight: 700; font-size: 0.875rem; margin-bottom: var(--space-2); }
.watch-rail__next { margin-bottom: var(--space-3); padding-bottom: var(--space-3); border-bottom: 1px solid var(--border-subtle); }
.watch-rail__chips { display: flex; gap: var(--space-2); overflow-x: auto; margin-bottom: var(--space-3); scrollbar-width: none; }
.watch-rail__chips::-webkit-scrollbar { display: none; }
.watch-rail__list { display: flex; flex-direction: column; gap: var(--space-3); }
.watch-rail__empty { padding: var(--space-4) 0; }

.watch-rail-card { display: flex; gap: var(--space-3); color: inherit; text-decoration: none; cursor: pointer; }
.watch-rail-card__thumb {
  position: relative; flex: 0 0 168px; aspect-ratio: 16 / 9;
  border-radius: var(--radius-md); overflow: hidden; background: #000;
  display: flex; align-items: center; justify-content: center;
}
.watch-rail-card__icon { display: inline-flex; width: 28px; height: 28px; color: rgba(255,255,255,0.7); }
.watch-rail-card__icon svg { width: 100%; height: 100%; }
.watch-rail-card__text { min-width: 0; flex: 1; }
.watch-rail-card__title {
  font-size: 0.875rem; font-weight: 600; line-height: 1.3; color: var(--text-primary);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; margin-bottom: 2px;
}
.watch-rail-card__meta { font-size: 0.75rem; color: var(--text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* a song's player stage — same 16:9 box as a video */
.watch-audio { position: relative; width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; background: linear-gradient(135deg, #1f1147, #0b0b16); }
.watch-audio__art { position: absolute; inset: 0; background-size: cover; background-position: center; filter: blur(28px) brightness(0.55); transform: scale(1.15); }
.watch-audio__cover { position: relative; height: 62%; aspect-ratio: 1; border-radius: var(--radius-lg); overflow: hidden; box-shadow: 0 12px 40px rgba(0,0,0,0.5); margin-bottom: 44px; background: linear-gradient(135deg, #EC4899, #7C3AED); display: flex; align-items: center; justify-content: center; }
.watch-audio__cover img { width: 100%; height: 100%; object-fit: cover; }
.watch-audio__note { width: 42%; color: rgba(255,255,255,0.8); }
.watch-audio__controls { position: absolute; left: 0; right: 0; bottom: 0; width: 100%; height: 44px; }
.watch-audio__missing { position: absolute; bottom: var(--space-4); color: rgba(255,255,255,0.7); font-size: 0.875rem; }

@media (max-width: 999px) {
  .watch-page { padding: 0 0 var(--space-6); gap: var(--space-4); }
  .watch-page__player { border-radius: 0; }
  .watch-page__main > *:not(.watch-page__player) { margin-left: var(--space-4); margin-right: var(--space-4); }
  .watch-page__rail { padding: 0 var(--space-4); }
}

/* ── Shorts branding badge — top-left, immersive player only ─────────── */
.shorts-badge {
  position: fixed;
  top: calc(var(--topbar-height) + var(--space-3));
  left: var(--space-4);
  z-index: var(--z-sticky);
  display: flex;
  align-items: center;
  gap: 6px;
  color: #fff;
  font-weight: 700;
  font-size: 1.0625rem;
  text-shadow: 0 1px 3px rgba(0,0,0,0.5);
}
.shorts-badge svg { width: 24px; height: 24px; }

/* ── Calendar icon on every scheduling input, app-wide ────────────────
   A single global rule instead of editing every module's own "schedule
   for" form (Concerts, Movies, Podcast, Battlesphere, Sports, Streaming,
   AI Studio, ...) — a consistent calendar glyph on the left makes every
   date+time picker in the app read the same way. Left side only: the
   browser's own native picker control already sits on the right of a
   datetime-local input and still works exactly as before. */
input[type="datetime-local"].form-input {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23909090' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2'/%3E%3Cline x1='16' y1='2' x2='16' y2='6'/%3E%3Cline x1='8' y1='2' x2='8' y2='6'/%3E%3Cline x1='3' y1='10' x2='21' y2='10'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: left 12px center;
  background-size: 18px 18px;
  padding-left: 40px;
}

/* ── Owner controls (hide / delete dialogs, My content) ─────────────────── */
.cc-dialog {
  position: fixed; inset: 0; z-index: 10000; display: flex; align-items: center; justify-content: center;
  padding: var(--space-4); background: rgba(0, 0, 0, 0.55);
}
.cc-dialog__card {
  width: 100%; max-width: 440px; max-height: 90vh; overflow-y: auto;
  background: var(--bg-surface); color: var(--text-primary); border-radius: var(--radius-lg);
  padding: var(--space-5); box-shadow: 0 16px 48px rgba(0, 0, 0, 0.35);
}
.cc-dialog__title { font-size: 1.125rem; font-weight: 700; margin: 0 0 var(--space-3); }
.cc-dialog__option { display: flex; gap: var(--space-3); align-items: flex-start; padding: var(--space-3) 0; cursor: pointer; }
.cc-dialog__option input { margin-top: 4px; }
.cc-dialog__actions { display: flex; justify-content: flex-end; gap: var(--space-2); margin-top: var(--space-4); }
.cc-dialog__error { margin-top: var(--space-3); }

.mc-row { display: flex; gap: var(--space-3); align-items: flex-start; padding: var(--space-3) 0; border-top: 1px solid var(--border-subtle); }
.mc-row:first-child { border-top: none; }
.mc-thumb { flex: 0 0 96px; aspect-ratio: 16 / 9; border-radius: var(--radius-md); overflow: hidden; background: var(--bg-elevated); display: flex; align-items: center; justify-content: center; color: var(--text-muted); font-size: 0.75rem; }
.mc-thumb img { width: 100%; height: 100%; object-fit: cover; }
.mc-main { flex: 1; min-width: 0; }
.mc-title { font-weight: 600; font-size: 0.9375rem; overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; word-break: break-word; }
.mc-actions { display: flex; gap: var(--space-2); flex-wrap: wrap; margin-top: var(--space-2); align-items: center; }
.mc-notice { padding: var(--space-3); border-radius: var(--radius-md); background: var(--bg-elevated); margin-bottom: var(--space-2); font-size: 0.875rem; }
.mc-notice--unread { border-left: 3px solid var(--primary-500, #2563EB); }
@media (max-width: 480px) { .mc-thumb { flex-basis: 72px; } }

/* ── Channel page (YouTube-style) ───────────────────────────────────────── */
.ch-page { max-width: 1000px; margin: 0 auto; padding: 0 var(--space-4) var(--space-8); position: relative; }
.ch-back { position: absolute; top: var(--space-2); left: var(--space-6); z-index: 2; width: 36px; height: 36px; border-radius: 50%; border: none; background: rgba(0,0,0,0.45); color: #fff; display: flex; align-items: center; justify-content: center; cursor: pointer; }
.ch-banner { margin: 0 calc(-1 * var(--space-4)) 0; aspect-ratio: 16 / 5; max-height: 220px; border-radius: 0; background: var(--gradient-mixed, linear-gradient(135deg,#2563EB,#22C55E)) center / cover no-repeat; }
.ch-header { display: flex; gap: var(--space-4); align-items: flex-end; margin-top: 0; position: relative; }
.ch-avatar { flex: 0 0 auto; margin-top: -56px; position: relative; z-index: 1; }
.ch-avatar .avatar { width: 112px; height: 112px; font-size: 2.25rem; border: 3px solid var(--bg-base); }
.ch-info { min-width: 0; }
.ch-name { font-size: 1.5rem; font-weight: 700; line-height: 1.2; margin: 0 0 4px; word-break: break-word; }
.ch-meta { font-size: 0.875rem; color: var(--text-muted); margin-top: 2px; }
.ch-handle { color: var(--text-primary); font-weight: 500; }
.ch-bio { margin-top: var(--space-4); font-size: 0.9375rem; color: var(--text-secondary, var(--text-muted)); }
.ch-bio__text { white-space: pre-wrap; word-break: break-word; }
.ch-bio__text--clamped { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.ch-bio__more { background: none; border: none; padding: 0; margin-top: 2px; color: var(--text-primary); font-weight: 600; cursor: pointer; font-size: 0.875rem; }
.ch-actions { display: flex; gap: var(--space-2); flex-wrap: wrap; margin-top: var(--space-4); }
.ch-pill { display: inline-flex; align-items: center; gap: 8px; height: 36px; padding: 0 var(--space-4); border-radius: 18px; border: none; background: var(--bg-elevated); color: var(--text-primary); font-size: 0.875rem; font-weight: 600; cursor: pointer; white-space: nowrap; }
.ch-pill--primary { background: var(--text-primary); color: var(--bg-surface, #fff); }
.ch-pill:disabled { opacity: 0.6; }
.ch-tabs { display: flex; gap: var(--space-5); margin-top: var(--space-5); border-bottom: 1px solid var(--border-subtle); overflow-x: auto; scrollbar-width: none; }
.ch-tabs::-webkit-scrollbar { display: none; }
.ch-tab { background: none; border: none; border-bottom: 2px solid transparent; padding: var(--space-3) 0; font-size: 0.9375rem; font-weight: 600; color: var(--text-muted); cursor: pointer; white-space: nowrap; }
.ch-tab--active { color: var(--text-primary); border-bottom-color: var(--text-primary); }
.ch-content { padding-top: var(--space-4); }
.ch-empty { color: var(--text-muted); padding: var(--space-6) 0; }
.ch-section { margin-bottom: var(--space-6); }
.ch-section__title { background: none; border: none; padding: 0; margin-bottom: var(--space-3); font-size: 1.25rem; font-weight: 700; color: var(--text-primary); cursor: pointer; }
.ch-videos { display: flex; flex-direction: column; gap: var(--space-4); }
.ch-video { display: flex; gap: var(--space-3); align-items: flex-start; cursor: pointer; margin-bottom: var(--space-4); }
.ch-videos .ch-video { margin-bottom: 0; }
.ch-video__thumb { position: relative; flex: 0 0 42%; max-width: 190px; aspect-ratio: 16 / 9; border-radius: var(--radius-md); overflow: hidden; background: #111; }
.ch-video__thumb img, .ch-video__thumb video { width: 100%; height: 100%; object-fit: cover; display: block; }
.ch-video__thumb--music { background: linear-gradient(135deg,#EC4899,#7C3AED); display: flex; align-items: center; justify-content: center; color: rgba(255,255,255,0.85); font-size: 1.75rem; }
.ch-video__thumb--live { background: linear-gradient(135deg,#EF4444,#7C3AED); }
.ch-live-badge { position: absolute; left: 6px; top: 6px; background: #EF4444; color: #fff; font-size: 0.6875rem; font-weight: 700; padding: 2px 6px; border-radius: 4px; }
.ch-duration { position: absolute; right: 6px; bottom: 6px; background: rgba(0,0,0,0.8); color: #fff; font-size: 0.75rem; font-weight: 600; padding: 1px 5px; border-radius: 4px; }
.ch-video__text { flex: 1; min-width: 0; }
.ch-video__title { font-size: 1rem; font-weight: 600; line-height: 1.3; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; word-break: break-word; }
.ch-video__meta { font-size: 0.8125rem; color: var(--text-muted); margin-top: 4px; }
.ch-video__more { background: none; border: none; color: var(--text-primary); cursor: pointer; padding: 4px; border-radius: 50%; flex: 0 0 auto; }
.ch-shorts { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: var(--space-3); }
.ch-shorts--scroll { display: flex; overflow-x: auto; gap: var(--space-3); padding-bottom: var(--space-2); scrollbar-width: none; }
.ch-shorts--scroll .ch-short { flex: 0 0 140px; }
.ch-short { position: relative; aspect-ratio: 9 / 16; border-radius: var(--radius-md); overflow: hidden; background: #111; cursor: pointer; }
.ch-short video, .ch-short img { width: 100%; height: 100%; object-fit: cover; display: block; }
.ch-short__title { position: absolute; left: 0; right: 0; bottom: 0; padding: 24px 8px 8px; color: #fff; font-size: 0.8125rem; font-weight: 600; background: linear-gradient(transparent, rgba(0,0,0,0.75)); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.ch-post { margin-bottom: var(--space-3); }
.ch-post__img { width: 100%; max-height: 360px; object-fit: cover; border-radius: var(--radius-md); margin-bottom: var(--space-2); }
.ch-about { display: flex; flex-direction: column; gap: var(--space-3); max-width: 640px; }
.ch-about__row { font-size: 0.9375rem; }
.video-card__avatar[data-channel-id] .avatar, .video-card__avatar .avatar { flex-shrink: 0; }
@media (min-width: 720px) {
  .ch-avatar { margin-top: -75px; }
  .ch-avatar .avatar { width: 160px; height: 160px; font-size: 3.125rem; }
  .ch-name { font-size: 2rem; }
  .ch-videos { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-5) var(--space-4); }
  .ch-videos .ch-video { flex-direction: column; }
  .ch-videos .ch-video__thumb { flex: none; max-width: none; width: 100%; }
  .ch-back { left: var(--space-6); }
}

/* ── WhatsApp-style chat (DM) ───────────────────────────────────────────
   GrooVVee colours: deep-blue header, pale-blue wallpaper, white incoming / blue outgoing bubbles, with the logo's yellow and orange for accents (online dot, read ticks, call icons, mic/send, unread badge) with a tail on the
   first bubble of each run, times + ticks inside the bubble, "TODAY" date chips, a white pill input and a round
   orange mic/send button. Scoped to .wa-chat so the group/room chats keep their own look. */
.dm-chat-pane.wa-chat {
  background-color: #eaf1ff;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220' viewBox='0 0 220 220' fill='none' stroke='%23000' stroke-opacity='0.055' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='30' cy='34' r='9'/%3E%3Cpath d='M92 30l5 10 11 1-8 8 2 11-10-5-10 5 2-11-8-8 11-1z'/%3E%3Cpath d='M160 40c-6-10-20-4-14 6l14 14 14-14c6-10-8-16-14-6z'/%3E%3Cpath d='M28 100h22M39 89v22'/%3E%3Crect x='88' y='92' width='24' height='18' rx='4'/%3E%3Ccircle cx='168' cy='100' r='11'/%3E%3Cpath d='M30 168c8-12 16 12 24 0'/%3E%3Cpath d='M98 160l14 20M112 160L98 180'/%3E%3Cpath d='M158 160h24v20h-24z'/%3E%3C/svg%3E");
  background-size: 220px 220px;
}
.wa-chat .dm-chat-pane__header { display: none; }

.wa-header {
  display: flex; align-items: center; gap: 2px;
  height: 56px; padding: 0 4px; flex-shrink: 0;
  background: linear-gradient(100deg, #1e3a8a 0%, #2563eb 100%); color: #fff; box-shadow: 0 2px 8px rgba(30, 58, 138, 0.35); position: relative; z-index: 2;
}
.wa-back {
  display: none; width: 40px; height: 40px; border: none; background: transparent; color: #fff;
  border-radius: 50%; align-items: center; justify-content: center; flex-shrink: 0; cursor: pointer;
}
.wa-who { flex: 1; min-width: 0; display: flex; align-items: center; gap: 10px; cursor: pointer; padding: 0 4px; }
.wa-avatar { position: relative; flex-shrink: 0; display: inline-flex; }
.wa-avatar .avatar { width: 40px; height: 40px; font-size: 0.9rem; border: 2px solid #ffc61a; }
.wa-avatar-dot { position: absolute; bottom: 0; right: 0; width: 11px; height: 11px; background: #facc15; border-radius: 50%; border: 2px solid #1e3a8a; }
.wa-name { font-size: 18px; font-weight: 500; line-height: 1.2; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.wa-status { font-size: 13px; line-height: 1.2; color: rgba(255, 255, 255, 0.82); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.wa-actions { display: flex; align-items: center; flex-shrink: 0; position: relative; }
.wa-icon-btn {
  width: 42px; height: 42px; border: none; background: transparent; color: #fff; border-radius: 50%;
  display: flex; align-items: center; justify-content: center; cursor: pointer;
}
.wa-icon-btn:active { background: rgba(255, 255, 255, 0.18); }
.wa-menu {
  position: absolute; right: 4px; top: 48px; z-index: 5; min-width: 190px; padding: 8px 0;
  background: #fff; color: #111b21; border-radius: 6px; box-shadow: 0 2px 12px rgba(11, 20, 26, 0.3);
}
.wa-menu[hidden] { display: none; }
.wa-menu button { display: block; width: 100%; text-align: left; padding: 12px 18px; border: none; background: none; font-size: 16px; color: #111b21; cursor: pointer; }
.wa-menu button:hover { background: #eaf1ff; }

.wa-list {
  flex: 1; min-height: 0; overflow-y: auto; display: flex; flex-direction: column;
  justify-content: safe flex-end; padding: 8px 10px; gap: 2px; overscroll-behavior: contain;
}
.wa-date { align-self: center; margin: 10px 0 6px; padding: 5px 14px; background: #fff; color: #1e40af; font-size: 12px; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; border-radius: 999px; box-shadow: 0 1px 3px rgba(30, 58, 138, 0.15); flex-shrink: 0; }
.wa-empty { align-self: center; margin: 24px 0; padding: 6px 14px; background: #fff; color: #1e40af; font-size: 13px; border-radius: 999px; box-shadow: 0 1px 3px rgba(30, 58, 138, 0.15); }
.wa-row { display: flex; flex-shrink: 0; }
.wa-row--out { justify-content: flex-end; }
.wa-row--first { margin-top: 6px; }

.wa-bubble {
  position: relative; max-width: 80%; padding: 7px 10px 8px 11px; border-radius: 16px;
  font-size: 15px; line-height: 1.35; color: #111b21; overflow-wrap: anywhere; white-space: pre-wrap;
  box-shadow: 0 1px 2px rgba(30, 58, 138, 0.16);
}
.wa-bubble--in { background: #fff; }
.wa-bubble--out { background: #2563eb; color: #fff; }
.wa-bubble--in.wa-bubble--tail { border-top-left-radius: 4px; }
.wa-bubble--out.wa-bubble--tail { border-top-right-radius: 4px; }
.wa-bubble--tail::before { content: ''; position: absolute; top: 0; width: 8px; height: 13px; }
.wa-bubble--in.wa-bubble--tail::before { left: -8px; background: #fff; clip-path: polygon(100% 0, 0 0, 100% 100%); }
.wa-bubble--out.wa-bubble--tail::before { right: -8px; background: #2563eb; clip-path: polygon(0 0, 100% 0, 0 100%); }
.wa-time { float: right; margin: 7px 0 -3px 10px; display: inline-flex; align-items: center; gap: 3px; font-size: 11px; line-height: 1; color: #667781; white-space: nowrap; user-select: none; }
.wa-tick { display: inline-flex; width: 16px; height: 11px; }
.wa-bubble--out .wa-time { color: rgba(255, 255, 255, 0.78); }
.wa-bubble--out .wa-tick--read { color: #ffd23f; }
.wa-tick--read { color: #d97706; }
.wa-media { margin: -3px -5px 4px; border-radius: 6px; overflow: hidden; max-width: 260px; }
.wa-media img, .wa-media video { display: block; width: 100%; max-height: 300px; object-fit: cover; }
.wa-bubble--voice { display: flex; align-items: center; gap: 8px; min-width: 210px; padding-right: 10px; }
.wa-sticker { font-size: 3.25rem; line-height: 1.1; padding: 0 4px; }
.wa-sticker-time { font-size: 11px; color: #667781; text-align: right; padding: 0 6px; }

.wa-call {
  align-self: center; display: flex; align-items: center; gap: 12px; margin: 6px 0; padding: 8px 14px 8px 10px;
  background: #fff; border-radius: 14px; border-left: 4px solid #ffc61a; box-shadow: 0 1px 3px rgba(30, 58, 138, 0.15); max-width: 86%; flex-shrink: 0;
}
.wa-call__icon { width: 38px; height: 38px; border-radius: 50%; background: #fff1b8; color: #1d4ed8; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.wa-call--missed { border-left-color: #ea0038; }
.wa-call--missed .wa-call__icon { background: #fde4e4; color: #ea0038; }
.wa-call__title { font-size: 15px; color: #111b21; line-height: 1.3; }
.wa-call--missed .wa-call__title { color: #ea0038; }
.wa-call__sub { font-size: 13px; color: #667781; line-height: 1.3; }
.wa-call__time { font-size: 11px; color: #667781; align-self: flex-end; }

/* input bar */
.wa-input { flex-shrink: 0; padding: 6px 8px calc(8px + env(safe-area-inset-bottom, 0px)); position: relative; }
.wa-input__row { display: flex; align-items: flex-end; gap: 6px; }
.wa-pill { flex: 1; min-width: 0; min-height: 48px; display: flex; align-items: center; gap: 0; padding: 0 4px; background: #fff; border-radius: 24px; border: 1.5px solid #bfd3fb; box-shadow: 0 1px 3px rgba(30, 58, 138, 0.12); }
.wa-pill:focus-within { border-color: #2563eb; }
.wa-pill__btn { width: 40px; height: 44px; border: none; background: transparent; color: #2563eb; display: flex; align-items: center; justify-content: center; flex-shrink: 0; cursor: pointer; border-radius: 50%; }
.wa-pill__input { flex: 1; min-width: 0; border: none; outline: none; background: transparent; font-size: 16px; color: #111b21; padding: 10px 2px; }
.wa-pill__input::placeholder { color: #667781; }
.wa-fab { width: 48px; height: 48px; border: none; border-radius: 50%; background: linear-gradient(135deg, #ffc61a, #ff9f1c); color: #18181b; display: flex; align-items: center; justify-content: center; flex-shrink: 0; cursor: pointer; box-shadow: 0 2px 6px rgba(224, 122, 0, 0.45); }
.wa-fab[hidden] { display: none; }
.wa-fab.rci-mic-btn--recording { background: #ea0038; }
.wa-panel { display: flex; flex-wrap: wrap; gap: 2px; margin: 0 0 6px; padding: 8px; background: #fff; border-radius: 12px; box-shadow: 0 1px 2px rgba(11, 20, 26, 0.2); max-height: 220px; overflow-y: auto; }
.wa-panel[hidden] { display: none; }
.wa-panel__label { width: 100%; font-size: 12px; color: #667781; text-transform: uppercase; padding: 2px 4px; }

/* phone: the open chat is a full screen, like WhatsApp — no top bar, no bottom tabs */
@media (max-width: 767px) {
  .dm-layout--chat-open { position: fixed; inset: 0; z-index: var(--z-modal, 300); height: 100vh; height: 100dvh; max-height: none; border-radius: 0; }
  .dm-layout--chat-open .dm-chat-pane { width: 100%; }
  .wa-back { display: flex; }
  .wa-bubble { font-size: 16px; }
}
/* .page-enter leaves a transform on #main-content, which would trap position:fixed inside it */
#main-content:has(.dm-layout--chat-open),
.page-enter:has(.dm-layout--chat-open) { transform: none !important; animation: none !important; }
@media (min-width: 768px) {
  .wa-bubble { font-size: 14.5px; }
  .wa-pill__input { font-size: 15px; }
}

/* conversation list, WhatsApp-style */
.dm-conv-item { gap: 14px; padding: 10px 16px; }
.dm-conv-item .avatar { width: 49px; height: 49px; font-size: 1rem; }
.dm-conv-item__name { font-size: 1.0625rem; font-weight: 500; }
.dm-conv-item__preview { font-size: 0.875rem; margin-top: 2px; }
.dm-conv-item__time { font-size: 0.75rem; }
.dm-conv-item__meta { gap: 5px; }
.dm-conv-item__badge { min-width: 20px; height: 20px; padding: 0 5px; background: #ff9f1c; color: #18181b; font-weight: 700; font-size: 0.75rem; }
.dm-conv-item__preview--unread { color: var(--text-primary); font-weight: 600; }
.dm-conv-item .avatar { border: 2px solid #bfd3fb; }
.dm-conv-item:hover { background: #eef4ff; }
.dm-conv-item__time { color: #2563eb; }

/* ── Live, the YouTube way ───────────────────────────────────────────────
   Watch page: 16:9 player, title, channel row with Subscribe, Like / Share, "N watching now" box, and the live chat
   in its own column on the right (under the video on a phone, where the whole page is full screen). Live home: the
   same video cards as the rest of the app with a red LIVE badge. */
.avatar--xs { width: 24px; height: 24px; font-size: 0.625rem; border-width: 0; }

.yt-live-home__heading { font-size: 1.25rem; font-weight: 700; margin: var(--space-6) 0 var(--space-4); }
.yt-live-thumb { background: linear-gradient(135deg, #27272a, #09090b); display: flex; align-items: center; justify-content: center; color: rgba(255, 255, 255, 0.8); }
.yt-live-thumb__art { display: flex; align-items: center; justify-content: center; }
.yt-live-thumb__art .avatar { width: 72px; height: 72px; font-size: 1.5rem; border: 2px solid rgba(255, 255, 255, 0.25); }
.yt-live-thumb .video-card__live-badge { left: auto; right: 8px; bottom: 8px; display: inline-flex; align-items: center; gap: 4px; }
.yt-live-thumb .video-card__live-badge::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: #fff; }

.yt-live { display: grid; grid-template-columns: minmax(0, 1fr) 400px; gap: 24px; align-items: start; max-width: 1500px; margin: 0 auto; padding: 16px 24px 32px; }
.yt-live__main { min-width: 0; }
.yt-live__player { position: relative; aspect-ratio: 16 / 9; background: #000; border-radius: 12px; overflow: hidden; }
.yt-live__media { position: absolute; inset: 0; }
.yt-live__media video { width: 100%; height: 100%; object-fit: contain; background: #000; display: block; }
.yt-live__placeholder { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--space-2); color: rgba(255, 255, 255, 0.6); }
.yt-live__overlay { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--space-2); background: rgba(0, 0, 0, 0.75); color: #fff; z-index: 3; }
.yt-live__overlay[hidden] { display: none; }
.yt-live__unmute { position: absolute; bottom: 44px; left: 12px; z-index: 2; display: flex; align-items: center; gap: 6px; padding: 6px 12px; border-radius: var(--radius-full); border: none; background: rgba(0, 0, 0, 0.65); color: #fff; cursor: pointer; font-size: 0.8125rem; }
.yt-live__unmute[hidden] { display: none; }
.yt-live__back { position: absolute; top: 8px; left: 8px; z-index: 4; width: 36px; height: 36px; border: none; border-radius: 50%; background: rgba(0, 0, 0, 0.5); color: #fff; display: flex; align-items: center; justify-content: center; cursor: pointer; }
.yt-live__back svg { width: 20px; height: 20px; }
.yt-live__badge { position: absolute; left: 12px; bottom: 12px; z-index: 2; display: inline-flex; align-items: center; gap: 5px; background: var(--error-500); color: #fff; font-size: 0.75rem; font-weight: 700; letter-spacing: 0.03em; padding: 3px 8px; border-radius: 4px; border: none; animation: none; }
.yt-live__badge svg { fill: #fff; }
.yt-live__badge.badge--neutral { background: rgba(0, 0, 0, 0.7); }

.yt-live__title { font-size: 1.25rem; font-weight: 600; line-height: 1.3; margin: 12px 0 8px; flex: 1; word-break: break-word; }
.yt-live__meta { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 12px 16px; margin-bottom: 12px; }
.yt-live__channel { display: flex; align-items: center; gap: 12px; min-width: 0; }
.yt-live__actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.yt-live__desc { margin-bottom: 12px; }
.yt-live__reactions { margin-bottom: 8px; }
.yt-live__controls { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding: 12px; background: var(--bg-elevated); border-radius: 12px; margin-top: 12px; }

.yt-live__chat { display: flex; flex-direction: column; height: min(calc(100vh - 110px), 720px); min-height: 360px; position: sticky; top: 16px; background: var(--bg-surface); border: 1px solid var(--border-default); border-radius: 12px; overflow: hidden; }
.yt-live__chat-head { padding: 12px 16px; font-weight: 600; font-size: 0.9375rem; border-bottom: 1px solid var(--border-default); flex-shrink: 0; }
.yt-live__chat-list { flex: 1; min-height: 0; overflow-y: auto; padding: 8px 12px; display: flex; flex-direction: column; justify-content: safe flex-end; gap: 2px; overscroll-behavior: contain; }
.yt-live__chat-empty { color: var(--text-muted); font-size: 0.8125rem; text-align: center; padding: var(--space-4); }
.yt-live__chat-foot { flex-shrink: 0; border-top: 1px solid var(--border-default); padding: 8px 12px 12px; }

.yt-chat-msg { display: flex; gap: 12px; align-items: flex-start; padding: 4px 0; font-size: 0.8125rem; line-height: 1.45; flex-shrink: 0; }
.yt-chat-msg__avatar { flex-shrink: 0; margin-top: 1px; }
.yt-chat-msg__body { min-width: 0; overflow-wrap: anywhere; }
.yt-chat-msg__name { color: var(--text-muted); font-weight: 500; margin-right: 8px; }
.yt-chat-msg--host .yt-chat-msg__name { background: #2563eb; color: #fff; padding: 1px 8px; border-radius: 10px; }
.yt-chat-msg__text { color: var(--text-primary); }
.yt-chat-msg__sticker { font-size: 1.75rem; line-height: 1.2; }
.yt-chat-msg__media { margin-top: 4px; max-width: 200px; border-radius: 8px; overflow: hidden; }

.yt-chat-input__who { display: flex; align-items: center; gap: 8px; font-size: 0.8125rem; font-weight: 500; margin-bottom: 8px; color: var(--text-secondary, var(--text-muted)); }
.yt-chat-input__row { display: flex; align-items: center; gap: 6px; }
.yt-chat-input__field { flex: 1; min-width: 0; display: flex; align-items: center; gap: 4px; border-bottom: 2px solid var(--border-default); padding: 2px 4px; }
.yt-chat-input__field:focus-within { border-bottom-color: var(--text-primary); }
.yt-chat-input__field input { flex: 1; min-width: 0; border: none; outline: none; background: transparent; font-size: 0.875rem; color: var(--text-primary); padding: 8px 2px; }
.yt-chat-input__icon, .yt-chat-input__send { width: 36px; height: 36px; border: none; border-radius: 50%; background: transparent; color: var(--text-muted); display: flex; align-items: center; justify-content: center; cursor: pointer; flex-shrink: 0; }
.yt-chat-input__send--on { color: var(--text-primary); }

@media (max-width: 1000px) and (min-width: 768px) {
  .yt-live { grid-template-columns: 1fr; }
  .yt-live__chat { position: static; height: 480px; }
}

/* phone: the whole page is a full screen — player on top, a compact info area, the chat filling the rest */
@media (max-width: 767px) {
  .yt-live { position: fixed; inset: 0; z-index: var(--z-modal, 300); height: 100vh; height: 100dvh; display: flex; flex-direction: column; align-items: stretch; gap: 0; padding: 0; background: var(--bg-base, #fff); overflow: hidden; }
  .yt-live__main { display: contents; }
  .yt-live__player { flex: 0 0 auto; width: 100%; border-radius: 0; }
  .yt-live__info { flex: 0 1 auto; max-height: 34vh; max-height: 34dvh; overflow-y: auto; padding: 0 12px; }
  .yt-live__title { font-size: 1.0625rem; margin: 10px 0 6px; }
  .yt-live__desc { padding: 8px 12px; margin-bottom: 8px; }
  .yt-live__desc #stream-desc-display:empty { display: none; }
  .yt-live__chat { flex: 1 1 0; min-height: 0; height: auto; position: static; border: none; border-top: 1px solid var(--border-default); border-radius: 0; }
  .yt-live__chat-head { padding: 8px 12px; }
  .yt-live__chat-foot { padding: 6px 10px calc(10px + env(safe-area-inset-bottom, 0px)); }
}
#main-content:has(.yt-live), .page-enter:has(.yt-live) { transform: none !important; animation: none !important; }

.yt-live__chat-head { position: relative; display: flex; align-items: center; }
.yt-live__chat-mode { display: inline-flex; align-items: center; gap: 4px; background: none; border: none; padding: 0; font: inherit; font-weight: 600; color: var(--text-primary); cursor: pointer; }
.yt-live__chat-menu { position: absolute; left: 12px; top: 100%; z-index: 6; min-width: 260px; padding: 6px 0; background: var(--bg-surface); border: 1px solid var(--border-default); border-radius: 8px; box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25); }
.yt-live__chat-menu[hidden] { display: none; }
.yt-live__chat-menu button { display: block; width: 100%; text-align: left; padding: 10px 16px; border: none; background: none; color: var(--text-primary); cursor: pointer; }
.yt-live__chat-menu button:hover { background: var(--bg-elevated); }
.yt-live__chat-menu b { display: block; font-weight: 600; font-size: 0.875rem; }
.yt-live__chat-menu small { display: block; color: var(--text-muted); font-size: 0.75rem; margin-top: 1px; }
.yt-live-thumb > img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* ── Live rewind bar and Super Chat ─────────────────────────────────────── */
.yt-live__media video { position: absolute; inset: 0; }
.yt-dvr { position: absolute; left: 0; right: 0; bottom: 0; z-index: 3; display: flex; align-items: center; gap: 10px; padding: 22px 12px 8px; color: #fff; background: linear-gradient(transparent, rgba(0, 0, 0, 0.72)); }
.yt-dvr[hidden] { display: none; }
.yt-dvr button { background: none; border: none; color: #fff; cursor: pointer; display: inline-flex; align-items: center; padding: 4px; }
.yt-dvr input[type="range"] { flex: 1; min-width: 0; accent-color: #ff0000; height: 4px; cursor: pointer; }
.yt-dvr__behind { font-size: 0.75rem; min-width: 38px; text-align: right; font-variant-numeric: tabular-nums; }
.yt-dvr__live { font-size: 0.75rem !important; font-weight: 700; letter-spacing: 0.03em; gap: 6px; }
.yt-dvr__live::before { content: ''; width: 8px; height: 8px; border-radius: 50%; background: #9e9e9e; }
.yt-dvr__live--on::before { background: #ff0000; }
.yt-live__player--dvr .yt-live__badge { display: none; }
.yt-live__player--dvr .yt-live__unmute { bottom: 58px; }

.yt-superchat-btn { color: #f9a825; }
.yt-superchat-btn svg { width: 18px; height: 18px; }
.yt-chat-input__star { color: #f9a825; }
.yt-superchat { margin: 6px 0; border-radius: 8px; overflow: hidden; background: var(--sc-body); color: #fff; flex-shrink: 0; }
.yt-superchat__head { display: flex; align-items: center; gap: 10px; padding: 8px 12px; background: var(--sc-head); }
.yt-superchat__name { font-size: 0.75rem; opacity: 0.85; }
.yt-superchat__amount { font-size: 0.9375rem; font-weight: 700; }
.yt-superchat__body { padding: 8px 12px 10px; font-size: 0.875rem; word-break: break-word; }
.yt-live__pins { display: flex; gap: 8px; overflow-x: auto; padding: 8px 12px; border-bottom: 1px solid var(--border-default); flex-shrink: 0; }
.yt-live__pins[hidden] { display: none; }
.yt-pin { display: inline-flex; align-items: center; gap: 6px; flex-shrink: 0; padding: 4px 10px 4px 4px; border-radius: 16px; background: var(--sc-body); color: #fff; font-size: 0.75rem; }
.yt-pin__name { max-width: 90px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.yt-sc-tiers { display: grid; grid-template-columns: repeat(5, 1fr); gap: 8px; margin-top: var(--space-3); }
.yt-sc-tier { border: 2px solid transparent; border-radius: 10px; padding: 10px 4px; background: var(--sc-head); color: #fff; cursor: pointer; display: flex; flex-direction: column; align-items: center; line-height: 1.1; }
.yt-sc-tier b { font-size: 1rem; }
.yt-sc-tier small { font-size: 0.6875rem; opacity: 0.85; }
.yt-sc-tier:disabled { opacity: 0.35; cursor: not-allowed; }
.yt-sc-tier--on { border-color: var(--text-primary); box-shadow: 0 0 0 2px var(--bg-surface) inset; }

/* ── Podcasts, the YouTube way ──────────────────────────────────────────── */
.pod-cover { position: relative; aspect-ratio: 1; border-radius: 12px; overflow: hidden; background: linear-gradient(135deg, #6d28d9, #db2777); display: flex; align-items: center; justify-content: center; color: rgba(255, 255, 255, 0.92); }
.pod-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pod-cover__mark { font-size: 2.75rem; font-weight: 800; line-height: 1; }
.pod-shows { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 24px 16px; margin-bottom: var(--space-8); }
.pod-show-card { cursor: pointer; min-width: 0; }
.pod-show-card__title { font-weight: 600; font-size: 0.9375rem; margin-top: 8px; line-height: 1.3; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.pod-show-card__meta { font-size: 0.8125rem; color: var(--text-muted); margin-top: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.pod-thumb { position: relative; width: 100%; height: 100%; overflow: hidden; background: #111; display: flex; align-items: center; justify-content: center; }
.pod-thumb__bg { position: absolute; inset: -20px; background-size: cover; background-position: center; filter: blur(18px) brightness(0.65); }
.pod-thumb .pod-thumb__cover { position: relative; height: 80%; width: auto; aspect-ratio: 1; border-radius: 8px; }
.pod-thumb .pod-cover__mark { font-size: 1.75rem; }
.pod-thumb video { width: 100%; height: 100%; object-fit: cover; display: block; }
.pod-badge { display: inline-block; font-size: 0.6875rem; font-weight: 700; letter-spacing: 0.03em; padding: 2px 6px; border-radius: 4px; background: var(--bg-elevated); color: var(--text-primary); }
.pod-badge--soon { position: absolute; left: 8px; bottom: 8px; background: rgba(0, 0, 0, 0.75); color: #fff; }
.pod-badge--paid { background: #f9a825; color: #000; vertical-align: middle; }

.pod-show { display: grid; grid-template-columns: 300px minmax(0, 1fr); gap: 32px; max-width: 1100px; margin: 0 auto; padding: var(--space-4); }
.pod-show__side { position: sticky; top: 16px; align-self: start; }
.pod-show__cover { width: 100%; }
.pod-show__title { font-size: 1.5rem; font-weight: 700; line-height: 1.2; margin: 14px 0 8px; word-break: break-word; }
.pod-show__host { display: inline-flex; align-items: center; gap: 8px; font-weight: 500; cursor: pointer; margin-bottom: 6px; }
.pod-show__stats { font-size: 0.8125rem; color: var(--text-muted); margin-bottom: 14px; }
.pod-show__buttons { display: flex; flex-wrap: wrap; gap: 8px; }
.pod-show__buttons .ch-pill svg { flex-shrink: 0; }
.pod-show__desc { margin-top: 14px; font-size: 0.875rem; color: var(--text-secondary, var(--text-muted)); }
.pod-show__heading { font-size: 1.25rem; font-weight: 700; margin: 0 0 8px; }
.pod-manage { border: 1px solid var(--border-default); border-radius: 12px; margin-bottom: var(--space-5); background: var(--bg-surface); }
.pod-manage > summary { padding: 12px 16px; font-weight: 600; cursor: pointer; }
.pod-manage__body { padding: 0 16px 16px; }

.pod-ep { display: flex; gap: 16px; padding: 12px 0; cursor: pointer; border-bottom: 1px solid var(--border-subtle); }
.pod-ep:last-child { border-bottom: none; }
.pod-ep__thumb { flex: 0 0 200px; aspect-ratio: 16 / 9; border-radius: 10px; overflow: hidden; position: relative; }
.pod-ep__body { flex: 1; min-width: 0; }
.pod-ep__title { font-weight: 600; font-size: 1rem; line-height: 1.3; word-break: break-word; }
.pod-ep__desc { color: var(--text-muted); font-size: 0.8125rem; margin-top: 4px; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.pod-ep__meta { color: var(--text-muted); font-size: 0.75rem; margin-top: 6px; }
.pod-ep__actions { margin-top: 8px; display: flex; gap: 8px; }
.pod-upcoming { display: flex; gap: 20px; align-items: flex-start; flex-wrap: wrap; }
.pod-upcoming__cover { width: 180px; flex-shrink: 0; }

@media (max-width: 860px) {
  .pod-show { grid-template-columns: 1fr; gap: 16px; padding: var(--space-3); }
  .pod-show__side { position: static; }
  .pod-show__cover { width: 60%; max-width: 240px; }
  .pod-ep__thumb { flex-basis: 140px; }
  .pod-ep__desc { display: none; }
}

/* ── Movies, the Netflix way ────────────────────────────────────────────
   Netflix's layout in the app's own colours: banner, scrolling rows, hover actions, More Info sheet. Only text drawn
   on top of a picture (the banner, card captions) is white, over a dark fade, so it stays readable. */
.nf-page { color: var(--text-primary); }
.nf-bar { display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap; padding: 4px 0 16px; }
.nf-bar__title { font-size: 1.5rem; font-weight: 800; letter-spacing: 0.01em; }
.nf-bar__tools { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.nf-select { height: 36px; background: var(--bg-elevated); color: var(--text-primary); border: 1px solid var(--border-default); border-radius: var(--radius-full, 18px); padding: 0 14px; font-size: 0.875rem; }
.nf-search { display: flex; align-items: center; gap: 8px; height: 36px; padding: 0 14px; background: var(--bg-elevated); border: 1px solid var(--border-default); border-radius: var(--radius-full, 18px); color: var(--text-muted); }
.nf-search input { background: transparent; border: none; outline: none; color: var(--text-primary); width: 170px; font-size: 0.875rem; }
.nf-btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; height: 36px; padding: 0 18px; border: none; border-radius: var(--radius-full, 18px); background: var(--text-primary); color: var(--bg-surface); font-weight: 700; font-size: 0.875rem; cursor: pointer; white-space: nowrap; }
.nf-btn--ghost { background: var(--bg-elevated); color: var(--text-primary); }
.nf-btn:hover { filter: brightness(1.12); }
.nf-panel { padding: 0 0 16px; }
.nf-empty { padding: 56px 24px; color: var(--text-muted); text-align: center; }

/* banner: white text over a dark fade on the picture */
.nf-hero { position: relative; min-height: clamp(340px, 42vw, 520px); display: flex; align-items: flex-end; border-radius: 14px; overflow: hidden; color: #fff; }
.nf-hero__media { position: absolute; inset: 0; overflow: hidden; background: linear-gradient(135deg, #27272a, #09090b); }
.nf-hero__media img, .nf-hero__media video { width: 100%; height: 100%; object-fit: cover; display: block; }
.nf-hero__media .nf-art { font-size: 8rem; opacity: 0.85; }
.nf-hero__shade { position: absolute; inset: 0; background: linear-gradient(77deg, rgba(0, 0, 0, 0.78) 0%, rgba(0, 0, 0, 0.1) 65%), linear-gradient(to top, rgba(0, 0, 0, 0.6) 0%, rgba(0, 0, 0, 0) 45%); }
.nf-hero__text { position: relative; padding: 0 clamp(16px, 4vw, 40px) clamp(24px, 4vw, 44px); max-width: 640px; }
.nf-hero__kicker { font-size: 0.75rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: #e5e5e5; }
.nf-hero__title { font-size: clamp(1.9rem, 5vw, 3.25rem); font-weight: 800; line-height: 1.04; margin: 6px 0 10px; text-shadow: 0 2px 12px rgba(0, 0, 0, 0.6); word-break: break-word; color: #fff; }
.nf-hero__meta { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; font-size: 0.875rem; color: #e0e0e0; }
.nf-hero__desc { font-size: clamp(0.875rem, 1.4vw, 1.0625rem); line-height: 1.4; max-width: 540px; margin: 10px 0 0; color: #f0f0f0; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; }
.nf-hero__buttons { display: flex; align-items: center; gap: 10px; margin-top: 16px; flex-wrap: wrap; }
.nf-btn--play { background: #fff; color: #000; height: 42px; padding: 0 24px; font-size: 1rem; }
.nf-btn--info { background: rgba(255, 255, 255, 0.28); color: #fff; height: 42px; padding: 0 22px; font-size: 1rem; }
.nf-price { color: #16a34a; font-weight: 700; }
.nf-hero .nf-price, .nf-modal__hero .nf-price { color: #4ade80; }
.nf-hd { border: 1px solid var(--border-default); border-radius: 3px; padding: 0 4px; font-size: 0.6875rem; }
.nf-hero .nf-hd { border-color: rgba(255, 255, 255, 0.55); }

.nf-ads { margin: 12px 0; display: grid; gap: 8px; }
.nf-rows { margin-top: 20px; padding-bottom: 40px; }
.nf-row { margin: 0 0 6px; position: relative; }
.nf-row:hover { z-index: 8; }
.nf-row__title { font-size: 1.25rem; font-weight: 700; color: var(--text-primary); margin: 0 0 4px; }
.nf-row__viewport { position: relative; }
.nf-row__track { display: flex; gap: 8px; overflow-x: auto; scroll-snap-type: x proximity; scrollbar-width: none; padding: 50px 0 130px; margin: -46px 0 -120px; }
.nf-row__track::-webkit-scrollbar { display: none; }
.nf-arrow { display: none; position: absolute; top: 46px; bottom: 130px; width: clamp(30px, 4vw, 48px); z-index: 9; border: none; background: rgba(0, 0, 0, 0.45); color: #fff; font-size: 2.25rem; cursor: pointer; opacity: 0; transition: opacity 0.2s; }
.nf-arrow--left { left: 0; }
.nf-arrow--right { right: 0; }
@media (hover: hover) and (pointer: fine) {
  .nf-arrow { display: block; }
  .nf-row__viewport:hover .nf-arrow { opacity: 1; }
}

.nf-card { position: relative; flex: 0 0 clamp(150px, 19vw, 260px); scroll-snap-align: start; cursor: pointer; outline: none; }
.nf-card__frame { position: relative; border-radius: 8px; overflow: hidden; background: var(--bg-surface); transition: transform 0.2s ease, box-shadow 0.2s ease; }
.nf-card__thumb { position: relative; aspect-ratio: 16 / 9; overflow: hidden; background: #27272a; }
.nf-card__thumb img, .nf-card__thumb video { width: 100%; height: 100%; object-fit: cover; display: block; }
.nf-art { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; font-size: 2rem; font-weight: 800; color: rgba(255, 255, 255, 0.9); background: linear-gradient(135deg, #7c3aed, #e11d48); }
.nf-card__cap { position: absolute; left: 0; right: 0; bottom: 0; padding: 22px 8px 6px; font-size: 0.75rem; font-weight: 700; line-height: 1.2; color: #fff; background: linear-gradient(transparent, rgba(0, 0, 0, 0.85)); overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.nf-new { position: absolute; left: 0; top: 8px; background: var(--error-500, #e11d48); color: #fff; font-size: 0.625rem; font-weight: 700; padding: 2px 6px; border-radius: 0 3px 3px 0; }
.nf-lock { position: absolute; right: 6px; top: 6px; background: rgba(0, 0, 0, 0.72); color: #fff; font-size: 0.625rem; font-weight: 600; padding: 2px 6px; border-radius: 3px; }
.nf-card__hover { display: none; padding: 10px 10px 12px; background: var(--bg-surface); color: var(--text-primary); }
.nf-card__actions { display: flex; gap: 6px; margin-bottom: 8px; }
.nf-card__meta { display: flex; gap: 8px; align-items: center; font-size: 0.75rem; color: var(--text-secondary, var(--text-muted)); }
.nf-card__tags { font-size: 0.75rem; color: var(--text-primary); margin-top: 4px; }
.nf-circle { width: 34px; height: 34px; border-radius: 50%; border: 2px solid var(--border-default); background: var(--bg-elevated); color: var(--text-primary); display: inline-flex; align-items: center; justify-content: center; cursor: pointer; flex-shrink: 0; }
.nf-circle:hover { border-color: var(--text-primary); }
.nf-circle--play, .nf-circle--on { background: var(--text-primary); color: var(--bg-surface); border-color: var(--text-primary); }
.nf-circle--right { margin-left: auto; }
.nf-circle:disabled { opacity: 0.4; cursor: default; }
@media (hover: hover) and (pointer: fine) {
  .nf-row .nf-card:hover { z-index: 9; }
  .nf-row .nf-card:hover .nf-card__frame { transform: scale(1.2); box-shadow: 0 10px 30px rgba(0, 0, 0, 0.28); }
  .nf-card:hover .nf-card__hover { display: block; }
  .nf-card:hover .nf-card__cap { display: none; }
  .nf-grid .nf-card:hover .nf-card__frame { transform: scale(1.05); }
}
.nf-row__track > .nf-card:first-child .nf-card__frame { transform-origin: left center; }
.nf-card:focus-visible .nf-card__frame { outline: 2px solid var(--text-primary); }

.nf-card--num { flex-basis: clamp(190px, 25vw, 340px); padding-left: clamp(56px, 8vw, 104px); }
.nf-num { position: absolute; left: 0; bottom: -6px; font-size: clamp(6rem, 12vw, 10rem); font-weight: 900; line-height: 0.8; letter-spacing: -0.08em; color: var(--bg-surface); -webkit-text-stroke: 3px var(--text-muted); pointer-events: none; }

.nf-results { padding: 8px 0 32px; }
.nf-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(clamp(150px, 20vw, 250px), 1fr)); gap: 28px 8px; padding: 8px 0; }
.nf-grid .nf-card { flex: none; }

.nf-modal { position: fixed; inset: 0; z-index: 10000; background: rgba(0, 0, 0, 0.55); overflow-y: auto; display: flex; justify-content: center; align-items: flex-start; padding: 32px 12px; }
.nf-modal__card { position: relative; width: 100%; max-width: 860px; background: var(--bg-surface); color: var(--text-primary); border-radius: 12px; overflow: hidden; box-shadow: 0 10px 50px rgba(0, 0, 0, 0.4); }
.nf-modal__hero { position: relative; aspect-ratio: 16 / 9; background: #000; color: #fff; }
.nf-modal__fade { position: absolute; inset: 0; background: linear-gradient(to top, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0) 60%); }
.nf-modal__heroText { position: absolute; left: clamp(16px, 4vw, 36px); right: 16px; bottom: clamp(16px, 4vw, 32px); }
.nf-modal__title { font-size: clamp(1.5rem, 4vw, 2.5rem); font-weight: 800; margin: 0 0 12px; line-height: 1.05; color: #fff; }
.nf-modal__hero .nf-circle { background: rgba(255, 255, 255, 0.25); border-color: rgba(255, 255, 255, 0.7); color: #fff; }
.nf-modal__hero .nf-circle--on { background: #fff; color: #000; }
.nf-modal__close { position: absolute; top: 12px; right: 12px; z-index: 3; width: 36px; height: 36px; border-radius: 50%; border: none; background: rgba(0, 0, 0, 0.6); color: #fff; font-size: 1.5rem; line-height: 1; cursor: pointer; }
.nf-modal__body { padding: 16px clamp(16px, 4vw, 36px) 32px; }
.nf-modal__cols { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); gap: 24px; }
.nf-modal__desc { margin: 12px 0 0; line-height: 1.5; color: var(--text-primary); white-space: pre-wrap; }
.nf-modal__side { font-size: 0.875rem; display: flex; flex-direction: column; gap: 8px; }
.nf-lbl { color: var(--text-muted); }
.nf-modal__h3 { font-size: 1.3rem; margin: 28px 0 12px; }
.nf-grid--modal { padding: 0; grid-template-columns: repeat(3, 1fr); gap: 16px 12px; }
.nf-modal .nf-card__hover { display: block; }
.nf-modal .nf-card__cap { display: none; }
.nf-modal .nf-card:hover .nf-card__frame { transform: none; box-shadow: none; }
@media (max-width: 640px) {
  .nf-bar__tools { width: 100%; }
  .nf-search { flex: 1; }
  .nf-search input { width: 100%; }
  .nf-hero { min-height: 380px; }
  .nf-modal__cols { grid-template-columns: 1fr; }
  .nf-grid--modal { grid-template-columns: repeat(2, 1fr); }
  .nf-modal { padding: 0; }
  .nf-modal__card { border-radius: 0; min-height: 100vh; }
}

/* ── Channel Intro Card ("swipe right to enter") ──────────────────────
   Full-screen cover shown before a channel page — see modules/_shared/channelIntro.js. */
/* Scales with the viewport's actual HEIGHT, not just width — a fixed 220px badly overflowed a real, common
   case: a phone held in landscape (short viewport height), where the avatar's top and the arrow's bottom both
   clipped off-screen since the column was simply taller than the screen. 30% of height, capped at 220px, keeps
   the old size on any normal portrait phone while shrinking gracefully whenever height is the tight dimension. */
.avatar--intro { width: clamp(100px, 30vh, 220px); height: clamp(100px, 30vh, 220px); font-size: clamp(1.25rem, 6vh, 2.75rem); }

.ch-intro {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-5);
  overflow: hidden;
  color: #fff;
  transition: opacity 450ms var(--ease-out), transform 450ms var(--ease-out);
}
.ch-intro--leaving { opacity: 0; transform: translateX(18%); pointer-events: none; }

.ch-intro__bg {
  position: absolute;
  inset: -20%;
  background: linear-gradient(120deg, var(--ci-c1), var(--ci-c2), var(--ci-c3), var(--ci-c1));
  background-size: 300% 300%;
  animation: ch-intro-bg-drift 12s ease-in-out infinite;
}

.ch-intro__media { position: relative; z-index: 1; }
.ch-intro-frame { display: inline-flex; border-radius: 20px; overflow: hidden; }
.ch-intro-frame .avatar--intro { border-radius: 16px; }

.ch-intro__name {
  position: relative;
  z-index: 1;
  font-size: 1.5rem;
  font-weight: 700;
  text-shadow: 0 2px 10px rgba(0,0,0,0.4);
  text-align: center;
  padding: 0 var(--space-6);
}

.ch-intro__arrow {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  background: rgba(255,255,255,0.18);
  border: 1px solid rgba(255,255,255,0.4);
  border-radius: var(--radius-full);
  color: #fff;
  padding: 10px 18px;
  font-size: 0.9375rem;
  font-weight: 600;
  cursor: pointer;
  margin-top: var(--space-6);
  animation: ch-intro-arrow-nudge 1.6s ease-in-out infinite;
}

@keyframes ch-intro-bg-drift {
  0%   { background-position: 0% 50%; }
  50%  { background-position: 100% 50%; }
  100% { background-position: 0% 50%; }
}
@keyframes ch-intro-arrow-nudge {
  0%, 100% { transform: translateX(0); }
  50%      { transform: translateX(6px); }
}
@media (prefers-reduced-motion: reduce) {
  .ch-intro__bg, .ch-intro__arrow { animation: none; }
  .ch-intro { transition: none; }
}
/* Extra headroom for very short viewports (landscape on a small phone, or a keyboard eating vertical space) —
   the avatar clamp above already does most of the work; this trims the remaining gaps too. */
@media (max-height: 420px) {
  .ch-intro { gap: var(--space-2); }
  .ch-intro__arrow { margin-top: var(--space-2); }
}

/* Customize-channel dialog: intro scheme/frame swatches. */
.ch-scheme-swatch {
  width: 36px; height: 36px; border-radius: 50%; border: 2px solid transparent; cursor: pointer; padding: 0;
}
.ch-scheme-swatch--active { border-color: var(--text-primary); box-shadow: 0 0 0 2px var(--bg-surface); }
.ch-frame-swatch {
  width: 36px; height: 36px; border-radius: 8px; border: 2px solid var(--border-default); background: var(--bg-elevated); cursor: pointer; padding: 0;
}
.ch-frame-swatch--active { border-color: var(--text-primary); }

/* ── Settings page (YouTube-style list) ──────────────────────────────── */
.settings-section-title { font-size: 0.75rem; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; color: var(--text-muted); padding: var(--space-4) 0 var(--space-2); }
.settings-section-title:first-child { padding-top: 0; }
.settings-row {
  display: flex; align-items: center; gap: var(--space-4);
  padding: var(--space-3) 0; border-bottom: 1px solid var(--border-subtle);
  cursor: pointer; background: none; border-left: none; border-right: none; border-top: none;
  width: 100%; text-align: left; color: var(--text-primary); font-family: inherit;
}
.settings-row:last-child { border-bottom: none; }
.settings-row--static { cursor: default; }
.settings-row--danger { color: var(--error-500, #dc2626); }
.settings-icon { flex-shrink: 0; width: 24px; height: 24px; display: flex; align-items: center; justify-content: center; color: var(--text-muted); }
.settings-row--danger .settings-icon { color: var(--error-500, #dc2626); }
.settings-row__body { flex: 1; min-width: 0; }
.settings-row__label { font-size: 0.9375rem; font-weight: 500; }
.settings-row__desc { font-size: 0.8125rem; color: var(--text-muted); margin-top: 2px; }
.settings-row__value { font-size: 0.8125rem; color: var(--text-muted); flex-shrink: 0; }
.settings-row__chevron { flex-shrink: 0; color: var(--text-muted); }

/* A real switch, not a plain checkbox — matches the sliding pill toggle every native settings screen (including
   YouTube's own) uses for on/off preferences. */
.settings-toggle { position: relative; flex-shrink: 0; width: 44px; height: 26px; display: inline-block; }
.settings-toggle input { position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; }
.settings-toggle__track {
  position: absolute; inset: 0; border-radius: var(--radius-full); background: var(--border-default);
  transition: background var(--transition-fast, 150ms);
}
.settings-toggle__track::before {
  content: ''; position: absolute; top: 2px; left: 2px; width: 22px; height: 22px; border-radius: 50%;
  background: #fff; box-shadow: 0 1px 3px rgba(0,0,0,0.3); transition: transform var(--transition-fast, 150ms);
}
.settings-toggle input:checked + .settings-toggle__track { background: var(--info-500, #2563eb); }
.settings-toggle input:checked + .settings-toggle__track::before { transform: translateX(18px); }
.settings-toggle input:disabled + .settings-toggle__track { opacity: 0.5; cursor: not-allowed; }
