/* ==========================================================================
   Tervra typefaces
   --------------------------------------------------------------------------
   Shipped as files, not borrowed from the operating system.

   Tervra previously set its display and money type in "Iowan Old Style", and
   its interface in -apple-system. Neither is a typeface; both are requests
   that the operating system supply one. The result was that Tervra's hero
   numerals rendered in Iowan on a Mac, Palatino Linotype on Windows and
   something else again on Linux, and the interface rendered in SF, Segoe and
   Roboto respectively. Three different products wearing one name — and the
   system stack in particular is the single most reliable visual signature of
   software that was generated rather than designed.

   All three families below are SIL Open Font License 1.1, which permits
   commercial redistribution. Licence texts sit beside the files.

   Source Serif 4 — Adobe. Money and display. A working text serif with the
     weight of a printed financial document, and proper tabular lining
     figures, which is the whole reason it is here.
   Public Sans — US Web Design System, a Libre Franklin fork. Interface.
     Institutional rather than fashionable; it does not look like a startup.
   IBM Plex Mono — identifiers only. See the mono rule in the type scale.
   ========================================================================== */
@font-face {
  font-family: "Tervra Serif";
  src: url("/fonts/SourceSerif4Variable-Roman.woff2") format("woff2-variations"),
       url("/fonts/SourceSerif4Variable-Roman.woff2") format("woff2");
  font-weight: 200 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Tervra Serif";
  src: url("/fonts/SourceSerif4Variable-Italic.woff2") format("woff2-variations"),
       url("/fonts/SourceSerif4Variable-Italic.woff2") format("woff2");
  font-weight: 200 900;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: "Tervra Sans";
  src: url("/fonts/PublicSans-Regular.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Tervra Sans";
  src: url("/fonts/PublicSans-Medium.woff2") format("woff2");
  font-weight: 500; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Tervra Sans";
  src: url("/fonts/PublicSans-SemiBold.woff2") format("woff2");
  font-weight: 600; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Tervra Sans";
  src: url("/fonts/PublicSans-Bold.woff2") format("woff2");
  font-weight: 700; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Tervra Mono";
  src: url("/fonts/IBMPlexMono-Regular.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Tervra Mono";
  src: url("/fonts/IBMPlexMono-Medium.woff2") format("woff2");
  font-weight: 500; font-style: normal; font-display: swap;
}

/* ==========================================================================
   Tervra design system

   Brand direction: private-banking restraint meeting modern fintech clarity.
   Deep ink ground, warm brass accent, one serif for identity and figures,
   one grotesque for interface text. No gradients-as-decoration, no drop
   shadows doing the work that hierarchy should do.

   Everything is a token. There are no inline styles anywhere in this app -
   that is what lets the Content-Security-Policy stay strict.
   ========================================================================== */

:root {
  /* Ink scale - the ground the product sits on */
  --ink-950: #080b12;
  --ink-900: #0d111a;
  --ink-850: #121824;
  --ink-800: #18202e;
  --ink-700: #222c3d;
  --ink-600: #33405a;
  --ink-500: #4b5b78;
  --ink-400: #6c7e9c;
  --ink-300: #94a3bd;
  --ink-200: #c2ccdb;
  --ink-100: #e3e8f0;
  --ink-050: #f4f6fa;

  /* Brass - the single accent. Used sparingly, for what matters. */
  --brass-600: #8a6a2f;
  --brass-500: #b08d46;
  --brass-400: #c9a765;
  --brass-300: #e0c893;
  --brass-100: #f3e8cf;

  /* Semantic */
  --positive-600: #1a6b4a;
  --positive-400: #35a878;
  --positive-100: #dff2e8;
  --caution-600: #8a5a12;
  --caution-400: #d4922b;
  --caution-100: #fbeed6;
  --critical-600: #8f2033;
  --critical-400: #cf4257;
  --critical-100: #fbe0e4;
  --info-600: #1f4f7a;
  --info-400: #3f86c4;
  --info-100: #dcecfa;

  /* Surfaces (light) */
  --bg: var(--ink-050);
  --surface: #ffffff;
  --surface-raised: #ffffff;
  --surface-sunken: #eef1f7;
  --border: #dde3ec;
  --border-strong: #c3ccda;
  --text: var(--ink-900);
  --text-muted: var(--ink-500);
  --text-subtle: var(--ink-400);
  --accent: var(--brass-600);
  --accent-soft: var(--brass-100);
  --focus: #2f6fd0;

  /* Type.
     The fallbacks exist for the moment before the files load, and are chosen
     to be metrically close so text does not jump. They are not the design. */
  --font-display: "Tervra Serif", "Source Serif 4", Georgia, serif;
  --font-sans: "Tervra Sans", "Libre Franklin", "Segoe UI", system-ui, sans-serif;
  --font-mono: "Tervra Mono", "IBM Plex Mono", ui-monospace, Consolas, monospace;

  /* A scale with intent rather than three sizes doing everything.
     Tervra's old interface set 380 of its ~400 elements at 15px, 13px and
     11px, which left weight and colour carrying all of the hierarchy. */
  --step--2: 0.6875rem;   /* 11px  — legal, footnote, column head */
  --step--1: 0.78125rem;  /* 12.5px — metadata, reference, secondary */
  --step-0: 0.875rem;     /* 14px  — body, the default */
  --step-1: 1rem;         /* 16px  — emphasised body, row primary */
  --step-2: 1.25rem;      /* 20px  — money in a row, sub-head */
  --step-3: 1.625rem;     /* 26px  — section display */
  --step-4: 2.25rem;      /* 36px  — page display */
  --step-5: 3.25rem;      /* 52px  — the single hero figure */

  /* The label. Tervra's one piece of typographic furniture: small, spaced,
     upper case, used for every field name in the product and on every
     document. It is what makes a Tervra screen and a Tervra statement look
     like they came from the same institution. */
  --label-size: 0.6875rem;
  --label-tracking: 0.1em;
  --label-weight: 600;

  /* Space */
  --s-1: 0.25rem;
  --s-2: 0.5rem;
  --s-3: 0.75rem;
  --s-4: 1rem;
  --s-5: 1.5rem;
  --s-6: 2rem;
  --s-7: 3rem;
  --s-8: 4rem;

  /* Three radii, and they are small. Tervra is a document, not an app icon:
     heavy rounding is the single strongest signal of a generated interface.
     999px pills and 14px cards were both removed for this reason. */
  --radius-sm: 2px;
  --radius: 4px;
  --radius-lg: 6px;

  --shadow-sm: 0 1px 2px rgba(13, 17, 26, 0.06);
  --shadow: 0 2px 8px rgba(13, 17, 26, 0.08);
  --shadow-lg: 0 12px 40px rgba(13, 17, 26, 0.16);

  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  --sidebar-w: 250px;
}

[data-theme="dark"] {
  --bg: var(--ink-950);
  --surface: var(--ink-900);
  --surface-raised: var(--ink-850);
  --surface-sunken: var(--ink-950);
  --border: #1f2937;
  --border-strong: #2c3a4f;
  --text: var(--ink-050);
  --text-muted: var(--ink-300);
  --text-subtle: var(--ink-400);
  --accent: var(--brass-400);
  --accent-soft: rgba(201, 167, 101, 0.12);
  --positive-100: rgba(53, 168, 120, 0.14);
  --caution-100: rgba(212, 146, 43, 0.14);
  --critical-100: rgba(207, 66, 87, 0.16);
  --info-100: rgba(63, 134, 196, 0.14);
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
  --shadow: 0 2px 10px rgba(0, 0, 0, 0.45);
  --shadow-lg: 0 16px 48px rgba(0, 0, 0, 0.6);
}

/* --------------------------------------------------------------------------
   Reset
   -------------------------------------------------------------------------- */
*,
*::before,
*::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--step-0);
  line-height: 1.55;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  font-feature-settings: "kern" 1;
}

