/* ==========================================================================
   Servicios Quintana — Business Platform
   Orange brand system, light + dark, phone-first.
   ========================================================================== */

/* ---------- tokens: light is the base ---------- */
:root {
  color-scheme: light;

  --brand:        #E65100;
  --brand-soft:   #FFF3E9;
  --brand-hover:  #C2410C;
  --brand-ink:    #FFFFFF;

  --bg:           #F3F4F6;
  --surface:      #FFFFFF;
  --surface-2:    #F9FAFB;
  --sidebar:      #FFFFFF;
  --border:       #E5E7EB;
  --border-strong:#D1D5DB;

  --text:         #111827;
  --text-2:       #4B5563;
  --text-3:       #9CA3AF;

  --good:         #067A55;
  --good-bg:      #ECFDF5;
  --warn:         #B45309;
  --warn-bg:      #FFFBEB;
  --bad:          #B91C1C;
  --bad-bg:       #FEF2F2;
  --info:         #1D4ED8;
  --info-bg:      #EFF6FF;

  /* validated categorical series (light, surface #FFFFFF) */
  --series-1:     #E65100;
  --series-2:     #2A78D6;
  --series-3:     #0E8F63;

  /* sequential orange ramp, light -> dark = low -> high */
  --seq-1: #FDD5AE;
  --seq-2: #FBB273;
  --seq-3: #F58A33;
  --seq-4: #DC6803;
  --seq-5: #A84A02;

  --grid:         #EDEFF2;
  --shadow:       0 1px 2px rgba(16,24,40,.06), 0 4px 12px rgba(16,24,40,.05);
  --shadow-lg:    0 12px 40px rgba(16,24,40,.18);
  --radius:       12px;
  --radius-sm:    8px;
  --sidebar-w:    244px;
}

/* ---------- dark: selected, not flipped ---------- */
:root[data-theme="dark"] {
  color-scheme: dark;

  --brand:        #F97316;
  --brand-soft:   #2A1A0E;
  --brand-hover:  #FB923C;
  --brand-ink:    #1A1004;

  --bg:           #111827;
  --surface:      #1F2937;
  --surface-2:    #263243;
  --sidebar:      #171F2E;
  --border:       #374151;
  --border-strong:#4B5563;

  --text:         #F9FAFB;
  --text-2:       #C3CBD6;
  --text-3:       #8A94A3;

  --good:         #34D399;
  --good-bg:      #082F24;
  --warn:         #FBBF24;
  --warn-bg:      #2E2205;
  --bad:          #F87171;
  --bad-bg:       #34110F;
  --info:         #7EB0F5;
  --info-bg:      #10203A;

  /* validated categorical series (dark, surface #1F2937) */
  --series-1:     #DE7412;
  --series-2:     #4A8CE0;
  --series-3:     #20A579;

  /* sequential on dark: dim -> bright = low -> high */
  --seq-1: #6B3A10;
  --seq-2: #8F4E13;
  --seq-3: #B96517;
  --seq-4: #DE7412;
  --seq-5: #F0973C;

  --grid:         #2B3646;
  --shadow:       0 1px 2px rgba(0,0,0,.4), 0 6px 18px rgba(0,0,0,.32);
  --shadow-lg:    0 16px 48px rgba(0,0,0,.55);
}

/* ---------- base ---------- */
* { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 14px/1.5 system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
}
a { color: inherit; text-decoration: none; }
h1,h2,h3,h4 { margin: 0; font-weight: 650; letter-spacing: -.01em; }
[hidden] { display: none !important; }
::selection { background: var(--brand); color: var(--brand-ink); }

/* ---------- layout ---------- */
#app { display: flex; min-height: 100vh; }

#sidebar {
  width: var(--sidebar-w); flex: 0 0 var(--sidebar-w);
  background: var(--sidebar); border-right: 1px solid var(--border);
  display: flex; flex-direction: column;
  position: sticky; top: 0; height: 100vh; z-index: 40;
}
.brand {
  display: flex; align-items: center; gap: 10px;
  padding: 18px 16px; border-bottom: 1px solid var(--border);
}
.brand-mark {
  width: 34px; height: 34px; border-radius: 9px; flex: none;
  background: var(--brand); color: var(--brand-ink);
  display: grid; place-items: center; font-weight: 800; font-size: 17px;
}
.brand-text { display: flex; flex-direction: column; line-height: 1.25; min-width: 0; }
.brand-text strong { font-size: 15px; }
.brand-text span { font-size: 11px; color: var(--text-3); }
.sidebar-close { margin-left: auto; }

.nav { flex: 1; overflow-y: auto; padding: 10px 10px 16px; }
.nav-group {
  font-size: 10.5px; text-transform: uppercase; letter-spacing: .09em;
  color: var(--text-3); font-weight: 700; padding: 14px 10px 5px;
}
.nav a {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 11px; border-radius: var(--radius-sm);
  color: var(--text-2); font-weight: 500; margin-bottom: 1px;
}
.nav a i { font-style: normal; width: 17px; text-align: center; opacity: .75; font-size: 13px; }
.nav a:hover { background: var(--surface-2); color: var(--text); }
.nav a.active { background: var(--brand); color: var(--brand-ink); font-weight: 650; }
.nav a.active i { opacity: 1; }
.pill {
  margin-left: auto; background: var(--bad); color: #fff;
  font-size: 10.5px; font-weight: 700; padding: 1px 7px; border-radius: 999px;
}
.nav a.active .pill { background: rgba(0,0,0,.28); color: #fff; }

.sidebar-foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px; padding: 12px 14px; border-top: 1px solid var(--border);
}
.ver { font-size: 11px; color: var(--text-3); }

