/* ==========================================================================
   Okami-ID Admin Console

   Chỉ dùng cho các trang /admin/* render tĩnh (AdminShell.razor).

   File này KHÔNG định nghĩa lại color token — nó dùng lại các biến `:root` của
   `_content/Okami.Shared.Pwa/css/auth.css`, vốn đã được App.razor nạp trước.
   Nhờ vậy admin console giống hệt màn đăng nhập về màu/typography, nhưng có
   layout riêng: sidebar + vùng nội dung trải rộng, không cột thương hiệu,
   không thẻ 3D.

   Lý do tách khỏi auth.css: auth.css thuộc `Okami.Shared.Pwa` và được cả PWA
   dùng chung; màn quản trị chỉ tồn tại trong host Identity.Api.

   Token riêng của console được khai báo trên `.admin-shell` chứ không phải
   `:root`: đây là thang đo dày (dashboard density) chỉ đúng cho màn quản trị,
   đưa lên `:root` sẽ làm co cả màn đăng nhập vốn dùng chung body.
   ========================================================================== */

/* ==========================================================================
   Admin Top Loading Progress Bar
   ========================================================================== */
.admin-top-progress {
  position: fixed;
  top: 0;
  left: 0;
  height: 3.5px;
  width: 0%;
  background: linear-gradient(90deg, #0082FF 0%, #7B61FF 50%, #FF4B72 100%);
  background-size: 200% 100%;
  animation: admin-progress-shimmer 2s infinite linear;
  box-shadow: 0 0 16px rgba(123, 97, 255, 0.9), 0 0 6px rgba(255, 75, 114, 0.7);
  z-index: 99999;
  pointer-events: none;
  opacity: 0;
  border-radius: 0 3px 3px 0;
}

.admin-top-progress::after {
  content: "";
  position: absolute;
  top: -2px;
  right: -3px;
  width: 7.5px;
  height: 7.5px;
  border-radius: 50%;
  background: #ffffff;
  box-shadow: 0 0 8px #ffffff, 0 0 16px #7B61FF;
}

.admin-top-progress.is-done {
  box-shadow: 0 0 20px rgba(0, 130, 255, 0.95);
}

@keyframes admin-progress-shimmer {
  0% { background-position: 0% 50%; }
  50% { background-position: 100% 50%; }
  100% { background-position: 0% 50%; }
}

@keyframes admin-fade-in-up {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

.admin-shell {
  /* Thang khoảng cách dày hơn màn đăng nhập: console hiển thị bảng và nhiều
     cặp nhãn/giá trị, không phải một form 6 dòng. */
  --admin-space-1: 4px;
  --admin-space-2: 8px;
  --admin-space-3: 12px;
  --admin-space-4: 16px;
  --admin-space-5: 20px;
  --admin-space-6: 24px;
  --admin-space-8: 32px;

  --admin-radius-sm: 9px;
  --admin-radius-md: 13px;
  --admin-radius-lg: 18px;

  /* Đường viền/nền lấy sắc tím của brand thay vì xám trung tính, để console
     không rơi về giao diện bootstrap mặc định. */
  --admin-line: rgba(18, 19, 25, 0.08);
  --admin-line-soft: rgba(18, 19, 25, 0.045);
  --admin-surface: rgba(255, 255, 255, 0.68);
  --admin-surface-solid: rgba(255, 255, 255, 0.92);
  --admin-hover: rgba(123, 97, 255, 0.06);
  --admin-focus-ring: 0 0 0 3px rgba(123, 97, 255, 0.28);

  /* Id, ví, hash: dùng mono để so sánh từng ký tự được. Không nạp webfont mới —
     app chạy trong Docker và màn quản trị không đáng một request font nữa. */
  --admin-mono: ui-monospace, SFMono-Regular, "SF Mono", "JetBrains Mono", Menlo, Consolas, monospace;
}

/* auth.css canh giữa body cho khung đăng nhập 1120x720 cố định. Console không
   sửa `body` (App.razor dùng chung cho mọi trang) mà tự trải rộng bên trong:
   một tấm panel bo góc lấp đầy viewport trừ padding của body. */
.admin-shell {
  display: flex;
  width: 100%;
  align-self: stretch;
  min-height: calc(100vh - 48px);
  background: var(--color-panel-bg);
  backdrop-filter: blur(32px);
  -webkit-backdrop-filter: blur(32px);
  border: 1px solid var(--color-panel-border);
  border-radius: 24px;
  box-shadow: var(--shadow-panel);
  overflow: hidden;
  position: relative;
  z-index: 1;
  animation: admin-shell-in 0.4s cubic-bezier(0.16, 1, 0.3, 1) both;
  transition: box-shadow 0.3s ease, border-color 0.3s ease;
}

@keyframes admin-shell-in {
  from {
    opacity: 0;
    transform: scale(0.992) translateY(6px);
  }
  to {
    opacity: 1;
    transform: scale(1) translateY(0);
  }
}

/* Bàn phím: đường tắt nhảy thẳng vào nội dung, không phải tab qua cả sidebar. */
.admin-skip-link {
  position: absolute;
  left: var(--admin-space-4);
  top: var(--admin-space-4);
  z-index: 20;
  padding: 10px 16px;
  border-radius: var(--admin-radius-sm);
  background: #ffffff;
  color: var(--color-purple);
  font-size: 13px;
  font-weight: 700;
  text-decoration: none;
  box-shadow: var(--shadow-panel);
  transform: translateY(-160%);
  transition: transform 0.15s ease;
}

.admin-skip-link:focus-visible {
  transform: translateY(0);
}

/* Mọi phần tử tương tác trong console phải có vòng focus nhìn thấy được —
   console điều khiển được hoàn toàn bằng bàn phím vì nó không có JavaScript. */
.admin-shell a:focus-visible,
.admin-shell button:focus-visible,
.admin-shell input:focus-visible,
.admin-shell select:focus-visible {
  outline: none;
  box-shadow: var(--admin-focus-ring);
  border-radius: var(--admin-radius-sm);
}

/* --------------------------------------------------------------------------
   Sidebar
   -------------------------------------------------------------------------- */
.admin-sidebar {
  width: 244px;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  padding: var(--admin-space-5) var(--admin-space-3) var(--admin-space-4);
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.58) 0%, rgba(255, 255, 255, 0.34) 100%);
  border-right: 1px solid var(--admin-line);
}

.admin-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  color: var(--color-text-main);
  padding: var(--admin-space-1) var(--admin-space-3) var(--admin-space-6);
  transition: opacity 0.2s ease;
}

/* Logo đặt trong một ô có quầng gradient của brand: 32px hình vuông trần trên
   nền kính trông như icon bị bỏ quên, không như dấu hiệu nhận diện. */
.admin-brand-mark {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  flex-shrink: 0;
  border-radius: 11px;
  background: rgba(255, 255, 255, 0.9);
  border: 1px solid rgba(123, 97, 255, 0.16);
  box-shadow: 0 4px 14px rgba(123, 97, 255, 0.16);
  transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1), box-shadow 0.3s ease, border-color 0.3s ease;
}

.admin-brand:hover .admin-brand-mark {
  transform: scale(1.08) rotate(-4deg);
  box-shadow: 0 6px 20px rgba(123, 97, 255, 0.32);
  border-color: rgba(123, 97, 255, 0.35);
}

.admin-brand-logo {
  width: 22px;
  height: 22px;
  transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.admin-brand:hover .admin-brand-logo {
  transform: scale(1.12);
}

.admin-brand-text {
  font-size: 17px;
  font-weight: 800;
  letter-spacing: -0.3px;
  line-height: 1.15;
  transition: color 0.2s ease;
}

.admin-brand-text small {
  display: block;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--color-text-muted);
  margin-top: 3px;
}

