/* ============================================================================
   Multi-Vendor Marketplace — Admin Panel Design System
   PHP 8.2 + MySQL 8 | Vanilla CSS + Alpine.js | No Tailwind
   ============================================================================ */

/* ---------- Design Tokens ---------- */
:root {
  /* Brand — teal #00515e (matches client storefront) */
  --brand: #00515e;
  --brand-600: #006574;
  --brand-700: #003d47;
  --brand-soft: #d9eef0;     /* light teal tint for backgrounds */
  --brand-soft-2: #e5f4f5;   /* even softer */

  /* Semantic */
  --success: #16a34a;
  --success-soft: #d1fae5;
  --warning: #d97706;
  --warning-soft: #fef3c7;
  --danger: #dc2626;
  --danger-soft: #fee2e2;
  --info: #00515e;            /* tie info to brand for consistency */
  --info-soft: #d9eef0;

  /* Neutrals — light theme (warm grey, not blue) */
  --bg: #f5f5f7;
  --surface: #ffffff;
  --surface-2: #fafafa;
  --border: #e5e7eb;
  --border-strong: #d1d5db;
  --text: #111827;
  --text-2: #4b5563;
  --text-3: #6b7280;
  --muted: #f3f4f6;

  /* Layout */
  --sidebar-w: 264px;
  --sidebar-collapsed-w: 76px;
  --header-h: 64px;
  --radius-sm: 6px;
  --radius: 10px;
  --radius-lg: 14px;
  --radius-pill: 999px;

  /* Shadow — neutral grey, no blue cast */
  --shadow-xs: 0 1px 2px rgba(0, 0, 0, .04);
  --shadow-sm: 0 2px 6px rgba(0, 0, 0, .05);
  --shadow: 0 6px 18px rgba(0, 0, 0, .07);
  --shadow-lg: 0 12px 32px rgba(0, 0, 0, .10);

  /* Focus ring — visible on every interactive element via :focus-visible */
  --focus-ring: 0 0 0 3px var(--brand-soft);

  /* Motion */
  --t-fast: 140ms cubic-bezier(.4, 0, .2, 1);
  --t:      220ms cubic-bezier(.4, 0, .2, 1);
  --t-slow: 320ms cubic-bezier(.4, 0, .2, 1);
  --ease-bounce: cubic-bezier(.34, 1.56, .64, 1);
}

/* ---------- Dark theme — slate-charcoal with cool brand pop ----------
   The previous dark theme used pure black, which made cards disappear into
   the page and lost depth. Switched to layered greys so surfaces stay
   visible, raised the brand teal so it doesn't muddy on dark, and built a
   shadow override that uses BLACK alpha (white shadows are pointless on a
   light background; black shadows are invisible on dark — both need the
   right colour). */
[data-theme="dark"] {
  --bg:         #0b0d10;
  --surface:    #14171c;
  --surface-2:  #1a1e24;
  --border:     #262b33;
  --border-strong: #363c46;
  --text:       #e7eaef;
  --text-2:     #a8b0bd;
  --text-3:     #6b7280;
  --muted:      #1d2129;

  --brand:      #4dd4e1;     /* bright cyan-teal — pops on dark */
  --brand-600:  #6fdbe6;     /* hover */
  --brand-700:  #8ce4ed;     /* even brighter for active text */
  --brand-soft: rgba(77, 212, 225, 0.12);
  --brand-soft-2: rgba(77, 212, 225, 0.06);
  --info:       #4dd4e1;
  --info-soft:  rgba(77, 212, 225, 0.12);

  --success-soft: rgba(34, 197, 94, 0.14);
  --warning-soft: rgba(245, 158, 11, 0.14);
  --danger-soft:  rgba(239, 68, 68, 0.14);

  --shadow-xs: 0 1px 2px rgba(0, 0, 0, .35);
  --shadow-sm: 0 2px 6px rgba(0, 0, 0, .45);
  --shadow:    0 6px 20px rgba(0, 0, 0, .55);
  --shadow-lg: 0 16px 40px rgba(0, 0, 0, .65);

  --focus-ring: 0 0 0 3px rgba(77, 212, 225, 0.35);
}

/* Smooth theme switch — only enabled AFTER first paint (the .theming class
   is added by layout.php in requestAnimationFrame) so we don't get a
   transition cascade on initial load. */
html.theming,
html.theming body,
html.theming .sidebar,
html.theming .header,
html.theming .card,
html.theming .kpi,
html.theming .modal,
html.theming .dropdown-menu,
html.theming .input,
html.theming .select,
html.theming .textarea,
html.theming .btn,
html.theming .nav-item {
  transition: background-color var(--t), color var(--t),
              border-color var(--t), box-shadow var(--t);
}

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }

/* Bind native form-widget colour scheme to our actual theme so the browser
   doesn't render dark `<select>` widgets when the OS is in dark mode but
   our admin UI is in light. Without this, pages with inline-styled selects
   (interaction, response, updates/search, users/permissions) look broken. */
html[data-theme="light"] { color-scheme: light; }
html[data-theme="dark"]  { color-scheme: dark; }

body {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  font-size: 14px;
  line-height: 1.5;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
}
img, svg { max-width: 100%; display: block; }
button { font: inherit; cursor: pointer; border: 0; background: none; color: inherit; }
a { color: var(--brand); text-decoration: none; }
a:hover { color: var(--brand-700); }
table { border-collapse: collapse; width: 100%; }

/* Element-level defaults for native form controls so pages that style
   their selects/inputs with inline styles (border only, no background)
   still render correctly in both themes. */
input, select, textarea, button {
  font: inherit;
  color: var(--text);
}
select, input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="submit"]):not([type="button"]) {
  background-color: var(--surface);
  color: var(--text);
}
select option { background-color: var(--surface); color: var(--text); }
::placeholder { color: var(--text-3); opacity: 1; }

/* Alpine.js cloak — hide elements until Alpine has bound them so
   x-show / x-text don't flash uninitialized content (e.g. modals). */
[x-cloak] { display: none !important; }

/* ---------- Layout ----------
   The shell is fixed to the viewport. Sidebar and main are independent
   scroll containers — sidebar stays put, content scrolls inside .main. */
