/* ═════════════════════════════════════════════════════════════════════════════
   NEAT WHEELS · DetailERP, the billing floor.

   Phone first. This is used one-handed, standing next to a car, often with a
   wet thumb, in a bay with the shutter open. So: a bottom tab bar within thumb
   reach, 46px targets, tables that become cards below 760px, and a light ground
   that survives daylight. The desktop layout is the ADDITION, not the base.

   Tokens come from system.css, the same ones the public website runs on, so
   the site a customer sees and the invoice they are handed match.

   Class names are unchanged from the dark build on purpose: app.js keeps
   working, and this file is the only thing that had to be rewritten.
   ═════════════════════════════════════════════════════════════════════════════ */

body { font-size: 14px; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--line-2); border-radius: 5px; }
::-webkit-scrollbar-thumb:hover { background: var(--faint); }

/* ── shell ──────────────────────────────────────────────────────────────── */
.shell { display: flex; min-height: 100vh; }
.main { flex: 1; min-width: 0; display: flex; flex-direction: column; }

/* The page carries the tab bar's height as bottom padding so the last row of
   every screen can still be reached and tapped. */
.page { padding: 16px 14px calc(96px + var(--safe-b)); max-width: 1500px; width: 100%; }

/* ── the side (desktop only) ────────────────────────────────────────────── */
.side {
  width: 236px; flex: none; background: var(--panel);
  border-right: 1px solid var(--line);
  display: none; flex-direction: column;
  position: sticky; top: 0; height: 100vh;
}
.brand { display: flex; align-items: center; gap: 11px; padding: 18px 18px 16px; }
.brand-mark {
  width: 38px; height: 38px; border-radius: 11px; flex: none;
  background: var(--gold-leaf); color: var(--ink);
  box-shadow: 0 6px 16px -8px rgba(199,151,51,.9);
  display: grid; place-items: center;
}
.brand-name { font-family: var(--display); font-size: 16px; font-weight: 800; letter-spacing: -0.04em; }
.brand-sub { font-size: 10.5px; color: var(--faint); letter-spacing: .1em; text-transform: uppercase; }

.nav { flex: 1; overflow-y: auto; padding: 4px 10px 10px; }
.nav-group {
  font-size: 9.5px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--faint); padding: 14px 8px 6px; font-weight: 700;
}
.nav-item {
  width: 100%; display: flex; align-items: center; gap: 10px;
  padding: 9px 10px; border-radius: var(--r-sm); border: 0; background: transparent;
  color: var(--ink-2); font-size: 13.5px; text-align: left;
  transition: background .16s var(--ease), color .16s var(--ease);
}
.nav-item:hover { background: var(--panel-3); color: var(--ink); }
.nav-item.on { background: var(--gold-leaf); color: var(--ink); font-weight: 700;
  box-shadow: 0 6px 16px -10px rgba(199,151,51,.95); }
.nav-item .badge-n {
  margin-left: auto; font-size: 10.5px; padding: 1px 7px; border-radius: 20px;
  background: var(--rose); color: #fff; font-weight: 700;
}
.nav-item.on .badge-n { background: var(--ink); color: var(--gold-fill); }

.side-foot { padding: 12px; border-top: 1px solid var(--line); }
.autobox {
  background: var(--gold-wash); border-radius: var(--r-sm); padding: 9px 10px;
  font-size: 11px; color: var(--ink-2); line-height: 1.45;
}
.autobox b { color: var(--gold-ink); font-weight: 700; display: flex; align-items: center; gap: 5px; }

/* ── topbar ─────────────────────────────────────────────────────────────── */
.topbar {
  display: flex; align-items: center; gap: 12px;
  padding: calc(11px + var(--safe-t)) 14px 11px;
  border-bottom: 1px solid var(--line); position: sticky; top: 0;
  background: rgba(242,242,239,.88);
  backdrop-filter: blur(14px) saturate(150%); -webkit-backdrop-filter: blur(14px) saturate(150%);
  z-index: 20;
}
/* min-width:0 so the subtitle below can actually ellipsis instead of forcing
   the flex row wider than the phone. */
.topbar-title { min-width: 0; }
.topbar h1 { font-size: 20px; font-weight: 800; letter-spacing: -.038em; }
.topbar .sub {
  font-size: 11.5px; color: var(--faint);
  /* One line on a phone, the GSTIN and state can wait for a wider screen. */
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 52vw;
}
.spacer { flex: 1; }

/* ── the bottom tab bar, the phone's real navigation ───────────────────── */
/* Five slots, the fifth opening everything else. Thumb-reachable, above the
   home indicator, and it never scrolls away. */
.tabbar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
  display: flex; align-items: stretch;
  padding-bottom: var(--safe-b);
  background: rgba(255,255,255,.94);
  backdrop-filter: blur(18px) saturate(160%); -webkit-backdrop-filter: blur(18px) saturate(160%);
  border-top: 1px solid var(--line);
}
.tab {
  flex: 1; border: 0; background: transparent; position: relative;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 3px; padding: 9px 2px 10px; min-height: 58px;
  font-size: 10.5px; font-weight: 600; letter-spacing: -.01em; color: var(--muted);
  -webkit-tap-highlight-color: transparent;
  transition: color .18s var(--ease);
}
.tab svg { width: 19px; height: 19px; }
.tab.on { color: var(--ink); }
.tab.on::before {
  content: ""; position: absolute; top: 0; left: 50%; transform: translateX(-50%);
  width: 28px; height: 3px; border-radius: 0 0 3px 3px; background: var(--gold-leaf);
}
.tab .badge-n {
  position: absolute; top: 5px; left: 50%; margin-left: 5px;
  min-width: 16px; height: 16px; padding: 0 4px; border-radius: 8px;
  background: var(--rose); color: #fff; font-size: 10px; font-weight: 700;
  display: grid; place-items: center;
}
.tab:active { color: var(--ink); }

