/* ==========================================================================
   billing admin design system

   Shares nothing with hershi-d.com. It takes its palette from the invoice
   template (ink #1b2230, accent #274b8f, hairline borders, tabular figures) so
   the admin and the printed documents read as one family, but the admin is its
   own interface: dense, quiet, keyboard first, nothing decorative.

   Light mode only for now. Every colour is a custom property and the dark set
   is already written under [data-theme="dark"], so turning it on later is one
   attribute on <html> and nothing else. prefers-color-scheme is deliberately
   NOT used, so dark can never switch itself on before it has been reviewed.

   Contents
     1.  Tokens
     2.  Reset and base
     3.  Layout shell
     4.  Sidebar and navigation
     5.  Topbar, page head, breadcrumbs
     6.  Flash messages
     7.  Buttons
     8.  Forms
     9.  Tables
     10. Cards, stats, key/value
     11. Badges and status
     12. Toolbar, filters, tabs, pager
     13. Empty states
     14. Utilities
     15. Responsive
     16. Print
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */

:root {
  /* Ink */
  --ink:          #1b2230;
  --ink-soft:     #68727f;
  --ink-faint:    #97a0ad;
  --ink-invert:   #ffffff;

  /* Surfaces */
  --bg:           #f4f6f9;
  --surface:      #ffffff;
  --surface-2:    #fafbfc;
  --surface-3:    #f2f5fb;
  --surface-sunk: #eef1f5;

  /* Lines */
  --line:         #e5e8ee;
  --line-strong:  #c9cfda;

  /* Accent */
  --accent:       #274b8f;
  --accent-hover: #1f3f79;
  --accent-soft:  #f2f5fb;
  --accent-line:  #c2d0e8;

  /* Status */
  --ok:          #1d6b45;
  --ok-soft:     #e8f4ed;
  --ok-line:     #b8dcc8;
  --warn:        #8a5a11;
  --warn-soft:   #fdf3e2;
  --warn-line:   #e8d3ac;
  --danger:      #a52f2f;
  --danger-hover:#8c2727;
  --danger-soft: #fbeaea;
  --danger-line: #eec7c7;
  --info:        #274b8f;
  --info-soft:   #f2f5fb;
  --info-line:   #c2d0e8;

  /* Type */
  --sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
  --mono: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, 'Liberation Mono', monospace;

  --fs-xs:   11.5px;
  --fs-sm:   12.5px;
  --fs-base: 14px;
  --fs-md:   15px;
  --fs-lg:   18px;
  --fs-xl:   22px;
  --fs-2xl:  27px;

  --lh-tight: 1.25;
  --lh:       1.5;

  /* Space, a 4px scale */
  --s1: 4px;
  --s2: 8px;
  --s3: 12px;
  --s4: 16px;
  --s5: 20px;
  --s6: 24px;
  --s7: 32px;
  --s8: 44px;

  /* Shape */
  --r-sm: 4px;
  --r:    6px;
  --r-lg: 8px;

  /* Chrome */
  --sidebar-w: 208px;
  --topbar-h:  56px;
  --content-max: 1180px;

  /* Depth. One soft shadow, used sparingly. No glows anywhere. */
  --shadow: 0 1px 2px rgba(27, 34, 48, .06), 0 4px 12px rgba(27, 34, 48, .05);

  --focus: 2px solid var(--accent);
  --focus-offset: 1px;
}

/* Ready for a later drop-in. Nothing sets data-theme yet. */
:root[data-theme="dark"] {
  --ink:          #e7ebf1;
  --ink-soft:     #99a3b1;
  --ink-faint:    #6d7787;
  --ink-invert:   #10141c;

  --bg:           #10141c;
  --surface:      #171c26;
  --surface-2:    #1c222e;
  --surface-3:    #1f2735;
  --surface-sunk: #0d1118;

  --line:         #262d3a;
  --line-strong:  #38414f;

  --accent:       #6f97dc;
  --accent-hover: #86a9e4;
  --accent-soft:  #1b2432;
  --accent-line:  #33456b;

  --ok:          #5fc08c;
  --ok-soft:     #14251c;
  --ok-line:     #264834;
  --warn:        #d9a45c;
  --warn-soft:   #251d10;
  --warn-line:   #473519;
  --danger:      #e07a7a;
  --danger-hover:#eb9393;
  --danger-soft: #2a1616;
  --danger-line: #4d2a2a;
  --info:        #6f97dc;
  --info-soft:   #1b2432;
  --info-line:   #33456b;

  --shadow: 0 1px 2px rgba(0, 0, 0, .4), 0 4px 12px rgba(0, 0, 0, .3);
}

