/* ---------------------------------------------------------------
   Admin panel — flat, quiet back-office visual language.
   White/light surfaces, hairline borders, one accent color used
   sparingly, sentence case everywhere, tables read like a
   spreadsheet rather than a consumer app.
------------------------------------------------------------------ */

:root {
  --bg: #FAFAF9;
  --surface: #FFFFFF;
  --border: #E3E2DE;
  --border-strong: #CFCDC7;
  --text: #1E211F;
  --text-muted: #6B6E69;
  --text-faint: #9A9C97;
  --accent: #1F6F5C;
  --accent-hover: #185A4A;
  --accent-tint: #EAF3F0;
  --danger: #B3432C;
  --danger-tint: #FBEEEA;
  --warn: #9A6B1E;
  --warn-tint: #FBF3E4;
  --radius: 6px;
  --shadow-modal: 0 12px 32px rgba(20, 22, 20, 0.16);
  font-variant-numeric: tabular-nums;
}

* { box-sizing: border-box; }
[hidden] { display: none !important; }

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  font-size: 14px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

button {
  font-family: inherit;
  font-size: 13px;
}

/* ---------- buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 8px 14px;
  border-radius: var(--radius);
  border: 1px solid var(--border-strong);
  background: var(--surface);
  color: var(--text);
  cursor: pointer;
  transition: background 0.12s ease, border-color 0.12s ease;
}
.btn:hover { background: #F3F2EF; }
.btn:disabled { opacity: 0.5; cursor: not-allowed; }
.btn-block { width: 100%; }
.btn-primary {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}
.btn-primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); }
.btn-secondary { background: var(--surface); }
/* Handoff: the 3 product-creation action buttons stay a plain white/
   secondary look at rest -- this marks whichever one the person is
   actively working through (New single item / New multiple items /
   Add color) as a real, distinct visual state, reusing the same
   accent green already used for "completed"/active states elsewhere
   in this file (.status-completed) rather than inventing a new shade.
   Applied/cleared via setActiveProductActionButton in app.js. */
.btn-action-active {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}
.btn-action-active:hover { background: var(--accent-hover); border-color: var(--accent-hover); }
.btn-danger {
  background: var(--surface);
  color: var(--danger);
  border-color: var(--danger);
}
.btn-danger:hover { background: var(--danger-tint); }
.btn-ghost {
  background: transparent;
  border-color: transparent;
  color: var(--text-muted);
}
.btn-ghost:hover { background: #F0EFEC; }
.btn-sm { padding: 4px 10px; font-size: 12px; }

/* ---------- login screen ---------- */
.login-screen {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg);
}
.login-card {
  width: 340px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 32px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.login-card h1 { font-size: 18px; margin: 0; }
.login-sub { margin: -8px 0 4px; color: var(--text-muted); font-size: 13px; }
.login-card label {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 12px;
  color: var(--text-muted);
}
.login-card input {
  font-size: 14px;
  padding: 8px 10px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  color: var(--text);
  background: var(--surface);
}
.login-card input:focus, button:focus-visible, a:focus-visible, select:focus-visible, textarea:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}
.form-error {
  background: var(--danger-tint);
  color: var(--danger);
  padding: 8px 10px;
  border-radius: var(--radius);
  font-size: 12px;
  margin: 0;
}
/* Real, reusable "this specific field has a problem" marker -- red
   border on the actual input/select/textarea, not just a generic
   message elsewhere on the page. Applied/cleared via the shared
   markFieldError/clearFieldErrors helpers (see app.js) so every form
   uses the same real mechanism rather than each screen inventing its
   own version. */
.field-error {
  border-color: var(--danger) !important;
  box-shadow: 0 0 0 1px var(--danger);
}
.login-config {
  margin-top: 4px;
  border-top: 1px solid var(--border);
  padding-top: 10px;
}
.login-config summary {
  font-size: 12px;
  color: var(--text-muted);
  cursor: pointer;
}
.login-config label { margin-top: 8px; }

