/* admin.css — Admin Console (/p/admin-[slug]) shared shell + Login + Overview.
   Design source: WEBSYS_MD/MEMBERSHIP_REQUIREMENTS.md §10 / §15.11. Desktop-first (1280px);
   no mobile stacking yet — see P_DEV_STATUS §6 for the Phase 5 build order. */

/* Body background painted immediately (not dependent on JS mounting
   .adm-shell/.adm-login-page) — every other /p page already does this;
   admin.css was the gap, causing a white flash while requireAdmin() +
   Supabase queries resolve (2026-07-08 fix). */
body { margin: 0; min-height: 100vh; min-height: 100dvh; background: var(--space-gradient), var(--bg-primary); background-repeat: no-repeat; background-attachment: fixed; }

/* ── Login (standalone, no sidebar) ─────────────────────────────────────── */
.adm-login-page {
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--space-gradient), var(--navbar-bg);
  background-repeat: no-repeat;
  background-attachment: fixed;
  font-family: var(--font-thai);
  color: var(--text-primary);
  padding: 24px;
}
.adm-login-card {
  width: 100%;
  max-width: 380px;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 32px 28px;
  text-align: center;
}
.adm-login-logo { font-size: 32px; margin-bottom: 12px; }
.adm-login-title { font-size: 20px; font-weight: 700; margin-bottom: 4px; }
.adm-login-sub { font-size: 13px; color: var(--text-secondary); margin-bottom: 24px; }
.adm-login-field { text-align: left; margin-bottom: 14px; }
.adm-login-field label { display: block; font-size: 12px; color: var(--text-secondary); margin-bottom: 8px; }
.adm-login-field input, .adm-login-field select {
  width: 100%;
  background: rgba(255,255,255,0.04);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 11px 12px;
  color: var(--text-primary);
  font-family: inherit;
  font-size: 14px;
}
.adm-login-field input:focus, .adm-login-field select:focus { outline: none; border-color: var(--accent-gold); }
/* Dark-mode native option-list popup (2026-07-25 fix, same reasoning as the
   date-input calendar icon below) — a bare <select> defaults to a light
   OS-native dropdown that clashes hard against this page's dark theme. */
.adm-login-field select { color-scheme: dark; cursor: pointer; }
/* appearance:none (2026-07-25 fix — "พื้นหลังขาว ข้อความขาว") — without it,
   several browsers keep the native <select> box's own chrome for the CLOSED
   control and simply ignore the custom background/border above, leaving
   white-on-white. Same fix already used by .nt-select (giveaway.css) for
   the exact same reason; the chevron below replaces the native arrow that
   appearance:none also removes. */
.adm-login-field select { appearance: none; padding-right: 30px; }
.adm-select-wrap { position: relative; }
.adm-select-wrap::after {
  content: '▾';
  position: absolute;
  right: 12px;
  top: 50%;
  transform: translateY(-50%);
  font-size: 10px;
  color: var(--text-secondary);
  pointer-events: none;
}
/* Native calendar-picker icon on <input type="date"> (2026-07-24 fix) — the
   browser renders that icon black by default regardless of our own
   color/background CSS (it's inside the input's UA shadow DOM, not
   something a plain `color` rule reaches); color-scheme tells the browser
   to use its dark-mode variant of that icon instead, matching the dark
   field it sits in. */
.adm-login-field input[type="date"] { color-scheme: dark; }
.adm-login-error {
  background: rgba(240,107,107,0.12);
  color: #F06B6B;
  border-radius: 8px;
  padding: 8px 10px;
  font-size: 12px;
  margin-bottom: 14px;
  text-align: left;
}
.adm-login-btn {
  width: 100%;
  background: var(--accent-gold);
  color: #1A1200;
  border: none;
  border-radius: 8px;
  padding: 12px;
  font-family: inherit;
  font-weight: 700;
  font-size: 14px;
  cursor: pointer;
  margin-top: 4px;
}
.adm-login-btn:disabled { opacity: 0.6; cursor: default; }
/* Secondary/back-button variant (2026-08-12 ask — Turnstile verify-step
   redesign) — same treatment as .auth-btn--ghost on the main site. */
.adm-login-btn--ghost {
  background: rgba(255,255,255,0.06);
  color: var(--text-primary);
  border: 1px solid var(--border);
}
.adm-login-btn--ghost:hover:not(:disabled) { background: rgba(255,255,255,0.1); }

/* X login (2026-07-08 ask) — admins who signed up via X have no password to
   use in the form below, so this is offered as an alternative up top. */
.adm-login-x-btn {
  width: 100%;
  display: flex; align-items: center; justify-content: center; gap: 8px;
  background: #000; color: #fff;
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: 8px;
  padding: 12px;
  font-family: inherit;
  font-weight: 700;
  font-size: 14px;
  cursor: pointer;
  margin-bottom: 16px;
}
.adm-login-x-btn:disabled { opacity: 0.6; cursor: default; }
.adm-login-divider {
  display: flex; align-items: center; gap: 10px;
  margin: 4px 0 16px;
  font-size: 11px;
  color: var(--text-secondary);
}
.adm-login-divider::before, .adm-login-divider::after { content: ''; flex: 1; height: 0; border-top: 1px solid var(--border); }
.adm-login-note {
  font-size: 11px;
  color: var(--text-secondary);
  margin-top: 18px;
  line-height: 1.5;
}
.adm-login-slug {
  font-size: 11px;
  color: var(--text-secondary);
  opacity: 0.6;
  margin-top: 6px;
  font-family: monospace;
}

/* ── Shell (sidebar + topbar) ────────────────────────────────────────────── */
.adm-shell {
  display: flex;
  min-height: 100vh;
  min-height: 100dvh;
  background: var(--space-gradient), var(--bg-primary);
  background-repeat: no-repeat;
  background-attachment: fixed;
  color: var(--text-primary);
  font-family: var(--font-thai);
}
.adm-sidebar {
  width: 240px;
  flex-shrink: 0;
  background: var(--navbar-bg);
  border-right: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  padding: 20px 0;
  transition: width 0.15s ease;
  /* Pinned to the viewport instead of stretching to the right column's
     height (2026-07-12 fix) — otherwise `.adm-sidebar__foot` (username +
     logout) drifted down past the fold on any page taller than one screen,
     since it just sits at the end of the sidebar's own flex column. */
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100dvh;
}
.adm-sidebar__brand {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 0 20px 20px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 12px;
}
.adm-sidebar__brand-icon { font-size: 18px; flex-shrink: 0; line-height: 1.4; }
.adm-sidebar__brand-text { flex: 1; line-height: 1.4; }
.adm-sidebar__brand-title { font-size: 14px; font-weight: 700; color: var(--text-primary); }
/* Matches nav.css .ppw-nav__brand-tag exactly (small gold text) — the main
   site's global nav renders its event name the same way. */