h1, h2, h3, h4 { margin: 0; font-weight: 600; line-height: 1.2; }
p { margin: 0 0 var(--s-3); }
a { color: inherit; }

button, input, select, textarea { font: inherit; color: inherit; }

:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

::selection { background: var(--accent-soft); }

/* --------------------------------------------------------------------------
   Typography helpers
   -------------------------------------------------------------------------- */
.display { font-family: var(--font-display); font-weight: 400; letter-spacing: -0.01em; }
.figure {
  font-family: var(--font-display);
  font-variant-numeric: tabular-nums lining-nums;
  letter-spacing: -0.015em;
}
.mono { font-family: var(--font-mono); font-size: 0.92em; }
.muted { color: var(--text-muted); }
.subtle { color: var(--text-subtle); }
.tiny { font-size: var(--step--2); }
.small { font-size: var(--step--1); }
.eyebrow {
  font-size: var(--step--2);
  text-transform: uppercase;
  letter-spacing: 0.11em;
  font-weight: 600;
  color: var(--text-subtle);
}
.numeric { font-variant-numeric: tabular-nums; }

/* --------------------------------------------------------------------------
   Shell
   -------------------------------------------------------------------------- */
.shell { display: flex; min-height: 100vh; }

.sidebar {
  width: var(--sidebar-w);
  flex: 0 0 var(--sidebar-w);
  background: var(--ink-950);
  color: var(--ink-200);
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
  border-right: 1px solid rgba(255, 255, 255, 0.06);
}

.brand {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-5) var(--s-5) var(--s-4);
}
.brand-mark {
  /* The symbol is drawn, not lettered. It carries its own proportion, so the
     only job here is colour and optical alignment with the wordmark. */
  width: 34px;
  height: 34px;
  color: var(--brass-300);
  flex-shrink: 0;
}
.brand-name {
  font-family: var(--font-display);
  font-size: var(--step-1);
  letter-spacing: 0.06em;
  color: #fff;
}
.brand-sub { font-size: var(--step--2); color: var(--ink-400); letter-spacing: 0.06em; }

.nav { padding: var(--s-2) var(--s-3); flex: 1; overflow-y: auto; }
.nav-group { margin-bottom: var(--s-5); }
.nav-group > .eyebrow { padding: 0 var(--s-3) var(--s-2); color: var(--ink-500); }

