/* ══════════════════════════════════════════════════════════════════════════
   QuotePro SaaS — design system

   Follows the visual language of the Mira Steels app: paired colour tokens
   (colour / -bg / -tint), soft layered shadows, small bold uppercase labels,
   Sora for text and JetBrains Mono for anything numeric.

   Two themes share one set of variable names, so no rule below this block
   ever refers to a literal colour.
   ══════════════════════════════════════════════════════════════════════════ */

@import url('https://fonts.googleapis.com/css2?family=Sora:wght@400;600;700;800&family=JetBrains+Mono:wght@500;700&display=swap');

/* ── Light (default, matches Mira) ─────────────────────────────────────── */
:root, :root[data-theme="light"] {
  --bg:        #f6f8fa;
  --surface:   #ffffff;
  --surface2:  #f6f8fa;
  --line:      #d0d7de;
  --line2:     #eaeef2;

  --ink:       #0d1117;
  --ink2:      #24292f;
  --ink3:      #57606a;
  --ink4:      #8c959f;

  --accent:        #0969da;
  --accent-bg:     #ddf4ff;
  --accent-border: #54aeff;
  --accent-ink:    #ffffff;

  --green:        #1a7f37;
  --green-bg:     #dafbe1;
  --green-border: #4ac26b;

  --red:        #cf222e;
  --red-bg:     #ffebe9;
  --red-border: #ff8182;

  --amber:        #9a6700;
  --amber-bg:     #fff8c5;
  --amber-border: #d4a72c;

  --purple:    #8250df;
  --purple-bg: #fbefff;

  --shadow:    0 1px 3px rgba(0,0,0,.08), 0 4px 16px rgba(0,0,0,.06);
  --shadow-lg: 0 8px 32px rgba(0,0,0,.14);

  --r:    8px;
  --r-lg: 12px;
  --r-xl: 16px;
  --radius: var(--r-lg);

  --font: 'Sora', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  --mono: 'JetBrains Mono', ui-monospace, Consolas, monospace;
}

/* ── Dark ──────────────────────────────────────────────────────────────── */
:root[data-theme="dark"] {
  --bg:        #0d1117;
  --surface:   #161b22;
  --surface2:  #1c2129;
  --line:      #30363d;
  --line2:     #21262d;

  --ink:       #e6edf3;
  --ink2:      #adbac7;
  --ink3:      #768390;
  --ink4:      #636e7b;

  --accent:        #2f81f7;
  --accent-bg:     #0d2d5e;
  --accent-border: #1f6feb;
  --accent-ink:    #ffffff;

  --green:        #3fb950;
  --green-bg:     #0d2b16;
  --green-border: #238636;

  --red:        #f85149;
  --red-bg:     #3d1418;
  --red-border: #da3633;

  --amber:        #d29922;
  --amber-bg:     #341a00;
  --amber-border: #9e6a03;

  --purple:    #a371f7;
  --purple-bg: #271052;

  --shadow:    0 1px 3px rgba(0,0,0,.4), 0 4px 16px rgba(0,0,0,.3);
  --shadow-lg: 0 8px 32px rgba(0,0,0,.55);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) {
    --bg:#0d1117; --surface:#161b22; --surface2:#1c2129;
    --line:#30363d; --line2:#21262d;
    --ink:#e6edf3; --ink2:#adbac7; --ink3:#768390; --ink4:#636e7b;
    --accent:#2f81f7; --accent-bg:#0d2d5e; --accent-border:#1f6feb;
    --green:#3fb950;  --green-bg:#0d2b16;  --green-border:#238636;
    --red:#f85149;    --red-bg:#3d1418;    --red-border:#da3633;
    --amber:#d29922;  --amber-bg:#341a00;  --amber-border:#9e6a03;
    --purple:#a371f7; --purple-bg:#271052;
    --shadow:0 1px 3px rgba(0,0,0,.4),0 4px 16px rgba(0,0,0,.3);
    --shadow-lg:0 8px 32px rgba(0,0,0,.55);
  }
}

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html { font-size: 15px; -webkit-tap-highlight-color: transparent; }

body {
  font-family: var(--font);
  background: var(--bg);
  color: var(--ink);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  min-height: 100vh;
}

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

.wrap   { max-width: 1120px; margin: 0 auto; padding: 0 20px; }
.narrow { max-width: 460px; }
.muted  { color: var(--ink3); }
.centered { text-align: center; }
.spacer { flex: 1; }
.mono   { font-family: var(--mono); }