/* --------------------------------------------------------------------------
   2. Reset and base
   -------------------------------------------------------------------------- */

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

html, body { margin: 0; padding: 0; }

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

body {
  font-family: var(--sans);
  font-size: var(--fs-base);
  line-height: var(--lh);
  color: var(--ink);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

h1, h2, h3, h4 { margin: 0; font-weight: 600; line-height: var(--lh-tight); letter-spacing: -0.011em; }
h1 { font-size: var(--fs-xl); }
h2 { font-size: var(--fs-lg); }
h3 { font-size: var(--fs-md); }
h4 { font-size: var(--fs-base); }

p { margin: 0 0 var(--s3); }
p:last-child { margin-bottom: 0; }

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

hr { border: 0; border-top: 1px solid var(--line); margin: var(--s5) 0; }

code, kbd, pre { font-family: var(--mono); font-size: var(--fs-sm); }

kbd {
  border: 1px solid var(--line-strong);
  border-bottom-width: 2px;
  border-radius: var(--r-sm);
  padding: 1px 5px;
  background: var(--surface-2);
  font-size: var(--fs-xs);
}

/* One focus treatment everywhere. Never removed, because this app is meant to
   be driven from the keyboard. */
:focus-visible {
  outline: var(--focus);
  outline-offset: var(--focus-offset);
  border-radius: var(--r-sm);
}
:focus:not(:focus-visible) { outline: none; }

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

/* --------------------------------------------------------------------------
   3. Layout shell
   -------------------------------------------------------------------------- */

.app {
  display: grid;
  grid-template-columns: var(--sidebar-w) minmax(0, 1fr);
  min-height: 100vh;
}

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

.content {
  flex: 1;
  width: 100%;
  /* min-width:0 matters. Without it a flex item refuses to shrink below its
     content, so the 780px line items table pushed the whole page wider than a
     phone instead of scrolling inside its own wrapper. */
  min-width: 0;
  max-width: var(--content-max);
  margin: 0 auto;
  padding: var(--s6) var(--s6) var(--s8);
}

.content--wide { max-width: none; }
.content--narrow { max-width: 720px; }

/* The public pay page and the printable documents use this instead of .app. */
.plain {
  min-height: 100vh;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: var(--s8) var(--s4);
}

/* --------------------------------------------------------------------------
   4. Sidebar and navigation
   -------------------------------------------------------------------------- */

.sidebar {
  background: var(--surface);
  border-right: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
}

.sidebar__brand {
  display: flex;
  align-items: center;
  gap: var(--s2);
  height: var(--topbar-h);
  padding: 0 var(--s4);
  border-bottom: 1px solid var(--line);
  flex: 0 0 auto;
}

.sidebar__mark {
  width: 22px;
  height: 22px;
  border-radius: var(--r-sm);
  background: var(--accent);
  color: #fff;
  font-size: var(--fs-xs);
  font-weight: 700;
  display: grid;
  place-items: center;
  flex: 0 0 auto;
}

.sidebar__name {
  font-size: var(--fs-md);
  font-weight: 600;
  letter-spacing: -0.015em;
  color: var(--ink);
}
.sidebar__brand:hover { text-decoration: none; }

.nav { padding: var(--s3) var(--s2); flex: 1 1 auto; }

.nav__label {
  font-size: var(--fs-xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--ink-faint);
  padding: var(--s3) var(--s3) var(--s1);
}

.nav__link {
  display: flex;
  align-items: center;
  gap: var(--s2);
  padding: 6px var(--s3);
  margin-bottom: 1px;
  border-radius: var(--r);
  color: var(--ink-soft);
  font-size: var(--fs-base);
  font-weight: 500;
  border-left: 2px solid transparent;
}
.nav__link:hover { background: var(--surface-2); color: var(--ink); text-decoration: none; }
.nav__link.is-active {
  background: var(--accent-soft);
  color: var(--accent);
  border-left-color: var(--accent);
  font-weight: 600;
}

.nav__key {
  margin-left: auto;
  font-size: var(--fs-xs);
  color: var(--ink-faint);
  font-family: var(--mono);
}

.sidebar__foot {
  border-top: 1px solid var(--line);
  padding: var(--s3);
  font-size: var(--fs-sm);
  color: var(--ink-faint);
  flex: 0 0 auto;
}
.sidebar__foot a { color: var(--ink-soft); }

/* --------------------------------------------------------------------------
   5. Topbar, page head, breadcrumbs
   -------------------------------------------------------------------------- */

.topbar {
  height: var(--topbar-h);
  display: flex;
  align-items: center;
  gap: var(--s3);
  padding: 0 var(--s6);
  background: var(--surface);
  border-bottom: 1px solid var(--line);
  position: sticky;
  top: 0;
  z-index: 20;
}

.topbar__title { font-size: var(--fs-md); font-weight: 600; }
.topbar__spacer { margin-left: auto; }

/* The hamburger. Hidden entirely on a wide screen, where the sidebar is simply
   a column and there is nothing to toggle. */
.topbar__menu {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 40px;
  height: 40px;
  padding: 0 9px;
  margin-left: calc(var(--s2) * -1);
  background: none;
  border: 0;
  border-radius: var(--r-sm);
  cursor: pointer;
  flex: 0 0 auto;
}
.topbar__menu span {
  display: block;
  height: 2px;
  width: 100%;
  background: var(--ink);
  border-radius: 2px;
}
.topbar__menu:hover { background: var(--fill, rgba(0, 0, 0, 0.04)); }
.topbar__menu:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.nav-backdrop { display: none; }
.nav-backdrop[hidden] { display: none; }

.crumbs {
  display: flex;
  align-items: center;
  gap: var(--s2);
  font-size: var(--fs-sm);
  color: var(--ink-soft);
  margin-bottom: var(--s3);
  flex-wrap: wrap;
}
.crumbs__sep { color: var(--ink-faint); }

.page-head {
  display: flex;
  align-items: flex-start;
  gap: var(--s4);
  flex-wrap: wrap;
  margin-bottom: var(--s5);
}
.page-head__text { min-width: 0; }
.page-head__title { font-size: var(--fs-2xl); letter-spacing: -0.02em; }
.page-head__sub { margin-top: 2px; color: var(--ink-soft); font-size: var(--fs-base); }
.page-head__actions { margin-left: auto; display: flex; gap: var(--s2); flex-wrap: wrap; align-items: center; }

.section-head {
  display: flex;
  align-items: center;
  gap: var(--s3);
  margin: var(--s7) 0 var(--s3);
}
.section-head:first-child { margin-top: 0; }
.section-head h2 { font-size: var(--fs-lg); }
.section-head .btn { margin-left: auto; }

/* --------------------------------------------------------------------------
   6. Flash messages
   -------------------------------------------------------------------------- */

.flashes { display: flex; flex-direction: column; gap: var(--s2); margin-bottom: var(--s4); }

.flash {
  display: flex;
  align-items: flex-start;
  gap: var(--s3);
  padding: var(--s3) var(--s4);
  border: 1px solid var(--line);
  border-left-width: 3px;
  border-radius: var(--r);
  background: var(--surface);
  font-size: var(--fs-base);
}
.flash__body { flex: 1; min-width: 0; }
.flash__close {
  background: none;
  border: 0;
  color: inherit;
  opacity: .55;
  cursor: pointer;
  font-size: var(--fs-lg);
  line-height: 1;
  padding: 0 2px;
}
.flash__close:hover { opacity: 1; }

.flash--success { background: var(--ok-soft);     border-color: var(--ok-line);     border-left-color: var(--ok);     color: var(--ok); }
.flash--error   { background: var(--danger-soft); border-color: var(--danger-line); border-left-color: var(--danger); color: var(--danger); }
.flash--warning { background: var(--warn-soft);   border-color: var(--warn-line);   border-left-color: var(--warn);   color: var(--warn); }
.flash--info    { background: var(--info-soft);   border-color: var(--info-line);   border-left-color: var(--info);   color: var(--info); }

/* --------------------------------------------------------------------------
   7. Buttons
   -------------------------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s2);
  font-family: inherit;
  font-size: var(--fs-base);
  font-weight: 500;
  line-height: 1.2;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--r);
  padding: 8px var(--s4);
  cursor: pointer;
  white-space: nowrap;
  text-decoration: none;
}
.btn:hover { background: var(--surface-2); border-color: var(--ink-faint); text-decoration: none; }
.btn:active { background: var(--surface-sunk); }
.btn[disabled], .btn.is-disabled {
  opacity: .5;
  cursor: not-allowed;
  pointer-events: none;
}

.btn--primary {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
  font-weight: 600;
}
.btn--primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); }

.btn--danger {
  background: var(--surface);
  border-color: var(--danger-line);
  color: var(--danger);
}
.btn--danger:hover { background: var(--danger-soft); border-color: var(--danger); }

.btn--danger-solid {
  background: var(--danger);
  border-color: var(--danger);
  color: #fff;
  font-weight: 600;
}
.btn--danger-solid:hover { background: var(--danger-hover); border-color: var(--danger-hover); }

.btn--ghost {
  background: transparent;
  border-color: transparent;
  color: var(--ink-soft);
}
.btn--ghost:hover { background: var(--surface-2); color: var(--ink); border-color: transparent; }

.btn--link {
  background: none;
  border: 0;
  padding: 0;
  color: var(--accent);
  font-weight: 500;
}
.btn--link:hover { background: none; text-decoration: underline; }

.btn--sm { padding: 4px 10px; font-size: var(--fs-sm); border-radius: var(--r-sm); }
.btn--lg { padding: 11px var(--s5); font-size: var(--fs-md); }
.btn--block { display: flex; width: 100%; }

.btn-row { display: flex; gap: var(--s2); flex-wrap: wrap; align-items: center; }
.btn-row--end { justify-content: flex-end; }
.btn-row--split > .btn-row__right { margin-left: auto; display: flex; gap: var(--s2); }

/* --------------------------------------------------------------------------
   8. Forms
   -------------------------------------------------------------------------- */

.field { margin-bottom: var(--s4); min-width: 0; }
.field:last-child { margin-bottom: 0; }

.label {
  display: block;
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--ink-soft);
  margin-bottom: var(--s1);
}
.label__req { color: var(--danger); font-weight: 400; }
.label__opt { color: var(--ink-faint); font-weight: 400; }

