/* ===========================================================================
   DBTB Accounting — the whole visual system, in one file.
   ===========================================================================
   THEME: "Instrument"

   The budgeting app this grew out of was warm paper and teal — a notebook.
   This is deliberately the opposite register: cool, engineered, precise. A
   measuring instrument. Accounting is measurement, and the thing being measured
   is whether two sides agree.

   ---------------------------------------------------------------------------
   ACCESSIBILITY IS THE ARCHITECTURE, NOT A PASS AT THE END
   ---------------------------------------------------------------------------

   1. COLOUR IS NEVER THE ONLY SIGNAL. Debits and credits are told apart by the
      letters "Dr"/"Cr" and by column position; colour is a secondary cue for
      people who can use it. Negative amounts carry a minus sign AND
      parentheses AND a spoken form. Everything here works in greyscale.

   2. THE WHOLE SCALE IS IN rem. A reader who sets 200% text gets 200% text.
      Nothing is sized in px except hairline borders.

   3. FOCUS IS ALWAYS VISIBLE, and the outline is never removed anywhere in
      this file. A keyboard user who loses the caret has lost the page.

   4. TARGETS ARE AT LEAST 2.75rem (44px at default size), including in the
      dense bookkeeper tables — density is achieved by removing padding around
      the row, never by shrinking what you have to hit.

   5. prefers-reduced-motion, prefers-contrast and dark mode are all honoured
      rather than assumed away.

   Contrast ratios are noted next to each colour. All body text is at least
   7:1 (WCAG AAA); nothing that carries meaning is below 4.5:1.
   =========================================================================== */

:root {
  --ink:        #101725;   /* deep blue-black, softer on the eye than pure black */
  --ink-2:      #3C4759;   /* secondary text — 7.1:1 on --ground */
  --ground:     #EEF1F6;   /* cool page background */
  --panel:      #FFFFFF;
  --panel-2:    #F7F9FC;
  --rule:       #C3CCDA;
  --rule-soft:  #DFE5EE;

  --signal:      #1B47C4;  /* interactive — 7.4:1 on white */
  --signal-deep: #153AA4;
  --signal-wash: #E4EAFB;

  --dr:      #8C2231;      /* debit / negative — oxblood, 7.3:1 on white */
  --dr-wash: #FBEAEC;
  --cr:      #0A5C41;      /* credit / positive — pine, 7.0:1 on white */
  --cr-wash: #E6F2EC;
  --warn:      #8A4B00;    /* 6.4:1 on white */
  --warn-wash: #FDF0DE;

  /* A modular scale, so headings relate to body text rather than being picked. */
  --step--1: .8125rem;
  --step-0:  1rem;
  --step-1:  1.1875rem;
  --step-2:  1.4375rem;
  --step-3:  1.875rem;
  --step-4:  2.5rem;

  --mono: ui-monospace, "SF Mono", Menlo, "Cascadia Mono", "Roboto Mono", monospace;
  --sans: system-ui, -apple-system, "Segoe UI", Inter, Roboto, sans-serif;

  --pad:    clamp(1rem, 3vw, 2rem);
  --radius: .5rem;
  --tap:    2.75rem;       /* 44px at default text size */
}

/* An explicit OS request for more contrast is a person telling you the
   defaults do not work for them. Believe them. */
@media (prefers-contrast: more) {
  :root {
    --ink: #000; --ink-2: #1A2231; --rule: #5A6678; --rule-soft: #8894A6;
    --ground: #FFF; --signal: #0B2E96; --dr: #6E0E1C; --cr: #04402C;
  }
}

@media (prefers-color-scheme: dark) {
  :root {
    --ink: #E8ECF4; --ink-2: #A9B4C8; --ground: #0C1119; --panel: #151C27;
    --panel-2: #1B2431; --rule: #35405233; --rule: #354052; --rule-soft: #232D3C;
    --signal: #8FA6E8; --signal-deep: #A9BCF2; --signal-wash: #1C2740;
    --dr: #F09aa6; --dr-wash: #2E1A1E;   /* lightened for contrast on dark */
    --cr: #6FD3AC; --cr-wash: #122A22;
    --warn: #E8B478; --warn-wash: #2C2113;
  }
}

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

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

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font: var(--step-0)/1.55 var(--sans);
  /* Never set a px font-size on :root and never lock zoom. */
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ── The two utilities everything depends on ─────────────────────────────── */

