/* =====================================================================
   SALESPOINT — DESIGN TOKENS
   A business ERP/POS shell for electronics & mobile retailers.
   Signature: a thin "barcode stripe" motif (var widths, like a scanned
   barcode) marks brand moments — login panel, sidebar logo, empty states —
   a nod to the serial/IMEI scanning this app is built around.
   ===================================================================== */
:root {
  /* Color */
  --sp-ink:        #0F172A;   /* primary text */
  --sp-ink-muted:  #55637A;   /* secondary text */
  --sp-surface:    #FFFFFF;
  --sp-bg:         #F4F6F9;   /* app canvas */
  --sp-border:     #E3E8EF;

  --sp-brand-900:  #0B2340;   /* deep navy (install wizard, headings) */

  /* Sampled from the app-backg2 design: a light menu with navy type. */
  --sp-nav-surface: #FDFDFD;  /* menu background */
  --sp-nav-header:  #001E64;  /* brand block at the top of the menu */
  --sp-nav-ink:     #0A2472;  /* menu text and icons */
  --sp-nav-active:  #012167;  /* the selected pill */
  --sp-nav-hover:   #EDF1FA;  /* row hover */
  --sp-nav-line:    #E1E7F5;  /* separators */
  --sp-blue:        #2269B6;  /* the arc accent in the design */
  --sp-dash-bg:     #F1F3F7;  /* dashboard canvas */

  /* Sky blue, for the menu's group tabs. */
  --sp-sky-100:        #E8F4FE;
  --sp-sky-200:        #D4EAFC;
  --sp-sky-line:       #A8D3F5;  /* the tab's edge */
  --sp-sky-line-strong: #6FB3E8;  /* hovered, open, or the group you are in */

  /* Form chrome. Panels sit on a tinted blue so a form reads as one block
     of work; the fields themselves are a neutral grey so the eye lands on
     what is fillable, and every label is the same navy as the menu. */
  --sp-form-surface:  #F4F8FE;  /* panel behind a form */
  --sp-form-line:     #DCE6F7;  /* its border, and rules between sections */
  --sp-field:         #F0F1F4;  /* text boxes and dropdowns at rest */
  --sp-field-border:  #E1E4EA;
  --sp-field-focus:   #2269B6;  /* the blue from the design */
  --sp-field-ring:    rgba(34, 105, 182, 0.16);
  --sp-form-label:    #0A2472;  /* labels and headings */
  --sp-brand-700:  #123A63;
  --sp-brand-500:  #1B4E82;

  --sp-accent:     #0E9C8C;   /* teal — actions, active states */
  --sp-accent-600: #0B8477;
  --sp-accent-100: #E3F6F3;

  --sp-success:    #1D9A5C;
  --sp-warning:    #C67C1E;
  --sp-danger:     #D3413F;
  --sp-info:       #2D6FE0;

  /* Type */
  --sp-font-ui:   'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --sp-font-num:  'Inter', ui-monospace, SFMono-Regular, monospace; /* tabular figures for money/qty */

  /* Layout */
  --sp-sidebar-w: 264px;
  --sp-topbar-h:  60px;
  --sp-radius:    8px;
  --sp-radius-lg: 12px;
  --sp-shadow:    0 1px 2px rgba(15, 23, 42, 0.06), 0 1px 1px rgba(15, 23, 42, 0.04);
  --sp-shadow-md: 0 4px 14px rgba(15, 23, 42, 0.08);
}

* { box-sizing: border-box; }

body {
  font-family: var(--sp-font-ui);
  background: var(--sp-bg);
  color: var(--sp-ink);
  font-size: 14.5px;
  -webkit-font-smoothing: antialiased;
}

.tabular-nums { font-variant-numeric: tabular-nums; font-family: var(--sp-font-num); }

/* ---------- Barcode-stripe signature -------------------------------- */
.sp-barcode {
  display: flex;
  align-items: stretch;
  gap: 2px;
  height: 34px;
}
.sp-barcode span {
  display: block;
  background: currentColor;
  border-radius: 1px;
}
/* varying widths, deterministic pseudo-random pattern */
.sp-barcode span:nth-child(1)  { width: 2px; }
.sp-barcode span:nth-child(2)  { width: 4px; }
.sp-barcode span:nth-child(3)  { width: 1px; }
.sp-barcode span:nth-child(4)  { width: 3px; }
.sp-barcode span:nth-child(5)  { width: 1px; }
.sp-barcode span:nth-child(6)  { width: 5px; }
.sp-barcode span:nth-child(7)  { width: 2px; }
.sp-barcode span:nth-child(8)  { width: 1px; }
.sp-barcode span:nth-child(9)  { width: 3px; }
.sp-barcode span:nth-child(10) { width: 2px; }
.sp-barcode span:nth-child(11) { width: 4px; }
.sp-barcode span:nth-child(12) { width: 1px; }

/* ---------- App shell ------------------------------------------------ */
.sp-shell { display: flex; min-height: 100vh; }

