/* App chrome. The printed document is styled in print.css. */

:root {
  /* Sampled from the LC Event Solutions estimate PDF. */
  --ink:      #171717;   /* body copy and headings */
  --ink-2:    #3f4449;
  --muted:    #5e6368;   /* secondary copy on the estimate */
  --line:     #d9d9d9;   /* rules on the estimate */
  --line-2:   #ececec;
  --bg:       #f7f7f7;   /* panel tint on the estimate */
  --panel:    #ffffff;
  --accent:   #171717;   /* app chrome */
  --brand:    #ff914d;   /* the orange band and footer rule */
  --brand-dk: #e87a35;
  --brand-lt: #fff1e6;
  --panel-2:  #fcfcfd;
  --blue:     #2563eb;  --blue-lt:   #e4edfd;   /* informational: links, Sent */
  --green:    #0f8a55;  --green-lt:  #dcf3e7;   /* settled: Paid, Approved, synced */
  --amber:    #b45309;  --amber-lt:  #fdeed7;   /* attention: Deposit Due, warnings */
  --red:      #c02626;  --red-lt:    #fbe2e2;   /* stop: overdue, Void, destructive */
  --purple:   #6d3fc4;  --purple-lt: #ece2fb;   /* in progress: Show, Wrapped */
  --dark:     #3a4150;                          /* terminal: Closed */
  --radius:   8px;

  /* Type scale. Seven stops. Everything below uses one of these. */
  --fs-xs:   11px;   /* field labels, table headers, badges, KPI labels */
  --fs-sm:   12px;   /* hints, footers, banners */
  --fs-md:   13px;   /* table body, buttons, inputs */
  --fs-base: 14px;   /* body copy, totals rows */
  --fs-lg:   16px;   /* modal titles, mobile nav */
  --fs-xl:   20px;   /* page h1, KPI values */
  --fs-2xl:  24px;   /* grand total, sheet title */

  /* Spacing on a 4pt grid. */
  --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px; --sp-5: 20px; --sp-6: 24px; --sp-8: 32px;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, Roboto, Helvetica, Arial, sans-serif;
}

* { box-sizing: border-box; }

/* A display rule on a class beats the browser's own [hidden] rule, so state it
   once here rather than remembering it at every call site. */
[hidden] { display: none !important; }

body {
  margin: 0;
  font-family: var(--sans);
  font-size: 14px;
  line-height: 1.45;
  color: var(--ink);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
}

h1 { font-size: var(--fs-xl); margin: 0; letter-spacing: -0.01em; line-height: 1.2; }
h2 { font-size: var(--fs-base); margin: 0; font-weight: 600; letter-spacing: 0.01em; line-height: 1.2; }
a { color: inherit; }
.link { color: var(--blue); text-decoration: none; }
.link:hover { text-decoration: underline; }
.muted { color: var(--muted); }
.small { font-size: var(--fs-sm); }
.strong { font-weight: 600; }
.mono { font-family: var(--mono); font-variant-numeric: tabular-nums; }
.right { text-align: right; }
.pad { padding: 16px; }
.warn-text { color: var(--amber); }

/* ---------- top bar ---------- */

#topbar {
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; gap: 24px;
  padding: 10px 20px;
  background: var(--accent); color: #fff;
  border-top: 4px solid var(--brand);
}
.brand { display: flex; align-items: center; gap: 10px; min-width: 170px; }
.brand img { max-height: 40px; max-width: 60px; object-fit: contain; }
#brandName { font-weight: 600; font-size: 14px; line-height: 1.2; }
.brand-sub { font-size: 11px; opacity: 0.55; letter-spacing: 0.06em; text-transform: uppercase; }

#nav { display: flex; gap: 2px; flex: 1; flex-wrap: wrap; }
#nav a {
  padding: 6px 11px; border-radius: 6px; text-decoration: none;
  color: rgba(255,255,255,0.62); font-size: 13px;
}
#nav a:hover { color: #fff; background: rgba(255,255,255,0.08); }
#nav a.active { color: #fff; background: rgba(255,145,77,0.22); box-shadow: inset 0 -2px 0 var(--brand); }

#main { max-width: 1220px; margin: 0 auto; padding: 20px; }
#foot { max-width: 1220px; margin: 0 auto; padding: 8px 20px 40px; color: var(--muted); font-size: 12px; }

/* ---------- buttons: four tiers, no more ----------
   primary   solid brand, one per screen
   secondary white with a border, everything else in a toolbar
   ghost     transparent, inside cards and banners
   danger    outlined red inline; solid red as the confirm in a dialog */