.app {
  display: grid;
  grid-template-columns: var(--sidebar-w) 1fr;
  height: 100vh;
  overflow: hidden;
  transition: grid-template-columns var(--t);
}
.app.collapsed { grid-template-columns: var(--sidebar-collapsed-w) 1fr; }

/* ---------- Sidebar ---------- */
.sidebar {
  background: var(--surface);
  border-right: 1px solid var(--border);
  height: 100vh;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  scrollbar-width: thin;
  scrollbar-color: var(--border-strong) transparent;
}
.sidebar::-webkit-scrollbar { width: 6px; }
.sidebar::-webkit-scrollbar-track { background: transparent; }
.sidebar::-webkit-scrollbar-thumb {
  background: var(--border-strong);
  border-radius: 3px;
  transition: background var(--t-fast);
}
.sidebar::-webkit-scrollbar-thumb:hover { background: var(--text-3); }

/* `.brand` is scoped to the sidebar so it never collides with utility
   classes like `.badge-pill.brand` (which uses brand colors but is a
   small inline pill, not a full-height header). */
.sidebar .brand {
  display: flex;
  align-items: center;
  gap: 10px;
  height: var(--header-h);
  padding: 0 18px;
  border-bottom: 1px solid var(--border);
  font-weight: 700;
  font-size: 16px;
  letter-spacing: -.01em;
  flex-shrink: 0;
  color: var(--text);
}
.sidebar .brand:hover { color: var(--text); }
.sidebar .brand-logo {
  width: 34px; height: 34px;
  border-radius: 9px;
  background: linear-gradient(135deg, var(--brand) 0%, var(--brand-700) 100%);
  display: grid; place-items: center;
  color: #fff; font-weight: 700;
  flex-shrink: 0;
  box-shadow: 0 4px 10px var(--brand-soft);
  transition: transform var(--t), box-shadow var(--t);
}
.sidebar .brand:hover .brand-logo { transform: rotate(-6deg) scale(1.05); }
.sidebar .brand-text {
  white-space: nowrap;
  opacity: 1;
  transition: opacity var(--t-fast);
}
.app.collapsed .sidebar .brand { padding: 0; justify-content: center; }
.app.collapsed .sidebar .brand-text { display: none; }

.nav-section {
  padding: 14px 12px 4px;
}
.nav-section-title {
  text-transform: uppercase;
  font-size: 11px;
  font-weight: 600;
  color: var(--text-3);
  letter-spacing: .08em;
  padding: 0 10px 8px;
  transition: opacity var(--t-fast);
}
.app.collapsed .nav-section-title {
  /* Collapsed: hide label, show a thin separator instead so groups still
     read as groups. */
  height: 1px; padding: 0; margin: 12px 14px;
  background: var(--border);
  overflow: hidden;
  color: transparent;
}

.nav-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 9px 12px;
  border-radius: var(--radius);
  color: var(--text-2);
  font-weight: 500;
  margin-bottom: 2px;
  position: relative;
  transition: background var(--t-fast), color var(--t-fast),
              transform var(--t-fast);
  cursor: pointer;
  user-select: none;
}
.nav-item:hover {
  background: var(--muted);
  color: var(--text);
}
.nav-item:active { transform: translateY(1px); }
.nav-item.active {
  background: var(--brand-soft);
  color: var(--brand-700);
  font-weight: 600;
}
/* Left bar accent on the active item */
.nav-item.active::before {
  content: '';
  position: absolute;
  left: -12px;
  top: 50%;
  transform: translateY(-50%);
  width: 3px;
  height: 18px;
  background: var(--brand);
  border-radius: 0 3px 3px 0;
  animation: navIndicator var(--t) var(--ease-bounce);
}
@keyframes navIndicator {
  from { height: 0; opacity: 0; }
  to   { height: 18px; opacity: 1; }
}
.nav-item .icon {
  width: 18px; height: 18px;
  flex-shrink: 0;
  transition: transform var(--t-fast);
}
.nav-item:hover .icon { transform: scale(1.08); }
.nav-item .badge {
  margin-left: auto;
  font-size: 11px;
  background: var(--danger);
  color: #fff;
  border-radius: var(--radius-pill);
  padding: 2px 7px;
  font-weight: 600;
  box-shadow: 0 0 0 2px var(--surface);
}

/* Stagger entry animation on first paint */
.nav-section .nav-item,
.nav-section .nav-group {
  animation: navIn 360ms ease both;
}
.nav-section .nav-item:nth-child(2) { animation-delay: 30ms; }
.nav-section .nav-item:nth-child(3) { animation-delay: 60ms; }
.nav-section .nav-item:nth-child(4) { animation-delay: 90ms; }
.nav-section .nav-item:nth-child(5) { animation-delay: 120ms; }
.nav-section .nav-item:nth-child(6) { animation-delay: 150ms; }
@keyframes navIn {
  from { opacity: 0; transform: translateX(-8px); }
  to   { opacity: 1; transform: none; }
}

/* Collapsed sidebar: hide text + badges, center icon, add tooltip on hover */
.app.collapsed .nav-item span:not(.icon),
.app.collapsed .nav-item .badge,
.app.collapsed .nav-item .chevron { display: none; }
.app.collapsed .nav-item { justify-content: center; padding: 11px 0; }
.app.collapsed .nav-item.active::before {
  left: 0; height: 60%; width: 3px;
}
/* Tooltip — populated by data-label set in layout.php */
.app.collapsed .sidebar .nav-item[data-label]::after {
  content: attr(data-label);
  position: absolute;
  left: calc(100% + 12px);
  top: 50%;
  transform: translateY(-50%) translateX(-4px);
  background: var(--text);
  color: var(--surface);
  font-size: 12px;
  font-weight: 500;
  padding: 6px 10px;
  border-radius: var(--radius-sm);
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  z-index: 70;
  box-shadow: var(--shadow);
  transition: opacity var(--t-fast), transform var(--t-fast);
}
.app.collapsed .sidebar .nav-item[data-label]:hover::after {
  opacity: 1;
  transform: translateY(-50%) translateX(0);
}
/* Suppress tooltips inside groups so the parent label isn't repeated */
.app.collapsed .nav-children .nav-item::after { content: none !important; }