.nav-item {
  display: flex; align-items: center; gap: var(--s-3);
  width: 100%;
  padding: var(--s-2) var(--s-3);
  margin-bottom: 1px;
  background: none; border: 0;
  border-radius: var(--radius-sm);
  color: var(--ink-300);
  text-align: left;
  cursor: pointer;
  font-size: var(--step--1);
  transition: background 140ms var(--ease), color 140ms var(--ease);
}
.nav-item:hover { background: rgba(255, 255, 255, 0.05); color: #fff; }
.nav-item[aria-current="page"] {
  background: rgba(201, 167, 101, 0.13);
  color: var(--brass-300);
  font-weight: 600;
}
.nav-item .glyph { width: 18px; text-align: center; opacity: 0.85; }
.nav-badge {
  margin-left: auto;
  background: var(--critical-400);
  color: #fff;
  border-radius: 999px;
  padding: 0 6px;
  font-size: var(--step--2);
  font-weight: 700;
}

.sidebar-foot {
  padding: var(--s-4) var(--s-5);
  border-top: 1px solid rgba(255, 255, 255, 0.07);
  font-size: var(--step--2);
  color: var(--ink-400);
}

.main { flex: 1; min-width: 0; display: flex; flex-direction: column; }

.topbar {
  display: flex; align-items: center; gap: var(--s-4);
  padding: var(--s-4) var(--s-6);
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  position: sticky; top: 0; z-index: 20;
}
.topbar h1 { font-size: var(--step-2); font-family: var(--font-display); font-weight: 400; }
.topbar .spacer { flex: 1; }

.content { padding: var(--s-6); max-width: 1360px; width: 100%; }

/* --------------------------------------------------------------------------
   Environment banner - always visible, never dismissible
   -------------------------------------------------------------------------- */
.env-banner {
  display: flex; align-items: center; gap: var(--s-3);
  padding: var(--s-2) var(--s-6);
  background: var(--caution-100);
  color: var(--caution-600);
  border-bottom: 1px solid var(--border);
  font-size: var(--step--1);
  font-weight: 500;
}
.env-banner strong { font-weight: 700; }
.env-banner .dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--caution-400);
  flex: 0 0 auto;
}

/* --------------------------------------------------------------------------
   Cards and layout
   -------------------------------------------------------------------------- */
.grid { display: grid; gap: var(--s-4); }
.grid.cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid.cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid.cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.grid.sidebar-right { grid-template-columns: minmax(0, 2fr) minmax(280px, 1fr); }

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
}
.card-head {
  display: flex; align-items: baseline; gap: var(--s-3);
  padding: var(--s-4) var(--s-5);
  border-bottom: 1px solid var(--border);
}
.card-head h2 { font-size: var(--step-1); font-weight: 600; }
.card-head .spacer { flex: 1; }
.card-body { padding: var(--s-5); }
.card-body.tight { padding: var(--s-3) var(--s-5); }
.card-foot {
  padding: var(--s-3) var(--s-5);
  border-top: 1px solid var(--border);
  background: var(--surface-sunken);
  border-radius: 0 0 var(--radius) var(--radius);
  font-size: var(--step--1);
}

.stack > * + * { margin-top: var(--s-4); }
.stack-sm > * + * { margin-top: var(--s-2); }
.row { display: flex; align-items: center; gap: var(--s-3); }
.row.wrap { flex-wrap: wrap; }
.row .spacer { flex: 1; }

/* --------------------------------------------------------------------------
   Balance and figures
   -------------------------------------------------------------------------- */
.balance-card { position: relative; overflow: hidden; }
.balance-card::before {
  content: "";
  position: absolute; inset: 0 auto 0 0; width: 3px;
  background: var(--accent);
}
.balance-amount {
  font-family: var(--font-display);
  font-size: var(--step-4);
  font-variant-numeric: tabular-nums lining-nums;
  letter-spacing: -0.02em;
  line-height: 1.05;
}
.balance-amount.sm { font-size: var(--step-3); }
.balance-meta { display: flex; gap: var(--s-5); margin-top: var(--s-3); }
.balance-meta div { font-size: var(--step--1); }
.balance-meta .value { font-variant-numeric: tabular-nums; font-weight: 600; }

.stat { padding: var(--s-4) var(--s-5); }
.stat .label {
  font-size: var(--step--2);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--text-subtle);
  font-weight: 600;
}
.stat .value {
  font-family: var(--font-display);
  font-size: var(--step-3);
  font-variant-numeric: tabular-nums;
  margin-top: var(--s-1);
}
.stat .value.critical { color: var(--critical-600); }
.stat .value.positive { color: var(--positive-600); }
.stat .value.caution { color: var(--caution-600); }
.stat .note { font-size: var(--step--2); color: var(--text-subtle); }

/* --------------------------------------------------------------------------
   Tables
   -------------------------------------------------------------------------- */
