/* ============================================================
   Reusable component styles. Reference tokens only.
   ============================================================ */

*, *::before, *::after { box-sizing: border-box; }
/* The hidden attribute always wins - component classes that set display
   (flex buttons, pills, menu items...) would otherwise quietly un-hide it. */
[hidden] { display: none !important; }

html, body {
  height: 100%;
}

body {
  margin: 0;
  font-family: var(--font-sans);
  background: var(--bg);
  color: var(--text-primary);
  -webkit-font-smoothing: antialiased;
  transition: background var(--dur-base) var(--ease), color var(--dur-base) var(--ease);
}

a { color: inherit; text-decoration: none; }

.text-muted { color: var(--text-muted); }
.text-secondary { color: var(--text-secondary); }

/* ---------------------------------------------------------- Buttons */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 10px 18px;
  border-radius: var(--radius-md);
  border: 1px solid transparent;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition: transform var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
  white-space: nowrap;
}
.btn:active { transform: translateY(1px); }
.btn-primary {
  background: linear-gradient(135deg, var(--primary), var(--primary-dark));
  color: var(--text-on-primary);
  box-shadow: 0 6px 16px rgba(109, 91, 240, 0.35);
}
.btn-primary:hover { box-shadow: 0 10px 24px rgba(109, 91, 240, 0.45); transform: translateY(-1px); }
.btn-secondary {
  background: var(--surface-glass);
  color: var(--text-primary);
  border-color: var(--border);
  backdrop-filter: blur(var(--blur));
}
.btn-secondary:hover { background: var(--surface-glass-strong); }
.btn-danger { background: var(--danger); color: #fff; }
.btn-whatsapp { background: #25D366; color: #fff; box-shadow: 0 6px 16px rgba(37, 211, 102, 0.3); }
.btn-whatsapp:hover { background: #1fbd5a; color: #fff; }
.wa-invoice-preview { display: block; width: 100%; max-height: 360px; object-fit: contain; object-position: top; border-radius: var(--radius-md); border: 1px solid var(--border); background: #fff; }
.form-control.is-invalid { border-color: var(--danger); }
.public-link-head { display: flex; gap: 12px; align-items: flex-start; margin-bottom: 12px; }
.public-link-head > i { width: 36px; height: 36px; border-radius: var(--radius-sm); flex-shrink: 0; display: flex; align-items: center; justify-content: center; background: rgba(124, 107, 245, 0.14); color: var(--primary-light); }
.public-link-row { display: flex; gap: 8px; }
.public-link-row .form-control { flex: 1 1 auto; min-width: 0; font-size: 13px; color: var(--text-secondary); }
.public-link-row .btn { flex: 0 0 auto; }
.btn-danger:hover { filter: brightness(1.08); }
.btn-ghost { background: transparent; color: var(--text-secondary); }
.btn-ghost:hover { background: var(--surface-glass); color: var(--text-primary); }
.btn-sm { padding: 6px 12px; font-size: 13px; }
.btn-icon { padding: 10px; width: 38px; height: 38px; justify-content: center; }
.btn:disabled { opacity: .55; cursor: not-allowed; transform: none !important; }

/* ----------------------------------------------------------- Forms */
label, .form-label {
  display: block;
  font-size: 13px;
  font-weight: 600;
  color: var(--text-secondary);
  margin-bottom: 6px;
}
.form-control, select.form-control, textarea.form-control {
  width: 100%;
  padding: 11px 14px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: var(--surface-2);
  color: var(--text-primary);
  font-size: 14px;
  font-family: inherit;
  transition: border-color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}
.form-control:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 3px rgba(109, 91, 240, 0.2);
}
.form-control::placeholder { color: var(--text-muted); }
.form-group { margin-bottom: 18px; }
.form-row { display: grid; gap: 16px; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
.form-hint { font-size: 12px; color: var(--text-muted); margin-top: 6px; }
.field-error { font-size: 12px; color: var(--danger); margin-top: 6px; }
.form-check { display: flex; align-items: center; gap: 8px; }
.form-check input { accent-color: var(--primary); width: 16px; height: 16px; }

/* ------------------------------------------------------------ Cards */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-1);
  transition: box-shadow var(--dur-base) var(--ease), transform var(--dur-base) var(--ease);
}
.card-glass {
  background: var(--surface-glass);
  backdrop-filter: blur(var(--blur));
  -webkit-backdrop-filter: blur(var(--blur));
  border: 1px solid var(--border);
}
.card-hover:hover { box-shadow: var(--shadow-2); transform: translateY(-2px); }
.card-body { padding: 24px; }
.card-header {
  padding: 18px 24px;
  border-bottom: 1px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.card-title { font-size: 16px; font-weight: 700; margin: 0; }
/* Keeps a card's primary action (e.g. "Add Item" on a long line-items
   grid) in view while scrolling through that card's content, instead of
   making the user scroll back up to find it. Needs its own background
   since sticking detaches it from the card's normal paint order. */
.card-header-sticky { position: sticky; top: var(--header-height); z-index: 20; background: var(--surface); }
/* A search/filter bar at the top of a long scrolling list (POS cart,
   IMEI search, ...) stays reachable instead of scrolling away with the
   list underneath it. */
.sticky-toolbar { position: sticky; top: var(--header-height); z-index: 15; background: var(--surface); padding-bottom: 10px; margin-bottom: -2px; }
/* .input-with-scan also sets position (to relative, for its own absolutely-
   positioned scan icon) - same specificity as .sticky-toolbar, so whichever
   is declared later in the file would otherwise win regardless of which
   actually belongs here. The compound selector outranks both. */
.input-with-scan.sticky-toolbar { position: sticky; }

/* --------------------------------------------------------- KPI cards */
.kpi-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: 16px;
}
.kpi-card {
  position: relative;
  overflow: hidden;
  padding: 20px;
  border-radius: var(--radius-lg);
  background: var(--surface-glass);
  backdrop-filter: blur(var(--blur));
  border: 1px solid var(--border);
  box-shadow: var(--shadow-1);
  transition: transform var(--dur-base) var(--ease), box-shadow var(--dur-base) var(--ease);
}
.kpi-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-2); }
.kpi-icon {
  width: 42px; height: 42px;
  border-radius: var(--radius-sm);
  display: flex; align-items: center; justify-content: center;
  margin-bottom: 14px;
  font-size: 16px;
}
.kpi-icon.accent-primary { background: rgba(124, 107, 245, 0.16); color: var(--primary-light); }
.kpi-icon.accent-success { background: var(--success-bg); color: var(--success); }
.kpi-icon.accent-warning { background: var(--warning-bg); color: var(--warning); }
.kpi-icon.accent-danger { background: var(--danger-bg); color: var(--danger); }
.kpi-value { font-size: 26px; font-weight: 800; letter-spacing: -0.02em; }
.kpi-label { font-size: 13px; color: var(--text-secondary); margin-top: 4px; }

