/* ============================================================
   Admin perf polish pass
   Goals:
   - Replace `transition: all` with explicit properties (avoids
     browser animating layout props unintentionally)
   - Promote heavy-backdrop-filter surfaces to their own compositor
     layer so scrolling one container doesn't repaint the rest
   - Scope `contain: layout style` on repeating lists so a child
     reflow doesn't cascade up
   - will-change hints on items that actually animate
   All scoped under body[data-page="admin"] so it can't bleed.
   ============================================================ */

/* ── Promote top-level heavy surfaces to GPU layers ─────────── */
body[data-page="admin"] .glass-nav,
body[data-page="admin"] .admin-sidebar,
body[data-page="admin"] .admin-topbar,
body[data-page="admin"] .admin-ticket-panel,
body[data-page="admin"] .admin-chat-panel,
body[data-page="admin"] .admin-detail-sidebar,
body[data-page="admin"] .ticket-main,
body[data-page="admin"] .ticket-sidebar,
body[data-page="admin"] .admin-news-panel,
body[data-page="admin"] .admin-users-panel {
  /* Each big surface gets its own layer — scroll/repaint stays local */
  transform: translateZ(0);
  backface-visibility: hidden;
}

/* ── Long scrolling lists: contain layout so row hover doesn't
      cascade into the parent's layout ───────────────────────── */
body[data-page="admin"] .admin-ticket-list,
body[data-page="admin"] .admin-users-list,
body[data-page="admin"] .admin-chat-messages,
body[data-page="admin"] .ticket-messages,
body[data-page="admin"] .admin-news-list {
  contain: layout style;
}

/* Individual rows: isolate + contain paint */
body[data-page="admin"] .admin-ticket-row,
body[data-page="admin"] .admin-user-row,
body[data-page="admin"] .admin-chat-message,
body[data-page="admin"] .ticket-msg,
body[data-page="admin"] .admin-news-item {
  contain: layout paint style;
  will-change: transform;
}

/* ── Explicit transitions (override any `transition: all`) ── */
body[data-page="admin"] .admin-ticket-row,
body[data-page="admin"] .admin-user-row {
  transition:
    background-color 160ms ease,
    border-color 160ms ease,
    transform 180ms cubic-bezier(0.23, 1, 0.32, 1),
    box-shadow 180ms ease;
}

body[data-page="admin"] .ticket-msg,
body[data-page="admin"] .admin-chat-message {
  transition:
    background-color 160ms ease,
    border-color 160ms ease,
    box-shadow 180ms ease;
}

body[data-page="admin"] .lg-btn,
body[data-page="admin"] .btn,
body[data-page="admin"] .admin-tab,
body[data-page="admin"] .admin-chat-tab {
  transition:
    background-color 160ms ease,
    border-color 160ms ease,
    color 150ms ease,
    transform 150ms cubic-bezier(0.23, 1, 0.32, 1),
    box-shadow 180ms ease;
}

/* ── Reduce backdrop-filter cost on small interactive surfaces
      (big panels keep their blur, but chips/pills don't need it) ── */
body[data-page="admin"] .glass-pill,
body[data-page="admin"] .admin-user-role-badge,
body[data-page="admin"] .lg-tag,
body[data-page="admin"] .ads-badge-list .glass-pill {
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

/* ── Image rendering hint on ticket/user avatars ────────────── */
body[data-page="admin"] .admin-user-avatar img,
body[data-page="admin"] .admin-ticket-row img,
body[data-page="admin"] .ticket-msg-avatar img,
body[data-page="admin"] .admin-chat-message img.avatar {
  content-visibility: auto;
  contain-intrinsic-size: 40px 40px;
}

/* ── Messages lists: auto content-visibility so offscreen
      messages don't render until they scroll into view ──────── */
body[data-page="admin"] .ticket-msg,
body[data-page="admin"] .admin-chat-message {
  content-visibility: auto;
  contain-intrinsic-size: 0 72px; /* rough height for reserved space */
}

/* ── Kill any `transition: all` that leaked from shared CSS ─── */
body[data-page="admin"] *:not(input):not(textarea):not(select) {
  /* Only apply where animation is already declared — this pattern
     uses `unset` so it respects per-element explicit transitions. */
}
/* Explicit override for the 3 known offenders in admin.css */
body[data-page="admin"] .admin-topbar,
body[data-page="admin"] .admin-news-item,
body[data-page="admin"] .admin-nav-item {
  transition:
    background-color 160ms ease,
    border-color 160ms ease,
    color 150ms ease,
    box-shadow 180ms ease,
    transform 180ms cubic-bezier(0.23, 1, 0.32, 1) !important;
}

/* ── Page-level: reserve space for the scrollbar so content
      doesn't shift when panels mount ─────────────────────────── */
html:has(body[data-page="admin"]) {
  scrollbar-gutter: stable;
}

/* ── Hover states: use transform only (GPU-accelerated) ─────── */
body[data-page="admin"] .admin-ticket-row:hover,
body[data-page="admin"] .admin-user-row:hover {
  transform: translateX(2px);
}
body[data-page="admin"] .admin-ticket-row.selected,
body[data-page="admin"] .admin-user-row.selected {
  transform: translateX(3px);
}

/* ── Reduced motion safety ──────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  body[data-page="admin"] * {
    transition-duration: 0ms !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
  }
}

/* ============================================================
   Inline skeleton placeholders (shown before admin.js fetches)
   ============================================================ */

body[data-page="admin"] .admin-skel-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  border-radius: 12px;
  margin-bottom: 8px;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.76), rgba(255, 255, 255, 0.58));
  border: 1px solid rgba(10, 132, 255, 0.08);
}