/* Present to a screen reader, absent to the eye. Used constantly: it is how a
   negative amount says "negative" and how an icon-only control gets a name. */
.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
/* Visible again on focus, for skip links. */
.sr-only-focusable:focus, .sr-only-focusable:focus-visible {
  position: static; width: auto; height: auto;
  margin: 0; overflow: visible; clip: auto; white-space: normal;
}

.skip {
  position: absolute; left: .5rem; top: -5rem; z-index: 999;
  background: var(--ink); color: var(--panel);
  padding: .75rem 1.25rem; border-radius: 0 0 var(--radius) var(--radius);
  font-weight: 650; text-decoration: none; transition: top .15s;
}
.skip:focus { top: 0; }

/* ONE focus style, everywhere, never removed. */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 3px solid var(--signal);
  outline-offset: 2px;
  border-radius: 3px;
}

/* ── Layout shell ────────────────────────────────────────────────────────── */

.shell { display: grid; grid-template-columns: minmax(0, 1fr); min-height: 100vh; }
@media (min-width: 60rem) { .shell { grid-template-columns: 17.5rem minmax(0, 1fr); } }

.rail {
  background: var(--ink);
  color: #E8ECF4;
  padding: 1.25rem var(--pad);
  display: flex; flex-direction: column; gap: 1.5rem;
}
@media (prefers-color-scheme: dark) { .rail { background: #070B12; } }

.brand { display: flex; align-items: baseline; gap: .5rem; font-weight: 700; font-size: var(--step-1); }
.brand .mark { font-family: var(--mono); font-size: var(--step-2); line-height: 1; color: #8FA6E8; letter-spacing: -.08em; }
.brand a { color: inherit; text-decoration: none; }

.eyebrow {
  font-size: .6875rem; text-transform: uppercase; letter-spacing: .14em;
  font-weight: 700; color: var(--ink-2); margin: 0 0 .35rem;
}
.rail .eyebrow { color: #9DAAC4; }

/* ── Company switcher — the most-used control in the product ─────────────── */
/* A bookkeeper hits this dozens of times a day, so it sits first in the DOM
   (after the skip link), is reachable with one key, and states plainly which
   books are open rather than relying on a highlighted row. */

.switcher { display: flex; flex-direction: column; gap: .4rem; }
.switcher select {
  font: 600 var(--step-0)/1.3 var(--sans);
  color: #fff; background: #1E2839;
  border: 2px solid #46536B; border-radius: var(--radius);
  padding: .7rem .75rem; min-height: var(--tap); width: 100%;
}
.switcher select:hover { border-color: #7C8CA8; }
.hint { font-size: var(--step--1); color: #9DAAC4; margin: 0; }

kbd {
  font: 600 .75rem var(--mono);
  background: #2A3547; border: 1px solid #46536B; border-bottom-width: 2px;
  border-radius: .25rem; padding: .1rem .35rem; white-space: nowrap;
}
main kbd { background: var(--panel-2); border-color: var(--rule); color: var(--ink); }

.nav { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .15rem; }
.nav a {
  display: flex; align-items: center; gap: .5rem;
  padding: .6rem .75rem; min-height: var(--tap);
  color: #E8ECF4; text-decoration: none;
  border-radius: .4rem; border-left: 3px solid transparent;
}
.nav a:hover { background: #1E2839; }
.nav a[aria-current="page"] { background: #1E2839; border-left-color: #8FA6E8; font-weight: 650; }
.nav .badge {
  margin-left: auto; background: var(--signal); color: #fff;
  font: 700 .75rem var(--mono); border-radius: 999px; padding: .1rem .45rem;
}

main { padding: var(--pad); max-width: 70rem; width: 100%; }

h1 { font-size: var(--step-3); line-height: 1.15; margin: 0 0 .25rem; letter-spacing: -.02em; }
h2 { font-size: var(--step-2); margin: 0 0 .75rem; letter-spacing: -.015em; }
h3 { font-size: var(--step-1); margin: 0 0 .5rem; }
.lede { color: var(--ink-2); margin: 0 0 1.5rem; max-width: 60ch; }

/* ── Panels ──────────────────────────────────────────────────────────────── */

.panel {
  background: var(--panel); border: 1px solid var(--rule);
  border-radius: .75rem; padding: 1.25rem var(--pad); margin-bottom: 1.5rem;
}
.panel > :first-child { margin-top: 0; }
.panel > :last-child  { margin-bottom: 0; }
.panel-flush { padding: 0; overflow: hidden; }
.panel-head { padding: 1.25rem var(--pad); border-bottom: 1px solid var(--rule-soft); }
.panel-head h2, .panel-head h3 { margin: 0; }
.panel-head p { margin: .25rem 0 0; color: var(--ink-2); font-size: var(--step--1); }

/* ── The dashboard tiles ─────────────────────────────────────────────────── */
/* Each tile is a <a> or a definition pair, never a bare div, so it is reachable
   and announced with its label attached to its number. */

.tiles { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); margin-bottom: 1.5rem; }
.tile {
  background: var(--panel); border: 1px solid var(--rule);
  border-radius: .75rem; padding: 1.15rem 1.25rem;
  display: flex; flex-direction: column; gap: .35rem;
  text-decoration: none; color: inherit; min-height: 6.5rem;
}
a.tile:hover { border-color: var(--signal); background: var(--signal-wash); }
.tile .label { font-size: var(--step--1); font-weight: 650; color: var(--ink-2); }
.tile .value { font: 700 var(--step-3)/1.05 var(--mono); font-variant-numeric: tabular-nums; letter-spacing: -.02em; }
.tile .note  { font-size: var(--step--1); color: var(--ink-2); }
.tile.good .value { color: var(--cr); }
.tile.bad  .value { color: var(--dr); }

/* ── The Balance Beam ────────────────────────────────────────────────────── */
/* The signature element: two bars pushing out from a centre fulcrum. What the
   business owns on one side; what it owes plus what the owner has on the other.
   In a correct set of books they are the same length.

   It is not decoration — it is the trial balance, drawn. And it is fully
   readable without seeing it: the verdict is a sentence in the live region
   below, so a screen reader user learns the same fact at the same moment. */

.beam-rows { display: grid; gap: .5rem; margin: .75rem 0; }
.beam-row  { display: grid; grid-template-columns: 9rem 1fr auto; align-items: center; gap: .75rem; }
@media (max-width: 34rem) {
  .beam-row { grid-template-columns: 1fr auto; }
  .beam-row .track { grid-column: 1 / -1; }
}
.beam-row .label { font-size: var(--step--1); font-weight: 650; }
.track { background: var(--ground); border: 1px solid var(--rule-soft); border-radius: .2rem; height: 1.5rem; overflow: hidden; }
.fill  { height: 100%; transition: width .5s cubic-bezier(.2,.7,.3,1); }
.fill.assets { background: var(--signal); }
.fill.claims { background: var(--ink-2); }
.beam-row .amt { font: 650 var(--step-0)/1 var(--mono); font-variant-numeric: tabular-nums; }

/* ── Verdicts and messages ───────────────────────────────────────────────── */
/* The glyph is decorative and marked aria-hidden in the markup; the words
   carry every bit of the meaning. */

.verdict {
  display: flex; align-items: flex-start; gap: .6rem;
  padding: .75rem .9rem; border-radius: var(--radius);
  font-weight: 600; font-size: var(--step--1);
  border: 1px solid transparent;
}
.verdict .glyph { font-family: var(--mono); font-size: var(--step-1); line-height: 1.2; }
.verdict.ok   { background: var(--cr-wash);   color: var(--cr);   border-color: currentColor; }
.verdict.off  { background: var(--dr-wash);   color: var(--dr);   border-color: currentColor; }
.verdict.warn { background: var(--warn-wash); color: var(--warn); border-color: currentColor; }
.verdict.info { background: var(--signal-wash); color: var(--signal-deep); border-color: currentColor; }

/* An error summary that receives focus after a failed submit. Announcing into
   the void and leaving focus in the form is how a screen reader user ends up
   not knowing anything went wrong. */
.error-summary {
  border: 2px solid var(--dr); background: var(--dr-wash);
  border-radius: var(--radius); padding: 1rem var(--pad); margin-bottom: 1.25rem;
}
.error-summary:focus { outline: 3px solid var(--dr); outline-offset: 2px; }
.error-summary h2 { color: var(--dr); font-size: var(--step-1); margin: 0 0 .5rem; }
.error-summary ul { margin: 0; padding-left: 1.25rem; }
.error-summary a  { color: var(--dr); font-weight: 650; }

/* ── Forms ───────────────────────────────────────────────────────────────── */

.controls { display: flex; flex-wrap: wrap; gap: 1rem; align-items: flex-end; }
.field { display: flex; flex-direction: column; gap: .3rem; min-width: 0; }
.field label { font-size: var(--step--1); font-weight: 650; }
.field .help  { font-size: var(--step--1); color: var(--ink-2); }
.field .error { font-size: var(--step--1); color: var(--dr); font-weight: 650; }

input, select, textarea {
  font: var(--step-0)/1.3 var(--sans);
  padding: .55rem .65rem; min-height: var(--tap);
  border: 2px solid var(--rule); border-radius: .4rem;
  background: var(--panel); color: var(--ink);
  max-width: 100%;
}
input:hover, select:hover, textarea:hover { border-color: var(--ink-2); }
input[aria-invalid="true"], select[aria-invalid="true"] { border-color: var(--dr); }
input[type="number"], input.num { font-family: var(--mono); text-align: right; font-variant-numeric: tabular-nums; }
textarea { min-height: 5rem; resize: vertical; }
fieldset { border: 1px solid var(--rule); border-radius: var(--radius); padding: 1rem; margin: 0 0 1rem; }
legend { font-weight: 650; padding: 0 .4rem; }

button {
  font: 650 var(--step-0)/1.3 var(--sans);
  min-height: var(--tap); padding: .55rem 1.1rem;
  border-radius: .4rem; cursor: pointer; border: 2px solid transparent;
}
button[disabled] { cursor: not-allowed; opacity: .55; }
.btn-primary { background: var(--signal); color: #fff; }
.btn-primary:hover:not([disabled]) { background: var(--signal-deep); }
.btn-quiet   { background: var(--panel); color: var(--signal); border-color: var(--rule); }
.btn-quiet:hover:not([disabled]) { background: var(--signal-wash); border-color: var(--signal); }
.btn-danger  { background: var(--panel); color: var(--dr); border-color: var(--dr); }
.btn-danger:hover:not([disabled]) { background: var(--dr-wash); }
.btn-row { display: flex; flex-wrap: wrap; gap: .75rem; align-items: center; }

@media (prefers-color-scheme: dark) { .btn-primary { color: #0C1119; } }

/* ── Tabs: real buttons, arrow-key navigable ─────────────────────────────── */

[role="tablist"] {
  display: flex; flex-wrap: wrap; gap: .25rem;
  border-bottom: 2px solid var(--rule); margin-bottom: 1.25rem;
}
[role="tab"] {
  background: none; border: none; border-bottom: 3px solid transparent;
  padding: .7rem 1rem; color: var(--ink-2); border-radius: .3rem .3rem 0 0;
}
[role="tab"]:hover { background: var(--signal-wash); color: var(--signal); }
[role="tab"][aria-selected="true"] { color: var(--signal); border-bottom-color: var(--signal); font-weight: 700; }

/* ── Tables ──────────────────────────────────────────────────────────────── */
/* Real <table> markup with <caption>, scope, row headers and <tfoot> totals, so
   a screen reader announces "Total assets, 404,430 dollars" when landing on the
   cell instead of reading a wall of divs. */

.table-scroll { overflow-x: auto; }
table { width: 100%; border-collapse: collapse; font-variant-numeric: tabular-nums; }
caption {
  text-align: left; padding: 1rem var(--pad) .5rem;
  font-size: .6875rem; text-transform: uppercase; letter-spacing: .14em;
  font-weight: 700; color: var(--ink-2);
}
th, td { padding: .55rem var(--pad); text-align: left; border-bottom: 1px solid var(--rule-soft); }
thead th {
  font-size: .6875rem; text-transform: uppercase; letter-spacing: .1em;
  color: var(--ink-2); border-bottom: 2px solid var(--rule); padding-top: .75rem;
  position: sticky; top: 0; background: var(--panel); z-index: 1;
}
td.num, th.num { text-align: right; font-family: var(--mono); white-space: nowrap; }
th.num { font-family: var(--sans); }
tbody tr:hover { background: var(--signal-wash); }
.acct-no { font-family: var(--mono); color: var(--ink-2); font-size: var(--step--1); margin-right: .6rem; }

tr.section-head th {
  background: var(--panel-2); font-size: var(--step--1); font-weight: 700;
  text-transform: none; letter-spacing: 0; color: var(--ink);
  border-bottom: 1px solid var(--rule); position: static;
}
tr.subtotal td, tr.subtotal th {
  font-weight: 650; border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule);
}
tfoot td, tfoot th {
  font-weight: 700; font-size: var(--step-1); background: var(--panel-2);
  border-top: 2.5px solid var(--ink); border-bottom: none;
  padding-top: .85rem; padding-bottom: .85rem;
}

/* Debit and credit are distinguished by the Dr/Cr letters and by column
   position first. These colours are the third cue, not the first. */
.dr { color: var(--dr); }
.cr { color: var(--cr); }
.neg { color: var(--dr); }
.muted { color: var(--ink-2); }
.tag {
  display: inline-block; font-size: var(--step--1); font-weight: 650;
  padding: .1rem .5rem; border-radius: 999px;
  border: 1px solid var(--rule); background: var(--panel-2); color: var(--ink-2);
}
.tag.draft { border-color: var(--warn); color: var(--warn); background: var(--warn-wash); }
.tag.void  { border-color: var(--dr);   color: var(--dr);   background: var(--dr-wash); }

/* ── Empty and loading states ────────────────────────────────────────────── */

.empty { padding: 2.5rem var(--pad); text-align: center; color: var(--ink-2); }
.empty strong { display: block; color: var(--ink); font-size: var(--step-1); margin-bottom: .35rem; }
.status { margin: 1rem 0 0; font-size: var(--step--1); color: var(--ink-2); }

/* A skeleton is a lie to a screen reader, so loading is a word, not a shimmer. */
.loading { padding: 2rem var(--pad); color: var(--ink-2); font-style: italic; }

footer {
  margin-top: 2rem; padding-top: 1rem; border-top: 1px solid var(--rule);
  font-size: var(--step--1); color: var(--ink-2);
}

/* ── Entry grid (the bookkeeper's screen) ────────────────────────────────── */

.lines { width: 100%; border-collapse: collapse; }
.lines th { font-size: var(--step--1); }
.lines td { padding: .35rem .5rem; vertical-align: top; }
.lines input, .lines select { width: 100%; min-height: var(--tap); }
.lines td.amount input { text-align: right; font-family: var(--mono); }

/* The running difference. Two states, both stated in words next to the figure. */
.running {
  display: flex; flex-wrap: wrap; gap: 1.5rem; align-items: baseline;
  padding: .9rem var(--pad); border-radius: var(--radius);
  background: var(--panel-2); border: 1px solid var(--rule); margin: 1rem 0;
}
.running dt { font-size: var(--step--1); font-weight: 650; color: var(--ink-2); }
.running dd { margin: 0; font: 700 var(--step-1) var(--mono); font-variant-numeric: tabular-nums; }
.running .balanced   { color: var(--cr); }
.running .unbalanced { color: var(--dr); }

/* ARIA combobox for the account picker. A real listbox, not a <datalist> —
   datalist support in screen readers is inconsistent enough that a bookkeeper
   cannot rely on it, and this screen is where they live. */
.combo { position: relative; }
.combo-list {
  position: absolute; z-index: 20; left: 0; right: 0; top: calc(100% + 2px);
  margin: 0; padding: .25rem; list-style: none; max-height: 15rem; overflow-y: auto;
  background: var(--panel); border: 2px solid var(--signal);
  border-radius: var(--radius); box-shadow: 0 8px 24px rgb(16 23 37 / .18);
}
.combo-list[hidden] { display: none; }
.combo-list li {
  padding: .5rem .6rem; border-radius: .3rem; cursor: pointer;
  display: flex; gap: .6rem; align-items: baseline; min-height: var(--tap);
}
.combo-list li[aria-selected="true"] { background: var(--signal); color: #fff; }
.combo-list li[aria-selected="true"] .acct-no { color: #DCE4FA; }

/* ── Print ───────────────────────────────────────────────────────────────── */

@media print {
  .rail, .controls, [role="tablist"], .skip, .btn-row, button { display: none !important; }
  .panel, .tile { border: none; box-shadow: none; }
  body { background: #fff; color: #000; }
  thead th { position: static; }
  a[href]::after { content: ""; }   /* the URL is noise on a printed statement */
}