/* ---------------------------------------------------------- Sidebar */
.app-shell { display: flex; min-height: 100vh; }
.sidebar {
  width: var(--sidebar-width);
  flex-shrink: 0;
  background: var(--surface-glass);
  backdrop-filter: blur(var(--blur));
  border-inline-end: 1px solid var(--border);
  padding: 20px 14px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  transition: width var(--dur-base) var(--ease);
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
  z-index: 40;
  /* Scrollbar follows the active theme instead of the browser/OS default
     gray bar, which looked out of place against every theme's own
     palette. Firefox uses scrollbar-color; Chrome/Edge/Safari use the
     ::-webkit-scrollbar rules below. */
  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: var(--radius-full); }
.sidebar::-webkit-scrollbar-thumb:hover { background: var(--text-muted); }
.sidebar.collapsed { width: var(--sidebar-width-collapsed); }

/* Theme-matched hover tooltip for the sidebar's [data-tooltip] elements.
   One fixed-position element on <body>, placed by sidebar.js - a CSS
   ::after inside the sidebar would get clipped by its overflow-y:auto. */
.ui-tooltip {
  position: fixed; z-index: 1000; pointer-events: none;
  background: var(--bg-elevated); color: var(--text-primary);
  border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
  padding: 7px 11px; font-size: 12.5px; font-weight: 600; white-space: nowrap;
  box-shadow: var(--shadow-2);
  opacity: 0; transform: translateY(-50%) translateX(-4px);
  transition: opacity var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
}
.ui-tooltip.show { opacity: 1; transform: translateY(-50%) translateX(0); }
.ui-tooltip.below { transform: translateX(-50%) translateY(-4px); }
.ui-tooltip.below.show { transform: translateX(-50%) translateY(0); }
.ui-tooltip.below::before {
  top: -5px; inset-inline-start: 50%;
  transform: translateX(-50%) rotate(45deg);
  border-inline-start: 1px solid var(--border-strong);
  border-block-start: 1px solid var(--border-strong);
  border-block-end: none;
}
.ui-tooltip::before {
  content: "";
  position: absolute; top: 50%; inset-inline-start: -5px;
  width: 8px; height: 8px;
  transform: translateY(-50%) rotate(45deg);
  background: var(--bg-elevated);
  border-inline-start: 1px solid var(--border-strong);
  border-block-end: 1px solid var(--border-strong);
}
.sidebar-brand {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 10px 18px;
  font-weight: 800; font-size: 17px;
  letter-spacing: -0.01em;
}
.sidebar-brand-mark {
  width: 34px; height: 34px; border-radius: 10px;
  background: linear-gradient(135deg, var(--primary), var(--secondary));
  display: flex; align-items: center; justify-content: center;
  color: #fff; font-weight: 800; flex-shrink: 0;
}
.sidebar.collapsed .sidebar-brand-label,
.sidebar.collapsed .nav-label,
.sidebar.collapsed .nav-section-title { display: none; }
.sidebar.collapsed .nav-section-items { grid-template-rows: 1fr !important; }