.table-wrap { overflow-x: auto; }
table.data { width: 100%; border-collapse: collapse; font-size: var(--step--1); }
table.data th {
  text-align: left;
  font-size: var(--step--2);
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--text-subtle);
  font-weight: 600;
  padding: var(--s-2) var(--s-4);
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
table.data td {
  padding: var(--s-3) var(--s-4);
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
}
table.data tbody tr { transition: background 120ms var(--ease); }
table.data tbody tr:hover { background: var(--surface-sunken); }
table.data tbody tr:last-child td { border-bottom: 0; }
table.data td.num, table.data th.num {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
table.data td.num.out { color: var(--text); }
table.data td.num.in { color: var(--positive-600); font-weight: 600; }
table.data tr.clickable { cursor: pointer; }

.empty {
  padding: var(--s-7) var(--s-5);
  text-align: center;
  color: var(--text-subtle);
}
.empty .glyph { font-size: var(--step-3); opacity: 0.4; display: block; margin-bottom: var(--s-2); }

/* --------------------------------------------------------------------------
   Pills and badges
   -------------------------------------------------------------------------- */
.pill {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 9px;
  border-radius: var(--radius-sm);
  font-size: var(--step--2);
  font-weight: 600;
  letter-spacing: 0.02em;
  white-space: nowrap;
  background: var(--surface-sunken);
  color: var(--text-muted);
  border: 1px solid var(--border);
}
.pill::before {
  content: ""; width: 6px; height: 6px; border-radius: 50%;
  background: currentColor; opacity: 0.75;
}
.pill.positive { background: var(--positive-100); color: var(--positive-600); border-color: transparent; }
.pill.caution  { background: var(--caution-100);  color: var(--caution-600);  border-color: transparent; }
.pill.critical { background: var(--critical-100); color: var(--critical-600); border-color: transparent; }
.pill.info     { background: var(--info-100);     color: var(--info-600);     border-color: transparent; }
.pill.plain::before { display: none; }

/* --------------------------------------------------------------------------
   Buttons
   -------------------------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s-2);
  padding: 0.5rem 1rem;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border-strong);
  background: var(--surface);
  color: var(--text);
  font-size: var(--step--1);
  font-weight: 600;
  cursor: pointer;
  transition: background 140ms var(--ease), border-color 140ms var(--ease),
    transform 90ms var(--ease), opacity 140ms var(--ease);
}
.btn:hover { background: var(--surface-sunken); }
.btn:active { transform: translateY(1px); }
.btn[disabled] { opacity: 0.5; cursor: not-allowed; }

.btn.primary {
  background: var(--ink-900);
  border-color: var(--ink-900);
  color: #fff;
}
.btn.primary:hover { background: var(--ink-800); border-color: var(--ink-800); }

.btn.accent {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}
.btn.accent:hover { filter: brightness(1.07); }

.btn.danger { color: var(--critical-600); border-color: var(--critical-400); }
.btn.danger:hover { background: var(--critical-100); }
.btn.ghost { border-color: transparent; background: transparent; }
.btn.ghost:hover { background: var(--surface-sunken); }
.btn.sm { padding: 0.3rem 0.65rem; font-size: var(--step--2); }
.btn.block { width: 100%; }

/* --------------------------------------------------------------------------
   Forms
   -------------------------------------------------------------------------- */
.field { margin-bottom: var(--s-4); }
.field label {
  display: block;
  font-size: var(--step--1);
  font-weight: 600;
  margin-bottom: var(--s-1);
}
.field .hint { font-size: var(--step--2); color: var(--text-subtle); margin-top: var(--s-1); }
.field .error { font-size: var(--step--2); color: var(--critical-600); margin-top: var(--s-1); }

.input, select.input, textarea.input {
  width: 100%;
  padding: 0.55rem 0.7rem;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  transition: border-color 140ms var(--ease), box-shadow 140ms var(--ease);
}
.input:focus {
  border-color: var(--focus);
  box-shadow: 0 0 0 3px rgba(47, 111, 208, 0.15);
  outline: none;
}
.input[aria-invalid="true"] { border-color: var(--critical-400); }
.input.amount {
  font-family: var(--font-display);
  font-size: var(--step-2);
  font-variant-numeric: tabular-nums;
}
textarea.input { min-height: 5rem; resize: vertical; }

.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s-3); }

/* --------------------------------------------------------------------------
   Notices
   -------------------------------------------------------------------------- */
.notice {
  display: flex; gap: var(--s-3);
  padding: var(--s-3) var(--s-4);
  border-radius: var(--radius-sm);
  border-left: 3px solid var(--info-400);
  background: var(--info-100);
  color: var(--info-600);
  font-size: var(--step--1);
}
.notice.caution  { border-color: var(--caution-400);  background: var(--caution-100);  color: var(--caution-600); }
.notice.critical { border-color: var(--critical-400); background: var(--critical-100); color: var(--critical-600); }
.notice.positive { border-color: var(--positive-400); background: var(--positive-100); color: var(--positive-600); }
.notice .glyph { flex: 0 0 auto; }
.notice ul { margin: var(--s-2) 0 0; padding-left: 1.1rem; }

/* --------------------------------------------------------------------------
   Modal
   -------------------------------------------------------------------------- */
.modal-backdrop {
  position: fixed; inset: 0;
  background: rgba(8, 11, 18, 0.55);
  display: grid; place-items: center;
  padding: var(--s-4);
  z-index: 100;
  animation: fade 160ms var(--ease);
}
.modal {
  background: var(--surface);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  width: min(560px, 100%);
  max-height: 88vh;
  overflow: auto;
  animation: rise 200ms var(--ease);
}
.modal-head { padding: var(--s-5) var(--s-5) var(--s-3); }
.modal-head h2 { font-family: var(--font-display); font-size: var(--step-2); font-weight: 400; }
.modal-body { padding: 0 var(--s-5) var(--s-4); }
.modal-foot {
  display: flex; gap: var(--s-3); justify-content: flex-end;
  padding: var(--s-4) var(--s-5);
  border-top: 1px solid var(--border);
}

@keyframes fade { from { opacity: 0; } }
@keyframes rise { from { opacity: 0; transform: translateY(10px) scale(0.99); } }

/* --------------------------------------------------------------------------
   Toasts
   -------------------------------------------------------------------------- */
.toasts {
  position: fixed; right: var(--s-5); bottom: var(--s-5);
  display: flex; flex-direction: column; gap: var(--s-2);
  z-index: 200;
  max-width: 380px;
}
.toast {
  padding: var(--s-3) var(--s-4);
  border-radius: var(--radius-sm);
  background: var(--ink-900);
  color: #fff;
  font-size: var(--step--1);
  box-shadow: var(--shadow-lg);
  animation: rise 180ms var(--ease);
}
.toast.critical { background: var(--critical-600); }
.toast.positive { background: var(--positive-600); }

/* --------------------------------------------------------------------------
   Auth screen
   -------------------------------------------------------------------------- */
