/* Daro Books — interface styles */
:root {
  /* Every colour is a token. A theme is a different set of values for these,
     and nothing else in this file needs to know which theme is in force.
     The names say what a colour is FOR, never which colour it is — a variable
     called --green in a blue theme is a trap somebody falls into later. */
  --accent: #0b6b3a;          /* buttons, links, focus rings */
  --accent-dark: #084d2a;     /* hover, document headings */
  --accent-soft: #e7f3ec;     /* pale fills: badges, section rows */
  --accent-line: #b9dcc8;     /* borders on those pale fills */

  --side-bg: #084d2a;         /* the sidebar */
  --side-text: #cfe4d8;
  --side-muted: #7fae95;
  --side-active: #6fcf97;

  --ink: #16202b;
  --ink-soft: #5a6672;
  --line: #dde3e8;
  --bg: #f4f6f8;
  --card: #ffffff;
  --card-soft: #fafbfc;

  --good: #0b6b3a;            /* a figure that helped profit — never the accent */
  --danger: #b3261e;
  --danger-bg: #fdecea;
  --danger-line: #f3c4c0;
  --warn: #8a5a00;
  --warn-bg: #fff5e0;
  --warn-line: #f0dcb0;
  --info: #0b4f8a;
  --info-bg: #e8f1fa;
  --info-line: #c3ddf3;

  --radius: 8px;
  --shadow: 0 1px 2px rgba(16, 32, 43, .06), 0 1px 8px rgba(16, 32, 43, .04);
  --mono: ui-monospace, "SF Mono", "Cascadia Mono", Consolas, monospace;
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  font-size: 14px;
  line-height: 1.5;
  color: var(--ink);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
}
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }
h1, h2, h3, h4 { margin: 0 0 .5rem; line-height: 1.25; font-weight: 650; }
h1 { font-size: 1.5rem; }
h2 { font-size: 1.15rem; }
h3 { font-size: 1rem; }
p { margin: 0 0 .75rem; }
small, .small { font-size: 12px; }
.muted { color: var(--ink-soft); }
.right { text-align: right; }
.center { text-align: center; }
.nowrap { white-space: nowrap; }
.mono { font-variant-numeric: tabular-nums; font-family: var(--mono); }
.num { text-align: right; font-variant-numeric: tabular-nums; }
.neg { color: var(--danger); }
.strong { font-weight: 650; }
.hide { display: none !important; }

/* ---------------- Layout ---------------- */
.shell { display: flex; min-height: 100vh; }
.sidebar {
  width: 232px; flex: 0 0 232px; background: var(--side-bg); color: var(--side-text);
  display: flex; flex-direction: column; position: sticky; top: 0; height: 100vh; overflow-y: auto;
}
.brand { padding: 1rem 1.1rem .75rem; color: #fff; font-weight: 700; font-size: 1.05rem;
  letter-spacing: .2px; border-bottom: 1px solid rgba(255,255,255,.12); }
.brand small { display: block; font-weight: 400; font-size: 11px; color: var(--side-muted); letter-spacing: 0; }
.brand-logo { display: block; max-height: 40px; max-width: 170px; width: auto;
  background: var(--card); padding: 4px 6px; border-radius: 5px; margin-bottom: .5rem; }
.company-switch { padding: .55rem 1.1rem; border-bottom: 1px solid rgba(255,255,255,.12); }
.company-switch label { color: var(--side-muted); font-size: 10.5px; text-transform: uppercase;
  letter-spacing: .09em; font-weight: 600; margin-bottom: .25rem; }
.company-switch select { background: rgba(255,255,255,.1); color: #fff;
  border-color: rgba(255,255,255,.2); font-size: 13px; padding: .3rem .4rem; }
.company-switch select option { color: var(--ink); background: var(--card); }
.nav { padding: .5rem 0 2rem; flex: 1; }
.nav-group { padding: .9rem 1.1rem .3rem; font-size: 10.5px; text-transform: uppercase;
  letter-spacing: .09em; color: var(--side-muted); font-weight: 600; }