.input, .select, .textarea {
  display: block;
  width: 100%;
  font-family: inherit;
  font-size: var(--fs-base);
  line-height: 1.4;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--r);
  padding: 8px 10px;
}
.input::placeholder, .textarea::placeholder { color: var(--ink-faint); }
.input:hover, .select:hover, .textarea:hover { border-color: var(--ink-faint); }
.input:focus, .select:focus, .textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--accent);
}
.input[readonly], .input[disabled], .select[disabled], .textarea[disabled] {
  background: var(--surface-sunk);
  color: var(--ink-soft);
  cursor: not-allowed;
}

.textarea { resize: vertical; min-height: 84px; }

.select {
  appearance: none;
  padding-right: var(--s7);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='%2368727f' d='M1.4 0 6 4.6 10.6 0 12 1.4 6 7.4 0 1.4z'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 11px center;
}

/* Numeric and code inputs line up in columns. */
.input--num, .input--money, .input--rate, .input--code {
  font-variant-numeric: tabular-nums;
  text-align: right;
}
.input--code { text-align: left; font-family: var(--mono); letter-spacing: .08em; }

.hint { margin-top: var(--s1); font-size: var(--fs-sm); color: var(--ink-soft); }

.error-text { margin-top: var(--s1); font-size: var(--fs-sm); color: var(--danger); font-weight: 500; }