/* Money and quantities read as numbers, never as prose. */
.amt { font-family: var(--mono); font-weight: 700; font-variant-numeric: tabular-nums; }

/* ══ HEADER / NAV ═══════════════════════════════════════════════════════ */
header {
  background: var(--surface);
  border-bottom: 1px solid var(--line);
  padding: 0 0;
  position: sticky; top: 0; z-index: 200;
  box-shadow: var(--shadow);
}
/* The app pages' two-row header uses .qp-topbar (below), which is more
   specific and sets everything it needs on its own. But eleven standalone
   pages — login, signup, pricing, billing, support, terms, and friends —
   never adopted that class; they still use a plain single-row
   <div class="wrap"> header. This rule is what puts "Sign in" beside the
   logo instead of stacked under it on those pages. Safe to combine with
   .qp-topbar: the properties here (flex/center/space-between) are exactly
   what .qp-topbar also sets for itself, so there's no conflict — this is
   only load-bearing on the pages that lack the more specific class. */
header .wrap {
  display: flex; align-items: center; justify-content: space-between;
  min-height: 56px; gap: 16px;
}

.logo {
  display: flex; flex-direction: column; justify-content: center;
  font-size: 1.1rem; font-weight: 800; letter-spacing: -.5px; line-height: 1.15;
  flex: 0 0 auto; white-space: nowrap;
}
.logo-brand { white-space: nowrap; }
.logo span { color: var(--accent); }
.logo small {
  font-size: .62rem; font-weight: 600; margin-top: 1px;
  color: var(--ink4); letter-spacing: .05em; text-transform: uppercase;
}

/* ══ HEADER — two rows, not one crowded one ═══════════════════════════════
   Row 1 (.qp-topbar): logo/tenant on the left, account cluster (sync,
   user, role, sign out) on the right — a single compact line.
   Row 2 (.qp-nav-row): destinations only, in their own horizontally
   scrolling strip. This was previously one row holding the logo AND every
   nav link AND sign-out together; past about 8 links it had nowhere left
   to go but wrap, which is what pushed the page title off the first
   screen on mobile. */
.qp-topbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; min-height: 56px; flex-wrap: nowrap; overflow-x: auto;
  scrollbar-width: none;
}
.qp-topbar::-webkit-scrollbar { display: none; }

.qp-account { display: flex; align-items: center; gap: 10px; flex: 0 0 auto; }
.qp-user {
  font-size: .82rem; font-weight: 600; color: var(--ink2); white-space: nowrap;
}
.qp-role { white-space: nowrap; text-transform: uppercase; }
.qp-signout {
  font-size: .8rem; font-weight: 600; color: var(--ink3); white-space: nowrap;
  padding: 6px 4px;
}
.qp-signout:hover { color: var(--ink); text-decoration: none; }

.qp-nav-row {
  border-top: 1px solid var(--line);
  padding: 2px 0;
}
.qp-nav {
  display: flex; align-items: center; gap: 2px;
  overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none;
}
.qp-nav::-webkit-scrollbar { display: none; }
.qp-nav a {
  flex: 0 0 auto; white-space: nowrap;
  padding: 8px 13px; font-size: .8rem; font-weight: 600; color: var(--ink3);
  border-radius: var(--r); transition: .15s;
}
.qp-nav a:hover { color: var(--ink); background: var(--surface2); text-decoration: none; }
.qp-nav a.on { color: var(--ink); background: var(--surface2); }

/* ══ PAGE ═══════════════════════════════════════════════════════════════ */
.section { padding: 24px 0 48px; animation: fadeUp .2s ease; }
@keyframes fadeUp { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

.page-title { font-size: 1.5rem; font-weight: 800; letter-spacing: -.5px; }

.page-head {
  display: flex; justify-content: space-between; align-items: flex-end;
  gap: 16px; flex-wrap: wrap; margin-bottom: 20px;
}

/* ══ CARDS ══════════════════════════════════════════════════════════════ */
.card {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); box-shadow: var(--shadow);
  padding: 22px;
}
.panel {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); box-shadow: var(--shadow);
  margin-bottom: 14px; overflow: hidden;
}
.panel > h3, .card-head {
  padding: 12px 18px; border-bottom: 1px solid var(--line2);
  font-size: .7rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: .07em; color: var(--ink3);
}
.panel .pad, .card-body { padding: 18px; }