.admin-nav {
  display: flex;
  flex-direction: column;
  gap: 4px;
  flex: 1;
}

.admin-nav-heading {
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  color: var(--color-text-muted);
  padding: var(--admin-space-2) var(--admin-space-3) var(--admin-space-1);
}

.admin-nav-link {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  border-radius: var(--admin-radius-md);
  font-size: 14.5px;
  font-weight: 700;
  color: var(--color-text-muted);
  text-decoration: none;
  transition: all 0.24s cubic-bezier(0.16, 1, 0.3, 1);
}

.admin-nav-link:hover {
  background: rgba(123, 97, 255, 0.08);
  color: var(--color-purple);
  transform: translateX(4px);
}

.admin-nav-link.active {
  background: rgba(123, 97, 255, 0.14);
  color: var(--color-purple);
  font-weight: 800;
}

/* Thanh dọc bên trái: khi nhiều mục nav xuất hiện (G7–G9), riêng nền tím nhạt
   không đủ để mắt bắt được mục đang mở trong một lượt quét. */
.admin-nav-link.active::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 3.5px;
  height: 22px;
  border-radius: 0 4px 4px 0;
  background: var(--color-primary-gradient);
  box-shadow: 0 0 10px rgba(123, 97, 255, 0.8), 0 0 4px rgba(255, 75, 114, 0.5);
}

.admin-nav-icon {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  stroke: currentColor;
  fill: none;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform 0.28s cubic-bezier(0.34, 1.56, 0.64, 1), color 0.2s ease;
}

.admin-nav-link:hover .admin-nav-icon {
  transform: scale(1.16) rotate(3deg);
  color: var(--color-purple);
}

/* Chân sidebar: đang đăng nhập là ai, và đường thoát. */
/* Hàng tài khoản ở góc trên bên phải cột nội dung: ngôn ngữ, ai đang đăng nhập,
   và lối ra. Một đường kẻ dưới tách nó khỏi tiêu đề và nút của chính trang, vốn
   nằm ở hàng kế tiếp. */
.admin-topbar {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--admin-space-4);
  padding-bottom: var(--admin-space-3);
  margin-bottom: var(--admin-space-5);
  border-bottom: 1px solid var(--admin-line);
}

.admin-identity {
  display: flex;
  align-items: center;
  gap: 11px;
  min-width: 0;
}

/* Chữ cái đầu thay cho ảnh đại diện: tài khoản quản trị không có avatar, và một
   ô trống ở đây còn tệ hơn không có gì. */
.admin-identity-avatar {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  flex-shrink: 0;
  border-radius: 10px;
  background: var(--color-primary-gradient);
  color: #ffffff;
  font-size: 13.5px;
  font-weight: 800;
  text-transform: uppercase;
  box-shadow: 0 2px 8px rgba(123, 97, 255, 0.3);
}

.admin-identity-email {
  display: block;
  min-width: 0;
  font-size: 13px;
  font-weight: 600;
  color: var(--color-text-muted);
  /* Email dài không được đẩy thanh trên cùng rộng ra; cắt ở đuôi và giữ nguyên
     phần định danh phía trước. */
  max-width: 240px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.admin-signout-form {
  margin: 0;
}

/* Menu ☰ chỉ dùng trên điện thoại (AdminShell.razor): ngôn ngữ, tài khoản và đăng xuất gom vào đây
   thay cho thanh trên cùng. Quy tắc 560px bên dưới mới cho nó hiện ra. */
.admin-menu {
  display: none;
  position: relative;
}

.admin-menu > summary {
  list-style: none;
  cursor: pointer;
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border-radius: var(--admin-radius-md);
  color: var(--color-text-main);
}

.admin-menu > summary::-webkit-details-marker {
  display: none;
}

.admin-menu[open] > summary {
  background: rgba(123, 97, 255, 0.12);
  color: var(--color-purple);
}

.admin-menu-popover {
  position: absolute;
  right: 0;
  top: calc(100% + var(--admin-space-2));
  z-index: 40;
  width: min(280px, calc(100vw - 24px));
  padding: var(--admin-space-2);
  display: grid;
  gap: var(--admin-space-1);
  background: #ffffff;
  border: 1px solid var(--admin-line);
  border-radius: var(--admin-radius-md);
  box-shadow: 0 18px 40px -12px rgba(18, 19, 25, 0.25);
}

.admin-menu-popover .admin-identity {
  padding: 8px 8px 12px;
  border-bottom: 1px solid var(--admin-line);
}

.admin-menu-popover .admin-identity-email {
  display: block;
  max-width: none;
  white-space: normal;
  overflow-wrap: anywhere;
}

.admin-menu-popover .admin-lang {
  justify-content: space-between;
  padding-left: 8px;
}

.admin-menu-popover .admin-lang-label {
  display: inline;
}

.admin-menu-popover .admin-btn {
  width: 100%;
  justify-content: flex-start;
}

/* --------------------------------------------------------------------------
   Vùng nội dung
   -------------------------------------------------------------------------- */
.admin-main {
  flex: 1;
  min-width: 0;
  padding: var(--admin-space-6) var(--admin-space-8) var(--admin-space-8);
  overflow-y: auto;
  animation: admin-fade-in-up 0.35s cubic-bezier(0.16, 1, 0.3, 1);
}

.admin-page-header {
  display: flex;
  align-items: flex-end;
  gap: var(--admin-space-4);
  flex-wrap: wrap;
  margin-bottom: var(--admin-space-5);
}

.admin-page-heading {
  min-width: 0;
  flex: 1;
}

/* Breadcrumb nằm TRÊN tiêu đề, không phải một link "quay lại" ở cuối trang:
   đường thoát phải nhìn thấy được ngay khi mở trang, không phải sau khi cuộn. */
.admin-breadcrumb {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--color-text-muted);
  margin-bottom: 8px;
  flex-wrap: wrap;
}

.admin-breadcrumb a {
  color: var(--color-text-muted);
  text-decoration: none;
  transition: var(--transition-fast);
}

/* Mục đầu ("ユーザー") không bao giờ bị ép xuống hai dòng. Các mục sau có thể là email của bản
   ghi — dài, không khoảng trắng — nên được tự ngắt thay vì đẩy mục cuối ra ngoài màn hình. */
.admin-breadcrumb > :first-child {
  white-space: nowrap;
}

.admin-breadcrumb > :not(:first-child) {
  min-width: 0;
  overflow-wrap: anywhere;
}

.admin-breadcrumb a:hover {
  color: var(--color-purple);
}

.admin-breadcrumb-separator {
  opacity: 0.45;
}

/* The title is a user's display name, or their email when they have none — an address of a wallet
   account holds no space at all, so it is given a break opportunity like the subtitle below (#128). */
.admin-page-title {
  font-size: 28px;
  font-weight: 800;
  letter-spacing: -0.5px;
  line-height: 1.2;
  color: var(--color-text-main);
  overflow-wrap: anywhere;
}

.admin-page-subtitle {
  font-size: 14.5px;
  color: var(--color-text-muted);
  margin-top: 5px;
  word-break: break-word;
}

.admin-page-actions {
  display: flex;
  align-items: center;
  gap: var(--admin-space-2);
  flex-shrink: 0;
}

.admin-panel {
  background: var(--admin-surface);
  border: 1px solid var(--color-panel-border);
  border-radius: var(--admin-radius-lg);
  padding: var(--admin-space-5) var(--admin-space-6);
  box-shadow: 0 10px 30px -5px rgba(18, 19, 25, 0.03);
}

