/* app.css — one stylesheet for the whole application.
   v1 carried a copy of its theme in each of 22 files; this replaces all of them. */

:root {
  --bg: #f1f4f9;
  --surface: #ffffff;
  --surface-2: #f7f9fc;
  --surface-3: #eef2f8;
  --border: #dde3ec;
  --border-strong: #c3ccdb;
  --text: #16202e;
  --text-2: #4a5768;
  --text-3: #7c8798;

  --brand: #1f4e79;
  --brand-2: #2f6da8;
  --brand-soft: #e8f0f9;

  --dr: #b02a37;          /* debit  */
  --cr: #16794c;          /* credit */
  --ok: #16794c;
  --warn: #a16207;
  --err: #b02a37;
  --info: #1f4e79;

  --radius: 8px;
  --radius-sm: 5px;
  --shadow-1: 0 1px 2px rgba(16, 26, 40, .06), 0 1px 3px rgba(16, 26, 40, .05);
  --shadow-2: 0 4px 12px rgba(16, 26, 40, .10), 0 2px 4px rgba(16, 26, 40, .06);
  --shadow-3: 0 18px 48px rgba(16, 26, 40, .22);

  --sidebar-w: 244px;
  --topbar-h: 56px;

  /* system-ui first: it resolves to whatever the operating system considers
     its interface face, which on Windows 11 is Segoe UI Variable rather than
     the older Segoe UI that was being asked for by name. The named faces stay
     behind it as the fallback chain for everything else. */
  --font: system-ui, -apple-system, "Segoe UI Variable Text", "Segoe UI",
          Roboto, "Helvetica Neue", Arial, sans-serif;
  --mono: ui-monospace, "Cascadia Mono", Consolas, "SF Mono", "Roboto Mono", monospace;

  /* One ring, used by every focusable thing. Keyboard users navigate this
     application all day — the register screens are built for it — and a focus
     state that is only a colour change is not one. */
  --ring: 0 0 0 3px rgba(47, 109, 168, .35);
}

[data-theme="dark"] {
  --bg: #10151d;
  --surface: #171e28;
  --surface-2: #1c242f;
  --surface-3: #222b38;
  --border: #2a3543;
  --border-strong: #3a4757;
  --text: #e6ecf4;
  --text-2: #a8b4c4;
  --text-3: #7b8798;
  --brand: #4a90d9;
  --brand-2: #6aa9e8;
  --brand-soft: #1c2a3a;
  --dr: #f08a95;
  --cr: #5fd1a0;
  --ok: #5fd1a0;
  --warn: #e0b34a;
  --err: #f08a95;
  --info: #6aa9e8;
  --shadow-1: 0 1px 2px rgba(0, 0, 0, .4);
  --shadow-2: 0 4px 12px rgba(0, 0, 0, .5);
  --shadow-3: 0 18px 48px rgba(0, 0, 0, .6);
  --ring: 0 0 0 3px rgba(106, 169, 232, .45);
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
}

body {
  font-family: var(--font);
  font-size: 14px;
  line-height: 1.5;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
}

a { color: var(--brand-2); text-decoration: none; }
a:hover { text-decoration: underline; }
h1, h2, h3, h4 { margin: 0; font-weight: 600; line-height: 1.25; }
p { margin: 0 0 .6em; }
code, .mono { font-family: var(--mono); font-size: .92em; }
.muted { color: var(--text-3); }
.small { font-size: 12px; }
.ta-right { text-align: right; }
.ta-center { text-align: center; }
.nowrap { white-space: nowrap; }
.hidden, [hidden] { display: none !important; }

/* ---------- layout ---------- */

.app {
  display: grid;
  grid-template-columns: var(--sidebar-w) 1fr;
  grid-template-rows: var(--topbar-h) 1fr;
  grid-template-areas: "brand topbar" "sidebar main";
  height: 100vh;
}
.app.is-collapsed { --sidebar-w: 60px; }