/* ---------- app shell ---------- */
.app-shell {
  display: flex;
  min-height: 100vh;
}
.sidebar {
  width: 200px;
  flex-shrink: 0;
  background: var(--surface);
  border-right: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
}
.sidebar-brand {
  padding: 18px 20px;
  font-weight: 600;
  font-size: 14px;
  color: var(--text);
  border-bottom: 1px solid var(--border);
}
.sidebar-nav {
  list-style: none;
  margin: 0;
  padding: 8px;
  flex: 1;
  overflow-y: auto;
}
.sidebar-nav li { margin: 1px 0; }
.sidebar-nav a {
  display: block;
  padding: 8px 12px;
  border-radius: var(--radius);
  color: var(--text-muted);
  font-size: 13px;
}
.sidebar-nav a:hover { background: #F3F2EF; text-decoration: none; color: var(--text); }
.sidebar-nav a.active {
  background: var(--accent-tint);
  color: var(--accent);
  font-weight: 600;
}
.sidebar-footer {
  border-top: 1px solid var(--border);
  padding: 12px;
}
.sidebar-user {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 12px;
  margin-bottom: 8px;
  color: var(--text-muted);
}
.role-pill {
  border: 1px solid var(--border-strong);
  border-radius: 999px;
  padding: 1px 8px;
  font-size: 11px;
  text-transform: lowercase;
}

.content {
  flex: 1;
  padding: 28px 36px 60px;
  /* Handoff -- real fluid width, confirmed directly with Ali: this
     used to cap at max-width: 1200px regardless of how wide the
     browser window actually was, wasting real screen space on wider
     monitors. Now genuinely full-width and responsive -- grows and
     shrinks with the window instead of stopping at a fixed cap. */
  width: 100%;
  min-width: 0; /* lets flex children (e.g. wide tables) shrink/scroll instead of overflowing the layout */
}

/* ---------- page header ---------- */
.page-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  margin-bottom: 20px;
  gap: 16px;
}
.page-header h1 { font-size: 18px; margin: 0 0 4px; }
.page-header .page-sub { color: var(--text-muted); font-size: 13px; margin: 0; }
.page-actions { display: flex; gap: 8px; flex-shrink: 0; }

/* ---------- metric cards ---------- */
.metric-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 14px;
  margin-bottom: 28px;
}
.metric-card {
  background: var(--accent-tint);
  border-radius: var(--radius);
  padding: 16px 18px;
}
.metric-label {
  font-size: 12px;
  color: var(--text-muted);
  margin: 0 0 6px;
  text-transform: none;
}
.metric-value {
  font-size: 26px;
  font-weight: 600;
  margin: 0;
  color: var(--text);
}
.metric-card.warn { background: var(--warn-tint); }
.metric-card.warn .metric-value { color: var(--warn); }

/* ---------- section / cards ---------- */
.section {
  margin-bottom: 32px;
}
.section-title {
  font-size: 13px;
  font-weight: 600;
  margin: 0 0 10px;
  color: var(--text);
}
.panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 18px;
}

/* ---------- tables ---------- */
table {
  width: 100%;
  border-collapse: collapse;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}
/* Handoff: fixed column widths specifically for the products list --
   expanding/collapsing a parent family used to shift every column
   left/right, since a plain (table-layout: auto) table recalculates
   widths from whatever rows are currently visible, and a parent row's
   "--" placeholders are a different width than its real variant rows'
   actual SKU/name/category text. Fixed widths here keep every column
   steady regardless of which rows are expanded. Scoped to this one
   table (not the generic `table` rule above) so other tables
   elsewhere in the admin keep their own natural, unaffected sizing. */