#main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
#topbar {
  display: flex; align-items: center; gap: 12px;
  padding: 14px 22px; background: var(--surface);
  border-bottom: 1px solid var(--border);
  position: sticky; top: 0; z-index: 30;
}
#page-title { font-size: 19px; flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#page-actions { display: flex; gap: 8px; flex-wrap: wrap; justify-content: flex-end; }
#view { padding: 22px; flex: 1; }
.menu-btn { display: none; }
.nav-scrim { display: none; }

/* ---------- buttons ---------- */
button { font: inherit; }
.btn, .ghost-btn, .icon-btn, .danger-btn, .subtle-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  border-radius: var(--radius-sm); border: 1px solid transparent;
  padding: 8px 14px; font-weight: 600; cursor: pointer;
  transition: background .12s, border-color .12s, color .12s, transform .05s;
  white-space: nowrap;
}
.btn:active, .ghost-btn:active, .danger-btn:active { transform: translateY(1px); }
.btn { background: var(--brand); color: var(--brand-ink); }
.btn:hover { background: var(--brand-hover); }
.ghost-btn, .subtle-btn {
  background: var(--surface); color: var(--text-2); border-color: var(--border-strong);
}
.ghost-btn:hover, .subtle-btn:hover { background: var(--surface-2); color: var(--text); }
.danger-btn { background: var(--bad-bg); color: var(--bad); border-color: currentColor; }
.danger-btn:hover { background: var(--bad); color: #fff; }
.icon-btn {
  background: transparent; border: none; color: var(--text-2);
  padding: 6px 9px; font-size: 17px; border-radius: var(--radius-sm);
}
.icon-btn:hover { background: var(--surface-2); color: var(--text); }
.btn.sm, .ghost-btn.sm, .danger-btn.sm, .subtle-btn.sm { padding: 5px 10px; font-size: 12.5px; }
.btn[disabled], .ghost-btn[disabled] { opacity: .5; pointer-events: none; }
/* These two are mobile-only. Declared after .icon-btn so its display wins
   nothing; the max-width:860px block below turns them back on. */
.sidebar-close, .menu-btn { display: none; }

/* language switch — present on every page */
.lang-btn {
  flex: none; display: inline-flex; align-items: center; gap: 5px;
  background: var(--brand-soft); color: var(--brand);
  border: 1px solid var(--brand); border-radius: 999px;
  padding: 5px 13px; font-weight: 800; font-size: 12px; cursor: pointer;
  letter-spacing: .04em;
}
.lang-btn:hover { background: var(--brand); color: var(--brand-ink); }
.modal-lang { padding: 3px 10px; font-size: 11px; }

/* call intake — the one button that has to be reachable from anywhere */
.call-btn {
  flex: none; display: inline-flex; align-items: center; gap: 6px;
  background: var(--brand); color: var(--brand-ink); border: 1px solid var(--brand);
  border-radius: 999px; padding: 7px 15px; font-weight: 700; font-size: 13px;
  cursor: pointer; white-space: nowrap;
  transition: background .12s, transform .05s;
}
.call-btn:hover { background: var(--brand-hover); border-color: var(--brand-hover); }
.call-btn:active { transform: translateY(1px); }

/* booked / just-asking switch on the call form */
.segmented { display: flex; gap: 0; border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm); overflow: hidden; }
.segmented .seg {
  flex: 1 1 0; min-width: 0; padding: 10px 12px; border: none; cursor: pointer;
  background: var(--surface); color: var(--text-2); font-weight: 650; font-size: 13px;
  border-right: 1px solid var(--border);
}
.segmented .seg:last-child { border-right: none; }
.segmented .seg:hover { background: var(--surface-2); color: var(--text); }
.segmented .seg.on { background: var(--brand); color: var(--brand-ink); }

/* do-not-serve banner */
.alert-bad {
  background: var(--bad-bg); color: var(--bad);
  border: 1px solid currentColor; border-left-width: 4px;
  border-radius: var(--radius-sm); padding: 13px 16px; font-size: 13.5px;
}
.alert-bad strong { display: block; margin-bottom: 3px; }

/* ---------- cards & grid ---------- */
.card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); box-shadow: var(--shadow);
}
.card-head {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 14px 18px; border-bottom: 1px solid var(--border);
}
.card-head h3 { font-size: 14.5px; }
.card-head .spacer { flex: 1; }
.card-body { padding: 18px; }
.grid { display: grid; gap: 16px; }
/* min-width:0 everywhere, so a wide table scrolls inside its card
   instead of stretching the card past the viewport. */
.grid > * { min-width: 0; }
.card { min-width: 0; }
.g2 { grid-template-columns: repeat(2, minmax(0,1fr)); }
.g3 { grid-template-columns: repeat(3, minmax(0,1fr)); }
.g4 { grid-template-columns: repeat(4, minmax(0,1fr)); }
/* main + side column */
.split { grid-template-columns: minmax(0,2fr) minmax(0,1fr); }
.stack { display: flex; flex-direction: column; gap: 16px; }
.row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.row.tight { gap: 6px; }
.spacer { flex: 1; }