.brand-cell {
  grid-area: brand;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 14px;
  background: var(--brand);
  color: #fff;
  overflow: hidden;
}
.brand-cell img { width: 30px; height: 30px; object-fit: contain; border-radius: 5px; background: #fff; padding: 2px; }
.brand-cell strong { font-size: 14px; letter-spacing: .2px; white-space: nowrap; }
.brand-cell small { display: block; font-size: 10.5px; opacity: .8; font-weight: 400; }
.app.is-collapsed .brand-cell .brand-text { display: none; }

.topbar {
  grid-area: topbar;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 16px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  box-shadow: var(--shadow-1);
  z-index: 20;
}
.topbar__spacer { flex: 1; }
.topbar__fy {
  font-size: 12px;
  color: var(--text-2);
  background: var(--surface-3);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 3px 11px;
}

.sidebar {
  grid-area: sidebar;
  background: var(--surface);
  border-right: 1px solid var(--border);
  overflow-y: auto;
  padding: 10px 0 24px;
}
.nav-group { margin-bottom: 4px; }
.nav-group__title {
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: .8px;
  color: var(--text-3);
  padding: 12px 16px 5px;
  font-weight: 700;
}
.app.is-collapsed .nav-group__title { visibility: hidden; height: 14px; padding: 6px 0 0; }
.nav-link {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 16px;
  color: var(--text-2);
  font-size: 13.5px;
  border-left: 3px solid transparent;
  white-space: nowrap;
}
.nav-link:hover { background: var(--surface-2); color: var(--text); text-decoration: none; }
.nav-link.is-active {
  background: var(--brand-soft);
  color: var(--brand-2);
  border-left-color: var(--brand);
  font-weight: 600;
}
.nav-link__icon { display: flex; align-items: center; justify-content: center; width: 18px; flex: none; }
.app.is-collapsed .nav-link__text { display: none; }

.main {
  grid-area: main;
  overflow-y: auto;
  padding: 18px 22px 60px;
}

@media (max-width: 900px) {
  .app { grid-template-columns: 1fr; grid-template-areas: "topbar" "main"; }
  .brand-cell, .sidebar { display: none; }
  .app.is-mobile-open { grid-template-columns: var(--sidebar-w) 1fr; grid-template-areas: "brand topbar" "sidebar main"; }
  .app.is-mobile-open .brand-cell, .app.is-mobile-open .sidebar { display: block; }
  .main { padding: 14px; }
}

/* ---------- page furniture ---------- */

.page-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 14px;
  flex-wrap: wrap;
}
.page-title { font-size: 20px; }
.page-sub { color: var(--text-3); font-size: 13px; margin: 3px 0 0; }
.page-actions { display: flex; gap: 8px; flex-wrap: wrap; }

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-1);
  padding: 16px;
  margin-bottom: 16px;
}
.card--flush { padding: 0; overflow: hidden; }
.card__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--border);
  background: var(--surface-2);
  flex-wrap: wrap;
}
.card__head h2, .card__head h3 { font-size: 14px; }
.card__body { padding: 16px; }
.card--warn { border-left: 3px solid var(--warn); }
.card--error { border-left: 3px solid var(--err); }
.card--ok { border-left: 3px solid var(--ok); }

.grid { display: grid; gap: 16px; }
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }
.grid--3 { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }

/* ---------- stats ---------- */

.stat-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 12px;
  margin-bottom: 16px;
}
.stat {
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 3px solid var(--brand);
  border-radius: var(--radius);
  padding: 12px 14px;
  box-shadow: var(--shadow-1);
}
.stat--dr { border-left-color: var(--dr); }
.stat--cr { border-left-color: var(--cr); }
.stat--warn { border-left-color: var(--warn); }
.stat--ok { border-left-color: var(--ok); }
.stat__label { display: block; font-size: 11px; text-transform: uppercase; letter-spacing: .6px; color: var(--text-3); font-weight: 700; }
.stat__value { display: block; font-size: 21px; font-weight: 600; margin-top: 4px; font-variant-numeric: tabular-nums; }
.stat__note { display: block; font-size: 11.5px; color: var(--text-3); margin-top: 2px; }