.adm-sidebar__brand-tag { font-size: 10px; color: var(--accent-gold); }
.adm-sidebar__collapse {
  flex-shrink: 0;
  width: 22px; height: 22px;
  display: none; /* desktop-only — shown in the >=769px block below */
  align-items: center; justify-content: center;
  background: rgba(255,255,255,0.05);
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--text-secondary);
  font-size: 11px;
  cursor: pointer;
}
/* min-height:0 + overflow-y:auto (2026-08-05 fix — sidebar now has 14
   top-level items + 2 nested; `.adm-sidebar` is pinned to a fixed
   100vh/100dvh height with no scroll mechanism anywhere, so past a certain
   item count the bottom entries were clipped outside the viewport with no
   way to reach them at all, not just visually cramped). Brand header and
   `.adm-sidebar__foot` stay fixed in place; only this middle nav section
   scrolls internally when it doesn't fit. */
.adm-sidebar__nav { flex: 1; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; gap: 2px; padding: 0 12px; }
.adm-sidebar__item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border-radius: 8px;
  color: var(--text-secondary);
  text-decoration: none;
  font-size: 13px;
  font-weight: 500;
  position: relative;
}
.adm-sidebar__item:hover { background: rgba(255,255,255,0.04); }
.adm-sidebar__item.is-active { background: var(--bg-elevated); color: var(--text-primary); font-weight: 600; }
.adm-sidebar__item.is-disabled { opacity: 0.4; pointer-events: none; }
.adm-sidebar__item-icon { flex-shrink: 0; }
/* Submenu row (2026-07-15 ask) — indented + smaller, nested directly under
   its parent (e.g. "จัดการผู้ใช้"), same interaction/active-state as a
   top-level item otherwise. */
.adm-sidebar__item--child { padding-left: 34px; font-size: 12px; }
.adm-sidebar.is-collapsed .adm-sidebar__item--child { display: none; } /* icon-only rail has no room for a nested label */
.adm-sidebar__badge {
  margin-left: auto;
  background: var(--accent-gold);
  color: #1A1200;
  font-size: 10px;
  font-weight: 700;
  border-radius: 10px;
  padding: 1px 7px;
}
.adm-sidebar__foot {
  padding: 12px 20px 0;
  border-top: 1px solid var(--border);
  margin-top: 12px;
  font-size: 12px;
}
.adm-sidebar__profile { display: flex; align-items: center; gap: 8px; color: var(--text-secondary); margin-bottom: 8px; }
.adm-sidebar__logout {
  display: flex;
  align-items: center;
  gap: 8px;
  background: none;
  border: none;
  color: var(--like-red);
  font-family: inherit;
  font-size: 12px;
  cursor: pointer;
  padding: 0;
}

/* ── Desktop sidebar collapse (icon-only rail) ─────────────────────────────
   Mobile already has its own off-canvas drawer pattern (see the mobile
   media query below) — this is a separate, desktop-only affordance, so it's
   scoped to >=769px and never interacts with `.is-open`/the mobile drawer. */
@media (min-width: 769px) {
  .adm-sidebar__collapse { display: flex; }
  .adm-sidebar.is-collapsed { width: 64px; }
  .adm-sidebar.is-collapsed .adm-sidebar__brand { flex-direction: column; align-items: center; gap: 8px; padding: 0 8px 16px; }
  .adm-sidebar.is-collapsed .adm-sidebar__brand-text { display: none; }
  .adm-sidebar.is-collapsed .adm-sidebar__item { justify-content: center; padding: 10px; }
  .adm-sidebar.is-collapsed .adm-sidebar__item-label { display: none; }
  .adm-sidebar.is-collapsed .adm-sidebar__badge { position: absolute; top: 4px; right: 4px; margin-left: 0; }
  .adm-sidebar.is-collapsed .adm-sidebar__foot { display: flex; flex-direction: column; align-items: center; gap: 10px; padding: 12px 8px 0; }
  .adm-sidebar.is-collapsed .adm-sidebar__profile-text,
  .adm-sidebar.is-collapsed .adm-sidebar__logout-label { display: none; }
}