/* ---------- stat tiles ---------- */
.stat {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 15px 17px;
  border-left: 3px solid var(--accent, var(--brand));
  box-shadow: var(--shadow); min-width: 0;
}
.stat .label {
  font-size: 11px; text-transform: uppercase; letter-spacing: .07em;
  color: var(--text-3); font-weight: 700;
}
.stat .value {
  font-size: 25px; font-weight: 700; margin-top: 5px;
  font-variant-numeric: tabular-nums; letter-spacing: -.02em;
  overflow-wrap: anywhere;
}
.stat .sub { font-size: 12px; color: var(--text-2); margin-top: 3px; }
.stat.good  { --accent: var(--good); }
.stat.warn  { --accent: var(--warn); }
.stat.bad   { --accent: var(--bad); }
.stat.info  { --accent: var(--info); }
.delta { font-weight: 700; font-size: 12px; }
.delta.up { color: var(--good); } .delta.down { color: var(--bad); }

/* ---------- tables ---------- */
.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
table.data { width: 100%; border-collapse: collapse; font-size: 13.5px; min-width: 640px; }
table.data th {
  text-align: left; font-size: 11px; text-transform: uppercase;
  letter-spacing: .06em; color: var(--text-3); font-weight: 700;
  padding: 10px 12px; border-bottom: 1px solid var(--border);
  position: sticky; top: 0; background: var(--surface); z-index: 1;
}
table.data td { padding: 11px 12px; border-bottom: 1px solid var(--border); vertical-align: middle; }
table.data tr:last-child td { border-bottom: none; }
table.data tbody tr:hover { background: var(--surface-2); }
table.data td.num, table.data th.num { text-align: right; font-variant-numeric: tabular-nums; }
table.data .actions { display: flex; gap: 5px; justify-content: flex-end; }
.clickable { cursor: pointer; }
.muted { color: var(--text-3); }
.strong { font-weight: 650; }
.mono { font-variant-numeric: tabular-nums; }

/* ---------- badges ---------- */
.badge {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 9px; border-radius: 999px; font-size: 11.5px; font-weight: 700;
  border: 1px solid transparent; white-space: nowrap;
}
.badge::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.badge.paid, .badge.done, .badge.won, .badge.published, .badge.complete, .badge.active-ok
  { background: var(--good-bg); color: var(--good); }
.badge.pending, .badge.sent, .badge.partial, .badge.todo, .badge.idea, .badge.new, .badge.contacted
  { background: var(--warn-bg); color: var(--warn); }
.badge.overdue, .badge.blocked, .badge.lost, .badge.urgent
  { background: var(--bad-bg); color: var(--bad); }
.badge.draft, .badge.void, .badge.canceled, .badge.skipped
  { background: var(--surface-2); color: var(--text-3); }
.badge.progress, .badge.quoted, .badge.scheduled, .badge.drafted, .badge.active
  { background: var(--info-bg); color: var(--info); }

/* ---------- forms ---------- */
label.field { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
label.field > span {
  font-size: 11.5px; font-weight: 650; color: var(--text-2);
  text-transform: uppercase; letter-spacing: .05em;
}
input, select, textarea {
  font: inherit; color: var(--text); background: var(--surface);
  border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
  padding: 9px 11px; width: 100%; min-width: 0;
}
input:focus, select:focus, textarea:focus {
  outline: none; border-color: var(--brand);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand) 22%, transparent);
}
textarea { resize: vertical; min-height: 80px; line-height: 1.55; }
input[type="checkbox"] { width: auto; accent-color: var(--brand); }
.form-grid { display: grid; gap: 14px; grid-template-columns: repeat(2, minmax(0,1fr)); }
.form-grid .full { grid-column: 1 / -1; }
.filters {
  display: flex; gap: 9px; flex-wrap: wrap; align-items: center; margin-bottom: 16px;
}
.filters input, .filters select { width: auto; min-width: 130px; padding: 7px 10px; }
.filters .search { min-width: 210px; flex: 1; max-width: 340px; }

/* ---------- modal ---------- */
.modal-scrim {
  position: fixed; inset: 0; background: rgba(9,12,20,.62);
  display: grid; place-items: center; padding: 18px; z-index: 100;
  backdrop-filter: blur(2px);
}
.modal {
  background: var(--surface); border-radius: var(--radius);
  box-shadow: var(--shadow-lg); border: 1px solid var(--border);
  width: min(700px, 100%); max-width: 100%;
  max-height: 90vh;
  /* dvh, not vh. On Android Chrome `vh` is measured against the viewport with
     the URL bar HIDDEN, so a 90vh window is taller than what you can actually
     see while the bar is showing -- and the footer with Save on it ends up
     below the fold. dvh follows the visible height. */
  max-height: 90dvh;
  display: flex; flex-direction: column;
}
.modal.wide { width: min(940px, 100%); }
/* Nothing inside may force the window wider than the screen. */
.modal-body > * { min-width: 0; }
.modal-head {
  display: flex; align-items: center; gap: 12px;
  padding: 16px 20px; border-bottom: 1px solid var(--border);
}
.modal-head h3 { font-size: 16px; flex: 1; }
.modal-body { padding: 20px; overflow-y: auto; overflow-x: hidden;
  -webkit-overflow-scrolling: touch; overscroll-behavior: contain; }