/* ══ FORMS ══════════════════════════════════════════════════════════════ */
.field { margin-bottom: 13px; }
.field label {
  display: block; font-size: .7rem; font-weight: 700;
  color: var(--ink2); margin-bottom: 5px; letter-spacing: .01em;
}
.field label .req, .req { color: var(--red); }

input, select, textarea {
  width: 100%; padding: 9px 12px; font-size: .84rem; font-family: var(--font);
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r); color: var(--ink); outline: none;
  transition: border-color .15s, box-shadow .15s;
}
input:focus, select:focus, textarea:focus {
  border-color: var(--accent-border);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent);
}
input:disabled, select:disabled { background: var(--surface2); color: var(--ink3); }
input[type=number] { font-family: var(--mono); font-weight: 600; }

.field .hint { font-size: .7rem; color: var(--ink3); margin-top: 4px; }
.field .err-msg { font-size: .72rem; color: var(--red); margin-top: 4px; display: none; font-weight: 600; }
.field.err input, .field.err select { border-color: var(--red-border); }
.field.err .err-msg { display: block; }

.row { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }

/* ══ BUTTONS ════════════════════════════════════════════════════════════ */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  width: 100%; padding: 10px 16px; border-radius: var(--r);
  font-size: .8rem; font-weight: 700; font-family: var(--font);
  cursor: pointer; border: 1px solid var(--line);
  background: var(--surface); color: var(--ink2);
  transition: transform .1s, background .15s, border-color .15s;
  text-decoration: none;
}
.btn:hover  { background: var(--surface2); border-color: var(--ink4); text-decoration: none; }
.btn:active { transform: scale(.985); }
.btn:disabled { opacity: .5; cursor: not-allowed; transform: none; }

