/* ==========================================================================
   css/components/user-panel.css
   Split from app.html (build 2026.10.08.9-beta), original lines 1568-1793.
   Rules are in their ORIGINAL order; load order is defined in index.html.
   ========================================================================== */
.user-panel {
  height: 58px;                  /* 56px content + 1px borders each side (border-box) */
  background: #1e1f24;            /* dark panel that fits the retuned palette (was #36373E grey) */
  border: 1px solid var(--border-strong); /* reference border, now theme-driven (default dark ≈ #3A3B42) */
  border-radius: 8px;   /* smaller, cleaner corners (was 12px) */
  position: fixed;
  left: 6px;    /* 1px tighter each side than before (was 5px) */
  bottom: 6px;  /* nudged up 1px (was 5px) */
  /* reach the end of the channel sidebar: server rail (64) + sidebar, 6px inset each side */
  width: calc(64px + var(--ch-w, 193px) - 12px);
  z-index: 90;
  box-shadow: none;
  backdrop-filter: blur(10px);
  display: flex;
  align-items: center;
  padding: 0 8px;
  gap: 8px;
}
/* In a call: the voice bar + user panel form ONE joined panel, split by the border
   line (not two separate cards). Panel gets a flat top + no top border so the voice
   bar's bottom border is the single divider line. */
.voice-bar.active + .user-panel { border-radius: 0 0 8px 8px; border-top: none; }
/* Speaking = a green ring on the PFP only, never a wash over the whole user panel. Gated
   on the voice bar being active so a leftover .speaking class can't ring the avatar when
   you're NOT in a call. */
.voice-bar.active + .user-panel.speaking .user-avatar { box-shadow: 0 0 0 2px #23a559; }
/* Same green ring on the channel-list voice roster avatar while that person talks. */
.voice-sidebar-member.speaking .voice-sidebar-avatar { box-shadow: 0 0 0 2px #23a559; }
/* Light theme: the hardcoded dark fill above left the user panel dark in light mode.
   Follow the theme's elevated surface instead (dark theme keeps #36373E). */
html[data-theme="light"] .user-panel,
html[data-theme="light"] .voice-bar { background: var(--bg-elevated); }
/* Widen the card when the secondary folder rail is open (server rail 56 + folder rail
   72 + channel sidebar), reaching the end. */
body:has(.folder-secondary-rail.visible) .user-panel,
body:has(.folder-secondary-rail.visible) .voice-bar { width: calc(64px + 72px + var(--ch-w, 193px) - 12px); }

.user-avatar {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--accent);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display, 'Space Grotesk', sans-serif);
  font-weight: 700;
  font-size: 12px;
  color: #fff;
  flex-shrink: 0;
  position: relative;
  cursor: pointer;
  transition: box-shadow 0.18s var(--ease-out, ease);
}
.user-avatar:hover { box-shadow: 0 0 0 2px var(--accent); }

.user-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 50%;
}
/* Avatars that HAVE an image must never show a coloured fill behind a transparent PNG.
   The per-user colorFromId colour (and the online-green that hashed into it) was bleeding
   through cutout avatars - on messages, voice tiles and the channel list. Neutral surface
   behind IMAGE avatars; the colourful fill stays only for initials-only avatars (no img). */
.msg-avatar:has(img), .member-avatar:has(img), .user-avatar:has(img),
.voice-tile-avatar:has(img), .voice-sidebar-avatar:has(img),
.profile-popup-avatar-inner:has(img), .msg-avatar:has(video), .user-avatar:has(video) {
  background: var(--bg-elevated) !important;
}


/* -- The mini profile card at the top of the user menu ------------------------------------
   The reference opens a small profile above the actions when you click your own avatar, not a
   bare list. The card bleeds to the menu's edges, so it cancels the menu's 6px padding rather
   than fighting it. */
/* Geometry taken from the reference's stylesheets, not from a screenshot:
     --custom-user-profile-popout-width   300px   (the menu's min-width)
     --custom-user-profile-banner-height  105px
     --radius-sm                            8px
     .user-profile-popout .avatar__75742  left 16px, top 61px
   The avatar has no size in CSS, but the modal's rule gives the relationship away -
   `top: banner-height - avatar-size/2` centres it on the banner's bottom edge - and top 61
   under a 105px banner resolves to an 80px avatar. */