.modal-foot {
  display: flex; gap: 9px; justify-content: flex-end;
  padding: 14px 20px; border-top: 1px solid var(--border); flex-wrap: wrap;
}

/* ---------- toasts ---------- */
#toasts {
  position: fixed; right: 18px; bottom: 18px; z-index: 200;
  display: flex; flex-direction: column; gap: 9px; max-width: min(380px, calc(100vw - 36px));
}
.toast {
  background: var(--surface); border: 1px solid var(--border);
  border-left: 3px solid var(--brand); border-radius: var(--radius-sm);
  padding: 11px 15px; box-shadow: var(--shadow-lg); font-size: 13.5px;
  animation: slide-in .18s ease-out;
}
.toast.ok  { border-left-color: var(--good); }
.toast.err { border-left-color: var(--bad); }
@keyframes slide-in { from { opacity: 0; transform: translateY(8px); } }

/* ---------- kanban ---------- */
.board {
  display: grid; grid-template-columns: repeat(4, minmax(230px, 1fr)); gap: 14px;
  /* Kanban columns have a floor width, so between ~1100px and ~1350px five of
     them are wider than the page. Scroll the board, not the whole page. */
  overflow-x: auto; padding-bottom: 4px;
}
.board.pipeline { grid-template-columns: repeat(5, minmax(200px, 1fr)); }
.col {
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: var(--radius); display: flex; flex-direction: column; min-height: 190px;
}
.col-head {
  display: flex; align-items: center; gap: 8px; padding: 11px 13px;
  border-bottom: 1px solid var(--border); font-weight: 700; font-size: 12.5px;
}
.col-head .n {
  background: var(--surface); color: var(--text-2); border-radius: 999px;
  padding: 1px 8px; font-size: 11px; border: 1px solid var(--border);
}
.col-body { padding: 10px; display: flex; flex-direction: column; gap: 9px; flex: 1; }
.col.drag-over { outline: 2px dashed var(--brand); outline-offset: -3px; }
.kcard {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-sm); padding: 11px 12px; cursor: grab;
  box-shadow: var(--shadow); border-left: 3px solid var(--accent, var(--border-strong));
}
.kcard:active { cursor: grabbing; }
.kcard.dragging { opacity: .45; }
.kcard .t { font-weight: 600; font-size: 13.5px; line-height: 1.35; }
.kcard .m { font-size: 11.5px; color: var(--text-3); margin-top: 6px;
  display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.kcard.p-urgent { --accent: var(--bad); }
.kcard.p-high   { --accent: var(--warn); }
.kcard.p-normal { --accent: var(--info); }
.kcard.p-low    { --accent: var(--border-strong); }
.kcard .od { color: var(--bad); font-weight: 700; }

/* ---------- calendar ---------- */
.cal { width: 100%; border-collapse: collapse; table-layout: fixed; }
.cal th {
  font-size: 10.5px; text-transform: uppercase; letter-spacing: .06em;
  color: var(--text-3); padding: 8px 4px; font-weight: 700; text-align: center;
}
.cal td {
  border: 1px solid var(--border); vertical-align: top;
  height: 106px; padding: 5px; background: var(--surface);
}
.cal td.out { background: var(--surface-2); }
.cal td.today { outline: 2px solid var(--brand); outline-offset: -2px; }
.cal .dn { font-size: 11.5px; color: var(--text-3); font-weight: 700; margin-bottom: 4px;
  display: flex; align-items: center; gap: 5px; }
.cal .today-tag {
  background: var(--brand); color: var(--brand-ink); font-size: 8.5px;
  letter-spacing: .08em; padding: 1px 5px; border-radius: 3px;
}
.cal td.today .dn { color: var(--brand); }
.cal .ev {
  font-size: 11px; padding: 3px 6px; border-radius: 5px; margin-bottom: 3px;
  background: var(--brand-soft); color: var(--brand); font-weight: 600;
  cursor: pointer; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  border-left: 2px solid var(--brand);
}
.cal .ev.published { background: var(--good-bg); color: var(--good); border-left-color: var(--good); }
.cal .ev.scheduled { background: var(--info-bg); color: var(--info); border-left-color: var(--info); }
.cal .ev.drafted   { background: var(--warn-bg); color: var(--warn); border-left-color: var(--warn); }
.cal .ev.overdue   { background: var(--bad-bg);  color: var(--bad);  border-left-color: var(--bad); }
.cal .ev.canceled  { background: var(--surface-2); color: var(--text-3);
                     border-left-color: var(--text-3); text-decoration: line-through; }
.cal .ev-count { display: none; }
/* what is already on your Google calendar: visible, muted, not yours to edit */
.cal .ev.ext {
  background: transparent; color: var(--text-3); font-weight: 500;
  border-left: 2px solid var(--text-3); cursor: default;
  font-style: italic;
}
.day-row.ext { cursor: default; border-style: dashed; }
.day-row.ext:hover { border-color: var(--border); background: var(--surface); }

/* a task that lives in Google Tasks too */
.kcard .m .gsync { color: var(--brand); font-weight: 700; }

/* ---------- card payments ---------- */
.txn-row {
  display: grid; gap: 12px; align-items: center; min-width: 0;
  grid-template-columns: 132px minmax(0,1fr) 116px auto;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  padding: 11px 12px; background: var(--surface);
}
.txn-row:hover { border-color: var(--border-strong); }
.txn-when { font-variant-numeric: tabular-nums; min-width: 0; }
.txn-amount { text-align: right; display: flex; flex-direction: column;
              align-items: flex-end; gap: 4px; }
/* badge() slugs its own text, so these match the confidence wording */
.badge.invoice-number-matches { background: var(--good-bg); color: var(--good); }
.badge.very-likely { background: var(--info-bg); color: var(--info); }
.badge.check-this-one { background: var(--warn-bg); color: var(--warn); }
.badge.set-aside { background: var(--surface-2); color: var(--text-3); }
.badge.bank { background: var(--info-bg); color: var(--info); }
.badge.still-clearing { background: var(--warn-bg); color: var(--warn); }
/* a bank transfer reads differently from a card swipe at a glance */
.txn-row.ach { border-left: 3px solid var(--info); }

@media (max-width: 860px) {
  .txn-row {
    grid-template-columns: minmax(0,1fr) auto;
    row-gap: 8px;
  }
  .txn-when   { grid-area: 1 / 1 / 2 / 2; }
  .txn-amount { grid-area: 1 / 2 / 2 / 3; }
  .txn-row > div:nth-child(2) { grid-area: 2 / 1 / 3 / 3; }
  .txn-row > .row:last-child  { grid-area: 3 / 1 / 4 / 3; }
}

/* one day, opened from the grid */
.day-row {
  display: flex; gap: 12px; align-items: flex-start; cursor: pointer;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  padding: 11px 12px; background: var(--surface);
}
.day-row:hover { border-color: var(--border-strong); background: var(--surface-2); }
.day-when {
  flex: 0 0 68px; text-align: right; font-variant-numeric: tabular-nums;
  border-right: 1px solid var(--border); padding-right: 11px;
}

/* ---------- the month grid on a phone ----------
   106px cells and 11px event text do not survive a 390px screen: the day
   number and the TODAY badge end up on top of each other, which is exactly
   what they did. Below 720px the events become coloured bars with a count,
   and the whole day opens on a tap instead. */
@media (max-width: 720px) {
  .cal th { font-size: 9px; padding: 6px 0; }
  .cal td { height: 62px; padding: 3px 3px 4px; position: relative; }
  .cal .dn { font-size: 12px; margin-bottom: 3px; justify-content: center; }
  .cal .today-tag { display: none; }              /* the circle says it instead */
  .cal td.today { outline-width: 2px; }
  .cal td.today .dn {
    color: var(--brand-ink); background: var(--brand);
    width: 21px; height: 21px; border-radius: 50%;
    justify-content: center; margin: 0 auto 3px;
  }
  .cal .ev {
    font-size: 0; line-height: 0; height: 5px; margin-bottom: 3px;
    padding: 0; border-radius: 3px; border-left: none;
  }
  .cal .ev.ext { background: var(--text-3); opacity: .5; }
  .cal .ev-count {
    display: block; text-align: center; font-size: 10px; font-weight: 700;
    color: var(--text-3); line-height: 1;
  }
  .day-when { flex-basis: 58px; }
}

/* ---------- charts ---------- */
.chart { width: 100%; display: block; overflow: visible; }
.chart text { font-size: 11px; fill: var(--text-3); }
.chart .axis-line { stroke: var(--border); stroke-width: 1; }
.chart .grid-line { stroke: var(--grid); stroke-width: 1; }
.chart .val-label { fill: var(--text-2); font-weight: 600; font-size: 10.5px; }
.chart rect.mark { transition: opacity .12s; }
.chart g.hit:hover rect.mark { opacity: .82; }
.legend { display: flex; gap: 14px; flex-wrap: wrap; font-size: 12px; color: var(--text-2); }
.legend span { display: inline-flex; align-items: center; gap: 6px; }
.legend i { width: 10px; height: 10px; border-radius: 3px; display: inline-block; }
.chart-tip {
  position: fixed; pointer-events: none; z-index: 300;
  background: var(--surface); border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm); box-shadow: var(--shadow-lg);
  padding: 8px 11px; font-size: 12.5px; color: var(--text);
  white-space: nowrap; opacity: 0; transition: opacity .1s;
}
.chart-tip.show { opacity: 1; }
.chart-tip .k { color: var(--text-3); }
.chart-tip b { font-variant-numeric: tabular-nums; }