/* Panel không viền, dùng khi nội dung đã tự chia thành các card. Bọc thêm một
   lớp khung quanh nhiều khung con chỉ tạo ra hai đường viền song song. */
.admin-panel.bare {
  background: none;
  border: none;
  border-radius: 0;
  padding: 0;
  box-shadow: none;
  animation: none;
}

/* --------------------------------------------------------------------------
   Card — nhóm thông tin có tiêu đề
   -------------------------------------------------------------------------- */
.admin-card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(380px, 1fr));
  gap: var(--admin-space-4);
  align-items: start;
}

.admin-card {
  background: var(--admin-surface-solid);
  border: 1px solid var(--admin-line);
  border-radius: var(--admin-radius-lg);
  padding: var(--admin-space-5);
  min-width: 0;
  box-shadow: 0 4px 20px rgba(18, 19, 25, 0.03);
  transition: transform 0.28s cubic-bezier(0.16, 1, 0.3, 1),
              box-shadow 0.28s cubic-bezier(0.16, 1, 0.3, 1),
              border-color 0.25s ease;
}

.admin-card:hover {
  transform: translateY(-3.5px);
  border-color: rgba(123, 97, 255, 0.25);
  box-shadow: 0 14px 32px -4px rgba(123, 97, 255, 0.12), 0 4px 14px rgba(18, 19, 25, 0.04);
}

.admin-card.wide {
  grid-column: 1 / -1;
}

.admin-card-title {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--color-text-muted);
  padding-bottom: var(--admin-space-3);
  margin-bottom: var(--admin-space-4);
  border-bottom: 1px solid var(--admin-line-soft);
}

/* Ô icon của tiêu đề card: nền tím rất nhạt + nét icon theo màu brand. Một hàng
   chữ hoa nhỏ màu xám tự nó không phân biệt được năm thẻ với nhau khi lướt mắt. */
.admin-card-icon {
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  flex-shrink: 0;
  border-radius: 8px;
  background: rgba(123, 97, 255, 0.1);
  color: var(--color-purple);
  transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1), background-color 0.2s ease, box-shadow 0.2s ease;
}

.admin-card:hover .admin-card-icon {
  transform: scale(1.15) rotate(-6deg);
  background: rgba(123, 97, 255, 0.18);
  box-shadow: 0 4px 12px rgba(123, 97, 255, 0.25);
}

.admin-card-icon svg {
  width: 15px;
  height: 15px;
  stroke: currentColor;
  fill: none;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* --------------------------------------------------------------------------
   Cặp nhãn / giá trị
   -------------------------------------------------------------------------- */
.admin-fields {
  display: grid;
  gap: var(--admin-space-4);
}

.admin-fields.two-up {
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
}

.admin-field-label {
  display: block;
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.8px;
  text-transform: uppercase;
  color: var(--color-text-muted);
  margin-bottom: 6px;
}

.admin-field-value {
  font-size: 15px;
  font-weight: 600;
  line-height: 1.5;
  color: var(--color-text-main);
  word-break: break-word;
}

/* Giá trị rỗng phải trông như "không có dữ liệu", không như chữ bị mất. */
.admin-field-value.empty {
  color: var(--color-text-muted);
  font-weight: 500;
}

.admin-field-value.mono {
  font-family: var(--admin-mono);
  font-size: 13.5px;
  font-weight: 500;
  letter-spacing: -0.2px;
  overflow-wrap: anywhere;
}

.admin-card-text {
  font-size: 14.5px;
  font-weight: 500;
  line-height: 1.6;
  color: var(--color-text-main);
}

/* Đoạn văn phải giữ độ dài dòng đọc được; trong console rộng 1400px một cảnh báo
   trải hết bề ngang là 200 ký tự một dòng. */
.admin-narrow {
  max-width: 720px;
}

.admin-field-note {
  display: block;
  font-size: 12.5px;
  font-weight: 500;
  color: var(--color-text-muted);
  margin-top: 3px;
}

/* --------------------------------------------------------------------------
   Nút
   -------------------------------------------------------------------------- */
/* auth.css chỉ có `.btn-primary` (nút submit full-width của form đăng nhập) và
   `.signup-link`. Console cần một bộ nút thật: các thao tác ở đây khác nhau về
   hệ quả — xuất dữ liệu cá nhân và khoá tài khoản không thể cùng là link xanh. */
.admin-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 10px 18px;
  border-radius: var(--admin-radius-sm);
  border: 1px solid transparent;
  font-family: inherit;
  font-size: 13.5px;
  font-weight: 700;
  line-height: 1.2;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  position: relative;
  transition: all 0.24s cubic-bezier(0.16, 1, 0.3, 1);
}

.admin-btn:active {
  transform: scale(0.96) translateY(1px);
}

.admin-btn-icon {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  stroke: currentColor;
  fill: none;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform 0.25s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.admin-btn:hover .admin-btn-icon {
  transform: scale(1.15);
}

.admin-btn.primary {
  color: #ffffff;
  background: var(--color-primary-gradient);
  box-shadow: 0 4px 14px rgba(123, 97, 255, 0.28);
}

.admin-btn.primary:hover {
  filter: brightness(1.08);
  transform: translateY(-2px);
  box-shadow: 0 8px 24px rgba(123, 97, 255, 0.42);
}

.admin-btn.secondary {
  color: var(--color-text-main);
  background: var(--color-btn-secondary-bg);
  border-color: var(--color-btn-secondary-border);
  box-shadow: 0 2px 6px rgba(18, 19, 25, 0.03);
}

.admin-btn.secondary:hover {
  background: var(--color-btn-secondary-hover-bg);
  border-color: rgba(123, 97, 255, 0.3);
  color: var(--color-purple);
  transform: translateY(-1.5px);
  box-shadow: 0 6px 16px rgba(123, 97, 255, 0.1);
}

.admin-btn.ghost {
  color: var(--color-text-muted);
  background: transparent;
}

.admin-btn.ghost:hover {
  background: rgba(123, 97, 255, 0.08);
  color: var(--color-purple);
  transform: translateX(2px);
}

/* Khoá tài khoản là hành động phá vỡ — nó không được trông giống "Xuất CSV". */
.admin-btn.danger {
  color: var(--color-error-text);
  background: var(--color-error-bg);
  border-color: var(--color-error-border);
}

.admin-btn.danger:hover {
  background: var(--color-error-text);
  color: #ffffff;
  border-color: var(--color-error-text);
  transform: translateY(-1.5px);
  box-shadow: 0 6px 18px rgba(239, 68, 68, 0.25);
}

.admin-btn.solid-danger {
  color: #ffffff;
  background: var(--color-error-text);
  box-shadow: 0 4px 12px rgba(239, 68, 68, 0.24);
}

.admin-btn.solid-danger:hover {
  filter: brightness(1.08);
  transform: translateY(-2px);
  box-shadow: 0 8px 22px rgba(239, 68, 68, 0.42);
}

/* --------------------------------------------------------------------------
   Thanh công cụ & form tìm kiếm
   -------------------------------------------------------------------------- */
.admin-toolbar {
  display: flex;
  align-items: flex-end;
  gap: var(--admin-space-3);
  flex-wrap: wrap;
}

/* Đẩy nhóm hành động sang phải: ô tìm kiếm bên trái, thao tác trên kết quả bên
   phải — hai vai trò khác nhau thì không xếp cạnh nhau như một danh sách link. */
.admin-toolbar-spacer {
  flex: 1;
  min-width: var(--admin-space-4);
}

/* Form trong màn quản trị không kéo dài hết bề ngang panel — một ô input rộng
   1100px không dễ đọc hơn ô rộng 420px. */
.admin-search {
  display: flex;
  align-items: flex-end;
  gap: 12px;
  flex: 0 1 540px;
  min-width: 280px;
}

.admin-search .input-group {
  flex: 1;
  min-width: 0;
  margin-bottom: 0;
}

.admin-search .input-label {
  font-size: 11.5px;
  font-weight: 800;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--color-text-muted);
  margin-bottom: 8px;
  display: block;
}