.products-table-grid { table-layout: fixed; }
.products-table-grid th:nth-child(1), .products-table-grid td:nth-child(1) { width: 56px; }
.products-table-grid th:nth-child(2), .products-table-grid td:nth-child(2) { width: 14%; }
.products-table-grid th:nth-child(3), .products-table-grid td:nth-child(3) { width: 24%; }
.products-table-grid th:nth-child(4), .products-table-grid td:nth-child(4) { width: 9%; }
.products-table-grid th:nth-child(5), .products-table-grid td:nth-child(5) { width: 9%; }
.products-table-grid th:nth-child(6), .products-table-grid td:nth-child(6) { width: 13%; }
.products-table-grid th:nth-child(7), .products-table-grid td:nth-child(7) { width: 10%; }
.products-table-grid th:nth-child(8), .products-table-grid td:nth-child(8) { width: 10%; }
.products-table-grid th:nth-child(9), .products-table-grid td:nth-child(9) { width: 11%; }
.products-table-grid td, .products-table-grid th { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Handoff: Designer page's live preview boxes -- a real, bordered
   frame around whatever image comes back (SVG barcode label, or
   pos_backend's real ReportLab-rendered receipt/certificate), capped
   at a sensible width so a tall receipt preview doesn't dominate the
   page. */
.designer-preview {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 14px;
  background: var(--surface);
  display: inline-block;
  max-width: 100%;
}
.designer-preview img { max-width: 320px; height: auto; display: block; }
/* Handoff -- real tabs for the Delivery page (Delivery orders /
   Drivers / Delivery zones), first tab pattern in this app. Deliberately
   simple: underline-style active state, no external library. */
.page-tabs {
  display: flex;
  gap: 4px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 20px;
}
.page-tab {
  padding: 10px 16px;
  border: none;
  background: none;
  font-weight: 600;
  font-size: 14px;
  color: var(--text-muted);
  cursor: pointer;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
}
.page-tab:hover { color: var(--text); }
.page-tab.is-active { color: var(--accent); border-bottom-color: var(--accent); }
.page-tab-panel[hidden] { display: none; }
/* Handoff -- the major "two kinds of delivery" feature. A small,
   indented table for an expanded district row's own areas, visually
   distinct from the main table it's nested inside. */
.nested-table { width: 100%; margin: 6px 0; font-size: 13px; }
.nested-table th, .nested-table td { padding: 4px 8px; }
.district-row-toggle { cursor: pointer; }
/* Handoff -- real click-to-toggle active/inactive, confirmed directly
   with Ali: the status badge itself is now the control, not just a
   read-only label. */
.badge-toggle { cursor: pointer; }
.badge-toggle:hover { opacity: 0.75; }
/* Receipt/gift-card-certificate previews are real PDFs (pos_backend's
   real ReportLab generator), not images -- an <img> tag can't render
   a PDF at all, confirmed directly by checking the real response
   content-type rather than assuming. An iframe needs explicit
   dimensions (unlike an <img>, which sizes itself from the image).
   Real bug found and fixed: a generic 320x420 iframe made the QR code
   (drawn last, at the real bottom of the page -- confirmed by
   actually rendering a real receipt PDF to a PNG and looking at it
   directly) appear to be "in the middle" of the visible preview,
   since the browser's PDF viewer can't fit an 80mm-wide, much-taller
   receipt into a 420px box and falls back to showing/scaling only
   part of the page. Receipt (tall, narrow -- 80mm wide, easily
   150-250mm+ tall with real content) and the gift card certificate
   (a real, fixed 140x90mm landscape card, confirmed directly in
   giftcard_certificate.py) are genuinely different shapes and need
   their own real aspect ratios, not one generic box for both. */
.designer-preview-pdf-receipt { width: 280px; height: 700px; border: none; }
.designer-preview-pdf-giftcard { width: 420px; height: 270px; border: none; }
/* Handoff: live preview moved to sit beside each Designer section's
   own fields (not below them) -- a real side-by-side layout, form on
   the left (flexible width), preview on the right (fixed width,
   matching its own real size so it doesn't stretch/shrink oddly).
   Stacks vertically on narrow screens, same responsive convention as
   the rest of this app's own .form-grid breakpoint. */
.designer-section-layout { display: flex; gap: 24px; align-items: flex-start; flex-wrap: wrap; }
.designer-section-layout > .designer-section-fields { flex: 1 1 380px; min-width: 300px; }
.designer-section-layout > .designer-section-preview { flex: 0 0 auto; }
thead th {
  text-align: left;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--text-faint);
  font-weight: 600;
  padding: 9px 12px;
  border-bottom: 1px solid var(--border);
  background: #FCFCFB;
}
tbody td {
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
  font-size: 13px;
  vertical-align: middle;
}
tbody tr:last-child td { border-bottom: none; }
tbody tr:hover { background: #FBFBFA; }
td.num, th.num { text-align: right; }
.row-link { cursor: pointer; }
.muted { color: var(--text-muted); }
.faint { color: var(--text-faint); }
.mono { font-variant-numeric: tabular-nums; }

/* ---------- badges / status ---------- */
.badge {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 11px;
  border: 1px solid var(--border-strong);
  color: var(--text-muted);
}
.badge.on { color: var(--accent); border-color: var(--accent); background: var(--accent-tint); }
.badge.off { color: var(--text-faint); }
.badge.status-refunded { color: var(--danger); border-color: var(--danger); background: var(--danger-tint); }
.badge.status-completed { color: var(--accent); border-color: var(--accent); background: var(--accent-tint); }
/* Stock Transfer statuses (CONVOY) -- pending/rejected/cancelled use the
   default unstyled badge above; only flagged (needs attention) and
   received (done, reuses status-completed's green) get their own look. */
.badge.status-flagged { color: var(--warn); border-color: var(--warn); background: var(--warn-tint); }
.badge.status-received { color: var(--accent); border-color: var(--accent); background: var(--accent-tint); }

/* ---------- toggle switch ---------- */
.switch {
  position: relative;
  display: inline-block;
  width: 34px;
  height: 19px;
  flex-shrink: 0;
}
.switch input { opacity: 0; width: 0; height: 0; }
.switch .slider {
  position: absolute;
  cursor: pointer;
  inset: 0;
  background: var(--border-strong);
  border-radius: 999px;
  transition: 0.15s;
}
.switch .slider::before {
  content: "";
  position: absolute;
  width: 15px;
  height: 15px;
  left: 2px;
  top: 2px;
  background: #fff;
  border-radius: 50%;
  transition: 0.15s;
}
.switch input:checked + .slider { background: var(--accent); }
.switch input:checked + .slider::before { transform: translateX(15px); }
.switch input:disabled + .slider { opacity: 0.5; cursor: not-allowed; }

/* ---------- forms ---------- */
.form-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
}
.form-grid.full { grid-template-columns: 1fr; }
/* Handoff: single-item form's identity/pricing rows requested as real
   4-column layouts, not the shared 2-column default -- a modifier on
   .form-grid rather than a new class, matching the existing .narrow
   convention already used elsewhere for the same base grid. */
.form-grid.cols-4 { grid-template-columns: 1fr 1fr 1fr 1fr; }
.form-grid.cols-3 { grid-template-columns: 1fr 1fr 1fr; }
.field { display: flex; flex-direction: column; gap: 4px; }
.field label { font-size: 12px; color: var(--text-muted); }
.field input, .field select, .field textarea {
  font-size: 13px;
  padding: 7px 10px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  font-family: inherit;
}
.field textarea { font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 12px; }
.field .hint { color: var(--text-faint); font-size: 11px; }
.field-row { display: flex; align-items: center; gap: 8px; }

.thumb {
  width: 36px; height: 36px; border-radius: var(--radius);
  object-fit: cover; border: 1px solid var(--border-strong);
  display: block;
}
.thumb-empty {
  display: flex; align-items: center; justify-content: center;
  color: var(--text-faint); font-size: 11px; background: var(--surface);
}
.thumb-lg { width: 120px; height: 120px; margin-bottom: 6px; }

/* ---------- filter bar ---------- */
.filter-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 14px;
  align-items: flex-end;
}
.filter-bar .field { min-width: 140px; }
.filter-bar .field.grow { flex: 1; min-width: 180px; }