/* ---------- buttons ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  font: inherit;
  font-size: 13px;
  font-weight: 500;
  padding: 7px 14px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border-strong);
  background: var(--surface);
  color: var(--text);
  cursor: pointer;
  white-space: nowrap;
  transition: background .12s, border-color .12s, transform .05s;
}
.btn:hover { background: var(--surface-3); text-decoration: none; }
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: .5; cursor: not-allowed; }
.btn--primary { background: var(--brand); border-color: var(--brand); color: #fff; }
.btn--primary:hover { background: var(--brand-2); border-color: var(--brand-2); }
.btn--danger { background: var(--err); border-color: var(--err); color: #fff; }
.btn--danger:hover { filter: brightness(1.08); }
.btn--ghost { background: transparent; border-color: var(--border-strong); }
.btn--sm { padding: 4px 9px; font-size: 12px; }
.btn--icon { padding: 5px 8px; }
.btn-row { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }

.chip {
  font: inherit;
  font-size: 11.5px;
  padding: 3px 10px;
  border-radius: 999px;
  border: 1px solid var(--border-strong);
  background: var(--surface);
  color: var(--text-2);
  cursor: pointer;
}
.chip:hover, .chip.is-on { background: var(--brand-soft); color: var(--brand-2); border-color: var(--brand-2); }

.badge {
  display: inline-block;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .4px;
  text-transform: uppercase;
  padding: 2px 7px;
  border-radius: 4px;
  background: var(--surface-3);
  color: var(--text-2);
  border: 1px solid var(--border);
}
.badge--ok { background: rgba(22, 121, 76, .12); color: var(--ok); border-color: transparent; }
.badge--warn { background: rgba(161, 98, 7, .14); color: var(--warn); border-color: transparent; }
.badge--err { background: rgba(176, 42, 55, .12); color: var(--err); border-color: transparent; }
.badge--info { background: var(--brand-soft); color: var(--brand-2); border-color: transparent; }
.badge--dr { background: rgba(176, 42, 55, .10); color: var(--dr); border-color: transparent; }
.badge--cr { background: rgba(22, 121, 76, .10); color: var(--cr); border-color: transparent; }

/* ---------- forms ---------- */

.form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 12px 14px;
}
.field { display: flex; flex-direction: column; gap: 4px; }
.field--wide { grid-column: 1 / -1; }
.field--check { flex-direction: row; align-items: center; gap: 8px; }
.field__label { font-size: 12px; font-weight: 600; color: var(--text-2); }
.field__hint { font-size: 11px; color: var(--text-3); }
.field__error { font-size: 11.5px; color: var(--err); font-weight: 500; }
.req { color: var(--err); font-style: normal; }

.input {
  font: inherit;
  font-size: 13.5px;
  padding: 7px 10px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text);
  width: 100%;
  transition: border-color .12s, box-shadow .12s;
}
.input:focus {
  outline: none;
  border-color: var(--brand-2);
  box-shadow: 0 0 0 3px rgba(47, 109, 168, .16);
}
.input:read-only, .input:disabled { background: var(--surface-3); color: var(--text-2); }
.input.is-unmatched { border-color: var(--warn); }
input[type="number"].input, .input--money { text-align: right; font-variant-numeric: tabular-nums; }
textarea.input { resize: vertical; }

.picker { display: flex; gap: 6px; align-items: stretch; }
.picker .input { flex: 1; }

.filter-bar {
  display: flex;
  align-items: flex-end;
  gap: 10px;
  flex-wrap: wrap;
  padding: 12px 16px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  margin-bottom: 14px;
}
.filter__item { display: flex; flex-direction: column; gap: 3px; font-size: 11.5px; color: var(--text-2); font-weight: 600; }
.filter__item .input { min-width: 140px; }
.filter__presets { display: flex; gap: 5px; flex-wrap: wrap; }

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

.table-wrap { overflow-x: auto; border-radius: var(--radius); }
.table-wrap--sticky { max-height: 62vh; overflow-y: auto; }

.table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
  background: var(--surface);
}
.table th, .table td {
  padding: 7px 10px;
  border-bottom: 1px solid var(--border);
  text-align: left;
  vertical-align: top;
}
.table thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--surface-3);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .5px;
  color: var(--text-2);
  font-weight: 700;
  white-space: nowrap;
  border-bottom: 2px solid var(--border-strong);
}
.table tbody tr:hover { background: var(--surface-2); }
.table tfoot td, .table tfoot th {
  background: var(--surface-3);
  font-weight: 700;
  border-top: 2px solid var(--border-strong);
  border-bottom: none;
  position: sticky;
  bottom: 0;
}
.table--compact th, .table--compact td { padding: 4px 8px; font-size: 12.5px; }
.table tr.is-void td { opacity: .55; text-decoration: line-through; }
.table tr.is-group td { background: var(--surface-3); font-weight: 700; }
.table tr.is-subtotal td { background: var(--surface-2); font-weight: 600; }