/* ---------- misc ---------- */
.empty { text-align: center; padding: 44px 20px; color: var(--text-3); }
.empty .big { font-size: 30px; margin-bottom: 10px; opacity: .55; }
.bar-track { height: 7px; background: var(--surface-2); border-radius: 999px; overflow: hidden; }
.bar-fill { height: 100%; background: var(--brand); border-radius: 999px; }
.kv { display: grid; grid-template-columns: auto 1fr; gap: 7px 16px; font-size: 13.5px; }
.kv dt { color: var(--text-3); }
.kv dd { margin: 0; text-align: right; font-variant-numeric: tabular-nums; }
.note {
  background: var(--brand-soft); border-left: 3px solid var(--brand);
  padding: 11px 14px; border-radius: var(--radius-sm); font-size: 13px; color: var(--text-2);
}
.prose { font-size: 14px; line-height: 1.7; white-space: pre-wrap;
  word-wrap: break-word; color: var(--text-2); }
.prose mark { background: var(--brand-soft); color: var(--brand); padding: 0 2px; border-radius: 3px; }
.tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--border); margin-bottom: 16px;
  overflow-x: auto; }
.tabs button {
  background: none; border: none; padding: 9px 14px; cursor: pointer;
  color: var(--text-2); font-weight: 600; border-bottom: 2px solid transparent;
  white-space: nowrap;
}
.tabs button.active { color: var(--brand); border-bottom-color: var(--brand); }
.skeleton { padding: 60px; text-align: center; color: var(--text-3); }