/* ---------- autocomplete dropdown (Orders report product filter) ---------- */
.autocomplete-list {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 20;
  margin-top: 2px;
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  box-shadow: var(--shadow-modal);
  max-height: 220px;
  overflow-y: auto;
}
.autocomplete-item {
  padding: 7px 10px;
  font-size: 13px;
  cursor: pointer;
}
.autocomplete-item:hover { background: var(--accent-tint); }

/* ---------- summary stat boxes (Orders report) ---------- */
.stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 12px;
  margin-bottom: 22px;
}
.stat-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 4px solid var(--border-strong);
  border-radius: var(--radius);
  padding: 12px 14px;
}
.stat-card .stat-label {
  font-size: 11px;
  color: var(--text-muted);
  margin: 0 0 5px;
}
.stat-card .stat-value {
  font-size: 20px;
  font-weight: 600;
  margin: 0;
  color: var(--text);
}
.stat-card .stat-sub {
  font-size: 11px;
  color: var(--text-faint);
  margin: 3px 0 0;
}
.stat-card.stat-accent { border-left-color: var(--accent); }
.stat-card.stat-accent .stat-value { color: var(--accent); }
.stat-card.stat-danger { border-left-color: var(--danger); }
.stat-card.stat-danger .stat-value { color: var(--danger); }
.stat-card.stat-warn { border-left-color: var(--warn); }
.stat-card.stat-warn .stat-value { color: var(--warn); }
.stat-card.stat-neutral { border-left-color: var(--border-strong); }