.admin-search .input-wrapper.has-icon {
  position: relative;
  display: flex;
  align-items: center;
}

.admin-search .input-icon {
  position: absolute;
  left: 14px;
  width: 18px;
  height: 18px;
  stroke: var(--color-purple);
  fill: none;
  stroke-width: 2.2;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0.65;
  pointer-events: none;
  transition: opacity 0.25s ease, transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1), stroke 0.2s ease;
}

.admin-search .input-wrapper.has-icon:focus-within .input-icon {
  opacity: 1;
  transform: scale(1.18) rotate(-4deg);
  stroke: var(--color-purple);
}

.admin-search .form-input {
  width: 100%;
  padding: 12px 16px;
  font-size: 14.5px;
  font-weight: 500;
  border-radius: 12px;
  background: #ffffff;
  border: 1.5px solid rgba(123, 97, 255, 0.2);
  box-shadow: 0 2px 8px rgba(18, 19, 25, 0.03);
  transition: all 0.25s cubic-bezier(0.16, 1, 0.3, 1);
}

.admin-search .input-wrapper.has-icon .form-input {
  padding-left: 42px;
}

.admin-search .form-input:focus {
  border-color: var(--color-purple);
  box-shadow: 0 0 0 4px rgba(123, 97, 255, 0.18), 0 8px 24px rgba(123, 97, 255, 0.12);
  transform: translateY(-1px);
  outline: none;
}

/* Xếp dọc các khối của một trang khi trang tự dựng bố cục (`Bare`), thay cho
   một loạt margin rời rạc trên từng khối. */
.admin-stack {
  display: grid;
  gap: var(--admin-space-4);
}

/* --------------------------------------------------------------------------
   Bảng
   -------------------------------------------------------------------------- */
.admin-table-wrapper {
  /* Bảng rộng cuộn trong khung của chính nó, không đẩy cả trang cuộn ngang. */
  overflow-x: auto;
  border: 1px solid var(--admin-line);
  border-radius: var(--admin-radius-lg);
  background: var(--admin-surface-solid);
  box-shadow: 0 10px 30px -5px rgba(18, 19, 25, 0.04);
}

.admin-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 14.5px;
}

.admin-table th {
  position: sticky;
  top: 0;
  z-index: 1;
  text-align: left;
  padding: 13px var(--admin-space-4);
  font-size: 11.5px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 1.1px;
  color: var(--color-text-muted);
  background: rgba(246, 248, 251, 0.94);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--admin-line);
  white-space: nowrap;
}

.admin-table td {
  padding: 13px var(--admin-space-4);
  border-bottom: 1px solid var(--admin-line-soft);
  vertical-align: middle;
}

.admin-table tbody tr:last-child td {
  border-bottom: none;
}

.admin-table tbody tr {
  transition: background-color 0.2s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.2s ease;
}

.admin-table tbody tr:hover {
  background: rgba(123, 97, 255, 0.055);
}

/* Cột trạng thái là câu trả lời, không phải phần đuôi thừa: ghim nó vào chiều
   rộng của chính nó thay vì để bảng kéo nó ra tận rìa phải màn hình. */
.admin-table .col-status {
  width: 1%;
  white-space: nowrap;
}

/* Ngày và badge không được ngắt dòng — cột co lại tới mức đó thì nên cuộn ngang,
   chứ không phải bẻ "2026-04-22" thành hai dòng. */
.admin-table td.nowrap {
  white-space: nowrap;
}

.admin-table .col-name {
  width: 30%;
}

.admin-table a {
  color: var(--color-text-main);
  text-decoration: none;
  font-weight: 700;
  transition: color 0.18s ease;
}

.admin-table a:hover {
  color: var(--color-purple);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* Chữ cái đầu trên nền màu suy ra từ chính id của tài khoản: cùng một hàng luôn
   ra cùng một màu, nên mắt nhận lại được một dòng đã xem mà không phải đọc email.
   Màu chỉ để nhận dạng — mọi thông tin trạng thái vẫn nằm ở cột Status. */
.admin-avatar {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  flex-shrink: 0;
  border-radius: 11px;
  font-size: 13.5px;
  font-weight: 800;
  text-transform: uppercase;
  color: hsl(var(--admin-avatar-hue, 250) 62% 34%);
  background: hsl(var(--admin-avatar-hue, 250) 78% 94%);
  border: 1px solid hsl(var(--admin-avatar-hue, 250) 70% 86%);
  box-shadow: 0 2px 6px rgba(123, 97, 255, 0.08);
  transition: transform 0.28s cubic-bezier(0.34, 1.56, 0.64, 1), box-shadow 0.28s ease;
}

.admin-table tbody tr:hover .admin-avatar {
  transform: scale(1.1) rotate(3deg);
  box-shadow: 0 4px 14px rgba(123, 97, 255, 0.25);
}

.admin-row-identity {
  display: flex;
  align-items: center;
  gap: var(--admin-space-3);
  min-width: 0;
}

/* Ô định danh chính của hàng: email, và ngay dưới là id rút gọn. Hàng không có
   email (tài khoản ví) vẫn phải nhận ra được — dòng dưới là thứ duy nhất còn lại. */
.admin-cell-primary {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  /* Email và địa chỉ ví không có khoảng trắng: không cho ngắt thì chúng quyết định độ rộng tối
     thiểu của cả bảng, và ở 768px cột trạng thái bị đẩy ra ngoài mép phải (#92). */
  overflow-wrap: anywhere;
}

/* Ô định danh là một link cả khối, nhưng gạch chân cả id 36 ký tự thì mắt không
   còn bắt được đâu là dòng chính — chỉ dòng trên được gạch. */
.admin-table a.admin-row-identity:hover {
  text-decoration: none;
}

.admin-table a.admin-row-identity:hover .admin-cell-primary > span:first-child {
  text-decoration: underline;
  text-underline-offset: 3px;
}

.admin-cell-secondary {
  font-family: var(--admin-mono);
  font-size: 12.5px;
  font-weight: 500;
  color: var(--color-text-muted);
  letter-spacing: -0.2px;
}

.admin-cell-muted {
  color: var(--color-text-muted);
}

/* Trạng thái tài khoản — câu hỏi hay gặp nhất khi support mở danh sách.
   Có chấm màu VÀ chữ: WCAG cấm truyền thông tin chỉ bằng màu. */
.admin-status {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 5px 12px 5px 10px;
  border-radius: 999px;
  border: 1px solid transparent;
  font-size: 12px;
  font-weight: 700;
  white-space: nowrap;
  transition: transform 0.2s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.2s ease;
}

.admin-status:hover {
  transform: translateY(-1px) scale(1.03);
}

.admin-status::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: currentColor;
  flex-shrink: 0;
  box-shadow: 0 0 6px currentColor;
}

.admin-status.ok {
  background: var(--color-success-bg);
  color: #15803d;
  border-color: var(--color-success-border);
}

.admin-status.ok::before {
  animation: admin-pulse-ok 2.4s ease-out infinite;
}

.admin-status.warn {
  background: #fff7ed;
  color: #c2610a;
  border-color: rgba(217, 119, 6, 0.22);
}

.admin-status.warn::before {
  animation: admin-pulse-warn 2.2s ease-out infinite;
}

