/* ==========================================================================
   KI Inventory — app.css
   Mobile-first. Works down to 375px. Light theme only, matching the mockup —
   the navy sidebar is the one deliberately dark surface in the app. There is
   no dark-mode variant: it was tried and explicitly rejected (it made the
   whole content area dark, not just the sidebar), so don't reintroduce a
   `prefers-color-scheme: dark` block without an opt-in toggle to go with it.
   ========================================================================== */

:root {
  --navy:        #0b3d63;
  --navy-dark:   #072a45;
  --amber:       #e8871e;
  --amber-dark:  #c9720f;
  --stat-blue:   #2f6fed;
  --stat-blue-bg:#e8effe;

  /* Dashboard stat-card tiles + action buttons — a small, saturated palette
     kept separate from --ok/--warn/--danger/--stat-blue above (those are used
     for pills, banners, and links elsewhere and shouldn't shift just because
     the dashboard's own look changes). */
  --dash-blue:       #2563eb;
  --dash-blue-dark:  #1d4ed8;
  --dash-green:      #16a34a;
  --dash-green-dark: #15803d;
  --dash-amber:      #f59e0b;
  --dash-red:        #dc2626;
  --dash-red-dark:   #b91c1c;

  --bg:          #f1f5f9;
  --surface:     #ffffff;
  --surface-2:   #eef2f6;
  --border:      #d5dde5;
  --text:        #1e293b;
  --text-soft:   #64748b;
  --danger:      #c0392b;
  --danger-bg:   #fdecea;
  --ok:          #1e7e50;
  --ok-bg:       #e6f4ec;
  --warn:        #9a6b00;
  --warn-bg:     #fcf1d8;

  --card-shadow: 0 1px 3px rgba(15, 23, 42, .06), 0 1px 2px rgba(15, 23, 42, .04);

  --radius: 8px;
  --radius-lg: 12px;
  --gap: 14px;
  --sidebar-w: 260px;
  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

* { box-sizing: border-box; }

html, body { margin: 0; padding: 0; }

body {
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.45;
  color: var(--text);
  background: var(--bg);
  -webkit-text-size-adjust: 100%;
}

h1 { font-size: 1.3rem; margin: 0; }
h2 { font-size: 1.05rem; margin: 0; }
code { background: var(--surface-2); padding: 1px 5px; border-radius: 4px; }

/* ---- loading / config ---- */
#app-loading {
  padding: 40px 16px;
  text-align: center;
  color: var(--text-soft);
}
#config-error {
  margin: 24px auto;
  max-width: 520px;
  padding: 16px 18px;
  background: var(--warn-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--text);
}

/* ---- buttons ---- */
.btn {
  font: inherit;
  padding: 9px 14px;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
  cursor: pointer;
  white-space: nowrap;
}
.btn:hover { background: var(--surface-2); }
.btn:disabled { opacity: .6; cursor: default; }
.btn-primary {
  background: var(--navy);
  border-color: var(--navy);
  color: #fff;
}
.btn-primary:hover { background: var(--navy-dark); }
.btn-green {
  background: var(--dash-green);
  border-color: var(--dash-green);
  color: #fff;
}
.btn-green:hover { background: var(--dash-green-dark); }
.btn-blue {
  background: var(--dash-blue);
  border-color: var(--dash-blue);
  color: #fff;
}
.btn-blue:hover { background: var(--dash-blue-dark); }
.btn-red {
  background: var(--dash-red);
  border-color: var(--dash-red);
  color: #fff;
}
.btn-red:hover { background: var(--dash-red-dark); }
.btn-ghost { background: transparent; }
/* ~28px tall before this (5px padding + .85rem line-height) — under every
   common touch-target guideline. Still deliberately smaller than a full
   .btn (that's the whole point of the class — pagination/row actions
   shouldn't read as prominently as a primary action), just not cramped. */
.btn-sm { padding: 8px 12px; font-size: .85rem; }
.btn-block, .btn-block.btn { width: 100%; display: block; }

/* ---- login ---- */
.auth {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px 16px;
}
.auth-card {
  width: 100%;
  max-width: 380px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 26px 22px 24px;
}
.wordmark { font-size: 1.4rem; font-weight: 700; letter-spacing: .3px; }
.wordmark-ki {
  background: var(--amber);
  color: #fff;
  padding: 1px 7px;
  border-radius: 5px;
  font-weight: 800;
}
.auth-sub { color: var(--text-soft); margin: 6px 0 20px; font-size: .9rem; }

/* ---- fields ---- */
.field { display: flex; flex-direction: column; gap: 5px; margin-bottom: 13px; }
.field-label { font-size: .82rem; font-weight: 600; color: var(--text-soft); }
.field-hint { font-size: .78rem; color: var(--text-soft); }
.control {
  font: inherit;
  padding: 9px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  width: 100%;
}
.control:focus { outline: 2px solid var(--navy); outline-offset: 1px; }
textarea.control { resize: vertical; min-height: 40px; }
/* padding grows the tap target a little beyond the checkbox+text's own
   size — free on top of the tap area the visible label text already
   gives these (Products' "Show inactive"/"Track serial numbers", Users'
   Active toggle), since clicking anywhere on a <label> already toggles
   the <input> it wraps. */
.inline-check { flex-direction: row; align-items: center; gap: 8px; padding: 4px 0; }
.inline-check input { width: auto; }

/* Labels picker's select-all + per-row checkboxes are the one place in
   the app with a BARE checkbox and no adjacent label text to lean on for
   tap area, so they get their own explicit size bump — scoped here
   rather than a blanket input[type=checkbox] rule, which would also
   resize the ones above that don't need it. The cell around it already
   gets 14px 12px padding for free from table.work-table's own rule
   (below), so no separate padding rule is needed here. */
#view-labels input[type="checkbox"] {
  width: 18px;
  height: 18px;
}

.form-error {
  background: var(--danger-bg);
  color: var(--danger);
  border: 1px solid var(--danger);
  border-radius: var(--radius);
  padding: 9px 11px;
  margin: 10px 0 0;
  font-size: .88rem;
}

/* ---- icons ---- */
.icon { display: inline-flex; }
.icon svg { width: 1.1em; height: 1.1em; display: block; }

/* ---- app shell: sidebar + main column ---- */
.app-shell { display: flex; min-height: 100vh; align-items: stretch; }

.sidebar {
  width: var(--sidebar-w);
  flex-shrink: 0;
  background: var(--navy-dark);
  color: #fff;
  display: flex;
  flex-direction: column;
  position: fixed;
  inset: 0 auto 0 0;
  z-index: 40;
  transform: translateX(-100%);
  transition: transform .2s ease;
}
.sidebar.is-open { transform: translateX(0); }

.sidebar-backdrop {
  position: fixed; inset: 0; background: rgba(4,8,12,.55); z-index: 39;
}

.sidebar-brand {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 20px 18px 18px;
  border-bottom: 1px solid rgba(255,255,255,.1);
}
.sidebar-logo { flex-shrink: 0; }
/* Placeholder logo (assets/logo.svg) until KI's real artwork replaces it —
   same slot the README's folder structure already reserves for assets/logo.png. */
.sidebar-logo-img { flex-shrink: 0; width: 40px; height: 40px; border-radius: 9px; display: block; }
.sidebar-brand-text { min-width: 0; }
.sidebar-company {
  font-weight: 800;
  font-size: .92rem;
  letter-spacing: .5px;
  text-transform: uppercase;
  overflow-wrap: anywhere;
}
.sidebar-slogan {
  font-style: italic;
  font-size: .74rem;
  opacity: .75;
  margin-top: 3px;
  line-height: 1.3;
}
.sidebar-close-btn {
  display: none;
  margin-left: auto;
  background: none; border: none; color: #fff; opacity: .8;
  padding: 2px; cursor: pointer; flex-shrink: 0;
}