.adm-main { flex: 1; min-width: 0; }
.adm-topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 18px 28px;
  border-bottom: 1px solid var(--border);
}
.adm-topbar__title-th { font-size: 18px; font-weight: 700; }
.adm-topbar__title-en { font-size: 12px; color: var(--text-secondary); }
.adm-topbar__search {
  position: relative;
  background: rgba(255,255,255,0.04);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 8px 12px;
  font-size: 13px;
  color: var(--text-secondary);
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 260px;
}
.adm-topbar__search-icon { flex-shrink: 0; }
.adm-topbar__search-input {
  flex: 1;
  min-width: 0;
  background: none;
  border: none;
  outline: none;
  color: var(--text-primary);
  font-family: inherit;
  font-size: 13px;
}
.adm-topbar__search-input::placeholder { color: var(--text-secondary); }
.adm-topbar__search kbd {
  margin-left: auto;
  background: rgba(255,255,255,0.08);
  border-radius: 4px;
  padding: 1px 6px;
  font-size: 10px;
  flex-shrink: 0;
}
.adm-search-dropdown {
  position: absolute;
  top: calc(100% + 6px);
  left: 0; right: 0;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 6px;
  max-height: 320px;
  overflow-y: auto;
  z-index: 50;
  box-shadow: 0 12px 32px rgba(0,0,0,0.4);
}
.adm-search-group-label { font-size: 11px; color: var(--text-secondary); font-weight: 600; padding: 6px 8px 4px; }
.adm-search-item {
  display: block;
  padding: 8px;
  border-radius: 6px;
  color: var(--text-primary);
  text-decoration: none;
  font-size: 13px;
}
.adm-search-item:hover { background: rgba(255,255,255,0.06); }
.adm-search-empty { padding: 12px 8px; color: var(--text-secondary); font-size: 12px; text-align: center; }
.adm-content { padding: 24px 28px; }
.adm-state { color: var(--text-secondary); font-size: 14px; padding: 40px 0; text-align: center; }
.adm-state--error { color: #F06B6B; }

.adm-mobile-toggle {
  display: none; /* shown only under the mobile breakpoint below */
  width: 36px; height: 36px;
  align-items: center; justify-content: center;
  background: rgba(255,255,255,0.05);
  border: 1px solid var(--border);
  border-radius: 8px;
  color: var(--text-primary);
  font-size: 16px;
  cursor: pointer;
  flex-shrink: 0;
}
.adm-scrim {
  display: none;
  position: fixed; inset: 0;
  background: rgba(0,0,0,0.6);
  z-index: 499;
}

/* Every <select>'s closed box already gets --text-primary from its own rule,
   but the open option list is native/OS-rendered and ignores that unless
   <option> itself is styled — left unstyled it fell back to the browser
   default (white background), which combined with our inherited white text
   made every dropdown's open list unreadable. */
.adm-shell select option,
.adm-login-page select option,
.adm-select-wrap select option {
  background: var(--bg-elevated);
  color: var(--text-primary);
}

/* ── Seat Overview ───────────────────────────────────────────────────────── */
.adm-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 12px;
  margin-bottom: 20px;
}
.adm-stat {
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 14px;
}
.adm-stat__head { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--text-secondary); margin-bottom: 6px; }
.adm-stat__dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
.adm-stat__v { font-size: 22px; font-weight: 700; }

/* User Management's "ผู้ใช้ทั้งหมด"/"ผู้ใช้ที่ถูกลบ" tabs (2026-07-10) — a
   self-contained copy of modals.css's .my-tabbar (Edit Profile's tab bar),
   which no admin page loads. Same bug class as the earlier .adm-delete-input
   fix: emitting a class from a stylesheet the page never links. */
.adm-tabbar {
  display: flex; gap: 6px;
  padding: 4px;
  margin-bottom: 16px;
  background: rgba(255, 255, 255, 0.05);
  border-radius: 12px;
  max-width: 420px;
}
.adm-tabbar__btn {
  flex: 1;
  padding: 9px 6px;
  border: 1px solid transparent;
  border-radius: 9px;
  background: transparent;
  color: var(--text-secondary);
  font: 600 12px var(--font-thai);
  cursor: pointer;
}
.adm-tabbar__btn.is-active {
  background: rgba(244, 161, 64, 0.14);
  border-color: var(--accent-gold);
  color: var(--accent-gold);
}

.adm-filters {
  display: flex;
  gap: 10px;
  margin-bottom: 16px;
  flex-wrap: wrap;
}
.adm-filters input, .adm-filters select {
  background: rgba(255,255,255,0.04);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 8px 10px;
  color: var(--text-primary);
  font-family: inherit;
  font-size: 13px;
}
.adm-filters input { flex: 1; min-width: 180px; }
/* Wraps a bare .adm-filters search <input> so search-clear.js's × button has
   a positioning anchor, without disturbing the input's own flex sizing
   above (2026-07-26 ask — every /p search box gets a clear button). */
.adm-filters .search-input-wrap { position: relative; flex: 1; min-width: 180px; }
.adm-filters .search-input-wrap input { width: 100%; }

.adm-table {
  width: 100%;
  border-collapse: collapse;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 10px;
  overflow: hidden;
  font-size: 13px;
}
.adm-table th, .adm-table td {
  text-align: left;
  padding: 10px 14px;
  border-bottom: 1px solid var(--border);
}
.adm-table th { color: var(--text-secondary); font-weight: 600; font-size: 12px; }
.adm-table tr:last-child td { border-bottom: none; }
.adm-table__total td { font-weight: 700; background: rgba(255,255,255,0.04); border-top: 1px solid var(--border); }
.adm-table__owner { display: flex; align-items: center; gap: 8px; }
.adm-table__owner a { color: var(--text-primary); font-weight: 600; text-decoration: none; }
.adm-table__owner a:hover { color: var(--accent-gold); text-decoration: underline; }
.adm-link { color: var(--accent-teal); text-decoration: none; }
.adm-link:hover { text-decoration: underline; }
.adm-table__owner .my-badge { padding: 3.5px 9px; border-radius: 9px; font-size: 10px; }
.adm-table__avatar {
  width: 24px; height: 24px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 13px; border: 1px solid var(--border); flex-shrink: 0;
}
.adm-table__empty { color: var(--text-secondary); }

/* ── Ticket Verification Hub ─────────────────────────────────────────────── */
/* Uploaded Proof / No Proof as two fully separate views behind a tab bar
   (2026-07-08 — replaced an earlier stacked-both-at-once layout). Each tab
   keeps its own pagination in JS; only the active tab's list is in the DOM. */
.adv-tabs { display: flex; gap: 6px; padding: 4px; margin-bottom: 16px; background: rgba(255, 255, 255, 0.05); border-radius: 12px; }
.adv-tabs__btn {
  flex: 1;
  padding: 10px 8px;
  border: 1px solid transparent;
  border-radius: 9px;
  background: transparent;
  color: var(--text-secondary);
  font: 600 13px var(--font-thai);
  cursor: pointer;
}
.adv-tabs__btn.is-active { background: rgba(244, 161, 64, 0.14); border-color: var(--accent-gold); color: var(--accent-gold); }

/* Ticket Verification tab bar (2026-08-10 redesign — replaced the earlier
   2026-08-09 two-stacked-boxes layout after it read as "two different
   components"): "รอตรวจสอบ" (the actual work queue) sits inside the SAME
   pill background as the other 4 reference/history tabs, separated only by
   a thin `.adv-tabs__divider` — one visual container, not two. Everything
   below is scoped to `.adv-tabs--verification` (or its child wrapper
   classes, which only exist on this page) so admin-fanproject.js's plain
   single-row `.adv-tabs` bar is completely unaffected. */