.nav a { display: block; padding: .42rem 1.1rem; color: var(--side-text); font-size: 13.5px; border-left: 3px solid transparent; }
.nav a:hover { background: rgba(255,255,255,.07); color: #fff; text-decoration: none; }
.nav a.active { background: rgba(255,255,255,.12); color: #fff; border-left-color: var(--side-active); font-weight: 600; }

.main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.topbar {
  background: var(--card); border-bottom: 1px solid var(--line); padding: .55rem 1.25rem;
  display: flex; align-items: center; gap: 1rem; position: sticky; top: 0; z-index: 20;
}
.topbar form.search { flex: 1; max-width: 420px; }
.topbar input[type=search] { width: 100%; }
.topbar .who { margin-left: auto; display: flex; align-items: center; gap: .75rem; font-size: 13px; }
.content { padding: 1.25rem; max-width: 1400px; width: 100%; }

.page-head { display: flex; align-items: flex-start; gap: 1rem; margin-bottom: 1rem; flex-wrap: wrap; }
.page-head h1 { margin: 0; }
.page-head .actions { margin-left: auto; display: flex; gap: .5rem; flex-wrap: wrap; }

/* ---------------- Cards ---------------- */
.card { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow); margin-bottom: 1rem; }
.card-head { padding: .7rem 1rem; border-bottom: 1px solid var(--line); display: flex;
  align-items: center; gap: .75rem; }
.card-head h2, .card-head h3 { margin: 0; }
.card-head .actions { margin-left: auto; display: flex; gap: .4rem; }
.card-body { padding: 1rem; }
.card-body.tight { padding: .5rem 1rem; }

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

.stat { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  padding: .85rem 1rem; box-shadow: var(--shadow); }
.stat .label { font-size: 11.5px; text-transform: uppercase; letter-spacing: .06em; color: var(--ink-soft); font-weight: 600; }
.stat .value { font-size: 1.45rem; font-weight: 680; font-variant-numeric: tabular-nums; margin-top: .15rem; }
.stat .sub { font-size: 12px; color: var(--ink-soft); }
.stat.accent { border-left: 3px solid var(--accent); }
.stat.warn { border-left: 3px solid var(--warn); }
.stat.danger { border-left: 3px solid var(--danger); }

/* ---------------- Tables ---------------- */
.table-wrap { overflow-x: auto; }
table.data { width: 100%; border-collapse: collapse; font-size: 13.5px; }
table.data th, table.data td { padding: .5rem .65rem; border-bottom: 1px solid var(--line); text-align: left; vertical-align: top; }
table.data thead th { background: var(--card-soft); font-size: 11.5px; text-transform: uppercase;
  letter-spacing: .05em; color: var(--ink-soft); font-weight: 650; white-space: nowrap;
  position: sticky; top: 0; z-index: 1; }
table.data tbody tr:hover { background: var(--card-soft); }
table.data tfoot td { font-weight: 650; border-top: 2px solid var(--ink); background: var(--card-soft); }
table.data td.num, table.data th.num { text-align: right; font-variant-numeric: tabular-nums; }
table.data tr.section td { background: var(--accent-soft); font-weight: 650; }
table.data tr.total td { font-weight: 650; border-top: 1px solid var(--ink); }
table.data tr.grand td { font-weight: 700; border-top: 2px double var(--ink); border-bottom: 2px double var(--ink); }
table.data .indent { padding-left: 1.75rem; }
.empty { padding: 2.5rem 1rem; text-align: center; color: var(--ink-soft); }

/* ---------------- Forms ---------------- */
label { display: block; font-size: 12.5px; font-weight: 600; color: var(--ink-soft); margin-bottom: .2rem; }
/* Matches every text-like input, including those written without a type
   attribute — an `input[type=text]` selector silently misses those, and they
   then fall back to their intrinsic ~190px width and overflow their column. */
input:not([type=checkbox]):not([type=radio]):not([type=submit]):not([type=button]):not([type=hidden]),
select, textarea {
  width: 100%; padding: .42rem .55rem; border: 1px solid var(--line); border-radius: 6px;
  font: inherit; color: var(--ink); background: var(--card);
}
input:focus, select:focus, textarea:focus { outline: 2px solid var(--accent); outline-offset: -1px; border-color: var(--accent); }
input[readonly], input:disabled, select:disabled { background: var(--card-soft); color: var(--ink-soft); }
textarea { min-height: 68px; resize: vertical; }
input.num { text-align: right; font-variant-numeric: tabular-nums; }
.field { margin-bottom: .75rem; }
.field-row { display: grid; gap: .75rem; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }
.check { display: flex; align-items: center; gap: .45rem; margin-bottom: .4rem; }
.check input { width: auto; }
.check label { margin: 0; font-weight: 500; color: var(--ink); font-size: 13.5px; }
.hint { font-size: 12px; color: var(--ink-soft); margin-top: .2rem; }
fieldset { border: 1px solid var(--line); border-radius: var(--radius); padding: .9rem 1rem; margin: 0 0 1rem; }
legend { font-weight: 650; font-size: 13px; padding: 0 .4rem; }

/* ---------------- Buttons ---------------- */
.btn { display: inline-flex; align-items: center; gap: .35rem; padding: .42rem .8rem;
  border: 1px solid var(--line); border-radius: 6px; background: var(--card); color: var(--ink);
  font: inherit; font-weight: 550; cursor: pointer; white-space: nowrap; }
.btn:hover { background: var(--card-soft); text-decoration: none; }
.btn-primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.btn-primary:hover { background: var(--accent-dark); border-color: var(--accent-dark); }
.btn-danger { background: var(--card); border-color: var(--danger); color: var(--danger); }
.btn-danger:hover { background: var(--danger-bg); }
.btn-sm { padding: .25rem .55rem; font-size: 12.5px; }
.btn-link { border: none; background: none; color: var(--accent); padding: 0; }
.btn[disabled] { opacity: .5; cursor: not-allowed; }
.btn-row { display: flex; gap: .5rem; flex-wrap: wrap; align-items: center; }

/* ---------------- Badges & alerts ---------------- */
.badge { display: inline-block; padding: .1rem .45rem; border-radius: 999px; font-size: 11px;
  font-weight: 650; text-transform: uppercase; letter-spacing: .03em; }
.badge-draft { background: var(--line); color: var(--ink-soft); }
.badge-open { background: var(--info-bg); color: var(--info); }
.badge-part { background: var(--warn-bg); color: var(--warn); }
.badge-paid { background: var(--accent-soft); color: var(--accent-dark); }
.badge-void { background: var(--danger-bg); color: var(--danger); }

.alert { padding: .65rem .9rem; border-radius: var(--radius); margin-bottom: .75rem;
  border: 1px solid transparent; font-size: 13.5px; }
.alert-success { background: var(--accent-soft); border-color: var(--accent-line); color: var(--accent-dark); }
.alert-danger { background: var(--danger-bg); border-color: var(--danger-line); color: var(--danger); }
.alert-warning { background: var(--warn-bg); border-color: var(--warn-line); color: var(--warn); }
.alert-info { background: var(--info-bg); border-color: var(--info-line); color: var(--info); }

.filters { display: flex; gap: .5rem; flex-wrap: wrap; align-items: flex-end; margin-bottom: 1rem;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); padding: .75rem 1rem; }
.filters .field { margin: 0; min-width: 130px; }
.tabs { display: flex; gap: .25rem; border-bottom: 1px solid var(--line); margin-bottom: 1rem; flex-wrap: wrap; }
.tabs a { padding: .45rem .8rem; border-bottom: 2px solid transparent; color: var(--ink-soft); font-weight: 550; }
.tabs a:hover { color: var(--ink); text-decoration: none; }
.tabs a.active { color: var(--accent); border-bottom-color: var(--accent); }