.um-card { position: relative; margin: -6px -6px 6px; border-radius: 8px 8px 0 0; overflow: hidden; }
.um-banner { height: 105px; background-size: cover; background-position: center; }
.um-banner img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* The ring around the avatar. A FLAT colour here cannot match a menu that repaints the
   wallpaper - the same mismatch the status dots had - so this element carries the identical
   floating-chrome background. That recipe is `background-attachment: fixed`, so its copy lines
   up with the menu's to the pixel and the ring reads as a hole, not a disc.
   6px of ring either side of an 80px avatar, so the ring sits at 16-6 / 61-6. */
.um-av-ring {
  position: absolute; left: 10px; top: 55px;
  width: 92px; height: 92px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--bg-floating, var(--bg-elevated));
}
.um-av {
  width: 80px; height: 80px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: 27px; color: #fff;
  overflow: hidden; position: relative;
}
.um-av img { width: 100%; height: 100%; object-fit: cover; border-radius: 50%; }
/* The large dot, off the same tokens as every other one - this IS the 80px-avatar case they
   were measured from (hole r=0.175 -> 28px footprint, centre at 85%). */
.um-dot {
  position: absolute; right: 4px; bottom: 4px;
  width: var(--status-dot-lg); height: var(--status-dot-lg); border-radius: 50%;
  border: var(--status-ring-w-lg) solid var(--status-ring); box-sizing: border-box;
}
/* Clears the avatar: it ends at 61 + 80 = 141, the banner at 105, and the reference leaves
   ~8px under it before the name. */
.um-info { padding: 44px 16px 12px; }
.um-name { font-size: 16px; font-weight: 700; color: var(--text-primary); display: flex; align-items: center; gap: 5px; flex-wrap: wrap; }
.um-sub { font-size: 12.5px; color: var(--text-muted); margin-top: 2px; }
.um-dotsep { opacity: .6; }
.um-cs {
  font-size: 12.5px; color: var(--text-secondary);
  margin-top: 9px; padding-top: 9px; border-top: 1px solid var(--border);
  word-break: break-word;
}
body[data-pfp="square"] .um-av, body[data-pfp="square"] .um-av img { border-radius: 22%; }

/* modern-style user menu, anchored above the user panel avatar. */
.user-menu {
  position: absolute;
  bottom: calc(100% + 8px);
  left: 8px;
  background: var(--bg-floating, var(--bg-elevated));
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 6px;
  /* Wider than the old three-item list: it now opens with a mini profile card (banner, avatar,
     name, handle, badges, custom status) above the actions. */
  min-width: 300px;
  box-shadow: 0 8px 28px rgba(0,0,0,0.45);
  z-index: 1000;
}
.user-menu-item {
  position: relative;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 10px;
  border-radius: 6px;
  cursor: pointer;
  font-size: 13px;
  color: var(--text-secondary);
}
.user-menu-item:hover { background: var(--bg-active); color: var(--text-primary); }
.user-menu-item .umi-chevron { margin-left: auto; opacity: 0.6; font-size: 11px; }
.user-menu-sep { height: 1px; background: var(--border); margin: 5px 6px; }
/* position:relative so the status silhouette (a ::after overlay - see members-rail.css)
   anchors to the swatch itself. Without it the overlay would position against the nearest
   positioned ancestor, i.e. the menu, and land somewhere arbitrary. */
.user-menu-dot { width: var(--status-dot); height: var(--status-dot); border-radius: 50%; flex-shrink: 0; position: relative; }
.user-menu-ic { width: 16px; height: 16px; flex-shrink: 0; opacity: 0.8; }
/* Status submenu flyout (opens to the right of the Status row on hover). */
.user-submenu {
  position: absolute;
  left: calc(100% + 6px);
  bottom: -6px;
  background: var(--bg-floating, var(--bg-elevated));
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 6px;
  min-width: 230px;
  box-shadow: 0 8px 28px rgba(0,0,0,0.45);
  display: none;
}
/* Transparent bridge across the 6px gap so moving the cursor from the Status
   row into the flyout doesn't cross a dead zone that closes it. */