/* Collapsed: hide nav-children entirely; group becomes icon-only */
.app.collapsed .nav-children { display: none !important; }

.nav-group { position: relative; }
.nav-group .nav-children {
  margin-left: 30px;
  padding-left: 10px;
  border-left: 1px solid var(--border);
  /* max-height animation — closed = 0, open = enough for any group. The
     transition timing scales with the difference, but for our small lists
     (≤12 items × 30px) the cap is around 360 px, which closes fast enough
     to feel responsive. The previous `grid-template-rows: 0fr → 1fr` trick
     looks great when it works but reverses unreliably across browsers. */
  max-height: 0;
  overflow: hidden;
  opacity: 0;
  transition: max-height var(--t), opacity var(--t-fast),
              padding var(--t-fast);
  padding-top: 0;
  padding-bottom: 0;
}
.nav-group.open .nav-children {
  max-height: 600px;
  opacity: 1;
  padding-top: 4px;
  padding-bottom: 4px;
}
.nav-group .chevron {
  margin-left: auto;
  transition: transform var(--t);
  opacity: .6;
}
.nav-group.open .chevron { transform: rotate(90deg); opacity: 1; }
.nav-children .nav-item {
  font-size: 13px;
  padding: 7px 12px;
  margin-bottom: 1px;
}
.nav-children .nav-item:hover { transform: translateX(2px); }

/* Sidebar footer — theme toggle, version, etc. */
.sidebar-foot {
  margin-top: auto;
  padding: 12px;
  border-top: 1px solid var(--border);
  position: sticky;
  bottom: 0;
  background: linear-gradient(180deg, transparent, var(--surface) 30%);
}
.theme-pill {
  width: 100%;
  border: 1px solid var(--border);
  background: var(--surface-2);
  justify-content: center;
  font-weight: 600;
}
.theme-pill:hover { background: var(--muted); border-color: var(--border-strong); }
.app.collapsed .sidebar-foot { padding: 12px 8px; }
.app.collapsed .theme-pill span { display: none; }

/* ---------- Header ---------- */
.main {
  display: flex;
  flex-direction: column;
  min-width: 0;
  height: 100vh;       /* fill the shell */
  overflow: hidden;    /* let .content own the scroll */
}
.header {
  height: var(--header-h);
  flex-shrink: 0;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 20px;
  z-index: 30;
  position: relative;
  backdrop-filter: saturate(1.2);
  -webkit-backdrop-filter: saturate(1.2);
}
/* Push the right-side cluster (notifications + user) hard-right.
   Whichever element comes after .search becomes the right group. */
.header > .search { margin-right: auto; }
.header > .search ~ .icon-btn,
.header > .search ~ .dropdown { flex-shrink: 0; }

.icon-btn {
  width: 40px; height: 40px;
  border-radius: var(--radius);
  display: grid; place-items: center;
  color: var(--text-2);
  position: relative;
  transition: background var(--t-fast), color var(--t-fast),
              transform var(--t-fast);
}
.icon-btn:hover { background: var(--muted); color: var(--text); }
.icon-btn:active { transform: scale(.94); }
.icon-btn .dot {
  position: absolute; top: 8px; right: 9px;
  width: 8px; height: 8px;
  background: var(--danger);
  border-radius: 50%;
  border: 2px solid var(--surface);
  animation: pulseDot 2s ease-in-out infinite;
}
@keyframes pulseDot {
  0%, 100% { box-shadow: 0 0 0 0 rgba(220, 38, 38, .55); }
  50%      { box-shadow: 0 0 0 6px rgba(220, 38, 38, 0); }
}

/* Theme toggle — animate the icon swap */
.theme-toggle .theme-ico {
  transition: transform var(--t) var(--ease-bounce), opacity var(--t-fast);
}
.theme-toggle:hover .theme-ico.sun  { transform: rotate(90deg); }
.theme-toggle:hover .theme-ico.moon { transform: rotate(-15deg); }

/* Universal focus-visible ring — only shown for keyboard, not mouse clicks */
:focus { outline: none; }
.icon-btn:focus-visible,
.btn:focus-visible,
.input:focus-visible,
.select:focus-visible,
.textarea:focus-visible,
.search input:focus-visible,
.nav-item:focus-visible,
.user-chip:focus-visible,
.dropdown-item:focus-visible,
.theme-pill:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
  border-radius: var(--radius);
}

.search {
  flex: 1;
  max-width: 460px;
  position: relative;
}
.search input {
  width: 100%;
  height: 38px;
  border: 1px solid var(--border);
  background: var(--bg);
  border-radius: var(--radius);
  padding: 0 14px 0 38px;
  outline: none;
  transition: border-color var(--t-fast), box-shadow var(--t-fast);
}
.search input:focus {
  border-color: var(--brand);
  box-shadow: 0 0 0 3px var(--brand-soft);
}
.search .search-icon {
  position: absolute; left: 12px; top: 50%; transform: translateY(-50%);
  color: var(--text-3); pointer-events: none;
}

.user-chip {
  display: flex; align-items: center; gap: 10px;
  padding: 4px 12px 4px 4px;
  border-radius: var(--radius-pill);
  cursor: pointer;
  transition: background var(--t-fast);
}
.user-chip:hover { background: var(--muted); }
.avatar {
  width: 32px; height: 32px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--brand), var(--brand-700));
  color: #fff;
  display: grid; place-items: center;
  font-weight: 600;
  font-size: 13px;
  flex-shrink: 0;
}
.avatar-lg { width: 64px; height: 64px; font-size: 22px; }
.avatar-sm { width: 24px; height: 24px; font-size: 11px; }
.user-chip-name { font-weight: 600; font-size: 13px; }
.user-chip-role { font-size: 11px; color: var(--text-3); }

/* ---------- Content ----------
   Owns the vertical scroll — sidebar and header stay still. */
.content {
  flex: 1;
  padding: 24px;
  max-width: 100%;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}