/* ---------- responsive ---------- */
/* ---- pass-through cost repeater (job form) ----
   Third-party costs re-billed at cost. Visually set apart from your own fees,
   because that is exactly the distinction that matters on the receipt. */
.pt-block {
  display: flex; flex-direction: column; gap: 10px; min-width: 0;
  border: 1px dashed var(--border); border-radius: var(--radius-sm);
  background: var(--surface-2); padding: 14px;
}
.pt-row {
  display: grid; gap: 8px; align-items: center; min-width: 0;
  grid-template-columns: minmax(0,1.7fr) minmax(0,1.3fr) minmax(0,.9fr)
                         minmax(0,1fr) 108px 34px;
}
.pt-row input, .pt-row select { min-width: 0; font-size: 13px; padding: 7px 9px; }
/* the explanation that prints under this line on the receipt: its own row */
.pt-row input[name="pt_note"] {
  grid-column: 1 / -1; font-size: 12.5px; font-style: italic;
  background: var(--surface); border-style: dashed;
}
.pt-row input[name="pt_amount"] { text-align: right; font-variant-numeric: tabular-nums; }
.pt-row > button { padding: 6px 9px; line-height: 1; }

/* one row per service performed — category, what it was, how many, each */
.svc-row {
  display: grid; gap: 8px; align-items: center; min-width: 0;
  grid-template-columns: minmax(0,1.1fr) minmax(0,2fr) 74px 104px 34px;
}
.svc-row input, .svc-row select { min-width: 0; font-size: 13px; padding: 7px 9px; }
.svc-row input[name="svc_note"] {
  grid-column: 1 / -1; font-size: 12.5px; font-style: italic;
  background: var(--surface); border-style: dashed;
}
/* the custom-name box takes the picker's place when it is showing */
.svc-row input[name="svc_name"] { grid-column: 2 / 3; }
.svc-row input[name="svc_name"][hidden] { display: none; }
.svc-row input[name="svc_qty"],
.svc-row input[name="svc_price"] { text-align: right; font-variant-numeric: tabular-nums; }
.svc-row > button { padding: 6px 9px; line-height: 1; }

/* a place you set out from: name + ZIP */
.base-row {
  display: grid; gap: 8px; align-items: center; min-width: 0;
  grid-template-columns: minmax(0,1fr) 88px 34px;
}
.base-row input { min-width: 0; font-size: 13px; padding: 7px 9px; }
.base-row input[name="base_zip"] { text-align: center; font-variant-numeric: tabular-nums; }
.base-row > button { padding: 6px 9px; line-height: 1; }