.auth {
  min-height: 100vh;
  display: grid;
  grid-template-columns: 1.1fr 1fr;
  background: var(--ink-950);
}
.auth-aside {
  padding: var(--s-8) var(--s-7);
  color: var(--ink-200);
  display: flex; flex-direction: column; justify-content: space-between;
  border-right: 1px solid rgba(255, 255, 255, 0.06);
}
.auth-aside h2 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--step-5);
  line-height: 1.1;
  color: #fff;
  max-width: 12ch;
}
.auth-aside .lede { max-width: 42ch; color: var(--ink-300); margin-top: var(--s-4); }
.auth-points { list-style: none; padding: 0; margin: var(--s-6) 0 0; }
.auth-points li {
  padding: var(--s-2) 0 var(--s-2) var(--s-5);
  position: relative;
  color: var(--ink-300);
  font-size: var(--step--1);
  border-top: 1px solid rgba(255, 255, 255, 0.06);
}
.auth-points li::before {
  content: "—";
  position: absolute; left: 0; color: var(--brass-400);
}
.auth-panel {
  background: var(--surface);
  display: grid; place-items: center;
  padding: var(--s-6);
}
.auth-form { width: min(380px, 100%); }
.auth-form h1 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--step-3);
  margin-bottom: var(--s-2);
}

.demo-logins {
  margin-top: var(--s-5);
  padding-top: var(--s-4);
  border-top: 1px solid var(--border);
}
.demo-logins button {
  display: block; width: 100%; text-align: left;
  padding: var(--s-2) var(--s-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-sunken);
  margin-bottom: var(--s-2);
  cursor: pointer;
  font-size: var(--step--2);
}
.demo-logins button:hover { border-color: var(--accent); }

/* --------------------------------------------------------------------------
   Detail lists
   -------------------------------------------------------------------------- */
.detail-list { display: grid; grid-template-columns: max-content 1fr; gap: var(--s-2) var(--s-5); }
.detail-list dt { font-size: var(--step--1); color: var(--text-subtle); }
.detail-list dd { margin: 0; font-size: var(--step--1); }

.timeline { list-style: none; padding: 0; margin: 0; }
.timeline li {
  position: relative;
  padding: 0 0 var(--s-4) var(--s-5);
  border-left: 1px solid var(--border);
}
.timeline li:last-child { border-left-color: transparent; padding-bottom: 0; }
.timeline li::before {
  content: ""; position: absolute; left: -4px; top: 5px;
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--border-strong);
}
.timeline li.done::before { background: var(--positive-400); }
.timeline li.current::before { background: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.timeline .when { font-size: var(--step--2); color: var(--text-subtle); }

/* --------------------------------------------------------------------------
   Utility
   -------------------------------------------------------------------------- */
/* A quiet pulse rather than a sweeping shimmer. The shimmer gradient is the
   single most recognisable loading treatment in generated interfaces, and it
   implies content is arriving in a shape it may not arrive in. */
.skeleton {
  background: var(--surface-sunken);
  animation: settle 1.6s ease-in-out infinite;
  border-radius: var(--radius-sm);
  height: 1rem;
}
@keyframes settle {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.55; }
}

@media (prefers-reduced-motion: reduce) {
  .skeleton { animation: none; }
}

.hidden { display: none !important; }
.text-right { text-align: right; }
.divider { height: 1px; background: var(--border); margin: var(--s-4) 0; }

/* --------------------------------------------------------------------------
   Responsive
   -------------------------------------------------------------------------- */
@media (max-width: 1080px) {
  .grid.cols-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .grid.cols-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .grid.sidebar-right { grid-template-columns: minmax(0, 1fr); }
  .auth { grid-template-columns: 1fr; }
  .auth-aside { display: none; }
}

@media (max-width: 780px) {
  :root { --sidebar-w: 100%; }
  .shell { flex-direction: column; }
  .sidebar {
    position: static; height: auto; width: 100%; flex: none;
    flex-direction: row; align-items: center; overflow-x: auto;
    border-right: 0; border-bottom: 1px solid rgba(255, 255, 255, 0.08);
  }
  .brand { padding: var(--s-3) var(--s-4); flex: 0 0 auto; }
  .brand-sub { display: none; }
  .nav { display: flex; gap: var(--s-1); padding: var(--s-2); overflow-x: auto; }
  .nav-group { display: flex; margin: 0; }
  .nav-group > .eyebrow { display: none; }
  .nav-item { white-space: nowrap; width: auto; }
  .sidebar-foot { display: none; }
  .content { padding: var(--s-4); }
  .topbar { padding: var(--s-3) var(--s-4); }
  .grid.cols-2, .grid.cols-3, .grid.cols-4 { grid-template-columns: minmax(0, 1fr); }
  .field-row { grid-template-columns: 1fr; }
  /* Only what a column declared droppable.
     This was `nth-child(n + 4)`, which hid Status and Amount on the payments
     list — a payment list with neither is not a payment list. */
  table.data th.optional,
  table.data td.optional { display: none; }
  .toasts { left: var(--s-4); right: var(--s-4); max-width: none; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

@media print {
  .sidebar, .topbar, .btn, .toasts { display: none !important; }
  .content { padding: 0; }
  .card { border: 1px solid #ccc; box-shadow: none; }
}


/* --------------------------------------------------------------------------
   Icons — one family, one stroke weight, aligned to the text baseline
   -------------------------------------------------------------------------- */
.icon {
  display: inline-block;
  vertical-align: -0.16em;
  flex: 0 0 auto;
  color: currentColor;
}
.nav-item .icon { opacity: 0.9; }
.nav-item[aria-current="page"] .icon { opacity: 1; }
.btn .icon { margin-right: -0.15em; }
.notice .icon { margin-top: 0.15em; }

/* --------------------------------------------------------------------------
   Joining journey
   -------------------------------------------------------------------------- */
.join {
  max-width: 780px;
  margin: 0 auto;
}
.join-head { margin-bottom: var(--s-6); }
.join-head h2 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--step-3);
  margin-bottom: var(--s-2);
}
.join-head p { color: var(--text-muted); max-width: 56ch; }

/* The step rail: named steps with real state, never a percentage. */
.rail { list-style: none; margin: 0 0 var(--s-6); padding: 0; display: grid; gap: 1px;
  background: var(--border); border: 1px solid var(--border);
  border-radius: var(--radius); overflow: hidden; }
.rail li {
  display: grid;
  grid-template-columns: 26px 1fr auto;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-3) var(--s-4);
  background: var(--surface);
  font-size: var(--step--1);
}
.rail li .mark {
  width: 22px; height: 22px; border-radius: 50%;
  display: grid; place-items: center;
  border: 1px solid var(--border-strong);
  color: var(--text-subtle);
}
.rail li.done .mark { background: var(--positive-100); border-color: transparent;
  color: var(--positive-600); }
