/* =========================================================
   SONA ERP — design tokens
   Ink/ivory base, brass = money & primary action,
   maroon = dues & destructive. Hairline borders, no shadows.
   ========================================================= */
:root {
  --ink:        #211D1A;
  --ink-soft:   #58524A;
  --ivory:      #FAF6EE;
  --panel:      #F1EBDD;
  --panel-alt:  #FFFFFF;
  --line:       #D9CFBB;
  --brass:      #A97C3D;
  --brass-dark: #8A6530;
  --maroon:     #6E2331;
  --maroon-soft:#F3E4E1;
  --sage:       #4B6350;
  --sage-soft:  #E7EEE4;
  --radius:     4px;
  --font-display: "Fraunces", Georgia, serif;
  --font-body:    "Inter", -apple-system, "Segoe UI", sans-serif;
}

* { box-sizing: border-box; }
html, body {
  margin: 0;
  padding: 0;
  background: var(--ivory);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.5;
}
h1, h2, h3 { font-family: var(--font-display); font-weight: 700; margin: 0 0 .4em; color: var(--ink); }
h1 { font-size: 1.9rem; }
h2 { font-size: 1.4rem; }
h3 { font-size: 1.15rem; }
a { color: var(--brass-dark); }
label { font-size: .88rem; font-weight: 700; color: var(--ink); display: block; margin-bottom: 4px; }

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