@media (max-width: 1100px) {
  /* Tablet: three stacked rows per cost, remove button pinned top-right. */
  .pt-row {
    grid-template-columns: minmax(0,1fr) minmax(0,1fr) 38px;
    padding-top: 10px; border-top: 1px solid var(--border);
  }
  .pt-row:first-child { padding-top: 0; border-top: none; }
  .pt-row input[name="pt_label"]      { grid-area: 1 / 1 / 2 / 3; }
  .pt-row > button                    { grid-area: 1 / 3 / 2 / 4; }
  .pt-row select[name="pt_category"]  { grid-area: 2 / 1 / 3 / 3; }
  .pt-row select[name="pt_carrier"]   { grid-area: 3 / 1 / 4 / 2; }
  .pt-row input[name="pt_reference"]  { grid-area: 3 / 2 / 4 / 3; }
  .pt-row input[name="pt_amount"]     { grid-area: 4 / 1 / 5 / 4; }
  .pt-row input[name="pt_note"]       { grid-area: 5 / 1 / 6 / 4; }
  /* Tablet and phone: a service is three stacked rows, × pinned top-right. */
  .svc-row {
    grid-template-columns: minmax(0,1fr) minmax(0,1fr) 38px;
    padding-top: 10px; border-top: 1px solid var(--border);
  }
  .svc-row:first-child { padding-top: 0; border-top: none; }
  .svc-row select[name="svc_category"] { grid-area: 1 / 1 / 2 / 3; }
  .svc-row > button                    { grid-area: 1 / 3 / 2 / 4; }
  .svc-row select[name="svc_pick"]     { grid-area: 2 / 1 / 3 / 4; }
  .svc-row input[name="svc_name"]      { grid-area: 3 / 1 / 4 / 4; }
  .svc-row input[name="svc_qty"]       { grid-area: 4 / 1 / 5 / 2; }
  .svc-row input[name="svc_price"]     { grid-area: 4 / 2 / 5 / 4; }
  .svc-row input[name="svc_note"]      { grid-area: 5 / 1 / 6 / 4; }
  .g4 { grid-template-columns: repeat(2, minmax(0,1fr)); }
  .board, .board.pipeline { grid-template-columns: repeat(2, minmax(210px,1fr)); }
  .split { grid-template-columns: minmax(0,1fr); }
}
@media (max-width: 860px) {
  #sidebar {
    position: fixed; left: 0; top: 0; bottom: 0;
    transform: translateX(-100%); transition: transform .2s ease, visibility .2s;
    box-shadow: var(--shadow-lg);
    /* Closed means gone: the version label peeked in at the left edge, and
       a keyboard could still tab into links you cannot see. */
    visibility: hidden;
  }
  body.nav-open #sidebar { transform: none; visibility: visible; }
  body.nav-open .nav-scrim {
    display: block; position: fixed; inset: 0;
    background: rgba(9,12,20,.5); z-index: 35;
  }
  .sidebar-close, .menu-btn { display: inline-flex; }
  #view { padding: 14px; }
  #topbar { padding: 12px 14px; }
  .g2, .g3, .g4, .split { grid-template-columns: minmax(0, 1fr); }
  /* Phone: one field per line, so nothing is squeezed to three letters. */
  .pt-row { grid-template-columns: minmax(0,1fr) 38px; }
  .pt-row input[name="pt_label"]      { grid-area: 1 / 1 / 2 / 2; }
  .pt-row > button                    { grid-area: 1 / 2 / 2 / 3; }
  .pt-row select[name="pt_category"]  { grid-area: 2 / 1 / 3 / 3; }
  .pt-row select[name="pt_carrier"]   { grid-area: 3 / 1 / 4 / 3; }
  .pt-row input[name="pt_reference"]  { grid-area: 4 / 1 / 5 / 3; }
  .pt-row input[name="pt_amount"]     { grid-area: 5 / 1 / 6 / 3; }
  .pt-row input[name="pt_note"]       { grid-area: 6 / 1 / 7 / 3; }
  .form-grid { grid-template-columns: minmax(0, 1fr); }
  .board, .board.pipeline { grid-template-columns: minmax(0, 1fr); }
  .cal td { height: auto; min-height: 62px; }
  #toasts { left: 14px; right: 14px; max-width: none; }
  /* Phone header: menu, title, call, language on one line; the page's own
     buttons drop to a second line rather than squeezing the title to nothing. */
  #topbar { flex-wrap: wrap; row-gap: 8px; }
  #page-title { font-size: 17px; flex: 1 1 auto; }
  #page-actions { order: 3; flex: 1 0 100%; justify-content: flex-start; }
  .call-btn { padding: 7px 12px; font-size: 15px; }
  .call-btn .call-label { display: none; }
}
/* Mobile first for the numbers: on a phone the headline tiles sit two to a
   row instead of one, so the money you check between appointments fits on
   the first screen rather than a long scroll of half-empty cards. */