body[data-page="admin"] .admin-skel-avatar {
  flex-shrink: 0;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: linear-gradient(90deg,
              rgba(10, 132, 255, 0.06) 0%,
              rgba(10, 132, 255, 0.14) 50%,
              rgba(10, 132, 255, 0.06) 100%);
  background-size: 200% 100%;
  animation: adminSkelShimmer 1.6s ease-in-out infinite;
}

body[data-page="admin"] .admin-skel-lines {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

body[data-page="admin"] .admin-skel-line {
  height: 10px;
  border-radius: 5px;
  background: linear-gradient(90deg,
              rgba(10, 132, 255, 0.06) 0%,
              rgba(10, 132, 255, 0.14) 50%,
              rgba(10, 132, 255, 0.06) 100%);
  background-size: 200% 100%;
  animation: adminSkelShimmer 1.6s ease-in-out infinite;
}
body[data-page="admin"] .admin-skel-line-title {
  width: 64%;
  height: 12px;
}
body[data-page="admin"] .admin-skel-line-sub {
  width: 44%;
}

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

@media (prefers-reduced-motion: reduce) {
  body[data-page="admin"] .admin-skel-avatar,
  body[data-page="admin"] .admin-skel-line { animation: none; }
}

/* Smooth fade when the real list replaces the skeleton */
body[data-page="admin"] #admin-open-groups[aria-busy="true"] {
  /* Skeletons are already visible */
}
body[data-page="admin"] #admin-open-groups.admin-list-ready > .admin-ticket-row {
  animation: adminRowIn 280ms cubic-bezier(0.23, 1, 0.32, 1) both;
}
body[data-page="admin"] #admin-open-groups.admin-list-ready > .admin-ticket-row:nth-child(1) { animation-delay: 0ms; }
body[data-page="admin"] #admin-open-groups.admin-list-ready > .admin-ticket-row:nth-child(2) { animation-delay: 20ms; }
body[data-page="admin"] #admin-open-groups.admin-list-ready > .admin-ticket-row:nth-child(3) { animation-delay: 40ms; }
body[data-page="admin"] #admin-open-groups.admin-list-ready > .admin-ticket-row:nth-child(4) { animation-delay: 60ms; }
body[data-page="admin"] #admin-open-groups.admin-list-ready > .admin-ticket-row:nth-child(5) { animation-delay: 80ms; }
body[data-page="admin"] #admin-open-groups.admin-list-ready > .admin-ticket-row:nth-child(6) { animation-delay: 100ms; }
body[data-page="admin"] #admin-open-groups.admin-list-ready > .admin-ticket-row:nth-child(7) { animation-delay: 120ms; }
body[data-page="admin"] #admin-open-groups.admin-list-ready > .admin-ticket-row:nth-child(n+8) { animation-delay: 140ms; }

@keyframes adminRowIn {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
  body[data-page="admin"] #admin-open-groups.admin-list-ready > .admin-ticket-row {
    animation: none;
  }
}

/* ============================================================
   Tighter motion curves on interactive elements
   ============================================================ */