.field--error .input,
.field--error .select,
.field--error .textarea { border-color: var(--danger); }
.field--error .input:focus { box-shadow: inset 0 0 0 1px var(--danger); }

/* Prefixed input, for a currency symbol or a rate. */
.input-group { display: flex; align-items: stretch; }
.input-group__addon {
  display: inline-flex;
  align-items: center;
  padding: 0 10px;
  background: var(--surface-2);
  border: 1px solid var(--line-strong);
  border-right: 0;
  border-radius: var(--r) 0 0 var(--r);
  color: var(--ink-soft);
  font-size: var(--fs-base);
  white-space: nowrap;
}
.input-group__addon--end { border-right: 1px solid var(--line-strong); border-left: 0; border-radius: 0 var(--r) var(--r) 0; }
.input-group .input { border-radius: 0 var(--r) var(--r) 0; }
.input-group .input:first-child { border-radius: var(--r) 0 0 var(--r); }
.input-group > .input:only-child { border-radius: var(--r); }

.check {
  display: flex;
  align-items: flex-start;
  gap: var(--s2);
  font-size: var(--fs-base);
  cursor: pointer;
  margin-bottom: var(--s2);
}
.check input { margin: 3px 0 0; accent-color: var(--accent); flex: 0 0 auto; }
.check__text { min-width: 0; }
.check__hint { display: block; font-size: var(--fs-sm); color: var(--ink-soft); }