.page-head {
  display: flex; align-items: flex-end; justify-content: space-between; gap: 16px;
  margin-bottom: 20px;
  flex-wrap: wrap;
}
.page-title {
  font-size: 22px; font-weight: 700; margin: 0 0 4px;
  letter-spacing: -.01em;
}
.page-sub { color: var(--text-3); font-size: 13px; margin: 0; }
.breadcrumb {
  display: flex; gap: 6px; font-size: 12px; color: var(--text-3);
  margin-bottom: 10px;
}
.breadcrumb a { color: var(--text-3); }
.breadcrumb a:hover { color: var(--text); }
.breadcrumb-sep { color: var(--border-strong); }

/* ---------- Cards ---------- */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
  overflow: hidden;
}
.card-header {
  padding: 16px 20px;
  border-bottom: 1px solid var(--border);
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px;
}
.card-title { font-size: 15px; font-weight: 600; margin: 0; }
.card-body { padding: 20px; }
.card-footer {
  padding: 14px 20px;
  border-top: 1px solid var(--border);
  background: var(--surface-2);
}

/* ---------- KPI Cards ---------- */
.kpi-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 16px;
  margin-bottom: 24px;
}
.kpi {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 18px 20px;
  position: relative;
  overflow: hidden;
  transition: transform var(--t-fast), box-shadow var(--t-fast),
              border-color var(--t-fast);
}
.kpi:hover {
  transform: translateY(-2px);
  border-color: var(--border-strong);
  box-shadow: var(--shadow-sm);
}
/* Subtle gradient sheen on the top edge */
.kpi::after {
  content: '';
  position: absolute;
  inset: 0 0 auto 0;
  height: 2px;
  background: linear-gradient(90deg, transparent, var(--brand), transparent);
  opacity: 0;
  transition: opacity var(--t);
}
.kpi:hover::after { opacity: .6; }
.kpi-label {
  font-size: 12px; color: var(--text-3); text-transform: uppercase;
  font-weight: 600; letter-spacing: .05em;
}
.kpi-value {
  font-size: 28px; font-weight: 700;
  margin: 6px 0 4px;
  letter-spacing: -.02em;
}
.kpi-trend {
  font-size: 12px; font-weight: 600;
  display: inline-flex; align-items: center; gap: 4px;
}
.kpi-trend.up { color: var(--success); }
.kpi-trend.down { color: var(--danger); }
.kpi-icon {
  position: absolute; top: 18px; right: 18px;
  width: 36px; height: 36px; border-radius: 10px;
  display: grid; place-items: center;
  background: var(--brand-soft); color: var(--brand);
}
.kpi-icon.success { background: var(--success-soft); color: var(--success); }
.kpi-icon.warning { background: var(--warning-soft); color: var(--warning); }
.kpi-icon.danger { background: var(--danger-soft); color: var(--danger); }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  height: 38px;
  padding: 0 16px;
  border-radius: var(--radius);
  font-weight: 600; font-size: 13px;
  border: 1px solid transparent;
  transition: all var(--t-fast);
  white-space: nowrap;
}
.btn:disabled { opacity: .55; cursor: not-allowed; }
.btn:not(:disabled):active { transform: translateY(1px); }
.btn-primary {
  background: var(--brand); color: #fff;
  box-shadow: 0 1px 2px rgba(0, 0, 0, .08), inset 0 1px 0 rgba(255, 255, 255, .15);
}
.btn-primary:hover:not(:disabled) {
  background: var(--brand-600);
  box-shadow: 0 4px 12px var(--brand-soft), inset 0 1px 0 rgba(255, 255, 255, .15);
}
[data-theme="dark"] .btn-primary { color: var(--bg); }
.btn-secondary {
  background: var(--surface); color: var(--text); border-color: var(--border);
}
.btn-secondary:hover:not(:disabled) { border-color: var(--border-strong); background: var(--muted); }
.btn-danger { background: var(--danger); color: #fff; }
.btn-danger:hover:not(:disabled) { background: #b91c1c; box-shadow: 0 4px 12px rgba(220, 38, 38, .25); }
.btn-success { background: var(--success); color: #fff; }
.btn-success:hover:not(:disabled) { background: #15803d; box-shadow: 0 4px 12px rgba(22, 163, 74, .25); }
.btn-ghost { color: var(--text-2); }
.btn-ghost:hover { background: var(--muted); color: var(--text); }
.btn-sm { height: 30px; padding: 0 12px; font-size: 12px; }
.btn-lg { height: 44px; padding: 0 22px; font-size: 14px; }
.btn-block { width: 100%; }

/* ---------- Forms ---------- */
.field { margin-bottom: 16px; }
.label {
  display: block; font-size: 13px; font-weight: 600;
  margin-bottom: 6px; color: var(--text);
}
.label .req { color: var(--danger); }
.input, .select, .textarea {
  width: 100%;
  height: 40px;
  border: 1px solid var(--border);
  background: var(--surface);
  border-radius: var(--radius);
  padding: 0 14px;
  outline: none;
  color: var(--text);
  transition: border-color var(--t-fast), box-shadow var(--t-fast);
}
.textarea { height: auto; padding: 12px 14px; resize: vertical; min-height: 100px; }
.input:focus, .select:focus, .textarea:focus {
  border-color: var(--brand);
  box-shadow: 0 0 0 3px var(--brand-soft);
}
.help { font-size: 12px; color: var(--text-3); margin-top: 4px; }
.error { font-size: 12px; color: var(--danger); margin-top: 4px; }

.input-group {
  display: flex; align-items: stretch;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  overflow: hidden;
}
.input-group:focus-within { border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-soft); }
.input-group .input { border: 0; height: 38px; }
.input-group-addon {
  display: grid; place-items: center;
  padding: 0 12px;
  background: var(--muted);
  color: var(--text-3);
  font-size: 13px;
  border-right: 1px solid var(--border);
}

.checkbox, .radio {
  width: 18px; height: 18px;
  accent-color: var(--brand);
  cursor: pointer;
}
.toggle {
  position: relative; display: inline-block;
  width: 40px; height: 22px;
}
.toggle input { display: none; }
.toggle-slider {
  position: absolute; inset: 0;
  background: var(--border-strong);
  border-radius: var(--radius-pill);
  cursor: pointer;
  transition: background var(--t);
}
.toggle-slider::before {
  content: ''; position: absolute;
  width: 16px; height: 16px;
  left: 3px; top: 3px;
  background: #fff;
  border-radius: 50%;
  transition: transform var(--t);
}
.toggle input:checked + .toggle-slider { background: var(--brand); }
.toggle input:checked + .toggle-slider::before { transform: translateX(18px); }

.form-grid {
  display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px;
}
.form-grid .full { grid-column: 1 / -1; }
@media (max-width: 720px) { .form-grid { grid-template-columns: 1fr; } }

/* ---------- Tables ---------- */
.table-wrap {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}
.table {
  font-size: 13px;
  min-width: 100%;
}
.table thead th {
  text-align: left;
  font-weight: 600;
  color: var(--text-3);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: .04em;
  padding: 12px 16px;
  background: var(--surface-2);
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
.table tbody td {
  padding: 14px 16px;
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
}
.table tbody tr:last-child td { border-bottom: 0; }
.table tbody tr:hover { background: var(--surface-2); }
.table .num { text-align: right; font-variant-numeric: tabular-nums; }
.table .actions { white-space: nowrap; text-align: right; }

.table-toolbar {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 14px 20px;
  border-bottom: 1px solid var(--border);
  background: var(--surface-2);
}
.table-toolbar .spacer { flex: 1; }

/* ---------- Badges & Chips ---------- */
.badge-pill {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 10px;
  font-size: 11px;
  font-weight: 600;
  border-radius: var(--radius-pill);
  background: var(--muted);
  color: var(--text-2);
  text-transform: capitalize;
}
.badge-pill.success { background: var(--success-soft); color: #047857; }
.badge-pill.warning { background: var(--warning-soft); color: #b45309; }
.badge-pill.danger { background: var(--danger-soft); color: #b91c1c; }
.badge-pill.info { background: var(--info-soft); color: var(--brand-700); }
.badge-pill.brand { background: var(--brand-soft); color: var(--brand-700); }
.badge-pill::before {
  content: ''; width: 6px; height: 6px; border-radius: 50%;
  background: currentColor;
}

.chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px;
  background: var(--muted);
  border-radius: var(--radius-pill);
  font-size: 12px;
  color: var(--text-2);
}
.chip-close {
  width: 14px; height: 14px;
  border-radius: 50%;
  display: grid; place-items: center;
  background: var(--border-strong);
  color: #fff;
  font-size: 10px;
  cursor: pointer;
}

/* ---------- Tabs ---------- */
.tabs {
  display: flex; gap: 2px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 20px;
  overflow-x: auto;
}
.tab {
  padding: 10px 16px;
  font-weight: 600; font-size: 13px;
  color: var(--text-2);
  border-bottom: 2px solid transparent;
  cursor: pointer;
  white-space: nowrap;
  transition: color var(--t-fast), border-color var(--t-fast);
}
.tab:hover { color: var(--text); }
.tab.active {
  color: var(--brand);
  border-color: var(--brand);
}

/* ---------- Alert / Notice ---------- */
.alert {
  padding: 12px 16px;
  border-radius: var(--radius);
  border: 1px solid;
  display: flex; gap: 10px;
  margin-bottom: 16px;
}
.alert.info { background: var(--info-soft); border-color: var(--brand); color: var(--brand-700); }
.alert.success { background: var(--success-soft); border-color: #6ee7b7; color: #065f46; }
.alert.warning { background: var(--warning-soft); border-color: #fcd34d; color: #92400e; }
.alert.danger { background: var(--danger-soft); border-color: #fca5a5; color: #991b1b; }

/* ---------- Modal ----------
   `.modal-backdrop` and `.modal-overlay` are aliases — both render the
   modal as a fixed, viewport-centered popup on top of dimmed content.
   `position: fixed` is enforced with !important because some pages have
   their own backdrop styles that previously broke pinning. */
.modal-backdrop,
.modal-overlay {
  position: fixed !important;
  top: 0 !important; right: 0 !important;
  bottom: 0 !important; left: 0 !important;
  z-index: 100;
  background: rgba(15, 18, 32, .55);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
  display: flex; align-items: center; justify-content: center;
  padding: 20px;
  animation: fadeIn var(--t);
  overflow-y: auto;
  /* Don't let any ancestor's transform turn `fixed` into `absolute`. */
  transform: none !important;
  filter: none !important;
}
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
.modal {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  width: 100%; max-width: 540px;
  box-shadow: var(--shadow-lg);
  animation: modalIn var(--t) ease;
  max-height: 90vh; overflow-y: auto;
  margin: auto; /* belt-and-braces centering for older browsers */
}
@keyframes modalIn {
  from { transform: translateY(12px); opacity: 0; }
  to   { transform: none; opacity: 1; }
}

/* Lock body scroll when a modal is open. Page scripts can opt in by
   adding the `modal-open` class to <body>; for the common pattern
   where the modal is a direct child of <body>/.app, a CSS-only guard:
   if any modal-overlay is rendered, freeze the surrounding scroll. */
body:has(> .modal-overlay),
body:has(> .modal-backdrop),
.app:has(> .modal-overlay),
.app:has(> .modal-backdrop) { overflow: hidden; }
.modal-lg { max-width: 760px; }
.modal-header {
  padding: 18px 22px; border-bottom: 1px solid var(--border);
  display: flex; align-items: center; justify-content: space-between;
}
.modal-title { font-size: 16px; font-weight: 600; margin: 0; }
.modal-body { padding: 22px; }
.modal-footer {
  padding: 14px 22px; border-top: 1px solid var(--border);
  display: flex; gap: 8px; justify-content: flex-end;
}

/* ---------- Dropdown ---------- */
.dropdown { position: relative; }
.dropdown-menu {
  /* Default positioning — header dropdowns (notifications, user menu) use
     this. Page-level dropdowns that need viewport-relative coords (e.g.
     row-action menus in /admin/products/all.php) supply their own
     position:fixed via inline style; the `:not([style*="position"])`
     guard below makes sure our default doesn't override them. */
  position: absolute; right: 0; top: calc(100% + 8px);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  min-width: 220px;
  padding: 6px;
  z-index: 50;
  animation: dropdownIn var(--t-fast) ease;
}
/* Animate only opacity — never transform. Transforms break the perceived
   position of dropdowns that are anchored via inline `position: fixed`
   coordinates from JavaScript (getBoundingClientRect). */
@keyframes dropdownIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.dropdown-item {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 12px;
  border-radius: var(--radius-sm);
  font-size: 13px;
  color: var(--text);
  cursor: pointer;
  width: 100%;
  text-align: left;
  transition: background var(--t-fast), color var(--t-fast);
}
.dropdown-item:hover { background: var(--muted); }
.dropdown-item.danger { color: var(--danger); }
.dropdown-item.danger:hover { background: var(--danger-soft); }
.dropdown-divider { height: 1px; background: var(--border); margin: 6px 0; }

/* ---------- Utilities ---------- */
.flex { display: flex; }
.flex-col { display: flex; flex-direction: column; }
.items-center { align-items: center; }
.items-start { align-items: flex-start; }
.justify-between { justify-content: space-between; }
.justify-end { justify-content: flex-end; }
.gap-2 { gap: 8px; } .gap-3 { gap: 12px; } .gap-4 { gap: 16px; } .gap-6 { gap: 24px; }
.grid { display: grid; }
.text-center { text-align: center; }
.text-right { text-align: right; }
.text-muted { color: var(--text-3); }
.text-sm { font-size: 12px; }
.text-lg { font-size: 16px; }
.text-xl { font-size: 18px; }
.font-semibold { font-weight: 600; }
.font-bold { font-weight: 700; }
.mt-2 { margin-top: 8px; } .mt-4 { margin-top: 16px; } .mt-6 { margin-top: 24px; }
.mb-2 { margin-bottom: 8px; } .mb-4 { margin-bottom: 16px; } .mb-6 { margin-bottom: 24px; }
.w-full { width: 100%; }
.hidden { display: none !important; }
.divider { height: 1px; background: var(--border); margin: 16px 0; }

/* Two/three column page layout */
.split-2 { display: grid; grid-template-columns: 2fr 1fr; gap: 20px; }
.split-3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 20px; }
@media (max-width: 1100px) { .split-2, .split-3 { grid-template-columns: 1fr; } }

/* ---------- Pagination ---------- */
.pagination {
  display: flex; align-items: center; gap: 4px;
  padding: 14px 20px;
  border-top: 1px solid var(--border);
  background: var(--surface-2);
}
.pagination .info { color: var(--text-3); font-size: 12px; }
.pagination .pages { margin-left: auto; display: flex; gap: 4px; }
.page-btn {
  min-width: 32px; height: 32px;
  border-radius: var(--radius-sm);
  display: grid; place-items: center;
  font-size: 12px; font-weight: 600;
  color: var(--text-2);
  border: 1px solid var(--border);
  background: var(--surface);
  padding: 0 8px;
}
.page-btn:hover { background: var(--muted); }
.page-btn.active { background: var(--brand); color: #fff; border-color: var(--brand); }
.page-btn:disabled { opacity: .4; cursor: not-allowed; }

/* ---------- Empty state ---------- */
.empty {
  text-align: center;
  padding: 60px 20px;
  color: var(--text-3);
}
.empty-icon {
  width: 64px; height: 64px;
  margin: 0 auto 16px;
  border-radius: 50%;
  background: var(--muted);
  display: grid; place-items: center;
  color: var(--text-3);
}
.empty-title { color: var(--text); font-weight: 600; margin: 0 0 6px; font-size: 15px; }

/* ---------- Auth pages ---------- */
.auth-shell {
  min-height: 100vh;
  display: grid;
  grid-template-columns: 1fr 1fr;
}
.auth-aside {
  background: linear-gradient(135deg, var(--brand) 0%, var(--brand-700) 100%);
  color: #fff;
  padding: 60px;
  display: flex; flex-direction: column; justify-content: space-between;
  position: relative;
  overflow: hidden;
}
.auth-aside::before {
  content: ''; position: absolute; inset: 0;
  background: radial-gradient(circle at 80% 20%, rgba(255,255,255,.1), transparent 50%);
}
.auth-form-wrap {
  display: grid; place-items: center;
  padding: 40px;
  background: var(--surface);
}
.auth-form { width: 100%; max-width: 400px; }
@media (max-width: 900px) { .auth-shell { grid-template-columns: 1fr; } .auth-aside { display: none; } }

/* ---------- Login footer / Activity feed ---------- */
.activity {
  display: flex; gap: 12px;
  padding: 12px 0;
  border-bottom: 1px dashed var(--border);
}
.activity:last-child { border: 0; }
.activity-icon {
  width: 32px; height: 32px;
  flex-shrink: 0;
  border-radius: 50%;
  display: grid; place-items: center;
  background: var(--muted);
  color: var(--text-3);
}
.activity-text { flex: 1; }
.activity-text strong { color: var(--text); font-weight: 600; }
.activity-time { font-size: 11px; color: var(--text-3); margin-top: 2px; }

/* ---------- Stat list ---------- */
.stat-list { list-style: none; padding: 0; margin: 0; }
.stat-list li {
  display: flex; align-items: center; justify-content: space-between;
  padding: 10px 0;
  border-bottom: 1px solid var(--border);
  font-size: 13px;
}
.stat-list li:last-child { border: 0; }
.stat-bar {
  width: 100%; height: 6px;
  background: var(--muted);
  border-radius: var(--radius-pill);
  overflow: hidden;
  margin-top: 6px;
}
.stat-bar-fill {
  height: 100%; background: var(--brand);
  border-radius: var(--radius-pill);
  transition: width 600ms ease;
}

/* ---------- SPA content swap ---------- */
.content {
  transition: opacity 160ms ease;
  animation: contentIn 280ms ease both;
}
@keyframes contentIn {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}
body[data-spa-loading="1"] { cursor: progress; }
body[data-spa-loading="1"] .content { pointer-events: none; }

/* ---------- Responsive: tablet landscape (≤1280px) ---------- */
@media (max-width: 1280px) {
  :root { --sidebar-w: 248px; }
}

/* ---------- Responsive: small laptop / large tablet (≤1100px) ----------
   Between the off-canvas breakpoint (≤900) and full desktop, auto-collapse
   the sidebar so there's actual room for the page content. The user can
   click the hamburger to expand it back. */
@media (max-width: 1100px) and (min-width: 901px) {
  .app:not(.collapsed) { grid-template-columns: var(--sidebar-collapsed-w) 1fr; }
  .app:not(.collapsed) .sidebar .brand-text,
  .app:not(.collapsed) .nav-section-title,
  .app:not(.collapsed) .nav-item span:not(.icon),
  .app:not(.collapsed) .nav-item .badge,
  .app:not(.collapsed) .nav-item .chevron,
  .app:not(.collapsed) .theme-pill span { display: none; }
  .app:not(.collapsed) .nav-item { justify-content: center; padding: 11px 0; }
  .app:not(.collapsed) .nav-item.active::before { left: 0; height: 60%; }
  .app:not(.collapsed) .sidebar .brand { padding: 0; justify-content: center; }
  .app:not(.collapsed) .nav-children { display: none !important; }
  .app:not(.collapsed) .sidebar .nav-item[data-label]:hover::after {
    opacity: 1;
    transform: translateY(-50%) translateX(0);
  }
  .app:not(.collapsed) .sidebar .nav-item[data-label]::after {
    content: attr(data-label);
    position: absolute;
    left: calc(100% + 12px);
    top: 50%;
    transform: translateY(-50%) translateX(-4px);
    background: var(--text);
    color: var(--surface);
    font-size: 12px;
    font-weight: 500;
    padding: 6px 10px;
    border-radius: var(--radius-sm);
    white-space: nowrap;
    pointer-events: none;
    opacity: 0;
    z-index: 70;
    box-shadow: var(--shadow);
    transition: opacity var(--t-fast), transform var(--t-fast);
  }
  .kpi-grid { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)) !important; }
  .kpi-value { font-size: 24px; }
  .content { padding: 20px; }
  .table thead th, .table tbody td { padding: 11px 13px; font-size: 12px; }
}

/* ---------- Reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; animation: none !important; }
}

/* ---------- Notifications dropdown ---------- */
.notif-dropdown { position: relative; }
.notif-menu {
  width: min(380px, calc(100vw - 24px));
  padding: 0;
  right: 0;
  left: auto;
}
.notif-head {
  padding: 14px 16px;
  border-bottom: 1px solid var(--border);
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
  background: var(--surface-2);
  border-radius: var(--radius) var(--radius) 0 0;
}
.notif-body {
  max-height: 60vh;
  overflow-y: auto;
  padding: 6px;
  scrollbar-width: thin;
  scrollbar-color: var(--border-strong) transparent;
}
.notif-body::-webkit-scrollbar { width: 6px; }
.notif-body::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 3px; }
.notif-body .dropdown-item {
  border-radius: var(--radius);
  margin-bottom: 2px;
  align-items: flex-start;
  cursor: pointer;
}
.notif-body .dropdown-item:hover { background: var(--brand-soft); }
.notif-foot {
  padding: 10px 16px;
  border-top: 1px solid var(--border);
  text-align: center;
  background: var(--surface-2);
  border-radius: 0 0 var(--radius) var(--radius);
}

/* Generic dropdown menus: prevent right-edge overflow on smaller viewports */
.dropdown { position: relative; }
.dropdown-menu {
  max-width: calc(100vw - 24px);
}

/* ---------- Print ---------- */
@media print {
  .sidebar, .header, .actions, .btn { display: none !important; }
  .content { padding: 0; }
}

/* =================================================================
 * RESPONSIVE — single source of truth. Everything below this line
 * is what controls layout for screens narrower than the desktop.
 * Approach: at <=900px we ABANDON the grid and stack everything as
 * blocks, sidebar becomes a fixed off-canvas drawer. Simple & robust.
 * ================================================================= */

/* Global guards — nothing horizontally escapes the viewport */
html, body { max-width: 100%; overflow-x: hidden; }
* { box-sizing: border-box; }
.app, .main, .content, .header, .card, .kpi, .table-wrap { min-width: 0; }
.card, .kpi, .table-wrap { max-width: 100%; }
.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
img, svg, video, canvas { max-width: 100%; height: auto; }

/* Mobile-only search-icon trigger button — hidden on desktop */
.search-trigger { display: none; }

/* ---------- Tablet portrait + mobile (≤900px) ---------- */
@media (max-width: 900px) {
  /* Drop the grid entirely. Stack as plain blocks.
     The sidebar is taken out of flow (position:fixed) below.
     On mobile we let the page scroll naturally — restore body-level scroll. */
  .app,
  .app.collapsed {
    display: block !important;
    grid-template-columns: none !important;
    width: 100%;
    height: auto !important;
    min-height: 100vh;
    overflow: visible !important;
  }
  .main {
    display: flex;
    flex-direction: column;
    width: 100%;
    min-width: 0;
    max-width: 100%;
    height: auto !important;
    overflow: visible !important;
  }
  .content { overflow: visible !important; }
  .header {
    position: sticky; top: 0;
    /* Translucent header on mobile — looks more app-like */
    background: color-mix(in srgb, var(--surface) 85%, transparent);
    backdrop-filter: blur(12px) saturate(1.4);
    -webkit-backdrop-filter: blur(12px) saturate(1.4);
  }

  /* Sidebar = fixed off-canvas drawer */
  .sidebar,
  .app.collapsed .sidebar {
    position: fixed;
    top: 0; left: 0;
    width: 288px;
    max-width: 86vw;
    height: 100vh;
    height: 100dvh;
    overflow-y: auto;
    overscroll-behavior: contain;
    transform: translateX(-100%);
    z-index: 60;
    transition: transform .28s cubic-bezier(.4, 0, .2, 1);
    box-shadow: 12px 0 40px rgba(0, 0, 0, .25);
  }
  .app.mobile-open .sidebar { transform: translateX(0); }
  .app.mobile-open::after {
    content: ''; position: fixed; inset: 0;
    background: rgba(15, 18, 32, .55);
    z-index: 55;
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
    animation: fadeIn .25s ease;
  }
  /* Animate the hamburger into a tidy "X" when the drawer is open */
  .app.mobile-open .nav-toggle svg line:nth-child(1) {
    transform: translateY(6px) rotate(45deg);
    transform-origin: center;
  }
  .app.mobile-open .nav-toggle svg line:nth-child(2) { opacity: 0; }
  .app.mobile-open .nav-toggle svg line:nth-child(3) {
    transform: translateY(-6px) rotate(-45deg);
    transform-origin: center;
  }
  .nav-toggle svg line { transition: transform var(--t), opacity var(--t-fast); }

  /* Force labels back on inside the drawer if "collapsed" was carried over */
  .app.collapsed .sidebar .brand-text { display: inline-block !important; }
  .app.collapsed .nav-section-title {
    display: block !important; height: auto !important;
    padding: 0 10px 8px !important; margin: 0 !important;
    background: none !important; color: var(--text-3) !important;
  }
  .app.collapsed .nav-item span,
  .app.collapsed .nav-item .badge,
  .app.collapsed .nav-item .chevron { display: inline-flex !important; }
  .app.collapsed .nav-item {
    justify-content: flex-start !important;
    padding: 9px 12px !important;
  }
  .app.collapsed .nav-item.active::before { left: -12px; height: 18px; width: 3px; }
  .app.collapsed .nav-children { display: block !important; }
  .app.collapsed .sidebar .nav-item::after { content: none !important; }
  .app.collapsed .theme-pill span { display: inline-block !important; }
  .app.collapsed .sidebar .brand { padding: 0 18px; justify-content: flex-start; }

  /* Header layout — tighter spacing, only essential controls visible.
     The `.search` becomes position:fixed (slide-down overlay) so it falls
     out of the flex flow, which means `margin-right:auto` on .search no
     longer pushes the right-side cluster right. We pin the cluster to the
     right by giving the search-trigger button (the first item after the
     hamburger) margin-left:auto.

     IMPORTANT: the `:not(.search-trigger)` is required because the more
     specific `.header > .search ~ .icon-btn` selector would otherwise
     overwrite our `margin-left: auto` with `margin-left: 2px`, leaving
     the whole cluster glued to the left edge next to the hamburger. */
  :root { --header-h: 60px; }
  .header { padding: 0 10px; gap: 4px; }
  .header .icon-btn { width: 40px; height: 40px; flex-shrink: 0; }
  .header > .search ~ .icon-btn:not(.search-trigger),
  .header > .search ~ .dropdown { margin-left: 2px; }
  .header > .search ~ .search-trigger { margin-left: auto; }
  .user-chip { padding: 3px 4px 3px 3px; gap: 0; }
  .user-chip .hide-mobile { display: none !important; }
  /* Theme toggle stays in the header — it's the primary control. The
     sidebar copy is the fallback when the drawer is open. */

  /* Search becomes a slide-down overlay opened by the search-icon button.
     Uses position:fixed (relative to viewport) so it always anchors below
     the header, regardless of sticky/scroll quirks. */
  .search-trigger { display: grid; place-items: center; }
  .header > .search {
    position: fixed;
    top: var(--header-h);
    left: 0;
    right: 0;
    width: 100%;
    max-width: none;
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    padding: 10px 12px;
    z-index: 50;
    transform: translateY(-110%);
    opacity: 0;
    pointer-events: none;
    transition: transform .2s ease, opacity .2s ease;
  }
  .header > .search.search-open {
    transform: translateY(0);
    opacity: 1;
    pointer-events: auto;
  }
  .header > .search input { height: 40px; }
  .header > .search .search-icon { left: 22px; }

  /* Content + page-head */
  .content { padding: 16px 14px; width: 100%; }
  .page-head { flex-direction: column; align-items: stretch; gap: 10px; }
  .page-head > .flex { flex-wrap: wrap; }
  .page-head .btn { flex: 1 1 auto; min-width: 0; }
  .page-title { font-size: 20px; }
  .page-sub   { font-size: 12px; }
  .breadcrumb { display: none; }

  /* KPI cards */
  .kpi-grid {
    display: grid !important;
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
    gap: 10px;
  }
  .kpi { padding: 14px; }
  .kpi-value { font-size: 18px; }
  .kpi-label, .kpi-trend { font-size: 11px; }
  .kpi-icon { width: 30px; height: 30px; top: 12px; right: 12px; }

  /* Cards / forms / split layouts */
  .card-header { padding: 12px 14px; flex-wrap: wrap; gap: 8px; }
  .card-header .card-title { font-size: 14px; }
  .card-body, .card-footer { padding: 14px; }
  .form-grid { grid-template-columns: 1fr !important; }
  .split-2, .split-3 { grid-template-columns: 1fr !important; gap: 16px; }

  /* Tables scroll horizontally */
  .table { min-width: 640px; }
  .table thead th, .table tbody td { padding: 8px 10px; font-size: 12px; white-space: nowrap; }

  /* Modal full-screen */
  .modal { width: 100%; max-width: 100%; max-height: 100vh; border-radius: 0; }

  /* Pagination wraps */
  .pagination { flex-wrap: wrap; gap: 8px; }
  .pagination .pages { margin-left: 0; }

  /* Notifications + dropdowns */
  .notif-menu { width: calc(100vw - 16px); right: 0; }
  .notif-body { max-height: 55vh; }
  .dropdown-menu { max-width: calc(100vw - 16px); }
}

/* ---------- Phone (≤520px) ---------- */
@media (max-width: 520px) {
  .header { padding: 0 8px; gap: 2px; }
  .header .icon-btn { width: 36px; height: 36px; }
  .brand-text { display: none; }
  .content { padding: 14px 12px; }
  .btn { padding: 0 12px; height: 36px; font-size: 12px; }
  .kpi { padding: 14px; }
  .user-chip { padding: 2px; }
  .user-chip:hover { background: transparent; }
  /* Notification dot reposition for smaller icon button */
  .icon-btn .dot { top: 6px; right: 7px; }
}

/* ---------- Tiny phone (≤380px) ---------- */
@media (max-width: 380px) {
  .kpi-grid { grid-template-columns: 1fr !important; }
  .kpi-value { font-size: 17px; }
  .header { padding: 0 4px; gap: 0; }
  .header .icon-btn { width: 34px; height: 34px; }
  .avatar { width: 30px; height: 30px; font-size: 13px; }
  .notif-menu { width: calc(100vw - 8px); }
}

/* ---------- Short viewport height (landscape phones) ---------- */
@media (max-height: 600px) {
  .notif-body { max-height: 50vh; }
}