.rail li.current { background: var(--accent-soft); }
.rail li.current .mark { border-color: var(--accent); color: var(--accent); }
.rail li .who { color: var(--text-subtle); font-size: var(--step--2); }

/* Company search */
.company-search { position: relative; }
.company-results {
  list-style: none; margin: var(--s-2) 0 0; padding: 0;
  border: 1px solid var(--border); border-radius: var(--radius);
  overflow: hidden;
}
.company-results li + li { border-top: 1px solid var(--border); }
.company-result {
  display: grid; grid-template-columns: 24px 1fr auto; gap: var(--s-3);
  align-items: start;
  width: 100%; text-align: left; padding: var(--s-3) var(--s-4);
  background: var(--surface); border: 0; cursor: pointer;
  transition: background 120ms var(--ease);
}
.company-result:hover { background: var(--surface-sunken); }
.company-result .name { font-weight: 600; }
.company-result .meta { font-size: var(--step--2); color: var(--text-subtle); }

/* The "we found your company" panel */
.found {
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius);
  padding: var(--s-5);
  background: var(--surface);
}
.found h3 { font-family: var(--font-display); font-weight: 400;
  font-size: var(--step-2); margin-bottom: var(--s-1); }
.found .company-number { font-family: var(--font-mono); font-size: var(--step--1);
  color: var(--text-muted); }
.found-facts { display: grid; grid-template-columns: repeat(2, minmax(0,1fr));
  gap: var(--s-3) var(--s-5); margin-top: var(--s-4); }
.found-facts .label { font-size: var(--step--2); color: var(--text-subtle);
  text-transform: uppercase; letter-spacing: 0.08em; }
.found-people { margin-top: var(--s-4); border-top: 1px solid var(--border);
  padding-top: var(--s-4); }
.found-people li { display: flex; align-items: center; gap: var(--s-2);
  padding: var(--s-1) 0; font-size: var(--step--1); }

.source-note {
  margin-top: var(--s-3); font-size: var(--step--2); color: var(--text-subtle);
  display: flex; align-items: center; gap: var(--s-2);
}

@media (max-width: 640px) {
  .found-facts { grid-template-columns: 1fr; }
  .rail li { grid-template-columns: 22px 1fr; }
  .rail li .who { grid-column: 2; }
}

/* --- Money states: the arithmetic, shown ------------------------------- */
.workings {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-top: var(--space-3);
}
.workings-row,
.workings-total {
  display: flex;
  justify-content: space-between;
  gap: var(--space-4);
  font-variant-numeric: tabular-nums;
}
.workings-row { color: var(--text-muted); }
.workings-total {
  border-top: 1px solid var(--border);
  padding-top: var(--space-2);
  font-weight: 600;
  color: var(--text);
}

.list-row {
  display: flex;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--border);
}
.list-row:last-child { border-bottom: none; }

/* A limit meter. Amber only near the top, because a bar that is always
   coloured tells nobody anything. */
.meter {
  height: 4px;
  border-radius: 2px;
  background: var(--border);
  overflow: hidden;
  margin-top: var(--space-1);
}
.meter-fill {
  height: 100%;
  background: var(--accent);
  transition: width var(--motion-slow) var(--ease);
}
.meter-fill.warn { background: var(--caution-400); }

/* Ordinary declines are calm. Only genuine security events are loud. */
.warn-text { color: var(--caution-600); }
.filters { align-items: flex-end; gap: var(--space-3); }
.filters .field { margin: 0; min-width: 9rem; }

/* Two-factor set-up.
 *
 * The key is read off the screen and typed into a phone, so it is spaced and
 * selectable rather than pretty. Recovery codes are the same job: transcribed
 * once, under mild stress, and never seen again. */
.secret-key {
  font-family: var(--font-mono);
  font-size: var(--step-1);
  letter-spacing: 0.12em;
  word-break: break-all;
  user-select: all;
  padding: var(--space-3);
  margin: var(--space-3) 0;
  border: 1px solid var(--border);
  background: var(--surface-sunken);
}

.plain-list { padding-left: 1.2em; margin: 0 0 var(--space-3); }
.plain-list li { margin-bottom: var(--space-2); }

.recovery-codes {
  list-style: none;
  padding: 0;
  margin: var(--space-3) 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
  gap: var(--space-2);
}
.recovery-codes li {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  letter-spacing: 0.06em;
  user-select: all;
  padding: var(--space-2);
  border: 1px solid var(--border);
}