.adv-tabs__primary-wrap { display: flex; flex: 1.2 1 0; }
.adv-tabs__primary-wrap .adv-tabs__btn { flex: 1; }
.adv-tabs__secondary-wrap { display: flex; gap: 6px; flex: 4 1 0; }
.adv-tabs__divider { flex: 0 0 auto; width: 1px; align-self: stretch; margin: 2px 4px; background: var(--border); }
.adv-tabs__btn--primary { border-color: rgba(244, 161, 64, 0.35); color: var(--accent-gold); }
.adv-tabs__btn--primary.is-active { border-color: var(--accent-gold); }

/* Desktop: count drops to its own line under icon+label, smaller and not
   bold, so the label reads as the primary content and the count as a
   lighter secondary detail. `.adv-tabs__btn-count` has `flex-basis: 100%`
   so it wraps onto a 2nd row on its own while icon+label stay together on
   row 1 — no separate wrapper markup needed. */
@media (min-width: 769px) {
  .adv-tabs--verification .adv-tabs__btn { display: flex; align-items: center; justify-content: center; flex-wrap: wrap; column-gap: 4px; }
  .adv-tabs--verification .adv-tabs__btn-count { flex: 1 0 100%; margin-top: 2px; font-size: 11px; font-weight: 400; }
}

/* Mobile: "รอตรวจสอบ" keeps its full icon+label+count on its own full-width
   row; divider drops to a horizontal rule; the 4 secondary tabs go into an
   equal 4-column grid with just icon+count (label hidden — 4 Thai labels
   don't fit 4 columns at any readable size). Still one `.adv-tabs`
   background box, just wrapped instead of scrolled — no separate boxes. */