/* ── primitives ─────────────────────────────────────────────────────────── */
.card { background: var(--panel); border: 1px solid var(--line); border-radius: var(--r); box-shadow: var(--shadow-1); }
.card-p { padding: 16px; }
.card-h {
  padding: 13px 16px; border-bottom: 1px solid var(--line);
  display: flex; align-items: center; gap: 10px;
}
.card-h h3 { font-size: 15px; font-weight: 700; letter-spacing: -.025em; }
.card-h .sub { font-size: 11.5px; color: var(--faint); }

/* Buttons keep the app's own class names but inherit the system's shape.
   44px minimum, because this is a touch screen before it is a desktop. */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  min-height: 44px; padding: 0 15px; border-radius: 999px;
  border: 1.5px solid var(--line-2); background: var(--panel); color: var(--ink);
  font-size: 14px; font-weight: 600; white-space: nowrap;
  -webkit-tap-highlight-color: transparent;
  transition: background .16s var(--ease), border-color .16s var(--ease),
              color .16s var(--ease), transform .12s var(--ease), box-shadow .2s var(--ease);
}
.btn:hover { background: var(--panel-3); }
.btn:active { transform: scale(.97); }
.btn:disabled { opacity: .45; pointer-events: none; }
.btn-primary { background: var(--gold-leaf); color: var(--ink); border-color: transparent; font-weight: 700;
  box-shadow: 0 8px 20px -12px rgba(199,151,51,1); }
.btn-primary:hover { filter: brightness(1.05); box-shadow: 0 12px 26px -12px rgba(199,151,51,1); }
.btn-ghost {
  background: transparent; border-color: transparent; color: var(--ink-2);
  min-height: 40px; padding: 0 10px;
}
.btn-ghost:hover { background: var(--panel-3); color: var(--ink); }
.btn-danger { background: transparent; color: var(--rose); border-color: rgba(185,59,51,.34); }
.btn-danger:hover { background: var(--rose-wash); }
.btn-sm { min-height: 36px; padding: 0 12px; font-size: 13px; }

/* 16px on inputs, always, anything smaller makes iOS Safari zoom the whole
   page the moment a field is focused, and it never zooms back out. */
.inp, select.inp, textarea.inp {
  width: 100%; background: var(--panel-2); border: 1.5px solid var(--line-2);
  border-radius: var(--r-sm); padding: 11px 13px; min-height: 46px; font-size: 16px;
  transition: border-color .16s var(--ease), background .16s var(--ease);
}
.inp:focus { outline: none; border-color: var(--ink); background: var(--panel); }
.inp::placeholder { color: var(--faint); }
textarea.inp { min-height: 76px; }
select.inp {
  appearance: none; padding-right: 34px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236B7A80' stroke-width='2.5' stroke-linecap='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 11px center; background-size: 14px;
}
.lbl {
  display: block; font-size: 10.5px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--muted); font-weight: 700; margin-bottom: 6px;
}
.field { margin-bottom: 13px; }
.grid2, .grid3 { display: grid; grid-template-columns: 1fr; gap: 12px; }
.row { display: flex; align-items: center; gap: 10px; }
.wrap { flex-wrap: wrap; }

/* ── tables → cards on a phone ──────────────────────────────────────────── */
/* Below 760px every table becomes a stack of cards. The column name on each
   cell comes from `data-l`, which app.js stamps by reading the table's own
   <thead> after each render, so a new screen gets card mode for free and no
   screen can be forgotten. */
.tw { overflow-x: auto; -webkit-overflow-scrolling: touch; }
table { width: 100%; border-collapse: collapse; }
th {
  text-align: left; padding: 10px 14px; font-size: 10px; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase; color: var(--muted);
  border-bottom: 1px solid var(--line); white-space: nowrap;
}
td { padding: 12px 14px; font-size: 13.5px; border-bottom: 1px solid var(--line); }
tbody tr:last-child td { border-bottom: 0; }
tbody tr { transition: background .12s var(--ease); }
tbody tr:hover td { background: var(--panel-2); }

.num { text-align: right; font-variant-numeric: tabular-nums; }
.strong { font-weight: 650; }
.dim { color: var(--ink-2); }
.faint { color: var(--faint); }
.mono-id { font-variant-numeric: tabular-nums; letter-spacing: -.01em; }

@media (max-width: 759px) {
  .tw { overflow-x: visible; }
  .tw table, .tw tbody, .tw tr, .tw td { display: block; width: 100%; }
  .tw thead { display: none; }
  .tw tbody tr {
    background: var(--panel); border: 1px solid var(--line); border-radius: var(--r);
    box-shadow: var(--shadow-1); margin-bottom: 10px; padding: 4px 2px; overflow: hidden;
  }
  .tw tbody tr:hover td { background: transparent; }
  .tw td {
    display: flex; align-items: center; justify-content: space-between; gap: 14px;
    padding: 9px 14px; border-bottom: 1px solid var(--line); text-align: left;
  }
  .tw td:last-child { border-bottom: 0; }
  .tw td::before {
    content: attr(data-l); flex: none;
    font-size: 10px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
    color: var(--muted);
  }
  /* A cell with no column name (the actions cell) gets the full width. */
  .tw td:not([data-l]) { justify-content: flex-end; }
  .tw td:not([data-l])::before { display: none; }
  .tw td.num { justify-content: space-between; }
}