@media (max-width: 860px) {
  .grid:has(> .stat) { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .stat { padding: 11px 12px; }
  .stat .label { font-size: 10px; letter-spacing: .05em; }
  .stat .value { font-size: 20px; }
  .stat .sub { font-size: 11px; }
}

@media print {
  #sidebar, #topbar, #page-actions, .filters { display: none !important; }
  #view { padding: 0; }
  .card { box-shadow: none; border-color: #ccc; }
}

/* ---- Knowledge Base: the two language panes in the editor ----
   Side by side when there is room, stacked on a phone. Writing the Spanish
   with the English in front of you is the only way the two stay in step. */
.kb-langs{display:grid;grid-template-columns:1fr 1fr;gap:16px}
.kb-pane{min-width:0}
.kb-pane-h{font-size:10.5px;font-weight:800;text-transform:uppercase;
  letter-spacing:.06em;color:var(--text-3);margin:0 0 6px;
  padding-bottom:5px;border-bottom:1px solid var(--border)}
@media (max-width:860px){ .kb-langs{grid-template-columns:1fr} }

/* ---- Client / B2B segmented switch ----
   A title company and a walk-in can ask for the same service and be quoted
   from different published price lists. This is that switch. */
.seg{display:inline-flex;border:1px solid var(--border);border-radius:8px;
  overflow:hidden;background:var(--surface-2)}
.seg-btn{appearance:none;border:0;background:transparent;color:var(--text-2);
  font:inherit;font-size:12.5px;font-weight:700;padding:6px 14px;cursor:pointer;
  white-space:nowrap}
.seg-btn + .seg-btn{border-left:1px solid var(--border)}
.seg-btn:hover{color:var(--text)}
.seg-btn.on{background:var(--brand);color:#fff}

/* ---------- editing an invoice's lines ----------
   A grid, not fixed flex widths. The first version pinned Qty, Unit and
   Amount to pixel widths, which gave every row a ~500px minimum -- on a
   360px phone that made the whole window wider than the screen, and the
   invoice total and the Save button sat off the right edge where they could
   not be read or pressed. */
.line-edit {
  display: grid; gap: 4px 10px; align-items: end;
  grid-template-columns: minmax(0, 1fr) 68px 96px auto 34px;
  grid-template-areas: "what qty unit amount del";
  padding: 10px 12px; border: 1px solid var(--border);
  border-radius: var(--radius-sm); background: var(--surface-2);
}
.line-edit .le-what   { grid-area: what; min-width: 0; }
.line-edit .le-qty    { grid-area: qty; }
.line-edit .le-unit   { grid-area: unit; }
.line-edit .le-amount { grid-area: amount; text-align: right; white-space: nowrap;
                        padding-bottom: 9px; }
.line-edit .le-del    { grid-area: del; margin-bottom: 6px; }
.le-amount-k { display: none; }

@media (max-width: 620px) {
  /* One field per row, full width, thumb-sized. The amount stops being a
     bare number in a column and says what it is. */
  .line-edit {
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
      "what   del"
      "qty    qty"
      "unit   unit"
      "amount amount";
    gap: 2px 10px;
  }
  .line-edit .le-amount {
    display: flex; justify-content: space-between; align-items: baseline;
    padding: 8px 0 2px; border-top: 1px dashed var(--border); margin-top: 6px;
  }
  .le-amount-k {
    display: inline; font: inherit; font-size: 10.5px; font-weight: 700;
    letter-spacing: .06em; text-transform: uppercase; color: var(--text-3);
  }
  .line-edit .le-del { align-self: start; margin: 0; }
}

/* ---------- windows on a phone ----------
   Full width, full visible height, with the header and the footer pinned so
   Save is always reachable without scrolling to find it. */
@media (max-width: 620px) {
  .modal-scrim { padding: 0; place-items: stretch; }
  .modal, .modal.wide {
    width: 100%; max-width: 100%;
    max-height: 100vh; max-height: 100dvh;
    height: 100dvh;
    border: 0; border-radius: 0;
  }
  .modal-head { position: sticky; top: 0; z-index: 2; background: var(--surface);
                padding: 14px 16px; }
  .modal-head h3 { font-size: 15.5px; }
  .modal-body { padding: 16px; }
  .modal-foot {
    position: sticky; bottom: 0; z-index: 2; background: var(--surface);
    padding: 12px 16px calc(12px + env(safe-area-inset-bottom));
    gap: 8px;
  }
  /* Full-width buttons: a half-visible Save is the bug this started with. */
  .modal-foot button, .modal-foot .btn, .modal-foot .ghost-btn,
  .modal-foot .danger-btn { flex: 1 1 130px; justify-content: center; }
}

/* ---- "we already know them" on the call window ----
   Shown while he is still typing the number, so he knows the call is going
   onto the record they already have rather than making a second copy. */
.known {
  border: 1px solid var(--good); border-left-width: 3px;
  background: color-mix(in srgb, var(--good) 8%, transparent);
  border-radius: var(--radius-sm); padding: 9px 12px; margin: -4px 0 4px;
}

/* ---- notarial journal tick on the Jobs table (v4.8) ---- */
.journal-cell { display: flex; align-items: center; gap: 4px; white-space: nowrap; }
.journal-tick {
  display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
  font-size: 12px; font-weight: 600; padding: 4px 9px 4px 7px;
  border-radius: 999px; border: 1px solid var(--border);
}
.journal-tick input { width: 16px; height: 16px; margin: 0; accent-color: var(--good); }
.journal-tick.todo { color: var(--warn); background: var(--warn-bg); border-color: var(--warn); }
.journal-tick.done { color: var(--good); background: var(--good-bg); border-color: transparent; }
.journal-na, .journal-add {
  border: 0; background: none; cursor: pointer; color: var(--muted, #6B7280);
  font-size: 15px; line-height: 1; padding: 4px 7px; border-radius: 6px; min-width: 28px;
}
.journal-na:hover, .journal-add:hover { background: var(--surface-2); color: inherit; }

/* ---- "needs you" strip at the top of the dashboard (v4.8) ---- */
.attention { display: grid; gap: 8px; margin-bottom: 16px; }
.attention-item {
  display: flex; align-items: flex-start; gap: 12px; text-decoration: none;
  color: inherit; padding: 11px 14px; border-radius: var(--radius-sm);
  border: 1px solid var(--border); border-left-width: 4px; background: var(--surface);
}
.attention-item:hover { background: var(--surface-2); }
.attention-item.bad  { border-left-color: var(--bad);  background: var(--bad-bg); }
.attention-item.warn { border-left-color: var(--warn); background: var(--warn-bg); }
.attention-item.info { border-left-color: var(--info); background: var(--info-bg); }
.attention-item .a-title { font-weight: 700; font-size: 13.5px; }
.attention-item .a-body { font-size: 12.5px; opacity: .85; margin-top: 2px; }
.attention-item .a-go { margin-left: auto; font-weight: 700; font-size: 12.5px;
  white-space: nowrap; align-self: center; color: var(--brand); }

/* ---- backup status in Settings (v4.8) ---- */
.backup-state { border-left-width: 4px; }
.backup-list { display: grid; gap: 6px; }
.backup-row { display: flex; align-items: center; justify-content: space-between;
  gap: 10px; font-size: 12.5px; }
.backup-row .mono { overflow-wrap: anywhere; }
.backup-other .ghost-btn { white-space: normal; height: auto; text-align: center;
  justify-content: center; line-height: 1.3; padding-top: 9px; padding-bottom: 9px; }