.user-submenu::before {
  content: '';
  position: absolute;
  left: -8px;
  top: 0;
  bottom: 0;
  width: 8px;
}
.user-menu-item.has-sub:hover > .user-submenu,
.user-submenu:hover { display: block; }
.user-submenu-item {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 8px 10px;
  border-radius: 6px;
  cursor: pointer;
  color: var(--text-secondary);
}
.user-submenu-item:hover { background: var(--bg-active); color: var(--text-primary); }
.user-submenu-item.active { color: var(--text-primary); }
.user-submenu-item .usi-dot { width: var(--status-dot); height: var(--status-dot); border-radius: 50%; flex-shrink: 0; margin-top: 3px; position: relative; }
.user-submenu-item .usi-label { font-size: 13px; font-weight: 500; }
.user-submenu-item .usi-desc { font-size: 11px; color: var(--text-muted); margin-top: 1px; }

.user-status-dot {
  position: absolute;
  /* Same corner as every other dot: the reference centres it at 84.375% of the avatar, which
     for a 16px dot on a 32px avatar is a 3px overhang. These were still -1px from when the dot
     was 11px, which put this one at 78% - visibly further into the avatar than the member
     list's. */
  bottom: -3px;
  right: -3px;
  width: var(--status-dot);
  height: var(--status-dot);
  border-radius: 50%;
  background: var(--green);
  border: var(--status-ring-w) solid var(--status-ring);
}

.user-info { flex: 1; overflow: hidden; }

.user-name {
  font-size: 13px;
  font-weight: 600;
  color: var(--text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.user-tag {
  font-size: 11px;
  color: var(--text-muted);
}

.user-actions { display: flex; gap: 2px; }

.user-action-btn {
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-sm);
  color: var(--text-secondary);
  font-size: 16px;
  transition: background 0.1s, color 0.1s, transform 0.14s var(--ease-spring, ease);
  cursor: pointer;
}
.user-action-btn:hover { background: var(--bg-active); color: var(--text-primary); }
.user-action-btn:active { transform: scale(0.88); }
.user-action-btn.muted { color: var(--red); }
/* Icon micro-interactions: a springy pop on hover; the gear slowly spins. */
.user-action-btn svg { transition: transform 0.16s var(--ease-spring, ease); transform-origin: center; }
.user-action-btn:hover svg { transform: scale(1.15); }
#settingsBtn:hover svg { animation: up-gear-spin 3s linear infinite; transform: none; }
@keyframes up-gear-spin { from { transform: rotate(0); } to { transform: rotate(360deg); } }

.mic-btn-group { position: relative; display: flex; align-items: center; }
.mic-chevron-btn {
  width: 14px; height: 32px;
  display: flex; align-items: center; justify-content: center;
  background: none; border: none; cursor: pointer;
  color: var(--text-muted); font-size: 9px; padding: 0;
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  transition: background 0.1s, color 0.1s;
}
.mic-chevron-btn:hover { background: var(--bg-active); color: var(--text-primary); }
.mic-device-picker {
  display: none; position: fixed;
  background: var(--bg-surface); border: 1px solid var(--border-strong);
  border-radius: var(--radius-md); padding: 6px; min-width: 220px;
  box-shadow: var(--shadow-lg); z-index: 9999;
}
.mic-device-picker.open { display: block; animation: menu-in 0.22s var(--ease-out, ease); }
.mic-device-picker-label {
  font-size: 10px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .8px; color: var(--text-muted); padding: 4px 8px 6px;
}
.mic-device-item {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 10px; border-radius: var(--radius-sm);
  cursor: pointer; font-size: 13px; color: var(--text-secondary);
  transition: background 0.1s;
}
.mic-device-item:hover { background: var(--bg-hover); color: var(--text-primary); }
.mic-device-item.selected { color: var(--accent-bright); }
.mic-device-dot {
  width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0;
  border: 2px solid var(--border-strong);
}
.mic-device-item.selected .mic-device-dot { background: var(--accent); border-color: var(--accent); }