/* ==========================================================================
   Tervra money
   --------------------------------------------------------------------------
   The most recognisable thing about a financial product should be the way it
   sets a number. These rules are Tervra's, and they appear identically in the
   application, on statements and in email.

   Rules:
   1. Money is always the serif. The interface is sans; money is not.
   2. Always tabular figures, so a column of amounts aligns on the decimal
      without any alignment code.
   3. The currency symbol is smaller and lifted — identification, not quantity.
   4. Pence are smaller and quieter than pounds. The eye reads £18,400 first
      and .00 second, which is the order a person actually wants. Pence are
      never removed.
   5. Negative is a true minus glyph in the text, not a colour. Colour is a
      second signal, never the only one.
   ========================================================================== */
.money {
  font-family: var(--font-display);
  font-variant-numeric: tabular-nums lining-nums;
  font-feature-settings: "tnum" 1, "lnum" 1;
  letter-spacing: -0.005em;
  white-space: nowrap;
}
.money-symbol {
  font-size: 0.78em;
  padding-right: 0.06em;
  vertical-align: 0.06em;
  color: var(--text-muted);
}
.money-sign {
  padding-right: 0.04em;
}
.money-point,
.money-minor {
  font-size: 0.72em;
  vertical-align: 0.04em;
  color: var(--text-muted);
}

/* Sizes. The hero is used once per screen — the answer to "what do I have".
   Everything else is subordinate to it by a clear step, not a nudge. */
.money-hero   { font-size: var(--step-5); line-height: 1; }
.money-figure { font-size: var(--step-3); line-height: 1.1; }
.money-row    { font-size: var(--step-2); line-height: 1.2; }
.money-inline { font-size: inherit; }

/* States. Weight, colour and one small mark — never eleven coloured badges.
   A reader distinguishes these without being taught the ledger vocabulary. */
.money-out .money-whole,
.money-out .money-sign { color: var(--text); }
.money-in .money-whole { color: var(--positive-600); }
.money-pending .money-whole,
.money-pending .money-symbol,
.money-pending .money-minor { color: var(--text-muted); }
.money-restricted { color: var(--text-muted); text-decoration: line-through
  var(--border-strong); text-decoration-thickness: 1px; }

/* ==========================================================================
   Tervra identifiers
   --------------------------------------------------------------------------
   Anything a person may need to read aloud, transcribe, or match against a
   piece of paper is set in the mono face: sort codes, account numbers,
   references, invoice numbers, property codes, statement ids.

   This is a functional rule before it is a stylistic one. A reference set in
   a proportional face invites a transcription error between 1 and l, 0 and O.
   It is also, repeated across every screen and every document, one of the
   things that makes a Tervra surface recognisable at a glance.
   ========================================================================== */
.ref {
  font-family: var(--font-mono);
  font-size: 0.92em;
  letter-spacing: 0.01em;
  font-variant-numeric: tabular-nums;
  color: var(--text-muted);
}
.ref-strong { color: var(--text); font-weight: 500; }

/* ==========================================================================
   The Tervra label
   --------------------------------------------------------------------------
   One piece of typographic furniture, used for every field name in the
   product and on every document.
   ========================================================================== */
.label {
  font-family: var(--font-sans);
  font-size: var(--label-size);
  font-weight: var(--label-weight);
  letter-spacing: var(--label-tracking);
  text-transform: uppercase;
  color: var(--text-muted);
}

/* ==========================================================================
   The Tervra ledger
   --------------------------------------------------------------------------
   Rows, not cards. A business owner scanning three weeks of activity is
   comparing amounts and counterparties, and comparison is what a list of
   aligned rows is for. Putting each transaction in its own rounded box makes
   them slower to read and takes four times the height.

   The only rules are horizontal hairlines between rows and a heavier one
   under each day. That is the whole decoration, and it is doing structural
   work rather than ornamental work.
   ========================================================================== */
.ledger-days { display: flex; flex-direction: column; }

.ledger-day-head {
  display: flex;
  align-items: baseline;
  gap: var(--s-3);
  padding: var(--s-5) 0 var(--s-2);
}
.ledger-day-rule {
  flex: 1;
  height: 1px;
  background: var(--border);
}

.txn {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--s-5);
  width: 100%;
  padding: var(--s-3) 0;
  border: 0;
  border-bottom: 1px solid var(--border);
  background: none;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
  transition: background-color 100ms ease;
}
.txn:hover { background: var(--surface-sunken); }
.txn:focus-visible { outline: 2px solid var(--focus); outline-offset: -2px; }

.txn-main { min-width: 0; }
.txn-who {
  font-size: var(--step-0);
  font-weight: 500;
  color: var(--text);
  overflow-wrap: anywhere;
}
.txn-context {
  font-size: var(--step--1);
  color: var(--text-muted);
  margin-top: 1px;
}
.txn-attribution {
  font-size: var(--step--1);
  color: var(--text-subtle);
  margin-top: 1px;
}

.txn-side {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 2px;
  flex-shrink: 0;
}
.txn-state {
  font-family: var(--font-sans);
  font-size: var(--label-size);
  font-weight: var(--label-weight);
  letter-spacing: var(--label-tracking);
  text-transform: uppercase;
  color: var(--text-muted);
}

/* Money that did not move is stated, not struck through in red. A declined
   card payment is an event the customer needs to see, not an alarm. */
.txn-void .txn-who { color: var(--text-muted); }
.txn-void .money { opacity: 0.55; }

/* ==========================================================================
   Controls
   --------------------------------------------------------------------------
   A browser-default select is the most reliable tell that nobody looked at a
   screen. These are the same square, hairlined shapes as the rest of Tervra,
   which is the point: a field, a table cell and a statement column should all
   look as though one person drew them.
   ========================================================================== */