.num { font-variant-numeric: tabular-nums; white-space: nowrap; }
.num--neg { color: var(--dr); }
.dr { color: var(--dr); }
.cr { color: var(--cr); }
.warn-text { color: var(--warn); }

.empty { text-align: center; padding: 40px 20px; color: var(--text-3); }
.empty__mark { font-size: 30px; opacity: .35; margin-bottom: 6px; }

.pre-scroll {
  max-height: 260px;
  overflow: auto;
  background: var(--surface-3);
  padding: 10px;
  border-radius: var(--radius-sm);
  font-size: 11.5px;
}

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

.toast-host {
  position: fixed;
  right: 18px;
  bottom: 18px;
  z-index: 900;
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-width: 380px;
}
.toast {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  padding: 10px 14px;
  border-radius: var(--radius);
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 3px solid var(--info);
  box-shadow: var(--shadow-2);
  font-size: 13px;
  opacity: 0;
  transform: translateY(8px);
  transition: opacity .2s, transform .2s;
}
.toast.is-in { opacity: 1; transform: none; }
.toast--success { border-left-color: var(--ok); }
.toast--error { border-left-color: var(--err); }
.toast--warn { border-left-color: var(--warn); }
.toast__icon {
  width: 18px; height: 18px; flex: none;
  border-radius: 50%;
  display: grid; place-items: center;
  font-size: 11px; font-weight: 700;
  background: var(--surface-3);
  color: var(--text-2);
}
.toast--success .toast__icon { background: rgba(22, 121, 76, .15); color: var(--ok); }
.toast--error .toast__icon { background: rgba(176, 42, 55, .15); color: var(--err); }
.toast--warn .toast__icon { background: rgba(161, 98, 7, .16); color: var(--warn); }

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

.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(12, 18, 28, .55);
  display: grid;
  place-items: center;
  padding: 20px;
  z-index: 800;
  opacity: 0;
  transition: opacity .18s;
}
.modal-overlay.is-in { opacity: 1; }
.modal {
  background: var(--surface);
  border-radius: var(--radius);
  box-shadow: var(--shadow-3);
  width: 100%;
  max-height: 90vh;
  display: flex;
  flex-direction: column;
  transform: translateY(10px) scale(.99);
  transition: transform .18s;
}
.modal-overlay.is-in .modal { transform: none; }
.modal--sm { max-width: 420px; }
.modal--md { max-width: 640px; }
.modal--lg { max-width: 900px; }
.modal--xl { max-width: 1150px; }
.modal__head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 13px 18px;
  border-bottom: 1px solid var(--border);
}
.modal__head h3 { font-size: 15px; }
.modal__x {
  border: 0; background: none; font-size: 24px; line-height: 1;
  color: var(--text-3); cursor: pointer; padding: 0 4px;
}
.modal__x:hover { color: var(--text); }
.modal__body { padding: 18px; overflow-y: auto; }
.modal__message { font-size: 14px; }
.modal__foot {
  display: flex; justify-content: flex-end; gap: 8px;
  padding: 12px 18px;
  border-top: 1px solid var(--border);
  background: var(--surface-2);
  border-radius: 0 0 var(--radius) var(--radius);
}