/* ---------- pagination ---------- */
.pagination {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 12px;
  font-size: 12px;
  color: var(--text-muted);
}

/* ---------- empty / blocked / error states ---------- */
.empty-state, .blocked-state, .error-state {
  padding: 28px 20px;
  text-align: center;
  color: var(--text-muted);
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius);
  background: var(--surface);
}
.blocked-state {
  text-align: left;
  border-style: solid;
  background: var(--warn-tint);
  border-color: #E7D6AC;
}
.blocked-state .blocked-title {
  font-weight: 600;
  color: var(--warn);
  margin: 0 0 6px;
  display: flex;
  align-items: center;
  gap: 6px;
}
.blocked-state p { margin: 0 0 8px; font-size: 13px; }
.blocked-state p:last-child { margin-bottom: 0; }
.error-state { border-color: var(--danger); background: var(--danger-tint); color: var(--danger); }

.loading { color: var(--text-faint); padding: 20px 0; font-size: 13px; }

/* ---------- modal ---------- */
.modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(20, 22, 20, 0.35);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 50;
}
.modal {
  width: 380px;
  background: var(--surface);
  border-radius: var(--radius);
  box-shadow: var(--shadow-modal);
  padding: 22px;
}
.modal h2 { font-size: 15px; margin: 0 0 8px; }
.modal p { font-size: 13px; color: var(--text-muted); margin: 0 0 14px; }
#modal-body { white-space: pre-line; }
.modal-actions { display: flex; justify-content: flex-end; gap: 8px; }

/* Handoff -- real "press the log, see the whole drawer" feature,
   confirmed directly with Ali: a real, wider variant for content that
   doesn't fit the plain 380px confirm modal (the full entries table +
   Drawer Close report + totals). */
.modal--wide { width: min(760px, 92vw); max-height: 86vh; display: flex; flex-direction: column; }
.modal-header-row { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
.modal-header-row h2 { margin: 0; }
#drawer-detail-body { overflow-y: auto; }

/* ---------- toast ---------- */
.toast {
  position: fixed;
  bottom: 20px;
  left: 50%;
  transform: translateX(-50%);
  background: var(--text);
  color: #fff;
  padding: 10px 18px;
  border-radius: var(--radius);
  font-size: 13px;
  z-index: 60;
  box-shadow: var(--shadow-modal);
}
.toast.error { background: var(--danger); }

/* ---------- detail panel (order drill-in) ---------- */
.detail-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 14px 20px;
  margin-bottom: 18px;
}
.detail-item .k { font-size: 11px; color: var(--text-faint); text-transform: uppercase; letter-spacing: 0.03em; margin: 0 0 3px; }
.detail-item .v { font-size: 14px; margin: 0; }

.back-link { display: inline-block; margin-bottom: 14px; font-size: 13px; color: var(--text-muted); }

/* ---------- collapsible panel (DISPATCH-14 §3a Stock Transfer redesign) ---------- */
.collapsible-panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}
.collapsible-panel + .collapsible-panel { margin-top: 16px; }
.collapsible-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 18px;
  background: #F7F6F4;
  border-bottom: 1px solid var(--border);
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  cursor: pointer;
  user-select: none;
}
.collapsible-header:last-child { border-bottom: none; }
.collapse-toggle {
  width: 26px; height: 26px;
  border-radius: 50%;
  border: none;
  background: var(--accent);
  color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-size: 11px;
  line-height: 1;
  cursor: pointer;
  flex-shrink: 0;
  transition: transform 0.15s;
}
.collapse-toggle:hover { background: var(--accent-hover); }
.collapse-toggle.collapsed { transform: rotate(180deg); }
.collapsible-body { padding: 18px; }
.collapsible-body.collapsed { display: none; }
.collapsible-body .form-grid.narrow { grid-template-columns: 1fr; max-width: 420px; }
.required-mark { color: var(--danger); margin-left: 2px; }

.transfer-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 20px; gap: 16px; }
.transfer-header .header-title-row { display: flex; align-items: center; gap: 10px; }
.transfer-header .icon-back {
  font-size: 18px; color: var(--text-muted); text-decoration: none; line-height: 1;
  padding: 2px 4px;
}
.transfer-header .icon-back:hover { color: var(--text); }
.transfer-header h1 { font-size: 18px; margin: 0; }