.btn-primary { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.btn-primary:hover { background: var(--accent); filter: brightness(1.08); border-color: var(--accent); }
.btn-green { background: var(--green); border-color: var(--green); color: #fff; }
.btn-danger { background: var(--red-bg); border-color: var(--red-border); color: var(--red); }
.btn-sm { padding: 6px 11px; font-size: .72rem; }
.btn-auto { width: auto; }

.icon-btn {
  background: transparent; border: 1px solid transparent; cursor: pointer;
  color: var(--ink3); padding: 5px 8px; border-radius: var(--r);
  font-size: .95rem; font-family: var(--font); line-height: 1;
  text-decoration: none; display: inline-flex; align-items: center;
}
.icon-btn:hover { background: var(--surface2); color: var(--ink); border-color: var(--line); text-decoration: none; }
.icon-btn.danger:hover { background: var(--red-bg); color: var(--red); border-color: var(--red-border); }

/* ══ BADGES ═════════════════════════════════════════════════════════════ */
.tag, .pill, .badge {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 3px 9px; border-radius: 20px;
  font-size: .65rem; font-weight: 700; letter-spacing: .02em;
  background: var(--line2); color: var(--ink3); border: 0;
}
.tag-green, .pill-active, .b-resolved { background: var(--green-bg); color: var(--green); }
.tag-amber, .pill-warn,   .b-in_progress, .b-waiting_on_customer { background: var(--amber-bg); color: var(--amber); }
.tag-red,   .pill-danger { background: var(--red-bg);   color: var(--red); }
.tag-blue,  .pill-trial,  .b-new { background: var(--accent-bg); color: var(--accent); }
.tag-grey,  .b-wont_do   { background: var(--line2);    color: var(--ink3); }

/* ══ NOTICES ════════════════════════════════════════════════════════════ */
.notice {
  border-radius: var(--r); padding: 11px 14px; font-size: .8rem;
  margin-bottom: 16px; border: 1px solid; font-weight: 500; line-height: 1.5;
}
.notice-warn  { background: var(--amber-bg);  border-color: var(--amber-border);  color: var(--amber); }
.notice-info  { background: var(--accent-bg); border-color: var(--accent-border); color: var(--accent); }
.notice-error { background: var(--red-bg);    border-color: var(--red-border);    color: var(--red); }
.notice a { color: inherit; text-decoration: underline; font-weight: 700; }

/* ══ TOOLBAR ════════════════════════════════════════════════════════════ */
.toolbar { display: flex; gap: 9px; align-items: center; flex-wrap: wrap; margin-bottom: 14px; }
.toolbar input[type=search] { flex: 1; min-width: 190px; }
.toolbar select { width: auto; min-width: 150px; }
.toolbar .btn { width: auto; }

/* ══ DATA TABLE ═════════════════════════════════════════════════════════ */
.table-wrap {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); box-shadow: var(--shadow); overflow-x: auto;
}
table.data { width: 100%; border-collapse: collapse; font-size: .8rem; }
table.data th {
  text-align: left; padding: 10px 14px; background: var(--surface2);
  color: var(--ink3); font-weight: 700; font-size: .66rem;
  text-transform: uppercase; letter-spacing: .07em;
  border-bottom: 2px solid var(--line); white-space: nowrap;
  position: sticky; top: 0; z-index: 1;
}
table.data td { padding: 11px 14px; border-bottom: 1px solid var(--line2); vertical-align: middle; }
table.data tr:last-child td { border-bottom: 0; }
table.data tbody tr { transition: background .1s; }
table.data tbody tr:hover { background: var(--surface2); }
table.data .num {
  text-align: right; font-family: var(--mono); font-weight: 600;
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
table.data .actions { text-align: right; white-space: nowrap; }
table.data .strong { font-weight: 700; }
table.data .docno { font-family: var(--mono); font-weight: 700; font-size: .76rem; color: var(--accent); }
table.data .sub { font-size: .7rem; color: var(--ink3); font-weight: 400; }

/* Phone: every row becomes a card with its own labels. Straight from the
   Mira app, and the reason that app works one-handed at a counter. */
@media (max-width: 720px) {
  /* .qp-nav already scrolls horizontally at every width (see the base rule
     above) — this just lets that strip bleed to the screen edges on a
     phone instead of sitting inset, so the first and last tab aren't
     visually cramped against the page margin. */
  .qp-nav-row {
    margin: 0 calc(-1 * var(--pad, 16px));
    padding: 2px var(--pad, 16px) 4px;
  }

  table.data thead { display: none; }
  table.data, table.data tbody, table.data tr, table.data td { display: block; width: 100%; }
  table.data tr {
    background: var(--surface); border: 1px solid var(--line);
    border-radius: var(--r); margin-bottom: 9px; padding: 10px 12px; position: relative;
  }
  .table-wrap { background: transparent; border: 0; box-shadow: none; padding: 0; }
  table.data td {
    text-align: right; padding: 5px 0 5px 42%; position: relative;
    border: 0; border-bottom: 1px solid var(--line2);
  }
  table.data tr td:last-child { border-bottom: 0; }
  table.data td::before {
    content: attr(data-label); position: absolute; left: 0; top: 50%;
    transform: translateY(-50%); font-weight: 700; font-size: .64rem;
    color: var(--ink3); text-transform: uppercase; letter-spacing: .05em;
    white-space: nowrap; text-align: left;
  }
  table.data td:first-child { padding-left: 0; text-align: left; }
  table.data td:first-child::before { display: none; }
  table.data .actions { text-align: left; padding-left: 0; }
}

select.status-pick {
  padding: 4px 9px; font-size: .7rem; font-weight: 700; width: auto;
  background: var(--line2); border: 1px solid transparent;
  border-radius: 20px; color: var(--ink2); cursor: pointer;
}
select.status-pick:hover { border-color: var(--line); }

.empty { text-align: center; padding: 48px 20px; color: var(--ink3); }
.empty h3 { color: var(--ink2); font-size: 1rem; margin-bottom: 6px; font-weight: 700; }
.empty p  { font-size: .82rem; margin-bottom: 18px; max-width: 420px; margin-left: auto; margin-right: auto; }
.count-note { font-size: .72rem; color: var(--ink4); }

/* ══ STAT TILES ═════════════════════════════════════════════════════════ */
.tiles, .stat-row {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 12px; margin-bottom: 18px;
}
.tile, .stat {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: 16px 18px; box-shadow: var(--shadow);
}
.tile .l, .stat .l {
  font-size: .66rem; color: var(--ink3); text-transform: uppercase;
  letter-spacing: .07em; font-weight: 700;
}
.tile .n, .stat .n {
  font-size: 1.55rem; font-weight: 800; letter-spacing: -.5px;
  font-family: var(--mono); margin-top: 3px;
}
.stat.warn .n { color: var(--amber); }
.stat.good .n { color: var(--green); }
.soon { opacity: .5; }

/* ══ DRAWER ═════════════════════════════════════════════════════════════ */
.drawer-bg {
  position: fixed; inset: 0; background: rgba(0,0,0,.5); z-index: 400;
  display: none; align-items: flex-start; justify-content: center;
  padding: 20px; overflow-y: auto; backdrop-filter: blur(2px);
}
.drawer-bg.open { display: flex; }
.drawer {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-xl); width: 100%; max-width: 540px; margin: auto 0;
  box-shadow: var(--shadow-lg);
}
.drawer header {
  display: flex; justify-content: space-between; align-items: center;
  padding: 15px 20px; border-bottom: 1px solid var(--line2);
  background: transparent; box-shadow: none; position: static; min-height: 0;
}
.drawer header h3 { font-size: .95rem; font-weight: 700; }
.drawer .body   { padding: 20px; }
.drawer .footer { padding: 14px 20px; border-top: 1px solid var(--line2); display: flex; gap: 10px; }
.drawer .footer .btn { flex: 1; }

/* ══ TOASTS ═════════════════════════════════════════════════════════════ */
#qp-toasts {
  position: fixed; right: 16px; bottom: 16px; z-index: 999;
  display: flex; flex-direction: column; gap: 8px; max-width: 340px;
}
.qp-toast {
  background: var(--surface); border: 1px solid var(--line); color: var(--ink);
  border-radius: var(--r); padding: 11px 14px; font-size: .8rem; font-weight: 600;
  box-shadow: var(--shadow-lg); transition: opacity .3s;
}
.qp-toast-ok   { border-left: 3px solid var(--green); }
.qp-toast-warn { border-left: 3px solid var(--amber); }
.qp-toast-err  { border-left: 3px solid var(--red); }