.rail {
  width: 220px;
  flex-shrink: 0;
  background: linear-gradient(180deg, #0F172A 0%, #1E1B4B 100%);
  color: var(--ivory);
  display: flex;
  flex-direction: column;
  padding: 20px 0;
  height: 100vh;
  position: sticky;
  top: 0;
  overflow-y: auto; /* menu scrolls on its own on short screens; the page scroll stays for content */
}
.rail .brand {
  font-family: var(--font-display);
  font-size: 1.2rem;
  padding: 0 20px 18px;
  border-bottom: 1px solid rgba(255,255,255,.1);
  margin-bottom: 8px;
  flex: none;
}
.rail .brand small { display: block; font-family: var(--font-body); font-size: .66rem; letter-spacing: .03em; color: #94A3B8; margin-top: 2px; }
.rail nav {
  flex: 1;
  overflow-y: auto;
  overflow-x: hidden;
  min-height: 0;
  padding: 4px 0;
}
.rail nav::-webkit-scrollbar { width: 5px; }
.rail nav::-webkit-scrollbar-thumb { background: rgba(255,255,255,.15); border-radius: 3px; }
.rail nav a {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 10px 20px;
  color: #CBD5E1;
  text-decoration: none;
  font-size: .87rem;
  border-left: 3px solid transparent;
}
.rail nav a .nav-icon { font-size: .95rem; flex: none; }
.rail nav a:hover { background: rgba(255,255,255,.06); color: #fff; }
.rail nav a.active {
  background: rgba(99,102,241,.22);
  border-left-color: #818CF8;
  color: #fff;
  font-weight: 600;
}
.rail .user-box { padding: 12px 20px 0; border-top: 1px solid rgba(255,255,255,.1); margin-top: 8px; flex: none; }
.rail .user-box .who { font-size: .8rem; color: #94A3B8; }
.rail .user-box a { color: #818CF8; font-size: .8rem; text-decoration: none; }

/* Section headers (top-level items, whether a plain link or a collapsible
   group) get their own accent color, cycling through a small palette so
   the rail reads as organized sections rather than one long flat list —
   matching the reference's colorful per-section icons. */
.rail nav .nav-section-label {
  display: flex; align-items: center; gap: 9px;
  padding: 11px 20px 5px;
  font-size: .7rem; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  color: #94A3B8;
}
.rail nav .nav-section-label .nav-icon { font-size: .85rem; }

/* Expandable submenu (e.g. Scheme Savings > Groups/Members/Receipts/...) */
.rail nav details { border-left: 3px solid transparent; }
.rail nav details.has-active { border-left-color: #818CF8; }
.rail nav details summary {
  display: flex;
  align-items: center;
  gap: 9px;
  justify-content: space-between;
  padding: 10px 20px;
  color: #CBD5E1;
  font-size: .87rem;
  cursor: pointer;
  list-style: none;
}
.rail nav details summary .summary-left { display: flex; align-items: center; gap: 9px; }
.rail nav details summary::-webkit-details-marker { display: none; }
.rail nav details summary:hover { background: rgba(255,255,255,.06); color: #fff; }
.rail nav details.has-active summary { background: rgba(99,102,241,.22); color: #fff; font-weight: 600; }
.rail nav details summary .chevron { font-size: .7rem; transition: transform .15s ease; color: #64748B; }
.rail nav details[open] summary .chevron { transform: rotate(90deg); }
.rail nav .sub-nav { padding: 2px 0 6px; }
.rail nav .sub-nav a {
  padding: 8px 20px 8px 40px;
  font-size: .82rem;
  color: #94A3B8;
  border-left: none;
}
.rail nav .sub-nav a:hover { background: rgba(255,255,255,.06); color: #fff; }
.rail nav .sub-nav a.active {
  background: rgba(99,102,241,.22);
  color: #fff;
  font-weight: 600;
}
@media (max-width: 760px) {
  .rail nav details summary .label, .rail nav details summary .chevron, .rail nav .sub-nav { display: none; }
}

.main { flex: 1; min-width: 0; }

/* ---------- Rate ticker (the hero strip) ---------- */
.ticker {
  display: flex;
  align-items: center;
  gap: 34px;
  padding: 14px 30px;
  background: var(--panel);
  border-bottom: 1px solid var(--line);
  flex-wrap: wrap;
}
.ticker .date { font-size: .82rem; color: var(--ink-soft); margin-right: 6px; }
.ticker .rate { display: flex; align-items: baseline; gap: 7px; }
.ticker .rate .metal { font-size: .82rem; color: var(--ink-soft); }
.ticker .rate .value { font-family: var(--font-display); font-size: 1.15rem; color: var(--brass-dark); font-weight: 600; }
.ticker .rate .value.stale { color: var(--maroon); }
.ticker .edit-link { margin-left: auto; font-size: .82rem; }

/* ---------- Content ---------- */
.content { padding: 28px 32px 60px; max-width: none; }
.content.narrow { max-width: 660px; }

.page-head { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: 20px; flex-wrap: wrap; gap: 10px; }
.page-head p { color: var(--ink-soft); margin: 2px 0 0; font-size: .9rem; }

.tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--line); margin-bottom: 22px; }
.tabs a { padding: 9px 16px; text-decoration: none; color: var(--ink-soft); font-size: .88rem; border-bottom: 2px solid transparent; margin-bottom: -1px; }
.tabs a.active { color: var(--ink); border-bottom-color: var(--brass); font-weight: 600; }

.panel {
  background: var(--panel-alt);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 22px;
  margin-bottom: 20px;
}
.panel + .panel { margin-top: 0; }

.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.grid-3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 16px; }
.grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; }
@media (max-width: 760px) {
  .grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr; }
  .rail { width: 64px; }
  .rail .brand, .rail nav a span.label, .rail .user-box .who { display: none; }
}

.field { margin-bottom: 14px; }
input[type=text], input[type=number], input[type=date], input[type=password], select, textarea {
  width: 100%;
  padding: 9px 11px;
  border: 1.5px solid var(--brass);
  border-radius: var(--radius);
  background: #fff;
  font-family: var(--font-body);
  font-size: .92rem;
  color: var(--ink);
  box-shadow: inset 0 1px 2px rgba(33,29,26,.06);
}
input:focus, select:focus, textarea:focus {
  outline: 2px solid var(--brass);
  outline-offset: 1px;
  border-color: var(--brass-dark);
}
.hint { font-size: .78rem; color: var(--ink-soft); margin-top: 3px; }

/* Segmented control — used for the real either/or business choices:
   percent vs value, per-gram vs flat */
.segmented { display: inline-flex; border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; }
.segmented button {
  border: none;
  background: var(--ivory);
  padding: 8px 14px;
  font-size: .85rem;
  color: var(--ink-soft);
  cursor: pointer;
  font-family: var(--font-body);
}
.segmented button + button { border-left: 1px solid var(--line); }
.segmented button.active { background: var(--brass); color: #fff; font-weight: 600; }

button.btn, a.btn, input[type=submit] {
  display: inline-block;
  background: var(--brass);
  color: #fff;
  border: none;
  padding: 10px 18px;
  border-radius: var(--radius);
  font-size: .9rem;
  font-weight: 600;
  cursor: pointer;
  text-decoration: none;
  font-family: var(--font-body);
}
button.btn:hover, a.btn:hover, input[type=submit]:hover { background: var(--brass-dark); }
button.btn.secondary { background: var(--panel); color: var(--ink); border: 1.5px solid var(--brass); font-weight: 600; }
button.btn.secondary:hover { background: var(--brass); color: #fff; }
button.btn.danger { background: var(--maroon); }
button.btn.ghost { background: var(--maroon-soft); color: var(--maroon); padding: 9px 16px; font-weight: 600; border: 1.5px solid var(--maroon); border-radius: var(--radius); box-shadow: 0 1px 2px rgba(0,0,0,.04); }
button.btn.ghost:hover { background: var(--maroon); color: #fff; }

table.data { width: 100%; border-collapse: collapse; font-size: .89rem; }
table.data th {
  text-align: left;
  font-size: .8rem;
  text-transform: uppercase;
  letter-spacing: .03em;
  color: var(--ink);
  border-bottom: 2px solid var(--line);
  padding: 8px 10px;
  font-weight: 700;
}
table.data td { padding: 10px 10px; border-bottom: 1px solid var(--line); vertical-align: top; }
table.data tr:last-child td { border-bottom: none; }
table.data td.num, table.data th.num { text-align: right; font-variant-numeric: tabular-nums; }
table.data tr.total-row td { font-weight: 700; border-top: 1px solid var(--ink); }

.badge { display: inline-block; padding: 2px 9px; border-radius: 10px; font-size: .74rem; font-weight: 600; }
.badge.in-stock { background: var(--sage-soft); color: var(--sage); }
.badge.sold { background: var(--panel); color: var(--ink-soft); }
.badge.with-customer { background: #FBEFD9; color: var(--brass-dark); }
.badge.due { background: var(--maroon-soft); color: var(--maroon); }

.stat-card { background: var(--panel-alt); border: 1px solid var(--line); border-radius: var(--radius); padding: 18px 20px; }
.stat-card .label { font-size: .78rem; color: var(--ink-soft); }
.stat-card .value { font-family: var(--font-display); font-size: 1.6rem; margin-top: 4px; }
.stat-card .value.brass { color: var(--brass-dark); }
.stat-card .value.maroon { color: var(--maroon); }

.stone-row { display: grid; grid-template-columns: 2fr 1fr 1fr 1fr 1fr auto auto; gap: 10px; align-items: end; margin-bottom: 10px; }
.payment-row { display: grid; grid-template-columns: 2fr 1fr 1fr 1fr 1fr auto; gap: 10px; align-items: end; margin-bottom: 10px; }
.payment-row { grid-template-columns: 1.4fr 1fr 1fr 1fr auto; }

.calc-box { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); padding: 16px 20px; }
.calc-box .line { display: flex; justify-content: space-between; padding: 5px 0; font-size: .9rem; }
.calc-box .line.total { border-top: 1px solid var(--ink); margin-top: 6px; padding-top: 10px; font-weight: 700; font-size: 1.05rem; }
.calc-box .line .val { font-variant-numeric: tabular-nums; }

.alert { padding: 12px 16px; border-radius: var(--radius); font-size: .88rem; margin-bottom: 16px; }
.alert.success { background: var(--sage-soft); color: var(--sage); border: 1px solid #cfe0cd; }
.alert.error { background: var(--maroon-soft); color: var(--maroon); border: 1px solid #e3c4c4; }

.empty-state { text-align: center; padding: 50px 20px; color: var(--ink-soft); }
.empty-state h3 { color: var(--ink); }

/* Barcode print label */
.barcode-label {
  border: 1px dashed var(--line);
  border-radius: var(--radius);
  /* Trimmed from 10px 14px — in a genuinely 12mm-tall label, 10px (≈2.6mm)
     of padding on top AND bottom (≈5.3mm combined) was eating more than
     a third of the entire available height on its own, on top of the
     code graphic's own already-tight footprint. */
  padding: 1px 6px;
  text-align: center;
  background: #fff;
  width: 200px;
}
.barcode-label .bl-shop { font-family: var(--font-display); font-size: calc(.26rem * var(--info-font-scale, 1)); font-weight: 700; line-height: 1; }
.barcode-label .bl-item { font-size: calc(.4rem * var(--info-font-scale, 1)); color: var(--ink); font-weight: 700; margin-bottom: 0; line-height: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.barcode-label .code-slot {
  display: flex; align-items: flex-start; justify-content: center;
  min-height: 42px; width: 88px; max-width: 88px; overflow: hidden;
  /* Explicit quiet zone: qrcodejs draws modules edge-to-edge with no
     margin of its own (confirmed by reading its rendering code), so
     without this a printed QR has zero blank border — and a scanner
     needs one (spec recommends ~4 modules) to even recognize a QR
     pattern, not just decode it faster. box-sizing:border-box keeps
     the declared 88px as the TOTAL box (so the grid math elsewhere
     that assumes this width stays correct); the padding becomes real
     blank space around the rendered code, not extra size on top of it. */
  padding: 6px; box-sizing: border-box;
}
.barcode-label .code-slot svg, .barcode-label .code-slot canvas, .barcode-label .code-slot img, .barcode-label .code-slot table { max-width: 100% !important; max-height: 100% !important; width: auto !important; height: auto !important; }
.barcode-label .code-slot img { image-rendering: pixelated; }
.barcode-label .bl-code { font-size: .74rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.barcode-label .bl-stones-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0 6px; text-align: left; }
.barcode-label .bl-stones { font-size: calc(.38rem * var(--stones-font-scale, 1)); color: var(--brass); font-weight: 700; line-height: 1.15; white-space: normal; word-break: break-word; }
.barcode-label .bl-purity { font-size: .48rem; color: var(--ink); font-weight: 700; line-height: 1; }
.barcode-label .bl-pcs { font-size: calc(.34rem * var(--info-font-scale, 1)); color: var(--ink); font-weight: 700; line-height: 1; }
.barcode-label .bl-weight { font-size: calc(.32rem * var(--info-font-scale, 1)); color: var(--ink); font-weight: 700; line-height: 1; }

.barcode-label .bl-inner { display: block; }
.barcode-label .bl-tail { display: none; }
.barcode-label .bl-row { display: block; }
.barcode-label .bl-code-col, .barcode-label .bl-info-col { display: block; }

/* Jewelry loop-tag sizes (80x12, 91x15) are physically landscape strips:
   barcode+code on one side, compact item/purity/stone/weight text on the
   other, both within the same short band — then a blank "tail" beyond a
   fold line for threading through the piece and folding back to close the
   loop. This is now CSS GRID, not table/table-cell — that switch is the
   actual fix for the persistent page-splitting bug, not another
   page-break tweak layered on the same foundation. Root cause (confirmed
   against Chrome's own documented behavior): page-break-inside/
   break-inside is reliably IGNORED on table-row/table-cell display
   elements in Chrome's print engine — every page-break-inside rule added
   to a table-cell ancestor here was therefore a no-op from the start,
   regardless of how it was worded or how many fallback properties were
   stacked on it. Table layout was chosen specifically to dodge a
   DIFFERENT Chrome print bug (flex layouts paginating unpredictably) —
   but that traded one bug for another, worse one. Grid avoids both: it
   isn't table-cell, so break-inside is actually honored, and it isn't
   flex, so it doesn't inherit that bug either. vertical-align (a
   table-only property) is replaced by align-self, its grid equivalent. */
.barcode-label.size-jewelry80x12, .barcode-label.size-jewelry91x15 {
  display: grid; grid-template-columns: var(--head-width, 68%) 1fr; width: 100%; padding: 0;
}
.barcode-label.size-jewelry80x12 .bl-inner, .barcode-label.size-jewelry91x15 .bl-inner {
  /* align-self was "center" — combined with the 2.2x on-screen magnify
     transform (transform-origin: top left) on the first label, a
     vertically-CENTERED box scaled up from its OWN top-left corner can
     extend upward past where you'd expect, overlapping whatever renders
     above it (the calibration dropdowns/hint text in this case). Using
     "start" keeps this element flush against the top of its row, so
     scaling from top-left grows it predictably downward/rightward only. */
  box-sizing: border-box; align-self: start;
  transform: translate(var(--shift-x, 0mm), var(--shift-y, 0mm)) rotate(var(--flip-deg, 0deg));
}
.barcode-label.size-jewelry80x12 .bl-row, .barcode-label.size-jewelry91x15 .bl-row {
  /* Rebalanced from 32/34/34 — the code column was consistently too
     narrow for a CODE128 barcode or QR to scan reliably (measured: a
     CODE128 encoding an 8-char barcode needs roughly 33mm of real
     width to keep bar width above a scanner's minimum reliable
     threshold; the old 32% share gave it well under half that even
     before quiet-zone padding). Code gets meaningfully more room;
     info and stones give some up — legibility of a few extra mm of
     item/stone text matters far less than the code actually scanning
     at all. */
  display: grid; grid-template-columns: 42% 30% 28%; width: 100%;
}
.barcode-label.size-jewelry80x12 .bl-code-col, .barcode-label.size-jewelry91x15 .bl-code-col {
  padding: 3px 4px 3px 6px; text-align: center; align-self: start;
  break-inside: avoid-page;
}
/* Changed from a vertical stack to a horizontal row — with a genuinely
   12mm-tall physical label, stacking the code graphic (~46px, tied to
   the scan-reliability minimum) with its number text underneath added
   enough extra height on its own to exceed 12mm before anything else on
   the label was even considered. An 80mm-wide label has plenty of
   horizontal room to spare; the 12mm height has almost none. Placing
   the number beside the graphic instead of below it keeps the total
   height close to just the graphic's own height, not graphic+text
   summed together. */
.barcode-label .bl-code-inner { display: flex; flex-direction: row; align-items: center; gap: 3px; min-height: 42px; break-inside: avoid-page; }
/* code-slot used to be flex:0 0 72px (fixed, non-shrinking) — at this
   label's actual computed column width (~56-61px at default calibration
   on jewelry80x12), that fixed 72px alone already exceeds the whole
   column, leaving bl-code's flex:1 1 auto exactly 0px of remaining
   space. With overflow:hidden on bl-code, the result wasn't a visible
   squeeze — the barcode/QR number text disappeared completely, with no
   visual sign anything was wrong. Confirmed by rendering the real CSS
   in a headless browser and reading the computed boxes directly,
   independent of calibration or stone content — this reproduced
   identically with or without a stones column. Fix: give bl-code a
   small guaranteed fixed width so its text can never be squeezed to
   zero, and let the graphic shrink (down to a still-scannable floor)
   to absorb whatever space is actually tight, instead of the other way
   around. */
.barcode-label .bl-code-inner .code-slot { flex: 0 1 88px; min-width: 60px; }
.barcode-label .bl-code-inner .bl-code { flex: 0 0 11px; writing-mode: vertical-rl; text-orientation: mixed; font-size: .22rem; letter-spacing: -0.5px; line-height: 1; margin-top: 0; white-space: nowrap; max-height: 42px; overflow: hidden; }
.barcode-label.size-jewelry80x12 .bl-info-col, .barcode-label.size-jewelry91x15 .bl-info-col {
  padding: 3px 4px; text-align: left; align-self: start;
}
.barcode-label.size-jewelry80x12 .bl-stones-col, .barcode-label.size-jewelry91x15 .bl-stones-col {
  padding: 3px 4px; text-align: left; align-self: start;
  border-left: 1px dashed var(--line);
  transform: translate(var(--stones-shift-x, 0mm), var(--stones-shift-y, 0mm));
}
.barcode-label.size-jewelry80x12 .bl-tail, .barcode-label.size-jewelry91x15 .bl-tail {
  text-align: left; align-self: start;
  border-left: 1px dashed var(--line); padding: 3px 6px;
}
/* "FOLD" label removed from the blank tail column — was purely decorative and not wanted on the printed tag. */
.barcode-label.size-jewelry80x12 .bl-item, .barcode-label.size-jewelry91x15 .bl-item { white-space: normal; }
.barcode-label.size-jewelry80x12 .bl-code, .barcode-label.size-jewelry91x15 .bl-code { font-size: .32rem; line-height: 1; margin-top: 2px; }

/* "Stone details" toggle — the info column (shop name, item, Pcs+
   Purity, G/S/N combined) is now the same content in both modes;
   render_label_info_col() no longer produces two variants. The only
   difference compact mode makes is hiding the itemized per-stone-type
   breakdown column, toggled by .compact-details on the print
   container. */
#print-labels.compact-details .barcode-label .bl-stones-col,
#barcode-labels.compact-details .barcode-label .bl-stones-col { display: none; }

/* N-up grids: real fixed-column layouts (not just flex-wrap) so a printed
   sheet reliably shows exactly N labels per row, matching physical N-up
   label sheet stock. */
#print-labels, #barcode-labels { display: block; }
.barcode-label { margin-bottom: 16px; }
#print-labels.grid-4up, #barcode-labels.grid-4up { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; }
#print-labels.grid-3up, #barcode-labels.grid-3up { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
#print-labels.grid-2up, #barcode-labels.grid-2up { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; }
.grid-4up .barcode-label, .grid-3up .barcode-label, .grid-2up .barcode-label { width: 100%; margin-bottom: 0; }


/* Physical label sizes — font scales down at smaller sizes, but stone/weight
   details stay visible on every size; use the print-calibration sliders
   (head width / shift) to fine-tune fit on your specific printer.
   Jewelry sizes deliberately don't get a padding override here — their
   grid-based layout above already sets padding:0 for a reason (12mm of
   height has no room to spare), and a generic padding here would silently
   re-add exactly what that rule removed. */
.barcode-label.size-xs25x20 { width: 95px; padding: 5px 7px; font-size: .68em; }
.barcode-label.size-sm33x20 { width: 125px; padding: 5px 8px; font-size: .74em; }
.barcode-label.size-med40x20 { width: 151px; font-size: .82em; }
.barcode-label.size-med50x25 { width: 189px; }
.barcode-label.size-jewelry80x12 { width: 302px; font-size: .82em; }
.barcode-label.size-jewelry91x15 { width: 344px; }

@media print {
  .rail, .ticker, .no-print, .sa-announcement-bar, .page-head, .tabs { display: none !important; height: 0 !important; max-height: 0 !important; overflow: hidden !important; margin: 0 !important; padding: 0 !important; border: 0 !important; }
  /* Moved here from inward.php's own inline <style> — as a page-specific
     rule it silently didn't apply anywhere else that renders
     .barcode-label elements (like the Reprint feature on reports.php),
     which kept hitting the exact same trailing-blank-page problem this
     was built to fix, with no way to benefit from the fix already found
     for it. Explicit page-break-after: avoid + a zeroed trailing margin
     on the last label — without this, nothing tells the browser it's
     safe to not start a new page after the final item. */
  #print-labels .barcode-label:last-child { page-break-after: avoid; break-after: avoid-page; margin-bottom: 0 !important; }
  .content { padding: 0; max-width: none; }
  /* Defensive reset: eliminate any residual top spacing from the app
     shell/layout wrappers before the actual label content, regardless
     of the exact source — every screenshot across a long back-and-forth
     on label printing showed a blank first page before content began,
     which is consistent with some margin/padding surviving into print
     even though the elements producing it are hidden. */
  html, body, .app-shell, .main { margin: 0 !important; padding: 0 !important; }
  /* #print-labels itself has a 14px top margin (for comfortable on-screen
     spacing below the calibration controls above it) that was never
     reset for print. Left in place, it pushes only the FIRST label down
     within its own fixed-height page — the very specific, reproducible
     "just the first item is short one line" pattern this took several
     rounds to pin down, since every later label starts fresh on its own
     page and was never affected by this at all. */
  #print-labels { margin-top: 0 !important; }
  /* The dashed borders (outer label edge, column dividers) are on-screen
     cutting/layout guides only — real die-cut label stock doesn't need
     them printed onto the physical tag, and they were showing up on the
     actual printout. border-width now goes to 0, not just border-color
     to transparent — a transparent border is invisible but its WIDTH
     still takes up box-model space, and in a 12mm-tall label even the
     ~0.5mm a 1px top+bottom border occupies is a real fraction of the
     entire available height. */
  .barcode-label, .barcode-label .bl-stones-col, .barcode-label .bl-tail {
    border-width: 0 !important;
  }
}

/* Autocomplete dropdown (customer search) */
.autocomplete-wrap { position: relative; }
.autocomplete-results {
  position: absolute; top: 100%; left: 0; right: 0; z-index: 20;
  background: var(--panel-alt); border: 1px solid var(--line); border-top: none;
  border-radius: 0 0 var(--radius) var(--radius); max-height: 220px; overflow-y: auto;
}
.autocomplete-results .ac-row { padding: 9px 12px; cursor: pointer; font-size: .88rem; border-bottom: 1px solid var(--line); }
.autocomplete-results .ac-row:last-child { border-bottom: none; }
.autocomplete-results .ac-row:hover { background: var(--panel); }
.autocomplete-results .ac-sub { color: var(--ink-soft); font-size: .78rem; }

/* Scanner-gun receiver box */
.scanner-box {
  background: var(--sage-soft);
  border: 1px dashed var(--sage);
  border-radius: var(--radius);
  padding: 16px;
  text-align: center;
  margin-bottom: 16px;
}
.scanner-box .scanner-label { font-size: .78rem; color: var(--sage); font-weight: 600; margin-bottom: 8px; }

/* Mode tab pills (Inventory scan / Home sale / F10 non-GST) */
.pill-tabs { display: flex; gap: 8px; margin-bottom: 16px; flex-wrap: wrap; }
.pill-tabs button {
  padding: 9px 16px; border-radius: 20px; border: 1px solid var(--line);
  background: var(--panel-alt); color: var(--ink-soft); font-size: .85rem; cursor: pointer; font-family: var(--font-body);
}
.pill-tabs button.active { background: var(--ink); color: var(--ivory); border-color: var(--ink); }

/* Print calibration sliders — larger track and thumb than the browser
   default, since these get dragged repeatedly while fine-tuning label
   alignment and a thin default slider is genuinely harder to grab
   precisely, especially inside the print-labels popup. */
input.cal-slider[type="range"] {
  height: 28px; margin: 6px 0;
  -webkit-appearance: none; appearance: none;
  background: transparent; cursor: pointer;
}
input.cal-slider[type="range"]::-webkit-slider-runnable-track {
  height: 8px; border-radius: 4px; background: var(--line);
}
input.cal-slider[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 24px; height: 24px; border-radius: 50%;
  background: var(--brass); border: 2px solid #fff; box-shadow: 0 1px 3px rgba(0,0,0,.3);
  margin-top: -8px; cursor: pointer;
}
input.cal-slider[type="range"]::-moz-range-track {
  height: 8px; border-radius: 4px; background: var(--line);
}
input.cal-slider[type="range"]::-moz-range-thumb {
  width: 24px; height: 24px; border-radius: 50%; border: 2px solid #fff;
  background: var(--brass); box-shadow: 0 1px 3px rgba(0,0,0,.3); cursor: pointer;
}

/* Debugging aid only — strips everything except the QR/barcode graphic
   and its number text, for testing the simplest possible case (does a
   bare code alone reliably print on 1 page?) before testing the full
   label with shop name/item/weights/stones added back in. Applies both
   on screen and during actual print, since the point is to genuinely
   test pagination behavior with minimal content, not just hide things
   visually while still measuring/printing the full label underneath. */
#print-labels.debug-minimal .bl-info-col,
#print-labels.debug-minimal .bl-stones-col {
  display: none !important;
}


/* ---------- Compact screens ----------
   body.compact is set by includes/header.php on every app screen. Same look, tighter spacing, so a whole
   bill or inward entry fits on screen with far less vertical scrolling.
   Screen only — printing uses its own rules. */
@media screen {
  body.compact { font-size: 14px; line-height: 1.4; }
  body.compact .ticker { padding: 7px 24px; gap: 24px; }
  body.compact .ticker .rate .value { font-size: 1.02rem; }
  body.compact .content { padding: 14px 20px 28px; }
  body.compact .page-head { margin-bottom: 8px; }
  body.compact .page-head h1 { font-size: 1.35rem; margin: 0; }
  body.compact .page-head p { font-size: .8rem; margin: 0; }
  body.compact .tabs { margin-bottom: 12px; flex-wrap: wrap; }
  body.compact .tabs a { padding: 6px 12px; font-size: .84rem; }
  body.compact h2 { font-size: 1.08rem; margin-bottom: 8px !important; }
  body.compact h3 { font-size: .95rem; }
  body.compact .panel { padding: 12px 16px; margin-bottom: 12px; }
  body.compact .grid-2, body.compact .grid-3, body.compact .grid-4 { gap: 4px 12px; }
  body.compact .field { margin-bottom: 8px; }
  body.compact label { font-size: .8rem; margin-bottom: 2px; }
  body.compact input[type=text], body.compact input[type=number], body.compact input[type=date],
  body.compact input[type=password], body.compact select, body.compact textarea { padding: 5px 9px; font-size: .88rem; }
  body.compact textarea { min-height: 0; }
  body.compact .hint { font-size: .74rem; margin-top: 1px; }
  body.compact button.btn, body.compact a.btn, body.compact input[type=submit] { padding: 6px 14px; font-size: .85rem; }
  body.compact button.btn.ghost { padding: 5px 12px; }
  body.compact .segmented button { padding: 5px 11px; font-size: .8rem; }
  body.compact .pill-tabs { margin-bottom: 8px; gap: 6px; }
  body.compact .pill-tabs button { padding: 5px 12px; font-size: .82rem; }
  body.compact .scanner-box { padding: 8px 12px; margin-bottom: 8px; }
  body.compact .scanner-box .scanner-label { margin-bottom: 4px; }
  body.compact table.data { font-size: .84rem; }
  body.compact table.data th { padding: 5px 8px; font-size: .72rem; }
  body.compact table.data td { padding: 5px 8px; }
  body.compact .calc-box { padding: 8px 14px; }
  body.compact .calc-box .line { padding: 2px 0; font-size: .86rem; }
  body.compact .calc-box .line.total { margin-top: 4px; padding-top: 5px; font-size: .96rem; }
  body.compact .stat-card { padding: 8px 12px; }
  body.compact .stat-card .value { font-size: 1.2rem; }
  body.compact .alert { padding: 8px 12px; margin-bottom: 10px; }
  body.compact .payment-row { margin-bottom: 6px; }

  /* Metal-bar balances (Orders, Bulk orders): one compact row of small cards */
  .vault-strip { display: grid; grid-template-columns: repeat(auto-fill, minmax(108px, 1fr)); gap: 6px; }
  .vault-strip .stat-card { padding: 5px 9px; }
  .vault-strip .stat-card .label { font-size: .7rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .vault-strip .stat-card .value { font-size: .98rem; margin-top: 0; }
  /* Issue metal: contract box (wider) beside the advance box */
  .contract-pair { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); gap: 12px; align-items: start; }
  .contract-pair > .panel { margin-bottom: 0; }
  @media (max-width: 1100px) { .contract-pair { grid-template-columns: 1fr; } }
  /* Two short sections placed side by side */
  .side-pair { gap: 4px 20px !important; }
  .side-pair h3 { margin: 0 0 4px; }
  @media (max-width: 1100px) { .side-pair { grid-template-columns: 1fr !important; } }

  /* Billing: barcode box + Add button on one line */
  .scan-row { display: flex; gap: 8px; align-items: center; }
  .scan-row input { flex: 1; min-width: 0; }
  .scan-row .btn { white-space: nowrap; }

  /* Billing: Step 1 (customer) and Step 2 (items) side by side */
  .bill-top { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: 12px; align-items: start; }
  .bill-top > .panel { margin-bottom: 12px; }
  @media (max-width: 1100px) { .bill-top { grid-template-columns: 1fr; } }

  /* Inward: purity rate cards in one row, collapsible when today's rates are set */
  .rate-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); gap: 8px; }
  .rate-cards .stat-card .label { font-size: .76rem; }
  details.rates-panel > summary { cursor: pointer; list-style: none; display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
  details.rates-panel > summary::-webkit-details-marker { display: none; }
  details.rates-panel > summary h2 { margin: 0 !important; }
  details.rates-panel > summary .rates-toggle { font-size: .8rem; color: var(--brass-dark); text-decoration: underline; }
  details.rates-panel[open] > summary { margin-bottom: 8px; }
  details.rates-panel[open] > summary .rates-toggle .when-closed { display: none; }
  details.rates-panel:not([open]) > summary .rates-toggle .when-open { display: none; }
}

/* ---------- Install-as-app + online-only (assets/js/app-install.js) ---------- */
[hidden] { display: none !important; } /* .btn's display:inline-block must not override hidden */
.app-install-back, .app-offline-cover {
  position: fixed; inset: 0; z-index: 10050; display: flex; align-items: center; justify-content: center;
  padding: 16px; background: rgba(33,29,26,.55);
}
.app-offline-cover { background: rgba(33,29,26,.72); backdrop-filter: blur(2px); }
.app-install-box, .app-offline-box {
  background: #fff; color: var(--ink); border-radius: 10px; width: min(440px, 100%);
  padding: 20px 22px; box-shadow: 0 12px 40px rgba(0,0,0,.28); font-size: .92rem; line-height: 1.5;
}
.app-install-box h2, .app-offline-box h2 { font-size: 1.2rem; margin: 0 0 10px; }
.app-install-box ol { padding-left: 20px; margin: 0 0 10px; }
.app-install-box li { margin-bottom: 4px; }
.app-offline-box { text-align: center; }
.app-offline-dot { width: 12px; height: 12px; border-radius: 50%; background: var(--maroon); margin: 0 auto 10px; }
@media (prefers-reduced-motion: no-preference) {
  .app-offline-dot { animation: app-pulse 1.4s ease-in-out infinite; }
  @keyframes app-pulse { 50% { opacity: .3; } }
}
.app-toast {
  position: fixed; left: 50%; bottom: 20px; transform: translateX(-50%); z-index: 10060;
  background: var(--ink); color: #fff; padding: 9px 16px; border-radius: 6px; font-size: .88rem;
  box-shadow: 0 6px 20px rgba(0,0,0,.25); max-width: calc(100% - 32px);
}
.rail .install-app-btn {
  display: block; width: calc(100% - 0px); margin: 8px 0 4px; padding: 6px 10px; border-radius: var(--radius);
  background: rgba(255,255,255,.08); color: #E0E7FF; border: 1px solid rgba(255,255,255,.18);
  font: 600 .8rem var(--font-body); cursor: pointer; text-align: left;
}
.rail .install-app-btn:hover { background: rgba(255,255,255,.16); }
.rail .install-app-btn:focus-visible { outline: 2px solid #A5B4FC; outline-offset: 2px; }
@media (max-width: 760px) { .rail .install-app-btn { font-size: 0; padding: 6px; text-align: center; } .rail .install-app-btn::before { content: "📲"; font-size: 1rem; } }