/* ── tags ───────────────────────────────────────────────────────────────── */
.tag {
  display: inline-flex; align-items: center; gap: 5px; padding: 3px 9px;
  border-radius: 20px; font-size: 11px; font-weight: 650; border: 1px solid;
}
.tag-paid   { color: var(--good); border-color: #BFE0CE; background: #EAF5EF; }
.tag-part   { color: var(--gold-ink); border-color: #EBD9AE; background: var(--gold-wash); }
.tag-unpaid { color: var(--rose-ink); border-color: #EFC9C5; background: var(--rose-wash); }
.tag-void   { color: var(--faint); border-color: var(--line-2); background: transparent; text-decoration: line-through; }
.tag-quiet  { color: var(--muted); border-color: var(--line-2); background: transparent; }

/* ── stat tiles ─────────────────────────────────────────────────────────── */
.stats { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; }
.stat {
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--r);
  padding: 15px 16px 17px; box-shadow: var(--shadow-1);
  transition: box-shadow .25s var(--ease), transform .25s var(--ease);
}
.stat:hover { box-shadow: var(--shadow-2); }
.stat .k { font-size: 10px; letter-spacing: .12em; text-transform: uppercase; color: var(--muted); font-weight: 700; }
.stat .v {
  font-family: var(--display); font-size: clamp(24px, 7vw, 30px); font-weight: 800;
  margin-top: 7px; letter-spacing: -0.045em; line-height: 1;
}
.stat .s { font-size: 11.5px; color: var(--faint); margin-top: 6px; }
.stat .rule { height: 3px; width: 26px; border-radius: 2px; background: var(--gold-leaf); margin-bottom: 12px; }
.stat.neg .rule { background: var(--rose); }
.stat.neg .v { color: var(--rose); }

/* ── dashboard: today ────────────────────────────────────────────────────── */
/* The one dark surface in the app, and deliberately the only one. On a paper
   ground it fixes the eye before anything else, which is the whole job of the
   line: what happened today, and the button to add to it. Gold is bright here
   because --gold-lift is gold on ink, the token exists for exactly this. */
.today {
  background: var(--ink); color: #F4F1EA; border-radius: var(--r-lg);
  padding: 18px 18px 20px; box-shadow: var(--shadow-2);
  display: flex; flex-direction: column; gap: 16px;
}
.today-main { min-width: 0; }
.today-date {
  font-size: 10.5px; letter-spacing: .12em; text-transform: uppercase;
  font-weight: 700; color: rgba(244,241,234,.5);
}
.today-figs { margin-top: 9px; display: flex; align-items: baseline; flex-wrap: wrap; gap: 0 9px; }
.today-big {
  font-family: var(--display); font-size: clamp(30px, 9vw, 40px); font-weight: 800;
  letter-spacing: -.045em; line-height: 1; color: var(--gold-lift);
}
.today-sep { font-size: 13px; color: rgba(244,241,234,.45); }
.today-mid { font-size: 15px; font-weight: 650; }
.today-none { font-size: 17px; font-weight: 550; color: rgba(244,241,234,.62); }
.today-in {
  flex-basis: 100%; margin-top: 8px; font-size: 12.5px; color: rgba(244,241,234,.62);
  display: inline-flex; align-items: center; gap: 6px;
}
.btn-today { align-self: flex-start; }

/* ── dashboard: the queue ────────────────────────────────────────────────── */
/* Every row is a real <button>: the row IS the action, so it has to be
   focusable and pressable, not a div with a click handler. The left rule is
   the only colour that varies, gold for money coming in, rose for money going
   out or stock running out, so the tone is readable before the words are. */
.queue { padding: 6px 8px; }
.qrow {
  width: 100%; display: flex; align-items: center; gap: 12px; text-align: left;
  padding: 13px 10px 13px 12px; border: 0; background: transparent; border-radius: var(--r);
  cursor: pointer; font: inherit; color: inherit;
  border-bottom: 1px solid var(--line);
  transition: background .18s var(--ease);
}
.qrow:last-child { border-bottom: 0; }
.qrow:hover { background: var(--panel-3); }
.qrow:active { background: var(--line); }
.qrow-i {
  flex: none; width: 34px; height: 34px; border-radius: 10px; display: grid; place-items: center;
  background: var(--panel-3); color: var(--ink-2);
}
.qrow.owe  .qrow-i { background: var(--gold-wash); color: var(--gold-ink); }
.qrow.owed .qrow-i,
.qrow.warn .qrow-i { background: var(--rose-wash); color: var(--rose-ink); }
.qrow-t { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.qrow-title { font-size: 14px; font-weight: 650; letter-spacing: -.01em; }
.qrow-sub {
  font-size: 11.5px; color: var(--faint); line-height: 1.35;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.qrow-v {
  flex: none; font-family: var(--display); font-size: 18px; font-weight: 800;
  letter-spacing: -.03em; font-variant-numeric: tabular-nums;
}
.qrow.owe  .qrow-v { color: var(--gold-ink); }
.qrow.owed .qrow-v { color: var(--rose); }

/* Empty is a sentence, not an empty grid. An "all clear" studio should be able
   to close the screen, not hunt for the thing it failed to show. */
.allclear { display: flex; gap: 14px; align-items: flex-start; padding: 8px 4px 12px; }
.allclear > svg { flex: none; color: var(--good); margin-top: 2px; }
.allclear b { display: block; font-size: 14.5px; margin-bottom: 4px; }
.allclear span { font-size: 12.5px; color: var(--muted); line-height: 1.5; }

/* ── dashboard: where everything else went ───────────────────────────────── */
/* The screens the old dashboard used to inline. Naming them keeps the promise
   that the numbers moved rather than disappeared. */
.elsewhere-lbl { margin: 20px 0 8px; }
.elsewhere { display: grid; grid-template-columns: 1fr; gap: 10px; }
.elsecard {
  display: block; text-align: left; cursor: pointer; font: inherit; color: inherit;
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--r);
  padding: 14px 15px;
  transition: border-color .2s var(--ease), box-shadow .22s var(--ease), transform .22s var(--ease);
}
.elsecard:hover { border-color: var(--gold-deep); box-shadow: var(--shadow-2); transform: translateY(-1px); }
.elsecard > svg { color: var(--gold-ink); }
.elsecard b { display: block; margin-top: 9px; font-size: 14px; font-weight: 700; letter-spacing: -.02em; }
.elsecard span { display: block; margin-top: 3px; font-size: 11.5px; color: var(--faint); line-height: 1.4; }

/* ── bars (six-month trend) ─────────────────────────────────────────────── */
/* Bars are capped and centred. Four months across a 1,100px card would
   otherwise give each one a 250px-wide slab, which reads as a colour block
   rather than a comparison. */
.bars { display: flex; align-items: flex-end; justify-content: center; gap: 14px; height: 120px; padding-top: 8px; }
.bar-col { flex: 1; max-width: 96px; display: flex; flex-direction: column; align-items: center; gap: 6px; min-width: 0; }
.bar {
  width: 100%; background: linear-gradient(180deg, var(--gold-fill), var(--gold-deep));
  border-radius: 4px 4px 0 0; min-height: 3px; transition: height .5s var(--ease);
}
.bar-lbl { font-size: 10.5px; color: var(--faint); white-space: nowrap; }
.bar-val { font-size: 10.5px; color: var(--ink-2); font-weight: 650; }

/* ── modals: bottom sheets on a phone ───────────────────────────────────── */
.backdrop {
  position: fixed; inset: 0; background: rgba(14,20,23,.44);
  backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px);
  z-index: 90; display: flex; align-items: flex-end; justify-content: center;
  animation: fade .18s var(--ease);
}
.modal {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--r-xl) var(--r-xl) 0 0;
  width: 100%; max-height: 94vh; overflow-y: auto; -webkit-overflow-scrolling: touch;
  padding-bottom: var(--safe-b);
  animation: sheet-up .3s var(--ease-out);
  box-shadow: 0 -20px 60px -28px rgba(14,20,23,.5);
}
@keyframes sheet-up { from { transform: translateY(100%); } to { transform: none; } }
.modal-h {
  padding: 16px 18px 14px; border-bottom: 1px solid var(--line);
  display: flex; align-items: flex-start; gap: 12px; position: sticky; top: 0;
  background: var(--panel); z-index: 2; border-radius: var(--r-xl) var(--r-xl) 0 0;
}
.modal-h h3 { font-size: 17px; }
.modal-h .sub { font-size: 12px; color: var(--faint); margin-top: 3px; }
.modal-b { padding: 18px; }
/* The footer is where Save lives, so it stays on screen while the form scrolls
   and it clears the home indicator. */
.modal-f {
  padding: 13px 18px calc(13px + var(--safe-b)); border-top: 1px solid var(--line);
  display: flex; justify-content: flex-end; gap: 9px; position: sticky; bottom: 0;
  background: var(--panel);
}
.modal-f .btn { flex: 1; }
.w-sm, .w-md, .w-lg, .w-xl { max-width: none; }

@keyframes fade { from { opacity: 0 } }
@keyframes rise { from { opacity: 0; transform: translateY(8px) } }
.in { animation: rise .22s var(--ease) both; }

/* The drawer behind the "More" tab. */
.drawer { background: var(--panel); width: min(300px, 84vw); }
.drawer .side { display: flex; width: 100%; }

/* ── toast ──────────────────────────────────────────────────────────────── */
#toasts {
  position: fixed; left: 12px; right: 12px; bottom: calc(74px + var(--safe-b)); z-index: 200;
  display: flex; flex-direction: column; gap: 8px; pointer-events: none;
}
.toast {
  background: var(--ink); color: #fff; border-left: 3px solid var(--gold-fill);
  border-radius: var(--r-sm); padding: 11px 14px; font-size: 13.5px;
  box-shadow: var(--shadow-3); animation: rise .24s var(--ease);
}
.toast.err { border-left-color: var(--rose); }