.admin-status.bad {
  background: var(--color-error-bg);
  color: #dc2626;
  border-color: var(--color-error-border);
}

.admin-status.bad::before {
  animation: admin-pulse-bad 1.8s ease-out infinite;
}

.admin-pagination {
  margin-top: var(--admin-space-4);
  display: flex;
  gap: var(--admin-space-3);
  align-items: center;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--color-text-muted);
}

.admin-pagination-count {
  flex: 1;
  text-align: center;
  font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------------------------
   Dòng thời gian (nhật ký thao tác quản trị)
   -------------------------------------------------------------------------- */
.admin-timeline {
  display: grid;
  gap: var(--admin-space-3);
}

.admin-timeline-item {
  position: relative;
  padding-left: var(--admin-space-4);
  font-size: 13px;
  line-height: 1.5;
}

.admin-timeline-item::before {
  content: "";
  position: absolute;
  left: 0;
  top: 7px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--color-purple);
  opacity: 0.5;
}

.admin-timeline-item.failed::before {
  background: var(--color-error-text);
  opacity: 1;
}

.admin-timeline-time {
  font-family: var(--admin-mono);
  font-size: 11.5px;
  color: var(--color-text-muted);
  letter-spacing: -0.2px;
}

.admin-timeline-body {
  font-weight: 600;
  overflow-wrap: anywhere;
}

/* --------------------------------------------------------------------------
   Trạng thái rỗng
   -------------------------------------------------------------------------- */
.admin-empty {
  display: grid;
  justify-items: center;
  gap: var(--admin-space-2);
  padding: 56px var(--admin-space-5);
  text-align: center;
  border: 1px dashed var(--admin-line);
  border-radius: var(--admin-radius-lg);
  background: rgba(255, 255, 255, 0.4);
}

.admin-empty-icon {
  width: 30px;
  height: 30px;
  stroke: var(--color-text-muted);
  fill: none;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0.55;
}

.admin-empty-title {
  font-size: 14.5px;
  font-weight: 700;
}

.admin-empty-hint {
  font-size: 12.5px;
  color: var(--color-text-muted);
  max-width: 380px;
}

/* Alert của auth.css mặc định ẩn (`display: none`) và được form bật lên; trong
   console nó luôn hiện khi được render, nên khỏi cần style inline ở từng trang. */
.admin-alert {
  display: flex;
  margin-bottom: var(--admin-space-5);
}

/* --------------------------------------------------------------------------
   Chuyển động

   Các trang này render tĩnh và tải lại toàn trang cho mỗi lần tìm kiếm hay đổi
   trang — không có JavaScript nào cập nhật tại chỗ. Một lượt vào ngắn khi trang
   dựng lên là thứ nói cho người dùng biết trang đã đổi; thiếu nó, mỗi lần bấm là
   một cú nháy trắng.

   Chỉ animate `opacity` và `transform`: hai thuộc tính này chạy trên compositor,
   không gây reflow và không đẩy layout (CLS).
   -------------------------------------------------------------------------- */