/* ══ QUOTATION BUILDER ══════════════════════════════════════════════════ */
.builder { display: grid; grid-template-columns: 1fr 330px; gap: 16px; align-items: start; }
@media (max-width: 940px) { .builder { grid-template-columns: 1fr; } }
.sticky-actions { position: sticky; top: 72px; }

.picker { position: relative; }
.picker-results {
  position: absolute; top: 100%; left: 0; right: 0; z-index: 300; margin-top: 4px;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r);
  max-height: 300px; overflow-y: auto; display: none; box-shadow: var(--shadow-lg);
}
.picker-results.open { display: block; }
.picker-row {
  padding: 10px 13px; cursor: pointer; border-bottom: 1px solid var(--line2);
  display: flex; justify-content: space-between; gap: 12px; align-items: center;
}
.picker-row:last-child { border-bottom: 0; }
.picker-row:hover, .picker-row.active { background: var(--surface2); }
.picker-row .nm { font-weight: 700; font-size: .82rem; }
.picker-row .meta { font-size: .68rem; color: var(--ink3); margin-top: 2px; }
.picker-row .pr { font-family: var(--mono); font-weight: 700; font-size: .8rem;
                  color: var(--green); white-space: nowrap; }
.picker-empty { padding: 14px; font-size: .8rem; color: var(--ink3); }

/* ══ QUOTATION/INVOICE LINE ITEMS ═══════════════════════════════════════
   One markup, two layouts via CSS Grid — not a duplicated DOM for mobile.
   Desktop lays every field out as a table-style row; mobile stacks each
   field as its own labeled row, matching a Mira-style item card. Because
   it's the SAME elements just repositioned, typing in a field never loses
   focus when the layout switches (e.g. resizing a window mid-edit) — a
   parallel "mobile-only" copy of the inputs would either fight the
   original for state or need constant manual syncing. */
:root {
  --li-cols: minmax(160px,1.6fr) 76px 96px 92px 84px 68px 88px 96px 32px;
}

.line-head {
  display: grid; grid-template-columns: var(--li-cols); gap: 8px;
  padding: 6px 10px; background: var(--surface2); border-radius: var(--r) var(--r) 0 0;
  font-size: .64rem; color: var(--ink3); font-weight: 700;
  text-transform: uppercase; letter-spacing: .05em;
}
.line-head > div:not(:first-child) { text-align: right; }

.line-item {
  display: grid; grid-template-columns: var(--li-cols); align-items: center;
  gap: 8px; padding: 8px 10px; border-bottom: 1px solid var(--line2);
}
.line-item:last-child { border-bottom: 0; }