.sidebar-nav { display: flex; flex-direction: column; gap: 2px; padding: 14px 12px; flex: 1; overflow-y: auto; }
.sidebar-nav a {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  border-radius: var(--radius);
  color: rgba(255,255,255,.82);
  text-decoration: none;
  font-size: .92rem;
}
.sidebar-nav a:hover { background: rgba(255,255,255,.08); color: #fff; }
.sidebar-nav a.is-active { background: var(--stat-blue); color: #fff; }
.sidebar-nav a .icon { flex-shrink: 0; opacity: .95; }
.sidebar-nav a .icon svg { width: 19px; height: 19px; }
.nav-more-toggle {
  display: flex; align-items: center; gap: 12px; width: 100%;
  margin-top: 6px; padding: 10px 12px; border: 0; border-radius: var(--radius);
  background: none; color: rgba(255,255,255,.62); font: inherit; font-size: .92rem;
  cursor: pointer; text-align: left;
}
.nav-more-toggle:hover { background: rgba(255,255,255,.08); color: #fff; }
.nav-more-toggle:focus-visible { outline: 2px solid var(--amber); outline-offset: -2px; }
.nav-more-toggle .icon { flex-shrink: 0; transition: transform .15s ease; }
.nav-more-toggle .icon svg { width: 19px; height: 19px; }
.nav-more-toggle.is-open .icon { transform: rotate(90deg); }
.nav-more-list { display: flex; flex-direction: column; gap: 2px; }
.nav-more-list[hidden] { display: none; }

.sidebar-contact {
  margin-top: auto; /* pins it to the bottom regardless of nav length */
  padding: 14px 18px 20px;
  border-top: 1px solid rgba(255,255,255,.1);
}
.sidebar-contact-row {
  display: flex; align-items: flex-start; gap: 9px;
  font-size: .78rem; opacity: .8; margin-bottom: 8px; line-height: 1.35;
}
.sidebar-contact-row:last-child { margin-bottom: 0; }
.sidebar-contact-row .icon { flex-shrink: 0; margin-top: 1px; }

.main-col { flex: 1; min-width: 0; display: flex; flex-direction: column; }

/* ---- topbar (light) ---- */
.topbar {
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  display: flex;
  flex-wrap: wrap;
  row-gap: 8px;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
}
.sidebar-toggle-btn {
  background: none; border: none; color: var(--text); cursor: pointer;
  padding: 6px; flex-shrink: 0; display: flex;
}
.topbar-search { position: relative; flex: 1; max-width: 480px; }
.topbar-search-icon {
  position: absolute; left: 12px; top: 50%; transform: translateY(-50%);
  color: var(--text-soft); pointer-events: none;
}
.topbar-search .control {
  border-radius: 999px;
  padding-left: 38px;
  background: var(--surface-2);
  border-color: transparent;
}
.topbar-search .control:focus { background: var(--surface); border-color: var(--navy); }
.topbar-search .control::placeholder { color: var(--text-soft); }
.topbar-date { color: var(--text-soft); font-size: .85rem; white-space: nowrap; }
.topbar-user { margin-left: auto; display: flex; align-items: center; gap: 10px; min-width: 0; }
.topbar-avatar {
  flex-shrink: 0;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: var(--surface-2);
  color: var(--text-soft);
  display: flex;
  align-items: center;
  justify-content: center;
}
.topbar-avatar .icon svg { width: 18px; height: 18px; }
.topbar-user-info { text-align: right; line-height: 1.25; min-width: 0; }
.topbar-user-name, .topbar-user-role {
  max-width: 220px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.topbar-user-name { font-size: .88rem; font-weight: 700; }
.topbar-user-role { font-size: .76rem; color: var(--text-soft); text-transform: capitalize; }

/* One color per role, so who's logged in as what is visible at a glance —
   the avatar tile goes solid, the role label under the name matches it.
   Deliberately a separate palette from the dashboard's blue/green/amber/red
   (those mean stock states; this means "who"), so the two never get
   confused for each other. */
.topbar-avatar.role-owner   { background: #4f46e5; color: #fff; }
.topbar-avatar.role-sales   { background: #0d9488; color: #fff; }
.topbar-avatar.role-cashier { background: #e11d48; color: #fff; }
.topbar-user-role.role-owner   { color: #4f46e5; }
.topbar-user-role.role-sales   { color: #0d9488; }
.topbar-user-role.role-cashier { color: #e11d48; }

@media (min-width: 960px) {
  .sidebar { position: static; transform: none; }
  .sidebar-backdrop { display: none !important; }
  .sidebar-toggle-btn { display: none; }
}
@media (max-width: 959px) {
  .sidebar-close-btn { display: block; }
}
/* Narrow screens: give the search box its own full-width row rather than
   squeezing it down to a sliver next to the user info + logout button. */
@media (max-width: 640px) {
  .topbar-search { order: 3; flex: 1 1 100%; max-width: none; }
  .topbar-user-name, .topbar-user-role { max-width: 130px; }
  .topbar-date { display: none; }
}

/* ---- app footer ---- */
.app-footer {
  text-align: center;
  color: var(--text-soft);
  font-size: .78rem;
  padding: 18px 16px 26px;
}
.app-footer-slogan::before { content: " · "; }

/* ---- views ---- */
/* Fills the space next to the sidebar rather than centering in a narrow
   column — a 1180px cap here was what forced the Products/Stock tables into
   horizontal scroll on ordinary desktop widths even though the page had
   plenty of unused width beyond the sidebar. Modest fixed padding instead of
   a max-width; the table itself still scrolls internally on small screens
   (see .table-wrap) rather than the page ever scrolling sideways. */
#app-content { padding: 24px 28px 32px; width: 100%; }
.view-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  margin-bottom: 16px;
}
.view-head-tools {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  margin-left: auto;
}
.view-head-tools .control { width: auto; min-width: 150px; }
.section-title { margin: 18px 0 8px; }
.stack { display: flex; flex-direction: column; gap: 4px; }
.row-gap { margin: 10px 0; }
.form-actions { margin-top: 16px; }
.muted { color: var(--text-soft); font-size: .87rem; margin: 10px 0 0; }

/* ---- stock summary line ---- */
.stock-summary {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  row-gap: 4px;
  margin: 0 0 14px;
  font-size: .9rem;
  color: var(--text-soft);
}
.stock-summary-sep { color: var(--border); }
.stock-summary-low {
  font: inherit;
  background: none;
  border: none;
  padding: 2px 8px;
  margin: -2px 0;
  color: var(--warn);
  text-decoration: underline;
  text-underline-offset: 2px;
  border-radius: 999px;
  cursor: pointer;
}
.stock-summary-low:hover { background: var(--warn-bg); text-decoration: none; }
.stock-summary-low.is-active { background: var(--warn-bg); text-decoration: none; }

/* ---- generic card ---- */
.card {
  background: var(--surface);
  border: none;
  box-shadow: var(--card-shadow);
  border-radius: var(--radius-lg);
  padding: 18px;
}
.card-head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 4px;
}
.card-head h2 { flex: 1; }
.card-link {
  font-size: .82rem;
  color: var(--stat-blue);
  text-decoration: none;
  white-space: nowrap;
  display: inline-flex;
  align-items: center;
  gap: 3px;
}
.card-link:hover { text-decoration: underline; }
.card-link-arrow svg { width: 14px; height: 14px; }

/* ---- dashboard ---- */
.dashboard-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 8px 16px;
  margin-bottom: 20px;
}
.dashboard-head-text h1 { font-size: 1.6rem; }
.dashboard-head-text p { margin: 4px 0 0; color: var(--text-soft); }
.dashboard-date { margin-left: auto; color: var(--text-soft); font-size: .88rem; }

/* 1 column by default (mobile), 2 from tablet width, 4 from desktop width —
   explicit breakpoints rather than auto-fit, so the count is exactly 4/2/1
   and never an in-between number on an odd container width. */
.stat-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 14px;
  margin-bottom: 18px;
}
@media (min-width: 640px) {
  .stat-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1024px) {
  .stat-grid { grid-template-columns: repeat(4, 1fr); }
}
.stat-card {
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: var(--card-shadow);
  border-radius: var(--radius-lg);
  padding: 20px;
  display: flex;
  align-items: center;
  gap: 14px;
}
/* A faint (~5%) tint of the card's own color behind everything, layered
   under the fully opaque icon tile and text — not a solid color fill. */
.stat-card-blue  { background-color: rgba(37, 99, 235, .05); }
.stat-card-green { background-color: rgba(22, 163, 74, .05); }
.stat-card-amber { background-color: rgba(245, 158, 11, .05); }
.stat-card-red   { background-color: rgba(220, 38, 38, .05); }

.stat-icon {
  flex-shrink: 0;
  width: 56px;
  height: 56px;
  border-radius: var(--radius-lg);
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
}
.stat-icon .icon svg { width: 26px; height: 26px; }
.stat-icon-blue  { background: var(--dash-blue); }
.stat-icon-green { background: var(--dash-green); }
.stat-icon-amber { background: var(--dash-amber); }
.stat-icon-red   { background: var(--dash-red); }
.stat-label {
  font-size: 13px;
  font-weight: 500;
  color: var(--text-soft);
  margin-bottom: 4px;
}
.stat-value { font-size: 30px; font-weight: 700; color: var(--text); line-height: 1.1; }

.dashboard-actions { display: flex; flex-wrap: wrap; gap: 12px; margin-bottom: 20px; }
.dashboard-actions .btn {
  flex: 1 1 0;
  min-width: 160px;
  padding: 16px 20px;
  border-radius: 10px;
  display: flex; align-items: center; justify-content: center; gap: 8px;
  font-weight: 600;
  font-size: 1rem;
}
.dashboard-actions .icon svg { width: 1.3em; height: 1.3em; }
/* A long label ("− Stock Out (not a sale)") wraps onto two lines on a
   phone instead of being cut off; "(not a sale)" stays together. */
.dashboard-actions .btn-label { white-space: normal; text-align: center; line-height: 1.2; min-width: 0; }
.nowrap { white-space: nowrap; }
.dashboard-actions > .btn { align-self: stretch; }
@media (max-width: 640px) {
  .dashboard-actions { flex-direction: column; }
  .dashboard-actions .btn { width: 100%; }
}

.dashboard-grid-2 {
  display: grid;
  grid-template-columns: 1fr;
  gap: 16px;
  margin-bottom: 16px;
}
/* Grid items default to min-width:auto, so the Recent Transactions card
   (which wraps a wide, nowrap .tx-table) would otherwise force this whole
   grid — and the page — wider than the viewport instead of letting
   .table-wrap's overflow-x:auto do its job. */
.dashboard-grid-2 > .card { min-width: 0; }
@media (min-width: 860px) {
  .dashboard-grid-2 { grid-template-columns: 1fr 1fr; }
}

.lowstock-list { display: flex; flex-direction: column; margin-top: 6px; }
.lowstock-row {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 0; border-bottom: 1px solid var(--border);
  font-size: .87rem;
}
.lowstock-row:last-child { border-bottom: none; }
.lowstock-main { flex: 1; min-width: 0; }
.lowstock-title { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lowstock-row { cursor: pointer; background: none; border: none; width: 100%; text-align: left; font: inherit; color: inherit; }
.lowstock-row:hover { background: var(--surface-2); border-radius: var(--radius); }
.lowstock-level { font-size: .78rem; color: var(--text-soft); white-space: nowrap; }
.reorder-card { border: 2px solid var(--dash-red); background: rgba(220, 38, 38, .04); margin-bottom: 16px; }
.reorder-card h2 { color: var(--dash-red); }
.reorder-qty { color: var(--dash-red); font-weight: 700; white-space: nowrap; font-variant-numeric: tabular-nums; }

/* ---- Recent Transactions table (Dashboard) ---- */
table.tx-table { border-collapse: collapse; width: 100%; font-size: .88rem; }
table.tx-table thead th {
  background: var(--surface-2);
  text-align: left;
  padding: 10px 14px;
  font-size: .72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--text-soft);
  white-space: nowrap;
}
table.tx-table tbody td {
  background: var(--surface);
  padding: 12px 14px;
  border-bottom: 1px solid var(--border);
  vertical-align: top;
  white-space: nowrap;
}
table.tx-table tbody tr:last-child td { border-bottom: none; }
table.tx-table tbody tr:hover td { background: var(--bg); }
table.tx-table td.num, table.tx-table th.num { text-align: right; font-variant-numeric: tabular-nums; }
.tx-sku { font-size: .76rem; color: var(--text-soft); margin-top: 2px; }


/* ---- form grid (modals + stock-in header) ---- */
.form-grid { display: grid; grid-template-columns: 1fr; gap: 4px 16px; }
@media (min-width: 620px) {
  .form-grid { grid-template-columns: 1fr 1fr; }
}
/* A control paired with a small button on the same line (e.g. a picker plus
   its "+ New" quick-add) inside a .field. */
.inline-row { display: flex; align-items: center; gap: 8px; }
.inline-row .control { flex: 1; min-width: 0; }

/* ---- tables ---- */
/* No border/background of its own — .table-wrap is always nested inside a
   .card now, which already provides the white background, radius, and
   shadow. It just needs to own the horizontal scroll. */
.table-wrap {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}
table.grid { border-collapse: collapse; width: 100%; font-size: .88rem; }
table.grid th, table.grid td {
  text-align: left;
  padding: 6px 10px;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
table.grid thead th {
  background: var(--surface-2);
  position: sticky;
  top: 0;
  font-size: .78rem;
  text-transform: uppercase;
  letter-spacing: .4px;
  color: var(--text-soft);
}
table.grid tbody tr:last-child td { border-bottom: none; }
table.grid td.num, table.grid th.num { text-align: right; font-variant-numeric: tabular-nums; }
table.grid td.neg { color: var(--danger); }
td.empty, .empty { text-align: center; color: var(--text-soft); padding: 22px; }
.row-inactive { opacity: .55; }

table.lines td { white-space: normal; vertical-align: top; }
table.lines .control { min-width: 110px; }
table.lines td[data-label="Serials"] .control { min-width: 180px; }

/* Daily work screens keep long product descriptions inside the viewport. */
.back-link { display: inline-block; margin-bottom: 14px; }
.stock-filters, .history-filters { display: grid; gap: 14px; margin-bottom: 20px; }
.stock-filters { grid-template-columns: minmax(0, 1fr) minmax(180px, 240px); }
.history-filters { grid-template-columns: repeat(2, minmax(0, 1fr)) minmax(150px, 1fr) minmax(0, 2fr); }
.stock-filters .field, .history-filters .field { min-width: 0; }
.work-pagination { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 12px; margin-top: 18px; }
.work-pagination span { font-size: .85rem; color: var(--text-soft); }
.stock-notice { background: var(--warn-bg); color: var(--text); border-left: 3px solid var(--warn); padding: 12px 16px; margin-bottom: 18px; }
.activity-sku { font-size: .78rem; color: var(--text-soft); margin: 4px 0; }
table.work-table { table-layout: fixed; background: var(--surface); }
table.work-table th, table.work-table td { white-space: normal; overflow-wrap: anywhere; padding: 14px 12px; vertical-align: top; }
table.work-table th { letter-spacing: 0; }
table.work-table .pill { display: inline-block; margin: 2px 4px 2px 0; white-space: normal; }
.stock-work-table th:nth-child(1) { width: 40%; }
.stock-work-table th:nth-child(2) { width: 27%; }
.stock-work-table th:nth-child(3) { width: 15%; }
.activity-table th:nth-child(1) { width: 17%; }
.activity-table th:nth-child(2) { width: 32%; }
.activity-table th:nth-child(3) { width: 9%; }
.activity-table th:nth-child(4) { width: 13%; }
.dashboard-actions { align-items: start; }
.dashboard-actions > .btn, .return-action { flex: 1 1 0; min-width: 0; }
.dashboard-actions .btn { min-width: 0; min-height: 54px; padding: 14px 16px; border-radius: 8px; text-decoration: none; }
.return-action .btn { width: 100%; }
.return-action small { display: block; margin-top: 5px; text-align: center; color: var(--text-soft); }
.return-action button:disabled { cursor: not-allowed; opacity: .6; }
#view-dashboard .stat-card { min-width: 0; padding: 18px 14px; gap: 10px; }
#view-dashboard .stat-icon { width: 40px; height: 40px; border-radius: 8px; }
.stat-copy { min-width: 0; }
#view-dashboard .stat-value { font-size: 24px; overflow-wrap: anywhere; }
#view-dashboard .card-head { margin-top: 28px; }
#view-dashboard .reorder-card .card-head { margin-top: 0; }
@media (max-width: 1100px) { .history-filters { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 640px) {
  #app-content { padding: 20px 16px; }
  .stock-filters, .history-filters { grid-template-columns: minmax(0, 1fr); }
  .dashboard-actions { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
  .dashboard-actions .btn { font-size: .88rem; padding: 12px 8px; }
  table.work-table, table.work-table tbody { display: block; }
  table.work-table thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  table.work-table tbody tr { display: block; border-bottom: 1px solid var(--border); padding: 12px; }
  table.work-table tbody td, table.work-table tbody tr:last-child td { display: grid; grid-template-columns: 80px minmax(0, 1fr); gap: 6px 10px; padding: 6px 0; border: 0; text-align: left; }
  table.work-table td[data-label]::before { content: attr(data-label); font-weight: 600; color: var(--text-soft); grid-column: 1; grid-row: 1; }
  table.work-table td > * { grid-column: 2; }
  table.work-table td .pill { justify-self: start; }
  table.work-table td.num { text-align: left; }
  table.work-table td.empty { display: block; }
  .work-pagination { justify-content: center; }
}

/* ---- Products: quick inline sell-price edit ---- */
.price-cell-btn {
  display: block;
  width: 100%;
  text-align: right;
  background: none;
  border: none;
  padding: 2px 4px;
  margin: -2px -4px;
  font: inherit;
  font-variant-numeric: tabular-nums;
  color: var(--text);
  cursor: pointer;
  border-radius: 4px;
}
.price-cell-btn:hover, .price-cell-btn:focus-visible {
  background: var(--bg);
  outline: none;
}
.price-cell-input { width: 100px; padding: 4px 6px; text-align: right; }

/* ---- flexible columns (Products, Stock) ----
   Every other column keeps the default white-space:nowrap above (sized to
   its own short content); Name/Category opt out so they wrap and soak up
   whatever width is left, instead of forcing the table wider than the page. */
table.grid td.wrap, table.grid th.wrap {
  white-space: normal;
  min-width: 160px;
}

/* ---- pills / tags ---- */
#view-products { container-type: inline-size; }
table.products-grid { table-layout: fixed; }
table.products-grid th, table.products-grid td {
  white-space: normal;
  overflow-wrap: anywhere;
  vertical-align: top;
  padding: 12px 8px;
}
table.products-grid th:nth-child(1) { width: 30%; }
table.products-grid th:nth-child(2) { width: 23%; }
table.products-grid th:nth-child(3) { width: 9%; }
table.products-grid th:nth-child(4) { width: 17%; }
table.products-grid th:nth-child(5) { width: 13%; }
table.products-grid th:nth-child(6) { width: 8%; }
.product-name { display: block; margin-bottom: 6px; }
.product-detail { margin-bottom: 4px; }
.product-sell { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; }
.product-price-editor { min-width: 0; max-width: 100%; }
.products-grid .price-cell-btn { margin: 0; text-align: left; overflow-wrap: anywhere; }
.products-grid .price-cell-input { max-width: 100%; }
.products-grid .btn { max-width: 100%; white-space: normal; }
@container (max-width: 850px) {
  table.products-grid, table.products-grid tbody { display: block; }
  table.products-grid thead {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
  }
  table.products-grid tbody tr { display: block; padding: 12px 0; border-bottom: 1px solid var(--border); }
  table.products-grid tbody td { display: block; border: 0; padding: 5px 0; }
  table.products-grid td[data-label]::before {
    content: attr(data-label);
    display: block;
    font-weight: 600;
    color: var(--text-soft);
    margin-bottom: 3px;
  }
  #view-products .view-head-tools { min-width: 0; flex-wrap: wrap; }
  #view-products .view-head-tools .control { min-width: 0; max-width: 100%; }
}

/* ---- pills / tags ---- */
.pill {
  font-size: .74rem;
  padding: 2px 8px;
  border-radius: 999px;
  border: 1px solid var(--border);
}
.pill-on { background: var(--ok-bg); color: var(--ok); border-color: var(--ok); }
.pill-off { background: var(--surface-2); color: var(--text-soft); }
.pill-green { background: var(--ok-bg); color: var(--ok); border-color: var(--ok); }
.pill-red   { background: var(--danger-bg); color: var(--danger); border-color: var(--danger); }
.pill-amber { background: var(--warn-bg); color: var(--warn); border-color: var(--warn); }
.tag {
  display: inline-block;
  margin-left: 6px;
  font-size: .7rem;
  padding: 1px 6px;
  border-radius: 4px;
  background: var(--surface-2);
  color: var(--text-soft);
}
.tag-warn { background: var(--warn-bg); color: var(--warn); }

/* ---- toasts ---- */
#toast-container {
  position: fixed;
  left: 50%;
  bottom: 18px;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  gap: 8px;
  z-index: 60;
  width: min(94vw, 460px);
}
.toast {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 11px 12px;
  border-radius: var(--radius);
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: 0 6px 20px rgba(0,0,0,.18);
  font-size: .9rem;
  animation: toast-in .18s ease-out;
}
.toast-leaving { opacity: 0; transition: opacity .2s; }
.toast-msg { flex: 1; }
.toast-x {
  background: none; border: none; font-size: 1.1rem; line-height: 1;
  cursor: pointer; color: var(--text-soft);
}
.toast-success { border-left: 4px solid var(--ok); }
.toast-error { border-left: 4px solid var(--danger); }
.toast-info { border-left: 4px solid var(--navy); }
@keyframes toast-in { from { transform: translateY(8px); opacity: 0; } }

/* ---- modal ---- */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(10,16,22,.5);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 24px 14px;
  overflow-y: auto;
  z-index: 50;
}
.modal {
  background: var(--surface);
  border-radius: var(--radius);
  border: 1px solid var(--border);
  width: 100%;
  max-width: 440px;
  margin-top: 4vh;
}
.modal-wide { max-width: 680px; }
.modal-head { padding: 16px 18px; border-bottom: 1px solid var(--border); }
.modal-title { font-size: 1.05rem; }
.modal-form { padding: 16px 18px 18px; }
.modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 16px;
}

/* ---- scan screen ---- */
.scan-search-row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 12px;
}
.scan-search-row .field { flex: 1; min-width: 220px; margin-bottom: 0; }
.scan-camera {
  margin-top: 14px;
  border-radius: var(--radius);
  overflow: hidden;
  background: #000;
  max-width: 420px;
}
.scan-video { display: block; width: 100%; max-height: 320px; object-fit: cover; }
.scan-html5-region { width: 100%; }
.scan-result { margin-top: 16px; }
.scan-not-found {
  padding: 14px 16px;
  border-radius: var(--radius);
  background: var(--warn-bg);
  color: var(--warn);
}
.scan-card-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 8px 16px;
  margin: 10px 0 16px;
}
.scan-card-row {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 8px 0;
  border-bottom: 1px solid var(--border);
}
.scan-card-label { color: var(--text-soft); font-size: .87rem; }
.scan-card-value { font-weight: 600; text-align: right; }
@media (min-width: 640px) {
  .scan-card-grid { grid-template-columns: 1fr 1fr; }
}

/* ---- misc ---- */
[hidden] { display: none !important; }

/* ---- Sales History (js/sales-list.js) ---- */
.view-sub { margin: 2px 0 0; color: var(--text-soft); font-size: .88rem; }
.period-bar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px 16px; margin-bottom: 16px; }
.period-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.chip {
  font: inherit; font-size: .84rem; padding: 7px 13px; border-radius: 999px;
  border: 1px solid var(--border); background: var(--surface); color: var(--text);
  white-space: nowrap; cursor: pointer;
}
.chip:hover { background: var(--surface-2); }
.chip.is-active { background: var(--navy); border-color: var(--navy); color: #fff; }
.period-range { display: flex; align-items: center; gap: 6px; font-size: .84rem; color: var(--text-soft); }
.period-range .control { width: auto; padding: 6px 8px; }
.sales-stats .stat-card { min-width: 0; padding: 16px 14px; gap: 10px; }
.sales-stats .stat-icon { width: 40px; height: 40px; border-radius: 8px; }
.sales-stats .stat-icon .icon svg { width: 22px; height: 22px; }
.sales-stats .stat-value { font-size: 19px; overflow-wrap: anywhere; font-variant-numeric: tabular-nums; }
.stat-sub { font-size: .76rem; color: var(--text-soft); margin-top: 2px; }
.sales-filter-bar { display: grid; grid-template-columns: minmax(0, 2.2fr) minmax(0, 3fr); gap: 14px; align-items: end; margin-bottom: 18px; }
.sales-filter-bar > .field { margin-bottom: 0; }
.sales-filters { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 14px; }
.sales-filters .field { margin-bottom: 0; min-width: 0; }
.sales-filters .sheet-head, .sales-filters .sheet-actions, .filter-toggle, .sheet-backdrop { display: none; }
.filter-count {
  display: inline-grid; place-items: center; min-width: 18px; height: 18px; margin-left: 6px; padding: 0 5px;
  border-radius: 999px; background: var(--stat-blue); color: #fff; font-size: .7rem; font-weight: 700;
}
.sales-table-card { padding: 0; overflow: hidden; }
table.sales-table { table-layout: fixed; font-size: .9rem; }
table.sales-table th, table.sales-table td { white-space: normal; overflow-wrap: anywhere; padding: 12px; vertical-align: top; }
table.sales-table th:nth-child(1) { width: 13%; }
table.sales-table th:nth-child(2) { width: 15%; }
table.sales-table th:nth-child(3) { width: 21%; }
table.sales-table th:nth-child(4) { width: 6%; }
table.sales-table th:nth-child(8) { width: 11%; }
table.sales-table td.num { white-space: nowrap; }
.view-head-tools .btn { display: inline-flex; align-items: center; gap: 6px; text-decoration: none; }
table.sales-table tbody tr.is-clickable { cursor: pointer; }
table.sales-table tbody tr.is-clickable:hover td,
table.sales-table tbody tr.is-clickable:focus-visible td { background: #f5f8fc; }
table.sales-table tbody tr.is-clickable:focus-visible { outline: 2px solid var(--navy); outline-offset: -2px; }
table.sales-table tfoot td { background: var(--surface-2); font-weight: 700; border-top: 2px solid var(--border); font-variant-numeric: tabular-nums; }
.sale-number { font-weight: 600; color: var(--navy); }
.sub { display: block; font-size: .76rem; color: var(--text-soft); }
.sub-text { color: var(--text-soft); }
.bal-due { color: var(--danger); }
.bal-refund { color: var(--warn); }
.bal-settled { color: var(--text-soft); }
.sales-cards { display: none; }

/* Sale detail as a right-hand side panel (ui.openModal size "drawer"). */
.modal-overlay-drawer { padding: 0; justify-content: flex-end; align-items: stretch; overflow: hidden; }
.modal-drawer {
  max-width: 540px; margin: 0; border-radius: 0; border: 0; height: 100%;
  display: flex; flex-direction: column; box-shadow: -10px 0 30px rgba(0, 0, 0, .15);
}
.modal-drawer .modal-form { flex: 1; overflow-y: auto; }
.sale-detail { display: flex; flex-direction: column; gap: 14px; }
.sale-detail-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: -4px; }
.sale-facts { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 18px; margin: 0; font-size: .88rem; }
.sale-facts dt { font-size: .76rem; font-weight: 600; color: var(--text-soft); }
.sale-facts dd { margin: 0; overflow-wrap: anywhere; }
.sale-money { display: grid; grid-template-columns: repeat(auto-fit, minmax(100px, 1fr)); gap: 1px; background: var(--border); border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; }
.sale-money > div { padding: 9px 10px; background: var(--surface); }
.sale-money small { display: block; font-size: .72rem; font-weight: 600; color: var(--text-soft); }
.sale-money b { font-size: .92rem; font-variant-numeric: tabular-nums; }
.sale-subhead { margin: 4px 0 -6px; font-size: .78rem; text-transform: uppercase; letter-spacing: .5px; color: var(--text-soft); }
table.sale-lines { width: 100%; border-collapse: collapse; font-size: .86rem; }
table.sale-lines td { padding: 8px 0; border-bottom: 1px solid var(--border); vertical-align: top; }
table.sale-lines td.num { text-align: right; white-space: nowrap; padding-left: 10px; font-variant-numeric: tabular-nums; }
table.sale-lines tr.sale-lines-total td { border-bottom: 0; font-weight: 700; }
table.sale-lines tr.sale-lines-total td.sub-text { font-weight: 400; font-size: .8rem; }
.serial-list { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 4px; }
.serial { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: .74rem; background: var(--surface-2); border-radius: 4px; padding: 1px 6px; }
.serial.is-returned { text-decoration: line-through; color: var(--warn); background: var(--warn-bg); }
.sale-timeline { list-style: none; margin: 0; padding: 0; font-size: .86rem; }
.sale-timeline li { display: grid; grid-template-columns: 12px minmax(0, 1fr) auto; gap: 10px; padding: 7px 0; position: relative; }
.sale-timeline li::before { content: ""; width: 10px; height: 10px; border-radius: 50%; margin-top: 5px; background: var(--dot, var(--border)); }
.sale-timeline li:not(:last-child)::after { content: ""; position: absolute; left: 4.5px; top: 20px; bottom: -6px; width: 1px; background: var(--border); }
.sale-timeline li.is-payment { --dot: var(--dash-green); }
.sale-timeline li.is-return { --dot: var(--dash-amber); }
.sale-timeline li.is-refund { --dot: var(--dash-red); }
.sale-timeline .amount { font-weight: 600; white-space: nowrap; font-variant-numeric: tabular-nums; }
.sale-actions { display: flex; flex-wrap: wrap; gap: 8px; padding-top: 12px; border-top: 1px solid var(--border); }
.sale-actions .btn:last-child { margin-left: auto; }

@media (max-width: 900px) {
  .sales-filter-bar { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 640px) {
  .period-bar { flex-wrap: nowrap; flex-direction: column; align-items: stretch; }
  .period-chips { flex-wrap: nowrap; overflow-x: auto; margin-right: -16px; padding-right: 16px; scrollbar-width: none; }
  .sales-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
  .sales-stats .stat-card { padding: 10px; gap: 8px; }
  .sales-stats .stat-icon { width: 30px; height: 30px; }
  .sales-stats .stat-icon .icon svg { width: 16px; height: 16px; }
  .sales-stats .stat-label { font-size: 11px; margin-bottom: 0; }
  .sales-stats .stat-value { font-size: 14.5px; }
  .sales-stats .stat-sub { display: none; }
  .sales-filter-bar { grid-template-columns: minmax(0, 1fr) auto; gap: 8px; }
  .filter-toggle { display: inline-flex; align-items: center; }
  .sheet-backdrop { display: block; position: fixed; inset: 0; background: rgba(10, 16, 22, .45); z-index: 44; }
  .sheet-backdrop[hidden] { display: none; }
  .sales-filters {
    display: none; position: fixed; left: 0; right: 0; bottom: 0; z-index: 45;
    grid-template-columns: minmax(0, 1fr); gap: 12px;
    background: var(--surface); border-radius: 18px 18px 0 0; padding: 18px 16px calc(18px + env(safe-area-inset-bottom, 0px));
    box-shadow: 0 -8px 30px rgba(0, 0, 0, .2);
  }
  .sales-filters.is-open { display: grid; }
  .sales-filters .sheet-head { display: block; }
  .sales-filters .sheet-actions { display: grid; grid-template-columns: 1fr 2fr; gap: 8px; }
  .sales-table-card { display: none; }
  .sales-cards { display: flex; flex-direction: column; gap: 8px; }
  p.sales-cards { display: block; }
  .sale-card {
    font: inherit; text-align: left; color: var(--text); cursor: pointer; width: 100%;
    background: var(--surface); border: 1px solid var(--border); border-radius: 10px;
    padding: 11px 12px; display: flex; flex-direction: column; gap: 4px;
  }
  .sale-card-row { display: flex; justify-content: space-between; align-items: center; gap: 8px; }
  .sale-card-customer { font-weight: 600; }
  .sale-card-money { display: flex; justify-content: space-between; font-size: .8rem; color: var(--text-soft); border-top: 1px dashed var(--border); padding-top: 6px; margin-top: 2px; }
  .sale-card-money > span:last-child { text-align: right; }
  .sale-card-money b { display: block; font-size: .88rem; color: var(--text); font-variant-numeric: tabular-nums; }
  .sale-card-money b.bal-due { color: var(--danger); }
  .sale-card-money b.bal-refund { color: var(--warn); }
  .modal-drawer { max-width: none; }
  .sale-facts { grid-template-columns: minmax(0, 1fr); }
  .sale-money { grid-template-columns: 1fr 1fr; }
  .sale-actions { position: sticky; bottom: -18px; background: var(--surface); margin: 0 -18px -18px; padding: 10px 18px 14px; }
  .sale-actions .btn { flex: 1 1 40%; }
  .sale-actions .btn:last-child { margin-left: 0; }
}

/* ---- Customers: detail stat row (same compact sizing as the dashboard's) ---- */
.customer-stats .stat-card { min-width: 0; padding: 18px 14px; gap: 10px; }
.customer-stats .stat-icon { width: 40px; height: 40px; border-radius: 8px; }
.customer-stats .stat-value { font-size: 22px; overflow-wrap: anywhere; }
.doc-btn { margin-left: 6px; padding: 2px 8px; font-size: .74rem; min-height: 0; vertical-align: middle; }

/* ---- Credit limit + aging (22_credit_limit.sql, js/aging.js) ---- */
.stack-tight { display: flex; flex-direction: column; gap: 4px; }
.field-hint.credit-over { color: var(--dash-red); font-weight: 600; }
.aging-over { color: var(--dash-red); font-weight: 700; }
.aging-near { color: var(--warn); font-weight: 700; }
.aging-table tr.clickable { cursor: pointer; }
.report-table tr.report-total td { font-weight: 700; background: var(--surface-2); }

/* ---- Alternative parts on the Scan card (25_part_compatibility.sql) ---- */
.scan-alts { margin: 12px 0; padding: 10px 12px; border-radius: var(--radius); background: var(--surface-2); }
.scan-alts h3 { margin: 0 0 4px; font-size: .9rem; }
.scan-alts-out { border: 2px solid var(--dash-red); background: rgba(220, 38, 38, .04); }
.scan-alts-out h3 { color: var(--dash-red); }
.alt-qty { color: var(--dash-green); font-weight: 700; white-space: nowrap; }

/* ---- Expiry warnings (js/expiry.js) ---- */
.expiry-card { border: 2px solid var(--dash-amber); background: rgba(245, 158, 11, .05); margin-bottom: 16px; }
#view-dashboard .expiry-card .card-head { margin-top: 0; }
.expiry-soon { color: var(--warn); font-weight: 700; white-space: nowrap; }


/* ==========================================================================
   Visual polish layer (2026-09) — kept as one block at the end of the file
   so it layers over the rules above without rewriting them. Everything here
   is presentation only: no layout a screen's JS depends on changes.
   ========================================================================== */

/* Amharic (Ethiopic script) — customer names, addresses and notes are often
   typed in Amharic. These fonts ship with the OS (Nyala on Windows, Kefa on
   macOS/iOS, Noto Sans Ethiopic on Android/Linux), so nothing is downloaded:
   the Latin fonts above still render English, and the browser falls through
   to one of these only for Ethiopic characters. */
:root {
  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial,
          "Noto Sans Ethiopic", "Nyala", "Kefa", "Abyssinica SIL", "Ebrima", sans-serif;
  --focus-ring: 0 0 0 3px rgba(47, 111, 237, .25);
  --card-shadow: 0 1px 3px rgba(15, 23, 42, .07), 0 1px 2px rgba(15, 23, 42, .04);
}
body { -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; }
h1 { font-size: 1.45rem; font-weight: 700; letter-spacing: -.01em; }
h2 { font-weight: 700; }

/* ---- buttons: clearer weight, press feedback, visible keyboard focus ---- */
.btn {
  font-weight: 500;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  transition: background-color .15s ease, border-color .15s ease, box-shadow .15s ease, transform .05s ease;
}
.btn:not(:disabled):active { transform: translateY(1px); }
.btn:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.btn:not(.btn-primary):not(.btn-green):not(.btn-blue):not(.btn-red):not(.btn-ghost):hover { border-color: #b8c4d0; }
.btn-primary, .btn-green, .btn-blue, .btn-red { font-weight: 600; }
.btn-block, .btn-block.btn { display: flex; }

/* ---- form controls: soft focus ring instead of a hard outline ---- */
.control { transition: border-color .15s ease, box-shadow .15s ease; min-height: 42px; }
.control:hover:not(:focus):not(:disabled) { border-color: #b8c4d0; }
.control:focus { outline: none; border-color: var(--stat-blue); box-shadow: var(--focus-ring); }
.control:disabled { background: var(--surface-2); color: var(--text-soft); }
.control::placeholder { color: #94a3b8; }
textarea.control { min-height: 42px; }
.field-label { color: #475569; }

/* ---- "Back to …" links read as navigation, not a raw blue hyperlink ---- */
.back-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--text-soft);
  font-size: .88rem;
  font-weight: 500;
  text-decoration: none;
  padding: 6px 10px 6px 6px;
  margin: -6px 0 12px -6px;
  border-radius: var(--radius);
}
.back-link::before { content: "\2190"; font-size: 1.05em; line-height: 1; }
.back-link:hover { color: var(--navy); background: var(--surface-2); }

/* ---- tables ---- */
table.grid tbody tr { transition: background-color .1s ease; }
table.grid tbody tr:hover td { background: #f8fafc; }
table.grid thead th { font-weight: 700; }
/* A work table sitting straight on the page (Stock, History, Customers …)
   gets the same rounded white "card" look the dashboard cards have. Inside
   a .card it stays flat, since the card already provides that. */
table.work-table {
  border-collapse: separate;
  border-spacing: 0;
  border-radius: var(--radius-lg);
  box-shadow: var(--card-shadow);
  overflow: hidden;
}
.card table.work-table, .table-wrap table.work-table { box-shadow: none; border-radius: 0; }
.pill { font-weight: 600; white-space: nowrap; }

/* ---- cards, modals, toasts ---- */
.card { border: 1px solid rgba(213, 221, 229, .6); }
.modal { border-radius: var(--radius-lg); box-shadow: 0 20px 50px rgba(15, 23, 42, .25); overflow: hidden; }
.modal-head { background: #f8fafc; }
.toast { border-radius: var(--radius-lg); }

/* ---- sidebar: active item gets a small amber edge (KI's brand colour) ---- */
.sidebar-nav a { position: relative; transition: background-color .15s ease, color .15s ease; }
.sidebar-nav a.is-active { font-weight: 600; box-shadow: inset 3px 0 0 var(--amber); }
.sidebar-nav a:focus-visible { outline: 2px solid var(--amber); outline-offset: -2px; }

/* ---- topbar ---- */
.topbar { position: sticky; top: 0; z-index: 30; box-shadow: 0 1px 0 rgba(15, 23, 42, .02); }
.topbar-date {
  background: var(--surface-2);
  padding: 6px 12px;
  border-radius: 999px;
  font-weight: 500;
  color: #475569;
}

/* ---- login ---- */
.auth {
  background:
    radial-gradient(900px 420px at 50% 0%, rgba(11, 61, 99, .09), transparent 75%),
    var(--bg);
}
.auth-card {
  max-width: 400px;
  border-radius: 16px;
  border-color: rgba(213, 221, 229, .7);
  box-shadow: 0 10px 30px rgba(15, 23, 42, .08), 0 1px 3px rgba(15, 23, 42, .06);
  padding: 32px 28px 28px;
  border-top: 4px solid var(--amber);
}
.auth-card .btn-primary { min-height: 46px; font-size: 1rem; margin-top: 6px; }

/* ---- mobile ---- */
@media (max-width: 640px) {
  /* 16px inputs stop iPhone Safari from zooming the page on every tap into
     a field — the single most annoying thing on a phone-based POS. */
  .control, select.control, textarea.control { font-size: 16px; }
  h1 { font-size: 1.3rem; }
  .topbar { padding: 10px 12px; }

  /* Dashboard: odd last quick-action button fills the row instead of
     sitting alone at half width. */
  .dashboard-actions > :last-child:nth-child(odd) { grid-column: 1 / -1; }

  /* Dashboard stats: the money card on its own row, the three small counts
     side by side beneath it — a phone sees all four without scrolling. */
  #view-dashboard .stat-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
  #view-dashboard .stat-grid > .stat-card:first-child { grid-column: 1 / -1; }
  #view-dashboard .stat-grid > .stat-card:not(:first-child) {
    flex-direction: column;
    align-items: flex-start;
    padding: 12px;
    gap: 8px;
  }
  #view-dashboard .stat-grid > .stat-card:not(:first-child) .stat-icon { width: 32px; height: 32px; }
  #view-dashboard .stat-grid > .stat-card:not(:first-child) .stat-icon .icon svg { width: 18px; height: 18px; }
  #view-dashboard .stat-grid > .stat-card:not(:first-child) .stat-label { font-size: 12px; }
  #view-dashboard .stat-grid > .stat-card:not(:first-child) .stat-value { font-size: 20px; }

  table.work-table tbody tr:hover td { background: transparent; }

  /* Sell / Stock In line items: one card per line with the field names
     above each box, instead of a wide table the cashier has to scroll
     sideways to finish. The tds already carry data-label for this. */
  table.lines, table.lines tbody { display: block; }
  table.lines thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  table.lines tbody tr {
    display: block;
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: 12px;
    margin-bottom: 12px;
    background: #f8fafc;
  }
  table.lines tbody tr:hover td { background: transparent; }
  table.lines tbody td, table.lines tbody tr:last-child td { display: block; border: 0; padding: 0 0 10px; text-align: left; }
  table.lines tbody td:last-child { padding-bottom: 0; }
  table.lines td[data-label]::before {
    content: attr(data-label);
    display: block;
    font-size: .82rem;
    font-weight: 600;
    color: #475569;
    margin-bottom: 5px;
  }
  table.lines .control, table.lines td[data-label="Serials"] .control { min-width: 0; width: 100%; }
  .modal-overlay { padding: 12px 10px; }
  .modal { margin-top: 2vh; }
}

/* ---- dashboard charts (js/dashboard-charts.js) ---- */
.dashboard-grid-charts { display: grid; grid-template-columns: 1fr; gap: 16px; margin-bottom: 16px; }
.dashboard-grid-charts > .card { min-width: 0; }
@media (min-width: 960px) {
  .dashboard-grid-charts { grid-template-columns: 1.6fr 1fr; }
  .dashboard-grid-charts.dashboard-grid-single { grid-template-columns: minmax(0, 520px); }
}
#view-dashboard .chart-card .card-head { margin-top: 0; margin-bottom: 10px; flex-wrap: wrap; }
.chart-total { font-size: 1.35rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.chart-sub { color: var(--text-soft); font-size: .84rem; margin-bottom: 6px; }
.chart-empty {
  display: grid; place-items: center; text-align: center; min-height: 170px; padding: 12px;
  color: var(--text-soft); font-size: .88rem; border: 1px dashed var(--border); border-radius: 10px; background: var(--bg);
}
.chart-empty strong { display: block; color: var(--text); margin-bottom: 4px; }
.sales-chart { display: block; }
.sales-chart text, .donut-wrap svg text { font: 11px var(--font); fill: var(--text-soft); }
.sales-chart .chart-ec { font-size: 10px; }
.chart-grid { stroke: var(--surface-2); }
.chart-line { fill: none; stroke: var(--dash-blue); stroke-width: 2.5; stroke-linejoin: round; }
.chart-dot { fill: var(--dash-blue); stroke: #fff; stroke-width: 1.5; }
.chart-wrap { position: relative; }
.chart-overlay {
  position: absolute; left: 50%; top: 38%; transform: translate(-50%, -50%); max-width: 90%;
  background: rgba(255, 255, 255, .92); border: 1px solid var(--border); border-radius: 8px;
  padding: 8px 14px; text-align: center; font-size: .86rem; color: var(--text-soft);
}
.chart-overlay strong { display: block; color: var(--text); }
.range-toggle { display: inline-flex; border: 1px solid var(--border); border-radius: 8px; overflow: hidden; }
.range-toggle button { font: inherit; font-size: .8rem; border: 0; background: var(--surface); color: var(--text); padding: 4px 10px; cursor: pointer; }
.range-toggle button + button { border-left: 1px solid var(--border); }
.range-toggle button.is-active { background: var(--surface-2); font-weight: 700; }
.donut-wrap { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; }
.donut-wrap svg { flex: none; }
.donut-wrap .donut-total { font-size: 26px; font-weight: 700; fill: var(--text); }
.donut-slice { cursor: pointer; }
.donut-legend { flex: 1; min-width: 160px; }
.donut-legend-row {
  display: flex; align-items: center; gap: 8px; width: 100%; padding: 7px 6px; border: 0; background: none;
  font: inherit; color: inherit; text-align: left; cursor: pointer; border-radius: var(--radius);
}
.donut-legend-row:hover { background: var(--surface-2); }
.donut-legend-row i { width: 10px; height: 10px; border-radius: 50%; flex: none; }
.donut-legend-row span { flex: 1; }
.rank-list { display: flex; flex-direction: column; }
.rank-row {
  display: flex; align-items: center; gap: 12px; padding: 10px 4px; border: 0; border-bottom: 1px solid var(--border);
  background: none; width: 100%; text-align: left; font: inherit; font-size: .87rem; color: inherit; text-decoration: none; cursor: pointer;
}
.rank-row:last-child { border-bottom: none; }
.rank-row:hover { background: var(--surface-2); border-radius: var(--radius); }
.rank-main { flex: 1; min-width: 0; }
.rank-no { width: 26px; height: 26px; border-radius: 6px; background: var(--surface-2); display: grid; place-items: center; font-weight: 700; flex: none; }
.rank-track { height: 6px; background: var(--surface-2); border-radius: 3px; margin-top: 5px; }
.rank-track i { display: block; height: 100%; background: var(--dash-blue); border-radius: 3px; }
.rank-amt { font-weight: 600; white-space: nowrap; text-align: right; font-variant-numeric: tabular-nums; }
.rank-amt .pill { margin-top: 3px; display: inline-block; }

/* ---- scan box (34_product_barcode.sql): Add Product, Stock In, Scan ---- */
.scanbox {
  display: grid;
  gap: 8px;
  padding: 12px;
  margin-bottom: 10px;
  border: 2px dashed #7aa7d6;
  border-radius: var(--radius);
  background: #eaf2fb;
}
.scanbox .scan-search-row .field { margin-bottom: 0; }
.scanbox .scan-search-row > .control { flex: 1; min-width: 0; }
.scanbox-label { font-weight: 600; font-size: .9rem; color: var(--navy); }
.scan-code { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; letter-spacing: .03em; }
.scanbox .scan-camera { margin-top: 0; }
.scanbox-status { padding: 8px 10px; border-radius: var(--radius); font-size: .87rem; }
.scanbox-ok { background: var(--ok-bg); color: var(--ok); }
.scanbox-warn { background: var(--warn-bg); color: var(--warn); }
.form-grid > .form-span { grid-column: 1 / -1; }
.scan-not-found p { margin: 0 0 8px; }
.scan-not-found .row-gap { margin-top: 4px; }
.link-barcode-list { height: auto; min-height: 180px; }
@keyframes line-flash { from { background: #fff3cf; } to { background: transparent; } }
tr.line-flash > td { animation: line-flash 1.6s ease-out; }
@media (prefers-reduced-motion: reduce) { tr.line-flash > td { animation: none; } }

/* ---- phone layout fixes (Sept 2026 iPhone screenshots) ---- */
/* Checkbox rows in forms (Add/Edit product, WHT): a bigger box lined up
   with the first line of its text, and no full field gap between rows. */
.inline-check input[type="checkbox"] {
  flex: none;
  width: 20px;
  height: 20px;
  margin: 1px 0 0;
  accent-color: var(--navy);
}
.field.inline-check { align-items: flex-start; gap: 10px; margin-bottom: 4px; padding: 8px 0; }
.modal-form .field.inline-check + .field:not(.inline-check) { margin-top: 10px; }

/* Keeps Save/Cancel in view at the bottom of a long form. `clip` (unlike
   hidden) doesn't make the modal a scroll box, so sticky works against the
   scrolling overlay; browsers without `clip` keep `hidden` and a normal row. */
.modal { overflow: hidden; overflow: clip; }

@media (max-width: 640px) {
  .modal-actions {
    position: sticky;
    bottom: 0;
    z-index: 1;
    margin: 16px -18px -18px;
    padding: 12px 18px calc(12px + env(safe-area-inset-bottom, 0px));
    background: var(--surface);
    border-top: 1px solid var(--border);
  }
  .modal-actions .btn { flex: 1 1 0; }
  /* The sale detail panel already pins its own action row (.sale-actions). */
  .modal-drawer .modal-actions { position: static; }

  /* Date under "Today" starts at the left edge instead of floating right. */
  .dashboard-date { margin-left: 0; flex-basis: 100%; }

  /* Page tools (Export CSV / New sale, Products search / Add) use the full
     width instead of hugging the right edge. */
  .view-head-tools { margin-left: 0; width: 100%; }
  .view-head-tools > .control { flex: 1 1 100%; min-width: 0; }
  .view-head-tools > .btn { flex: 1 1 0; }
  .view-head-tools > .inline-check { flex: none; }

  /* Sales History period chips wrap onto a second row rather than running
     off the right edge. */
  .period-chips { flex-wrap: wrap; overflow: visible; margin-right: 0; padding-right: 0; }

  /* Search + Status on Stock/History: the fields already carry a bottom
     margin, so no extra grid gap on top of it. */
  .stock-filters, .history-filters { gap: 0; margin-bottom: 14px; }

  /* "No customers yet." spans the card instead of wrapping in the label column. */
  table.work-table tbody td.empty,
  table.work-table tbody tr:last-child td.empty { display: block; text-align: center; padding: 18px 0; }
}
/* Checkbox + label outside a .field (Products "Show inactive", Users "Active"). */
label.inline-check:not(.field) { display: inline-flex; align-items: center; gap: 8px; }
label.inline-check:not(.field) input[type="checkbox"] { margin: 0; }
/* Products: "Sell:" lines up with its price (.muted's top margin pushed it
   down), and the first product card doesn't start with a double gap. */
.product-sell .muted { margin: 0; }
@container (max-width: 850px) {
  table.products-grid tbody tr:first-child { padding-top: 0; }
}

/* ---- phone layout fixes, part 2 (Sell, Stock In, Reports, Aging, History) ---- */
@media (max-width: 640px) {
  /* Customer picker + "+ New customer": the button drops under the picker
     instead of squeezing it to "— walk-in / no cus". */
  .inline-row { flex-wrap: wrap; }
  .inline-row > .control { flex: 1 1 180px; }
  table.lines .inline-row > .control { flex-basis: 0; }

  /* Scan box (Stock In, Add product): the code field gets the full row so
     its placeholder isn't cut off; Use camera goes under it. */
  .scanbox .scan-search-row { flex-wrap: wrap; }
  .scanbox .scan-search-row > .control { flex: 1 1 100%; }

  /* A line with nothing in a column (Serials on a non-serial item) doesn't
     show an empty heading. */
  table.lines tbody td:empty { display: none; }

  /* Reports / Aging / customer stats: two compact cards per row instead of
     one tall card each (the dashboard and Sales History have their own). */
  .stat-grid:not(.sales-stats) { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .stat-grid:not(.sales-stats) > .stat-card { min-width: 0; padding: 12px; gap: 10px; }
  .stat-grid:not(.sales-stats) > .stat-card:last-child:nth-child(odd) { grid-column: 1 / -1; }
  .stat-grid:not(.sales-stats) .stat-icon { width: 36px; height: 36px; border-radius: 8px; }
  .stat-grid:not(.sales-stats) .stat-icon .icon svg { width: 20px; height: 20px; }
  .stat-grid:not(.sales-stats) .stat-label { font-size: 12px; }
  .stat-grid:not(.sales-stats) .stat-value { font-size: 18px; overflow-wrap: anywhere; }

  /* History: the GRN / SIV button stays button-sized. */
  table.work-table td .doc-btn { justify-self: start; margin-left: 0; }
}
/* ---- phone tidy-up ----
   Tables that turn into cards on a phone used one label row per column, so
   a single product or history line took most of the screen. These rules
   make the cards compact lists, tighten nested form cards, and keep scan
   boxes and toolbars from squeezing their inputs. */
@media (max-width: 640px) {
  .card { padding: 14px; }
  .card .card { padding: 12px; }
  #app-content { padding: 16px 12px 20px; }

  /* Generic label/value cards (Labels, Reports, Customers, ...). */
  table.work-table tbody tr { padding: 10px 12px; }
  table.work-table tbody td, table.work-table tbody tr:last-child td { grid-template-columns: 88px minmax(0, 1fr); padding: 3px 0; line-height: 1.35; }
  table.work-table td[data-label]::before { font-size: .8rem; line-height: 1.6; }
  table.work-table tbody tr td.empty { display: block; }

  /* Stock: name and status on top, SKU and quantity beneath. */
  table.stock-work-table tbody tr { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 2px 12px; align-items: center; }
  table.stock-work-table tbody td, table.stock-work-table tbody tr:last-child td { display: block; padding: 0; }
  table.stock-work-table td[data-label]::before { content: none; }
  table.stock-work-table tbody tr td:nth-child(1) { grid-area: 1 / 1; font-weight: 600; }
  table.stock-work-table tbody tr td:nth-child(2) { grid-area: 2 / 1; color: var(--text-soft); font-size: .84rem; }
  table.stock-work-table tbody tr td:nth-child(3) { grid-area: 2 / 2; justify-self: end; text-align: right; font-weight: 600; white-space: nowrap; }
  table.stock-work-table tbody tr td:nth-child(4) { grid-area: 1 / 2; justify-self: end; }
  table.stock-work-table td.empty { grid-column: 1 / -1; }

  /* History and the Dashboard's Recent Activity: product and quantity on
     top, date and type next, who and value last. */
  table.activity-table tbody tr { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 4px 12px; align-items: start; }
  table.activity-table tbody td, table.activity-table tbody tr:last-child td { display: block; padding: 0; }
  table.activity-table td[data-label]::before { content: none; }
  table.activity-table tbody tr td:nth-child(1) { grid-area: 2 / 1; color: var(--text-soft); font-size: .82rem; }
  table.activity-table tbody tr td:nth-child(2) { grid-area: 1 / 1; }
  table.activity-table tbody tr td:nth-child(2) .pill { display: inline-block; margin: 4px 4px 0 0; }
  table.activity-table tbody tr td:nth-child(3) { grid-area: 1 / 2; justify-self: end; text-align: right; font-weight: 700; font-size: 1.05rem; }
  table.activity-table tbody tr td:nth-child(4) { grid-area: 2 / 2; display: flex; flex-direction: column; align-items: flex-end; gap: 4px; }
  table.activity-table tbody tr td:nth-child(4) .btn { width: auto; padding: 2px 10px; }
  table.activity-table tbody tr td:nth-child(5) { grid-area: 3 / 1; color: var(--text-soft); font-size: .82rem; }
  table.activity-table tbody tr td:nth-child(5)::before { content: "By "; }
  table.activity-table tbody tr td:nth-child(6) { grid-area: 3 / 2; justify-self: end; text-align: right; font-size: .84rem; }
  table.activity-table td.empty { grid-column: 1 / -1; }
  .history-filters { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 10px; }
  .activity-sku { font-size: .82rem; color: var(--text-soft); }

  /* Scan boxes: the camera button goes under a full-width input, and the
     hint in the input is in the normal font so it fits. */
  .scanbox .scan-search-row { flex-wrap: wrap; }
  .scanbox .scan-search-row > .control { flex: 1 1 100%; }
  .scanbox .scan-search-row > .btn { flex: 1 1 100%; }
  .scan-code:placeholder-shown { font-family: inherit; letter-spacing: 0; }

  /* Report and summary stat cards: two small cards per row. */
  #view-reports .stat-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
  #view-reports .stat-card { padding: 10px; gap: 8px; }
  #view-reports .stat-icon { width: 32px; height: 32px; }
  #view-reports .stat-icon .icon svg { width: 18px; height: 18px; }
  #view-reports .stat-label { font-size: 12px; }
  #view-reports .stat-value { font-size: 17px; overflow-wrap: anywhere; }

  /* Sales History period chips wrap instead of running off the edge. */
  .period-chips { flex-wrap: wrap; overflow-x: visible; margin-right: 0; padding-right: 0; }
}

/* Products on a phone: a compact two-column card per product. */
@container (max-width: 560px) {
  #view-products .view-head-tools { width: 100%; }
  #view-products .view-head-tools .control[type="search"] { flex: 1 1 100%; }
  table.products-grid tbody tr { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px 14px; padding: 12px 0; }
  table.products-grid tbody td { padding: 0; font-size: .88rem; }
  table.products-grid td[data-label]::before { font-size: .72rem; text-transform: uppercase; letter-spacing: .04em; margin-bottom: 2px; }
  table.products-grid td:nth-child(1) { grid-column: 1 / -1; font-size: .95rem; }
  table.products-grid td:nth-child(1)::before { content: none; }
  table.products-grid td:nth-child(1) .product-detail { font-size: .85rem; color: var(--text-soft); }
  table.products-grid td:last-child { grid-column: 1 / -1; }
  table.products-grid td:last-child::before { content: none; }
  table.products-grid td:last-child .btn { margin-right: 6px; }
  table.products-grid td.empty { grid-column: 1 / -1; }
  .product-detail { margin-bottom: 1px; }
}
.product-sell .muted { margin: 0; font-size: inherit; }

/* ==========================================================================
   Phone app look (≤640px): navy KI header, bottom tab bar, one-row quick
   actions and white 2×2 stat cards on the Dashboard. Desktop is unchanged:
   everything phone-only below is hidden or reset above 640px.
   ========================================================================== */
.topbar-brand, .topbar-user-chevron, .tabbar, .dashboard-actions > .dash-more { display: none; }
.topbar-user-btn {
  display: flex; align-items: center; gap: 10px; min-width: 0;
  padding: 0; border: 0; background: none; font: inherit; color: inherit; text-align: inherit; cursor: default;
}
.topbar-user-name, .topbar-user-role { display: block; }
.dashboard-date { display: inline-flex; align-items: center; flex-wrap: wrap; gap: 4px 6px; }
.dashboard-date-icon svg { width: 16px; height: 16px; }
.chart-empty-icon { display: block; width: max-content; margin: 0 auto 8px; color: #94a3b8; }
.chart-empty-icon svg { width: 30px; height: 30px; }

@media (max-width: 640px) {
  /* ---- header: navy band with logo, company name and the user menu ---- */
  .topbar {
    position: static;
    background: var(--navy);
    border-bottom: 0;
    box-shadow: none;
    padding: 12px 16px 0;
    gap: 10px;
    row-gap: 12px;
  }
  .sidebar-toggle-btn { display: none; }
  .topbar-brand { display: flex; align-items: center; gap: 10px; flex: 1 1 0; min-width: 0; }
  .topbar-brand-logo { width: 40px; height: 40px; border-radius: 9px; flex: none; }
  /* Wraps onto as many lines as it needs; never cut off with "…". */
  .topbar-brand-name {
    color: #fff; font-weight: 800; font-size: .7rem; line-height: 1.2;
    text-transform: uppercase; letter-spacing: .01em; min-width: 0;
  }
  .topbar-user { margin-left: 0; flex: none; position: relative; }
  .topbar-user-btn { gap: 8px; padding: 4px; border-radius: 10px; color: #fff; cursor: pointer; }
  .topbar-user-btn:focus-visible { outline: 2px solid var(--amber); outline-offset: 2px; }
  .topbar-user-info { text-align: left; }
  /* A long name ("Kedir Mohammed") wraps onto two lines to leave room for the company name. */
  .topbar .topbar-user-name {
    color: #fff; font-size: .78rem; line-height: 1.2; max-width: 84px;
    white-space: normal; overflow-wrap: break-word;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  }
  .topbar .topbar-user-role { color: rgba(255, 255, 255, .75); font-size: .7rem; max-width: 84px; }
  .topbar .topbar-avatar { width: 34px; height: 34px; }
  .topbar-user-chevron { display: inline-flex; }
  .topbar-user-chevron svg { width: 18px; height: 18px; }
  .topbar-user #logout-btn {
    display: none; position: absolute; right: 0; top: calc(100% + 6px); z-index: 35;
    background: var(--surface); color: var(--text); border: 1px solid var(--border);
    box-shadow: 0 8px 24px rgba(15, 23, 42, .18); padding: 10px 20px;
  }
  .topbar-user.is-open #logout-btn { display: inline-flex; }

  /* The search sits on a light sheet with rounded top corners over the navy. */
  .topbar-search {
    order: 3; flex: 1 1 100%; max-width: none;
    margin: 0 -16px; padding: 14px 16px 4px;
    background: var(--bg); border-radius: 22px 22px 0 0;
  }
  .topbar-search-icon { left: 30px; top: calc(50% + 5px); }
  .topbar-search .control { background: #e6ebf1; }

  #app-content { padding: 8px 16px 16px; }
  .app-footer { padding-bottom: calc(84px + env(safe-area-inset-bottom, 0px)); }
  #toast-container { bottom: calc(80px + env(safe-area-inset-bottom, 0px)); }

  /* ---- bottom tab bar ---- */
  .tabbar {
    display: flex; position: fixed; left: 0; right: 0; bottom: 0; z-index: 38;
    background: var(--surface); border-top: 1px solid var(--border);
    box-shadow: 0 -2px 12px rgba(15, 23, 42, .06);
    padding: 0 4px env(safe-area-inset-bottom, 0px);
  }
  .tabbar-item {
    flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; align-items: center; gap: 3px;
    padding: 8px 2px 9px; border: 0; border-top: 3px solid transparent; background: none;
    font: inherit; font-size: .74rem; color: var(--text-soft); text-decoration: none; cursor: pointer;
  }
  .tabbar-item .icon svg { width: 24px; height: 24px; }
  .tabbar-item.is-active { color: var(--dash-blue); border-top-color: var(--dash-blue); font-weight: 600; }
  .tabbar-item:focus-visible { outline: 2px solid var(--dash-blue); outline-offset: -2px; }

  /* ---- Dashboard: date above "Today" ---- */
  #view-dashboard .dashboard-head { flex-direction: column-reverse; align-items: flex-start; gap: 10px; margin-bottom: 14px; }
  #view-dashboard .dashboard-head h1 { font-size: 1.6rem; }
  .dashboard-date { color: var(--text); font-size: .86rem; }
  .dashboard-date-ec { color: var(--text-soft); font-size: .76rem; }

  /* ---- Dashboard: Sell / Stock In / Add Product / More in one row ---- */
  .dashboard-actions { display: flex; flex-direction: row; flex-wrap: wrap; gap: 6px; margin-bottom: 16px; }
  /* Growth weights roughly follow label length, so all four always share
     one row; a label wraps inside its button rather than push More down. */
  .dashboard-actions > .btn {
    flex: 1 1 0; width: auto; min-width: 0; min-height: 46px; padding: 8px 5px; gap: 4px;
    font-size: 13px; line-height: 1.15; white-space: normal; text-align: center;
    border-radius: 10px; grid-column: auto;
  }
  .dashboard-actions > .btn-primary { flex-grow: .95; }
  .dashboard-actions > .dash-stock-in { flex-grow: 1.15; }
  .dashboard-actions > .dash-add { flex-grow: 1.4; }
  /* Line break before the extra buttons when More is open. */
  .dashboard-actions.is-expanded::after { content: ""; order: 5; flex-basis: 100%; height: 0; }
  .dashboard-actions .icon svg { width: 18px; height: 18px; }
  .dashboard-actions > .btn-primary { background: var(--dash-blue); border-color: var(--dash-blue); }
  .dashboard-actions > .dash-stock-in,
  .dashboard-actions > .dash-add { background: var(--surface); border-color: var(--border); color: var(--text); }
  .dashboard-actions > .dash-add { color: var(--dash-green); }
  .dashboard-actions > .dash-stock-in:hover,
  .dashboard-actions > .dash-add:hover { background: var(--surface-2); }
  .dash-plus { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .dashboard-actions > .dash-extra { display: none; order: 10; flex: 1 1 28%; }
  .dashboard-actions.is-expanded > .dash-extra { display: flex; }
  .dashboard-actions > .dash-more { display: flex; flex-grow: .95; }

  /* ---- Dashboard: white 2×2 stat cards with a round tinted icon ---- */
  #view-dashboard .stat-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; margin-bottom: 16px; }
  #view-dashboard .stat-grid > .stat-card.stat-card {
    grid-column: auto; flex-direction: row; align-items: center; gap: 10px; padding: 14px 12px;
    background: var(--surface); border: 1px solid rgba(213, 221, 229, .7);
  }
  #view-dashboard .stat-grid > .stat-card.stat-card .stat-icon.stat-icon { width: 42px; height: 42px; border-radius: 50%; flex: none; }
  #view-dashboard .stat-grid > .stat-card.stat-card .stat-icon.stat-icon .icon svg { width: 22px; height: 22px; }
  #view-dashboard .stat-grid .stat-icon-blue  { background: rgba(37, 99, 235, .1);  color: var(--dash-blue); }
  #view-dashboard .stat-grid .stat-icon-green { background: rgba(22, 163, 74, .1);  color: var(--dash-green); }
  #view-dashboard .stat-grid .stat-icon-amber { background: rgba(245, 158, 11, .14); color: var(--dash-amber); }
  #view-dashboard .stat-grid .stat-icon-red   { background: rgba(220, 38, 38, .1);  color: var(--dash-red); }
  #view-dashboard .stat-grid > .stat-card.stat-card .stat-label { font-size: 12.5px; margin-bottom: 2px; }
  #view-dashboard .stat-grid > .stat-card.stat-card .stat-value { font-size: 17px; overflow-wrap: normal; }
  #view-dashboard .stat-grid .stat-unit { font-size: .78em; }

  /* Chart title and the 7 / 30 / 90 days switch share one line. */
  /* Title and switch share a line; if a phone is too narrow the whole switch
     moves under the title (never a cut-off "…"). */
  #view-dashboard .chart-card { padding-left: 12px; padding-right: 12px; }
  #view-dashboard .chart-card .card-head { flex-wrap: wrap; gap: 6px 8px; }
  #view-dashboard .chart-card .card-head h2 { flex: 0 1 auto; font-size: .88rem; white-space: nowrap; }
  #view-dashboard .range-toggle { flex: none; margin-left: auto; }
  #view-dashboard .range-toggle button { padding: 5px 5px; font-size: .68rem; }
  /* Stock status: donut beside its legend. */
  .donut-wrap { flex-wrap: nowrap; gap: 14px; }
  .donut-wrap svg { width: 120px; height: 120px; }
  .donut-legend { min-width: 0; }
  .donut-legend-row { padding: 6px 2px; font-size: .88rem; }
}
/* Smaller phones (360px wide): keep the four quick actions on one row;
   the chart title may wrap above the 7 / 30 / 90 switch rather than be cut. */
@media (max-width: 370px) {
  .dashboard-actions > .btn { font-size: 12px; }
  .dashboard-actions .icon svg { width: 16px; height: 16px; }
  .topbar-brand-logo { width: 34px; height: 34px; }
}
/* Phone turned sideways, tablets and narrow windows: the Dashboard buttons
   flow into as many rows as they need and their labels wrap, so a label is
   never cut off at the button edge. Wide screens still get one row of six. */
@media (min-width: 641px) {
  .dashboard-actions { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); align-items: stretch; }
  .dashboard-actions > .btn { min-width: 0; white-space: normal; text-align: center; line-height: 1.2; }
}

/* ---- Products form: Extra details (products.specs) as labelled rows ---- */
.spec-rows { display: flex; flex-direction: column; gap: 6px; }
.spec-rows:empty { display: none; }
.spec-row { display: grid; grid-template-columns: minmax(90px, 30%) minmax(0, 1fr) auto; gap: 8px; align-items: center; }
.spec-name { font-size: .88rem; font-weight: 600; color: #475569; overflow-wrap: anywhere; }
.spec-remove { padding: 6px 10px; color: var(--text-soft); }
.spec-editor > div:not(.spec-rows) { margin-top: 2px; }

/* Sell: confirm-before-save summary (Step 1). */
.confirm-lines { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--border); }
.confirm-line { display: flex; justify-content: space-between; gap: 12px; padding: 8px 0; border-bottom: 1px solid var(--border); overflow-wrap: anywhere; }
.confirm-line .num { white-space: nowrap; }
.confirm-total { margin: 4px 0 0; font-size: 1.05rem; }
/* Products: a seller sees the price read-only. */
.price-cell-readonly { font-weight: 600; }