.form-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 var(--s5); }
.form-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.form-grid__full { grid-column: 1 / -1; }

.form-actions {
  display: flex;
  gap: var(--s2);
  align-items: center;
  margin-top: var(--s6);
  padding-top: var(--s4);
  border-top: 1px solid var(--line);
}
.form-actions__end { margin-left: auto; display: flex; gap: var(--s2); }

fieldset { border: 0; margin: 0; padding: 0; min-width: 0; }
legend {
  padding: 0;
  font-size: var(--fs-sm);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--ink-faint);
  margin-bottom: var(--s3);
}

/* --------------------------------------------------------------------------
   9. Tables
   -------------------------------------------------------------------------- */

.table-wrap {
  overflow-x: auto;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--surface);
}
.table-wrap .table { border: 0; border-radius: 0; }

.table {
  width: 100%;
  border-collapse: collapse;
  background: var(--surface);
  font-size: var(--fs-base);
}

.table th {
  text-align: left;
  font-size: var(--fs-xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--ink-soft);
  padding: var(--s3) var(--s4);
  border-bottom: 1px solid var(--line-strong);
  white-space: nowrap;
  background: var(--surface-2);
}

.table td {
  padding: var(--s3) var(--s4);
  border-bottom: 1px solid var(--line);
  vertical-align: top;
}

.table tbody tr:last-child td { border-bottom: 0; }
.table tbody tr:hover td { background: var(--surface-2); }

.table--dense th { padding: var(--s2) var(--s3); }
.table--dense td { padding: 6px var(--s3); }

.table--fixed { table-layout: fixed; }

/* Tabular figures on every number, so columns of money line up. */
.table .num, .table th.num, .num {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.table .mono, .mono { font-family: var(--mono); font-size: var(--fs-sm); }

.table tfoot td {
  border-top: 1px solid var(--line-strong);
  border-bottom: 0;
  font-weight: 600;
  background: var(--surface-2);
}

.table__sort { color: inherit; display: inline-flex; align-items: center; gap: 4px; }
.table__sort:hover { color: var(--ink); text-decoration: none; }
.table__sort[aria-sort="ascending"]::after  { content: "\2191"; }
.table__sort[aria-sort="descending"]::after { content: "\2193"; }

.table__actions { text-align: right; white-space: nowrap; }
.table__actions .btn { margin-left: var(--s1); }

.table tr.is-void td { color: var(--ink-faint); }
.table tr.is-void .table__primary { text-decoration: line-through; }

.table__primary { font-weight: 500; color: var(--ink); }
.table__secondary { display: block; font-size: var(--fs-sm); color: var(--ink-soft); }

/* --------------------------------------------------------------------------
   10. Cards, stats, key/value
   -------------------------------------------------------------------------- */

.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  margin-bottom: var(--s5);
}
.card:last-child { margin-bottom: 0; }