.li-name .nm { width: 100%; font-weight: 600; }
.li-name .meta { font-size: .72rem; color: var(--ink3); margin-top: 2px; }

.li-field { text-align: right; }
.li-field input { width: 100%; padding: 6px 8px; font-size: .8rem; text-align: right; }
.li-label { display: none; }   /* the .line-head row IS the label, on desktop */

.li-val { font-family: var(--mono); font-weight: 700; white-space: nowrap; }
.li-total { color: var(--green); font-size: .88rem; }

.li-remove { justify-self: end; }

@media (max-width: 720px) {
  .line-head { display: none; }   /* each card carries its own labels instead */

  .line-item {
    grid-template-columns: 1fr auto;   /* label column, value column */
    grid-template-areas:
      "name    name"
      "qty     qty"
      "rate    rate"
      "taxable taxable"
      "hsn     hsn"
      "gst     gst"
      "gstamt  gstamt"
      "total   remove";
    gap: 10px 0; padding: 12px; border: 1px solid var(--line); border-radius: var(--r);
    margin-bottom: 10px; background: var(--surface);
  }
  .line-item > :nth-child(1) { grid-area: name; }
  .line-item > :nth-child(2) { grid-area: qty; }
  .line-item > :nth-child(3) { grid-area: rate; }
  .line-item > :nth-child(4) { grid-area: taxable; }
  .line-item > :nth-child(5) { grid-area: hsn; }
  .line-item > :nth-child(6) { grid-area: gst; }
  .line-item > :nth-child(7) { grid-area: gstamt; }
  .line-item > :nth-child(8) { grid-area: total; }
  .line-item > :nth-child(9) { grid-area: remove; align-self: center; justify-self: end; }

  .li-field {
    display: flex; justify-content: space-between; align-items: center;
    text-align: right; padding: 4px 0; border-bottom: 1px solid var(--line2);
  }
  .li-label {
    display: block; font-size: .68rem; font-weight: 700; color: var(--ink3);
    text-transform: uppercase; letter-spacing: .05em; text-align: left;
  }
  .li-field input { width: 120px; }
  .li-total { font-size: 1rem; }
}

.w-qty { width: 82px; } .w-rate { width: 102px; } .w-gst { width: 72px; }

/* boq.html's review table is a real <table> (a scan-and-confirm list, not
   a per-item editing card), so it keeps ordinary table styling rather than
   the .line-item grid built above for the quotation editor. */
table.lines { width: 100%; border-collapse: collapse; font-size: .8rem; }
table.lines th {
  text-align: left; padding: 8px 10px; background: var(--surface2);
  font-size: .64rem; color: var(--ink3); font-weight: 700;
  text-transform: uppercase; letter-spacing: .06em; border-bottom: 2px solid var(--line);
}
table.lines td { padding: 8px 10px; border-bottom: 1px solid var(--line2); vertical-align: middle; }
table.lines tr:last-child td { border-bottom: 0; }
table.lines input { padding: 6px 9px; font-size: .8rem; text-align: right; }
table.lines input.txt { text-align: left; font-family: var(--font); font-weight: 600; }
table.lines .num { text-align: right; font-family: var(--mono); font-weight: 700;
                   color: var(--green); white-space: nowrap; }

.totals .line { display: flex; justify-content: space-between; gap: 12px;
                padding: 6px 0; font-size: .82rem; color: var(--ink2); }
.totals .line .v { font-family: var(--mono); font-weight: 600; font-variant-numeric: tabular-nums; }
.totals .line.grand {
  border-top: 2px solid var(--line); margin-top: 8px; padding-top: 11px;
  font-size: 1.05rem; font-weight: 800; color: var(--ink);
}
.totals .line.grand .v { font-weight: 800; }
.totals .sub { font-size: .7rem; color: var(--ink4); }
.disc-row { display: flex; gap: 8px; }
.disc-row select { flex: 0 0 92px; }
.disc-row input  { flex: 1; }
.words { font-size: .72rem; color: var(--ink3); font-style: italic;
         border-top: 1px solid var(--line2); margin-top: 10px; padding-top: 10px; }