/* ---------------- Line-item editor ---------------- */
/* table-layout:fixed makes the column widths in the markup authoritative, so a
   long item name cannot squeeze the VAT selector down to two letters. */
table.lines { width: 100%; border-collapse: collapse; font-size: 13px; table-layout: fixed; min-width: 900px; }
table.lines select { text-overflow: ellipsis; }
table.lines th { font-size: 11px; text-transform: uppercase; letter-spacing: .05em;
  color: var(--ink-soft); text-align: left; padding: .3rem .3rem; font-weight: 650;
  overflow-wrap: anywhere; }
table.lines th.center, table.lines td.center { text-align: center; }
table.lines input[type=checkbox] { width: auto; }
table.lines td { padding: .18rem .2rem; vertical-align: top; }
table.lines input, table.lines select { padding: .32rem .4rem; font-size: 13px; }
table.lines td.rm { width: 28px; }
.totals { margin-left: auto; width: 320px; max-width: 100%; }
.totals table { width: 100%; font-size: 13.5px; }
.totals td { padding: .22rem .3rem; }
.totals td:last-child { text-align: right; font-variant-numeric: tabular-nums; }
.totals tr.grand td { font-weight: 700; font-size: 1.05rem; border-top: 2px solid var(--ink); padding-top: .4rem; }

/* ---------------- Login ---------------- */
.login-wrap { min-height: 100vh; display: grid; place-items: center; background:
  linear-gradient(135deg, var(--side-bg), var(--accent)); padding: 1rem; }
.login-card { background: var(--card); border-radius: 12px; padding: 2rem; width: 100%; max-width: 380px;
  box-shadow: 0 12px 40px rgba(0,0,0,.2); }
.login-card h1 { text-align: center; color: var(--accent-dark); }
.login-card .sub { text-align: center; color: var(--ink-soft); margin-bottom: 1.25rem; font-size: 13px; }

/* ---------------- Chart ---------------- */
.chart { display: flex; align-items: flex-end; gap: 4px; height: 150px; padding-top: .5rem; }
.chart .col { flex: 1; display: flex; flex-direction: column; justify-content: flex-end;
  align-items: center; gap: 2px; min-width: 0; }
.chart .bars { display: flex; gap: 2px; align-items: flex-end; width: 100%; height: 120px; }
.chart .bar { flex: 1; border-radius: 2px 2px 0 0; min-height: 2px; }
.chart .bar.rev { background: var(--accent); }
.chart .bar.exp { background: var(--line); }
.chart .lbl { font-size: 10px; color: var(--ink-soft); white-space: nowrap; }
.legend { display: flex; gap: 1rem; font-size: 12px; color: var(--ink-soft); margin-top: .5rem; }
.legend i { display: inline-block; width: 10px; height: 10px; border-radius: 2px; margin-right: .3rem; }