.card__head {
  display: flex;
  align-items: center;
  gap: var(--s3);
  padding: var(--s4) var(--s5);
  border-bottom: 1px solid var(--line);
}
.card__title { font-size: var(--fs-md); font-weight: 600; }
.card__head .btn { margin-left: auto; }
.card__body { padding: var(--s5); }
.card__body--flush { padding: 0; }
.card__foot {
  padding: var(--s4) var(--s5);
  border-top: 1px solid var(--line);
  background: var(--surface-2);
  border-radius: 0 0 var(--r-lg) var(--r-lg);
}

.stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: var(--s3);
  margin-bottom: var(--s5);
}

.stat {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: var(--s4);
}
.stat__label {
  font-size: var(--fs-xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--ink-soft);
}
.stat__value {
  margin-top: var(--s1);
  font-size: var(--fs-xl);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
}
.stat__note { margin-top: 2px; font-size: var(--fs-sm); color: var(--ink-soft); }
.stat--accent { background: var(--accent-soft); border-color: var(--accent-line); }
.stat--accent .stat__value { color: var(--accent); }

.kv { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--s2) var(--s4); margin: 0; font-size: var(--fs-base); }
.kv dt { color: var(--ink-soft); white-space: nowrap; }
.kv dd { margin: 0; min-width: 0; }
.kv dd.num { text-align: left; font-variant-numeric: tabular-nums; }
.kv--tight { gap: var(--s1) var(--s3); font-size: var(--fs-sm); }

/* --------------------------------------------------------------------------
   11. Badges and status
   -------------------------------------------------------------------------- */

.badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 8px;
  border-radius: 999px;
  border: 1px solid var(--line-strong);
  background: var(--surface-2);
  color: var(--ink-soft);
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: .02em;
  text-transform: uppercase;
  white-space: nowrap;
}

.badge--draft   { background: var(--surface-2);   border-color: var(--line-strong); color: var(--ink-soft); }
.badge--sent    { background: var(--info-soft);   border-color: var(--info-line);   color: var(--info); }
.badge--paid    { background: var(--ok-soft);     border-color: var(--ok-line);     color: var(--ok); }
.badge--void    { background: var(--surface-sunk);border-color: var(--line-strong); color: var(--ink-faint); }
.badge--overdue { background: var(--danger-soft); border-color: var(--danger-line); color: var(--danger); }
.badge--warning { background: var(--warn-soft);   border-color: var(--warn-line);   color: var(--warn); }

.badge--plain {
  text-transform: none;
  letter-spacing: 0;
  font-weight: 500;
  font-size: var(--fs-sm);
}

.amount-in  { color: var(--ok); }
.amount-out { color: var(--danger); }
.amount-nil { color: var(--ink-faint); }

/* The payment code, wherever it is shown. Monospaced and spaced out so a
   leading zero is unmistakable. */
.code {
  font-family: var(--mono);
  font-size: var(--fs-base);
  letter-spacing: .12em;
  background: var(--surface-3);
  border: 1px solid var(--accent-line);
  border-radius: var(--r-sm);
  padding: 1px 7px;
  color: var(--ink);
}

/* --------------------------------------------------------------------------
   12. Toolbar, filters, tabs, pager
   -------------------------------------------------------------------------- */

.toolbar {
  display: flex;
  align-items: center;
  gap: var(--s2);
  flex-wrap: wrap;
  margin-bottom: var(--s4);
}
.toolbar__end { margin-left: auto; display: flex; gap: var(--s2); align-items: center; }