/* ══ SETTINGS SUB-NAV ═══════════════════════════════════════════════════ */
.settings-nav {
  display: flex; gap: 0; border-bottom: 1px solid var(--line);
  margin-bottom: 22px; flex-wrap: wrap; overflow-x: auto;
}
.settings-nav a {
  padding: 11px 15px; font-size: .78rem; font-weight: 600; color: var(--ink3);
  border-bottom: 2.5px solid transparent; margin-bottom: -1px; white-space: nowrap;
}
.settings-nav a:hover { color: var(--ink2); text-decoration: none; }
.settings-nav a.on { color: var(--ink); border-bottom-color: var(--ink); font-weight: 700; }

/* ══ MARKETING PAGES ════════════════════════════════════════════════════ */
.hero { text-align: center; padding: 60px 0 34px; }
.hero h1 { font-size: 2.3rem; font-weight: 800; letter-spacing: -1px; margin-bottom: 14px; }
.hero p { color: var(--ink3); font-size: 1rem; max-width: 560px; margin: 0 auto; }

.toggle {
  display: flex; justify-content: center; gap: 4px; margin: 26px auto 30px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: 999px; padding: 4px; width: fit-content; box-shadow: var(--shadow);
}
.toggle button {
  border: 0; background: transparent; color: var(--ink3); cursor: pointer;
  padding: 8px 18px; border-radius: 999px; font-size: .8rem;
  font-family: var(--font); font-weight: 700; width: auto;
}
.toggle button.on { background: var(--ink); color: var(--surface); }
.save-badge { background: var(--green-bg); color: var(--green); font-size: .66rem;
              padding: 2px 7px; border-radius: 999px; margin-left: 6px; font-weight: 700; }

.plans { display: grid; grid-template-columns: repeat(auto-fit, minmax(270px, 1fr)); gap: 16px; }
.plan {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-xl); padding: 26px; display: flex; flex-direction: column;
  position: relative; box-shadow: var(--shadow);
}
.plan.featured { border-color: var(--accent-border); box-shadow: var(--shadow-lg); }
.plan .tag {
  position: absolute; top: -11px; left: 50%; transform: translateX(-50%);
  background: var(--accent); color: var(--accent-ink); font-size: .62rem;
  font-weight: 800; padding: 4px 12px; border-radius: 999px; letter-spacing: .06em;
}
.plan h3 { font-size: 1.05rem; font-weight: 800; margin-bottom: 4px; }
.plan .desc { color: var(--ink3); font-size: .8rem; min-height: 34px; }
.price { margin: 14px 0 6px; }
.price .amt { font-size: 2.1rem; font-weight: 800; letter-spacing: -1px; font-family: var(--font); }
.price .per { color: var(--ink3); font-size: .8rem; font-weight: 600; }
.price .note { color: var(--ink4); font-size: .72rem; min-height: 18px; margin-top: 2px; }
.plan ul { list-style: none; margin: 18px 0; flex: 1; }
.plan li { font-size: .82rem; color: var(--ink2); padding: 5px 0 5px 22px; position: relative; }
.plan li::before { content: '✓'; position: absolute; left: 0; color: var(--green); font-weight: 800; }
.plan li.off { color: var(--ink4); }
.plan li.off::before { content: '×'; color: var(--ink4); }

.summary {
  background: var(--surface2); border: 1px solid var(--line2);
  border-radius: var(--r); padding: 14px 16px; margin-bottom: 18px; font-size: .82rem;
}
.summary .line { display: flex; justify-content: space-between; padding: 3px 0; color: var(--ink3); }
.summary .line.total {
  border-top: 1px solid var(--line); margin-top: 8px; padding-top: 9px;
  font-weight: 800; color: var(--ink); font-size: .95rem;
}

/* ══ TRUST ══════════════════════════════════════════════════════════════ */
.trust { margin-top: 48px; padding-top: 34px; border-top: 1px solid var(--line); }
.quote-card {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-xl); padding: 26px 28px; max-width: 620px;
  margin: 0 auto 28px; box-shadow: var(--shadow);
}
.quote-card blockquote { font-size: 1rem; line-height: 1.65; color: var(--ink); margin: 0 0 18px; }
.quote-card .attrib { display: flex; align-items: center; gap: 12px; }
.quote-card .avatar {
  width: 42px; height: 42px; border-radius: 50%; flex: 0 0 42px;
  background: var(--accent); color: var(--accent-ink); font-weight: 800;
  display: flex; align-items: center; justify-content: center;
}
.quote-card .who { font-weight: 700; font-size: .88rem; }
.quote-card .org { font-size: .78rem; color: var(--ink3); }
.trust-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 14px; }
.trust-item {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: 18px 20px; box-shadow: var(--shadow);
}
.trust-item .ti-icon { font-size: 1.3rem; margin-bottom: 8px; }
.trust-item .ti-t { font-weight: 700; font-size: .88rem; margin-bottom: 4px; }
.trust-item .ti-d { font-size: .78rem; color: var(--ink3); line-height: 1.55; }