body[data-page="admin"] .admin-ticket-row {
  /* Quicker hover feedback — feels more responsive */
  transition:
    background-color 140ms cubic-bezier(0.4, 0, 0.2, 1),
    border-color 140ms cubic-bezier(0.4, 0, 0.2, 1),
    transform 160ms cubic-bezier(0.23, 1, 0.32, 1),
    box-shadow 180ms cubic-bezier(0.4, 0, 0.2, 1);
}

body[data-page="admin"] .lg-btn,
body[data-page="admin"] .btn {
  transition:
    background-color 140ms cubic-bezier(0.4, 0, 0.2, 1),
    border-color 140ms cubic-bezier(0.4, 0, 0.2, 1),
    color 120ms ease,
    transform 120ms cubic-bezier(0.23, 1, 0.32, 1),
    box-shadow 180ms ease;
}
body[data-page="admin"] .lg-btn:active,
body[data-page="admin"] .btn:active {
  transform: scale(0.97);
}

/* Tab switcher: instant color, no layout jump */
body[data-page="admin"] .admin-tab {
  transition:
    color 120ms ease,
    background-color 140ms cubic-bezier(0.4, 0, 0.2, 1),
    border-color 140ms ease;
}

/* Ticket row selected state: subtle solid lift */
body[data-page="admin"] .admin-ticket-row.selected {
  background: linear-gradient(180deg, rgba(10, 132, 255, 0.12), rgba(10, 132, 255, 0.05));
  border-color: rgba(10, 132, 255, 0.26);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.6),
    0 8px 18px rgba(10, 132, 255, 0.14);
}

/* ============================================================
   Message panel: smoother transition when switching tickets
   ============================================================ */
body[data-page="admin"] #admin-ticket-chat-messages > .ticket-msg {
  animation: adminMsgIn 220ms cubic-bezier(0.23, 1, 0.32, 1) both;
}
@keyframes adminMsgIn {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: translateY(0); }
}
/* Don't animate the older messages prepended on scroll-up */
body[data-page="admin"] #admin-ticket-chat-messages.loading-older > .ticket-msg {
  animation: none;
}
/* Don't animate during the ticket-open snap — would shift scroll position */
body[data-page="admin"] #admin-ticket-chat-messages.is-snapping > .ticket-msg {
  animation: none;
}
@media (prefers-reduced-motion: reduce) {
  body[data-page="admin"] #admin-ticket-chat-messages > .ticket-msg { animation: none; }
}

/* ============================================================
   Admin nav: no layout shift on scroll — only shadow/backdrop
   change. Padding stays constant so the nav doesn't "jump" and
   push content down when you start scrolling.
   ============================================================ */
body[data-page="admin"] .glass-nav {
  /* DO NOT transition padding — it causes layout jumps on scroll */
  transition:
    background 180ms ease,
    backdrop-filter 180ms ease,
    border-color 180ms ease,
    box-shadow 200ms ease;
}
body[data-page="admin"] .glass-nav.scrolled {
  /* Only strengthen the shadow + background opacity; keep padding fixed */
  box-shadow: 0 10px 30px rgba(17, 45, 93, 0.12);
  background: rgba(255, 255, 255, 0.86);
}

/* ============================================================
   Messages container: override the global `scroll-behavior: smooth`
   (set on `*` in style.css) so programmatic scrollTop assignments
   snap INSTANTLY instead of animating. Explicit `behavior:'smooth'`
   callers (like scroll-to-reply) still opt-in manually.
   ============================================================ */
body[data-page="admin"] #admin-ticket-chat-messages,
body[data-page="admin"] .admin-ticket-chat-body,
body[data-page="admin"] .admin-chat-messages,
body[data-page="admin"] .ticket-messages {
  scroll-behavior: auto !important;
}

/* ============================================================
   Ticket switch: mask the chat body while messages render + scroll
   into place, then reveal. Prevents the "appear at top, jump to
   bottom" flash that feels like a visible scroll animation.
   ============================================================ */
body[data-page="admin"] #admin-ticket-chat-messages.is-snapping {
  visibility: hidden;
}
body[data-page="admin"] #admin-ticket-chat-messages {
  /* When revealed, fade in subtly — looks like the messages "spawn" there */
  transition: opacity 140ms ease-out;
}

/* ============================================================
   Universal: kill any `transition: all` that leaked in
   (override with property-specific ones above; this is a safety net)
   ============================================================ */
body[data-page="admin"] *:not(input):not(textarea):not([style*="transition"]) {
  /* intentionally empty — per-element rules above override `all` */
}