.sp-sidebar {
  width: var(--sp-sidebar-w);
  background: var(--sp-nav-surface);
  border-right: 1px solid var(--sp-nav-line);
  color: var(--sp-nav-ink);
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  position: fixed;
  top: 0; bottom: 0; left: 0;
  z-index: 40;
  transition: transform 0.2s ease;
}
.sp-sidebar-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 18px 20px;
  background: var(--sp-nav-header);
  color: #fff;
}
.sp-sidebar-brand .sp-barcode { color: #fff; }
.sp-sidebar-brand-name { font-weight: 700; font-size: 17px; letter-spacing: 0.2px; }

/* The design's wave, pinned below the menu. flex-shrink:0 keeps it its own
   height while .sp-nav takes the remaining space and scrolls above it. */
.sp-sidebar-wave {
  flex-shrink: 0;
  height: 96px;
  background: url("../img/sidebar-wave.jpg") left bottom / 100% auto no-repeat;
}

/* ---------- Sidebar navigation ------------------------------------------*/
.sp-nav { flex: 1; overflow-y: auto; padding: 8px 8px 24px; }
.sp-nav::-webkit-scrollbar { width: 6px; }
.sp-nav::-webkit-scrollbar-thumb { background: #D5DEF0; border-radius: 3px; }

/* Pinned links sit above the groups */
.sp-nav-pinned {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 12px; margin-bottom: 3px;
  border-radius: var(--sp-radius);
  color: var(--sp-nav-ink); text-decoration: none;
  font-size: 13.5px; font-weight: 600;
}
.sp-nav-pinned:hover { background: var(--sp-nav-hover); color: var(--sp-nav-active); }
.sp-nav-pinned.active { background: var(--sp-nav-active); color: #fff; }
.sp-nav-pinned i { font-size: 16px; width: 18px; text-align: center; }

/* ---- Collapsible groups ---- */
.sp-nav-group { margin-top: 4px; }

/* Each group reads as a tab: a pale sky-blue block with a crisp sky-blue
   edge. Flat on purpose — a drawn line states where the tab ends far more
   clearly than a soft shadow does. */
.sp-nav-group-toggle {
  display: flex; align-items: center; gap: 10px; width: 100%;
  background: var(--sp-sky-100); cursor: pointer;
  border: 1px solid var(--sp-sky-line);
  padding: 9px 12px; border-radius: var(--sp-radius);
  color: var(--sp-nav-ink); text-align: left;
  transition: background 0.15s ease, border-color 0.15s ease;
}
.sp-nav-group-toggle:hover {
  background: var(--sp-sky-200);
  border-color: var(--sp-sky-line-strong);
}
/* The group you are in, and the one you have opened, carry the firmer edge. */
.sp-nav-group.is-current > .sp-nav-group-toggle,
.sp-nav-group.is-open > .sp-nav-group-toggle {
  background: var(--sp-sky-200);
  border-color: var(--sp-sky-line-strong);
}
.sp-nav-group-icon { font-size: 15px; width: 18px; text-align: center; }

.sp-nav-group-label {
  flex: 1;
  font-size: 11px; text-transform: uppercase; letter-spacing: 0.07em;
  font-weight: 700;
}

/* Marks the group holding the current page while it is collapsed */
.sp-nav-dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--sp-nav-active); flex-shrink: 0;
}
.sp-nav-group.is-open .sp-nav-dot { display: none; }
.sp-nav-group.is-current .sp-nav-group-toggle { color: var(--sp-nav-active); }

.sp-nav-chevron {
  font-size: 11px; transition: transform 0.18s ease; flex-shrink: 0;
}
.sp-nav-group.is-open .sp-nav-chevron { transform: rotate(180deg); }
.sp-nav-group.is-open .sp-nav-group-toggle { color: var(--sp-nav-active); }

/* Collapsed by default. The grid animates one row from 0fr to 1fr, which is
   why the links live inside a single .sp-nav-group-inner wrapper — as direct
   children they would fall into auto-sized implicit rows and never collapse. */
.sp-nav-group-items {
  display: grid; grid-template-rows: 0fr;
  transition: grid-template-rows 0.18s ease;
}
.sp-nav-group.is-open .sp-nav-group-items { grid-template-rows: 1fr; }
.sp-nav-group-inner { overflow: hidden; min-height: 0; }

.sp-nav-group-items a {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 12px 8px 26px; margin-bottom: 1px;
  border-radius: var(--sp-radius);
  color: var(--sp-nav-ink); text-decoration: none;
  font-size: 13px; font-weight: 500;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sp-nav-group-items a:hover { background: var(--sp-nav-hover); color: var(--sp-nav-active); }
.sp-nav-group-items a.active { background: var(--sp-nav-active); color: #fff; font-weight: 600; }
.sp-nav-group-items a i { font-size: 14px; width: 16px; text-align: center; flex-shrink: 0; }

@media (prefers-reduced-motion: reduce) {
  .sp-nav-group-items, .sp-nav-chevron { transition: none; }
}
.sp-main { flex: 1; margin-left: var(--sp-sidebar-w); display: flex; flex-direction: column; min-height: 100vh; }

.sp-topbar {
  height: var(--sp-topbar-h);
  background: var(--sp-surface);
  border-bottom: 1px solid var(--sp-border);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 22px;
  position: sticky;
  top: 0;
  z-index: 30;
}
.sp-topbar-title { font-weight: 700; font-size: 16px; }
.sp-topbar-actions { display: flex; align-items: center; gap: 16px; }
.sp-user-chip { display: flex; align-items: center; gap: 8px; cursor: pointer; }
.sp-user-avatar {
  width: 32px; height: 32px; border-radius: 50%;
  background: var(--sp-accent-100); color: var(--sp-accent-600);
  display: flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: 13px;
}

.sp-content { padding: 22px; flex: 1; }

.sp-hamburger { display: none; background: none; border: none; font-size: 20px; color: var(--sp-ink); }

/* ---------- Cards / KPIs ---------------------------------------------- */
.sp-card {
  background: var(--sp-surface);
  border: 1px solid var(--sp-border);
  border-radius: var(--sp-radius-lg);
  box-shadow: var(--sp-shadow);
}
.sp-kpi { padding: 16px 18px; }
.sp-kpi-label { font-size: 12.5px; color: var(--sp-ink-muted); font-weight: 600; text-transform: uppercase; letter-spacing: 0.03em; }
.sp-kpi-value { font-size: 18px; font-weight: 700; margin-top: 6px; }
.sp-kpi-sub { font-size: 12px; color: var(--sp-ink-muted); margin-top: 4px; }

/* ---------- Buttons ----------------------------------------------------*/
.btn-sp-primary {
  background: var(--sp-accent); border-color: var(--sp-accent); color: #fff;
}
.btn-sp-primary:hover { background: var(--sp-accent-600); border-color: var(--sp-accent-600); color: #fff; }
.btn-sp-outline {
  border: 1px solid var(--sp-border); color: var(--sp-ink); background: #fff;
}

/* ---------- Badges ------------------------------------------------------*/
.sp-badge { font-size: 11.5px; font-weight: 600; padding: 3px 9px; border-radius: 999px; display: inline-block; }
.sp-badge-success { background: #E7F6EC; color: var(--sp-success); }
.sp-badge-warning { background: #FCF1DF; color: var(--sp-warning); }
.sp-badge-danger  { background: #FBEAEA; color: var(--sp-danger); }
.sp-badge-info    { background: #E8EFFD; color: var(--sp-info); }

/* ---------- Auth / Install screens -------------------------------------*/
.sp-auth-wrap {
  min-height: 100vh; display: flex; background: var(--sp-brand-900);
}
.sp-auth-aside {
  flex: 1.1; display: none; padding: 56px; color: #fff; position: relative; overflow: hidden;
  background: linear-gradient(180deg, var(--sp-brand-900) 0%, var(--sp-brand-700) 100%);
}
.sp-auth-aside .sp-barcode { color: var(--sp-accent); height: 54px; margin-bottom: 28px; }

/* Maker's mark, pinned to the foot of the blue panel. Absolute rather than
   in flow so it stays on the baseline of the panel whatever length the
   headline runs to. */
.sp-auth-mark {
  position: absolute; left: 56px; right: 56px; bottom: 40px;
  padding-top: 18px; border-top: 1px solid rgba(255, 255, 255, 0.16);
  font-size: 12.5px; line-height: 1.7;
}
.sp-auth-mark-name { color: #E2E9F5; font-weight: 600; letter-spacing: 0.2px; }
.sp-auth-mark-by   { color: #9FB2CC; }
.sp-auth-form-col {
  flex: 1; background: var(--sp-bg); display: flex; align-items: center; justify-content: center; padding: 24px;
}
.sp-auth-card { width: 100%; max-width: 400px; }

.sp-install-shell { min-height: 100vh; background: var(--sp-bg); padding: 32px 16px; }
.sp-install-steps { display: flex; justify-content: center; gap: 6px; margin-bottom: 26px; flex-wrap: wrap; }
.sp-install-step-dot {
  width: 30px; height: 30px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
  font-size: 12.5px; font-weight: 700; background: #fff; border: 1px solid var(--sp-border); color: var(--sp-ink-muted);
}
.sp-install-step-dot.is-active { background: var(--sp-accent); border-color: var(--sp-accent); color: #fff; }
.sp-install-step-dot.is-done { background: var(--sp-brand-900); border-color: var(--sp-brand-900); color: #fff; }
.sp-install-card { max-width: 640px; margin: 0 auto; }

/* ---------- Responsive --------------------------------------------------*/
@media (max-width: 991px) {
  .sp-sidebar { transform: translateX(-100%); }
  .sp-sidebar.is-open { transform: translateX(0); }
  .sp-main { margin-left: 0; }
  .sp-hamburger { display: inline-flex; }
}
@media (min-width: 992px) {
  .sp-auth-aside { display: block; }
}

/* =========================================================================
   Phase 2A — Administration components
   Built only from the tokens above; no new colors or fonts introduced.
   ========================================================================= */

/* ---------- Page header (title + actions) -------------------------------*/
.sp-page-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap; margin-bottom: 16px;
}
.sp-page-head h1 {
  font-size: 20px; font-weight: 700; color: var(--sp-form-label);
  margin: 0; letter-spacing: -0.01em;
}
.sp-page-head .sp-page-sub {
  font-size: 13px; color: var(--sp-ink-muted); margin-top: 2px;
}
/* The short blue rule under the title, as in the design. */
.sp-page-head .sp-page-sub::after {
  content: ''; display: block; width: 54px; height: 3px; border-radius: 2px;
  background: var(--sp-field-focus); margin-top: 10px;
}

/* ---------- Data table --------------------------------------------------*/
.sp-table-wrap {
  background: var(--sp-surface); border: 1px solid var(--sp-border);
  border-radius: var(--sp-radius-lg); box-shadow: var(--sp-shadow);
  overflow-x: auto;
}
.sp-table { width: 100%; margin: 0; border-collapse: separate; border-spacing: 0; }
.sp-table thead th {
  background: var(--sp-bg); color: var(--sp-ink-muted);
  font-size: 11.5px; font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.04em; white-space: nowrap;
  padding: 10px 14px; border-bottom: 1px solid var(--sp-border);
}
.sp-table tbody td {
  padding: 12px 14px; font-size: 13.5px; color: var(--sp-ink);
  border-bottom: 1px solid var(--sp-border); vertical-align: middle;
}
.sp-table tbody tr:last-child td { border-bottom: 0; }
.sp-table tbody tr:hover { background: var(--sp-accent-100); }
.sp-table .sp-td-actions { text-align: right; white-space: nowrap; }
.sp-table .sp-td-strong { font-weight: 600; }

/* ---------- Empty state -------------------------------------------------*/
.sp-empty { text-align: center; padding: 48px 20px; color: var(--sp-ink-muted); }
.sp-empty i { font-size: 30px; color: var(--sp-border); }
.sp-empty p { margin: 10px 0 16px; font-size: 13.5px; }

/* ---------- Forms -------------------------------------------------------*/
.sp-form-card { background: var(--sp-form-surface); border: 1px solid var(--sp-form-line);
  border-radius: var(--sp-radius-lg); box-shadow: var(--sp-shadow); padding: 20px; }
.sp-form-section + .sp-form-section { margin-top: 22px; padding-top: 22px; border-top: 1px solid var(--sp-form-line); }

/* The blue rule stands in for the icon tile in the design — the same
   signal, without an extra element in thirty form views. */
.sp-form-section-title { font-size: 12px; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.06em; color: var(--sp-form-label); margin-bottom: 14px;
  display: flex; align-items: center; gap: 8px; }
.sp-form-section-title::before {
  content: ''; flex: none; width: 4px; height: 14px; border-radius: 2px;
  background: var(--sp-field-focus);
}

.sp-label { font-size: 12.5px; font-weight: 600; color: var(--sp-form-label); margin-bottom: 5px; display: block; }
.sp-label .sp-req { color: var(--sp-danger); margin-left: 2px; }
.sp-hint { font-size: 11.5px; color: var(--sp-ink-muted); margin-top: 4px; }
.sp-form-actions { display: flex; gap: 10px; justify-content: flex-end;
  margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--sp-form-line); }

/* ---------- Forms in a popup -------------------------------------------
   The Add forms open over their list rather than on a page of their own.
   The modal wears the same clothes as a form card: blue panel, dark blue
   headings, grey fields — so it reads as the same software, not a
   Bootstrap dialog that wandered in. */
.sp-modal .modal-content {
  background: var(--sp-form-surface); border: 1px solid var(--sp-form-line);
  border-radius: var(--sp-radius-lg); overflow: hidden;
}
.sp-modal .modal-header {
  background: #fff; border-bottom: 1px solid var(--sp-form-line); padding: 14px 20px;
}
.sp-modal .modal-title {
  font-size: 15px; font-weight: 700; color: var(--sp-form-label);
  display: flex; align-items: center; gap: 8px; margin: 0;
}
.sp-modal .modal-body { padding: 18px 20px; }
.sp-modal .modal-footer {
  background: #fff; border-top: 1px solid var(--sp-form-line);
  padding: 12px 20px; gap: 10px;
}
/* The form wraps the header, body and footer, which makes the form — not
   .modal-content — the column that has to flex. Without this the footer
   slides off the bottom of a tall form and the Create button cannot be
   reached. */
.sp-modal .modal-content > form {
  display: flex; flex-direction: column;
  flex: 1 1 auto; max-height: 100%; min-height: 0;
}
.sp-modal .modal-body { min-height: 0; }

/* The body already scrolls; a second scrollbar on a section would trap
   the pointer halfway down the form. */
.sp-modal .sp-form-section { overflow: visible; }


/* A form with the air taken out of it: sections sit closer together and
   the rule between them does the separating instead of empty space. */
.sp-form-tight .sp-form-section + .sp-form-section { margin-top: 16px; padding-top: 16px; }
.sp-form-tight .sp-form-section-title { margin-bottom: 10px; }
.sp-form-tight .sp-form-actions { margin-top: 16px; padding-top: 14px; }

/* A checkbox has no label above it, so on a row beside labelled inputs it
   floats up on its own. This drops it onto the same line as the fields
   next to it. */
.sp-check-field { min-height: 38px; display: flex; align-items: center; gap: 2px; }
.sp-check-field .form-check-input { margin-top: 0; }
.sp-check-field .form-check-label { font-size: 13px; color: var(--sp-ink); }

/* ---------- Line items inside a form ------------------------------------
   An invoice has however many lines it has, so they are a table rather
   than a fixed grid. It scrolls sideways on a narrow screen instead of
   squeezing the numbers into columns too thin to read. */
.sp-lines-wrap { overflow-x: auto; border: 1px solid var(--sp-form-line);
  border-radius: var(--sp-radius); background: #fff; }
.sp-lines { width: 100%; min-width: 720px; border-collapse: collapse; }
.sp-lines th {
  font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--sp-form-label); background: var(--sp-form-surface);
  padding: 8px 10px; border-bottom: 1px solid var(--sp-form-line); text-align: left;
}
.sp-lines td { padding: 8px 10px; border-bottom: 1px solid var(--sp-form-line); vertical-align: top; }
.sp-lines tr:last-child td { border-bottom: 0; }
.sp-lines .w-product { min-width: 260px; }
.sp-lines .w-num     { width: 120px; }
.sp-lines .w-act     { width: 44px; text-align: center; }
.sp-line-note { font-size: 11px; color: var(--sp-ink-muted); margin-top: 3px; min-height: 14px; }

/* The totals block: labels left, figures right, on one tidy column so the
   eye can run down the numbers. */
.sp-totals { margin-top: 14px; margin-left: auto; width: 100%; max-width: 320px;
  font-size: 13px; }
.sp-totals > div { display: flex; justify-content: space-between; align-items: baseline;
  padding: 5px 0; }
.sp-totals-grand { border-top: 1px solid var(--sp-form-line); margin-top: 4px; padding-top: 8px !important; }
.sp-totals-grand span { font-weight: 700; color: var(--sp-form-label); }
.sp-totals-grand b { font-size: 17px; font-weight: 700; color: var(--sp-form-label); }
#inv-balance-row { border-top: 1px dashed var(--sp-form-line); color: var(--sp-ink-muted); }
#inv-balance-row.is-change b { color: var(--sp-success, #0E9C8C); }

/* The running total, kept in the footer where it cannot scroll away. */
.sp-modal-summary { display: flex; align-items: baseline; gap: 18px; font-size: 13px;
  color: var(--sp-ink-muted); flex-wrap: wrap; }
.sp-modal-summary b { color: var(--sp-form-label); font-size: 15px; font-weight: 700;
  margin-left: 6px; }
.sp-modal-summary #inv-balance-row.is-change b { color: #0E9C8C; }

/* ---------- Article matrix ----------------------------------------------
   Colours and sizes as tick-boxes, in sets, so choosing the eight sizes a
   shoe actually comes in is eight taps and not a scroll through thirty. */
.sp-optset + .sp-optset { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--sp-form-line); }
.sp-optset-head { display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 8px; }
.sp-optset-head b { font-size: 12.5px; color: var(--sp-form-label); }
.sp-optgrid { display: flex; flex-wrap: wrap; gap: 8px; }
.sp-opt { display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
  background: #fff; border: 1px solid var(--sp-field-border); border-radius: var(--sp-radius);
  padding: 7px 12px; font-size: 13px; min-height: 38px; user-select: none; }
.sp-opt:hover { border-color: var(--sp-field-focus); }
.sp-opt:has(input:checked) { border-color: var(--sp-field-focus); background: var(--sp-form-surface);
  font-weight: 600; color: var(--sp-form-label); }

/* What the form is about to create, said before it creates it. */
.sp-article-count { font-size: 13px; color: var(--sp-ink-muted); align-self: center; }
.sp-article-count.is-ok   { color: var(--sp-form-label); font-weight: 600; }
.sp-article-count.is-warn { color: #C67C1E; font-weight: 600; }

/* Adding a colour or size without leaving the form. */
.sp-optnew { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 10px;
  padding: 10px; background: #fff; border: 1px dashed var(--sp-field-border);
  border-radius: var(--sp-radius); }
.sp-optnew[hidden] { display: none; }
.sp-optnew [data-value] { width: 180px; }
.sp-optnew [data-code]  { width: 100px; }
.sp-optnew-msg { font-size: 12px; color: var(--sp-ink-muted); }
.sp-optnew-msg.is-bad { color: var(--sp-danger); }
/* A just-added option is easy to lose among thirty existing ones. */
.sp-opt.is-new { animation: sp-optflash 900ms ease-out; }
@keyframes sp-optflash { 0% { background: #D7F0EA; } 100% { background: var(--sp-form-surface); } }

/* A line whose quantity just moved, so adding the same product twice is
   visibly a change and not a no-op. */
.doc-line.is-new > td { animation: sp-lineflash 700ms ease-out; }
@keyframes sp-lineflash { 0% { background: #D7F0EA; } 100% { background: transparent; } }







.form-control, .form-select {
  background-color: var(--sp-field);
  border: 1px solid var(--sp-field-border); border-radius: var(--sp-radius);
  font-size: 13.5px; padding: 8px 11px; color: var(--sp-ink);
}
/* A select draws its own chevron over the right-hand padding, so the
   shorthand above must not be allowed to take that space back — the arrow
   would sit on top of the text. Only shows up on a narrow select, where
   there is no slack for it to hide in. */
.form-select { padding-right: 2.1rem; background-position: right 0.65rem center; }

.form-control::placeholder { color: #98A2B3; }

/* Filling something in lifts it to white: the field you are working in is
   then the brightest thing on the panel. */
.form-control:focus, .form-select:focus {
  background-color: var(--sp-surface);
  border-color: var(--sp-field-focus); box-shadow: 0 0 0 3px var(--sp-field-ring);
}
.form-control:disabled, .form-select:disabled,
.form-control[readonly] { background-color: #E8EAEE; color: var(--sp-ink-muted); }

/* ---------- Small buttons in table rows ---------------------------------*/
.sp-btn-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: var(--sp-radius);
  border: 1px solid var(--sp-border); background: var(--sp-surface);
  color: var(--sp-ink-muted); font-size: 14px; text-decoration: none;
  transition: all .12s ease;
}
.sp-btn-icon:hover { border-color: var(--sp-accent); color: var(--sp-accent); background: var(--sp-accent-100); }
.sp-btn-icon.sp-btn-danger:hover { border-color: var(--sp-danger); color: var(--sp-danger); background: #FCEBEB; }
.sp-btn-icon.sp-btn-warn:hover   { border-color: #C67C1E; color: #C67C1E; background: #FDF4E7; }
.sp-btn-icon + .sp-btn-icon { margin-left: 4px; }

/* ---------- Permission checklist ---------------------------------------*/
.sp-perm-module { background: var(--sp-form-surface); border: 1px solid var(--sp-form-line);
  border-radius: var(--sp-radius-lg); margin-bottom: 12px; overflow: hidden; }
.sp-perm-module-head {
  display: flex; align-items: center; justify-content: space-between;
  background: #E8EFFB; padding: 10px 14px; border-bottom: 1px solid var(--sp-form-line);
}
.sp-perm-module-name { font-size: 12.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: var(--sp-form-label); }
.sp-perm-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 10px; padding: 14px; }
.sp-perm-item { display: flex; align-items: flex-start; gap: 8px; font-size: 13px; color: var(--sp-ink); }
.sp-perm-item code { font-size: 11px; color: var(--sp-ink-muted); display: block; }
.sp-perm-blurb { font-size: 11.5px; color: var(--sp-ink-muted); display: block; line-height: 1.45; }
.form-check-input:checked { background-color: var(--sp-accent); border-color: var(--sp-accent); }
.form-check-input:focus { border-color: var(--sp-accent); box-shadow: 0 0 0 3px var(--sp-accent-100); }

/* ---------- Filter bar --------------------------------------------------*/
/* A filter bar is a form, so it wears the same clothes. */
.sp-filter-bar {
  display: flex; gap: 10px; flex-wrap: wrap; align-items: flex-end;
  background: var(--sp-form-surface); border: 1px solid var(--sp-form-line);
  border-radius: var(--sp-radius-lg); padding: 14px; margin-bottom: 14px;
}

/* ---------- Audit diff cell --------------------------------------------*/
.sp-diff { font-family: var(--sp-font-num); font-size: 11.5px; line-height: 1.5; margin: 0; white-space: pre-wrap; word-break: break-word; }
.sp-diff-old { color: var(--sp-danger); }
.sp-diff-new { color: var(--sp-success); }

/* ---------- Phase 2B — product media -----------------------------------*/
.sp-thumb {
  width: 30px; height: 30px; object-fit: cover; border-radius: 5px;
  border: 1px solid var(--sp-border); margin-right: 8px; vertical-align: middle;
}
.sp-image-preview {
  max-width: 140px; max-height: 140px; object-fit: cover;
  border: 1px solid var(--sp-border); border-radius: var(--sp-radius);
}

/* ---------- Phase 3 — stock quantities ---------------------------------*/
.sp-qty-in   { color: var(--sp-success); font-weight: 600; }
.sp-qty-out  { color: var(--sp-danger);  font-weight: 600; }
.sp-qty-low  { color: var(--sp-warning); font-weight: 600; }

/* =========================================================================
   Phase 5 — Point of Sale
   ========================================================================= */
.sp-pos-results {
  position: absolute; z-index: 50; margin-top: 4px;
  background: var(--sp-surface); border: 1px solid var(--sp-border);
  border-radius: var(--sp-radius); box-shadow: var(--sp-shadow-md);
  max-height: 320px; overflow-y: auto; width: min(520px, 90vw);
}
.sp-pos-result {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  width: 100%; text-align: left; padding: 9px 12px; background: none;
  border: 0; border-bottom: 1px solid var(--sp-border); font-size: 13.5px; color: var(--sp-ink);
}
.sp-pos-result:last-child { border-bottom: 0; }
.sp-pos-result:hover { background: var(--sp-accent-100); }
.sp-pos-result small { display: block; color: var(--sp-ink-muted); font-size: 11.5px; }

.sp-pos-summary { position: sticky; top: calc(var(--sp-topbar-h) + 16px); }
.sp-pos-line {
  display: flex; justify-content: space-between; align-items: baseline;
  padding: 6px 0; font-size: 13.5px; color: var(--sp-ink-muted);
}
.sp-pos-line span:last-child { color: var(--sp-ink); font-weight: 600; }
.sp-pos-total {
  border-top: 1px solid var(--sp-border); margin-top: 6px; padding-top: 10px;
  font-size: 15px; font-weight: 650;
}
.sp-pos-total span:last-child { font-size: 20px; color: var(--sp-accent); }

/* method | amount | reference | remove.
   Flexible with minimums rather than rigid tracks: in the POS side column
   the fixed 100px/90px/30px tracks left the method select about 2px of
   usable width, so "Cash" had nowhere to render at all. Where all four no
   longer fit on one line the reference wraps onto its own instead of
   everything being crushed. */
.sp-pay-row {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: 6px; margin-bottom: 6px;
}
/* 132px is measured, not guessed: the longest method label is "Bank
   Transfer" at 79px, plus the field padding and the chevron's reserved
   space. Anything less clips it. */
.sp-pay-row > select { flex: 2 1 132px; min-width: 132px; }
/* The amount and the reference give way first. They hold "0.00" and a short
   reference, so they still read at 56px, whereas the method select cannot go
   below its longest label and the remove button is a fixed square. Letting
   these two absorb the squeeze keeps all four on one line, which matters
   because the remove button is the last child: any wrap strands it alone. */
.sp-pay-row > input { flex: 1 1 76px; min-width: 56px; }

/* Below about 290px all four cannot share a line, and overflowing would
   cut the row off. It wraps instead — but a flexible field alone on the
   second line would grow to the full width and push the remove button down
   again, so the reference is capped to leave the button's 30px beside it. */
.sp-pay-row > input[type="text"] { max-width: calc(100% - 36px); }
.sp-pay-row > button, .sp-pay-row > span { flex: 0 0 30px; }

/* ---------- Receipt (print) --------------------------------------------*/
.sp-receipt {
  max-width: 320px; margin: 0 auto; padding: 16px;
  font-family: var(--sp-font-num); font-size: 12px; color: #000;
}
.sp-receipt h2 { font-size: 15px; text-align: center; margin: 0 0 2px; }
.sp-receipt .sp-receipt-meta { text-align: center; font-size: 11px; margin-bottom: 10px; }
.sp-receipt table { width: 100%; border-collapse: collapse; }
.sp-receipt th, .sp-receipt td { padding: 2px 0; vertical-align: top; }
.sp-receipt thead th { border-bottom: 1px dashed #000; text-align: left; font-size: 11px; }
.sp-receipt .sp-receipt-totals { border-top: 1px dashed #000; margin-top: 6px; padding-top: 6px; }
.sp-receipt .sp-receipt-foot { text-align: center; margin-top: 12px; font-size: 11px; }
.sp-receipt .num { text-align: right; }
@media print {
  .sp-no-print { display: none !important; }
  body { background: #fff; }
}

/* ---------- Phase 8 — warranty status -----------------------------------*/
.sp-warranty-box {
  border: 1px solid var(--sp-border); border-left-width: 4px;
  border-radius: var(--sp-radius); padding: 10px 14px; font-size: 13.5px;
  background: var(--sp-bg);
}
.sp-warranty-box.is-covered { border-left-color: var(--sp-success); background: #EAF7F0; }
.sp-warranty-box.is-expired { border-left-color: var(--sp-danger);  background: #FCEBEB; }
.sp-warranty-box.is-unknown { border-left-color: var(--sp-ink-muted); }

/* =========================================================================
   Dashboard watermark
   Applied only where the Dashboard controller sets $pageClass, so no other
   form gets a background. The image is pre-lightened onto the canvas colour;
   the mask fades its edges so it melts into the page instead of showing as
   a rectangle. It sits behind everything and ignores the pointer.
   ========================================================================= */
/* No negative margins here. They were once used to bleed this colour to
   the window edge, but .sp-dashboard-bg IS .sp-content, so -22px on each
   side made the element 44px wider than its container and left the whole
   dashboard scrolling 22px sideways. The canvas grey and the page grey are
   three units apart, so the bleed bought nothing worth a scrollbar. */
.sp-dashboard-bg { position: relative; background: var(--sp-dash-bg); }

.sp-dashboard-bg::before {
  content: "";
  position: fixed;
  right: 0;
  bottom: 0;
  width: min(46vw, 720px);
  height: min(92vh, 1240px);
  background: url("../img/dashboard-bg.jpg") right bottom / contain no-repeat;
  /* Fade out towards the content so there is no visible edge */
  -webkit-mask-image: linear-gradient(to left, #000 0%, rgba(0,0,0,0.85) 42%, transparent 92%),
                      linear-gradient(to top,  #000 0%, rgba(0,0,0,0.85) 55%, transparent 96%);
  -webkit-mask-composite: source-in;
          mask-image: linear-gradient(to left, #000 0%, rgba(0,0,0,0.85) 42%, transparent 92%),
                      linear-gradient(to top,  #000 0%, rgba(0,0,0,0.85) 55%, transparent 96%);
          mask-composite: intersect;
  opacity: 0.85;
  pointer-events: none;
  z-index: 0;
}

/* Dashboard content must sit above the watermark */
.sp-dashboard-bg > * { position: relative; z-index: 1; }

/* On narrow screens it would sit under the cards and hurt legibility */
@media (max-width: 991px) {
  .sp-dashboard-bg::before { display: none; }
}

@media print {
  .sp-dashboard-bg::before { display: none; }
}

/* ---------- Business profile tiles -------------------------------------*/
/* Whole-tile targets rather than bare checkboxes: this screen is used once
   at setup, on a touch device as often as a desktop, and mis-ticking a
   trade quietly changes what the customer sees. */
.sp-profile-grid {
  display: grid; gap: 10px;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
}
.sp-profile {
  display: flex; align-items: flex-start; gap: 10px; cursor: pointer;
  padding: 12px 14px; margin: 0;
  background: var(--sp-surface);
  border: 1px solid var(--sp-border);
  border-radius: var(--sp-radius-lg);
  transition: border-color .15s ease, background .15s ease, box-shadow .15s ease;
}
.sp-profile:hover { border-color: var(--sp-accent); }
.sp-profile:has(input:checked) {
  border-color: var(--sp-accent);
  background: var(--sp-accent-100);
  box-shadow: inset 0 0 0 1px var(--sp-accent);
}
.sp-profile input { margin-top: 2px; flex: none; }
.sp-profile-body { display: flex; flex-direction: column; gap: 2px; }
.sp-profile-name { font-size: 13px; font-weight: 600; color: var(--sp-ink); }
.sp-profile-blurb { font-size: 12px; color: var(--sp-ink-muted); line-height: 1.4; }

.sp-perm-item input:disabled + label { opacity: .75; }

/* What distinguishes one line from the next at the till — Black, XL.
   Reads as a badge rather than prose so it survives a fast scan. */
.sp-pos-variant {
  display: inline-block; margin-left: 8px; font-style: normal;
  font-size: 11px; font-weight: 600; letter-spacing: .2px;
  color: var(--sp-accent-600, var(--sp-accent));
  background: var(--sp-accent-100); border-radius: 999px; padding: 1px 8px;
  vertical-align: middle;
}

/* ---------- Type-ahead combo (customer at the till) ---------------------*/
.sp-combo { position: relative; }
/* Full width of the field it belongs to, unlike the product search which
   overlays the wider page. */
.sp-combo-results { width: 100%; }
.sp-combo .form-control { padding-right: 34px; }

/* Clears back to walk-in. Only shown once somebody is actually chosen. */
.sp-combo-clear {
  position: absolute; top: 7px; right: 8px;
  width: 24px; height: 24px; padding: 0; line-height: 1;
  display: flex; align-items: center; justify-content: center;
  border: 0; border-radius: 50%; cursor: pointer;
  background: transparent; color: var(--sp-ink-muted); font-size: 14px;
}
.sp-combo-clear:hover { background: var(--sp-field-border); color: var(--sp-danger); }

/* Keyboard cursor. Distinct from :hover so arrowing down is visible while
   the mouse is somewhere else entirely. */
.sp-pos-result.is-cursor { background: var(--sp-accent-100); box-shadow: inset 2px 0 0 var(--sp-accent); }

/* Maker's mark at the foot of the user menu. Inert by design — it sits
   directly under Sign Out, so it must not look or behave like a target. */
.sp-menu-mark {
  padding: 8px 16px 4px;
  font-size: 11px; line-height: 1.6; color: var(--sp-ink-muted);
  cursor: default; user-select: none; white-space: nowrap;
}
.sp-menu-mark > div:first-child { font-weight: 600; color: var(--sp-form-label); }

/* A product name that opens its detail page. Reads as text until you point
   at it — an underlined link in every cart row would be visual noise. */
a.sp-td-strong { color: inherit; text-decoration: none; }
a.sp-td-strong:hover { color: var(--sp-field-focus); text-decoration: underline; }

/* The printer a document is meant for, on the print button. The browser
   chooses the device, so the most the page can do is say which one. */
.sp-print-target {
  font-size: 11px; font-weight: 600; opacity: .75;
  padding-left: 6px; border-left: 1px solid currentColor; margin-left: 4px;
}

/* =========================================================================
   Printable documents — invoice preview
   Two shapes of the same invoice. On screen each sits on a sheet the width
   it will actually print, so the preview is a preview and not just the page
   in a box. On paper the stage disappears and only the document remains.
   ========================================================================= */
.sp-preview { background: #E7EBF1; margin: 0; }

.sp-preview-bar {
  position: sticky; top: 0; z-index: 10;
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 12px 18px; background: var(--sp-surface);
  border-bottom: 1px solid var(--sp-border); flex-wrap: wrap;
}
.sp-preview-switch { display: flex; align-items: center; gap: 4px; font-size: 12.5px;
  margin: 0 auto;
  background: var(--sp-field); border-radius: 999px; padding: 3px; }
.sp-preview-switch > * { padding: 5px 14px; border-radius: 999px; text-decoration: none; color: var(--sp-ink-muted); }
.sp-preview-switch .is-current { background: var(--sp-surface); color: var(--sp-form-label); font-weight: 600; }
.sp-preview-switch a:hover { color: var(--sp-field-focus); }

.sp-preview-stage { padding: 24px 16px 48px; display: flex; justify-content: center; }
.sp-preview-stage .sp-sheet {
  background: #fff; box-shadow: 0 6px 24px rgba(15, 23, 42, .14);
}
/* 210mm and 80mm: the real widths, so what you see is the line breaks you get. */
.sp-sheet-a4      .sp-sheet { width: 210mm; min-height: 297mm; padding: 14mm 14mm 12mm; }
.sp-sheet-receipt .sp-sheet { width: 80mm; padding: 6mm 4mm; }

/* ---------- 80 mm slip --------------------------------------------------*/
/* Monospaced so columns line up on a thermal head, which is what a till
   slip has always looked like and what makes it quick to scan. */
.sp-slip { font-family: 'Consolas', 'DejaVu Sans Mono', ui-monospace, monospace;
  font-size: 11px; line-height: 1.4; color: #000; }
.sp-slip-head { text-align: center; }
.sp-slip-name { font-size: 15px; font-weight: 700; letter-spacing: .02em; margin-bottom: 2px; }
.sp-slip-rule { border-top: 1px dashed #000; margin: 6px 0; }
.sp-slip-title { text-align: center; font-weight: 700; letter-spacing: .14em; margin-bottom: 5px; }
.sp-slip-meta > div, .sp-slip-totals > div, .sp-slip-item-calc {
  display: flex; justify-content: space-between; gap: 8px;
}
.sp-slip-meta > div > span:first-child { color: #333; }
.sp-slip-item { margin-bottom: 5px; }
.sp-slip-item-name { font-weight: 700; }
.sp-slip-serial { font-size: 10px; padding-left: 8px; }
.sp-slip-totals .grand { font-size: 13px; font-weight: 700; border-top: 1px solid #000;
  margin-top: 4px; padding-top: 4px; }
.sp-slip-footer { text-align: center; font-size: 10px; margin-top: 4px; }

@media print {
  .sp-preview { background: #fff; }
  .sp-preview-stage { padding: 0; display: block; }
  .sp-preview-stage .sp-sheet {
    width: auto !important; min-height: 0 !important; padding: 0 !important;
    box-shadow: none !important;
  }
}

/* Choosing a print format. Two large targets rather than a dropdown — this
   is a decision made in a hurry, often on a touch screen. */
.sp-print-pick { display: grid; gap: 10px; }
.sp-print-choice {
  display: flex; align-items: center; gap: 14px; text-decoration: none;
  padding: 14px 16px; border: 1px solid var(--sp-form-line);
  border-radius: var(--sp-radius-lg); background: var(--sp-form-surface);
  color: var(--sp-ink); transition: border-color .15s ease, background .15s ease;
}
.sp-print-choice:hover { border-color: var(--sp-field-focus); background: #EAF2FE; }
.sp-print-choice i { font-size: 24px; color: var(--sp-field-focus); flex: none; }
.sp-print-choice strong { display: block; font-size: 14px; color: var(--sp-form-label); }
.sp-print-choice small { display: block; font-size: 11.5px; color: var(--sp-ink-muted); margin-top: 1px; }

/* ---------- A4 tax invoice ----------------------------------------------
   Built to the supplied reference: navy masthead, billed-to band, banded
   item table, payment panel beside a totals card with the balance called
   out in amber. Colours are fixed rather than tokenised — this is a
   document that leaves the building, so it must look the same whatever the
   application theme becomes.
   ------------------------------------------------------------------------*/
.sp-inv { --nv: #1C3E5E; --nv-2: #24557E; --ink: #1F2937; --mut: #667283;
  --line: #DCE3EC; --band: #EEF3F8; --amber-bg: #FDF0DC; --amber: #B5701C;
  color: var(--ink); font-size: 11.5px; line-height: 1.45; }

/* The masthead bleeds to the sheet edge, so it cancels the sheet padding. */
.sp-inv-head {
  background: var(--nv); color: #fff; display: flex; justify-content: space-between;
  align-items: flex-start; gap: 20px; padding: 16mm 14mm 12mm;
  margin: -14mm -14mm 0;
}
.sp-inv-brand { display: flex; gap: 14px; align-items: flex-start; }
.sp-inv-logo {
  width: 46px; height: 46px; flex: none; border-radius: 9px; background: #fff;
  color: var(--nv); font-size: 26px; font-weight: 800; line-height: 46px; text-align: center;
}
.sp-inv-company { font-size: 22px; font-weight: 800; letter-spacing: -.01em; line-height: 1.1; }
.sp-inv-company-sub { font-size: 10px; color: #B7C7D8; margin-top: 4px; line-height: 1.5; }
.sp-inv-headright { text-align: right; }
.sp-inv-doctype { font-size: 22px; font-weight: 800; letter-spacing: .02em; }
.sp-inv-doctype-sub { font-size: 10px; color: #B7C7D8; margin-top: 3px; }

/* Section headings share one look throughout the sheet. */
.sp-inv-h { font-size: 11px; font-weight: 800; letter-spacing: .04em; color: var(--nv); }
.sp-inv-h-section { margin: 14px 0 6px; }
.sp-inv-h-sub { font-size: 9.5px; margin-bottom: 5px; }

.sp-inv-band {
  display: grid; grid-template-columns: 1.25fr 1fr; gap: 28px;
  background: #F7FAFD; border: 1px solid var(--line); border-radius: 6px;
  padding: 12px 16px; margin-top: 14px; font-size: 11px; color: var(--mut);
}
.sp-inv-band .sp-inv-h { margin-bottom: 5px; }
.sp-inv-party { font-weight: 700; color: var(--ink); font-size: 12px; }
.sp-inv-meta { width: 100%; border-collapse: collapse; }
.sp-inv-meta td { padding: 1.5px 0; }
.sp-inv-meta td:first-child { color: var(--mut); }
.sp-inv-meta td:last-child { text-align: right; font-weight: 700; color: var(--nv); }

.sp-inv-items { width: 100%; border-collapse: collapse; font-size: 11px; }
.sp-inv-items thead th {
  background: var(--nv-2); color: #fff; font-size: 9px; font-weight: 700;
  letter-spacing: .05em; padding: 7px 8px; text-align: left; white-space: nowrap;
}
.sp-inv-items thead th.num { text-align: right; }
.sp-inv-items thead th.idx { width: 26px; text-align: center; background: var(--nv); }
.sp-inv-items tbody td { padding: 8px; border-bottom: 1px solid var(--line);
  border-right: 1px solid var(--line); vertical-align: middle; }
.sp-inv-items tbody td:first-child { border-left: 1px solid var(--line); }
.sp-inv-items thead th { border-right: 1px solid rgba(255,255,255,.18); }
.sp-inv-items thead th:last-child { border-right: 0; }
.sp-inv-items tbody tr.alt td { background: var(--band); }
.sp-inv-items td.idx { text-align: center; color: var(--mut); }
.sp-inv-items td.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.sp-inv-items td.strong { font-weight: 700; }
.sp-inv-item { font-weight: 700; }
.sp-inv-ref { font-size: 9.5px; color: var(--mut); margin-top: 1px; }
.sp-inv-serials { margin-top: 3px; display: flex; flex-wrap: wrap; gap: 4px; }
.sp-inv-serials span {
  font-size: 9px; border: 1px solid #C4D3E4; border-radius: 3px; padding: 0 5px;
  color: var(--nv); font-variant-numeric: tabular-nums;
}

.sp-inv-bottom { display: grid; grid-template-columns: 1fr 300px; gap: 22px; margin-top: 18px; }
.sp-inv-panel { border: 1px solid var(--line); border-radius: 6px; padding: 12px 14px; }
.sp-inv-panel hr { border: 0; border-top: 1px solid var(--line); margin: 8px 0 10px; }
.sp-inv-payments { width: 100%; border-collapse: collapse; font-size: 10px; }
.sp-inv-payments th {
  background: var(--band); color: var(--nv); font-size: 8.5px; font-weight: 700;
  letter-spacing: .04em; padding: 5px 7px; text-align: left; border: 1px solid var(--line);
}
.sp-inv-payments td { padding: 5px 7px; border: 1px solid var(--line); color: var(--ink); }
.sp-inv-payments .num { text-align: right; font-variant-numeric: tabular-nums; }
.sp-inv-none { font-size: 10.5px; color: var(--mut); }
.sp-inv-notes-h { font-weight: 700; color: var(--nv); font-size: 10.5px; margin-top: 12px; }
.sp-inv-notes { font-size: 10.5px; color: var(--mut); margin-top: 2px; }

.sp-inv-summary { border: 1px solid var(--line); border-radius: 6px; padding: 12px 14px; align-self: start; }
.sp-inv-summary .sp-inv-h { margin-bottom: 8px; }
.sp-inv-row { display: flex; justify-content: space-between; gap: 12px; padding: 5px 0; font-size: 11px; }
.sp-inv-row span:last-child { font-variant-numeric: tabular-nums; white-space: nowrap; }
.sp-inv-row.grand {
  border-top: 2px solid var(--nv); margin-top: 6px; padding-top: 9px;
  font-size: 13.5px; font-weight: 800; color: var(--nv);
}
/* The one number anybody chasing payment actually looks for. */
.sp-inv-due {
  display: flex; justify-content: space-between; gap: 12px;
  background: var(--amber-bg); color: var(--amber); font-weight: 800; font-size: 12.5px;
  padding: 9px 12px; margin: 8px -14px -12px; border-radius: 0 0 6px 6px;
}
.sp-inv-due.settled { background: #E7F6EE; color: #1D7A4C; }
.sp-inv-due span:last-child { font-variant-numeric: tabular-nums; }

.sp-inv-footer {
  display: flex; justify-content: space-between; gap: 16px; margin-top: 22px;
  padding-top: 9px; border-top: 1px solid var(--line);
  font-size: 9.5px; color: var(--mut);
}
.sp-inv-footer .strong { font-weight: 700; color: var(--nv); }

@media print {
  /* Backgrounds are the design here, not decoration. */
  .sp-inv-head, .sp-inv-items thead th, .sp-inv-items tbody tr.alt td,
  .sp-inv-due, .sp-inv-payments th, .sp-inv-band {
    -webkit-print-color-adjust: exact; print-color-adjust: exact;
  }
  .sp-inv-items tr, .sp-inv-bottom { page-break-inside: avoid; }
  .sp-inv-items thead { display: table-header-group; }
}

/* ---------- Dashboard tiles, toned by meaning ---------------------------
   Each tile carries a wash of its own colour rather than a flat white card,
   so the board reads at a glance. Kept in the app's register: the same
   navy/blue/teal family as the menu and the forms, at low saturation, with
   the number itself left dark so it stays the most legible thing on the
   tile. The colour is a label, not decoration — see the view for which
   figure gets which tone.
   ------------------------------------------------------------------------*/
.sp-kpi {
  position: relative; overflow: hidden;
  border-color: var(--tone-line, var(--sp-border));
  background:
    linear-gradient(135deg, var(--tone-wash, #fff) 0%, #fff 68%);
}
/* A stripe down the leading edge — the strongest hint at the smallest cost. */
.sp-kpi::before {
  content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  background: var(--tone, transparent);
}
.sp-kpi .sp-kpi-label { color: var(--tone-ink, var(--sp-ink-muted)); }
/* The figure carries the menu navy rather than the near-black body ink —
   it reads as the headline of the tile without shouting. This rule has to
   win over the base .sp-kpi-value, hence the doubled selector. */
.sp-kpi .sp-kpi-value { color: var(--sp-form-label); }

/* One blue chip on every tile, whatever tone the tile carries. The wash and
   the edge stripe still do the colour-coding; holding the icon constant
   makes the row read as a set rather than nine competing badges. */
.sp-kpi-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; flex: none; border-radius: 9px;
  background: var(--sp-blue); color: #fff; font-size: 17px;
}

.sp-tone-blue   { --tone: #2269B6; --tone-ink: #1B4F8A; --tone-wash: #E9F2FC; --tone-line: #CFE0F4; }
.sp-tone-teal   { --tone: #0E9C8C; --tone-ink: #0B7A6E; --tone-wash: #E6F7F4; --tone-line: #C9EAE4; }
.sp-tone-green  { --tone: #1D9A5C; --tone-ink: #157548; --tone-wash: #E8F7EE; --tone-line: #CBE9D8; }
.sp-tone-amber  { --tone: #C67C1E; --tone-ink: #99601a; --tone-wash: #FDF3E4; --tone-line: #F2DDBE; }
.sp-tone-orange { --tone: #D3703F; --tone-ink: #A85529; --tone-wash: #FDEFE8; --tone-line: #F4D5C5; }
.sp-tone-indigo { --tone: #3F51B5; --tone-ink: #303F8F; --tone-wash: #ECEEFB; --tone-line: #D3D9F1; }
.sp-tone-rose   { --tone: #C2416A; --tone-ink: #9A3354; --tone-wash: #FCEBF1; --tone-line: #F1CDDA; }
.sp-tone-sky    { --tone: #0E8BB8; --tone-ink: #0B6C8F; --tone-wash: #E6F5FB; --tone-line: #C6E4F1; }
.sp-tone-violet { --tone: #7A4BC4; --tone-ink: #5F399B; --tone-wash: #F2ECFC; --tone-line: #DED0F3; }

/* On the dashboard the tiles sit over the watermark, so they need to stay
   opaque rather than letting it bleed through the wash. */
.sp-dashboard-bg .sp-kpi { background-color: #fff; }

@media print {
  .sp-kpi::before, .sp-kpi-icon { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
}

/* ---------- Message box -------------------------------------------------
   One dialog for every question and every notice. Centred, small, with the
   icon carrying the meaning so the shape is read before the words are.
   ------------------------------------------------------------------------*/
.sp-dialog .modal-content { border: 0; border-radius: var(--sp-radius-lg); box-shadow: var(--sp-shadow-md); }
.sp-dialog .modal-body { padding: 26px 24px 6px; }

.sp-dialog-icon {
  width: 54px; height: 54px; margin: 0 auto 14px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%; font-size: 26px;
}
.sp-dialog-icon.is-ask     { background: var(--sp-sky-100);   color: var(--sp-blue); }
.sp-dialog-icon.is-info    { background: var(--sp-sky-100);   color: var(--sp-blue); }
.sp-dialog-icon.is-danger  { background: #FCECEC;             color: var(--sp-danger); }
.sp-dialog-icon.is-error   { background: #FCECEC;             color: var(--sp-danger); }
.sp-dialog-icon.is-success { background: var(--sp-accent-100); color: var(--sp-accent-600); }

.sp-dialog-title { font-size: 16px; font-weight: 700; color: var(--sp-form-label); margin-bottom: 6px; }
.sp-dialog-text  { font-size: 13.5px; color: var(--sp-ink-muted); line-height: 1.5;
                   white-space: pre-line; }   /* a blank line in the message stays a blank line */

.sp-dialog-actions { border-top: 0; justify-content: center; gap: 8px; padding: 18px 24px 24px; }
.sp-dialog-actions .btn { min-width: 96px; }
/* Yes sits on the right, where the eye finishes — and No is what Escape,
   the backdrop and the close button all do. */
.sp-dialog-actions .sp-dialog-yes { order: 2; }
.sp-dialog-actions .sp-dialog-no  { order: 1; }