footer { border-top: 1px solid var(--line); margin-top: 52px; padding: 22px 0; }

@media (max-width: 560px) {
  html { font-size: 14px; }
  .hero h1 { font-size: 1.7rem; }
  .row { grid-template-columns: 1fr; }
  .wrap { padding: 0 14px; }
}

/* An input holding a value the server will reject. Used by the credit note
   form when a quantity exceeds what is left to credit — the message alone
   is easy to miss when several lines are on screen. */
input.bad, select.bad {
  border-color: #cf222e;
  background: rgba(207, 34, 46, 0.05);
}

/* ══ ROW ACTIONS ════════════════════════════════════════════════════════
   Labelled buttons rather than bare icons. Icons alone tested badly: on a
   quotation list the difference between "download" and "edit" matters, and
   a glyph makes the user hover to find out. Colour carries meaning, the
   label carries the certainty. */
td.actions { white-space: nowrap; }
.act {
  display: inline-block; padding: 5px 10px; margin: 2px 1px;
  font-size: .76rem; font-weight: 700; line-height: 1.35;
  border: 1px solid var(--line); border-radius: var(--r);
  background: var(--surface); color: var(--ink2);
  cursor: pointer; transition: .15s; vertical-align: middle;
}
.act:hover { border-color: var(--accent); color: var(--ink); text-decoration: none; }
.act-wa  { background: #25d366; border-color: #25d366; color: #fff; }
.act-pdf { background: #0b5fff; border-color: #0b5fff; color: #fff; }
.act-xl  { background: #1a7f37; border-color: #1a7f37; color: #fff; }
.act-ok  { background: #1a7f37; border-color: #1a7f37; color: #fff; }
.act-wa:hover, .act-pdf:hover, .act-xl:hover, .act-ok:hover { color: #fff; opacity: .9; }
.act-del { color: #cf222e; }
.act-del:hover { background: #cf222e; border-color: #cf222e; color: #fff; }

@media (max-width: 720px) {
  /* The stacked-card layout right-aligns cells; actions read better as a
     left-flowing row of buttons under the rest of the record. */
  table.data td.actions { text-align: left; padding-left: 0; }
  table.data td.actions::before { display: none; }
}

/* ══ SYNC STATUS PILL ═══════════════════════════════════════════════════
   Placed next to the logo, matching the reference app's own layout. Colour
   carries the state (green=synced, amber=pending, grey=offline) so it can
   be read at a glance without stopping to read the label text. */
.sync-pill {
  display: flex; align-items: center; gap: 6px;
  padding: 5px 10px; margin-left: 4px;
  border: 1px solid var(--line); border-radius: 999px;
  background: var(--surface2); color: var(--ink2);
  font-size: .74rem; font-weight: 600; cursor: pointer;
  white-space: nowrap;
}
.sync-pill:hover { border-color: var(--accent); color: var(--ink); }
.sync-pill .dot { width: 7px; height: 7px; border-radius: 50%; flex: 0 0 auto; }
.sync-pill .dot.green { background: var(--green); }
.sync-pill .dot.amber { background: var(--amber); }
.sync-pill .dot.grey  { background: var(--ink3); }
.sync-pill .dot.pulse { animation: qp-pulse 1s ease-in-out infinite; }
@keyframes qp-pulse { 0%,100% { opacity: 1; } 50% { opacity: .35; } }

@media (max-width: 480px) {
  .sync-pill span:not(.dot) { display: none; }  /* dot alone on very narrow phones */
  .sync-pill { padding: 6px; }
}

/* The account row can scroll, but Sign Out is used too often to be worth
   discovering by scrolling for — the user's name is the item people can
   most afford to lose sight of first. Measured against real widths: this
   alone closes the gap at 320-375px without needing to touch anything
   else in the row. */
@media (max-width: 400px) {
  .qp-user { display: none; }
}