.btn {
  font: inherit; font-size: var(--fs-md); line-height: 1.2;
  min-height: 32px; padding: 6px 13px;
  border: 1px solid var(--line); border-radius: 6px;
  background: #fff; color: var(--ink); cursor: pointer;
  white-space: nowrap;
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
}
.btn:hover:not(:disabled) { border-color: #c9cfda; background: var(--panel-2); }
.btn:disabled { opacity: 0.5; cursor: default; }
.btn-primary { background: var(--brand); border-color: var(--brand); color: var(--ink); font-weight: 600; }
/* Darken the fill on hover; keep ink text, white on this orange is under 3:1. */
.btn-primary:hover:not(:disabled) { background: var(--brand-dk); border-color: var(--brand-dk); color: var(--ink); }
.btn-ghost { background: transparent; }
.btn-danger { color: var(--red); border-color: #f0d2d2; }
.btn-danger:hover:not(:disabled) { background: #fdf3f3; border-color: #e6b5b5; }
/* The confirm in a destructive dialog has to read as the strong choice. */
.modal-foot .btn-danger { background: var(--red); border-color: var(--red); color: #fff; font-weight: 600; }
.modal-foot .btn-danger:hover:not(:disabled) { background: #a41f1f; border-color: #a41f1f; color: #fff; }

/* One focus ring for everything a keyboard can land on. */
.btn:focus-visible, .inp:focus-visible, .mini:focus-visible, .linkbtn:focus-visible,
#nav a:focus-visible, .nav-more:focus-visible, .clickable:focus-visible {
  outline: 2px solid var(--blue); outline-offset: 2px;
}
.inp:focus { outline: 2px solid var(--blue); outline-offset: -1px; border-color: var(--blue); }

/* Dark bars: a ghost button must not go white on hover. */
#topbar .btn { border-color: rgba(255,255,255,0.2); }
#topbar .btn-primary { border-color: var(--brand); }
#topbar .btn-ghost:hover:not(:disabled), #printBar .btn-ghost:hover:not(:disabled) {
  background: rgba(255,255,255,0.1); border-color: rgba(255,255,255,0.35); color: #fff;
}
.btn-row { display: flex; gap: 8px; flex-wrap: wrap; }

.mini {
  font: inherit; font-size: var(--fs-base); line-height: 1;
  min-width: 28px; min-height: 28px; padding: 0 4px;
  border: 1px solid transparent; border-radius: 4px;
  background: transparent; color: var(--muted); cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
}
.mini:hover:not(:disabled) { background: var(--line-2); color: var(--ink); }
.mini:disabled { opacity: 0.4; cursor: default; }
.mini.danger:hover { background: #fdecec; color: var(--red); }

/* ---------- cards + layout ---------- */

.card {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--radius); margin-bottom: 16px; overflow: hidden;
}
.card-head {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: var(--sp-3) var(--sp-4); border-bottom: 1px solid var(--line-2); background: var(--panel-2);
}
.card-head h2 { text-transform: uppercase; font-size: var(--fs-xs); letter-spacing: 0.07em; color: var(--ink-2); }
.card > .grid, .card > .filters, .card > textarea, .card > p { padding: var(--sp-4); }
.card > .grid + .grid { padding-top: 0; }

.toolbar {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 16px; flex-wrap: wrap; margin-bottom: 16px;
}
.toolbar-title { min-width: 240px; }
.toolbar-sub { display: flex; align-items: center; gap: 8px; margin-top: 5px; flex-wrap: wrap; font-size: 13px; }
.toolbar-actions { display: flex; gap: 7px; flex-wrap: wrap; align-items: center; }
.toolbar-actions select.inp { width: auto; min-width: 180px; }

.grid { display: grid; gap: 12px; }
.grid-2 { grid-template-columns: repeat(2, minmax(0,1fr)); }
.grid-3 { grid-template-columns: repeat(3, minmax(0,1fr)); }
.grid-4 { grid-template-columns: repeat(4, minmax(0,1fr)); }
.grid-5 { grid-template-columns: repeat(5, minmax(0,1fr)); }

.editor-bottom { display: grid; grid-template-columns: 1.35fr 1fr; gap: 16px; align-items: start; }
.side .card { margin-bottom: 16px; }

.filters { display: flex; gap: 8px; flex-wrap: wrap; }
.filters .inp { max-width: 260px; }

/* ---------- form controls ---------- */

.inp {
  font: inherit; font-size: 13px; width: 100%;
  padding: 6px 9px; border: 1px solid var(--line); border-radius: 6px;
  background: #fff; color: var(--ink);
}
.inp:disabled { background: #f7f8fa; color: var(--muted); }
select.inp { cursor: pointer; }
textarea.inp { resize: vertical; line-height: 1.5; }
.inp.num { text-align: right; font-family: var(--mono); font-variant-numeric: tabular-nums; }
.inp.sm { width: 82px; }
.inp.mode { width: 62px; }

.field { display: block; }
.field-label {
  display: block; font-size: var(--fs-xs); text-transform: uppercase;
  letter-spacing: 0.05em; color: var(--muted); margin-bottom: var(--sp-1);
}
.field-hint { display: block; font-size: var(--fs-sm); color: var(--muted); margin-top: var(--sp-1); }

/* ---------- badges + banners ---------- */

.badge {
  display: inline-block; padding: 2px 8px; border-radius: 999px;
  font-size: 11px; font-weight: 600; letter-spacing: 0.01em; white-space: nowrap;
}
.badge-gray   { background: #eceef2; color: #565e6d; }
.badge-blue   { background: #e4edfd; color: #1d4ed8; }
.badge-green  { background: #dcf3e7; color: #0b6b43; }
.badge-amber  { background: #fdeed7; color: #92400e; }
.badge-purple { background: #ece2fb; color: #5b32a8; }
.badge-red    { background: #fbe2e2; color: #a41f1f; }
.badge-darkred{ background: #7d1d1d; color: #fff; }
.badge-dark   { background: #3a4150; color: #fff; }

.banner {
  padding: 9px 14px; background: #f2f6fd; border-bottom: 1px solid #dbe6fa;
  font-size: var(--fs-sm); color: #24406f;
}
.card > .banner:last-child { border-bottom: none; }
.banner-warn { background: #fdf6e8; border-color: #f3e2bd; color: #7a5410; }
div.banner { border-radius: var(--radius); border: 1px solid #dbe6fa; margin-bottom: 16px; }
div.banner-warn { border-color: #f3e2bd; }

/* ---------- KPIs ---------- */

.kpis { display: grid; grid-template-columns: repeat(4, minmax(0,1fr)); gap: 12px; margin-bottom: 16px; }
.card .kpis { padding: 14px; margin-bottom: 0; }
.kpi { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); padding: var(--sp-4); }
.kpi-label { font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: 0.05em; color: var(--muted); }
.kpi-value { font-size: var(--fs-xl); font-weight: 600; letter-spacing: -0.02em; margin-top: 3px; line-height: 1.2; }
.kpi-sub { font-size: var(--fs-sm); color: var(--muted); margin-top: 2px; }
.kpi-bad .kpi-value  { color: var(--red); }
.kpi-warn .kpi-value { color: var(--amber); }
.kpi-good .kpi-value { color: var(--green); }

/* ---------- alerts ---------- */

.alerts { display: flex; flex-direction: column; }
.alert {
  display: flex; justify-content: space-between; gap: 16px; align-items: baseline;
  padding: 10px 14px; border-bottom: 1px solid var(--line-2);
  text-decoration: none; border-left: 3px solid transparent;
}
.alert:last-child { border-bottom: none; }
.alert:hover { background: #fafbfc; }
.alert-bad  { border-left-color: var(--red); }
.alert-warn { border-left-color: var(--amber); }
.alert-title { font-weight: 600; font-size: 13px; }
.alert-detail { color: var(--muted); font-size: var(--fs-sm); text-align: right; }

/* ---------- tables ---------- */

.grid-table, .mini-table, .lines { width: 100%; border-collapse: collapse; font-size: 13px; }
.grid-table th, .mini-table th, .lines th {
  text-align: left; font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--muted); font-weight: 600; padding: var(--sp-2) var(--sp-3);
  border-bottom: 1px solid var(--line); background: #fcfcfd;
}
.grid-table th.right, .mini-table th.right { text-align: right; }
.grid-table td, .mini-table td { padding: 9px var(--sp-3); border-bottom: 1px solid var(--line-2); }
.grid-table tr:last-child td, .mini-table tr:last-child td { border-bottom: none; }
.grid-table tbody tr.clickable { cursor: pointer; }
.grid-table tbody tr.clickable:hover { background: #f7f9fc; }
.grid-table tfoot td, .mini-table tfoot td { padding: 9px 12px; border-top: 1px solid var(--line); font-weight: 600; }
.mini-table { font-size: var(--fs-md); }
.mini-table td, .mini-table th { padding: 6px 14px; }
.table-wrap { overflow-x: auto; }
td.empty { padding: 20px 14px; color: var(--muted); text-align: center; }

/* ---------- line item editor ---------- */

.lines td { padding: 5px 8px; border-bottom: 1px solid var(--line-2); vertical-align: middle; }
.lines th { padding: 8px; }
.lines .c-drag  { width: 52px; white-space: nowrap; }
.lines .c-cat   { width: 150px; }
.lines .c-qty   { width: 78px; }
.lines .c-price { width: 108px; }
.lines .c-amt   { width: 108px; text-align: right; font-weight: 600; white-space: nowrap; }
.lines .c-tax   { width: 104px; }
.lines .c-cost  { width: 100px; }
.lines .c-x     { width: 34px; }
.cost-inp { background: #fcfaf5; }
.line-actions { display: flex; gap: 8px; padding: 12px 14px; border-top: 1px solid var(--line-2); background: #fcfcfd; }
.rate-picker { max-width: 340px; }

/* ---------- totals stack ---------- */

.totals .trows { padding: 6px 14px 14px; }
.trow {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; padding: 7px 0; border-bottom: 1px solid var(--line-2);
}
.trow:last-child { border-bottom: none; }
.trow-label { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; color: var(--ink-2); }
.trow-val { font-weight: 600; white-space: nowrap; }
.trow-fee { background: #fbfbfd; margin: 0 -14px; padding: 9px 14px; border-top: 1px solid var(--line-2); }
.trow-fee .trow-label { flex-wrap: nowrap; }
.trow-fee .fee-label { width: 132px; font-weight: 600; }
.trow-fee .fee-base { width: 140px; font-size: 12px; }
.trow-note { border-bottom: none; padding: 2px 0 6px; }
.trow-total { border-top: 2px solid var(--brand); border-bottom: none; margin-top: 4px; padding-top: 10px; }
.trow-total .trow-label { font-weight: 700; letter-spacing: 0.04em; color: var(--ink); font-size: 13px; }
.trow-total .trow-val { font-size: var(--fs-2xl); }
.trow-sub .trow-label, .trow-sub .trow-val { color: var(--muted); }

/* ---------- margin panel ---------- */

.margin-card .card-head { background: #fbfaf6; }
.margin-under { border-color: #f0d9a8; }
.margin-hero { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; padding: 14px; }
.margin-hero .big { font-size: var(--fs-xl); font-weight: 600; letter-spacing: -0.02em; }

/* ---------- logo settings ---------- */

.logo-row { display: flex; gap: 16px; align-items: center; padding: 14px; border-top: 1px solid var(--line-2); }
.logo-preview {
  width: 150px; height: 74px; border: 1px dashed var(--line); border-radius: 6px;
  display: flex; align-items: center; justify-content: center; background: #fcfcfd; flex-shrink: 0;
}
.logo-preview img { max-width: 90%; max-height: 90%; object-fit: contain; }
.logo-preview { background: #fff; }

/* ---------- modal ---------- */

.modal-back {
  position: fixed; inset: 0; z-index: 100; background: rgba(16,18,22,0.42);
  display: flex; align-items: flex-start; justify-content: center;
  padding: 48px 16px; overflow-y: auto;
}
.modal { background: #fff; border-radius: 10px; width: 100%; max-width: 620px; box-shadow: 0 18px 50px rgba(0,0,0,0.25); }
.modal-wide { max-width: 880px; }
.modal-head { display: flex; align-items: center; justify-content: space-between; padding: 14px 18px; border-bottom: 1px solid var(--line-2); }
.modal-head h2 { font-size: var(--fs-lg); }
.modal-x { border: none; background: none; font-size: 22px; line-height: 1; color: var(--muted); cursor: pointer; padding: 0 4px; }
.modal-body { padding: var(--sp-4) var(--sp-5); }
.modal-foot { display: flex; justify-content: flex-end; gap: 8px; padding: var(--sp-3) var(--sp-5); border-top: 1px solid var(--line-2); background: var(--panel-2); border-radius: 0 0 10px 10px; }
.modal-foot .btn-ghost.btn-danger { margin-right: auto; }

/* ---------- toast ---------- */

.toast {
  position: fixed; left: 50%; bottom: 26px; transform: translateX(-50%);
  z-index: 200; padding: 9px 17px; border-radius: 7px;
  background: var(--accent); color: #fff; font-size: 13px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.24); transition: opacity 0.35s, transform 0.35s;
}
.toast-err { background: var(--red); }
.toast.out { opacity: 0; transform: translateX(-50%) translateY(8px); }

/* ---------- print overlay bar ---------- */

#printBar {
  position: sticky; top: 0; z-index: 30;
  display: none; align-items: center; justify-content: space-between; gap: 16px;
  padding: 10px 20px; background: var(--accent); color: #fff;
}
#printBar .btn-ghost { color: #fff; border-color: rgba(255,255,255,0.25); }
.print-hint { font-size: 12px; opacity: 0.7; }

body.printing #topbar,
body.printing #main,
body.printing #foot { display: none; }

/* ---------- responsive ---------- */

@media (max-width: 1080px) {
  .editor-bottom { grid-template-columns: 1fr; }
  .grid-4, .grid-5 { grid-template-columns: repeat(2, minmax(0,1fr)); }
  .kpis { grid-template-columns: repeat(2, minmax(0,1fr)); }
}
@media (max-width: 720px) {
  #topbar { flex-wrap: wrap; gap: 10px; }
  #nav { order: 3; width: 100%; }
  .grid-2, .grid-3, .grid-4, .grid-5 { grid-template-columns: 1fr; }
  .kpis { grid-template-columns: 1fr; }
  .margin-hero { grid-template-columns: 1fr; }
}

/* Auto-save indicator sits where a save button would be. */
.save-state { font-size: 12px; color: var(--muted); padding: 0 6px; white-space: nowrap; }
.save-state.is-saving { color: var(--amber); }

/* Inline fix button inside a warning banner. */
.inline-fix { padding: 3px 9px; font-size: 12px; margin-left: 4px; }
.small-inp { font-size: 12px; }

/* Logo settings: preview on the left, the two sources explained on the right. */
.logo-row { align-items: flex-start; }
.logo-controls { display: flex; flex-direction: column; gap: 9px; flex: 1; min-width: 0; }
.logo-note { max-width: 62ch; }
.logo-preview img[src$=".svg"] { image-rendering: auto; }

/* ---------- login screen ---------- */

body.gated #topbar,
body.gated #foot { display: none; }
body.gated { background: var(--ink); }

.auth-wrap {
  min-height: 100vh; display: flex; align-items: center; justify-content: center;
  padding: 40px 16px;
}
.auth-card {
  width: 100%; max-width: 380px; background: var(--panel);
  border-radius: 12px; padding: 30px 28px 24px;
  border-top: 5px solid var(--brand);
  box-shadow: 0 20px 60px rgba(0,0,0,0.35);
  display: flex; flex-direction: column; gap: 13px;
}
.auth-logo { height: 74px; width: auto; align-self: flex-start; object-fit: contain; }
.auth-card h1 { font-size: 19px; margin: 2px 0 0; }
.auth-sub { margin: -8px 0 4px; color: var(--muted); font-size: 13px; }
.auth-submit { width: 100%; padding: 10px; font-size: 14px; margin-top: 4px; }
.auth-err {
  background: #fdecec; border: 1px solid #f3caca; color: #8f2020;
  padding: 8px 11px; border-radius: 6px; font-size: 12.5px;
}
.auth-err.auth-ok { background: #e6f5ee; border-color: #bfe3d2; color: #0b6b43; }
.auth-foot { display: flex; justify-content: space-between; align-items: center; gap: 10px; margin-top: 2px; }
.linkbtn {
  background: none; border: none; padding: 0; font: inherit; font-size: 12px;
  color: var(--blue); cursor: pointer; text-decoration: underline;
}
.auth-loading { align-items: center; text-align: center; padding: 44px 28px; }
.spinner {
  width: 26px; height: 26px; border-radius: 50%;
  border: 3px solid var(--line); border-top-color: var(--brand);
  animation: spin 0.8s linear infinite; margin: 0 auto 4px;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ---------- account + sync state in the top bar ---------- */

#account { display: flex; align-items: center; gap: 10px; }
.account { display: flex; align-items: center; gap: 7px; }
.account-email {
  font-size: 12px; color: rgba(255,255,255,0.62);
  max-width: 168px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
#topbar .account-out { color: #fff; font-size: 12px; padding: 5px 9px; }

.sync-chip {
  font-size: 11px; padding: 3px 9px; border-radius: 999px; white-space: nowrap;
  background: rgba(255,255,255,0.1); color: rgba(255,255,255,0.7);
}
.sync-ok     { background: rgba(70,190,130,0.18); color: #86e3b4; }
.sync-saving { background: rgba(255,145,77,0.2);  color: #ffc79c; }
.sync-remote { background: rgba(90,160,255,0.2);  color: #a9ccff; }
.sync-error  { background: rgba(224,80,80,0.22);  color: #ffb3b3; }

@media (max-width: 900px) {
  .account-email { display: none; }
}

/* ---------- Google sign-in ---------- */

.google-btn {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  width: 100%; padding: 10px; font-size: 14px; font-weight: 500;
  background: #fff; border: 1px solid #cfd4dc; color: #16181d;
}
.google-btn:hover:not(:disabled) { background: #f7f8fa; border-color: #b9c0cc; }
.google-btn svg { flex-shrink: 0; }

.auth-or {
  display: flex; align-items: center; gap: 10px;
  color: var(--muted); font-size: 11.5px; text-transform: uppercase; letter-spacing: 0.08em;
  margin: 2px 0;
}
.auth-or::before, .auth-or::after {
  content: ''; flex: 1; height: 1px; background: var(--line);
}
.auth-toggle { align-self: center; }
.auth-email { display: flex; flex-direction: column; gap: 12px; }
.auth-note { text-align: center; margin-top: 4px; }
.auth-offline { align-self: center; margin-top: 2px; color: var(--muted); }

/* Who-has-access panel */
.add-user { align-items: end; border-top: 1px solid var(--line-2); }
.add-user-btn { display: flex; align-items: flex-end; height: 100%; }
.add-user-btn .btn { width: 100%; }

/* Someone else changed the document you have open. */
.conflict-banner { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

/* =====================================================================
   Phone and tablet
   Audit in docs/MOBILE-SPEC.md. This block covers the issues that are
   purely presentational; the navigation and the line-item cards are
   separate pieces of work.
   ===================================================================== */

@media (max-width: 820px) {

  /* Wide list tables were being clipped by .card{overflow:hidden}, so the
     Total and Balance columns simply vanished with no way to scroll to them. */
  .card { overflow: visible; }
  .grid-table, .mini-table {
    display: block;
    overflow-x: auto;
    white-space: nowrap;
    -webkit-overflow-scrolling: touch;
  }
  .grid-table thead, .mini-table thead { position: sticky; top: 0; }

  /* iOS Safari zooms the whole page when a field under 16px takes focus,
     and never zooms back out. Every input has to be at least 16px. */
  /* Every one of these has to clear 16px or iOS zooms on focus. The two
     compound selectors need naming explicitly to beat their own specificity. */
  .inp, select.inp, textarea.inp { font-size: 16px; padding: 9px 11px; }
  .trow-fee .fee-base, .small-inp, .inp.small-inp { font-size: 16px; }
  .inp.sm { width: 96px; }
  .inp.mode { width: 74px; }

  /* Touch targets. Anything a thumb has to hit gets 44px. */
  .btn { padding: 11px 15px; font-size: 15px; min-height: 44px; }
  .mini { min-width: 40px; min-height: 40px; font-size: 16px; }
  .modal-x { min-width: 44px; min-height: 44px; font-size: 26px; }
  .linkbtn { display: inline-block; padding: 10px 2px; min-height: 40px; }
  #nav a { padding: 10px 12px; min-height: 40px; display: flex; align-items: center; }

  /* The production fee row forced roughly 600px of controls onto one line
     inside a 320px card, pushing the amount off-screen. Stack it. */
  .trow { flex-wrap: wrap; }
  .trow-fee .trow-label { flex-wrap: wrap; }
  .trow-fee .fee-label { width: 100%; }
  .trow-fee .fee-base { width: auto; flex: 1 1 140px; }
  .trow-label { gap: 6px; }
  .trow-val { margin-left: auto; }

  /* Modals become a sheet rather than a floating card. */
  .modal-back { padding: 0; align-items: flex-end; }
  .modal { max-width: none; border-radius: 14px 14px 0 0; max-height: 92vh; overflow-y: auto; }
  .modal-foot { position: sticky; bottom: 0; }
  .modal-foot .btn { flex: 1; }

  .toolbar-actions { width: 100%; }
  .toolbar-actions .btn { flex: 1 1 auto; }
  .filters .inp { max-width: none; flex: 1 1 100%; }
}

@media (max-width: 720px) {
  /* 100vh on mobile Safari is the viewport WITHOUT the browser chrome, so a
     100vh box is taller than the space actually available and the content
     ends up under the toolbar. dvh tracks the real height. */
  .auth-wrap { min-height: 100vh; min-height: 100dvh; padding: 20px 14px; }
  .auth-card { padding: 24px 20px 20px; }
}

/* ---------------------------------------------------------------------
   Bottom tab bar (phones)
   The same #nav element, repositioned. refreshChrome's active-state logic
   is untouched. Four daily destinations plus More.
   --------------------------------------------------------------------- */

.nav-more {
  font: inherit; background: none; border: none; cursor: pointer;
  color: rgba(255,255,255,0.62); font-size: 13px; padding: 6px 11px; border-radius: 6px;
}
.nav-more:hover { color: #fff; background: rgba(255,255,255,0.08); }
.nav-more.active { color: #fff; background: rgba(255,145,77,0.22); }

.nav-sheet { display: flex; flex-direction: column; }
.nav-sheet-link {
  padding: 15px 4px; border-bottom: 1px solid var(--line-2);
  text-decoration: none; font-size: 16px; font-weight: 500;
}
.nav-sheet-link:last-child { border-bottom: none; }

/* On a wide screen More is redundant - every link is already on the bar. */
@media (min-width: 821px) { .nav-more { display: none; } }

@media (max-width: 820px) {

  /* The top bar stops being sticky and shrinks to identity only, so it
     scrolls away and gives the content back its vertical space. */
  #topbar {
    position: static;
    gap: 12px;
    padding: 9px 14px;
    padding-top: calc(9px + env(safe-area-inset-top));
  }
  #newJobBtn { display: none; }        /* every screen already offers one */
  #account { margin-left: auto; }

  /* The nav leaves the header and becomes the tab bar. */
  #nav {
    position: fixed;
    left: 0; right: 0; bottom: 0;
    z-index: 40;
    display: flex;
    gap: 0;
    background: var(--accent);
    border-top: 1px solid rgba(255,255,255,0.12);
    padding-bottom: env(safe-area-inset-bottom);
    box-shadow: 0 -2px 12px rgba(0,0,0,0.2);
  }
  #nav a, .nav-more {
    flex: 1;
    min-width: 0;
    border-radius: 0;
    padding: 11px 4px;
    font-size: 11.5px;
    text-align: center;
    justify-content: center;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    min-height: 52px;
    display: flex; align-items: center;
  }
  #nav a.nav-2 { display: none; }      /* these three live behind More */
  #nav a.active, .nav-more.active {
    background: rgba(255,145,77,0.18);
    box-shadow: inset 0 3px 0 var(--brand);
    color: #fff;
  }

  /* Nothing may hide behind the bar. */
  #main { padding-bottom: 84px; }
  #foot { padding-bottom: 92px; }
  .toast { bottom: calc(72px + env(safe-area-inset-bottom)); }
  .modal-back { padding-bottom: 0; }
  body.printing #nav { display: none; }
}

/* ---------------------------------------------------------------------
   Line items as cards (phones)
   The nine-column table stops being a table below 820px. Each row becomes
   a card: description, qty, unit price and amount visible at rest;
   category, tax and cost behind one tap.
   --------------------------------------------------------------------- */

.line-more { display: none; }
.lines .c-more { width: 0; padding: 0; }

@media (max-width: 820px) {

  .lines, .lines thead, .lines tbody, .lines tr, .lines td, .lines th { display: block; }
  .lines thead { display: none; }              /* labels move onto the cells */
  .lines { white-space: normal; overflow: visible; }
  .table-wrap { overflow: visible; }

  .lines tr {
    border: 1px solid var(--line);
    border-radius: 10px;
    margin: 10px 12px;
    padding: 10px 11px 8px;
    background: #fff;
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 8px 10px;
    align-items: center;
  }
  .lines td { border: none; padding: 0; }

  /* At rest: description across the top, then qty x price, then the amount. */
  .lines .c-desc  { grid-column: 1 / -1; order: 1; }
  .lines .c-qty   { order: 2; }
  .lines .c-price { order: 3; }
  .lines .c-amt   { grid-column: 1 / -1; order: 4;
                    text-align: right; font-size: 17px; font-weight: 700;
                    padding-top: 6px; border-top: 1px solid var(--line-2); }
  .lines .c-more  { grid-column: 1 / -1; order: 5; width: auto; }
  .lines .c-x     { position: absolute; }      /* replaced by the row header below */

  /* qty and unit price get their labels back */
  .lines .c-qty::before, .lines .c-price::before {
    content: attr(data-label);
    display: block; font-size: 10.5px; text-transform: uppercase;
    letter-spacing: 0.05em; color: var(--muted); margin-bottom: 3px;
  }
  .lines .c-qty .inp, .lines .c-price .inp { width: 100%; }

  /* The drawer. Hidden until the row is opened. */
  .lines .c-cat, .lines .c-tax, .lines .c-cost, .lines .c-drag { display: none; }
  .lines tr.is-open .c-cat  { display: block; order: 6; grid-column: 1 / -1; }
  .lines tr.is-open .c-tax  { display: block; order: 7; }
  .lines tr.is-open .c-cost { display: block; order: 8; }
  .lines tr.is-open .c-drag { order: 9; grid-column: 1 / -1; }
  .lines tr.is-open .c-cat::before,
  .lines tr.is-open .c-tax::before,
  .lines tr.is-open .c-cost::before,
  .lines tr.is-open .c-drag::before {
    content: attr(data-label);
    display: block; font-size: 10.5px; text-transform: uppercase;
    letter-spacing: 0.05em; color: var(--muted); margin-bottom: 3px;
  }
  /* Move up / move down sit side by side under their label, not stacked. */
  .lines tr.is-open .c-drag {
    display: grid; grid-template-columns: 1fr 1fr; gap: 8px;
  }
  .lines tr.is-open .c-drag::before { grid-column: 1 / -1; margin-bottom: 0; }
  .lines tr.is-open .c-drag .mini {
    border: 1px solid var(--line); border-radius: 6px; min-height: 40px;
  }
  .lines tr.is-open .c-cat .inp, .lines tr.is-open .c-tax .inp, .lines tr.is-open .c-cost .inp { width: 100%; }

  /* Remove sits top-right of the card, away from the fields. */
  .lines .c-x {
    position: absolute; top: 6px; right: 6px; width: auto;
  }
  .lines tr { position: relative; padding-right: 46px; }
  .lines .c-desc .inp { padding-right: 4px; }

  .line-more {
    display: block; width: 100%; text-align: center;
    font-size: 12.5px; min-height: 38px; padding: 8px;
    color: var(--muted); border-style: dashed;
  }
  .line-actions { flex-direction: column; }
  .line-actions .rate-picker, .line-actions .btn { max-width: none; width: 100%; }
  td.empty { padding: 22px 12px; }
}

/* ---------- history and rescue ---------- */
.hist-when { white-space: nowrap; color: var(--muted); width: 130px; }
.hist-table tbody tr.hist-detail:hover { background: none; }
.hist-detail td { background: #fbfbfd; padding: 0 !important; }
.hist-changes { display: flex; flex-direction: column; }
.hist-change {
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  padding: 10px 14px; border-bottom: 1px solid var(--line-2);
}
.hist-change:last-child { border-bottom: none; }
.hist-verb {
  display: inline-block; font-size: 10.5px; font-weight: 700; letter-spacing: 0.05em;
  text-transform: uppercase; padding: 2px 7px; border-radius: 4px; margin-right: 4px;
}
.hist-create { background: #dcf3e7; color: #0b6b43; }
.hist-update { background: #e4edfd; color: #1d4ed8; }
.hist-delete { background: #fbe2e2; color: #a41f1f; }

@media (max-width: 820px) {
  .hist-when { width: auto; }
  .hist-change { flex-direction: column; align-items: stretch; gap: 8px; }
  .hist-change .btn { width: 100%; }
}

/* ---------------------------------------------------------------------
   The client-facing approval page
   No app chrome. Just the estimate and a decision.
   --------------------------------------------------------------------- */

body.share-mode { background: #6b7280; }
body.share-mode #topbar, body.share-mode #nav, body.share-mode #foot { display: none; }
body.share-mode #main { padding: 0; max-width: none; }

.share-wrap { padding: 24px 14px 60px; }
.share-card {
  max-width: 8.5in; margin: 0 auto; background: #fff;
  border-radius: 4px; box-shadow: 0 8px 40px rgba(0,0,0,0.3); overflow: hidden;
}
.share-msg { padding: 48px 30px; text-align: center; }
.share-msg h1 { font-size: 20px; margin-bottom: 8px; }

.share-state {
  padding: 13px 20px; font-size: 13.5px;
  background: #f2f6fd; color: #24406f; border-bottom: 1px solid #dbe6fa;
}
.share-ok { background: #e6f5ee; color: #0b6b43; border-color: #bfe3d2; }
.share-no { background: #fdecec; color: #8f2020; border-color: #f3caca; }

/* The sheet keeps its print styling but must not be a fixed letter page here. */
.share-sheet-host .sheet {
  width: auto; min-height: 0; margin: 0; box-shadow: none; border-radius: 0;
}

.share-actions { padding: 22px 24px 26px; border-top: 3px solid var(--brand); background: #fcfcfd; }
.share-sign { max-width: 340px; }
.share-sign .field-label { font-size: 11px; }
.share-actions .auth-err { margin-top: 12px; }
.share-btns { display: flex; gap: 10px; margin-top: 16px; flex-wrap: wrap; }
.share-approve { flex: 1 1 320px; padding: 13px 20px; font-size: 15px; }
.share-decline { flex: 0 1 140px; }

/* the link panel inside the editor */
.share-row { border: 1px solid var(--line); border-radius: 8px; padding: 12px; margin-bottom: 10px; }
.share-fresh { border-color: var(--brand); background: var(--brand-lt); }
.share-row-head { display: flex; align-items: center; gap: 9px; margin-bottom: 9px; }
.share-url-row { display: flex; gap: 8px; }
.share-url { font-family: var(--mono); font-size: 11.5px; }
.share-make { margin-top: 14px; }
.share-note { margin-top: 10px; }

@media (max-width: 720px) {
  .share-wrap { padding: 0 0 40px; }
  .share-card { border-radius: 0; box-shadow: none; }
  .share-sheet-host .sheet { padding: 0.42in 18px 0.4in; font-size: 11pt; }
  .share-btns { flex-direction: column; }
  .share-decline { flex: 1 1 auto; }
}

/* Same-day kit clashes */
.clash-jobs { display: flex; flex-direction: column; gap: 4px; padding: 12px 14px; }
.clash-job { text-decoration: none; font-weight: 600; }
.clash-hard td { background: #fdf6e8; }

/* Dates never wrap; names take the slack. */
.grid-table .c-date { white-space: nowrap; width: 1%; }
.grid-table .c-name { width: 40%; }

/* One New job button on desktop is plenty - the page header has it. */
@media (min-width: 821px) { #newJobBtn { display: none; } }

/* Empty states: what goes here, and the button that puts it there. */
.empty-state {
  padding: 30px 20px; text-align: center;
  display: flex; flex-direction: column; align-items: center; gap: 8px;
}
.empty-title { font-size: 15px; font-weight: 600; }
.empty-state .btn { margin-top: 8px; }

/* Rate card: six tables, one column plan, so the numbers line up down the page. */
.rate-table { table-layout: fixed; }
.rate-table th:nth-child(1), .rate-table td:nth-child(1) { width: 30%; }
.rate-table th:nth-child(2), .rate-table td:nth-child(2) { width: 8%; }
.rate-table th:nth-child(3), .rate-table td:nth-child(3),
.rate-table th:nth-child(4), .rate-table td:nth-child(4),
.rate-table th:nth-child(5), .rate-table td:nth-child(5) { width: 12%; }
.rate-table th:nth-child(6), .rate-table td:nth-child(6),
.rate-table th:nth-child(7), .rate-table td:nth-child(7) { width: 8%; }
.rate-table th:nth-child(8), .rate-table td:nth-child(8) { width: 6%; }
.rate-table th:nth-child(9), .rate-table td:nth-child(9) { width: 8%; }
@media (max-width: 820px) { .rate-table { table-layout: auto; } }

/* =====================================================================
   Design audit fixes, phones and tablets
   ===================================================================== */

@media (max-width: 820px) {

  /* M1: the editor was 451-476px wide on a 390px phone. The totals card is a
     grid item, so it needs min-width:0 to be allowed to shrink, and the four
     fee controls need to be allowed to wrap. Otherwise the whole page is
     wider than the screen and the tab bar and toasts fall off the edge. */
  .editor-bottom > * { min-width: 0; }
  .trow-fee .trow-label { min-width: 0; flex-wrap: wrap; }
  .trow-fee .trow-label > .inp.mode,
  .trow-fee .trow-label > .inp.num.sm,
  .trow-fee .trow-label > .inp.fee-base { flex: 1 1 auto; width: auto; min-width: 0; }
  .trow-fee .trow-label > .fee-label { flex: 1 1 100%; width: 100%; }

  /* M2: the logo row never wrapped and its button refused to. */
  .logo-row { flex-wrap: wrap; }
  .btn { white-space: normal; }

  /* S2: a sideways-scrolling table needs to look like one. */
  .grid-table, .mini-table { border-right: 1px solid var(--line); }
  .table-wrap { position: relative; }
  .table-wrap::after {
    content: ''; position: absolute; top: 0; right: 0; bottom: 0; width: 24px;
    background: linear-gradient(to right, rgba(255,255,255,0), #fff); pointer-events: none;
  }
}

@media (max-width: 720px) {

  /* S9: four tall KPI cards ate the first screen. */
  .kpis { grid-template-columns: repeat(2, minmax(0,1fr)); gap: var(--sp-2); }
  .kpi { padding: var(--sp-3); }
  .kpi-value { font-size: 18px; }

  /* S10: alert title and detail fought over one line. */
  .alert { flex-direction: column; align-items: flex-start; gap: 2px; }
  .alert-detail { text-align: left; }

  /* S14: the jurisdiction table becomes stacked rows. */
  .jur-table thead { display: none; }
  .jur-table, .jur-table tbody, .jur-table tr, .jur-table td { display: block; border-right: none; }
  .jur-table tr { padding: var(--sp-3); border-bottom: 1px solid var(--line-2); }
  .jur-table td { padding: 3px 0; }
  .jur-table td.c-x { text-align: right; }
}

@media (max-width: 360px) {
  .kpis { grid-template-columns: 1fr; }
}

/* S7: a destructive button sits apart from the ones you actually use. */
.toolbar-actions .btn-apart { margin-left: auto; }
@media (max-width: 820px) { .toolbar-actions .btn-apart { margin-left: 0; order: 99; } }

/* M9 */
.trow-void .trow-label, .trow-void .trow-val { color: var(--muted); text-decoration: line-through; }

/* A void document is worth nothing. The list says so, the way the editor does. */
.void-amt { color: var(--muted); text-decoration: line-through; }

/* ---------- boot loader ----------
   Sits in #main in the static HTML. The first render wipes it, so nothing has
   to remove it by hand. The chrome is held back until that render so the page
   arrives in one piece instead of showing an empty header over an empty body
   and then rearranging itself. */
body.booting #topbar,
body.booting #foot { display: none; }

.boot {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: var(--sp-3);
  min-height: 52vh;
  opacity: 0;
  animation: boot-in 220ms ease-out 200ms forwards;
}
.boot-ring {
  width: 26px; height: 26px; border-radius: 50%;
  border: 2.5px solid var(--line);
  border-top-color: var(--brand);
  animation: boot-spin 700ms linear infinite;
}
.boot-label { font-size: var(--fs-sm); color: var(--muted); }
.boot-noscript {
  max-width: 28rem; margin: 18vh auto 0; text-align: center;
  font-size: var(--fs-base); color: var(--muted);
}

@keyframes boot-in { to { opacity: 1; } }
@keyframes boot-spin { to { transform: rotate(360deg); } }

/* A spinner is motion for its own sake. Pulse instead when that is unwelcome. */
@media (prefers-reduced-motion: reduce) {
  .boot { animation-duration: 1ms; animation-delay: 200ms; }
  .boot-ring {
    border-color: var(--line); border-top-color: var(--brand);
    animation: boot-pulse 1.4s ease-in-out infinite;
  }
  @keyframes boot-pulse { 0%, 100% { opacity: .3 } 50% { opacity: 1 } }
}