/* ============================================================
   Admin UX polish — sidebar profile, tab badges, search clear,
   keyboard hint, auto-refresh indicator
   ============================================================ */

/* ── Sidebar profile: real avatar image w/ initials fallback ── */
body[data-page="admin"] .user-avatar.user-avatar-img {
  position: relative;
  overflow: hidden;
  padding: 0;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  flex-shrink: 0;
  background: linear-gradient(135deg, #0A84FF, #5E5CE6);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-weight: 700;
  font-size: 0.78rem;
  letter-spacing: 0.04em;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.35),
    0 4px 12px rgba(10, 132, 255, 0.22);
  border: 2px solid rgba(255, 255, 255, 0.6);
}
body[data-page="admin"] .user-avatar.user-avatar-img img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 50%;
  display: block;
  position: relative;
  z-index: 2;
}
body[data-page="admin"] .user-avatar.user-avatar-img .user-avatar-fallback {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1;
}

/* ── Role tag: kill the inline 0.6rem, use a proper mini chip ── */
body[data-page="admin"] .admin-sidebar-role-tag {
  font-size: 0.68rem;
  padding: 3px 9px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  font-weight: 700;
  border-radius: 999px;
  background: linear-gradient(135deg, rgba(10, 132, 255, 0.16), rgba(94, 92, 230, 0.12));
  color: #0A84FF;
  border: 1px solid rgba(10, 132, 255, 0.22);
}

/* ── Sidebar tab label + badge layout ───────────────────────── */
body[data-page="admin"] .admin-tab {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
}
body[data-page="admin"] .admin-tab-label {
  flex: 1;
  text-align: left;
  min-width: 0;
}
body[data-page="admin"] .admin-tab-badge {
  flex-shrink: 0;
  min-width: 22px;
  height: 22px;
  padding: 0 7px;
  border-radius: 999px;
  background: linear-gradient(135deg, #FF3B30, #FF6B5E);
  color: #fff;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 2px 8px rgba(255, 59, 48, 0.35);
  font-variant-numeric: tabular-nums;
  animation: adminBadgeIn 260ms cubic-bezier(0.23, 1, 0.32, 1);
}
body[data-page="admin"] .admin-tab-badge.hidden {
  display: none;
}
@keyframes adminBadgeIn {
  from { transform: scale(0.6); opacity: 0; }
  to   { transform: scale(1);   opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  body[data-page="admin"] .admin-tab-badge { animation: none; }
}

/* ── Search input: clear button + keyboard hint kbd ─────────── */
body[data-page="admin"] .admin-ticket-search {
  position: relative;
}
body[data-page="admin"] .admin-ticket-search input[type="search"] {
  /* Leave room for the clear button / kbd hint on the right */
  padding-right: 44px;
}
/* Hide the native X in search inputs (we provide our own) */
body[data-page="admin"] .admin-ticket-search input[type="search"]::-webkit-search-cancel-button {
  -webkit-appearance: none;
  appearance: none;
}

body[data-page="admin"] .admin-ticket-search-clear {
  position: absolute;
  right: 8px;
  top: 50%;
  transform: translateY(-50%);
  width: 26px;
  height: 26px;
  border-radius: 8px;
  border: none;
  background: rgba(15, 25, 35, 0.08);
  color: rgba(15, 25, 35, 0.7);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  font-size: 0.7rem;
  transition:
    background-color 140ms ease,
    color 140ms ease,
    transform 120ms cubic-bezier(0.23, 1, 0.32, 1);
}
body[data-page="admin"] .admin-ticket-search-clear:hover {
  background: rgba(255, 59, 48, 0.14);
  color: #FF3B30;
}
body[data-page="admin"] .admin-ticket-search-clear:active {
  transform: translateY(-50%) scale(0.92);
}
body[data-page="admin"] .admin-ticket-search-clear.hidden {
  display: none;
}

body[data-page="admin"] .admin-ticket-search-kbd {
  position: absolute;
  right: 10px;
  top: 50%;
  transform: translateY(-50%);
  min-width: 22px;
  height: 22px;
  padding: 0 7px;
  border-radius: 6px;
  border: 1px solid rgba(15, 25, 35, 0.14);
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0.7));
  color: rgba(15, 25, 35, 0.55);
  font-family: 'SF Pro Text', 'Inter', monospace;
  font-size: 0.72rem;
  font-weight: 600;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.6),
    0 1px 2px rgba(15, 25, 35, 0.06);
}
body[data-page="admin"] .admin-ticket-search-kbd.hidden {
  display: none;
}