/* Filters.
   This was a wrapping flex row with align-items:flex-end. On a narrow screen
   the search box took the first line on its own and the remaining flex lines
   were spread apart, which read as a tall empty gap between the search box and
   the first select. A block container with an explicit grid underneath is
   deterministic and cannot do that at any width.

   The search box and its button stay visible. Everything else lives in a
   <details class="filters__more">, closed unless a filter is actually applied. */
.filters {
  padding: var(--s4);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  margin-bottom: var(--s4);
}
.filters .field { margin-bottom: 0; }

.filters__bar {
  display: flex;
  gap: var(--s3);
  align-items: center;
}
.filters__bar .field { flex: 1 1 auto; min-width: 0; }
.filters__bar .input { width: 100%; min-width: 0; }
.filters__bar .btn { flex: 0 0 auto; }

.filters__more { margin-top: var(--s3); }
.filters__more > summary {
  cursor: pointer;
  list-style: none;
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--ink-soft);
  padding: var(--s1) 0;
  -webkit-user-select: none;
  user-select: none;
}
.filters__more > summary::-webkit-details-marker { display: none; }
.filters__more > summary::before {
  content: "\25B8";
  display: inline-block;
  width: 1.1em;
}
.filters__more[open] > summary::before { content: "\25BE"; }
.filters__more > summary:hover { color: var(--ink); }
.filters__more > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.filters__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--s3);
  margin-top: var(--s2);
}
.filters__grid .input,
.filters__grid .select { width: 100%; min-width: 0; }

.filters .btn-row { margin-top: var(--s3); }

/* A quiet correction control tucked beside a value, for the few fields that
   describe a record rather than calculate anything. */
.inline-edit { display: inline; }
.inline-edit > summary {
  display: inline;
  cursor: pointer;
  list-style: none;
  margin-left: var(--s2);
  font-size: var(--fs-sm);
  color: var(--ink-soft);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.inline-edit > summary::-webkit-details-marker { display: none; }
.inline-edit > summary:hover { color: var(--accent); }
.inline-edit > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.inline-edit form { margin-top: var(--s2); }
.inline-edit__row {
  display: flex;
  gap: var(--s2);
  align-items: center;
  flex-wrap: wrap;
}
.inline-edit__row .select { min-width: 0; flex: 0 1 200px; }

.tabs {
  display: flex;
  gap: var(--s1);
  border-bottom: 1px solid var(--line);
  margin-bottom: var(--s5);
  overflow-x: auto;
}
.tab {
  padding: var(--s2) var(--s3);
  color: var(--ink-soft);
  font-weight: 500;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  white-space: nowrap;
}
.tab:hover { color: var(--ink); text-decoration: none; }
.tab.is-active { color: var(--accent); border-bottom-color: var(--accent); font-weight: 600; }

.pager {
  display: flex;
  align-items: center;
  gap: var(--s2);
  margin-top: var(--s4);
  font-size: var(--fs-sm);
  color: var(--ink-soft);
  flex-wrap: wrap;
}
.pager__end { margin-left: auto; display: flex; gap: var(--s2); align-items: center; }

/* --------------------------------------------------------------------------
   13. Empty states
   -------------------------------------------------------------------------- */

.empty {
  text-align: center;
  padding: var(--s8) var(--s5);
  color: var(--ink-soft);
  background: var(--surface);
  border: 1px dashed var(--line-strong);
  border-radius: var(--r-lg);
}
.empty__title { font-size: var(--fs-md); font-weight: 600; color: var(--ink); margin-bottom: var(--s1); }
.empty__body { max-width: 44ch; margin: 0 auto var(--s4); }
.empty--flush { border: 0; background: none; padding: var(--s7) var(--s5); }

/* --------------------------------------------------------------------------
   14. Utilities
   -------------------------------------------------------------------------- */

.muted     { color: var(--ink-soft); }
.faint     { color: var(--ink-faint); }
.strong    { font-weight: 600; }
.small     { font-size: var(--fs-sm); }
.xsmall    { font-size: var(--fs-xs); }
.nowrap    { white-space: nowrap; }
.truncate  { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pre-line  { white-space: pre-line; }
.right     { text-align: right; }
.center    { text-align: center; }
.tabular   { font-variant-numeric: tabular-nums; }
.hidden    { display: none !important; }

.row   { display: flex; gap: var(--s3); align-items: center; flex-wrap: wrap; }
.row--top { align-items: flex-start; }
.stack { display: flex; flex-direction: column; gap: var(--s3); }
.stack--tight { gap: var(--s1); }
.grid-2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s5); }
.grid-3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s5); }
.spacer { margin-left: auto; }