.busy {
  position: fixed; inset: 0; z-index: 950;
  background: rgba(12, 18, 28, .35);
  display: grid; place-items: center;
}
.busy__box {
  background: var(--surface); padding: 16px 22px; border-radius: var(--radius);
  box-shadow: var(--shadow-3); display: flex; align-items: center; gap: 12px;
}
.spinner {
  width: 16px; height: 16px; border-radius: 50%;
  border: 2px solid var(--border-strong); border-top-color: var(--brand);
  animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ---------- user menu ---------- */

.user-btn {
  display: flex; align-items: center; gap: 8px;
  border: 1px solid var(--border); background: var(--surface);
  border-radius: 999px; padding: 3px 11px 3px 3px; cursor: pointer;
  font: inherit; color: var(--text);
}
.user-btn:hover { background: var(--surface-2); }
.avatar {
  width: 28px; height: 28px; border-radius: 50%;
  object-fit: cover; background: var(--brand); color: #fff;
  display: grid; place-items: center; font-size: 12px; font-weight: 700;
  flex: none; border: 0;
}
.avatar--lg { width: 76px; height: 76px; font-size: 26px; }
.user-btn__meta { text-align: left; line-height: 1.15; }
.user-btn__name { font-size: 12.5px; font-weight: 600; display: block; }
.user-btn__role { font-size: 10.5px; color: var(--text-3); display: block; }

.dropdown {
  position: absolute; top: calc(var(--topbar-h) - 4px); right: 16px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); box-shadow: var(--shadow-2);
  min-width: 208px; padding: 5px; z-index: 100;
}
.dropdown a, .dropdown button {
  display: flex; align-items: center; gap: 9px;
  width: 100%; padding: 8px 11px; font: inherit; font-size: 13px;
  background: none; border: 0; color: var(--text);
  border-radius: var(--radius-sm); cursor: pointer; text-align: left;
}
.dropdown a:hover, .dropdown button:hover { background: var(--surface-2); text-decoration: none; }
.dropdown hr { border: 0; border-top: 1px solid var(--border); margin: 5px 0; }

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