.input,
select.input,
textarea.input {
  font-family: var(--font-sans);
  font-size: var(--step-0);
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: 2px;
  padding: 0.5rem 0.625rem;
  width: 100%;
  transition: border-color 120ms ease, box-shadow 120ms ease;
  appearance: none;
  -webkit-appearance: none;
}
.input::placeholder { color: var(--text-subtle); }
.input:hover { border-color: var(--text-subtle); }
.input:focus,
.input:focus-visible {
  outline: none;
  border-color: var(--accent);
  /* A ring rather than a glow: one crisp line, no blur, no colour wash. */
  box-shadow: 0 0 0 2px var(--accent-soft);
}
.input:disabled {
  background: var(--surface-sunken);
  color: var(--text-subtle);
  cursor: not-allowed;
}

/* The chevron is drawn, not borrowed from the platform, so the control looks
   identical on Windows, macOS and Linux. */
select.input {
  padding-right: 2rem;
  background-image:
    linear-gradient(45deg, transparent 50%, currentColor 50%),
    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position:
    calc(100% - 1.05rem) calc(50% + 1px),
    calc(100% - 0.75rem) calc(50% + 1px);
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  color: var(--text);
}

/* Money inputs get the money treatment, so what you type looks like what you
   will be shown afterwards. */
.input-money {
  font-family: var(--font-display);
  font-variant-numeric: tabular-nums;
  font-size: var(--step-2);
  text-align: right;
}

.ledger-count { display: block; padding: var(--s-3) 0 0; }

/* Filters sit on a rule rather than in a panel — a toolbar, not a card. */
.filters {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-4);
  align-items: flex-end;
  padding-bottom: var(--s-4);
  border-bottom: 1px solid var(--border);
}
.filters .field { min-width: 9rem; }
.filters .field:first-child { flex: 1 1 16rem; }

/* ==========================================================================
   The Tervra masthead and working surface
   --------------------------------------------------------------------------
   Supersedes .shell/.sidebar/.main/.topbar. Those rules remain below for any
   surface not yet migrated; these take precedence by being later and by the
   markup no longer emitting the old classes.

   The composition is editorial: an identity line, the position, a horizontal
   section rail under a rule, then the work — full width, no rail stealing
   250px from a table of money.
   ========================================================================== */
.shell {
  display: block;
  min-height: 100vh;
  background: var(--surface);
}

.masthead {
  display: flex;
  align-items: baseline;
  gap: var(--s-6);
  padding: var(--s-5) var(--s-6) var(--s-4);
  max-width: 1600px;
  margin: 0 auto;
}
.masthead-identity { display: flex; align-items: center; gap: var(--s-3); }
.masthead-names { display: flex; align-items: baseline; gap: var(--s-3); }
.masthead .brand-name {
  font-family: var(--font-display);
  font-size: var(--step-1);
  letter-spacing: 0.18em;
  color: var(--text);
}
/* The business, permanently visible. A person running four companies asks
   which one far more often than they ask for Settings. */
.masthead-context {
  font-family: var(--font-sans);
  font-size: var(--step--1);
  color: var(--text-muted);
  padding-left: var(--s-3);
  border-left: 1px solid var(--border);
}

.masthead-position {
  margin-left: auto;
  display: flex;
  align-items: baseline;
  gap: var(--s-3);
}
.masthead-position:empty { display: none; }

.masthead-actions { display: flex; gap: var(--s-2); }
.icon-button {
  background: none;
  border: 1px solid transparent;
  border-radius: 2px;
  padding: var(--s-2);
  color: var(--text-muted);
  cursor: pointer;
  line-height: 0;
}
.icon-button:hover { color: var(--text); border-color: var(--border); }
.icon-button:focus-visible { outline: 2px solid var(--focus); outline-offset: 1px; }

/* The rail. Words, horizontally, under a rule — read as a sequence rather
   than scanned as a stack of icon-and-label pairs. */
.rail {
  display: flex;
  gap: var(--s-5);
  padding: 0 var(--s-6);
  max-width: 1600px;
  margin: 0 auto;
  border-bottom: 1px solid var(--border);
  overflow-x: auto;
  scrollbar-width: none;
}
.rail::-webkit-scrollbar { display: none; }

.rail-item {
  position: relative;
  background: none;
  border: 0;
  padding: var(--s-3) 0 calc(var(--s-3) + 1px);
  font-family: var(--font-sans);
  font-size: var(--step-0);
  color: var(--text-muted);
  white-space: nowrap;
  cursor: pointer;
}
.rail-item:hover { color: var(--text); }
.rail-item:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
/* The active mark is a rule, not a pill — the same closing rule the symbol
   is built from, doing the same job: this is the one that counts. */
.rail-item[aria-current="page"],
.rail-item.is-active {
  color: var(--text);
  font-weight: 500;
  box-shadow: inset 0 -2px 0 0 var(--accent);
}

.env-strip {
  max-width: 1600px;
  margin: 0 auto;
  padding: var(--s-2) var(--s-6);
  font-family: var(--font-sans);
  font-size: var(--step--1);
  color: var(--text-muted);
  border-bottom: 1px solid var(--border);
}
.env-strip strong { color: var(--text); font-weight: 600; }
.env-live { color: var(--critical, #8c2b3a); }

/* The working surface. Full width, one editorial column, generous measure. */
.surface {
  max-width: 1600px;
  margin: 0 auto;
  padding: var(--s-6);
}

@media (max-width: 720px) {
  .masthead { flex-wrap: wrap; gap: var(--s-3); padding: var(--s-4); }
  .masthead-position { margin-left: 0; width: 100%; }
  .rail { padding: 0 var(--s-4); gap: var(--s-4); }
  .surface { padding: var(--s-4); }
}