/* ---------------- Documents (print) ---------------- */
.doc { background: var(--card); padding: 2rem; max-width: 820px; margin: 0 auto; border: 1px solid var(--line);
  border-radius: var(--radius); }
.doc-head { display: flex; justify-content: space-between; gap: 2rem; margin-bottom: 1.5rem; }
.doc-head .co h2 { color: var(--accent-dark); margin-bottom: .25rem; }
.doc-logo { max-height: 72px; max-width: 260px; width: auto; display: block; margin-bottom: .6rem; }
@media print { .doc-logo { max-height: 64px; } }
.doc-title { text-align: right; }
.doc-title h1 { font-size: 1.6rem; letter-spacing: .04em; text-transform: uppercase; color: var(--accent-dark); }
.doc-parties { display: flex; gap: 2rem; margin-bottom: 1.25rem; }
.doc-parties > div { flex: 1; }
.doc-parties .lbl { font-size: 10.5px; text-transform: uppercase; letter-spacing: .07em;
  color: var(--ink-soft); font-weight: 650; margin-bottom: .25rem; }
.doc table.data thead th { background: var(--accent-soft); color: var(--accent-dark); }
.doc-foot { margin-top: 2rem; padding-top: 1rem; border-top: 1px solid var(--line);
  font-size: 12px; color: var(--ink-soft); }

/* Shown only on paper — a letterhead above a report, for instance. */
.print-only { display: none; }