.mt-0 { margin-top: 0; }      .mb-0 { margin-bottom: 0; }
.mt-1 { margin-top: var(--s1); } .mb-1 { margin-bottom: var(--s1); }
.mt-2 { margin-top: var(--s2); } .mb-2 { margin-bottom: var(--s2); }
.mt-3 { margin-top: var(--s3); } .mb-3 { margin-bottom: var(--s3); }
.mt-4 { margin-top: var(--s4); } .mb-4 { margin-bottom: var(--s4); }
.mt-5 { margin-top: var(--s5); } .mb-5 { margin-bottom: var(--s5); }
.mt-6 { margin-top: var(--s6); } .mb-6 { margin-bottom: var(--s6); }

.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;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: var(--accent);
  color: #fff;
  padding: var(--s2) var(--s4);
  border-radius: 0 0 var(--r) 0;
}
.skip-link:focus { left: 0; }

/* --------------------------------------------------------------------------
   15. Responsive
   -------------------------------------------------------------------------- */

@media (max-width: 900px) {
  .app { grid-template-columns: 1fr; }

  /* The sidebar becomes an off canvas drawer behind the hamburger.
     It used to flatten into a wrapping row of every link above the content,
     which ate most of a phone screen and threw away the group headings. As a
     drawer it keeps the real sidebar layout, headings and all. */
  .sidebar {
    position: fixed;
    top: 0;
    left: 0;
    width: min(82vw, 300px);
    height: 100vh;
    height: 100dvh;
    z-index: 60;
    border-right: 1px solid var(--line);
    transform: translateX(-100%);
    transition: transform 0.22s ease;
    overflow-y: auto;
  }
  .sidebar.is-open {
    transform: none;
    box-shadow: 0 0 40px rgba(27, 34, 48, 0.28);
  }

  /* Someone who turns animation off should still get an instant open. */
  @media (prefers-reduced-motion: reduce) {
    .sidebar { transition: none; }
  }

  .nav-backdrop {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 50;
    background: rgba(27, 34, 48, 0.45);
  }
  .nav-backdrop[hidden] { display: none; }

  /* Do not let the page scroll underneath an open drawer. */
  body.nav-open { overflow: hidden; }

  .topbar__menu { display: flex; }

  .content { padding: var(--s4) var(--s4) var(--s7); }
  .topbar { padding: 0 var(--s4); }

  .form-grid, .form-grid--3, .grid-2, .grid-3 { grid-template-columns: minmax(0, 1fr); }
  .page-head__actions { margin-left: 0; width: 100%; }
}

@media (max-width: 600px) {
  /* .filters is no longer a flex container, so the old flex-direction rule that
     lived here did nothing. The narrow layout is handled by filters__grid's
     auto-fit columns instead. This keeps only the width safety net. */
  .filters .input, .filters .select { min-width: 0; width: 100%; }
  .form-actions { flex-wrap: wrap; }
}

/* --------------------------------------------------------------------------
   16. Print

   Admin pages are not the printable artefact, the invoice and receipt
   documents are, and those bring their own stylesheet. This only makes an
   accidental print of an admin page readable.
   -------------------------------------------------------------------------- */

@media print {
  .sidebar, .topbar, .flashes, .page-head__actions, .toolbar, .filters,
  .pager, .table__actions, .form-actions, .skip-link, .no-print {
    display: none !important;
  }
  body { background: #fff; }
  .app { display: block; }
  .content { max-width: none; padding: 0; }
  .card, .table-wrap { border-color: #ccc; box-shadow: none; }
  a { color: inherit; text-decoration: none; }
}