.products-toolbar { display: flex; align-items: center; gap: 18px; margin-bottom: 14px; flex-wrap: wrap; }
.bulk-add-field { display: flex; align-items: center; gap: 8px; }
.bulk-add-field input[type="number"] {
  width: 64px; font-size: 13px; padding: 7px 10px;
  border: 1px solid var(--border-strong); border-radius: var(--radius);
}
.bulk-add-field .hint { font-size: 11px; color: var(--text-faint); }
.row-product-cell { position: relative; min-width: 200px; }
.row-product-cell input[readonly] { background: #FAFAF9; color: var(--text-muted); }
.row-product-selected { display: flex; gap: 6px; align-items: center; }
.row-product-selected input[readonly] { flex: 1; }

/* Stock Transfer / New Stock "Add product" search widget (CONVOY).
   Real bug found and fixed: this used to be `position: absolute` on
   the table cell, which clipped/mispositioned the dropdown for rows
   near the bottom of a long table. Positioning (position/top/left/
   right/bottom/width) is now computed and set inline in JS
   (attachProductAutocomplete), anchored to the real viewport --
   only the presentational styling stays here. */
.autocomplete-dropdown {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  max-height: 220px;
  overflow-y: auto;
  z-index: 200;
  box-shadow: var(--shadow-modal);
}
.autocomplete-item { padding: 8px 12px; font-size: 13px; cursor: pointer; }
.autocomplete-item:hover { background: #F3F2EF; }
.autocomplete-item.muted { cursor: default; }
.autocomplete-item.muted:hover { background: transparent; }

@media (max-width: 800px) {
  .app-shell { flex-direction: column; }
  .sidebar { width: 100%; height: auto; position: relative; }
  .content { padding: 20px; }
  .form-grid { grid-template-columns: 1fr; }
  .form-grid.cols-4 { grid-template-columns: 1fr; }
  .form-grid.cols-3 { grid-template-columns: 1fr; }
}

/* Order receipt printing (FOLIO §6e). Two print modes, chosen by
   app.js setting/clearing body[data-print-mode="full"] before calling
   window.print():
   - Default (no attribute): "Print receipt" — the dedicated compact
     8cm template (.receipt-print) is the ONLY thing printed. This
     replaces the old "hide the sidebar and print the whole page"
     approach, which produced a full-width web-page printout with no
     receipt-like structure.
   - data-print-mode="full": "Print full details" — restores that old
     whole-page behavior for when someone genuinely wants the full
     on-screen detail on paper, with .receipt-print explicitly hidden
     so it doesn't ALSO print underneath everything else. */
@media print {
  .sidebar, .no-print, #modal-backdrop, .toast { display: none !important; }
  .app-shell { display: block; }
  .content { padding: 0; }

  .receipt-print { display: none; }
  body[data-print-mode="full"] .receipt-print { display: none !important; }
  body:not([data-print-mode="full"]) .content > *:not(.receipt-print) {
    display: none !important;
  }
  body:not([data-print-mode="full"]) .receipt-print {
    display: block !important;
  }
}

/* @page controls the physical print media itself -- 80mm (8cm) wide,
   height auto so it doesn't force a fixed page length on a
   variable-length order (per the handoff's explicit "width: 8cm,
   height auto" instruction, not a fixed-height page). Most receipt
   printers/print-to-PDF drivers respect @page size directly. */
@page {
  size: 80mm auto;
  margin: 3mm;
}

.receipt-print {
  display: none; /* shown only under @media print, see above */
  width: 8cm;
  margin: 0 auto;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  font-size: 11px;
  line-height: 1.45;
  color: #000;
}
.receipt-logo {
  text-align: center;
  font-size: 18px;
  font-weight: 700;
  letter-spacing: 0.04em;
  margin-top: 2mm;
}
.receipt-tagline {
  text-align: center;
  font-size: 11px;
  letter-spacing: 0.12em;
  color: #333;
  margin-bottom: 3mm;
}
.receipt-meta {
  border-top: 1px dashed #000;
  border-bottom: 1px dashed #000;
  padding: 2mm 0;
  margin-bottom: 2mm;
}
.receipt-meta p { margin: 0 0 1mm; }
.receipt-items {
  width: 100%;
  border-collapse: collapse;
  margin-bottom: 2mm;
  background: transparent;
  border: none;
  border-radius: 0;
}
.receipt-items thead th {
  text-align: left;
  font-size: 10px;
  text-transform: none;
  letter-spacing: 0;
  color: #000;
  background: transparent;
  padding: 1mm 0;
  border-bottom: 1px solid #000;
}
.receipt-items td {
  padding: 1mm 0;
  border-bottom: none;
  font-size: 11px;
  vertical-align: top;
}
.receipt-items th.num, .receipt-items td.num { text-align: right; }
.receipt-totals {
  border-top: 1px dashed #000;
  padding-top: 2mm;
  margin-bottom: 2mm;
}
.receipt-totals p {
  display: flex;
  justify-content: space-between;
  margin: 0 0 1mm;
}
.receipt-total-line {
  font-weight: 700;
  font-size: 13px;
  border-top: 1px solid #000;
  padding-top: 1mm;
  margin-top: 1mm !important;
}
.receipt-thankyou {
  text-align: center;
  font-weight: 600;
  margin: 3mm 0 2mm;
}
.receipt-qr {
  display: flex;
  justify-content: center;
  margin-bottom: 2mm;
}
.receipt-qr-placeholder {
  width: 22mm;
  height: 22mm;
  border: 1px dashed #666;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  font-size: 9px;
  color: #666;
  line-height: 1.3;
}
.receipt-followus {
  text-align: center;
  font-size: 10px;
  margin: 0 0 3mm;
}
.receipt-branches {
  border-top: 1px dashed #000;
  padding-top: 2mm;
  margin-bottom: 2mm;
  font-size: 10px;
  text-align: center;
}
.receipt-branches-title {
  font-weight: 600;
  margin: 0 0 1mm;
}
.receipt-branches p { margin: 0 0 1mm; }
.receipt-contact {
  text-align: center;
  font-size: 10px;
  padding-bottom: 3mm;
}
.receipt-contact p { margin: 0 0 1mm; }

/* ---------- PALETTE: product creation wizard (§6b) ---------- */
.wizard-steps {
  display: flex;
  gap: 4px;
  margin-bottom: 18px;
  border-bottom: 1px solid var(--border, #e5e3de);
  padding-bottom: 0;
}
.wizard-step-tab {
  padding: 8px 14px;
  font-size: 12px;
  color: var(--text-faint);
  border-bottom: 2px solid transparent;
  white-space: nowrap;
}
.wizard-step-tab.active { color: var(--text); border-bottom-color: var(--accent); font-weight: 600; }
.wizard-step-tab.done { color: var(--text-muted); }
.wizard-actions { display: flex; gap: 8px; margin-top: 16px; justify-content: space-between; }
.wizard-actions .left, .wizard-actions .right { display: flex; gap: 8px; }

.variant-table { width: 100%; border-collapse: collapse; margin-top: 8px; }
.variant-table th { text-align: left; font-size: 11px; color: var(--text-faint); text-transform: uppercase; letter-spacing: 0.02em; padding: 4px 6px; }
.variant-table td { padding: 4px 6px; vertical-align: top; }
.variant-table input[type="text"], .variant-table input[type="number"] {
  width: 100%; padding: 5px 7px; font-size: 13px; border: 1px solid var(--border, #ddd); border-radius: 4px;
}
.variant-row { border-top: 1px solid var(--border, #eee); cursor: grab; }
.variant-row.dragging { opacity: 0.4; }
.variant-row .drag-handle { cursor: grab; color: var(--text-faint); user-select: none; padding: 0 4px; }
/* Handoff §3b: branch name is now shown directly above each qty/threshold
   input instead of relying on a 3-letter truncated placeholder + hover
   tooltip -- Ali's screenshot showed literal "?" marks where he expected
   to see which column belonged to which branch. */
.branch-qty-field { display: flex; flex-direction: column; align-items: center; gap: 2px; }
.branch-qty-label { font-size: 9px; color: var(--text-faint); max-width: 52px; text-align: center; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Handoff §3b: real per-field validation highlighting, replacing a
   generic bottom-of-screen-only error banner for the cases this
   editor can check client-side (missing required fields, duplicate
   codes/names within one batch). */
.variant-row input.field-error { border-color: var(--danger, #b3261e); background: color-mix(in srgb, var(--danger, #b3261e) 8%, transparent); }
.field-error-msg { font-size: 11px; color: var(--danger, #b3261e); margin-top: 2px; max-width: 160px; }
.bulk-set-row { background: var(--surface, #FAFAF8); border-radius: 6px; }
.bulk-set-row td { padding: 8px 6px; }
.variant-qty-toggle { font-size: 11px; color: var(--accent); cursor: pointer; }
.variant-qty-box { display: none; gap: 6px; flex-wrap: wrap; margin-top: 4px; }
.variant-qty-box.open { display: flex; }
.variant-qty-box .field { min-width: 90px; }
.gallery-grid { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 6px; }
.gallery-thumb { position: relative; width: 96px; display: flex; flex-direction: column; align-items: center; gap: 4px; }
.gallery-thumb img { width: 96px; height: 96px; object-fit: cover; border-radius: 6px; border: 1px solid var(--border, #ddd); }
.gallery-thumb.gallery-thumb-main img { border: 2px solid var(--accent); }
.gallery-thumb .gallery-remove {
  position: absolute; top: -6px; right: -6px; width: 18px; height: 18px; border-radius: 50%;
  background: var(--danger, #b3261e); color: #fff; border: none; font-size: 11px; cursor: pointer; line-height: 18px; padding: 0;
}
.gallery-main-badge {
  font-size: 10px; color: var(--accent); font-weight: 600; text-transform: uppercase; letter-spacing: 0.03em;
}
.gallery-thumb .gallery-make-main { font-size: 11px; padding: 2px 8px; }
.variant-image-block { border: 1px solid var(--border, #eee); border-radius: 8px; padding: 10px; margin-bottom: 10px; }
/* DISPATCH-23 §4b -- per-variant inline images in the Variants step:
   "up to 10 images uploadable in one selection, previewed as medium
   icons, 5 per row, each deletable individually from the icon itself".
   A real CSS grid (not flex-wrap) so 5-per-row holds regardless of
   container width, rather than an incidental wrap point. */
.gallery-grid-5col { display: grid; grid-template-columns: repeat(5, 1fr); gap: 8px; margin-top: 6px; max-width: 420px; }
.gallery-grid-5col .gallery-thumb { width: auto; }
.gallery-grid-5col .gallery-thumb img { width: 72px; height: 72px; }
.category-tree-picker { max-height: 220px; overflow-y: auto; border: 1px solid var(--border, #ddd); border-radius: 6px; padding: 6px; }
.category-tree-picker label { display: block; padding: 4px 6px; font-size: 13px; cursor: pointer; border-radius: 4px; }
.category-tree-picker label:hover { background: var(--surface, #F3F2EF); }
/* Handoff §3b -- shared category tree (renderCategoryTree): inline
   create + up/down reorder, used by both the wizard's Category step
   and the standalone Categories page. */
.category-tree-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 4px 6px; border-radius: 4px; }
.category-tree-row:hover { background: var(--surface, #F3F2EF); }
.category-tree-radio { display: flex; align-items: center; gap: 6px; font-size: 13px; cursor: pointer; flex: 1; }
.category-tree-name { font-size: 13px; flex: 1; }
.category-tree-actions { display: flex; gap: 2px; flex-shrink: 0; }
.btn-icon { border: none; background: none; cursor: pointer; font-size: 12px; padding: 2px 5px; border-radius: 4px; color: var(--text-muted); }
.btn-icon:hover:not(:disabled) { background: var(--border, #eee); }
.btn-icon:disabled { opacity: 0.3; cursor: default; }
.category-tree-add-form { display: flex; align-items: center; gap: 6px; padding: 4px 6px; }
.category-tree-add-form input { flex: 1; max-width: 220px; }
.type-badge { font-size: 11px; padding: 2px 8px; border-radius: 10px; border: 1px solid var(--border, #ddd); }
.type-badge.simple { color: var(--text-muted); }
.type-badge.parent { color: var(--accent); border-color: var(--accent); background: var(--accent-tint); }
.type-badge.variant { color: var(--text-faint); }
.parent-row-toggle { cursor: pointer; user-select: none; }
.variant-nested-row td:first-child { padding-left: 26px; }

/* Gift card print template (MINT -- gift cards phase 2 addendum).
   .gc-print-only is invisible on screen and only appears when printing
   -- lets the gift-card detail view show its normal interactive
   controls on screen while printing a clean, minimal card instead of
   the whole page. Same .no-print escape hatch as the order-receipt
   pattern above, just inverted for this one block. */
.gc-print-only { display: none; }
@media print {
  .gc-print-only { display: block; }
}