@media print {
  .sidebar, .topbar, .no-print, .page-head .actions { display: none !important; }
  .print-only { display: block; }
  body { background: var(--card); }
  .content { padding: 0; max-width: none; }
  .doc { border: none; padding: 0; max-width: none; }
  .card { box-shadow: none; border-color: #ccc; page-break-inside: avoid; }
  table.data thead th { position: static; }
  a { color: inherit; text-decoration: none; }
}

@media (max-width: 900px) {
  .shell { flex-direction: column; }
  .sidebar { width: 100%; flex: none; height: auto; position: static; }
  .nav { display: flex; flex-wrap: wrap; padding-bottom: .5rem; }
  .nav-group { width: 100%; padding-top: .5rem; }
  .nav a { border-left: none; border-bottom: 2px solid transparent; }
  .nav a.active { border-left: none; border-bottom-color: var(--side-active); }
  .content { padding: .75rem; }
  .totals { width: 100%; }
}

/* ---------------- Definition lists, used on record pages ---------------- */
dl.detail { display: grid; grid-template-columns: minmax(120px, auto) 1fr;
            gap: .3rem .9rem; margin: 0; font-size: 13.5px; }
dl.detail dt { color: var(--ink-soft); }
dl.detail dd { margin: 0; }

.form-actions { display: flex; gap: .5rem; flex-wrap: wrap; align-items: center;
                margin: 1rem 0; }
.inline-form { display: flex; gap: .5rem; flex-wrap: wrap; align-items: center; }
.inline-form select, .inline-form input { width: auto; }

/* One-off text colours used where a figure has to read as good or bad. */
.text-danger { color: var(--danger); }
.text-success { color: var(--accent-dark); }

/* ---------------- Surfaces that a dark theme has to be able to move -------- */
input, select, textarea { background: var(--card); color: var(--ink); }
input::placeholder, textarea::placeholder { color: var(--ink-soft); opacity: .75; }
input:disabled, select:disabled, textarea:disabled,
input[readonly] { background: var(--card-soft); color: var(--ink-soft); }
table.data thead th { background: var(--card-soft); }
pre, code { color: var(--ink); }

/* A message shown as it will arrive: the line breaks the person typed are the
   line breaks the customer sees, so they are kept rather than collapsed. */
.preview-mail { background: var(--card-soft); border: 1px solid var(--line);
  border-radius: var(--radius); padding: .8rem 1rem; white-space: pre-wrap;
  word-break: break-word; font-family: inherit; font-size: .95rem;
  line-height: 1.55; margin: 0; }
details > summary { color: var(--accent); cursor: pointer; }
hr { border: none; border-top: 1px solid var(--line); }

/* A dark theme should not print as a black page. Printing is always on paper. */
@media print {
  html[data-theme] { --bg: #fff; --card: #fff; --card-soft: #fff;
                     --ink: #000; --ink-soft: #444; --line: #bbb; }
}

/* ---------------- The colour picker --------------------------------------- */
.theme-grid { display: grid; gap: .75rem;
  grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); }
.theme-option { display: block; position: relative; cursor: pointer;
  border: 1px solid var(--line); border-radius: var(--radius);
  padding: .7rem .8rem; background: var(--card); }
.theme-option:hover { border-color: var(--accent); }
.theme-option input { position: absolute; opacity: 0; pointer-events: none; }
.theme-option:has(input:checked) { border-color: var(--accent);
  box-shadow: 0 0 0 2px var(--accent-soft), 0 0 0 3px var(--accent); }
.theme-swatch { display: flex; height: 26px; border-radius: 5px; overflow: hidden;
  border: 1px solid var(--line); margin-bottom: .5rem; }
.theme-swatch span { flex: 1; }
.theme-swatch span:first-child { flex: 1.4; }
.theme-name { display: block; font-weight: 600; }
.theme-note { display: block; line-height: 1.35; }

/* ---------------- Insights: the screens that explain the figures ----------- */

/* A movement is either good for profit or bad for it, and the eye should know
   which before it reads the number. Green and red are earned here, unlike
   everywhere else in the interface where they are decoration.

   --good is deliberately not --accent: in the Burgundy theme the accent is red
   and in Ocean it is blue, and a figure that helped profit must not be shown
   in either. Every theme defines its own readable green. */
.pos { color: var(--good); }

.crumbs { display: flex; flex-wrap: wrap; gap: .35rem; align-items: center;
  font-size: 13px; margin-bottom: .75rem; color: var(--ink-soft); }
.crumbs a { color: var(--accent); }
.crumbs span { color: var(--ink-soft); }

.movement { display: flex; gap: 1.5rem; flex-wrap: wrap; align-items: flex-start; }
.movement-figure { min-width: 230px; padding-left: .8rem;
  border-left: 4px solid var(--line); }
.movement.up .movement-figure { border-left-color: var(--good); }
.movement.down .movement-figure { border-left-color: var(--danger); }
.movement-figure .label { font-size: 11.5px; text-transform: uppercase;
  letter-spacing: .06em; color: var(--ink-soft); font-weight: 600; }
.movement-figure .value { font-size: 2rem; font-weight: 700;
  font-variant-numeric: tabular-nums; line-height: 1.15; }
.movement.up .movement-figure .value { color: var(--good); }
.movement.down .movement-figure .value { color: var(--danger); }
.movement-figure .sub { font-size: 12.5px; color: var(--ink-soft); margin-top: .2rem; }
.movement-words { flex: 1; min-width: 260px; }
.movement-words p { margin: 0 0 .45rem; line-height: 1.5; }
.movement-words p:first-child { font-size: 1.05rem; font-weight: 600; }

/* Bars are drawn from the same numbers in the row beside them; they are a way
   of reading the column faster, never a substitute for it. */
.share-col { width: 130px; }
.bar { height: 9px; background: var(--card-soft); border: 1px solid var(--line);
  border-radius: 999px; overflow: hidden; }
.bar span { display: block; height: 100%; }
.bar-up span { background: var(--good); }
.bar-down span { background: var(--danger); }

/* The brief */
.points { list-style: none; margin: 0; padding: 0; }
.points li { display: flex; gap: .8rem; padding: .75rem 1rem;
  border-bottom: 1px solid var(--line); align-items: flex-start; }
.points li:last-child { border-bottom: none; }
.point-mark { width: 4px; align-self: stretch; border-radius: 999px;
  background: var(--line); flex: none; }
.point-urgent .point-mark { background: var(--danger); }
.point-watch .point-mark { background: var(--warn); }
.point-good .point-mark { background: var(--good); }
.point-body { flex: 1; min-width: 0; }
.point-body strong { display: block; }
.point-body .muted { line-height: 1.45; }
.point-amount { text-align: right; font-variant-numeric: tabular-nums;
  font-weight: 650; white-space: nowrap; }
.point-action { flex: none; }

.brief-quiet { text-align: center; padding: 2rem 1rem; color: var(--ink-soft); }

/* The board pack prints; on paper each part starts on its own page. */
@media print {
  .pack-section { break-before: page; }
  .pack-section:first-of-type { break-before: auto; }
}

/* ---------------- Two-factor sign-in -------------------------------------- */

/* A six-digit code is read back character by character, so it is set wide and
   monospaced rather than in the body face. */
.code-input { font-family: var(--mono); font-size: 1.5rem; letter-spacing: .35em;
  text-align: center; padding: .6rem; }

.qr-holder { display: flex; justify-content: center; padding: 1rem;
  background: #ffffff; border: 1px solid var(--line); border-radius: var(--radius);
  margin-bottom: 1rem; }
/* The QR itself is always drawn dark-on-white, whatever the theme: a scanner
   needs the contrast the standard assumes, and an inverted code will not read. */
.qr-holder svg { max-width: 100%; height: auto; }

/* The secret written out for somebody typing it into their phone by hand.
   The width and the wrapping are stated outright rather than left to inherit,
   so no other rule can squash it; one click selects the whole thing. */
code.secret-key { font-family: var(--mono); font-size: 1.05rem; letter-spacing: .06em;
  background: var(--card-soft); border: 1px solid var(--line);
  border-radius: var(--radius); padding: .5rem .7rem; display: block;
  width: auto; height: auto; min-width: 0; max-width: 100%;
  white-space: normal; word-break: break-word; overflow-wrap: anywhere;
  line-height: 1.7; user-select: all; -webkit-user-select: all; }

.recovery-grid { display: grid; gap: .5rem;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
.recovery-code { font-family: var(--mono); font-size: 1.05rem; text-align: center;
  padding: .5rem; border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--card-soft); }

.inline-form { display: flex; gap: .4rem; align-items: center; margin-top: .6rem;
  flex-wrap: wrap; }
.inline-form input { max-width: 190px; }

/* ---------------- Bank statement import ----------------------------------- */

/* Charts stretch to the card and keep their height. preserveAspectRatio is
   "none" on the SVG, so the viewBox does the scaling and the bars stay put. */
.chart-wrap { width: 100%; overflow-x: auto; }
.cash-chart { width: 100%; height: 170px; display: block; }
.chart-labels { display: flex; margin-top: .25rem; }
.chart-labels span { flex: 1; text-align: center; font-size: 10.5px;
  color: var(--ink-soft); white-space: nowrap; overflow: hidden; }

/* The little coloured squares in a chart legend. Named "swatch", not "key":
   the two-factor screen prints a key in a <code class="secret-key"> and an
   earlier ".key" here matched both, squeezing a 32-character secret into a
   10-pixel box so it came out one character per line. */
.swatch { display: inline-block; width: 10px; height: 10px; border-radius: 2px;
  vertical-align: middle; margin: 0 .15rem 0 .5rem; }
.swatch-in { background: var(--good); }
.swatch-out { background: var(--danger); }
.swatch-bal { background: var(--accent); }

/* One bar split into parts: recognised, worth a look, needs you, done. */
.split-bar { display: flex; height: 14px; border-radius: 999px; overflow: hidden;
  background: var(--card-soft); border: 1px solid var(--line); }
.split-bar span { display: block; }
.split-key { display: flex; flex-wrap: wrap; gap: 1rem; margin-top: .55rem;
  font-size: 12px; color: var(--ink-soft); }
.split-key i { display: inline-block; width: 9px; height: 9px; border-radius: 2px;
  margin-right: .3rem; }

/* Where the money went: a name, a bar under it, a figure beside it. */
table.data.breakdown td { border-bottom: none; padding: .35rem .4rem; }
table.data.breakdown .bar { height: 6px; background: var(--card-soft);
  border-radius: 999px; overflow: hidden; margin-top: .25rem; }
table.data.breakdown .bar span { display: block; height: 100%; }

table.data.statement .desc { max-width: 420px; }
table.data.statement tr.row-done { opacity: .58; }
table.data.statement tr.row-done:hover { opacity: 1; }

/* --------------------------------------------------------------------------
   The till
   --------------------------------------------------------------------------
   Two columns: what is being bought on the left, what is being paid on the
   right. On a small screen they stack, because a counter tablet is held
   upright as often as sideways.
*/
.till { display: grid; grid-template-columns: 1fr 22rem; gap: 1.25rem; align-items: start; }
@media (max-width: 62rem) { .till { grid-template-columns: 1fr; } }

.till-find {
  width: 100%; font-size: 1.15rem; padding: .7rem .85rem;
  border: 2px solid var(--accent); border-radius: var(--radius);
  background: var(--surface); color: var(--text);
}
.till-find:focus { outline: none; box-shadow: 0 0 0 3px var(--accent-soft); }

.till-results { margin-top: .5rem; display: grid; gap: .3rem; max-height: 18rem; overflow-y: auto; }
.till-result {
  display: grid; grid-template-columns: 1fr auto; gap: .1rem .75rem;
  text-align: left; padding: .5rem .7rem; border: 1px solid var(--line);
  border-radius: var(--radius); background: var(--surface); color: var(--text);
  cursor: pointer; font: inherit;
}
.till-result:hover { border-color: var(--accent); background: var(--surface-2); }
.till-result .n { font-weight: 600; }
.till-result .p { font-variant-numeric: tabular-nums; font-weight: 600; }
.till-result .s { grid-column: 1 / -1; font-size: .78rem; color: var(--muted); }

.till-basket input.num { width: 5.5rem; text-align: right; }
.till-basket input.qty { width: 4.5rem; }

.till-total, .till-change, .till-short {
  border-radius: var(--radius); padding: .7rem .85rem; margin-bottom: .75rem;
}
.till-total { background: var(--accent); color: #fff; }
.till-total .label, .till-change .label, .till-short .label {
  font-size: .75rem; text-transform: uppercase; letter-spacing: .04em; opacity: .85;
}
.till-total .value { font-size: 1.9rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.till-change { background: var(--good-soft, var(--surface-2)); border: 1px solid var(--good); }
.till-change .value { font-size: 1.4rem; font-weight: 700; color: var(--good); }
.till-short { background: var(--surface-2); border: 1px solid var(--danger); }
.till-short .value { font-size: 1.2rem; font-weight: 700; color: var(--danger); }

.till-tender {
  border: 1px solid var(--line); border-radius: var(--radius);
  padding: .6rem .7rem; margin-bottom: .5rem; background: var(--surface-2);
}
.till-tender .head { display: flex; justify-content: space-between; align-items: center; }
.till-tender label { display: block; font-size: .78rem; color: var(--muted); margin-top: .4rem; }
.till-tender input, .till-tender select { width: 100%; }
.till-add-tender { display: flex; gap: .4rem; margin: .5rem 0 .75rem; }

.btn-block { display: block; width: 100%; margin-top: .5rem; }

.count-grid input.num { width: 6rem; }
.till-difference {
  font-size: 1.15rem; font-weight: 700; padding: .55rem .7rem;
  border-radius: var(--radius); background: var(--surface-2);
}
.till-difference.ok { color: var(--good); }
.till-difference.short { color: var(--danger); }
.till-difference.over { color: var(--accent); }

/* The printed slip, on screen and on paper. */
.roll {
  width: 80mm; max-width: 100%; margin: 0 auto; padding: 6mm 4mm;
  background: #fff; color: #111; font-family: ui-monospace, "Courier New", monospace;
  font-size: 11px; line-height: 1.45; border: 1px solid var(--line);
}
.roll-head { text-align: center; margin-bottom: .6rem; }
.roll-facts { display: flex; justify-content: space-between; border-top: 1px dashed #999;
              border-bottom: 1px dashed #999; padding: .3rem 0; margin-bottom: .3rem; }
.roll-ref { text-align: center; font-size: 10px; }
.roll-lines, .roll-totals { width: 100%; border-collapse: collapse; margin-top: .4rem; }
.roll-lines td.q { padding-left: 1em; color: #444; }
.roll-lines td.a, .roll-totals td.a { text-align: right; }
.roll-totals { border-top: 1px dashed #999; padding-top: .3rem; }
.roll-totals tr.big td { font-size: 13px; font-weight: 700; padding-top: .2rem; }
.roll-foot { text-align: center; border-top: 1px dashed #999; margin-top: .5rem; padding-top: .4rem; }

@media print {
  .roll { border: none; width: auto; padding: 0; }
}

/* ---------------- Paying for a licence ------------------------------------ */

/* One button per gateway. Big enough to be obviously the thing to press, and
   showing the amount on the button itself, because a customer who has to hold
   a figure in their head while a checkout loads is a customer who pays the
   wrong amount. */
.pay-choices { display: grid; gap: .6rem; margin-top: .8rem;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }

.pay-choice { display: flex; flex-direction: column; gap: .15rem;
  padding: .85rem 1rem; border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--card-soft); text-decoration: none; color: var(--ink);
  transition: border-color .12s ease, transform .12s ease; }
.pay-choice:hover { border-color: var(--accent); transform: translateY(-1px); }
.pay-choice:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.pay-choice-name { font-weight: 600; }
.pay-choice-sum { font-family: var(--mono); font-size: 1.15rem; color: var(--accent); }
.pay-choice-note { font-size: .82rem; color: var(--ink-soft); }

/* ==========================================================================
   How the screen is arranged
   ==========================================================================
   Three arrangements, chosen per person under Account. The markup is identical
   in all three — the same sidebar element, the same links, the same order — so
   there is one menu to maintain and no chance of the arrangements drifting
   apart. Only where it sits changes. See app/layouts.py. */

.menu-button { display: none; }

/* --- Menu across the top ------------------------------------------------- */

.shell.layout-topbar { display: block; }

.shell.layout-topbar .sidebar {
  position: sticky; top: 0; z-index: 40;
  width: 100%; min-height: 0; height: auto;
  display: flex; align-items: center; flex-wrap: wrap;
  gap: .25rem 1.25rem;
  padding: .5rem 1rem;
  overflow: visible;
  border-right: 0;
  border-bottom: 1px solid rgba(255, 255, 255, .12);
}
.shell.layout-topbar .brand {
  margin: 0 .75rem 0 0; padding: 0; border: 0; white-space: nowrap;
  display: flex; align-items: center; gap: .5rem;
}
.shell.layout-topbar .brand small { display: none; }
.shell.layout-topbar .brand-logo { max-height: 26px; }
.shell.layout-topbar .company-switch { margin: 0; padding: 0; border: 0; }
.shell.layout-topbar .company-switch label { display: none; }

/* The nav becomes a row. Each group heading turns into the label of the
   cluster that follows it, and the cluster opens on hover or focus — so it
   works with a mouse, a keyboard and a touch screen. */
.shell.layout-topbar .nav {
  display: flex; align-items: center; flex-wrap: wrap; gap: .1rem .35rem;
  padding: 0; margin: 0; flex: 1; min-width: 0;
}
.shell.layout-topbar .nav > a {
  padding: .35rem .6rem; border-radius: 6px; white-space: nowrap;
}
.shell.layout-topbar .nav-group {
  position: relative; margin: 0; padding: .35rem .6rem;
  border-radius: 6px; cursor: default; white-space: nowrap;
  font-size: .8rem; letter-spacing: .01em; text-transform: none;
  opacity: .95;
}
.shell.layout-topbar .nav-group::after { content: " ▾"; opacity: .55; font-size: .7em; }
.shell.layout-topbar .nav-group:hover { background: rgba(255, 255, 255, .1); }

/* Everything between one group heading and the next becomes that heading's
   drop-down. Done with sibling selectors so the HTML stays one flat list. */
.shell.layout-topbar .nav-group ~ a { display: none; }
.shell.layout-topbar .nav-group:hover ~ a,
.shell.layout-topbar .nav-group:focus-within ~ a { display: block; }

.shell.layout-topbar .main { width: 100%; }
.shell.layout-topbar .content { max-width: 1500px; margin: 0 auto; }

/* --- No standing menu ---------------------------------------------------- */

.shell.layout-focused { display: block; }
.shell.layout-focused .sidebar {
  position: fixed; top: 0; left: 0; bottom: 0; z-index: 60;
  transform: translateX(-100%); transition: transform .18s ease;
  box-shadow: 0 0 40px rgba(0, 0, 0, .3);
}
body.menu-open .shell.layout-focused .sidebar { transform: translateX(0); }
.shell.layout-focused .main { width: 100%; }
.shell.layout-focused .content { max-width: 1100px; margin: 0 auto; }

.shell.layout-focused .menu-button,
body[data-layout="focused"] .menu-button { display: flex; }

.menu-button {
  position: fixed; top: .7rem; left: .7rem; z-index: 70;
  width: 40px; height: 36px; padding: 8px 9px;
  flex-direction: column; justify-content: space-between;
  background: var(--card); border: 1px solid var(--line); border-radius: 8px;
  cursor: pointer; box-shadow: 0 1px 3px rgba(0, 0, 0, .12);
}
.menu-button span { display: block; height: 2px; background: var(--ink); border-radius: 2px; }
.shell.layout-focused .content,
.shell.layout-focused .topbar { padding-left: 3.4rem; }

/* --- Narrow windows -----------------------------------------------------
   Below this width there is not room for a standing menu in any arrangement,
   so every arrangement behaves like the focused one. */

@media (max-width: 900px) {
  .shell .sidebar {
    position: fixed; top: 0; left: 0; bottom: 0; z-index: 60; width: 17rem;
    transform: translateX(-100%); transition: transform .18s ease;
    box-shadow: 0 0 40px rgba(0, 0, 0, .3);
    display: block; overflow-y: auto;
  }
  body.menu-open .shell .sidebar { transform: translateX(0); }
  .shell .main { width: 100%; }
  .menu-button { display: flex; }
  .shell.layout-topbar .nav-group ~ a { display: block; }
  .shell .content { padding-left: 1rem; padding-right: 1rem; }
  .shell.layout-focused .content { padding-left: 1rem; }
  .page-head { padding-left: 3.2rem; }
}

/* A backdrop, so tapping away from an open menu shuts it. */
body.menu-open::after {
  content: ""; position: fixed; inset: 0; z-index: 50;
  background: rgba(0, 0, 0, .35);
}
@media (min-width: 901px) {
  .shell.layout-sidebar ~ * body.menu-open::after { display: none; }
}

/* --- Choosing an arrangement -------------------------------------------- */

.layout-grid {
  display: grid; gap: .75rem;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
}
.layout-option {
  display: flex; flex-direction: column; gap: .3rem;
  padding: .8rem; border: 1px solid var(--line); border-radius: 10px;
  cursor: pointer; background: var(--card);
}
.layout-option:hover { border-color: var(--accent); }
.layout-option.chosen { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-soft); }
.layout-option input { position: absolute; opacity: 0; pointer-events: none; }

/* A small picture of the arrangement, so nobody has to read to understand it. */
.layout-sketch {
  display: flex; gap: 3px; height: 46px; margin-bottom: .35rem;
  border: 1px solid var(--line); border-radius: 5px; padding: 3px;
  background: var(--card-soft);
}
.layout-sketch span { display: block; border-radius: 3px; }
.ls-menu { background: var(--accent); }
.ls-body { background: var(--line); flex: 1; }
.layout-sketch-sidebar .ls-menu { width: 26%; }
.layout-sketch-topbar { flex-direction: column; }
.layout-sketch-topbar .ls-menu { height: 22%; }
.layout-sketch-focused .ls-menu { width: 8%; opacity: .45; }
