:root {
  --primary: #1f4e79;
  --accent:  #c8791a;
  --bg:      #f5f6f8;
  --card:    #ffffff;
  --text:    #22262b;
  --muted:   #626b76;
  --line:    #dde2e8;
  --good:    #1d7a44;
  --bad:     #b3261e;
  --warn:    #9a6800;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 15px/1.5 system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

a { color: var(--primary); }

/* ── Chrome ─────────────────────────────────────────────── */

/* Both nav rows travel together, so the sections and the section's own pages are
   always a click away however far down a long list of invoices somebody is. One
   sticky wrapper rather than two sticky bars, because the top bar wraps to two
   lines on a narrow window and the second bar would then have to guess where to sit.
   On a short window it scrolls away as normal - a phone has no room to give up. */
@media (min-height: 520px) {
  .chrome { position: sticky; top: 0; z-index: 30; }
}

.topbar {
  display: flex; align-items: center; gap: 1.5rem; flex-wrap: wrap;
  background: var(--primary); color: #fff; padding: .6rem 1.25rem;
}
.topbar a { color: #fff; text-decoration: none; }
.brand { display: flex; flex-direction: column; line-height: 1.15; }
.brand strong { font-size: 1.15rem; letter-spacing: .06em; }
.brand span { font-size: .75rem; opacity: .8; }
.topbar nav { display: flex; gap: .25rem; flex-wrap: wrap; flex: 1; }
.topbar nav a { padding: .4rem .7rem; border-radius: 5px; font-size: .92rem; }
.topbar nav a:hover { background: rgba(255,255,255,.14); }
.topbar nav a.on { background: rgba(255,255,255,.24); font-weight: 600; }
.who { display: flex; align-items: center; gap: .75rem; font-size: .85rem; }

/* Always-present search in the chrome. Narrow enough not to compete with the nav. */
.topsearch { margin: 0; }
.topsearch input[type=search] {
  width: 11rem; padding: .3rem .55rem; border-radius: 5px;
  border: 1px solid rgba(255,255,255,.3); background: rgba(255,255,255,.14);
  color: #fff; font: inherit; font-size: .85rem;
}
.topsearch input[type=search]::placeholder { color: rgba(255,255,255,.7); }
.topsearch input[type=search]:focus {
  outline: 2px solid rgba(255,255,255,.65); outline-offset: -1px;
  background: #fff; color: var(--text);
}
.topsearch input[type=search]:focus::placeholder { color: var(--muted); }
.linkish {
  background: none; border: 0; color: #fff; opacity: .85;
  cursor: pointer; font: inherit; text-decoration: underline; padding: 0;
}

main { max-width: 1180px; margin: 1.5rem auto 3rem; padding: 0 1.25rem; }
.foot { text-align: center; color: var(--muted); font-size: .8rem; padding: 0 1rem 2rem; }

/* ── Blocks ─────────────────────────────────────────────── */
.card {
  background: var(--card); border: 1px solid var(--line);
  border-radius: 8px; padding: 1.1rem 1.25rem; margin-bottom: 1.25rem;
}
.card > h2 { margin: 0 0 .9rem; font-size: 1.05rem; }
.card > h2 .sub { font-weight: 400; color: var(--muted); font-size: .85rem; margin-left: .5rem; }

.page-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap; margin-bottom: 1rem;
}
.page-head h1 { font-size: 1.4rem; margin: 0; }
.page-head .sub { color: var(--muted); font-size: .9rem; }

.grid { display: grid; gap: 1.25rem; }
.grid.two   { grid-template-columns: repeat(auto-fit, minmax(330px, 1fr)); }
.grid.three { grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }
.grid.four  { grid-template-columns: repeat(auto-fit, minmax(175px, 1fr)); }

.stat { background: var(--card); border: 1px solid var(--line); border-radius: 8px; padding: .9rem 1rem; }
.stat .k { color: var(--muted); font-size: .78rem; text-transform: uppercase; letter-spacing: .04em; }
.stat .v { font-size: 1.5rem; font-weight: 600; margin-top: .2rem; }
.stat .n { color: var(--muted); font-size: .78rem; margin-top: .15rem; }
.stat.hi { border-color: var(--accent); box-shadow: inset 0 2px 0 var(--accent); }

/* ── Tables ─────────────────────────────────────────────── */
table { width: 100%; border-collapse: collapse; font-size: .92rem; }
th, td { text-align: left; padding: .5rem .6rem; border-bottom: 1px solid var(--line); vertical-align: top; }
th { font-size: .75rem; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); }
tbody tr:hover { background: #fafbfc; }
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
tfoot td { font-weight: 600; border-top: 2px solid var(--line); border-bottom: 0; }
.table-scroll { overflow-x: auto; }
.empty { color: var(--muted); padding: .75rem 0; }

/* ── Forms ──────────────────────────────────────────────── */
label { display: block; font-size: .8rem; color: var(--muted); margin-bottom: .2rem; }
input[type=text], input[type=email], input[type=password], input[type=date],
input[type=number], select, textarea {
  width: 100%; padding: .45rem .55rem; border: 1px solid var(--line);
  border-radius: 5px; font: inherit; background: #fff; color: var(--text);
}
input:focus, select:focus, textarea:focus { outline: 2px solid var(--primary); outline-offset: -1px; }
textarea { min-height: 4.5rem; resize: vertical; }
.field { margin-bottom: .8rem; }
.row { display: grid; gap: .8rem; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }
.checkline { display: flex; align-items: center; gap: .4rem; font-size: .9rem; color: var(--text); }
.checkline label { margin: 0; color: var(--text); font-size: .9rem; }

.btn {
  display: inline-block; background: var(--primary); color: #fff; border: 1px solid var(--primary);
  padding: .45rem .9rem; border-radius: 5px; cursor: pointer; font: inherit; text-decoration: none;
}
.btn:hover { filter: brightness(1.08); }
.btn.ghost { background: #fff; color: var(--primary); }
.btn.warn { background: var(--warn); border-color: var(--warn); }
.btn.danger { background: var(--bad); border-color: var(--bad); }
.btn.small { padding: .25rem .6rem; font-size: .85rem; }
.actions { display: flex; gap: .5rem; flex-wrap: wrap; align-items: center; }

.filters { display: flex; gap: .6rem; flex-wrap: wrap; align-items: flex-end; margin-bottom: 1rem; }
.filters .field { margin: 0; }
.filters input, .filters select { min-width: 9rem; }

/* ── Badges and flashes ─────────────────────────────────── */
.badge {
  display: inline-block; padding: .1rem .5rem; border-radius: 999px;
  font-size: .75rem; font-weight: 600; border: 1px solid;
}
.badge.good  { color: var(--good); border-color: var(--good); background: #eaf6ef; }
.badge.bad   { color: var(--bad);  border-color: var(--bad);  background: #fdeceb; }
.badge.warn  { color: var(--warn); border-color: var(--warn); background: #fdf5e3; }
.badge.plain { color: var(--muted); border-color: var(--line); background: #f2f4f6; }

.flash { padding: .65rem .9rem; border-radius: 6px; margin-bottom: 1rem; border: 1px solid; }
.flash.ok   { background: #eaf6ef; border-color: var(--good); color: #14562f; }
.flash.bad  { background: #fdeceb; border-color: var(--bad);  color: #7d1a15; }
.flash.warn { background: #fdf5e3; border-color: var(--warn); color: #6b4900; }

.muted { color: var(--muted); }
.small { font-size: .85rem; }
.right { text-align: right; }
.nowrap { white-space: nowrap; }
.note {
  background: #f2f6fb; border-left: 3px solid var(--primary);
  padding: .6rem .8rem; border-radius: 4px; font-size: .88rem; margin: .75rem 0;
}

/* ── Login ──────────────────────────────────────────────── */
.login-wrap { max-width: 380px; margin: 8vh auto; padding: 0 1rem; }
.login-wrap h1 { text-align: center; color: var(--primary); letter-spacing: .08em; margin-bottom: .1rem; }
.login-wrap .tag { text-align: center; color: var(--muted); font-size: .85rem; margin: 0 0 1.5rem; }

/* ── Invoice line editor ────────────────────────────────── */
.lines td { vertical-align: middle; }
.lines input[type=text] { min-width: 5rem; }
.lines .desc { min-width: 15rem; }
.lines .drop { min-width: 12rem; }
.totals { margin-left: auto; max-width: 22rem; }
.totals table td { border: 0; padding: .25rem .3rem; }
.totals tr.grand td { border-top: 2px solid var(--line); font-size: 1.05rem; font-weight: 700; padding-top: .5rem; }

/* ── Printable invoice ──────────────────────────────────── */
.sheet {
  max-width: 8.5in; margin: 1rem auto; background: #fff; padding: .6in;
  border: 1px solid var(--line); color: #000;
}
.sheet h1 { margin: 0; font-size: 1.6rem; color: var(--primary); }
.sheet .head { display: flex; justify-content: space-between; gap: 2rem; margin-bottom: 1.5rem; }
.sheet .parties { display: flex; justify-content: space-between; gap: 2rem; margin-bottom: 1.25rem; }
.sheet .meta td { border: 0; padding: .1rem .5rem .1rem 0; font-size: .9rem; }
.print-bar { max-width: 8.5in; margin: 1rem auto 0; display: flex; gap: .5rem; }

@media print {
  .print-bar, .chrome, .topbar, .foot, .noprint { display: none !important; }
  body { background: #fff; }
  .sheet { border: 0; margin: 0; padding: 0; max-width: none; }
}

/* A whole table row that behaves like the link it contains. */
tr.rowlink { cursor: pointer; }

/* ── Second row: the current section's pages, as pills ─────────────────────── */
.subbar {
  display: flex; gap: .4rem; flex-wrap: wrap; align-items: center;
  background: #eef2f7; border-bottom: 1px solid var(--line);
  padding: .55rem 1.25rem;
}
.subbar-where {
  font-size: .72rem; text-transform: uppercase; letter-spacing: .08em;
  color: var(--muted); font-weight: 600; margin-right: .5rem;
}
.subbar .pill {
  color: var(--primary); text-decoration: none; font-size: .9rem; font-weight: 500;
  padding: .35rem .9rem; border-radius: 999px;
  background: var(--card); border: 1px solid var(--line);
}
.subbar .pill:hover { border-color: var(--primary); background: #fff; }
.subbar .pill.on {
  background: var(--primary); border-color: var(--primary); color: #fff; font-weight: 600;
}

/* ── Quick links ──────────────────────────────────────────────────────────────
   The dashboard is a place to start a job, so each tile is a whole target rather
   than a card with a link buried in it. */
/* Three columns, one per kind of job. They fall to two and then one as the window
   narrows, because a column of tiles squeezed to 150px helps nobody. */
/* Three columns of jobs. Account and People and Paperwork share the third, Account on
   top, because both are short and neither earns a column of its own. */
.quick-cols {
  display: grid; gap: 1.25rem 1.25rem;
  grid-template-columns: repeat(auto-fit, minmax(290px, 1fr));
  align-items: start;
}
.quick-col { display: flex; flex-direction: column; gap: .9rem; }

.quick-head {
  font-size: .95rem; letter-spacing: 0; font-weight: 600;
  color: var(--text); margin: 0 0 .1rem;
  padding-bottom: .4rem; border-bottom: 2px solid var(--line);
}
/* A second heading further down the same column needs air above it. */
.quick-head.stacked { margin-top: .9rem; }

.tiles { display: grid; gap: .9rem; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }

.tile {
  display: block; text-decoration: none; color: var(--text);
  background: var(--card); border: 1px solid var(--line); border-radius: 8px;
  padding: 1rem 1.1rem;
  transition: border-color .12s, box-shadow .12s, transform .12s;
}
.tile:hover {
  border-color: var(--primary);
  box-shadow: 0 4px 14px rgba(31,78,121,.12);
  transform: translateY(-1px);
}
.tile strong { display: block; color: var(--primary); font-size: 1.05rem; margin-bottom: .35rem; }

/* The one number that matters, if there is one. Big enough to read at a glance from
   across the desk, which a sentence containing it never is. */
.tile .figure {
  display: block; font-style: normal; font-weight: 700;
  font-size: 1.45rem; line-height: 1.1; color: var(--text);
  font-variant-numeric: tabular-nums; margin: .1rem 0 .45rem;
}

/* Short lines rather than a paragraph: the tile is scanned, never read. */
.tile ul { list-style: none; margin: 0; padding: 0; }
.tile li {
  position: relative; padding-left: .85rem; margin-bottom: .22rem;
  color: var(--muted); font-size: .88rem; line-height: 1.4;
}
.tile li::before {
  content: ""; position: absolute; left: 0; top: .52em;
  width: 4px; height: 4px; border-radius: 50%; background: var(--line);
}
.tile:hover li::before { background: var(--primary); }
.tile li:last-child { margin-bottom: 0; }

/* The one most likely to be wanted, and the one that needs attention. */
.tile.lead { border-color: var(--primary); box-shadow: inset 0 3px 0 var(--primary); }
.tile.warn { border-color: var(--warn); box-shadow: inset 0 3px 0 var(--warn); }
.tile.warn strong { color: var(--warn); }

/* ── Editing payments on an invoice ───────────────────────────────────────────
   A table of editable payments needs more width than half a page has, so each is a
   small block instead: the amount on its own line, the fields beneath it. Nothing
   scrolls sideways. */
.payrow {
  border: 1px solid var(--line); border-radius: 6px;
  padding: .6rem .7rem; margin-bottom: .6rem; background: #fcfdfe;
}
.payrow-head { display: flex; align-items: center; gap: .6rem; margin-bottom: .45rem; }
.payrow-head strong { font-size: 1.05rem; font-variant-numeric: tabular-nums; }
.payrow-x { margin-left: auto; }

/* Two per line, so a date sits beside a method and nothing is squeezed to a sliver. */
.payrow-grid { display: grid; gap: .4rem; grid-template-columns: repeat(2, minmax(0, 1fr)); }
.payrow-grid > * { min-width: 0; }
.payrow-grid > :last-child { grid-column: 1 / -1; }

@media (max-width: 560px) {
  .payrow-grid { grid-template-columns: 1fr; }
  .payrow-grid > :last-child { grid-column: auto; }
}

/* Sortable column headings. The whole heading is the link, so the target is the width
   of the column rather than the width of the word, and the arrow keeps its space on the
   column in force so the row does not shift as the sort moves. */
th.sortable { padding: 0; }
th.sortable a {
  display: block; padding: .5rem .6rem; color: inherit; text-decoration: none;
  white-space: nowrap;
}
th.sortable a:hover { color: var(--text); background: var(--bg); }
th.sorted a { color: var(--primary); }
th.sortable .arrow { display: inline-block; width: .85em; text-align: right; }
th.sortable.num a { text-align: right; }

/* A heading for a section inside a card, below the card's own h2. */
.sub-head {
  font-size: .95rem; margin: 0 0 .5rem; color: var(--text);
  display: flex; align-items: baseline; gap: .5rem;
}
.sub-head .sub { font-size: .8rem; color: var(--muted); font-weight: 400; }

/* The figure to check against the paper slip, sized to be read across the desk. */
.slip-total strong { font-size: 1.25rem; display: block; line-height: 1.2; }

/* A link to #billing or #deposit must not land under the sticky chrome. */
main [id] { scroll-margin-top: 7rem; }

/* Staging, and never mistakable for the real thing: the whole site turns from the live
   blue to teal - header, buttons, links, headings - as well as carrying the band. The body
   class comes from APP_ENV, so a copied database cannot change it. */
.env-stage { --primary: #19675f; }
.env-stage .tile:hover { box-shadow: 0 4px 14px rgba(25,103,95,.14); }

/* Staging, and never mistakable for the real thing. */
.envbar {
  background: var(--accent); color: #fff; font-size: .8rem; font-weight: 600;
  letter-spacing: .03em; padding: .35rem 1.25rem; text-align: center;
}

/* ── Dashboard tiles with entries ─────────────────────────────────────────────
   A tile is no longer one big link: its heading goes to the job, each entry to itself,
   and See more to the whole list. So it does not lift on hover, and its links say
   where they go on their own. */
div.tile:hover { transform: none; box-shadow: none; border-color: var(--line); }
div.tile.lead:hover { border-color: var(--primary); box-shadow: inset 0 3px 0 var(--primary); }
div.tile.warn:hover { border-color: var(--warn); box-shadow: inset 0 3px 0 var(--warn); }
.tile .tile-head { text-decoration: none; }
.tile .tile-head:hover strong { text-decoration: underline; }
.tile li a { color: var(--text); text-decoration: none; }
.tile li a:hover { color: var(--primary); text-decoration: underline; }
.tile li .when { display: block; font-size: .8rem; color: var(--muted); }
.tile .more {
  display: inline-block; margin-top: .55rem; font-size: .85rem; font-weight: 600;
  color: var(--primary); text-decoration: none;
}
.tile .more:hover { text-decoration: underline; }