.empty { text-align: center; padding: 40px 20px; color: var(--faint); font-size: 13.5px; }
.empty svg { opacity: .4; margin-bottom: 10px; }

.warn-strip {
  background: var(--rose-wash); border: 1px solid #EFC9C5;
  border-radius: var(--r-sm); padding: 11px 13px; font-size: 13px; color: var(--rose-ink);
}
.note-strip {
  background: var(--gold-wash); border: 1px solid #EBD9AE;
  border-radius: var(--r-sm); padding: 11px 13px; font-size: 13px; color: var(--gold-ink);
}

/* ── login ──────────────────────────────────────────────────────────────── */
.login-wrap {
  min-height: 100vh; display: grid; place-items: center; padding: 20px;
  background: radial-gradient(1100px 620px at 50% -12%, #FFFFFF 0%, var(--paper) 62%);
}
.login { width: 100%; max-width: 372px; }
.login .card { padding: 28px 24px; }
.login-mark {
  width: 52px; height: 52px; border-radius: 15px; background: var(--gold-fill);
  color: var(--ink); display: grid; place-items: center; margin: 0 auto 16px;
}
.login h2 { text-align: center; font-size: 21px; }
.login .sub { text-align: center; color: var(--faint); font-size: 12.5px; margin: 6px 0 22px; }

/* ── invoice paper (screen preview + print) ─────────────────────────────── */
/* Unchanged from the dark build: this is a piece of A5 paper, and paper has
   been white the whole time. Only the chrome around it ever changed. */
.paper-sheet {
  background: #fff; color: #101418; padding: 15px 16px;
  font-size: 10px; line-height: 1.34; position: relative;
  font-variant-numeric: tabular-nums;
}
.paper-sheet table { border-collapse: collapse; }
.paper-sheet .ph { border-bottom: 2px solid #101418; padding-bottom: 7px;
  display: flex; justify-content: space-between; gap: 14px; }
.paper-sheet .pname { font-family: var(--display); font-size: 16px; font-weight: 700; letter-spacing: -.02em; }
.paper-sheet .ptitle { font-family: var(--display); font-size: 14px; font-weight: 700; text-align: right; }
.paper-sheet .plabel { font-size: 7.5px; letter-spacing: .1em; text-transform: uppercase;
  color: #6A7780; font-weight: 700; }
.paper-sheet .pitems th { background: #101418; color: #fff; padding: 4px 6px;
  font-size: 8px; letter-spacing: .05em; border: 0; }
.paper-sheet .pitems td { padding: 4px 6px; border-bottom: 1px solid #E4E8EA; font-size: 9px; color: #101418; }
.paper-sheet .pbox { border: 1px solid #C9D0D4; border-radius: 3px; padding: 6px 8px; }
.paper-sheet .prow { display: flex; justify-content: space-between; padding: 1px 0; }
.paper-sheet .ptotal { display: flex; justify-content: space-between; border-top: 2px solid #101418;
  margin-top: 3px; padding-top: 4px; font-weight: 700; font-size: 12px; }
.paper-sheet .pmark { position: absolute; inset: 0; display: grid; place-items: center; pointer-events: none; }
.paper-sheet .pmark span {
  transform: rotate(-26deg); font-family: var(--display); font-size: 46px; font-weight: 800;
  color: rgba(16,20,24,.09); border: 5px solid rgba(16,20,24,.09); padding: 5px 22px; border-radius: 8px;
}
/* The sheet is a table on paper whatever the viewport did to other tables. */
.paper-sheet .tw table, .paper-sheet .tw tbody, .paper-sheet .tw tr, .paper-sheet .tw td { display: revert; }
.paper-sheet .tw thead { display: revert; }
.paper-sheet td::before { content: none; }

@media print {
  /* Hide everything's own paint, then bring back only the invoice sheet.
     `visibility` rather than `display` on the ancestors, so the sheet nested
     inside the modal survives while the chrome around it does not. */
  body * { visibility: hidden !important; }
  #print-area, #print-area * { visibility: visible !important; }
  #print-area {
    position: absolute !important; left: 0; top: 0; width: 100%;
    background: #fff !important;
  }
  .no-print, .tabbar { display: none !important; }
  .backdrop { position: static !important; display: block !important;
    background: none !important; backdrop-filter: none !important; padding: 0 !important; }
  .modal { max-height: none !important; overflow: visible !important;
    border: 0 !important; box-shadow: none !important; max-width: none !important;
    border-radius: 0 !important; animation: none !important; }
  @page { size: A5 portrait; margin: 7mm; }
}

/* ═══ 560px ═════════════════════════════════════════════════════════════ */
@media (min-width: 560px) {
  .grid2 { grid-template-columns: 1fr 1fr; }
  .stats { grid-template-columns: repeat(auto-fit, minmax(168px, 1fr)); }
  .modal-f .btn { flex: none; }
  /* The day and its button share a line once there is room for both. */
  .today { flex-direction: row; align-items: center; justify-content: space-between; padding: 20px 22px; }
  .btn-today { align-self: auto; }
  .elsewhere { grid-template-columns: repeat(3, 1fr); }
}

/* ═══ 760px, tables become tables again ════════════════════════════════ */
@media (min-width: 760px) {
  .grid3 { grid-template-columns: repeat(3, 1fr); }
  .backdrop { align-items: center; padding: 20px; }
  .modal {
    border-radius: var(--r-lg); max-height: 92vh; padding-bottom: 0;
    animation: rise .22s var(--ease); box-shadow: var(--shadow-3);
  }
  .modal-h { border-radius: var(--r-lg) var(--r-lg) 0 0; }
  .modal-f { border-radius: 0 0 var(--r-lg) var(--r-lg); padding-bottom: 13px; }
  .w-sm { max-width: 420px; } .w-md { max-width: 640px; }
  .w-lg { max-width: 900px; } .w-xl { max-width: 1120px; }
  #toasts { left: auto; right: 18px; bottom: auto; top: 18px; max-width: 380px; }
}

/* ═══ 900px, the desktop side rail ═════════════════════════════════════ */
@media (min-width: 900px) {
  .side { display: flex; }
  .tabbar { display: none; }
  .page { padding: 22px 26px 60px; }
  .topbar { padding: 15px 26px; }
  .topbar h1 { font-size: 24px; }
  .topbar .sub { max-width: none; }
  /* On a phone the queue row's sub-line is one truncated line; on desktop
     there is room to let the low-stock names wrap and be read in full. */
  .qrow-sub { white-space: normal; }
  .qrow { padding: 15px 12px 15px 14px; }
  .qrow-v { font-size: 21px; }
}

/* ── analytics: ranked rows ──────────────────────────────────────────────── */
/* A bar per row rather than a bare number column: the point of a "what sells"
   list is the gap between first and last, and a column of rupees hides it. */
.rank { padding: 9px 0; border-bottom: 1px solid rgba(36,49,55,.5); }
.rank:last-child { border-bottom: 0; }
.rank-top { display: flex; align-items: baseline; gap: 12px; }
.rank-name { flex: 1; min-width: 0; font-size: 13.5px; font-weight: 550;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rank-val { font-weight: 650; font-size: 13.5px; font-variant-numeric: tabular-nums; }
.rank-track { margin-top: 7px; height: 5px; border-radius: 3px; background: var(--panel-3); overflow: hidden; }
.rank-fill { height: 100%; border-radius: 3px;
  background: linear-gradient(90deg, var(--gold-fill), var(--gold-deep));
  transition: width .5s var(--ease); }
.rank-sub { margin-top: 5px; font-size: 11.5px; color: var(--faint); }

/* ── analytics: payment mix ──────────────────────────────────────────────── */
/* One stacked bar, because the question is "what share", not "how much",
   four separate bars would make the reader do the division themselves. */
.mixbar { display: flex; height: 12px; border-radius: 6px; overflow: hidden; background: var(--panel-3); }
.mixseg { height: 100%; transition: width .5s var(--ease); }
.mixseg.s0, .dot.d0 { background: var(--gold-leaf); }
.mixseg.s1, .dot.d1 { background: var(--gold-deep); }
.mixseg.s2, .dot.d2 { background: #8A7A52; }
.mixseg.s3, .dot.d3 { background: #55606A; }
.dot { display: inline-block; width: 9px; height: 9px; border-radius: 50%; margin-right: 7px; }

/* ── whatsapp: what this can and cannot do ───────────────────────────────── */
/* The dialog changes shape by capability, so the explanation has to be part of
   it rather than a footnote: a desktop browser genuinely cannot attach a file
   to WhatsApp, and a UI that hides that just produces a chat with no bill in it. */
.wa-how {
  display: flex; gap: 11px; align-items: flex-start; margin-bottom: 14px;
  padding: 12px 13px; border-radius: var(--r);
  background: var(--rose-wash); border: 1px solid rgba(185,59,51,.2);
}
.wa-how.can { background: var(--gold-wash); border-color: rgba(199,151,51,.3); }
.wa-how > svg { flex: none; margin-top: 1px; color: var(--rose-ink); }
.wa-how.can > svg { color: var(--gold-ink); }
.wa-how b { display: block; font-size: 13px; margin-bottom: 3px; }
.wa-how span { font-size: 12px; color: var(--ink-2); line-height: 1.5; }
.wa-how code { font-family: var(--mono, ui-monospace, monospace); font-size: 11.5px; }

.wa-bill {
  display: flex; align-items: center; gap: 9px; font-size: 13px;
  padding: 11px 13px; border-radius: var(--r);
  border: 1px dashed var(--line-2); color: var(--muted);
}
.wa-bill.ok { border-style: solid; color: var(--ink); background: var(--panel-3); }
.wa-bill.err { border-color: rgba(185,59,51,.4); color: var(--rose-ink); background: var(--rose-wash); }
.wa-bill > svg { color: var(--gold-ink); flex: none; }

/* ── payments: where the money lands ─────────────────────────────────────── */
/* Shown before the payment is saved. "₹15,000 against four bills" is a real
   decision the studio is making, so it is spelled out bill by bill rather than
   happening quietly and being discovered later in a statement. */
.alloc {
  margin: 4px 0 14px; padding: 12px 13px;
  background: var(--panel-3); border: 1px solid var(--line); border-radius: var(--r);
}
.alloc-row {
  display: flex; align-items: center; gap: 8px; font-size: 12.5px;
  padding: 7px 0; border-bottom: 1px solid var(--line);
}
.alloc-row:last-child { border-bottom: 0; padding-bottom: 0; }
.alloc-row.adv { color: var(--rose-ink); }
.alloc-row.adv > svg { flex: none; }
.alloc-amt { font-weight: 700; font-variant-numeric: tabular-nums; }

/* ── the discount box on an invoice line ─────────────────────────────────── */
/* One control, two meanings: the toggle says which side you are typing, and the
   mirror underneath is what the server resolved the other side to. It is never
   worked out in the browser, so it cannot disagree with the saved bill. */
.disc { position: relative; display: flex; align-items: center; flex: none; }
.disc-t {
  width: 30px; height: 40px; flex: none; cursor: pointer;
  border: 1.5px solid var(--line-2); border-right: 0; border-radius: 10px 0 0 10px;
  background: var(--panel-3); color: var(--ink-2); font: inherit; font-weight: 700; font-size: 13px;
}
.disc-t:hover { background: var(--line); color: var(--ink); }
.disc-i { width: 74px; border-radius: 0 10px 10px 0 !important; }
.disc-m {
  position: absolute; left: 30px; top: 100%; margin-top: 2px;
  font-size: 10px; color: var(--gold-ink); font-weight: 650; white-space: nowrap;
}

/* A loss is a bar too, drawn in the colour reserved for money going the wrong
   way, so a bad month is legible at a glance rather than just short. */
.bar-neg { background: linear-gradient(180deg, #D0574E, var(--rose)) !important; }
.tot-row td { border-top: 2px solid var(--line-2); font-weight: 700; }

.logo-box {
  width: 120px; height: 56px; flex: none; display: grid; place-items: center;
  border: 1px dashed var(--line-2); border-radius: var(--r); background: var(--panel-3); overflow: hidden;
}
.logo-box img { max-width: 100%; max-height: 100%; object-fit: contain; }

.lastprice {
  position: absolute; left: 2px; top: 100%; margin-top: 2px;
  font-size: 10px; color: var(--faint); white-space: nowrap;
}

/* ── your cost, while you are setting the price ──────────────────────────── */
/* Owner information: it comes from /api/quote (behind the session) and never
   reaches the invoice or the PDF. Marked with an eye so it reads as something
   only this side of the counter sees. */
.costline {
  display: flex; align-items: center; gap: 7px; flex-wrap: wrap;
  margin: -2px 0 10px 70px; font-size: 11.5px; color: var(--muted);
}
.costline > svg { color: var(--gold-ink); flex: none; }
.costline b { color: var(--ink); font-weight: 700; }
.costmargin { margin-left: auto; font-weight: 700; color: var(--good); }
.costmargin.bad { color: var(--rose); }

/* ── section tabs ────────────────────────────────────────────────────────── */
/* What let the side rail go from eighteen entries to six: the related screens
   are now words on one line where they can be compared, instead of a scroll of
   rail items where they cannot. Scrolls sideways on a phone rather than
   wrapping into a second row that pushes the page down. */
.tabstrip {
  display: flex; gap: 2px; align-items: center;
  padding: 0 14px; border-bottom: 1px solid var(--line); background: var(--panel);
  overflow-x: auto; scrollbar-width: none;
}
.tabstrip::-webkit-scrollbar { display: none; }
.tstab {
  position: relative; flex: none; cursor: pointer; font: inherit;
  padding: 12px 14px 11px; border: 0; background: transparent;
  color: var(--muted); font-size: 13.5px; font-weight: 600; white-space: nowrap;
  border-bottom: 2px solid transparent; margin-bottom: -1px;
  transition: color .18s var(--ease), border-color .18s var(--ease);
  display: flex; align-items: center; gap: 7px;
}
.tstab:hover { color: var(--ink); }
.tstab.on { color: var(--ink); border-bottom-color: var(--gold-deep); }
.tstab .badge-n { position: static; }

@media (min-width: 900px) {
  .tabstrip { padding: 0 26px; }
}

/* ── prices you can change where you see them ────────────────────────────── */
.pricecell {
  display: inline-flex; align-items: center; gap: 6px; cursor: pointer; font: inherit;
  border: 1px solid transparent; border-radius: 8px; padding: 3px 7px; margin: -3px -7px;
  background: transparent; color: var(--ink); font-weight: 650; font-variant-numeric: tabular-nums;
  transition: background .15s var(--ease), border-color .15s var(--ease);
}
.pricecell > svg { opacity: 0; color: var(--gold-ink); transition: opacity .15s var(--ease); }
.pricecell:hover { background: var(--gold-wash); border-color: rgba(199,151,51,.35); }
.pricecell:hover > svg { opacity: 1; }
.pricecell.empty { color: var(--faint); font-weight: 500; }
.pricecell-i { width: 108px; min-height: 32px; padding: 0 8px; font-size: 13px; }

/* One row per vehicle size, the shape of "this job costs different money on a
   hatchback and on an XUV", which is one service and several prices. */
.sizegrid { display: grid; gap: 2px; }
.sizerow {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 5px 0; font-size: 13px; border-bottom: 1px solid var(--line);
}
.sizerow:last-child { border-bottom: 0; }
.sizerow > span { color: var(--muted); }
.sizerow.base { border-top: 1px dashed var(--line-2); margin-top: 3px; padding-top: 8px; }
.sizerow.base > span { font-style: italic; }

.sizechip {
  display: inline-flex; align-items: center; gap: 2px;
  border: 1.5px solid var(--line-2); border-radius: 999px; padding: 2px 4px 2px 10px;
  background: var(--panel);
}
.sizechip input {
  border: 0; background: transparent; font: inherit; font-size: 13px; font-weight: 600;
  width: 86px; color: var(--ink); outline: none;
}
.sizechip button {
  border: 0; background: transparent; cursor: pointer; color: var(--faint);
  display: grid; place-items: center; width: 22px; height: 22px; border-radius: 50%;
}
.sizechip button:hover { background: var(--rose-wash); color: var(--rose); }

/* ── linking WhatsApp ────────────────────────────────────────────────────── */
.wa-setup {
  border: 1px solid var(--line); border-radius: var(--r); padding: 14px;
  background: var(--panel-3);
}
.wa-setup p { font-size: 12.5px; color: var(--muted); line-height: 1.55; margin: 10px 0 0; }
.wa-state { display: inline-flex; align-items: center; gap: 7px; font-size: 13px; font-weight: 700; }
.wa-state.on { color: var(--good); }
.wa-state.wait { color: var(--gold-ink); }
.wa-state.off { color: var(--faint); }
.wa-qr {
  display: block; width: 220px; height: 220px; margin: 12px 0 0;
  border: 1px solid var(--line); border-radius: var(--r); background: #fff; padding: 6px;
}
/* The risk is stated where the decision is made, not in a footnote. */
.wa-warn {
  display: flex; gap: 9px; margin-top: 12px; padding: 10px 11px; border-radius: var(--r);
  background: var(--rose-wash); border: 1px solid rgba(185,59,51,.25);
  font-size: 12px; color: var(--ink-2); line-height: 1.5;
}
.wa-warn > svg { flex: none; margin-top: 2px; color: var(--rose-ink); }


/* Spend filter chips. A chip carries its own total, so choosing a type and
   reading what it cost are the same glance, the number is the reason you are
   pressing it. A type with nothing in it this range stays visible but recedes,
   because a chip that disappears reads as a type that was deleted. */
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 11px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--panel);
  font: inherit; font-size: 12.5px; font-weight: 600; color: var(--ink);
  cursor: pointer; transition: background .15s, border-color .15s, color .15s;
}
.chip:hover { border-color: var(--line-2); }
.chip-v { font-weight: 700; font-variant-numeric: tabular-nums; color: var(--ink-2); }
.chip.nil { color: var(--faint); }
.chip.nil .chip-v { color: var(--faint); }
.chip.on { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.chip.on .chip-v { color: var(--paper); }

/* A reference that goes somewhere, inside a table cell. */
.linkish {
  border: 0; background: none; padding: 0; font: inherit; color: var(--ink-2);
  text-decoration: underline; text-underline-offset: 2px; cursor: pointer;
}
.linkish:hover { color: var(--ink); }

/* The GST basis choice. It is two full-width statements rather than a switch:
   a toggle labelled "inclusive" tells you nothing until you see which number
   moves, so each option carries a worked example at the studio's own slab. */
.basis { margin-bottom: 12px; }
.basis-opts { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.basis-opt {
  display: flex; flex-direction: column; gap: 3px; align-items: flex-start;
  padding: 9px 12px; border-radius: 10px; text-align: left;
  border: 1px solid var(--line); background: var(--panel);
  font: inherit; color: var(--ink); cursor: pointer;
  transition: background .15s, border-color .15s, color .15s;
}
.basis-opt:hover { border-color: var(--line-2); }
.basis-l { font-size: 13px; font-weight: 650; letter-spacing: -.01em; }
.basis-s { font-size: 11.5px; color: var(--muted); font-variant-numeric: tabular-nums; }
.basis-opt.on { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.basis-opt.on .basis-s { color: var(--gold-lift); }
@media (max-width: 560px) { .basis-opts { grid-template-columns: 1fr; } }

/* The badge already says "Neat Wheels", so it replaces the gold car tile and
   the name beside it rather than sitting next to a second copy of the name.
   Only DetailERP stays, the one thing the badge does not say. */
.brand { flex-direction: column; align-items: flex-start; gap: 6px; }
.brand-logo { height: 46px; width: auto; display: block; }
.login-logo { height: 84px; width: auto; display: block; margin: 0 auto 12px; }

/* Setup. A list, in the order the work has to happen, not a wizard that traps
   you on step 3. Each row states why it matters, because "add your GSTIN" is an
   instruction and "it is printed on every bill you issue" is a reason. */
.setup-head h2 { font-family: var(--display); font-size: 24px; letter-spacing: -.03em; margin: 0 0 4px; }
.setup-head p { color: var(--muted); font-size: 14px; margin: 0 0 12px; max-width: 60ch; }
.setup-bar { height: 6px; border-radius: 999px; background: var(--panel-3); overflow: hidden; margin-bottom: 6px; }
.setup-bar span { display: block; height: 100%; background: var(--gold-leaf); transition: width .4s var(--ease, ease); }
.setup-row {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 14px 16px; border-bottom: 1px solid var(--line);
}
.setup-row:last-child { border-bottom: 0; }
.setup-n {
  flex: none; width: 24px; height: 24px; border-radius: 999px;
  display: grid; place-items: center; font-size: 12px; font-weight: 700;
  background: var(--panel-3); color: var(--muted);
}
.setup-row.done .setup-n { background: var(--ink); color: var(--gold-lift); }
.setup-t { flex: 1; min-width: 0; }
.setup-title { font-size: 14px; font-weight: 650; letter-spacing: -.01em; }
.setup-row.done .setup-title { color: var(--muted); }
.setup-why { font-size: 12.5px; color: var(--muted); margin-top: 2px; }
.setup-row.waiting .setup-title,
.setup-row.waiting .setup-why { color: var(--faint); }