.nav-section { border-radius: var(--radius-sm); }
.nav-section + .nav-section { margin-top: 2px; }
.nav-section-title {
  all: unset;
  box-sizing: border-box;
  width: 100%;
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  cursor: pointer;
  font-size: 11px; text-transform: uppercase; letter-spacing: .1em;
  color: var(--text-muted); margin: 16px 4px 6px; padding: 7px 10px;
  font-weight: 800;
  border-radius: var(--radius-sm);
  transition: color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.nav-section-title:hover { color: var(--text-secondary); background: var(--surface-glass); }
.nav-section.open .nav-section-title { color: var(--primary-light); }
.nav-section-title:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.nav-section-chevron {
  font-size: 9px; flex-shrink: 0;
  color: var(--text-muted);
  transition: transform var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.nav-section.open .nav-section-chevron { color: var(--primary-light); transform: rotate(180deg); }
.nav-section-items {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--dur-base) var(--ease);
}
.nav-section.open .nav-section-items { grid-template-rows: 1fr; }
.nav-section-items-inner { overflow: hidden; min-height: 0; display: flex; flex-direction: column; gap: 2px; }
.nav-item {
  position: relative;
  display: flex; align-items: center; gap: 12px;
  padding: 10px 12px;
  border-radius: var(--radius-sm);
  color: var(--text-secondary);
  font-size: 14px; font-weight: 500;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.nav-item i { width: 18px; text-align: center; flex-shrink: 0; }
.nav-item:hover { background: var(--surface-glass-strong); color: var(--text-primary); }
.nav-item.active { background: rgba(124, 107, 245, 0.14); color: var(--primary-light); }
.nav-item.active::before {
  content: "";
  position: absolute; inset-inline-start: -14px; top: 8px; bottom: 8px; width: 3px;
  background: var(--primary); border-radius: var(--radius-full);
}
.nav-item .badge-soon {
  margin-inline-start: auto; font-size: 10px; padding: 2px 6px;
  border-radius: var(--radius-full); background: var(--surface-2); color: var(--text-muted);
}

/* ------------------------------------------------------------ Header */
.topbar {
  height: var(--header-height);
  display: flex; align-items: center; gap: 14px;
  padding: 0 24px;
  background: var(--surface-glass);
  backdrop-filter: blur(var(--blur));
  border-bottom: 1px solid var(--border);
  position: sticky; top: 0; z-index: 30;
}
.topbar-search {
  flex: 1; max-width: 420px;
  display: flex; align-items: center; gap: 10px;
  padding: 9px 14px;
  border-radius: var(--radius-md);
  background: var(--surface-2);
  border: 1px solid var(--border);
  color: var(--text-muted);
  cursor: pointer;
}
.topbar-actions { display: flex; align-items: center; gap: 8px; margin-inline-start: auto; }
.icon-btn {
  width: 38px; height: 38px; border-radius: var(--radius-sm);
  display: flex; align-items: center; justify-content: center;
  color: var(--text-secondary);
  border: 1px solid transparent;
  cursor: pointer;
  position: relative;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.icon-btn:hover { background: var(--surface-glass-strong); color: var(--text-primary); }
/* Header buttons share the primary (New Customer) look, so they follow
   whichever theme is active. */
.topbar .icon-btn {
  background: linear-gradient(135deg, var(--primary), var(--primary-dark));
  color: var(--text-on-primary);
  box-shadow: 0 4px 12px rgba(109, 91, 240, 0.3);
  transition: box-shadow var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
}
.topbar .icon-btn:hover {
  background: linear-gradient(135deg, var(--primary), var(--primary-dark));
  color: var(--text-on-primary);
  box-shadow: 0 8px 20px rgba(109, 91, 240, 0.42);
  transform: translateY(-1px);
}
.topbar .icon-btn .dot { border-color: var(--primary); }
.icon-btn .dot {
  position: absolute; top: 6px; inset-inline-end: 6px;
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--danger); border: 2px solid var(--bg);
}
.avatar {
  width: 36px; height: 36px; border-radius: var(--radius-full);
  background: linear-gradient(135deg, var(--primary), var(--secondary));
  color: #fff; display: flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: 13px; flex-shrink: 0;
}
.user-menu-trigger { display: flex; align-items: center; gap: 10px; cursor: pointer; padding: 4px; padding-inline-end: 6px; border-radius: var(--radius-full); }
.user-menu-trigger:hover { background: var(--surface-glass-strong); }
.user-menu-name { font-size: 13px; font-weight: 600; line-height: 1.1; }
.user-menu-role { font-size: 11px; color: var(--text-muted); }

/* ------------------------------------------------------------- Main */
.main-content { flex: 1; min-width: 0; }
.page-container { padding: 28px 32px; max-width: var(--content-max); margin: 0 auto; }
.page-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; margin-bottom: 24px; flex-wrap: wrap; }
.page-title { font-size: 22px; font-weight: 800; letter-spacing: -0.01em; margin: 0 0 4px; }
.page-subtitle { color: var(--text-secondary); font-size: 14px; margin: 0; }
.breadcrumb { display: flex; gap: 6px; align-items: center; font-size: 13px; color: var(--text-muted); margin-bottom: 8px; }
.breadcrumb a:hover { color: var(--text-primary); }

/* ------------------------------------------------------------ Tables */
.table-wrap { overflow-x: auto; border-radius: var(--radius-lg); border: 1px solid var(--border); background: var(--surface); }
table.data-table { width: 100%; border-collapse: collapse; font-size: 14px; min-width: 640px; }
.data-table thead th {
  position: sticky; top: 0;
  text-align: start; padding: 14px 18px;
  background: var(--surface-2);
  color: var(--text-secondary);
  font-size: 12px; text-transform: uppercase; letter-spacing: .04em; font-weight: 700;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
.data-table tbody td { padding: 14px 18px; border-bottom: 1px solid var(--border); vertical-align: middle; }
.data-table tbody tr:last-child td { border-bottom: none; }
.data-table tbody tr { transition: background var(--dur-fast) var(--ease); }
/* Zebra striping - a long list of similar rows (or cards) is much faster
   to scan/read when every other one has a faint tint, instead of one flat
   wall of identical rows. */
.data-table tbody tr:nth-child(even) { background: var(--surface-2); }
.data-table tbody tr:hover { background: var(--surface-glass); }
.item-cards > .item-card:nth-child(even) { background: var(--surface-2); }
.table-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 16px 18px; flex-wrap: wrap; }
/* flex: 1 - sized from its inputs' starting width, the form ran out of room
   once they grew and pushed the Filter button onto a line of its own. */
.table-filters { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; flex: 1 1 auto; min-width: 0; }
/* Filters used to rely on each page's own hand-picked pixel width
   (240px/160px/200px/...), which read as arbitrary and misaligned side by
   side. flex-basis here overrides that per-page width (it wins over an
   inline width once flex-basis is no longer auto) so every filter gets a
   consistent, evenly-proportioned size that still wraps cleanly. */
.table-filters .form-control, .table-filters .ss { flex: 1 1 180px; max-width: 260px; }
.table-filters .btn { flex: 0 0 auto; }

/* -------------------------------------------------------- Pagination */
.pagination { display: flex; gap: 6px; align-items: center; padding: 16px 18px; justify-content: flex-end; }
.page-link {
  min-width: 34px; height: 34px; padding: 0 8px;
  display: flex; align-items: center; justify-content: center;
  border-radius: var(--radius-sm); font-size: 13px; font-weight: 600;
  color: var(--text-secondary); border: 1px solid var(--border);
}
.page-link:hover { background: var(--surface-glass-strong); }
.page-link.active { background: var(--primary); color: #fff; border-color: transparent; }
.page-link.disabled { opacity: .4; pointer-events: none; }

/* --------------------------------------------------- Badges / pills */
.pill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 11px; border-radius: var(--radius-full);
  font-size: 12px; font-weight: 700;
}
.pill-success { background: var(--success-bg); color: var(--success); }
.pill-warning { background: var(--warning-bg); color: var(--warning); }
.pill-danger { background: var(--danger-bg); color: var(--danger); }
.pill-neutral { background: var(--surface-2); color: var(--text-secondary); }
.pill-primary { background: rgba(124, 107, 245, .16); color: var(--primary-light); }

/* --------------------------------------------------------- Skeleton */
.skeleton {
  background: linear-gradient(90deg, var(--surface-2) 25%, var(--surface-glass-strong) 37%, var(--surface-2) 63%);
  background-size: 400% 100%;
  animation: skeleton-pulse 1.4s ease infinite;
  border-radius: var(--radius-sm);
}
@keyframes skeleton-pulse { 0% { background-position: 100% 50%; } 100% { background-position: 0 50%; } }

/* ------------------------------------------------------- Empty state */
.empty-state { text-align: center; padding: 64px 24px; color: var(--text-secondary); }
.empty-state-icon {
  width: 64px; height: 64px; border-radius: var(--radius-lg);
  background: var(--surface-glass); display: flex; align-items: center; justify-content: center;
  font-size: 26px; color: var(--primary-light); margin: 0 auto 18px;
}
.empty-state-title { font-size: 16px; font-weight: 700; color: var(--text-primary); margin-bottom: 6px; }

/* ---------------------------------------------------------- Item cards */
/* The mobile alternative to an 11-column table row (see purchase-items.js) -
   hidden on desktop, shown in its place under @media (max-width: 960px). */
.item-cards { display: none; flex-direction: column; gap: 10px; padding: 14px 16px; }
/* Already sits inside a padded .card-body here, unlike its other uses
   (directly inside a plain .card/.table-wrap) - its own side padding on
   top of that just wasted width on a screen that's tight to begin with. */
#pos-cart-cards { padding-inline: 0; }
.item-card {
  display: block; text-decoration: none; color: inherit;
  border: 1px solid var(--border); border-radius: var(--radius-md);
  background: var(--surface); padding: 12px 14px;
  transition: background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
a.item-card:active { background: var(--surface-glass-strong); }
.item-card-top { display: flex; align-items: flex-start; gap: 10px; }
.item-card-icon {
  width: 36px; height: 36px; border-radius: var(--radius-sm); flex-shrink: 0;
  background: rgba(124, 107, 245, 0.14); color: var(--primary-light);
  display: flex; align-items: center; justify-content: center; font-size: 15px;
}
.item-card-info { flex: 1; min-width: 0; }
.item-card-title { font-weight: 700; font-size: 14.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.item-card-meta { font-size: 12px; color: var(--text-muted); margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.item-card-actions { display: flex; gap: 4px; flex-shrink: 0; }
.item-card-actions .icon-btn { width: 32px; height: 32px; }
.item-card-bottom {
  display: flex; align-items: center; justify-content: space-between;
  margin-top: 10px; padding-top: 10px; border-top: 1px dashed var(--border);
  font-size: 13.5px;
}

/* Auto-generated mobile cards for any .data-table (tables.js) */
.row-deferred { display: none !important; }
.auto-card { cursor: pointer; }
.auto-card:active { background: var(--surface-glass-strong); }
.auto-card:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.auto-card .item-card-top { align-items: center; }
.auto-card-chevron { color: var(--text-muted); font-size: 12px; flex-shrink: 0; }
.auto-card-badge { flex-shrink: 0; }
.auto-card-badge .pill { font-size: 10.5px; padding: 3px 9px; }
.auto-card-check { width: 18px; height: 18px; accent-color: var(--primary); flex-shrink: 0; margin: 0; }
.auto-card-fields {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px 14px;
  margin-top: 10px; padding-top: 10px; border-top: 1px dashed var(--border);
}
.auto-card-field { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.auto-card-label { font-size: 10.5px; text-transform: uppercase; letter-spacing: .06em; color: var(--text-muted); font-weight: 700; }
.auto-card-value { font-size: 13px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.auto-card-value div { display: inline; margin-inline-start: 4px; }
.auto-card-value .pill { font-size: 11px; padding: 2px 8px; }
.auto-card-note { padding: 12px 14px; border: 1px dashed var(--border); border-radius: var(--radius-md); font-size: 13px; color: var(--text-secondary); }
.auto-cards-selectall { display: flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 600; padding: 2px 4px; cursor: pointer; }
.auto-cards-selectall input { width: 18px; height: 18px; accent-color: var(--primary); margin: 0; }
.auto-cards-summary { display: none; margin: 0 16px 14px; border: 1px solid var(--border); border-radius: var(--radius-md); padding: 2px 14px; background: var(--surface-2); }
.auto-summary-row { display: flex; justify-content: space-between; gap: 12px; padding: 9px 0; font-size: 13.5px; }
.auto-summary-row + .auto-summary-row { border-top: 1px solid var(--border); }
.card-body > .auto-cards, .card-body > .auto-cards-summary { padding-inline: 0; margin-inline: 0; }
.table-scroll-footer { text-align: center; font-size: 12.5px; color: var(--text-muted); padding: 14px; }
.table-scroll-sentinel { height: 1px; }

.detail-list { display: flex; flex-direction: column; }
.detail-row { display: flex; justify-content: space-between; align-items: baseline; gap: 16px; padding: 11px 0; border-bottom: 1px solid var(--border); }
.detail-row:last-child { border-bottom: none; }
.detail-label { font-size: 11.5px; color: var(--text-muted); font-weight: 700; text-transform: uppercase; letter-spacing: .05em; flex-shrink: 0; max-width: 45%; }
.detail-value { text-align: end; font-size: 14px; font-weight: 600; min-width: 0; overflow-wrap: anywhere; }
.row-detail-modal .modal-body { padding-top: 6px; padding-bottom: 6px; }

/* ------------------------------------------------- Offline mode (core.js) */
.offline-banner {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 9px 24px; font-size: 13px; line-height: 1.45;
  border-bottom: 1px solid var(--border); background: var(--surface-2); color: var(--text-primary);
}
.offline-banner > i { flex-shrink: 0; }
.offline-banner > span { flex: 1 1 260px; min-width: 0; }
.offline-banner a, .offline-banner button {
  flex-shrink: 0; font: inherit; font-weight: 700; cursor: pointer;
  padding: 4px 12px; border-radius: var(--radius-full); border: 1px solid currentColor;
  background: transparent; color: inherit; text-decoration: none;
}
.offline-banner.is-offline { background: var(--warning-bg); color: var(--warning); }
.offline-banner.is-offline span { color: var(--text-primary); }
.offline-banner.is-syncing, .offline-banner.is-pending { background: rgba(124, 107, 245, .12); color: var(--primary-light); }
.offline-banner.is-syncing span, .offline-banner.is-pending span { color: var(--text-primary); }
.offline-banner.is-issue { background: var(--danger-bg); color: var(--danger); }
.offline-banner.is-issue span { color: var(--text-primary); }
.is-disabled { opacity: .45; pointer-events: none; }
.install-steps { margin: 0; padding-inline-start: 22px; display: flex; flex-direction: column; gap: 10px; font-size: 14px; line-height: 1.45; }

.offline-receipt { font-size: 13px; }
.offline-receipt .r-head { text-align: center; margin-bottom: 10px; }
.offline-receipt .r-head strong { font-size: 16px; }
.offline-receipt .r-head div { color: var(--text-muted); }
.offline-receipt .r-meta { border-block: 1px dashed var(--border-strong); padding: 8px 0; margin-bottom: 8px; display: flex; flex-direction: column; gap: 2px; }
.offline-receipt table { width: 100%; border-collapse: collapse; }
.offline-receipt th { text-align: start; font-size: 11px; text-transform: uppercase; color: var(--text-muted); padding: 4px 0; }
.offline-receipt td { padding: 5px 0; vertical-align: top; }
.offline-receipt .r-num { text-align: end; white-space: nowrap; padding-inline-start: 10px; }
.offline-receipt .r-sub { font-size: 11.5px; color: var(--text-muted); }
.offline-receipt .r-totals { border-top: 1px dashed var(--border-strong); margin-top: 6px; padding-top: 6px; }
.offline-receipt .r-totals div { display: flex; justify-content: space-between; padding: 2px 0; }
.offline-receipt .r-total { font-weight: 800; font-size: 15px; }
.offline-receipt .r-foot { margin-top: 12px; font-size: 12px; color: var(--text-muted); text-align: center; }

/* --------------------------------------------------------------- Modal */
.modal-backdrop {
  position: fixed; inset: 0; background: rgba(6, 6, 14, 0.55);
  display: flex; align-items: center; justify-content: center; z-index: 100;
  opacity: 0; pointer-events: none; transition: opacity var(--dur-base) var(--ease);
  padding: 20px;
}
.modal-backdrop.open { opacity: 1; pointer-events: auto; }
.modal {
  width: 100%; max-width: 520px;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-3);
  transform: translateY(12px) scale(.98); opacity: 0;
  transition: transform var(--dur-base) var(--ease), opacity var(--dur-base) var(--ease);
  max-height: 88vh; display: flex; flex-direction: column;
}
.modal-backdrop.open .modal { transform: translateY(0) scale(1); opacity: 1; }
.modal-header { padding: 20px 24px; border-bottom: 1px solid var(--border); display: flex; align-items: center; justify-content: space-between; }
.modal-title { font-weight: 700; font-size: 16px; }
.modal-body { padding: 24px; overflow-y: auto; }
.modal-footer { padding: 16px 24px; border-top: 1px solid var(--border); display: flex; justify-content: flex-end; gap: 10px; }

/* --------------------------------------------------------------- Toast */
.toast-stack { position: fixed; top: 20px; inset-inline-end: 20px; z-index: 200; display: flex; flex-direction: column; gap: 10px; width: min(360px, calc(100vw - 40px)); }
.toast {
  padding: 14px 16px; border-radius: var(--radius-md);
  background: var(--bg-elevated); border: 1px solid var(--border);
  box-shadow: var(--shadow-2);
  display: flex; align-items: flex-start; gap: 10px;
  transform: translateX(120%); opacity: 0;
  transition: transform var(--dur-base) var(--ease), opacity var(--dur-base) var(--ease);
}
.toast.show { transform: translateX(0); opacity: 1; }
.toast-icon { font-size: 16px; margin-top: 1px; }
.toast.toast-success .toast-icon { color: var(--success); }
.toast.toast-error .toast-icon { color: var(--danger); }
.toast.toast-info .toast-icon { color: var(--info); }
.toast-message { font-size: 13px; color: var(--text-primary); flex: 1; }
.toast-close { cursor: pointer; color: var(--text-muted); }

/* ----------------------------------------------------------- Dropdown */
.dropdown { position: relative; }
.dropdown-menu {
  position: absolute; inset-inline-end: 0; top: calc(100% + 8px);
  min-width: 220px; background: var(--bg-elevated);
  border: 1px solid var(--border); border-radius: var(--radius-md);
  box-shadow: var(--shadow-2); padding: 8px; z-index: 90;
  opacity: 0; transform: translateY(-6px); pointer-events: none;
  transition: opacity var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
}
.dropdown-menu.open { opacity: 1; transform: translateY(0); pointer-events: auto; }
.dropdown-item {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 10px; border-radius: var(--radius-sm);
  font-size: 13.5px; color: var(--text-secondary); cursor: pointer;
}
.dropdown-item:hover { background: var(--surface-glass-strong); color: var(--text-primary); }
.dropdown-divider { height: 1px; background: var(--border); margin: 6px 4px; }

/* ------------------------------------------------------ Barcode scanner */
.input-with-scan { position: relative; display: flex; }
.input-with-scan input { padding-inline-end: 38px; }
.input-with-scan .scan-btn {
  position: absolute; inset-inline-end: 4px; top: 50%; transform: translateY(-50%);
  width: 30px; height: 30px; border: none; background: transparent;
  /* text-secondary, not text-muted - text-muted reads as a near-invisible
     dark-on-dark smudge against the input's own background on the dark
     themes (the icon all but disappears, not just "subtle"). */
  color: var(--text-secondary); display: flex; align-items: center; justify-content: center;
  cursor: pointer; border-radius: var(--radius-sm); font-size: 14px; padding: 0;
}
.input-with-scan .scan-btn:hover { background: var(--surface-glass-strong); color: var(--primary-light); }

/* A discount value + its Rs/% unit read as one control, not two floating
   boxes bumped up against each other - same "one input, one attached
   control" idea as the scan button above. */
.discount-input-group {
  display: flex; align-items: stretch;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--surface-2); overflow: hidden;
  transition: border-color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}
.discount-input-group:focus-within { border-color: var(--primary); box-shadow: 0 0 0 3px rgba(109, 91, 240, 0.2); }
.discount-input-group input.form-control,
.discount-input-group select.form-control {
  border: none; background: transparent; border-radius: 0; min-height: auto;
}
.discount-input-group input.form-control:focus,
.discount-input-group select.form-control:focus {
  box-shadow: none; border-color: transparent;
}
.discount-input-group input.form-control { flex: 1; min-width: 0; width: 0; }
.discount-input-group select.form-control {
  flex: none; width: auto; max-width: 58px;
  padding-inline: 6px 4px; border-inline-start: 1px solid var(--border);
  color: var(--text-secondary); font-weight: 600; font-size: 12.5px;
}

.scan-overlay {
  display: none; position: fixed; inset: 0; z-index: 200; background: #000;
  flex-direction: column; overflow: hidden;
}
.scan-overlay.open { display: flex; }
.scan-topbar {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 16px; position: relative; z-index: 2;
}
.scan-title { font-weight: 700; font-size: 15px; color: #fff; display: flex; align-items: center; gap: 8px; }
.scan-topbar .icon-btn { color: #fff; }
.scan-topbar .icon-btn:hover { background: rgba(255, 255, 255, 0.15); }
.scan-video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.scan-frame {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: 92%; max-width: 560px; height: 110px;
  border: 3px solid var(--primary-light); border-radius: var(--radius-md);
  box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.45); z-index: 1;
}
.scan-hint {
  position: absolute; bottom: 40px; inset-inline: 0; text-align: center;
  color: #fff; font-size: 13.5px; z-index: 2; margin: 0; padding: 0 20px;
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.6);
}
.scan-hint.is-warning {
  inset-inline: 16px; padding: 10px 14px; border-radius: var(--radius-md);
  background: rgba(217, 119, 6, 0.92); font-weight: 600; text-shadow: none;
}

/* ------------------------------------------------------- Command palette */
.cmdk-backdrop {
  position: fixed; inset: 0; background: rgba(6,6,14,.6); z-index: 150;
  display: flex; align-items: flex-start; justify-content: center; padding-top: 12vh;
  opacity: 0; pointer-events: none; transition: opacity var(--dur-base) var(--ease);
}
.cmdk-backdrop.open { opacity: 1; pointer-events: auto; }
.cmdk {
  width: min(560px, 92vw);
  background: var(--bg-elevated); border: 1px solid var(--border);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-3);
  overflow: hidden;
  transform: translateY(-8px); transition: transform var(--dur-base) var(--ease);
}
.cmdk-backdrop.open .cmdk { transform: translateY(0); }
.cmdk-input { width: 100%; border: none; background: transparent; padding: 18px 20px; font-size: 15px; color: var(--text-primary); border-bottom: 1px solid var(--border); }
.cmdk-input:focus { outline: none; }
.cmdk-results { max-height: 360px; overflow-y: auto; padding: 8px; }
.cmdk-item { display: flex; align-items: center; gap: 12px; padding: 11px 12px; border-radius: var(--radius-sm); cursor: pointer; font-size: 13.5px; }
.cmdk-item:hover, .cmdk-item.active { background: var(--surface-glass-strong); }
.cmdk-empty { padding: 32px; text-align: center; color: var(--text-muted); font-size: 13px; }

/* ------------------------------------------------- Searchable select */
/* Progressive enhancement wrapper around every <select class="form-control">
   (see searchable-select.js) - the real <select> stays in the DOM
   (visually hidden, .ss-native below) so forms/JS that read or set its
   value keep working untouched; this just adds a type-to-filter UI on top. */
.ss { position: relative; display: block; width: 100%; }
.ss-native {
  position: absolute !important; width: 1px !important; height: 1px !important;
  padding: 0 !important; margin: -1px !important; overflow: hidden !important;
  clip: rect(0, 0, 0, 0) !important; white-space: nowrap !important; border: 0 !important;
  opacity: 0; pointer-events: none;
}
.ss-trigger {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  cursor: pointer; text-align: start; width: 100%;
}
.ss-trigger[disabled] { opacity: .6; cursor: not-allowed; }
.ss-trigger-label { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-align: start; }
.ss-trigger-label.ss-placeholder { color: var(--text-muted); }
.ss-trigger-chevron { font-size: 11px; color: var(--text-muted); flex-shrink: 0; transition: transform var(--dur-fast) var(--ease); }
.ss-trigger.ss-open .ss-trigger-chevron { transform: rotate(180deg); }
.ss-panel {
  position: fixed; background: var(--bg-elevated); border: 1px solid var(--border);
  border-radius: var(--radius-md); box-shadow: var(--shadow-2); z-index: 120;
  max-height: 320px; display: flex; flex-direction: column; overflow: hidden;
}
.ss-search { border: none; border-bottom: 1px solid var(--border); background: transparent; padding: 10px 12px; font-size: 13.5px; color: var(--text-primary); width: 100%; }
.ss-search:focus { outline: none; }
.ss-options { overflow-y: auto; padding: 6px; flex: 1 1 auto; min-height: 0; }
.ss-options:focus { outline: none; }
.ss-option { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* -------------------------------------------------------------- Auth */
.auth-page {
  min-height: 100vh; display: flex; align-items: center; justify-content: center;
  background: radial-gradient(circle at 20% 20%, rgba(124,107,245,.25), transparent 45%),
              radial-gradient(circle at 80% 80%, rgba(161,140,246,.2), transparent 45%),
              var(--bg);
  padding: 24px;
  position: relative;
  overflow: hidden;
}
.auth-card {
  width: 100%; max-width: 420px;
  background: var(--surface-glass);
  backdrop-filter: blur(var(--blur));
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-3);
  padding: 40px 36px;
  position: relative; z-index: 1;
}
.auth-brand { display: flex; align-items: center; gap: 12px; margin-bottom: 28px; }
.auth-title { font-size: 20px; font-weight: 800; margin: 0 0 6px; }
.auth-subtitle { color: var(--text-secondary); font-size: 13.5px; margin: 0 0 28px; }
.auth-orb { position: absolute; border-radius: 50%; filter: blur(60px); opacity: .5; }

/* ---------------------------------------------------------- Responsive */

/* ------------------------------------------------------- Bottom nav app */
.bottom-nav {
  display: none;
  position: fixed; inset-inline: 0; bottom: 0; z-index: 60;
  background: var(--surface-glass); backdrop-filter: blur(var(--blur));
  border-top: 1px solid var(--border);
  padding: 6px 4px calc(6px + env(safe-area-inset-bottom, 0px));
  box-shadow: 0 -4px 20px rgba(0, 0, 0, 0.12);
}
.bottom-nav-items { display: flex; align-items: stretch; justify-content: space-around; }
.bottom-nav-item {
  flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 3px; padding: 7px 4px; border-radius: var(--radius-sm);
  color: var(--text-muted); font-size: 10.5px; font-weight: 600;
  min-width: 0; border: none; background: none; cursor: pointer; font-family: inherit;
}
.bottom-nav-item i { font-size: 18px; }
.bottom-nav-item span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; }
.bottom-nav-item.active { color: var(--primary-light); }
.bottom-nav-item:active { background: var(--surface-glass-strong); }

.sidebar-backdrop {
  display: none;
  position: fixed; inset: 0; background: rgba(6, 6, 14, 0.5); z-index: 45;
  opacity: 0; pointer-events: none; transition: opacity var(--dur-base) var(--ease);
}
.sidebar-backdrop.open { opacity: 1; pointer-events: auto; }

@media (max-width: 960px) {
  /* The sidebar's desktop look is a translucent "glass" panel (it always
     sits over the page's own background there). As a mobile drawer it
     sits over a dark dimming backdrop instead, and that same translucency
     lets the dimming bleed through - a solid background keeps it reading
     as a clean, fully opaque panel while open. */
  .sidebar { position: fixed; inset-inline-start: -100%; top: 0; height: 100vh; transition: inset-inline-start var(--dur-base) var(--ease); box-shadow: var(--shadow-3); z-index: 50; background: var(--surface); backdrop-filter: none; }
  .sidebar.mobile-open { inset-inline-start: 0; }
  /* The bottom tab bar stays on top of the drawer (its "More" tab closes
     it), so the drawer's last items need room to scroll clear of it; dvh
     tracks the visible height as mobile browser toolbars show/hide. */
  .sidebar { height: 100dvh; padding-bottom: calc(88px + env(safe-area-inset-bottom, 0px)); }
  .sidebar-backdrop { display: block; }
  #purchase-items-table-wrap { display: none; }
  #pos-cart-table-wrap { display: none; }
  table.has-auto-cards, #hub-stock-table, #hub-customer-table { display: none; }
  .offline-banner { padding: 9px 16px; }
  .item-cards { display: flex; }
  .auto-cards-summary { display: block; }
  /* padding-bottom on body itself doesn't reliably extend scroll height
     here (body has height:100% + border-box, which caps its box rather
     than growing it for padding) - .page-container has no explicit
     height, so its own padding-bottom correctly reserves real space
     below the last bit of page content, clear of the fixed bottom nav. */
  .page-container { padding: 20px 16px calc(76px + env(safe-area-inset-bottom, 0px)); }
  .topbar { padding: 0 16px; }
  .topbar-search { display: none; }
  #sidebar-mobile-toggle { display: flex !important; }
  #sidebar-collapse-toggle, #sidebar-sections-toggle { display: none !important; }
  .bottom-nav { display: block; }

  /* The icon-rail "collapsed" look is a desktop space-saver (persisted
     per-user). It makes no sense on the mobile drawer - a temporary
     overlay has no reason to hide its own labels - so force the drawer
     back to full width with labels visible even if the user's desktop
     preference has it collapsed. */
  .sidebar.collapsed { width: var(--sidebar-width); }
  .sidebar.collapsed .sidebar-brand-label,
  .sidebar.collapsed .nav-label { display: revert; }
  .sidebar.collapsed .nav-section-title { display: flex; }
}

/* ----------------------------------------------------- Phones (<=640px) */
@media (max-width: 640px) {
  /* Pages with a fixed 2/3-column .form-row (dashboard, settings, POS,
     repair/purchase forms, ...) always stack to one column on phones -
     overrides the inline grid-template-columns set per-page for desktop. */
  /* minmax(0, 1fr), not a bare 1fr - a bare fr track's implicit "auto"
     minimum lets it grow to fit a wide child's intrinsic content size
     (e.g. a .data-table's min-width), which is exactly the overflow this
     rule exists to prevent. The explicit 0 floor lets the track - and
     the .table-wrap inside it - actually shrink to the viewport, so the
     table scrolls internally instead of blowing out the whole page. */
  .form-row { grid-template-columns: minmax(0, 1fr) !important; }

  .page-container { padding: 16px 12px calc(76px + env(safe-area-inset-bottom, 0px)); }
  .page-header { margin-bottom: 18px; }
  .page-title { font-size: 19px; }
  .page-header > .btn,
  .page-header > a.btn,
  .page-header > .flex { width: 100%; justify-content: center; }
  .page-header > .flex { flex-wrap: wrap; }
  .page-header > .flex > .btn, .page-header > .flex > a.btn { flex: 1 1 auto; justify-content: center; }

  /* Any other non-table flex row (filter pills, action-button groups) -
     wraps instead of forcing the page wider when it doesn't all fit on
     one line. Table-cell action rows are excluded; they live inside an
     already horizontally-scrollable .table-wrap, by design. */
  .flex:not(td) { flex-wrap: wrap; }

  .topbar { padding: 0 10px; gap: 6px; height: 58px; }
  .card-header-sticky { top: 58px; }
  .sticky-toolbar { top: 58px; }
  .topbar-actions { gap: 2px; }
  .icon-btn { width: 34px; height: 34px; }
  .user-menu-name, .user-menu-role { display: none; }
  .user-menu-trigger .nav-label { display: none; }
  [data-dropdown-toggle="branch-menu"] span { display: none; }
  [data-dropdown-toggle="branch-menu"] { width: 38px !important; padding: 0 !important; justify-content: center; }

  .dropdown-menu { position: fixed; inset-inline: 10px; inset-inline-start: 10px; top: 62px !important; width: auto; max-width: none; }

  .card-body { padding: 16px; }
  .card-header { padding: 14px 16px; }
  .kpi-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 10px; }
  .kpi-card { padding: 14px; }
  .kpi-value { font-size: 20px; }

  .data-table { font-size: 13px; min-width: 560px; }
  .data-table thead th, .data-table tbody td { padding: 11px 12px; }

  .modal-backdrop { padding: 0; align-items: flex-end; }
  .modal { max-width: 100%; max-height: 92vh; border-radius: var(--radius-lg) var(--radius-lg) 0 0; }
  .modal-header, .modal-footer { padding: 16px; }
  .modal-body { padding: 16px; }
  .modal-footer { flex-wrap: wrap; }
  .modal-footer .btn { flex: 1 1 auto; }

  .btn { min-height: 44px; }
  .btn-sm { min-height: 36px; }
  .form-control { min-height: 44px; }
  textarea.form-control { min-height: 80px; }

  .table-toolbar { padding: 12px; }
  .table-filters { width: 100%; }
  .table-filters .form-control { flex: 1 1 140px; }

  /* A row of tabs that wraps to 2-3 lines reads as broken on a phone -
     one scrollable line (swipe sideways), like a native app's tab strip. */
  .catalog-tabs { flex-wrap: nowrap !important; overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none; }
  .catalog-tabs::-webkit-scrollbar { display: none; }
  .catalog-tabs .btn { flex: 0 0 auto; }
}