@keyframes admin-rise {
  from {
    opacity: 0;
    transform: translateY(14px) scale(0.988);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

@keyframes admin-slide-in {
  from {
    opacity: 0;
    transform: translateX(-16px);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}

@keyframes admin-fade {
  from {
    opacity: 0;
    transform: translateY(6px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes admin-bar-grow {
  0% {
    transform: translateY(-50%) scaleY(0.1);
    opacity: 0;
  }
  60% {
    transform: translateY(-50%) scaleY(1.15);
    opacity: 1;
  }
  100% {
    transform: translateY(-50%) scaleY(1);
    opacity: 1;
  }
}

/* Nhịp thở pulsing mềm mại cho các trạng thái chấm tròn */
@keyframes admin-pulse-ok {
  0%, 100% {
    box-shadow: 0 0 0 0 rgba(22, 163, 74, 0.55);
  }
  50% {
    box-shadow: 0 0 0 4.5px rgba(22, 163, 74, 0);
  }
}

@keyframes admin-pulse-warn {
  0%, 100% {
    box-shadow: 0 0 0 0 rgba(217, 119, 6, 0.55);
  }
  50% {
    box-shadow: 0 0 0 4.5px rgba(217, 119, 6, 0);
  }
}

@keyframes admin-pulse-bad {
  0%, 70%, 100% {
    box-shadow: 0 0 0 0 rgba(220, 38, 38, 0.6);
  }
  35% {
    box-shadow: 0 0 0 5.5px rgba(220, 38, 38, 0);
  }
}

.admin-sidebar {
  animation: admin-slide-in 0.4s cubic-bezier(0.16, 1, 0.3, 1) both;
}

.admin-page-header {
  animation: admin-rise 0.42s cubic-bezier(0.16, 1, 0.3, 1) both;
}

.admin-panel {
  animation: admin-rise 0.42s cubic-bezier(0.16, 1, 0.3, 1) 0.04s both;
}

.admin-alert {
  animation: admin-rise 0.36s cubic-bezier(0.16, 1, 0.3, 1) both;
}

.admin-nav-link.active::before {
  animation: admin-bar-grow 0.35s cubic-bezier(0.34, 1.56, 0.64, 1) 0.1s both;
}

@keyframes admin-card-pop {
  0% {
    opacity: 0;
    transform: translateY(22px) scale(0.965);
  }
  65% {
    opacity: 1;
    transform: translateY(-3.5px) scale(1.006);
  }
  100% {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

/* Thẻ vào lệch nhau theo nhịp nảy (spring bounce) rõ ràng */
.admin-card {
  animation: admin-card-pop 0.48s cubic-bezier(0.16, 1, 0.3, 1) both;
}

.admin-card:nth-child(1) { animation-delay: 0.10s; }
.admin-card:nth-child(2) { animation-delay: 0.20s; }
.admin-card:nth-child(3) { animation-delay: 0.30s; }
.admin-card:nth-child(4) { animation-delay: 0.38s; }
.admin-card:nth-child(5) { animation-delay: 0.46s; }
.admin-card:nth-child(n + 6) { animation-delay: 0.52s; }

.admin-table-wrapper {
  animation: admin-rise 0.42s cubic-bezier(0.16, 1, 0.3, 1) 0.05s both;
}

/* Các hàng bảng lướt lên và hiện ra mượt mà theo nhịp cascade */
.admin-table tbody tr {
  animation: admin-fade 0.32s cubic-bezier(0.16, 1, 0.3, 1) both;
}

.admin-table tbody tr:nth-child(1) { animation-delay: 0.04s; }
.admin-table tbody tr:nth-child(2) { animation-delay: 0.07s; }
.admin-table tbody tr:nth-child(3) { animation-delay: 0.10s; }
.admin-table tbody tr:nth-child(4) { animation-delay: 0.13s; }
.admin-table tbody tr:nth-child(5) { animation-delay: 0.16s; }
.admin-table tbody tr:nth-child(6) { animation-delay: 0.19s; }
.admin-table tbody tr:nth-child(7) { animation-delay: 0.22s; }
.admin-table tbody tr:nth-child(8) { animation-delay: 0.25s; }
.admin-table tbody tr:nth-child(n + 9) { animation-delay: 0.28s; }

.admin-empty {
  animation: admin-rise 0.4s cubic-bezier(0.16, 1, 0.3, 1) 0.08s both;
}

/* Vệt sáng chạy qua theo con trỏ ở hàng đang trỏ tới */
.admin-table tbody tr:hover td:first-child {
  box-shadow: inset 3.5px 0 0 var(--color-purple);
  transition: box-shadow 0.2s cubic-bezier(0.16, 1, 0.3, 1);
}

/* --------------------------------------------------------------------------
   Responsive — sidebar xếp thành hàng ngang trên màn hẹp
   -------------------------------------------------------------------------- */
/* --------------------------------------------------------------------------
   Bộ chuyển ngữ (日本語 / English)

   Nằm ở thanh trên cùng của cột nội dung trên các màn console, và ghim ở góc
   trên bên phải trên hai màn dùng AccountShell (đăng nhập, đổi mật khẩu) —
   hai màn đó không có thanh trên cùng để đặt vào.
   -------------------------------------------------------------------------- */
.admin-lang {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13.5px;
}

.admin-lang.floating {
  position: absolute;
  top: 16px;
  right: 24px;
  z-index: 10;
}

.admin-lang-label {
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  color: var(--color-text-muted);
  margin-right: 3px;
}

.admin-lang.floating .admin-lang-label {
  display: none;
}

.admin-lang-link {
  color: var(--color-text-muted);
  text-decoration: none;
  font-weight: 500;
  padding: 3px 6px;
  border-radius: 6px;
  transition: var(--transition-fast);
}

.admin-lang-link:hover {
  color: var(--color-text-main);
  background: rgba(18, 19, 25, 0.04);
  text-decoration: none;
}

/* Ngôn ngữ đang dùng không phải link đi đâu cả — nó là trạng thái hiện tại. */
.admin-lang-link.active {
  color: var(--color-purple);
  font-weight: 700;
  background: rgba(123, 97, 255, 0.09);
  text-decoration: none;
  cursor: default;
}

.admin-lang-separator {
  color: var(--admin-line);
  opacity: 0.6;
}

/* Vùng bấm 44px cho ngón tay. Ngưỡng 900px chứ không phải 860px: bộ chuyển ngữ cũng nằm trên
   hai màn dùng AccountShell (đăng nhập, đổi mật khẩu), vốn đổi bố cục ở 900px. */
@media (max-width: 900px) {
  .admin-lang-link {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: 0 10px;
  }
}

@media (max-width: 1024px) {
  .admin-main {
    padding: var(--admin-space-5) var(--admin-space-6) var(--admin-space-6);
  }
}

@media (max-width: 860px) {
  .admin-shell {
    flex-direction: column;
    border-radius: 20px;
  }

  .admin-sidebar {
    width: 100%;
    flex-direction: row;
    align-items: center;
    gap: var(--admin-space-3);
    padding: 10px var(--admin-space-4);
    border-right: none;
    border-bottom: 1px solid var(--admin-line);
    overflow-x: auto;
  }

  .admin-brand {
    padding: 0 var(--admin-space-2) 0 0;
  }

  .admin-brand-text small {
    display: none;
  }

  .admin-nav {
    flex-direction: row;
    flex: 1;
  }

  .admin-nav-heading {
    display: none;
  }

  .admin-nav-link.active::before {
    display: none;
  }

  /* Thanh trên cùng hẹp lại thì nhãn "言語" là thứ bỏ được đầu tiên: hai lựa
     chọn ngôn ngữ tự nó đã nói lên đang chọn cái nào. */
  .admin-topbar {
    flex-wrap: wrap;
    gap: var(--admin-space-2);
  }

  .admin-lang-label {
    display: none;
  }

  .admin-identity-email {
    max-width: 140px;
  }

  .admin-page-header {
    align-items: flex-start;
  }

  /* Ba nút của màn chi tiết user không vừa một hàng 375px; không cho xuống dòng thì nút thứ
     ba bị cắt ở mép phải (#92). */
  .admin-page-actions {
    width: 100%;
    flex-wrap: wrap;
  }

  /* Vùng bấm 44px cho ngón tay. */
  .admin-brand,
  .admin-nav-link,
  .admin-btn,
  .admin-row-identity {
    min-height: 44px;
  }

  /* Link breadcrumb chỉ cao bằng dòng chữ: phần đệm nới vùng bấm ra 44px, margin âm trả lại
     đúng chỗ đó để tiêu đề bên dưới không bị đẩy xuống. */
  .admin-breadcrumb a {
    padding: 14px 0;
    margin: -14px 0;
  }

  /* Dưới 16px, iOS Safari tự zoom trang khi ô nhập được focus. */
  .admin-search .form-input {
    font-size: 16px;
  }

  /* Không chữ nào trên điện thoại nhỏ hơn 12px. */
  .admin-search .input-label,
  .admin-field-label,
  .admin-table th,
  .admin-timeline-time {
    font-size: 12px;
  }

  .admin-main {
    padding: var(--admin-space-5) var(--admin-space-4) var(--admin-space-6);
  }

  .admin-panel {
    padding: var(--admin-space-4) var(--admin-space-4);
  }

  .admin-card-grid {
    grid-template-columns: 1fr;
  }

  .admin-search {
    flex: 1 1 100%;
    min-width: 0;
  }
}

@media (max-width: 560px) {
  /* Console trải hết màn hình thay vì là một tấm card nổi giữa lề 16px của body: ở bề ngang
     này, 32px lề là gần một phần mười màn hình. Chỉ áp cho body có chứa console, giống
     `body:has(.account-page)` của account.css. */
  /* `clip`, không phải `hidden` như auth.css: `overflow-x: hidden` biến body thành vùng cuộn, và
     phần tử sticky bên trong khi đó bám vào body (không cuộn) thay vì màn hình. */
  body:has(.admin-shell) {
    padding: 0;
    overflow-x: clip;
  }

  /* Hai màn đăng nhập/đổi mật khẩu admin dùng AccountShell, trên điện thoại không còn card:
     bộ chuyển ngữ nằm vào thanh 60px trên cùng (auth.css). */
  .admin-lang.floating {
    top: 8px;
    right: 12px;
  }

  /* Cả hai đều phải hết là vùng cuộn/cắt, nếu không thanh trên cùng và ô tìm kiếm không bám được
     theo màn hình khi cuộn. */
  .admin-shell {
    min-height: 100vh;
    border: none;
    border-radius: 0;
    overflow: visible;
  }

  .admin-main {
    overflow: visible;
  }

  /* Một thanh duy nhất ở trên cùng (#92, phương án C): logo, mục điều hướng, và menu ☰ thay cho
     hàng ngôn ngữ / tài khoản / đăng xuất vốn chiếm ba dòng trước tiêu đề. */
  .admin-sidebar {
    position: sticky;
    top: 0;
    z-index: 30;
    overflow: visible;
    background: rgba(255, 255, 255, 0.96);
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
    animation: none;
  }

  .admin-menu {
    display: block;
  }

  .admin-topbar {
    display: none;
  }

  /* Nút chỉ còn icon (xuất CSV, tìm kiếm). Nhãn vẫn nằm trong DOM làm tên truy cập được. */
  .admin-btn-icon-phone {
    width: 44px;
    padding: 0;
  }

  .admin-btn-icon-phone .admin-btn-label,
  .admin-search-form .input-label {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }

  /* Nút xuất CSV đứng cạnh tiêu đề thay vì chiếm một hàng riêng. */
  .admin-page-actions:has(> .admin-btn-icon-phone:only-child) {
    width: auto;
  }

  /* Ô tìm kiếm bám ngay dưới thanh trên cùng khi cuộn danh sách. */
  .admin-search-form {
    position: sticky;
    top: 64px;
    z-index: 20;
    margin-inline: calc(-1 * var(--admin-space-4));
    padding: var(--admin-space-2) var(--admin-space-4);
    background: linear-gradient(180deg, var(--color-bg-base) 80%, rgba(246, 248, 251, 0));
  }

  .admin-search {
    gap: var(--admin-space-2);
  }

  /* Mỗi user một hàng thấp (#92, phương án C): avatar + email ở dòng trên, tên và ngày tạo ở dòng
     dưới, trạng thái bên phải — gấp đôi số user trên một màn so với dạng thẻ. Bảng cuộn ngang từng
     giấu mất cột trạng thái, đúng thứ support mở danh sách để xem. Tiêu đề cột ẩn khỏi mắt nhưng
     vẫn còn cho trình đọc màn hình. */
  .admin-table thead {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }

  .admin-table,
  .admin-table tbody {
    display: block;
  }

  /* Cột 1 = avatar + khoảng cách (34 + 12), cột 2 = tên, cột 3 = ngày, cột 4 = trạng thái. */
  .admin-table tr {
    position: relative;
    display: grid;
    grid-template-columns: 46px minmax(0, 1fr) auto auto;
    align-items: center;
    padding: 10px var(--admin-space-3);
    border-bottom: 1px solid var(--admin-line-soft);
  }

  .admin-table tbody tr:last-child {
    border-bottom: none;
  }

  .admin-table td {
    display: block;
    padding: 0;
    border-bottom: none;
  }

  .admin-table td:nth-child(1) {
    grid-column: 1 / 4;
    grid-row: 1;
    min-width: 0;
  }

  /* Dòng thứ hai kéo lên cạnh avatar thay vì nằm dưới nó, để hàng chỉ cao hơn avatar một chút. */
  .admin-table td:nth-child(2),
  .admin-table td:nth-child(3) {
    grid-row: 2;
    margin-top: -14px;
    min-width: 0;
    font-size: 12.5px;
    color: var(--color-text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .admin-table td:nth-child(2) {
    grid-column: 2;
  }

  .admin-table td:nth-child(3) {
    grid-column: 3;
    padding-left: var(--admin-space-2);
  }

  .admin-table td:nth-child(4) {
    grid-column: 4;
    grid-row: 1 / span 2;
    display: flex;
    align-items: center;
    gap: 2px;
    padding-left: var(--admin-space-2);
  }

  .admin-table td:nth-child(4)::after {
    content: "›";
    font-size: 20px;
    line-height: 1;
    color: #b6bdcc;
  }

  /* Id / địa chỉ ví rời khỏi danh sách (vẫn tìm được, và có trên màn chi tiết); email cắt bằng "…". */
  .admin-row-identity {
    align-items: flex-start;
  }

  .admin-row-identity .admin-cell-secondary {
    display: none;
  }

  .admin-row-identity .admin-cell-primary > span:first-child {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  /* Cả hàng là một vùng bấm mở bản ghi, không chỉ dòng email. */
  .admin-table a.admin-row-identity::after {
    content: "";
    position: absolute;
    inset: 0;
  }

  /* Vệt tím bên trái chỉ hợp với ô đầu của một hàng bảng; trên thẻ nó chỉ tô nửa trên. */
  .admin-table tbody tr:hover td:first-child {
    box-shadow: none;
  }
}

@media (max-width: 420px) {
  .admin-page-title {
    font-size: 21px;
  }

  /* Email đầy đủ không còn chỗ; chỉ giữ chữ cái đầu, phần còn lại vẫn đọc được
     bằng title. */
  .admin-identity-email {
    display: none;
  }
}

/* Chuyển động ở đây chỉ là trang trí (nhấc nút, đổi nền hàng); người đã tắt
   hiệu ứng không mất thông tin nào khi bỏ chúng đi. */
@media (prefers-reduced-motion: reduce) {
  .admin-shell *,
  .admin-shell *::before,
  .admin-shell *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    /* Không bỏ delay thì phần tử vẫn nằm ở khung hình `from` (opacity 0) suốt
       thời gian chờ — tắt hiệu ứng lại thành trang chớp nháy. */
    animation-delay: 0ms !important;
  }

  .admin-btn:hover {
    transform: none;
  }
}

/* --------------------------------------------------------------------------
   Nhật ký audit (#35 G9) — /admin/audit và khung hoạt động ở trang chi tiết user
   -------------------------------------------------------------------------- */
.audit-filters {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: var(--admin-space-3) 14px;
  padding: 18px;
  border: 1px solid var(--admin-line);
  border-radius: var(--admin-radius-lg);
  background: var(--admin-surface-solid);
  box-shadow: 0 10px 30px -5px rgba(18, 19, 25, 0.04);
}

.audit-filters .input-label {
  display: block;
  margin-bottom: 7px;
  font-size: 11.5px;
  font-weight: 800;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--color-text-muted);
}

.audit-filters .form-input {
  width: 100%;
  box-sizing: border-box;
  padding: 11px 14px;
  font-size: 14px;
  font-weight: 500;
  border-radius: 12px;
  background: #ffffff;
  border: 1.5px solid rgba(123, 97, 255, 0.2);
}

.audit-filters .form-input:focus {
  outline: none;
  border-color: var(--color-purple);
  box-shadow: var(--admin-focus-ring);
}

.audit-filter-actions {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
}

.audit-spacer {
  flex: 1;
}

.audit-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--admin-space-2);
}

.audit-chip {
  display: inline-flex;
  align-items: center;
  padding: 6px 12px;
  border-radius: 999px;
  font-size: 12.5px;
  font-weight: 700;
  color: var(--color-text-muted);
  text-decoration: none;
  background: rgba(255, 255, 255, 0.7);
  border: 1px solid var(--admin-line);
}

.audit-chip:hover,
.audit-chip.on {
  color: var(--color-purple);
  border-color: rgba(123, 97, 255, 0.35);
  background: rgba(123, 97, 255, 0.08);
}

.audit-note {
  margin: 0;
  padding: 10px 14px;
  font-size: 12.5px;
  color: var(--color-text-muted);
  border-radius: 12px;
  background: rgba(123, 97, 255, 0.05);
  border: 1px dashed rgba(123, 97, 255, 0.25);
}

.audit-time,
.audit-mono {
  font-family: var(--admin-mono);
  font-size: 12px;
  white-space: nowrap;
}

.audit-actor {
  display: flex;
  align-items: center;
  gap: var(--admin-space-2);
  min-width: 180px;
}

.audit-kind {
  display: inline-block;
  padding: 2px 8px;
  margin-right: 4px;
  border-radius: 7px;
  font-size: 10.5px;
  font-weight: 800;
  letter-spacing: 0.4px;
  white-space: nowrap;
  color: #64748b;
  background: #eef1f5;
}

.audit-kind.admin { color: #6d28d9; background: #f3efff; }
.audit-kind.user { color: #0369a1; background: #e8f4ff; }
.audit-kind.system { color: #b45309; background: #fff4e0; }

.audit-action {
  font-weight: 700;
}

.audit-action code {
  display: block;
  font-family: var(--admin-mono);
  font-size: 11.5px;
  font-weight: 500;
  color: var(--color-text-muted);
}

.audit-details {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  max-width: 280px;
}

.audit-kv {
  padding: 2px 7px;
  border-radius: 6px;
  font-family: var(--admin-mono);
  font-size: 11px;
  white-space: nowrap;
  background: rgba(18, 19, 25, 0.045);
}

/* Một hàng thất bại có vệt đỏ bên trái, để một chuỗi lần bị từ chối nhìn thấy mà không phải đọc từng dòng. */
.audit-table tbody tr.failed td:first-child {
  box-shadow: inset 3px 0 0 #ef4444;
}

/* Nhật ký audit trên điện thoại: bố cục thẻ của danh sách user (4 cột) không hợp với 7 cột ở đây — các ô chồng lên nhau.
   Mỗi bản ghi thành một thẻ đọc từ trên xuống: thời điểm + kết quả, hành động, người thực hiện, đối tượng, chi tiết, IP. */
@media (max-width: 560px) {
  .admin-table.audit-table tr {
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 4px var(--admin-space-2);
    align-items: start;
    padding: var(--admin-space-3);
  }

  .admin-table.audit-table td {
    display: block;
    grid-column: 1 / -1;
    grid-row: auto;
    margin-top: 0;
    padding-left: 0;
    min-width: 0;
    font-size: 13px;
    color: inherit;
    white-space: normal;
    overflow: visible;
    overflow-wrap: anywhere;
  }

  .admin-table.audit-table td:nth-child(1) { grid-column: 1; grid-row: 1; color: var(--color-text-muted); }
  .admin-table.audit-table td:nth-child(5) { grid-column: 2; grid-row: 1; }
  /* The user list's "›" belongs to its 4th cell; here the 4th cell is the target. */
  .admin-table.audit-table td:nth-child(4)::after { content: none; }
  .admin-table.audit-table td:nth-child(3) { grid-row: 2; }
  .admin-table.audit-table td:nth-child(2) { grid-row: 3; }
  .admin-table.audit-table td:nth-child(4) { grid-row: 4; }
  .admin-table.audit-table td:nth-child(7) { grid-row: 5; }
  .admin-table.audit-table td:nth-child(6) { grid-row: 6; color: var(--color-text-muted); }

  .audit-actor {
    min-width: 0;
    flex-wrap: wrap;
  }

  .audit-details {
    max-width: none;
  }

  /* Vệt đỏ cho cả thẻ, không chỉ ô đầu. */
  .audit-table tbody tr.failed td:first-child {
    box-shadow: none;
  }

  .audit-table tbody tr.failed {
    box-shadow: inset 3px 0 0 #ef4444;
  }
}

/* ==========================================================================
   Dashboard (/admin, add-admin-dashboard)

   Thẻ số liệu, biểu đồ cột SVG vẽ phía server và thanh theo provider. Dùng lại token của console
   (--admin-*), cùng màu với .admin-status cho trạng thái cảnh báo, không thêm font hay thư viện.
   ========================================================================== */
.admin-dashboard {
  display: flex;
  flex-direction: column;
  gap: var(--admin-space-4);
}

/* A card title is an h2 for the outline but keeps the console's small uppercase label. */
.admin-dashboard h2.admin-card-title {
  margin-top: 0;
}

.admin-dashboard .admin-card-title h2 {
  margin: 0;
  font: inherit;
  letter-spacing: inherit;
}

.admin-dashboard .admin-card-title {
  justify-content: space-between;
}

.admin-card-link {
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: 0.2px;
  text-transform: none;
  color: var(--color-purple);
  text-decoration: none;
}

.admin-card-link:hover,
.admin-card-link:focus-visible {
  text-decoration: underline;
}

.admin-dashboard-stamp {
  font-family: var(--admin-mono);
  font-size: 12.5px;
  color: var(--color-text-muted);
  white-space: nowrap;
}

.admin-dashboard-split {
  display: grid;
  grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
  gap: var(--admin-space-4);
  align-items: start;
}

.admin-dashboard-column {
  display: flex;
  flex-direction: column;
  gap: var(--admin-space-4);
  min-width: 0;
}

.admin-stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--admin-space-3);
}

.admin-stat-grid.compact {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  margin-top: var(--admin-space-3);
}

.admin-stat {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
  padding: var(--admin-space-3) var(--admin-space-4);
  border: 1px solid var(--admin-line);
  border-radius: var(--admin-radius-md);
  background: var(--admin-surface-solid);
}

.admin-stat-label {
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.8px;
  text-transform: uppercase;
  color: var(--color-text-muted);
}

.admin-stat-value {
  font-size: 28px;
  font-weight: 800;
  letter-spacing: -0.5px;
  line-height: 1.1;
  color: var(--color-text-main);
  font-variant-numeric: tabular-nums;
}

.admin-stat-grid.compact .admin-stat-value {
  font-size: 22px;
}

.admin-stat-note {
  font-size: 12px;
  font-weight: 500;
  color: var(--color-text-muted);
  font-variant-numeric: tabular-nums;
}

.admin-stat-note.up {
  color: #15803d;
  font-weight: 700;
}

.admin-stat.warn {
  background: #fff7ed;
  border-color: rgba(217, 119, 6, 0.22);
}

.admin-stat.warn .admin-stat-value {
  color: #c2610a;
}

.admin-stat.alert {
  background: var(--color-error-bg);
  border-color: var(--color-error-border);
}

.admin-stat.alert .admin-stat-value {
  color: #dc2626;
}

.admin-chart-legend {
  display: flex;
  gap: var(--admin-space-4);
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.8px;
  text-transform: uppercase;
  color: var(--color-text-muted);
}

.admin-chart-legend i {
  display: inline-block;
  width: 10px;
  height: 10px;
  margin-right: 6px;
  border-radius: 3px;
  vertical-align: -1px;
}

.admin-chart-legend i.succeeded,
.admin-chart rect.succeeded {
  background: var(--color-purple);
  fill: var(--color-purple);
}

.admin-chart-legend i.failed,
.admin-chart rect.failed {
  background: var(--color-pink);
  fill: var(--color-pink);
}

.admin-chart {
  display: block;
  width: 100%;
  height: auto;
  max-width: 100%;
}

.admin-chart line.grid {
  stroke: var(--admin-line);
  stroke-width: 1;
}

.admin-chart text.axis {
  font-family: inherit;
  font-size: 10px;
  font-weight: 600;
  fill: var(--color-text-muted);
}

.admin-bars {
  display: grid;
  gap: var(--admin-space-2);
  margin-bottom: var(--admin-space-3);
}

.admin-bar {
  display: grid;
  grid-template-columns: 96px minmax(0, 1fr) 64px;
  align-items: center;
  gap: var(--admin-space-3);
  font-size: 13px;
  font-weight: 600;
}

.admin-bar-track {
  height: 8px;
  border-radius: 999px;
  background: var(--admin-line-soft);
  overflow: hidden;
}

.admin-bar-fill {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: var(--color-primary-gradient);
}

.admin-bar-value {
  text-align: right;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}

.admin-health {
  margin: 0;
  display: grid;
}

.admin-health > div {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--admin-space-3);
  padding: 10px 0;
  border-bottom: 1px solid var(--admin-line-soft);
}

.admin-health > div:last-child {
  border-bottom: none;
}

.admin-health dt {
  font-size: 13.5px;
  font-weight: 700;
  color: var(--color-text-main);
}

.admin-health dd {
  margin: 0;
}

.admin-health-text {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 2px;
  min-width: 0;
  text-align: right;
}

@media (max-width: 860px) {
  .admin-dashboard-split {
    grid-template-columns: minmax(0, 1fr);
  }
}

@media (max-width: 560px) {
  .admin-stat-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .admin-stat-value {
    font-size: 24px;
  }

  .admin-bar {
    grid-template-columns: 80px minmax(0, 1fr) 52px;
  }

  .admin-dashboard-stamp {
    white-space: normal;
  }

  /* The one bar at the top of a phone (#92) fits the logo, two entries and the menu, not a third: the
     labels broke into a column of single characters and pushed the page sideways. The logo already
     leads to /admin, so the dashboard entry is the one that goes. */
  .admin-nav-link.dashboard {
    display: none;
  }

  /* The chart is drawn 560 units wide and shrinks with the screen, so its labels shrink too: about half size at
     390px. Doubling them in chart units brings them back to roughly the 10px they are on a desktop. */
  .admin-chart text.axis {
    font-size: 16px;
  }
}