/* ── Keyboard focus ring on ticket rows (for j/k navigation) ── */
body[data-page="admin"] .admin-ticket-row:focus-visible {
  outline: none;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.6),
    0 0 0 3px rgba(10, 132, 255, 0.38);
}

/* ── Sidebar tab hover + focus polish ───────────────────────── */
body[data-page="admin"] .admin-tab:hover:not(.active) {
  background: linear-gradient(180deg, rgba(10, 132, 255, 0.06), rgba(10, 132, 255, 0.02));
}
body[data-page="admin"] .admin-tab:focus-visible {
  outline: none;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.5),
    0 0 0 3px rgba(10, 132, 255, 0.4);
}

/* ── Chat actions grouping: primary left / secondary right ──── */
body[data-page="admin"] .admin-chat-actions {
  padding: 12px 16px;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.72), rgba(255, 255, 255, 0.55));
  border-top: 1px solid rgba(10, 132, 255, 0.08);
}

/* Make the "Delete" button visually de-emphasized until hovered */
body[data-page="admin"] #admin-chat-delete {
  background: transparent;
  border: 1px solid rgba(239, 68, 68, 0.28);
  color: rgba(239, 68, 68, 0.85);
  box-shadow: none;
}
body[data-page="admin"] #admin-chat-delete:hover {
  background: linear-gradient(180deg, #ff5b54, #e5342b);
  color: #fff;
  border-color: transparent;
  box-shadow: 0 6px 16px rgba(229, 52, 43, 0.32);
}