.login-page {
  min-height: 100vh;
  display: grid;
  grid-template-columns: 1.05fr .95fr;
  background: var(--bg);
}
.login-hero {
  background: linear-gradient(150deg, #1f4e79 0%, #123252 60%, #0d2439 100%);
  color: #fff;
  padding: 48px 52px;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
/* The maker's mark, small and above the fold. A business being asked to type
   its tax credentials into a page should be able to see whose page it is
   without scrolling for the answer. */
.login-hero__mark {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 30px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .3px;
  color: rgba(255, 255, 255, .82);
}
.login-hero__mark img { border-radius: 7px; background: #fff; padding: 3px; }

.login-hero h1 { font-size: 31px; margin-bottom: 12px; letter-spacing: -.4px; }
.login-hero p { color: rgba(255, 255, 255, .8); max-width: 44ch; font-size: 14.5px; }
.login-hero ul { list-style: none; padding: 0; margin: 26px 0 0; display: grid; gap: 11px; }
.login-hero li {
  display: flex; gap: 12px; align-items: flex-start;
  color: rgba(255, 255, 255, .88); font-size: 13.5px; line-height: 1.5;
  max-width: 52ch;
}
.login-hero .bullet__icon { display: flex; flex: none; margin-top: 2px; opacity: .7; }
.login-hero li strong { color: #fff; }
.login-vendor {
  margin-top: 30px;
  padding-top: 18px;
  border-top: 1px solid rgba(255, 255, 255, .16);
  max-width: 44ch;
}
.login-vendor p { font-size: 13px; color: rgba(255, 255, 255, .72); }
.login-vendor__by { color: rgba(255, 255, 255, .92); margin-bottom: 4px; letter-spacing: .2px; }
.login-vendor a { color: #fff; text-decoration: underline; text-underline-offset: 2px; }
.login-panel { display: grid; place-items: center; padding: 32px; }
/* A real card, not a form floating in the margin. What is being asked for
   here is a password, and a box with an edge reads as somewhere it is safe to
   type one. */
.login-box {
  width: 100%;
  max-width: 380px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-2);
  padding: 28px;
}
.login-box h2 { font-size: 21px; margin-bottom: 4px; }
.login-box .form-grid { grid-template-columns: 1fr; margin-top: 20px; }
.login-alert {
  background: rgba(176, 42, 55, .10);
  border: 1px solid rgba(176, 42, 55, .3);
  color: var(--err);
  border-radius: var(--radius-sm);
  padding: 9px 12px;
  font-size: 13px;
  margin-top: 14px;
}
/* The same box, for the one message that is not a complaint. */
.login-alert--ok {
  background: rgba(22, 121, 76, .10);
  border-color: rgba(22, 121, 76, .3);
  color: var(--ok);
}
.login-foot {
  margin: 18px 0 0;
  font-size: 12px;
  line-height: 1.6;
  color: var(--text-3);
}
.login-note {
  margin-top: 18px; padding: 11px 13px;
  background: var(--surface-3); border-radius: var(--radius-sm);
  font-size: 12.5px; color: var(--text-2);
}
@media (max-width: 860px) {
  .login-page { grid-template-columns: 1fr; }
  .login-hero { padding: 30px 24px; }
  .login-hero__mark { margin-bottom: 20px; }
  /* The pitch is for somebody deciding; a phone at the counter is somebody
     signing in. Two bullets keep the page honest without pushing the box
     below a second scroll. */
  .login-hero li:nth-child(n+3) { display: none; }
  .login-vendor { margin-top: 22px; }
  .login-panel { padding: 24px 16px 40px; }
  .login-box { padding: 22px; box-shadow: none; }
}

/* ---------- voucher entry helpers ---------- */

.entry-total-bar {
  display: flex; flex-wrap: wrap; gap: 20px;
  align-items: center; justify-content: flex-end;
  padding: 12px 16px;
  background: var(--surface-3);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  margin: 14px 0;
}
.entry-total-bar .tot { text-align: right; }
.entry-total-bar .tot span { display: block; font-size: 11px; text-transform: uppercase; letter-spacing: .5px; color: var(--text-3); font-weight: 700; }
.entry-total-bar .tot strong { font-size: 17px; font-variant-numeric: tabular-nums; }
.entry-total-bar .tot--grand strong { font-size: 22px; color: var(--brand-2); }

/* passenger entry grid */
.pax-grid td { padding: 3px 5px; vertical-align: middle; }
.pax-grid .input { padding: 5px 7px; font-size: 13px; }
.pax-grid td.ta-right { font-variant-numeric: tabular-nums; white-space: nowrap; }
.pax-grid tbody tr:hover { background: transparent; }
.pax-grid .small { font-size: 10.5px; line-height: 1.3; margin-top: 2px; }
.pax-grid input[data-f="taxable"], .pax-grid input[data-f="nonTaxable"] { background: var(--surface-3); }

.posting-preview { font-size: 12.5px; }
.posting-preview td { padding: 4px 8px; }
.posting-preview .acc { color: var(--text-2); }

.linked-box {
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius-sm);
  padding: 10px 13px;
  background: var(--surface-2);
  font-size: 12.5px;
  margin-bottom: 12px;
}

.kv-list { display: grid; grid-template-columns: auto 1fr; gap: 5px 14px; font-size: 13px; }
.kv-list dt { color: var(--text-3); font-weight: 600; }
.kv-list dd { margin: 0; }

.tabs { display: flex; gap: 3px; border-bottom: 1px solid var(--border); margin-bottom: 16px; flex-wrap: wrap; }
.tab {
  font: inherit; font-size: 13px; font-weight: 500;
  padding: 8px 15px; border: 0; background: none; cursor: pointer;
  color: var(--text-2); border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.tab:hover { color: var(--text); }
.tab.is-on { color: var(--brand-2); border-bottom-color: var(--brand); font-weight: 600; }

.help-note {
  font-size: 12.5px; color: var(--text-2);
  background: var(--brand-soft); border-left: 3px solid var(--brand);
  padding: 9px 13px; border-radius: var(--radius-sm); margin-bottom: 14px;
}

/* A stat card that is also a filter. Same shape as a read-only one, because
   it reports the same kind of thing — it just also does something. */
.stat-row--tight { gap: 8px; margin-bottom: 12px; }
.stat--button {
  font: inherit;
  text-align: left;
  cursor: pointer;
  border-left-color: var(--border-strong);
  transition: border-color .12s, background .12s;
}
.stat--button:hover { border-left-color: var(--brand); background: var(--surface-2); }
.stat--button.is-on { border-left-color: var(--brand); background: var(--brand-soft); }

/* ---------- icons ---------- */

/* Drawn in currentColor, so an icon is whatever colour the thing around it is
   — grey in a resting nav link, brand blue in the active one, white on a
   primary button. No second asset and no filters. */
.icon {
  flex: none;
  display: block;
  vertical-align: -0.18em;
  /* The strokes are drawn on a 24 grid and scaled down, so at 18px a 1.6
     stroke lands between pixels and greys out. Nudging it up keeps the line
     crisp at the size the sidebar actually uses. */
  stroke-width: 1.7;
}
.btn .icon, .dropdown .icon { margin-right: 2px; }
.btn--icon .icon { margin: 0; }
.nav-link .icon { stroke-width: 1.6; }
.nav-link.is-active .icon { stroke-width: 1.9; }

.btn--wide { justify-content: flex-start; }

.quick-tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 7px;
  padding: 14px 8px;
  height: 100%;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text-2);
  font-size: 11.5px;
  text-align: center;
  line-height: 1.3;
  transition: border-color .12s, color .12s, background .12s;
}
.quick-tile:hover {
  border-color: var(--brand-2);
  color: var(--brand-2);
  background: var(--brand-soft);
  text-decoration: none;
}
.quick-tile .icon { stroke-width: 1.5; }

/* ---------- command palette ---------- */

.palette {
  position: fixed;
  inset: 0;
  z-index: 200;
  background: rgba(16, 26, 40, .45);
  display: flex;
  justify-content: center;
  /* flex-start on both axes. Not centred vertically because the box grows
     downwards as results arrive, and a centred one would shift the first
     result out from under the cursor every time the list changed length —
     and not stretched, because a box the height of the screen holding two
     results looks broken. */
  align-items: flex-start;
  padding: 12vh 16px 16px;
}

.palette__box {
  width: min(640px, 100%);
  max-height: min(70vh, 560px);
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  box-shadow: var(--shadow-3);
  overflow: hidden;
}

.palette__input {
  font: inherit;
  font-size: 16px;
  padding: 15px 18px;
  border: 0;
  border-bottom: 1px solid var(--border);
  background: transparent;
  color: var(--text);
  width: 100%;
}
.palette__input:focus { outline: none; }
.palette__input::placeholder { color: var(--text-3); }

.palette__list { overflow-y: auto; padding: 6px; }

.palette__row {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 9px 12px;
  border-radius: var(--radius-sm);
  cursor: pointer;
  font-size: 13.5px;
}
.palette__row.is-on { background: var(--brand-soft); }
.palette__row.is-on .palette__label { color: var(--brand-2); font-weight: 600; }
.palette__icon { width: 20px; text-align: center; flex: none; }
.palette__label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.palette__hint { color: var(--text-3); font-size: 12px; flex: none; }
.palette__empty { padding: 22px; text-align: center; color: var(--text-3); font-size: 13px; }

.palette__foot {
  display: flex;
  gap: 16px;
  padding: 8px 16px;
  border-top: 1px solid var(--border);
  background: var(--surface-2);
  color: var(--text-3);
  font-size: 11.5px;
}

kbd {
  font: inherit;
  font-size: 11px;
  font-family: var(--mono);
  padding: 1px 5px;
  margin-right: 3px;
  border: 1px solid var(--border-strong);
  border-bottom-width: 2px;
  border-radius: 4px;
  background: var(--surface);
  color: var(--text-2);
}

/* The way in, for everyone who does not know the shortcut yet. Reads as a
   search box and behaves as a button, because that is what it is — the real
   input is the one inside the palette. */
.topbar__find {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 0 0 auto;
  width: 304px;
  padding: 6px 11px;
  font: inherit;
  font-size: 12.5px;
  color: var(--text-3);
  background: var(--surface-3);
  border: 1px solid var(--border);
  border-radius: 999px;
  cursor: pointer;
  text-align: left;
}
.topbar__find:hover { border-color: var(--brand-2); color: var(--text-2); }
.topbar__find span { flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.topbar__find kbd { margin-right: 0; }

/* Below this the label is competing with the company name for the same
   strip, and the company name wins. The button stays as the magnifier alone,
   which is still the thing people reach for. */
@media (max-width: 1100px) {
  .topbar__find { width: auto; }
  .topbar__find span, .topbar__find kbd { display: none; }
}

/* ---------- keyboard, motion and pointer ---------- */

/* :focus-visible rather than :focus, so a mouse click does not leave a ring
   behind on a button nobody is navigating to. Every interactive element is
   listed: a keyboard user who tabs into something that does not light up has
   lost their place on the page, and on a data-entry screen that means losing
   the row they were on. */
.btn:focus-visible,
.chip:focus-visible,
.tab:focus-visible,
.nav-link:focus-visible,
.input:focus-visible,
a:focus-visible,
select:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid transparent;      /* kept for forced-colours mode */
  outline-offset: 2px;
  box-shadow: var(--ring);
  border-radius: var(--radius-sm);
}

/* The input already carries its own tinted ring; this keeps the border in
   step with it rather than stacking a second, brighter one on top. */
.input:focus-visible { border-color: var(--brand-2); }

/* Money, everywhere it is read in a column. Proportional digits make a column
   of figures ragged, and a ragged column is one an eye cannot scan for the
   odd one out — which is most of what looking at a ledger is. */
.num, .stat__value, .tot strong, td.ta-right, th.ta-right {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

/* Someone who has asked their system to stop animating things has usually
   asked for a reason. Transitions become instant rather than merely faster:
   a 10ms transition is still a transition. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
  .btn:active { transform: none; }
}

/* Touch and pen: a 13px button is a comfortable mouse target and an awkward
   thumb one. Nothing moves on a desktop, where the pointer is fine. */
@media (pointer: coarse) {
  .btn { padding: 10px 16px; }
  .btn--sm { padding: 7px 12px; }
  .input { padding: 10px 12px; font-size: 15px; }   /* 15px+ stops iOS zooming on focus */
  .nav-link { padding-top: 10px; padding-bottom: 10px; }
  .tab { padding: 12px 16px; }
}

@media print {
  .app { display: block; height: auto; }
  .sidebar, .topbar, .brand-cell, .page-actions, .filter-bar, .no-print { display: none !important; }
  .main { padding: 0; overflow: visible; }
  .card { box-shadow: none; border: 0; }
}

/* ---------- entry grid ----------------------------------------------------
   The passenger grid is where an operator spends their day, so the running
   totals follow them down a long voucher rather than sitting at the bottom of
   a page they have scrolled past. */

.entry-total-bar--sticky {
  position: sticky;
  bottom: 0;
  z-index: 3;
  box-shadow: 0 -2px 10px rgba(16, 26, 40, .07);
}

.grid-foot {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  padding: 10px 16px;
  border-top: 1px solid var(--border);
}

.pax-grid .input--sm { padding: 4px 6px; font-size: 12px; }

/* A row the software has something to say about. Tinted rather than outlined:
   an outline on one row of twenty moves the others by a pixel, and a grid that
   twitches while you type it is a grid people stop reading. */
.table tr.row--warn > td { background: color-mix(in srgb, var(--warn) 7%, transparent); }
.table tr.row--warn > td:first-child { box-shadow: inset 3px 0 0 var(--warn); }

/* Every line's complaint, against the line it belongs to, each one a link
   that puts the cursor in the row. */
.problem-list { margin: 0; padding-left: 18px; line-height: 1.75; font-size: 13px; }
.problem-list li { margin-bottom: 2px; }

.linkish {
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  font-weight: 700;
  color: var(--brand-2);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.linkish:hover { color: var(--brand); }

/* ---------- ticket register ---------- */

.table tr.is-open td { background: color-mix(in srgb, var(--warn) 4%, transparent); }

/* The caption over a statutory register, naming it as the tax office does. */
.book-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  padding: 12px 16px;
  border-bottom: 1px solid var(--border);
}
.book-head h3 { margin: 0; font-size: 13px; letter-spacing: .6px; }

.card--ok { border-left: 3px solid var(--ok); }

/* ---------- sync indicator ------------------------------------------------
   The books live on this machine and on the server, and the honest state of
   that is worth one small light rather than a screen. Green when everything
   here has reached the server, amber while something is waiting, red when the
   server has refused something and a person needs to look. */

.topbar__sync {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: none;
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 3px 10px 3px 8px;
  font: inherit;
  font-size: 12px;
  color: var(--text-2);
  cursor: pointer;
  white-space: nowrap;
}
.topbar__sync:hover { border-color: var(--border-strong); color: var(--text); }
.topbar__sync-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--ok);
  flex: none;
}
.topbar__sync[data-state="queued"] .topbar__sync-dot { background: var(--warn); }
.topbar__sync[data-state="error"]  .topbar__sync-dot { background: var(--err); }
.topbar__sync[data-state="offline"] .topbar__sync-dot { background: var(--text-3); }
.topbar__sync[data-state="busy"] .topbar__sync-dot {
  background: var(--brand-2);
  animation: sync-pulse 1.1s ease-in-out infinite;
}
@keyframes sync-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .25; } }

/* Below about 900px the topbar is already fighting for room, and the dot on
   its own still answers the only urgent question. */
@media (max-width: 900px) { .topbar__sync-text { display: none; } }