@media (max-width: 768px) {
  .adv-tabs--verification { flex-wrap: wrap; }
  .adv-tabs--verification .adv-tabs__primary-wrap { flex: 1 1 100%; }
  .adv-tabs--verification .adv-tabs__divider { flex: 1 1 100%; width: auto; height: 1px; align-self: auto; margin: 6px 2px; }
  .adv-tabs--verification .adv-tabs__secondary-wrap { flex: 1 1 100%; display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; }
  .adv-tabs--verification .adv-tabs__secondary-wrap .adv-tabs__btn {
    display: flex; flex-direction: column; align-items: center; gap: 3px;
    padding: 8px 4px; font-size: 11px;
  }
  .adv-tabs--verification .adv-tabs__secondary-wrap .adv-tabs__btn-label { display: none; }
}
.adv-list { display: flex; flex-direction: column; gap: 10px; }
.adv-row {
  display: flex;
  align-items: center;
  gap: 14px;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 12px 16px;
  flex-wrap: wrap;
}
.adv-thumb {
  width: 40px; height: 40px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 8px;
  background: rgba(255,255,255,0.04);
  border: 1px solid var(--border);
  color: var(--text-primary);
  font-size: 18px;
  cursor: pointer;
  flex-shrink: 0;
}
.adv-row__info { flex: 1; min-width: 200px; }
.adv-row__seat { font-weight: 600; font-size: 13px; margin-bottom: 4px; }
.adv-row__owner { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--text-secondary); margin-bottom: 2px; }
.adv-row__time { font-size: 11px; color: var(--text-secondary); opacity: 0.7; }
.adv-row__actions { display: flex; gap: 8px; }
.adv-reject {
  width: 100%;
  background: rgba(240,107,107,0.08);
  border: 1px solid rgba(240,107,107,0.3);
  border-radius: 8px;
  padding: 12px;
  margin-top: 10px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.adv-reject__select, .adv-reject__free {
  background: rgba(255,255,255,0.04);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 8px 10px;
  color: var(--text-primary);
  font-family: inherit;
  font-size: 13px;
}
.adv-reject__free.is-invalid { border-color: #F06B6B; }
.adv-reject__note { font-size: 11px; color: var(--text-secondary); }
.adv-reject__btns { display: flex; gap: 8px; justify-content: flex-end; }

/* ── User Management ────────────────────────────────────────────────────── */
.adu-chips { display: flex; gap: 6px; flex-wrap: wrap; }
.adu-chip {
  font-size: 11px;
  font-weight: 600;
  border-radius: 6px;
  padding: 2px 8px;
}
.adu-chip--x { background: rgba(19,205,203,0.16); color: var(--accent-teal); }
.adu-chip--manual { background: rgba(255,255,255,0.08); color: var(--text-secondary); }
.adu-chip--privacy { background: rgba(168,57,254,0.16); color: #A839FE; }
.adu-chip--admin { background: rgba(244,161,64,0.16); color: var(--accent-gold); }

/* ── Marketplace Moderation ──────────────────────────────────────────────── */
.adm-info-banner {
  background: rgba(19,205,203,0.08);
  border: 1px solid rgba(19,205,203,0.25);
  color: var(--accent-teal);
  border-radius: 8px;
  padding: 10px 14px;
  font-size: 12px;
  margin-bottom: 16px;
}
.adm-info-banner--amber {
  background: rgba(244,161,64,0.08);
  border-color: rgba(244,161,64,0.25);
  color: var(--accent-gold);
}

/* ── Test Parameters ─────────────────────────────────────────────────────── */
.adm-code {
  font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
  font-size: 12px;
  background: rgba(255,255,255,0.08);
  border-radius: 6px;
  padding: 2px 8px;
  color: var(--accent-teal);
  white-space: nowrap;
}
.tp-param-row { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; }
.tp-copy-btn { font-size: 12px; padding: 4px 7px; }
/* 2026-07-10 ask — "ใช้ที่หน้า" chips + คำอธิบาย text sized 10% down from
   .adm-table's 13px body / .adu-chip's 11px default. */
.tp-desc { font-size: 11.7px; }
.tp-desc__warn { margin-top: 4px; color: var(--accent-gold); }
.tp-pages .adu-chip { font-size: 9.9px; }

/* ── Password Reset ──────────────────────────────────────────────────────── */
/* Autocomplete (2026-07-09): input search dropped its own "ค้นหา" button in
   favor of a live dropdown as the admin types — .adp-search is the anchor
   for the absolutely-positioned .adp-result-list overlay below it, so the
   dropdown floats over the page instead of shoving content down. */
.adp-search { position: relative; max-width: 360px; margin-bottom: 16px; }
.adp-search input { width: 100%; background: rgba(255,255,255,0.04); border: 1px solid var(--border); border-radius: 8px; padding: 8px 10px; color: var(--text-primary); font-family: inherit; font-size: 13px; }
.adp-result-list {
  position: absolute; top: calc(100% + 6px); left: 0; right: 0; z-index: 20;
  display: flex; flex-direction: column; gap: 4px;
  background: var(--dropdown-bg); border: 1px solid var(--border); border-radius: 10px;
  padding: 6px; max-height: 260px; overflow-y: auto;
  box-shadow: 0 8px 24px rgba(0,0,0,0.35);
}
.adp-result-item {
  display: flex; align-items: center; gap: 10px;
  background: transparent; border: 1px solid transparent; border-radius: 8px;
  padding: 8px 10px; color: var(--text-primary); font-family: inherit; font-size: 13px;
  cursor: pointer; text-align: left;
}
.adp-result-item:hover { background: rgba(255,255,255,0.05); border-color: rgba(244,161,64,0.4); }
.adp-result-item > span:nth-child(2) { flex: 1; }
.adp-card {
  background: var(--bg-elevated); border: 1px solid var(--border); border-radius: 12px;
  padding: 18px; margin-bottom: 20px; max-width: 420px;
}
.adp-card__head { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.adp-card__username { font-size: 16px; font-weight: 700; }
.adp-card__chips { display: flex; gap: 6px; margin-bottom: 14px; }
.adp-blocked { font-size: 12px; color: #F06B6B; background: rgba(240,107,107,0.08); border: 1px solid rgba(240,107,107,0.25); border-radius: 8px; padding: 10px 12px; margin-bottom: 12px; }
/* Revoke-X-link action (2026-07-08): block-level + its own top gap so it
   never sits flush against the warning box above or a temp-password panel
   that might already be showing below. */
.adp-revoke-btn { display: flex; width: 100%; margin-top: 4px; padding: 10px 12px; font-size: 12px; }
.adp-success {
  background: rgba(79,209,135,0.08); border: 1px solid rgba(79,209,135,0.3); border-radius: 12px;
  padding: 18px; max-width: 420px;
}
.adp-success__head { font-size: 14px; font-weight: 700; color: #4FD187; margin-bottom: 12px; }
.adp-success__box {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  background: rgba(0,0,0,0.25); border-radius: 8px; padding: 10px 14px; margin-bottom: 12px;
}
.adp-success__box code { font-family: monospace; font-size: 16px; font-weight: 700; letter-spacing: 0.5px; color: var(--text-primary); }
.adp-success__note { font-size: 11px; color: var(--text-secondary); }
.adm-report-detail {
  background: rgba(240,107,107,0.06);
  padding: 12px 16px !important;
}
.adm-report-detail__item { padding: 6px 0; border-bottom: 1px solid var(--border); }
.adm-report-detail__item:last-child { border-bottom: none; }
.adm-report-detail__reason { font-size: 12px; font-weight: 600; }
.adm-report-detail__note { font-size: 12px; color: var(--text-secondary); margin-top: 2px; }
.adm-report-detail__time { font-size: 11px; color: var(--text-secondary); opacity: 0.7; margin-top: 2px; }
.adm-report-detail__item .tk-btn { margin-top: 6px; }

.adm-table__actions { display: flex; gap: 10px; justify-content: flex-end; }
.adm-table th.adm-th--right { text-align: right; }
/* Seat Overview "อัปเดตล่าสุด" column — 10% smaller, faded white (2026-07-10 ask). */
.adm-updated-cell { font-size: 11.7px; color: rgba(255,255,255,0.5); }

.adm-remove-confirm {
  background: rgba(240,107,107,0.06);
  border: 1px solid rgba(240,107,107,0.25);
  border-radius: 10px;
  padding: 14px 16px !important;
}
.adm-remove-confirm__warn { font-size: 12px; color: #F06B6B; margin-bottom: 10px; }
.adm-remove-confirm select { margin-bottom: 10px; width: 100%; max-width: 420px; display: block; }
/* 2026-07-10 — type-"DELETE"-to-confirm, replacing the old two-click
   confirmation for seat/user deletion. Self-contained styling (not relying
   on the shared `.auth-input` class) — auth.css isn't loaded on any admin
   page, so `.adm-delete-input` previously rendered as an unstyled browser
   default input, clashing with the dark theme around it. */
.adm-remove-confirm input.adm-delete-input {
  margin-bottom: 10px;
  width: 100%;
  max-width: 420px;
  display: block;
  background: rgba(255,255,255,0.04);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 8px 10px;
  color: var(--text-primary);
  font-family: inherit;
  font-size: 13px;
}
.adm-remove-confirm input.adm-delete-input:focus { border-color: rgba(240,107,107,0.5); outline: none; }
.adm-remove-confirm__hint { font-size: 11px; color: var(--text-secondary); margin: -6px 0 10px; }

/* ── Phase Control ───────────────────────────────────────────────────────── */
.adm-phase-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 16px;
}
.adm-phase-card {
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 18px;
}
.adm-phase-card--emergency {
  margin-bottom: 24px;
  border-color: rgba(244,161,64,0.35);
}
.adm-phase-card__head { display: flex; gap: 12px; margin-bottom: 16px; }
.adm-phase-card__icon {
  width: 40px; height: 40px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  background: rgba(255,255,255,0.05); border-radius: 10px; font-size: 18px;
}
.adm-phase-card__name-row { display: flex; align-items: center; gap: 8px; }
.adm-phase-card__name { font-weight: 700; font-size: 14px; }
.adm-phase-card__chip { font-size: 10px; color: var(--text-secondary); background: rgba(255,255,255,0.06); border-radius: 6px; padding: 1px 6px; }
.adm-phase-card__desc { font-size: 12px; color: var(--text-secondary); margin-top: 4px; }
.adm-phase-card__row { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding-top: 14px; border-top: 1px solid var(--border); }
.adm-phase-card__label { font-size: 12px; color: var(--text-secondary); }

.adm-switch {
  position: relative; flex-shrink: 0;
  width: 44px; height: 24px;
  border: none; border-radius: 12px;
  background: rgba(255,255,255,0.15);
  cursor: pointer;
}
.adm-switch::after {
  content: ''; position: absolute; top: 2px; left: 2px;
  width: 20px; height: 20px; border-radius: 50%;
  background: #fff; transition: left 0.15s ease;
}
.adm-switch.is-on { background: #4FD187; }
.adm-switch.is-on::after { left: 22px; }
.adm-switch:disabled { opacity: 0.6; cursor: default; }

/* ── Activity Logs (plain/functional per §10.8) ─────────────────────────── */
.adm-table--plain th, .adm-table--plain td { font-family: var(--font-thai); font-size: 12px; }
.adm-table--plain tr.is-zebra { background: rgba(255,255,255,0.02); }
.adm-log-type {
  /* Exception: the Type chip keeps its own font regardless of the table's
     font-family, per explicit request — it reads as a status code, not prose. */
  font-family: monospace;
  font-size: 10px; font-weight: 700;
  background: rgba(255,255,255,0.06);
  border-radius: 6px; padding: 2px 6px;
}
.adm-log-type--approve, .adm-log-type--auth { background: rgba(79,209,135,0.16); color: #4FD187; }
.adm-log-type--reject, .adm-log-type--delete { background: rgba(240,107,107,0.16); color: #F06B6B; }
.adm-log-type--phase, .adm-log-type--reset { background: rgba(244,161,64,0.16); color: var(--accent-gold); }
.adm-log-sentence { font-size: 13px; }
.adm-log-sentence__meta { color: var(--text-secondary); font-size: 11px; margin-top: 2px; }
.adm-log-ref { font-size: 11px; color: var(--text-secondary); cursor: help; }

/* ── Shared detail-card primitives (used by the User Profile page below) ── */
.adt-card {
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 16px;
  margin-bottom: 14px;
}
.adt-card__title { font-size: 13px; font-weight: 700; margin-bottom: 10px; }
.adt-card__title-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 10px; }
.adt-card__title-row .adt-card__title { margin-bottom: 0; }
.adt-row { display: flex; justify-content: space-between; gap: 12px; padding: 6px 0; font-size: 13px; }
.adt-row__label { color: var(--text-secondary); }
.adt-row__value { text-align: right; }

/* ── User Profile (new page, 2026-07-07 — topbar search + User Management's
   "ดูข้อมูล" both land here; read-only, no approve/reject/delete controls). ── */
.adup-hero { display: flex; align-items: center; gap: 14px; margin: 16px 0 20px; }
/* Plain section divider (2026-07-15 ask) — was .my-divider's constellation
   line+star; generous top margin gives each section's heading real
   breathing room instead of sitting flush under the line above it. */
.adup-divider { height: 0; border-top: 1px solid var(--border); margin: 28px 0 20px; }
.adup-hero__avatar {
  width: 56px; height: 56px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: 26px;
  border-radius: 50%;
  border: 3px solid var(--border);
  background: var(--bg-elevated);
}
.adup-hero__name { font-size: 18px; font-weight: 700; margin-bottom: 6px; }
.adup-ticket-list { display: flex; flex-direction: column; gap: 10px; }
.adup-ticket {
  display: flex;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 10px;
  overflow: hidden;
}
.adup-ticket__rail { width: 4px; flex-shrink: 0; }
.adup-ticket__body { flex: 1; padding: 12px 14px; display: flex; flex-direction: column; gap: 8px; }
.adup-ticket__head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.adup-ticket__seat { font-weight: 700; font-size: 13px; }
.adup-ticket__meta { display: flex; gap: 14px; font-size: 12px; color: var(--text-secondary); }

/* ── Zone Summary + Zone Detail (new pages, 2026-07-07) ───────────────────── */
.adz-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 14px;
}
.adz-card {
  display: block;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 16px;
  text-decoration: none;
  color: var(--text-primary);
  transition: border-color 0.12s ease, transform 0.12s ease;
}
.adz-card:hover { border-color: rgba(244,161,64,0.4); transform: translateY(-1px); }
.adz-card__head { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
.adz-card__swatch { width: 12px; height: 12px; border-radius: 50%; flex-shrink: 0; }
.adz-card__code { font-size: 18px; font-weight: 700; }
.adz-card__chip {
  font-size: 10px; color: var(--text-secondary);
  background: rgba(255,255,255,0.06);
  border-radius: 6px; padding: 2px 7px;
}
.adz-card__section { font-size: 12px; color: var(--text-secondary); margin-bottom: 10px; }
.adz-card__counts { display: flex; flex-wrap: wrap; gap: 6px; font-size: 12px; margin-bottom: 10px; }
.adz-card__counts-label { font-weight: 300; color: var(--text-secondary); }
.adz-card__counts b { color: var(--text-primary); font-weight: 700; }
.adz-card__counts-sep { color: var(--border); }
.adz-card__stats { display: flex; flex-wrap: wrap; gap: 6px; }
.adz-stat-chip { font-size: 10px; font-weight: 700; border-radius: 6px; padding: 2px 6px; }
.adz-stat-chip--verified { background: rgba(79,209,135,0.16); color: #4FD187; }
.adz-stat-chip--pending { background: rgba(250,191,89,0.16); color: #FABF59; }
.adz-stat-chip--unverified { background: rgba(255,255,255,0.08); color: var(--text-secondary); }
.adz-stat-chip--rejected { background: rgba(240,107,107,0.16); color: #F06B6B; }
.adz-stat-chip--forsale { background: rgba(19,205,203,0.16); color: var(--accent-teal); }

.adz-hero { display: flex; align-items: center; gap: 10px; margin: 16px 0 4px; flex-wrap: wrap; }
.adz-hero__swatch { width: 20px; height: 20px; border-radius: 50%; flex-shrink: 0; border: 2px solid var(--border); }
.adz-hero__code { font-size: 24px; font-weight: 700; }
.adz-hero__chip {
  font-size: 11px; color: var(--text-secondary);
  background: rgba(255,255,255,0.06);
  border-radius: 8px; padding: 3px 9px;
}
.adz-section { font-size: 13px; color: var(--text-secondary); margin-bottom: 16px; }

/* ── Mobile (<768px, MOBILE_STRATEGY §B2 breakpoint) ────────────────────────
   Placed last on purpose — CSS cascade order matters here as much as the
   media query itself: several unconditional `.adm-*` rules earlier in this
   file would otherwise win over same-specificity rules declared inside an
   earlier media query. Sidebar becomes an off-canvas drawer instead of
   squeezing the 240px column into a narrow viewport; topbar drops the
   search box. Tables keep their real <table> structure (2026-07-07 decision
   — a stacked-card/accordion pass was tried and reverted) and instead
   scroll horizontally inside their own container, so the rest of the page
   never scrolls sideways. */
@media (max-width: 768px) {
  .adm-shell { flex-direction: column; }

  .adm-sidebar {
    position: fixed; top: 0; left: 0; bottom: 0;
    z-index: 500;
    transform: translateX(-100%);
    transition: transform 0.2s ease;
    box-shadow: 4px 0 24px rgba(0,0,0,0.4);
  }
  .adm-sidebar.is-open { transform: translateX(0); }
  .adm-scrim.is-open { display: block; }

  .adm-mobile-toggle { display: flex; }
  /* justify-content:flex-start, not the desktop space-between — with the
     search box hidden below, space-between had only 2 children left
     (hamburger, title) and stretched them to opposite ends, making the
     page title read as right-aligned instead of sitting next to the menu
     button. */
  .adm-topbar { padding: 14px 16px; gap: 12px; justify-content: flex-start; }
  .adm-topbar__search { display: none; }
  .adm-content { padding: 16px; }

  /* Stat cards: fit as many as the viewport allows (usually 3) and only
     drop to fewer once a card gets too narrow for its own content. */
  .adm-stats { grid-template-columns: repeat(auto-fit, minmax(100px, 1fr)); }
  .adm-phase-grid { grid-template-columns: 1fr; }

  /* Search sits alone on its own row; every other filter control (selects,
     the Export CSV button, etc.) wraps onto the row(s) below and splits
     into 2–3 columns instead of scrolling off-screen. Giving the text input
     flex-basis:100% forces the wrap point right after it. */
  .adm-filters { flex-wrap: wrap; overflow-x: visible; }
  .adm-filters > input[type="text"], .adm-filters > .search-input-wrap { flex: 1 1 100%; min-width: 0; }
  .adm-filters > select, .adm-filters > button { flex: 1 1 30%; min-width: 0; }

  /* Table scrolls horizontally within its own box; nothing else on the page
     moves sideways. min-width keeps columns from squeezing illegibly thin
     before the scrollbar kicks in. white-space:nowrap stops long cell text
     (e.g. a timestamp) from line-wrapping inside a squeezed column — the
     whole point of the horizontal scroll is that columns keep their natural
     width instead of wrapping awkwardly. No gradient/fade affordance here
     by request — the scrollbar itself (tokens.css) is the only cue.
     touch-action:pan-x tells the browser this element only ever handles
     horizontal drags — vertical swipes starting on the table pass straight
     through to the page instead of the gesture being ambiguous. */
  .adm-table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; touch-action: pan-x; }
  .adm-table { min-width: 640px; }
  .adm-table th, .adm-table td { white-space: nowrap; }
}

/* ── Sponsor Giveaways admin forms (brand / campaign+prizes) ───────────────
   Reuses .adm-login-field's input styling (generic, not scoped to the login
   card) for text/select/textarea/date fields instead of inventing a second
   field style. */
.adm-login-field textarea, .adm-login-field select {
  width: 100%;
  background: rgba(255,255,255,0.04);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 11px 12px;
  color: var(--text-primary);
  font-family: inherit;
  font-size: 14px;
}
.adm-login-field textarea:focus, .adm-login-field select:focus { outline: none; border-color: var(--accent-gold); }
.adm-login-field textarea { resize: vertical; min-height: 90px; }
.adm-login-field--toggle { display: flex; align-items: center; justify-content: space-between; gap: 10px; }

.adm-form {
  max-width: 720px;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 22px;
  margin-bottom: 20px;
}
.adm-form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0 16px; }
.adm-form-section-title { font-size: 13px; font-weight: 700; color: var(--accent-gold); margin: 22px 0 10px; }
.adm-form-section-title:first-child { margin-top: 0; }
.adm-form-actions { display: flex; gap: 10px; margin-top: 8px; }

.adm-checkbox-group { display: flex; flex-wrap: wrap; gap: 8px; }
.adm-checkbox-item {
  display: inline-flex; align-items: center; gap: 6px;
  background: rgba(255,255,255,0.04);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 7px 10px;
  font-size: 12px;
  cursor: pointer;
  /* Button-safe reset (2026-07-24 ask) — some callers now render this as a
     plain <button> instead of <label><input type=checkbox>, since the chip
     itself is already the whole clickable control; buttons don't inherit
     color/font the way labels do by default, so restate both explicitly. */
  font-family: inherit;
  color: var(--text-primary);
}
.adm-checkbox-item input { margin: 0; }
.adm-checkbox-item.is-checked { border-color: var(--accent-gold); color: var(--accent-gold); background: rgba(244,161,64,0.1); }

/* Chevron hint on a text input backed by a <datalist> (2026-07-24 ask) — a
   plain text box gives no visual cue that typing opens suggestions; same
   arrow treatment as .nt-select-wrap (giveaway.css), just for a text input
   instead of a real <select>. */
.adm-suggest-wrap { position: relative; }
.adm-suggest-wrap input { padding-right: 30px; }
.adm-suggest-wrap::after {
  content: '▾';
  position: absolute;
  right: 12px;
  top: 50%;
  transform: translateY(-50%);
  font-size: 9px;
  color: var(--text-secondary);
  pointer-events: none;
}

/* Locked/disabled input with the lock icon INSIDE the field itself
   (2026-07-24 ask), not just next to its label — a clearer "you can't type
   here" cue right where the cursor would otherwise go. */
.adm-locked-input-wrap { position: relative; }
.adm-locked-input-wrap input { padding-right: 34px; }
.adm-locked-input-wrap__icon {
  position: absolute;
  right: 12px;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  /* text-secondary (139,143,168) on its own already reads fine against the
     dark input; the extra opacity:0.7 stacked on top (2026-07-24 fix, was
     dimming it further, looked closer to sunken-black than a visible icon)
     is gone. */
  color: var(--text-secondary);
  pointer-events: none;
}
.adm-locked-input-wrap__icon svg { width: 12px; height: 12px; }

.adm-logo-upload { display: flex; align-items: center; gap: 14px; }
.adm-logo-upload__preview {
  width: 64px; height: 64px; flex-shrink: 0;
  border-radius: 10px; border: 1px dashed var(--border);
  background: rgba(255,255,255,0.04) center/cover no-repeat;
  display: flex; align-items: center; justify-content: center;
  font-size: 10px; color: var(--text-secondary); text-align: center;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
}
.adm-logo-upload__preview:hover { border-color: var(--accent-gold); }
/* Icon + short label instead of a bare "IMG" placeholder string (2026-07-24
   fix) — reads as an upload affordance, not an unfinished placeholder. Only
   shown when the preview has no background-image set (empty state). */
/* opacity:0.6 removed (2026-07-24 fix) — stacked on top of the already-muted
   text-secondary color it inherits, this read as a dark/sunken icon rather
   than a clear upload affordance against the dark preview box. */
.adm-logo-upload__preview-empty { display: flex; flex-direction: column; align-items: center; gap: 4px; color: var(--text-secondary); pointer-events: none; }
.adm-logo-upload__preview-empty svg { width: 18px; height: 18px; }

/* Full-width dropzone variant (2026-07-24 ask, giveaway-form.js only — the
   base 64px square elsewhere, e.g. admin-fanproject-edit.js's own logo
   upload, is unaffected since it never adds this modifier). */
.adm-logo-upload--wide { display: block; }
.adm-logo-upload__preview--wide {
  width: 100%;
  height: 140px;
  flex-direction: column;
  gap: 6px;
}
.adm-logo-upload__preview--wide .adm-logo-upload__preview-empty { flex-direction: row; font-size: 13px; gap: 8px; }
.adm-logo-upload__preview--wide .adm-logo-upload__preview-empty svg { width: 22px; height: 22px; }

.adm-prize-row {
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 14px;
  margin-bottom: 12px;
  background: rgba(255,255,255,0.02);
}
.adm-prize-row__head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; }
.adm-prize-row__title { font-size: 12px; font-weight: 700; color: var(--text-secondary); }
.adm-prize-row__actions { display: flex; align-items: center; gap: 8px; }
.adm-prize-row__actions .tk-btn--icon:disabled { opacity: 0.35; cursor: not-allowed; }
.adm-prize-row__grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0 16px; }

@media (max-width: 768px) {
  .adm-form { padding: 16px; max-width: 100%; }
  .adm-form-grid, .adm-prize-row__grid { grid-template-columns: 1fr; }
}

/* Star Buddy reports (admin-marketplace.js — §13, folded into this same
   page rather than a separate admin screen). List, not a table, since a
   ride_shares post has a different shape than a ticket listing. */
.adm-gohome-reports { margin-top: 24px; }
.adm-gohome-reports__head { margin-bottom: 12px; }
.adm-gohome-reports__title { font-size: 14px; font-weight: 700; }
.adm-gohome-reports__empty { font-size: 12px; color: var(--text-secondary); padding: 12px 0; }
.adm-gohome-report {
  position: relative; /* anchors .adm-gohome-report__corner-btn (2026-07-15 ask) */
  border: 1px solid var(--border); border-radius: 10px;
  padding: 12px 44px 12px 14px; margin-bottom: 10px;
  background: rgba(255,255,255,0.02);
}
/* Delete in the card's bottom-right corner (2026-07-15 ask) — was its own
   full-width button row under every card. */
.adm-gohome-report__corner-btn { position: absolute; right: 10px; bottom: 10px; }
.adm-gohome-report__route { font-size: 13px; font-weight: 700; }
.adm-gohome-report__meta { font-size: 11px; color: var(--text-secondary); margin-top: 4px; }
.adm-gohome-report__reason { font-size: 12px; color: var(--like-red); margin-top: 6px; font-weight: 600; }
.adm-gohome-report__detail { font-size: 12px; color: var(--text-secondary); margin-top: 4px; }
.adm-gohome-report__time { font-size: 10px; color: var(--text-secondary); margin-top: 6px; }

/* admin-health.js redesign (2026-07-26 ask — "too cluttered", full page
   redesign): the on/off toggle collapses to one row instead of its own
   card, and the add form is a disclosure instead of always taking space. */
.adh-toggle-row {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 14px 16px;
  background: var(--bg-elevated, rgba(255,255,255,0.03));
  border: 1px solid var(--border);
  border-radius: 10px;
  margin-bottom: 20px;
}
.adh-toggle-row__label { font-size: 13px; font-weight: 700; }
.adh-toggle-row__desc { font-size: 11px; color: var(--text-secondary); margin-top: 2px; }

.adh-add-toggle {
  display: block;
  margin: 4px 0 20px;
  padding: 10px 16px;
  background: rgba(244, 161, 64, 0.12);
  border: 1px solid rgba(244, 161, 64, 0.4);
  border-radius: 8px;
  color: var(--accent-gold);
  font: 700 13px var(--font-thai);
  cursor: pointer;
}
.adh-form-panel:not([hidden]) { margin-bottom: 20px; }

.adh-source-badge {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
}
.adh-source-badge--self { background: rgba(19, 205, 203, 0.14); color: var(--accent-teal); }
.adh-source-badge--manual { background: rgba(74, 85, 120, 0.25); color: #B8C0DE; }

/* admin-homesafe.js — identity cell (avatar + name/flag + handle) reused
   inside an .adm-table row, same visual language as .hs-card's left side
   (homesafe.css) scaled down for a table cell. */
.adh-user-cell { display: flex; align-items: center; gap: 8px; }
.adh-user-cell__avatar {
  width: 28px; height: 28px; border-radius: 50%; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: 14px;
}
.adh-user-cell__name { display: flex; align-items: center; gap: 6px; font-weight: 600; }
.adh-user-cell__handle { font-size: 11px; color: var(--text-secondary); }