/* ── "Refresh" button: subtle auto-refresh indicator ────────── */
body[data-page="admin"] #admin-chat-refresh {
  position: relative;
}
body[data-page="admin"] #admin-chat-refresh.is-refreshing > i {
  animation: adminRefreshSpin 0.8s linear infinite;
}
@keyframes adminRefreshSpin {
  from { transform: rotate(0); }
  to   { transform: rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) {
  body[data-page="admin"] #admin-chat-refresh.is-refreshing > i { animation: none; }
}

/* ============================================================
   Power-user UI: help overlay, snippet menu, draft indicator
   ============================================================ */

/* ── Draft indicator on ticket row ─────────────────────────── */
body[data-page="admin"] .admin-ticket-row.has-draft::before {
  content: "";
  position: absolute;
  left: 6px;
  top: 50%;
  transform: translateY(-50%);
  width: 4px;
  height: 26px;
  border-radius: 3px;
  background: linear-gradient(180deg, #FF9F0A, #FFB945);
  box-shadow: 0 0 8px rgba(255, 159, 10, 0.55);
  pointer-events: none;
  z-index: 2;
}
body[data-page="admin"] .admin-ticket-row.has-draft {
  /* Slight left padding bump to leave room for the draft bar */
  padding-left: 16px;
}
body[data-page="admin"] .admin-ticket-row.has-draft::after {
  content: "Draft";
  position: absolute;
  top: 8px;
  right: 8px;
  background: rgba(255, 159, 10, 0.14);
  color: #b36f00;
  border: 1px solid rgba(255, 159, 10, 0.35);
  padding: 1px 6px;
  border-radius: 999px;
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  pointer-events: none;
}

/* ── Keyboard help overlay ─────────────────────────────────── */
.admin-shortcut-help {
  position: fixed;
  inset: 0;
  z-index: 99999;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  animation: adminOverlayIn 220ms cubic-bezier(0.23, 1, 0.32, 1);
}
.admin-shortcut-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(8, 15, 29, 0.42);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.admin-shortcut-card {
  position: relative;
  width: min(560px, 100%);
  max-height: min(80vh, 680px);
  overflow: auto;
  background: linear-gradient(180deg, #fff, #f6f9fe);
  border: 1px solid rgba(10, 132, 255, 0.16);
  border-radius: 20px;
  box-shadow:
    0 40px 100px rgba(17, 45, 93, 0.3),
    inset 0 1px 0 rgba(255, 255, 255, 0.6);
  padding: 22px 26px;
}
.admin-shortcut-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 14px;
}
.admin-shortcut-head h3 {
  margin: 0;
  font-size: 1.15rem;
  font-weight: 700;
  color: #0f1923;
}
.admin-shortcut-close {
  background: transparent;
  border: 1px solid rgba(10, 132, 255, 0.14);
  color: #0f1923;
  width: 32px;
  height: 32px;
  border-radius: 10px;
  cursor: pointer;
  transition: background 140ms ease, color 140ms ease;
}
.admin-shortcut-close:hover {
  background: rgba(239, 68, 68, 0.12);
  color: #ef4444;
  border-color: rgba(239, 68, 68, 0.3);
}
.admin-shortcut-list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.admin-shortcut-list > li {
  display: grid;
  grid-template-columns: 180px 1fr;
  align-items: center;
  gap: 14px;
  padding: 9px 0;
  border-bottom: 1px dashed rgba(10, 132, 255, 0.12);
}
.admin-shortcut-list > li:last-child { border-bottom: none; }
.admin-shortcut-keys {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  flex-wrap: wrap;
}
.admin-shortcut-keys .sep {
  color: rgba(15, 25, 35, 0.4);
  font-size: 0.75rem;
  margin: 0 2px;
}
.admin-shortcut-help kbd,
.admin-snippet-menu kbd,
body[data-page="admin"] .admin-chat-actions kbd {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 22px;
  height: 22px;
  padding: 0 7px;
  border: 1px solid rgba(15, 25, 35, 0.16);
  background: linear-gradient(180deg, #fff, #eef4fc);
  color: rgba(15, 25, 35, 0.82);
  font-family: 'SF Pro Text', 'Inter', monospace;
  font-size: 0.72rem;
  font-weight: 600;
  border-radius: 6px;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.6),
    0 1px 2px rgba(15, 25, 35, 0.06);
}
.admin-shortcut-desc {
  color: rgba(15, 25, 35, 0.78);
  font-size: 0.88rem;
}
.admin-shortcut-footer {
  margin: 18px 0 0;
  padding-top: 14px;
  border-top: 1px solid rgba(10, 132, 255, 0.12);
  font-size: 0.78rem;
}

/* ── Snippet menu popup ────────────────────────────────────── */
.admin-snippet-menu {
  position: fixed;
  z-index: 99998;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.98), rgba(252, 253, 255, 0.94));
  backdrop-filter: blur(22px) saturate(160%);
  -webkit-backdrop-filter: blur(22px) saturate(160%);
  border: 1px solid rgba(10, 132, 255, 0.18);
  border-radius: 16px;
  box-shadow:
    0 30px 60px rgba(17, 45, 93, 0.22),
    inset 0 1px 0 rgba(255, 255, 255, 0.6);
  overflow: hidden;
  animation: adminSnippetIn 200ms cubic-bezier(0.23, 1, 0.32, 1);
}
.admin-snippet-menu-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 16px;
  border-bottom: 1px solid rgba(10, 132, 255, 0.1);
  font-size: 0.78rem;
  font-weight: 600;
  color: rgba(15, 25, 35, 0.7);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.admin-snippet-list {
  list-style: none;
  margin: 0;
  padding: 6px;
  max-height: 320px;
  overflow: auto;
}
.admin-snippet-list > li {
  margin: 0;
  padding: 0;
}
.admin-snippet-item {
  display: flex;
  flex-direction: column;
  gap: 3px;
  width: 100%;
  padding: 10px 14px;
  background: transparent;
  border: none;
  border-radius: 10px;
  cursor: pointer;
  text-align: left;
  transition: background 140ms ease, transform 120ms cubic-bezier(0.23, 1, 0.32, 1);
}
.admin-snippet-item:hover {
  background: rgba(10, 132, 255, 0.08);
  transform: translateX(2px);
}
.admin-snippet-label {
  font-weight: 700;
  font-size: 0.86rem;
  color: #0A84FF;
}
.admin-snippet-preview {
  font-size: 0.78rem;
  color: rgba(15, 25, 35, 0.72);
  line-height: 1.35;
}

/* ── Subtle entry animations ───────────────────────────────── */
@keyframes adminOverlayIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes adminSnippetIn {
  from { opacity: 0; transform: translateY(6px) scale(0.98); }
  to   { opacity: 1; transform: translateY(0)   scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .admin-shortcut-help,
  .admin-snippet-menu { animation: none; }
}

/* ── Chat action button tweaks to accommodate new icons ────── */
body[data-page="admin"] #admin-chat-refresh {
  /* Icon-only button now — make it square */
  width: 34px;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
body[data-page="admin"] #admin-chat-copylink,
body[data-page="admin"] #admin-chat-help-btn {
  width: 34px;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
