/* ==========================================================================
   Sijil — design tokens (transcribed from DESIGN.md, do not hand-tune here)
   ========================================================================== */

:root {
  /* Green scale */
  --green-700: #00583A;
  --green-600: #00724C;
  --green-500: #008A5D;
  --green-400: #00B67F;
  --green-200: #91DEBC;
  --green-100: #CDF2E0;

  /* Ink scale (green-shifted neutral — never pure grey) */
  --ink-900: #121E18;
  --ink-700: #313E38;
  --ink-500: #5C6661;
  --ink-300: #9EA7A3;
  --ink-100: #D9E0DD;
  --ink-050: #F0F5F2;
  --white: #FFFFFF;

  /* Semantic — bound to document state only */
  --success: #008A5D;
  --success-bg: #CDF2E0;
  --success-text: #00583A;
  --warning: #E1A035;
  --warning-bg: #FBF1DF;
  --warning-text: #8A5B0E;
  --error: #C13C3B;
  --error-bg: #FDECEB;
  --error-text: #8E2C2B;
  --info: #3077AD;
  --info-bg: #E4EEF7;
  --info-text: #1F4E73;
  --error-tint: #FFF7F6;
  --warning-tint: #FFFCF5;

  /* Type */
  --font-display: 'Familjen Grotesk', 'Inter', sans-serif;
  --font-body: 'Sora', 'Inter', sans-serif;
  --font-data: 'IBM Plex Mono', ui-monospace, 'SFMono-Regular', monospace;

  /* Spacing scale */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 24px;
  --sp-6: 34px;
  --sp-7: 52px;
  --sp-8: 76px;

  /* Shape */
  --r-control: 4px;
  --r-card: 6px;
  --r-pill: 100px;

  /* Content widths */
  --w-reading: 880px;
  --w-table: 1120px;
  --w-form: 520px;

  /* Motion — colour/opacity only, 120ms */
  --ease: cubic-bezier(0.4, 0, 0.2, 1);
  --dur: 120ms;
}

/* ==========================================================================
   Reset & base
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

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

body {
  margin: 0;
  background: var(--ink-050);
  color: var(--ink-900);
  font-family: var(--font-body);
  font-weight: 400;
  font-size: 16px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 { margin: 0; font-family: var(--font-display); color: var(--ink-900); }
p { margin: 0; }
a { color: inherit; }
button { font-family: var(--font-body); cursor: pointer; }
ul { margin: 0; padding: 0; list-style: none; }

/* Selection, caret, focus, scrollbar — theme the browser surfaces */
::selection { background: var(--green-200); color: var(--ink-900); }
:focus-visible {
  outline: 2px solid var(--green-600);
  outline-offset: 2px;
}
input, textarea, select { caret-color: var(--green-600); }
* { scrollbar-color: var(--ink-300) var(--ink-050); scrollbar-width: thin; }
::-webkit-scrollbar { height: 10px; width: 10px; }
::-webkit-scrollbar-track { background: var(--ink-050); }
::-webkit-scrollbar-thumb { background: var(--ink-300); border-radius: var(--r-pill); border: 2px solid var(--ink-050); }

.container {
  max-width: var(--w-table);
  margin: 0 auto;
  padding: 0 var(--sp-5);
}
.container--reading {
  max-width: calc(var(--w-reading) + (var(--sp-5) * 2));
}
.container--form {
  max-width: calc(var(--w-form) + (var(--sp-5) * 2));
}

/* ==========================================================================
   Type scale
   ========================================================================== */

.display {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(2.75rem, 5.5vw, 4.75rem);
  line-height: 1.08;
  letter-spacing: -0.03em;
  max-width: 16ch;
}
.heading {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(1.5rem, 2.6vw, 1.75rem);
  line-height: 1.2;
  letter-spacing: -0.025em;
}
/* Card/row-level sub-steps of the Heading role — same family, smaller scope. */
.heading--card { font-size: 1.375rem; }
.heading--row { font-size: 1.25rem; }
.subhead {
  font-family: var(--font-body);
  font-weight: 300;
  font-size: 1.1875rem;
  line-height: 1.6;
  color: var(--ink-700);
  max-width: 62ch;
}
.body-text {
  font-size: 1rem;
  line-height: 1.65;
  color: var(--ink-700);
  max-width: 68ch;
}
/* Caption sub-step of Body, for secondary helper text under a body paragraph. */
.caption-text { font-size: 0.875rem; color: var(--ink-500); }
.label {
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 0.6875rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-500);
}
.data {
  font-family: var(--font-data);
  font-variant-numeric: tabular-nums;
  font-weight: 500;
}

/* Eyebrow — the brand's square device. One square, never two. Used sparingly, section-level only. */
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  font-family: var(--font-data);
  font-weight: 500;
  font-size: 0.75rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--green-700);
  margin-bottom: var(--sp-4);
}
.eyebrow::before {
  content: '';
  width: 8px;
  height: 8px;
  background: var(--green-500);
  flex-shrink: 0;
}

/* ==========================================================================
   Buttons
   ========================================================================== */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  height: 48px;
  padding: 14px 24px;
  border-radius: var(--r-control);
  font-size: 1rem;
  font-weight: 500;
  text-decoration: none;
  border: none;
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease), color var(--dur) var(--ease);
  white-space: nowrap;
}
.btn--sm { height: 36px; padding: 8px 16px; font-size: 0.9375rem; }

/* green-600, not green-500: white-on-green-500 computes to 4.38:1, just under
   WCAG AA's 4.5:1 for normal-size text. green-600 clears it (~6:1). */
.btn--primary { background: var(--green-600); color: var(--white); }
.btn--primary:hover { background: var(--green-700); }

.btn--secondary { background: transparent; color: var(--ink-900); border: 1.5px solid var(--ink-900); }
.btn--secondary:hover { background: var(--white); }

.btn--quiet { background: transparent; color: var(--ink-700); border: 1.5px solid var(--ink-100); }
.btn--quiet:hover { border-color: var(--ink-300); }

.btn--on-dark { background: transparent; color: var(--white); border: 1.5px solid rgba(255,255,255,0.35); }
.btn--on-dark:hover { border-color: var(--white); background: rgba(255,255,255,0.06); }

.btn:disabled { opacity: 0.5; cursor: not-allowed; }

.btn-row { display: flex; flex-wrap: wrap; gap: var(--sp-4); align-items: center; }

/* ==========================================================================
   Fields
   ========================================================================== */

.field { display: flex; flex-direction: column; gap: var(--sp-2); }
.field + .field { margin-top: var(--sp-4); }
.field label { font-family: var(--font-body); font-weight: 500; font-size: 0.6875rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-500); }
.field-required { color: var(--error); text-transform: none; letter-spacing: 0; }
.field input,
.field select,
.field textarea {
  height: 48px;
  padding: 13px 14px;
  border: 1px solid var(--ink-100);
  border-radius: var(--r-control);
  font-family: var(--font-body);
  font-size: 1rem;
  color: var(--ink-900);
  background: var(--white);
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
  width: 100%;
}
.field textarea { height: auto; min-height: 112px; padding-top: 13px; resize: vertical; }
.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: none;
  border-color: var(--ink-900);
  box-shadow: 0 0 0 2px var(--green-600);
}
.field .hint { font-size: 0.8125rem; color: var(--ink-500); }
.field.has-error input { border-color: var(--error); }
.field .error-msg { font-size: 0.8125rem; color: var(--error); display: none; }
.field.has-error .error-msg { display: block; }

/* ==========================================================================
   Status pills & data pills
   ========================================================================== */

.pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border-radius: var(--r-pill);
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 0.8125rem;
  white-space: nowrap;
}
.pill::before { content: ''; width: 7px; height: 7px; flex-shrink: 0; }
.pill--success { background: var(--success-bg); color: var(--success-text); }
.pill--success::before { background: var(--success); }
.pill--warning { background: var(--warning-bg); color: var(--warning-text); }
.pill--warning::before { background: var(--warning); }
.pill--error { background: var(--error-bg); color: var(--error-text); }
.pill--error::before { background: var(--error); }
.pill--info { background: var(--info-bg); color: var(--info-text); }
.pill--info::before { background: var(--info); }
.pill--neutral { background: var(--ink-100); color: var(--ink-700); }
.pill--neutral::before { background: var(--ink-500); }

.data-pill {
  display: inline-flex;
  align-items: center;
  padding: 3px 9px;
  border: 1px solid var(--ink-100);
  border-radius: var(--r-pill);
  font-family: var(--font-data);
  font-size: 0.8125rem;
  color: var(--ink-700);
  white-space: nowrap;
}

/* ==========================================================================
   Cards, notices, tables
   ========================================================================== */

.card {
  background: var(--white);
  border: 1px solid var(--ink-100);
  border-radius: var(--r-card);
}

/* Modal — flat by the system's own rule (no shadow to lift the dialog off
   the page); the scrim behind it is what separates the two surfaces. */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(18, 30, 24, 0.6);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--sp-5);
  z-index: 100;
}
.modal-overlay[hidden] { display: none; }
.modal-dialog {
  background: var(--white);
  border: 1px solid var(--ink-100);
  border-radius: var(--r-card);
  padding: var(--sp-6);
  max-width: 720px;
  width: 100%;
  max-height: calc(100vh - var(--sp-8));
  overflow-y: auto;
  position: relative;
}
.modal-dialog__close {
  position: absolute;
  top: var(--sp-4);
  right: var(--sp-4);
  width: 32px;
  height: 32px;
  border: 1px solid var(--ink-100);
  background: var(--white);
  color: var(--ink-500);
  font-size: 1.125rem;
  line-height: 1;
  cursor: pointer;
  border-radius: var(--r-control);
}
.modal-dialog__close:hover { color: var(--ink-900); border-color: var(--ink-900); }
.modal-dialog__close:focus-visible { outline: 2px solid var(--green-600); outline-offset: 2px; }

.notice { background: var(--white); border: 1px solid var(--ink-100); border-radius: var(--r-card); padding: var(--sp-4) var(--sp-5); display: flex; gap: var(--sp-3); align-items: flex-start; }
.notice::before { content: ''; width: 8px; height: 8px; margin-top: 8px; flex-shrink: 0; background: var(--ink-500); }
.notice p { font-size: 0.9375rem; color: var(--ink-700); }
.notice strong { color: var(--ink-900); }
.notice--attention { background: var(--warning-bg); border-color: transparent; }
.notice--attention::before { background: var(--warning); }
.notice--irreversible { background: var(--ink-900); border-color: transparent; }
.notice--irreversible::before { background: var(--green-400); }
.notice--irreversible p { color: rgba(255,255,255,0.82); }
.notice--irreversible strong { color: var(--white); }

/* A notice that also carries an action (the billing "Pay"/"Buy invoices"
   warnings): text and button sit in one row, vertically centered against
   each other — the plain .notice above is tuned for text-only content
   (align-items: flex-start, so a multi-line paragraph reads top-aligned
   with its marker), which left a button placed after the text stranded
   below it instead of beside it. Wraps to its own line under the text on
   narrow viewports rather than compressing. */
.notice--with-action { align-items: center; flex-wrap: wrap; row-gap: var(--sp-3); }
.notice--with-action::before { margin-top: 0; }
.notice__body { flex: 1 1 240px; min-width: 0; }
.notice__body p { margin: 0; }
.notice--with-action .btn { flex-shrink: 0; }

/* One buyable invoice package, in Settings' billing section — name, count/
   total/per-invoice price, and a Buy button in one row, divided from the
   next by a hairline (matches the settings page's other list patterns). */
.package-row { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4); padding: var(--sp-4) 0; border-top: 1px solid var(--ink-100); }
.package-row__info { min-width: 0; }

.table-wrap { overflow-x: auto; border: 1px solid var(--ink-100); border-radius: var(--r-card); background: var(--white); }
table.data-table { width: 100%; border-collapse: collapse; min-width: 560px; }
.data-table thead th {
  text-align: left;
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 0.6875rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--white);
  background: var(--ink-900);
  padding: var(--sp-3) var(--sp-4);
}
.data-table thead th.num { text-align: right; }
.data-table tbody td {
  padding: var(--sp-3) var(--sp-4);
  border-bottom: 1px solid var(--ink-100);
  font-size: 0.9375rem;
  min-height: 48px;
  color: var(--ink-900);
}
.data-table tbody tr:last-child td { border-bottom: none; }
.data-table tbody tr { transition: background var(--dur) var(--ease); }
.data-table tbody tr:hover { background: var(--ink-050); }
.data-table td.num { text-align: right; font-family: var(--font-data); font-variant-numeric: tabular-nums; }
.data-table tr.exception td { background: var(--error-tint); position: relative; }
.data-table tr.exception td:first-child::before { content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 3px; background: var(--error); }
.data-table tr.row-link { cursor: pointer; }
.data-table tr.row-link:focus-visible { outline: 2px solid var(--green-600); outline-offset: -2px; }
.data-table td.is-low { color: var(--error); font-weight: 600; }

/* Sortable column headers: the button fills the th so the whole header
   cell is clickable, not just the text — same padding as a plain th so
   nothing shifts when a column becomes sortable. */
.data-table th.sortable { padding: 0; }
.th-sort-btn {
  all: unset;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  gap: 6px;
  width: 100%;
  padding: var(--sp-3) var(--sp-4);
  cursor: pointer;
  font: inherit;
  color: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
}
.data-table th.num .th-sort-btn { justify-content: flex-end; }
.th-sort-btn:hover { color: var(--green-200); }
.th-sort-btn:focus-visible { outline: 2px solid var(--green-400); outline-offset: -2px; }
.sort-arrow { display: inline-flex; flex-direction: column; justify-content: center; line-height: 0.55; flex-shrink: 0; }
.sort-arrow::before, .sort-arrow::after { content: ''; display: block; width: 0; height: 0; border-left: 3px solid transparent; border-right: 3px solid transparent; opacity: 0.35; }
.sort-arrow::before { border-bottom: 4px solid currentColor; margin-bottom: 2px; }
.sort-arrow::after { border-top: 4px solid currentColor; }
th[aria-sort="ascending"] .sort-arrow::before { opacity: 1; color: var(--green-200); }
th[aria-sort="ascending"] .sort-arrow::after { opacity: 0.25; }
th[aria-sort="descending"] .sort-arrow::after { opacity: 1; color: var(--green-200); }
th[aria-sort="descending"] .sort-arrow::before { opacity: 0.25; }

.pagination { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; margin-top: var(--sp-4); }
.pagination__btn {
  min-width: 32px;
  height: 32px;
  padding: 0 8px;
  border: 1px solid var(--ink-100);
  border-radius: var(--r-control);
  background: var(--white);
  color: var(--ink-700);
  font-family: var(--font-data);
  font-size: 0.8125rem;
  cursor: pointer;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.pagination__btn:hover:not(:disabled) { background: var(--ink-050); }
.pagination__btn.is-active { background: var(--ink-900); color: var(--white); border-color: var(--ink-900); }
.pagination__btn:disabled { opacity: 0.35; cursor: not-allowed; }

/* ==========================================================================
   Step trail
   ========================================================================== */

.step-trail { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
.step-trail .step { display: flex; align-items: center; gap: var(--sp-2); font-family: var(--font-body); font-size: 0.8125rem; font-weight: 500; color: var(--ink-300); }
.step-trail .step::before { content: ''; width: 7px; height: 7px; background: var(--ink-100); }
.step-trail .step.done { color: var(--ink-700); }
.step-trail .step.done::before { background: var(--green-500); }
.step-trail .step.current { color: var(--ink-900); }
.step-trail .step.current::before { background: var(--info); }
.step-trail .step.error { color: var(--error-text); }
.step-trail .step.error::before { background: var(--error); }
.step-trail .connector { width: 18px; height: 1px; background: var(--ink-100); flex-shrink: 0; }

/* ==========================================================================
   Stat block
   ========================================================================== */

.stat {
  border: 1px solid var(--ink-100);
  background: var(--white);
  border-radius: var(--r-card);
  padding: var(--sp-5);
}
.stat .stat-label { font-family: var(--font-body); font-weight: 500; font-size: 0.6875rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-500); line-height: 1.4; }
.stat .stat-value { font-family: var(--font-data); font-variant-numeric: tabular-nums; font-weight: 500; font-size: 2.25rem; color: var(--ink-900); line-height: 1.1; margin-top: var(--sp-2); }
.stat .stat-value .unit { font-size: 1rem; color: var(--ink-500); font-weight: 400; margin-left: 4px; }
.stat .stat-foot { font-size: 0.8125rem; color: var(--ink-500); margin-top: var(--sp-2); }
.stat .stat-value--error { color: var(--error); }

/* The mini stats sit in a row of equal-height grid cells, but their labels
   don't all wrap the same way at every width ("Not sent yet" can take two
   lines where "Rejected" takes one) — reserving two lines' worth of height
   for every label keeps every value starting at the same baseline instead
   of drifting down under a taller label. */
.dash-mini-stats .stat-label { min-height: calc(1.4em * 2); }
.dash-mini-stats .stat { display: flex; flex-direction: column; }

/* A stat that doubles as a filter shortcut: same card, but built as a real
   button so it's reachable by keyboard and reads as interactive, not just
   informational. */
button.stat--clickable {
  font: inherit;
  color: inherit;
  text-align: left;
  width: 100%;
  cursor: pointer;
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
button.stat--clickable:hover { border-color: var(--green-500); box-shadow: 0 2px 10px rgba(18, 30, 24, 0.08); }
button.stat--clickable:focus-visible { outline: 2px solid var(--green-600); outline-offset: 2px; }

/* ==========================================================================
   Layout helpers
   ========================================================================== */

.section { padding: var(--sp-8) 0; }
.section--tight { padding: var(--sp-7) 0; }
.section--chrome { background: var(--ink-900); color: var(--white); }

/* Trust section: a real UAE skyline grounds the residency claim instead of
   another data block on flat ink-900 — desaturated and darkened heavily so
   it reads as texture and place, never competing with the text on top. */
#trust { position: relative; overflow: hidden; }
#trust::before {
  content: '';
  position: absolute;
  inset: 0;
  background-image: url('https://images.unsplash.com/photo-1512453979798-5ea266f8880c?w=1600&q=70&auto=format&fit=crop');
  background-size: cover;
  background-position: center 42%;
  filter: grayscale(1) contrast(1.15) brightness(0.5);
  opacity: 0.6;
}
#trust::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(18,30,24,0.72) 0%, rgba(18,30,24,0.95) 100%);
}
#trust .container { position: relative; z-index: 1; }
.section--raised { background: var(--white); }
.section-head { max-width: 640px; margin-bottom: var(--sp-6); }
.section-head p { margin-top: var(--sp-3); }

.grid-2 { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--sp-5); }
.grid-3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--sp-4); }
.grid-4 { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--sp-4); }

@media (max-width: 900px) {
  .grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .grid-3 { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
}
@media (max-width: 720px) {
  :root { --sp-8: 52px; --sp-7: 40px; }
  .container { padding: 0 var(--sp-4); }
  .grid-2, .grid-3, .grid-4 { grid-template-columns: minmax(0, 1fr); }
}

.visually-hidden {
  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:focus {
  position: fixed; top: var(--sp-3); left: var(--sp-3); width: auto; height: auto;
  padding: var(--sp-2) var(--sp-4); background: var(--ink-900); color: var(--white);
  border-radius: var(--r-control); z-index: 200; clip: auto; overflow: visible;
}

/* ==========================================================================
   Wordmark — the brand's own outlined artwork (extracted from the client's
   brand guidelines), never re-typed live. "Sijil" with both i's dotless,
   tittles replaced by green squares — the brand's one and only device.
   ========================================================================== */

.wordmark {
  display: inline-flex;
  align-items: center;
  text-decoration: none;
}
.wordmark__img {
  height: 22px;
  width: auto;
  display: block;
}

/* ==========================================================================
   Site header
   ========================================================================== */

.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--ink-050);
  border-bottom: 1px solid var(--ink-100);
}
.site-header__inner {
  display: flex;
  align-items: center;
  gap: var(--sp-6);
  height: 72px;
}
.site-nav {
  display: flex;
  gap: var(--sp-5);
  margin-left: var(--sp-2);
  flex: 1;
}
.site-nav a {
  font-size: 0.9375rem;
  font-weight: 400;
  color: var(--ink-700);
  text-decoration: none;
  transition: color var(--dur) var(--ease);
}
.site-nav a:hover { color: var(--ink-900); }
.site-header__actions { display: flex; align-items: center; gap: var(--sp-4); }
.nav-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 40px;
  height: 40px;
  background: transparent;
  border: 1px solid var(--ink-100);
  border-radius: var(--r-control);
}
.nav-toggle span { display: block; width: 18px; height: 2px; background: var(--ink-900); margin: 0 auto; transition: transform var(--dur) var(--ease), opacity var(--dur) var(--ease); }
.nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

.mobile-nav[hidden] { display: none; }
.mobile-nav {
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
  padding: var(--sp-4) var(--sp-5) var(--sp-5);
  border-top: 1px solid var(--ink-100);
  background: var(--ink-050);
}
.mobile-nav a {
  padding: var(--sp-3) 0;
  font-size: 1rem;
  color: var(--ink-900);
  text-decoration: none;
  border-bottom: 1px solid var(--ink-100);
}
.mobile-nav__actions { display: flex; gap: var(--sp-3); margin-top: var(--sp-4); }
.mobile-nav__actions .btn { flex: 1; }

@media (max-width: 860px) {
  .site-nav, .site-header__actions { display: none; }
  .nav-toggle { display: flex; }
}

/* ==========================================================================
   Hero
   ========================================================================== */

/* The hero's only decoration is the brand's own device, at two scales: a
   faint repeating square-field texture (echoing a ledger's grid — "sijil"
   itself means register) and one large outlined square as a quiet accent.
   Flat, hard-edged, no gradient, no blur — same rules as everywhere else. */
.hero {
  padding: var(--sp-8) 0 var(--sp-7);
  position: relative;
  overflow: hidden;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='56' height='56'%3E%3Crect x='6' y='6' width='4' height='4' fill='%23D9E0DD'/%3E%3Crect x='36' y='28' width='3' height='3' fill='%23D9E0DD'/%3E%3Crect x='20' y='42' width='3' height='3' fill='%23D9E0DD' opacity='.6'/%3E%3C/svg%3E");
  background-repeat: repeat;
}
.hero__accent-square {
  position: absolute;
  top: -60px;
  right: 4%;
  width: 300px;
  height: 300px;
  border: 1.5px solid var(--green-200);
  pointer-events: none;
  z-index: 0;
}
.hero__accent-square::after {
  content: '';
  position: absolute;
  top: 40px;
  left: 40px;
  width: 14px;
  height: 14px;
  background: var(--green-200);
}
.hero__inner {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
  position: relative;
  z-index: 1;
  gap: var(--sp-7);
  align-items: start;
}
.hero__ctas { margin-top: var(--sp-6); }
.hero__stats { padding: var(--sp-5); position: sticky; top: 96px; }
.hero__stats-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--sp-4); margin-top: var(--sp-3); }
.deadline-stat { padding-top: var(--sp-3); border-top: 1px solid var(--ink-100); }
.deadline-stat__who { font-size: 0.8125rem; color: var(--ink-500); margin-bottom: var(--sp-1); }
.deadline-stat__date { font-size: 1.375rem; color: var(--ink-900); }
.deadline-stat__sub { font-size: 0.8125rem; color: var(--ink-500); margin-top: var(--sp-1); }
.hero__countdown-line { margin-top: var(--sp-5); padding-top: var(--sp-4); border-top: 1px solid var(--ink-100); font-size: 0.9375rem; color: var(--ink-700); }
.hero__countdown-line .data { font-size: 1.375rem; color: var(--green-700); }
.stated-as-at { font-size: 0.75rem; color: var(--ink-500); margin-top: var(--sp-3); }

@media (max-width: 900px) {
  .hero__inner { grid-template-columns: minmax(0, 1fr); }
  .hero__stats { position: static; }
  /* Below this width the hero stacks to one column, so the accent square
     no longer sits behind the stat card — it would cut across the
     headline instead. The repeating texture alone carries the hero. */
  .hero__accent-square { display: none; }
}

/* ==========================================================================
   How it works — Upload / Validate / Transmit (nested inside Product)
   ========================================================================== */

/* Same square-mark-on-a-line device as the deadline timeline, reused for a
   sequence of actions instead of a sequence of dates — one motif doing two
   jobs, not two different "how this works" components. Sits inside the
   Product section as its mechanism-at-a-glance opener, above the deeper
   feature rows. */
.how-steps__lead { margin-top: var(--sp-6); }
.how-steps { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--sp-6); margin-top: var(--sp-4); padding-bottom: var(--sp-7); border-bottom: 1px solid var(--ink-100); }
.how-step { position: relative; padding-top: var(--sp-5); }
.how-step::before {
  content: '';
  position: absolute;
  top: 7px;
  left: 15px;
  right: calc(-1 * var(--sp-6) + 15px);
  height: 1px;
  background: var(--ink-100);
}
.how-step:last-child::before { display: none; }
.how-step__mark { position: absolute; top: 0; left: 0; width: 15px; height: 15px; background: var(--green-500); }
.how-step__num { display: block; font-size: 0.8125rem; color: var(--ink-300); margin-top: var(--sp-4); }
.how-step h3 { margin-top: var(--sp-1); }
.how-step .body-text { margin-top: var(--sp-2); max-width: 34ch; }
@media (max-width: 720px) {
  .how-steps { grid-template-columns: minmax(0, 1fr); gap: var(--sp-6); }
  .how-step::before { top: 0; bottom: calc(-1 * var(--sp-6) + 15px); left: 6px; right: auto; width: 1px; height: auto; }
  .how-step:last-child::before { display: none; }
  .how-step { padding-left: var(--sp-5); padding-top: 0; }
  .how-step__mark { top: 3px; left: 0; }
}

/* ==========================================================================
   Mandate section
   ========================================================================== */

/* Two revenue-band timelines side by side, each its own short Appoint/
   Go-live sequence, instead of one five-point strip mixing both bands
   together — a business only needs to find its own column. */
.mandate-timelines { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--sp-6); margin-top: var(--sp-7); }
.mandate-timeline-group .deadline-timeline { margin-top: var(--sp-4); }
@media (max-width: 640px) {
  .mandate-timelines { grid-template-columns: minmax(0, 1fr); gap: var(--sp-6); }
}

/* Full-width dark chrome stat panel — the two hardest numbers on the page
   get the whole row to themselves, right under the timelines they follow
   from. */
.mandate-stats--chrome {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--sp-6);
  background: var(--ink-900);
  border-radius: var(--r-card);
  padding: var(--sp-6);
  margin-top: var(--sp-6);
}
.mandate-stats--chrome .stat { background: transparent; border: 0; padding: 0; }
.mandate-stats--chrome .stat + .stat { border-left: 1px solid rgba(255,255,255,0.14); padding-left: var(--sp-6); }
.mandate-stats--chrome .stat-value { color: var(--white); font-size: 2.75rem; }
.mandate-stats--chrome .stat-value .unit { color: rgba(255,255,255,0.6); }
.mandate-stats--chrome .stat-value--error { color: var(--error); }
.mandate-stats--chrome .stat-foot { color: rgba(255,255,255,0.72); }
.mandate-stats--chrome .stated-as-at { color: rgba(255,255,255,0.5); }
@media (max-width: 640px) {
  .mandate-stats--chrome { grid-template-columns: minmax(0, 1fr); }
  .mandate-stats--chrome .stat + .stat { border-left: 0; padding-left: 0; border-top: 1px solid rgba(255,255,255,0.14); padding-top: var(--sp-5); margin-top: var(--sp-1); }
}

/* Deadline timeline — squares on a line, never a progress bar. These five
   dates are the page's own stated thesis ("the mandate's real dates are the
   hero"); they render at large Data scale, not as a caption under the rule. */
.deadline-timeline { display: flex; align-items: flex-start; gap: 0; margin-top: var(--sp-7); overflow-x: auto; padding-bottom: var(--sp-2); }
.deadline-timeline__item { flex: 1; min-width: 148px; position: relative; padding-top: var(--sp-5); }
.deadline-timeline__item::before {
  content: '';
  position: absolute;
  top: 7px;
  left: 0;
  right: 0;
  height: 1px;
  background: var(--ink-100);
}
.deadline-timeline__item:first-child::before { left: 8px; }
.deadline-timeline__item:last-child::before { right: calc(100% - 8px); }
.deadline-timeline__mark { position: absolute; top: 0; left: 0; width: 15px; height: 15px; background: var(--green-500); }
.deadline-timeline__item .data { font-size: 1.75rem; font-weight: 500; color: var(--ink-900); margin-top: var(--sp-3); display: block; letter-spacing: -0.01em; }
.deadline-timeline__label { font-size: 0.8125rem; color: var(--ink-500); margin-top: var(--sp-1); }
@media (max-width: 720px) {
  .deadline-timeline { flex-direction: column; overflow-x: visible; }
  .deadline-timeline__item { padding-left: var(--sp-5); padding-top: 0; margin-bottom: var(--sp-5); min-width: 0; }
  .deadline-timeline__item::before { top: 0; bottom: 0; left: 6px; right: auto; width: 1px; height: auto; }
  .deadline-timeline__item:first-child::before, .deadline-timeline__item:last-child::before { left: 6px; right: auto; top: 0; bottom: 0; }
  .deadline-timeline__mark { top: 4px; left: 0; }
  .deadline-timeline__item .data { font-size: 1.5rem; }
}

/* ==========================================================================
   Tracks section
   ========================================================================== */

/* Asymmetric photo + stacked-cards split — real people at real work, not two
   interchangeable feature cards with matching icons. The one photographic
   moment on the page outside the Trust section, desaturated and green-toned
   so it reads as this brand's photography, not stock. */
.tracks-layout { display: grid; grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.2fr); gap: var(--sp-6); margin-top: var(--sp-2); align-items: stretch; }
.tracks-photo { position: relative; margin: 0; overflow: hidden; border-radius: var(--r-card); min-height: 320px; }
.tracks-photo img { width: 100%; height: 100%; object-fit: cover; filter: grayscale(1) contrast(1.08) brightness(0.92); display: block; }
.tracks-photo::after {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--green-700);
  mix-blend-mode: color;
  opacity: 0.65;
}
.tracks-cards { display: flex; flex-direction: column; gap: var(--sp-4); }
@media (max-width: 900px) {
  .tracks-layout { grid-template-columns: minmax(0, 1fr); }
  .tracks-photo { min-height: 220px; }
}

.track-card { padding: var(--sp-6); display: flex; flex-direction: column; gap: var(--sp-3); }
.track-card .btn { align-self: flex-start; margin-top: var(--sp-2); }
.track-list { display: flex; flex-direction: column; gap: var(--sp-2); margin: var(--sp-2) 0; }
.track-list li {
  position: relative;
  padding-left: var(--sp-4);
  font-size: 0.9375rem;
  color: var(--ink-700);
  line-height: 1.5;
}
.track-list li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 8px;
  width: 6px;
  height: 6px;
  background: var(--green-500);
}

/* ==========================================================================
   Product showcase
   ========================================================================== */

.product-showcase { display: flex; flex-direction: column; gap: var(--sp-8); margin-top: var(--sp-6); }
/* min-width: 0 on grid items overrides their default min-width:auto, which
   otherwise lets wide content (the 560px-min data table) force the whole
   grid — and the page — wider than the viewport instead of scrolling within
   its own .table-wrap. */
.product-row { display: grid; grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr); gap: var(--sp-6); align-items: center; }
.product-row > * { min-width: 0; }
.product-row--reverse { grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr); }
.product-row--reverse .product-row__copy { order: 2; }
.product-row--reverse .product-row__mock { order: 1; }
.product-row__mock { padding: var(--sp-5); }
@media (max-width: 900px) {
  .product-row, .product-row--reverse { grid-template-columns: minmax(0, 1fr); }
  .product-row--reverse .product-row__copy,
  .product-row--reverse .product-row__mock { order: initial; }
}

/* Third row breaks the split-row rhythm on purpose: two consecutive
   left/right splits read fine, a third in a row starts to feel like a
   template stamped three times. Copy stacks full-width above a full-width
   proof table instead. */
.product-row--full { display: block; }
.product-row--full .product-row__copy { max-width: 640px; margin-bottom: var(--sp-5); }

.mock-stat-row { display: flex; justify-content: space-between; gap: var(--sp-5); flex-wrap: wrap; }
.mock-stat-value { font-size: 2.5rem; }
.mock-stat-mini-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--sp-4); align-content: start; }
.mock-stat-mini-grid > div { display: flex; flex-direction: column; gap: 2px; }
.mock-stat-mini-grid .data { font-size: 1.25rem; }

.mock-checks__stats { display: flex; gap: var(--sp-6); }
.mock-checks__stats > div { display: flex; flex-direction: column; gap: 2px; }
.mock-checks__stats .data { font-size: 1.75rem; }

/* ==========================================================================
   Trust section
   ========================================================================== */

.trust-callout { margin-top: var(--sp-6); max-width: var(--w-reading); }
.trust-grid { margin-top: var(--sp-7); }
.trust-item__num { font-size: 2rem; color: var(--green-400); margin-bottom: var(--sp-2); }
.trust-icon { width: 28px; height: 28px; stroke: var(--green-400); stroke-width: 1.6; fill: none; stroke-linecap: square; stroke-linejoin: miter; margin-bottom: var(--sp-3); }

/* ==========================================================================
   Contact form
   ========================================================================== */

.contact-form { padding: var(--sp-6); margin-top: var(--sp-3); }
.form-status { margin-top: var(--sp-3); font-size: 0.9375rem; min-height: 1.4em; }
.form-status.is-success { color: var(--green-700); }
.form-status.is-error { color: var(--error); }

/* ==========================================================================
   Footer
   ========================================================================== */

.site-footer { background: var(--white); border-top: 1px solid var(--ink-100); padding: var(--sp-7) 0; }
.footer__inner { display: grid; grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr); gap: var(--sp-6); align-items: start; }
.footer__disclaimer { font-size: 0.8125rem; color: var(--ink-500); max-width: 56ch; margin-top: var(--sp-4); line-height: 1.6; }
.footer__nav { display: flex; flex-direction: column; gap: var(--sp-2); }
.footer__nav a { font-size: 0.9375rem; color: var(--ink-700); text-decoration: none; }
.footer__nav a:hover { color: var(--ink-900); }
@media (max-width: 720px) { .footer__inner { grid-template-columns: minmax(0, 1fr); } }

/* ==========================================================================
   Auth shell (sign-in)
   ========================================================================== */

.auth-body { min-height: 100vh; display: flex; align-items: center; }
.auth-shell { width: 100%; max-width: var(--w-form); margin: 0 auto; padding: var(--sp-6) var(--sp-4); }
.auth-shell__top { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--sp-6); }
.auth-card { padding: var(--sp-6); }
.auth-card__demo-note { margin-top: var(--sp-5); padding-top: var(--sp-4); border-top: 1px solid var(--ink-100); font-size: 0.8125rem; color: var(--ink-500); }
.auth-shell__foot { text-align: center; margin-top: var(--sp-5); font-size: 0.9375rem; color: var(--ink-700); }
.auth-shell__foot a { color: var(--green-700); font-weight: 500; text-decoration: none; }
.auth-shell__foot a:hover { text-decoration: underline; }

/* ==========================================================================
   App shell (dashboard)
   ========================================================================== */

.app-body { background: var(--ink-050); }

/* "Working as X" — sits above the app-nav header on every screen while a
   tax agent is inside a client's business, so which business is never a
   mode they can forget. Amber, the same semantic used for "capacity
   running low" elsewhere — this is the same kind of fact: pay attention,
   you're not looking at your own account. */
/* Sticky, not just top-of-flow: it stays on screen while the page scrolls,
   so which business is current is never a fact that scrolls out of view. */
.firm-banner { background: var(--warning-bg); position: sticky; top: 0; z-index: 90; }
.firm-banner__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  padding: 10px 0;
  font-size: 0.8125rem;
  color: var(--warning-text);
  flex-wrap: wrap;
}
.firm-banner__mark { display: inline-block; width: 7px; height: 7px; background: var(--warning); margin-right: 4px; }

.firm-switcher { position: relative; }
.firm-switcher__toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: none;
  border: none;
  padding: 4px 2px;
  color: var(--warning-text);
  text-decoration: underline;
  font-weight: 500;
  font: inherit;
  font-size: 0.8125rem;
  cursor: pointer;
}
.firm-switcher__toggle:hover { color: var(--ink-900); }
.firm-switcher__toggle:focus-visible { outline: 2px solid var(--ink-900); outline-offset: 2px; }
.firm-switcher__caret { display: inline-block; width: 0; height: 0; border-left: 4px solid transparent; border-right: 4px solid transparent; border-top: 5px solid currentColor; }
.firm-switcher__toggle[aria-expanded="true"] .firm-switcher__caret { transform: rotate(180deg); }
.firm-switcher__menu {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  min-width: 220px;
  background: var(--white);
  border: 1px solid var(--ink-100);
  border-radius: var(--r-card);
  box-shadow: 0 8px 24px rgba(18, 30, 24, 0.16);
  padding: 6px;
  z-index: 100;
}
.firm-switcher__option {
  display: block;
  width: 100%;
  text-align: left;
  padding: 8px 10px;
  border: none;
  background: none;
  font-family: var(--font-body);
  font-size: 0.875rem;
  color: var(--ink-900);
  border-radius: var(--r-control);
  cursor: pointer;
}
.firm-switcher__option:hover { background: var(--ink-050); }
.firm-switcher__empty { padding: 8px 10px; font-size: 0.8125rem; color: var(--ink-500); }
.firm-switcher__all {
  display: block;
  margin-top: 4px;
  padding: 8px 10px;
  border-top: 1px solid var(--ink-100);
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--green-700);
  text-decoration: none;
}
.firm-switcher__all:hover { color: var(--green-600); text-decoration: underline; }

.app-nav { background: var(--ink-900); }
.app-nav__inner { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4); height: 64px; flex-wrap: wrap; }
.firm-header-name { font-family: var(--font-body); font-size: 0.9375rem; color: rgba(255,255,255,0.72); flex: 1 1 auto; }
.app-tabs { display: flex; gap: var(--sp-5); flex: 1 1 auto; }
@media (max-width: 640px) {
  .app-nav__inner { height: auto; padding-top: 14px; padding-bottom: 14px; }
  .app-tabs { order: 3; flex-basis: 100%; padding-top: 10px; margin-top: 2px; border-top: 1px solid rgba(255,255,255,0.12); gap: var(--sp-4); }
}
.app-tab {
  font-size: 0.9375rem;
  color: var(--ink-300);
  text-decoration: none;
  height: 64px;
  display: flex;
  align-items: center;
  border-bottom: 2px solid transparent;
  transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.app-tab:hover { color: var(--white); }
.app-tab--active { color: var(--white); border-bottom-color: var(--green-500); }
.app-nav__actions { display: flex; align-items: center; gap: var(--sp-3); }

.app-main { padding: var(--sp-7) 0 var(--sp-8); }
.app-page-head { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4); flex-wrap: wrap; margin-bottom: var(--sp-5); }
.app-page-head > * { min-width: 0; }

/* minmax(0, 1fr), not bare 1fr — a bare fr track's implicit minimum is its
   content's min-content width, which a long formatted amount (e.g.
   "12,710.00") can push wider than the viewport. 0 lets the track (and the
   number inside it) actually shrink instead of forcing the page to scroll. */
.dash-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.3fr); gap: var(--sp-4); }
.dash-capacity .stat-value { font-size: 3rem; }
.dash-mini-stats { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--sp-4); }
@media (max-width: 900px) {
  .dash-grid { grid-template-columns: minmax(0, 1fr); }
  .dash-mini-stats { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
}
.dash-demo-note { margin-top: var(--sp-6); font-size: 0.8125rem; color: var(--ink-500); text-align: center; }

.report-links { display: flex; flex-wrap: wrap; gap: var(--sp-3); margin-top: var(--sp-5); }
.report-links a {
  font-size: 0.9375rem;
  font-weight: 500;
  color: var(--green-700);
  text-decoration: none;
  padding: 8px 14px;
  border: 1px solid var(--ink-100);
  border-radius: var(--r-pill);
  background: var(--white);
}
.report-links a:hover { border-color: var(--green-600); background: var(--ink-050); }

.filter-row { display: flex; align-items: flex-end; gap: var(--sp-3); flex-wrap: wrap; margin-top: var(--sp-2); }
.filter-field { min-width: 150px; }
.filter-field--grow { flex: 1; min-width: 200px; }
.filter-field input, .filter-field select { height: 40px; padding: 0 12px; }
/* "Clear filters" sits on the same baseline as the fields (align-items:
   flex-end), but a .btn--sm is 36px tall against their 40px — four pixels
   short enough to look visibly off. Match it exactly instead. */
.filter-row .btn { height: 40px; }

/* ==========================================================================
   Invoice detail
   ========================================================================== */

.back-link { font-size: 0.9375rem; color: var(--ink-500); text-decoration: none; }
.back-link:hover { color: var(--ink-900); }

.invoice-head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--sp-4); margin-top: var(--sp-4); flex-wrap: wrap; }

.invoice-totals { display: flex; justify-content: flex-end; gap: var(--sp-6); margin-top: var(--sp-4); padding-top: var(--sp-4); border-top: 1px solid var(--ink-100); }
.invoice-totals > div { display: flex; flex-direction: column; align-items: flex-end; gap: 2px; }
.invoice-totals .data { font-size: 1.0625rem; }
.invoice-totals__grand .data { font-size: 1.375rem; color: var(--ink-900); }
@media (max-width: 720px) {
  .invoice-totals { flex-direction: column; align-items: flex-end; gap: var(--sp-2); }
}

.fix-inline { display: flex; gap: var(--sp-3); margin-top: var(--sp-3); flex-wrap: wrap; }
.fix-inline__input { height: 40px; padding: 0 12px; border: 1px solid var(--ink-100); border-radius: var(--r-control); font-family: var(--font-body); font-size: 0.9375rem; flex: 1; min-width: 180px; }
.fix-inline__input:focus { outline: none; border-color: var(--ink-900); box-shadow: 0 0 0 2px var(--green-600); }

.btn--destructive-outline { background: transparent; color: var(--error); border: 1.5px solid var(--error); }
.btn--destructive-outline:hover { background: var(--error-tint); }

.compliance-copy { background: var(--white); border: 1px solid var(--ink-100); border-radius: var(--r-card); padding: var(--sp-6); margin-top: var(--sp-5); }
.compliance-copy__foot { margin-top: var(--sp-5); padding-top: var(--sp-4); border-top: 1px solid var(--ink-100); }
.activity-section { margin-top: var(--sp-6); }

/* ==========================================================================
   Clients directory
   ========================================================================== */

.client-detail-row td { background: var(--ink-050); padding: var(--sp-5) var(--sp-4); border-bottom: 1px solid var(--ink-100); }
.client-detail-row .data-table { background: var(--white); }
.add-client-panel { padding: var(--sp-6); margin-bottom: var(--sp-5); }

/* Same expandable-row treatment as the clients directory, reused for the
   VAT summary's "invoices behind this bucket" reveal. */
.vat-detail-row td { background: var(--ink-050); padding: var(--sp-5) var(--sp-4); border-bottom: 1px solid var(--ink-100); }
.vat-detail-row .data-table { background: var(--white); }

/* ==========================================================================
   Settings
   ========================================================================== */

.tax-questions { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--sp-3) var(--sp-5); margin-top: var(--sp-3); }
@media (max-width: 720px) { .tax-questions { grid-template-columns: minmax(0, 1fr); } }
.tax-question { display: flex; align-items: center; gap: var(--sp-3); font-size: 0.9375rem; color: var(--ink-900); cursor: pointer; }
.tax-question input { width: 18px; height: 18px; accent-color: var(--green-500); flex-shrink: 0; }
.tax-questions-disclosure { margin-top: var(--sp-3); }
.tax-questions-disclosure summary {
  font-size: 0.9375rem;
  font-weight: 500;
  color: var(--green-700, var(--green-500));
  cursor: pointer;
  list-style: none;
  padding: var(--sp-2) 0;
}
.tax-questions-disclosure summary::-webkit-details-marker { display: none; }
.tax-questions-disclosure summary::before { content: '▸ '; display: inline-block; transition: transform 0.15s ease; }
.tax-questions-disclosure[open] summary::before { transform: rotate(90deg); }
.tax-questions-disclosure summary:focus-visible { outline: 2px solid var(--info); outline-offset: 2px; }
.add-person-panel { border: 1px solid var(--ink-100); }

/* ==========================================================================
   Form groups (new invoice) — per DLS "06b Form structure"
   ========================================================================== */

/* min-width: 0 overrides the browser default that lets a <fieldset> refuse to
   shrink below its content's natural width — without it, a wide table inside
   forces the whole page to scroll sideways instead of scrolling within .table-wrap. */
.form-group { border: 1px solid var(--ink-100); border-radius: var(--r-card); padding: 18px; margin: 0 0 var(--sp-4); min-width: 0; }
.form-group__legend {
  font-family: var(--font-data);
  font-size: 0.65625rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-500);
  padding: 0 6px;
}
.form-group__cols { display: grid; grid-template-columns: repeat(3, minmax(180px, 1fr)); gap: var(--sp-4); margin-top: var(--sp-3); }
@media (max-width: 720px) { .form-group__cols { grid-template-columns: minmax(0, 1fr); } }
/* .field + .field's top margin is meant for fields stacked in normal flow
   (sign-in, contact form); inside a grid every field after the first in DOM
   order still matches that sibling selector even though it isn't actually
   below the previous one, so every cell but the first row's first field was
   quietly pushed down — the reported "Client field is out of alignment" bug.
   The grid's own gap already spaces rows; reset the margin here. */
.form-group__cols > .field + .field { margin-top: 0; }

/* Direction toggle — "I'm sending this" vs "I received this, from a
   supplier". A segmented pair, not a dropdown: the choice is binary and
   should be visible and one click, not buried in a select. */
.direction-toggle { display: inline-flex; border: 1px solid var(--ink-900); border-radius: var(--r-control); overflow: hidden; margin-bottom: var(--sp-5); }
.direction-toggle__btn {
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 0.9375rem;
  padding: 12px 20px;
  background: var(--white);
  color: var(--ink-900);
  border: 0;
  cursor: pointer;
}
.direction-toggle__btn + .direction-toggle__btn { border-left: 1px solid var(--ink-900); }
.direction-toggle__btn.is-active { background: var(--ink-900); color: var(--white); }
.direction-toggle__btn:focus-visible { outline: 2px solid var(--green-600); outline-offset: -2px; }
@media (max-width: 640px) {
  .direction-toggle { display: flex; }
  .direction-toggle__btn { flex: 1; padding: 12px 12px; }
}

.li-input { width: 100%; height: 40px; padding: 0 10px; border: 1px solid var(--ink-100); border-radius: var(--r-control); font-family: var(--font-body); font-size: 0.9375rem; background: var(--white); }
.li-input:focus { outline: none; border-color: var(--ink-900); box-shadow: 0 0 0 2px var(--green-600); }
.li-input--num { font-family: var(--font-data); text-align: right; }
.li-input--error { border-color: var(--error); }
.li-field-error { font-size: 0.8125rem; color: var(--error); margin-top: 4px; }
.data-table td .li-input, .data-table td select.li-input { min-width: 90px; }
.data-table td .li-input--item { min-width: 200px; }
.li-remove { width: 28px; height: 28px; border: 1px solid var(--ink-100); background: var(--white); border-radius: var(--r-control); color: var(--ink-500); font-size: 1rem; cursor: pointer; line-height: 1; }
.li-remove:hover:not(:disabled) { border-color: var(--error); color: var(--error); }
.li-remove:disabled { opacity: 0.35; cursor: not-allowed; }

/* New-client review cards (import.js) */
.new-client-approve-toggle { width: 16px; height: 16px; }

/* Staged import table (import.js) */
.data-table th input[type="checkbox"], .data-table td input[type="checkbox"] { width: 16px; height: 16px; }

/* Searchable column-picker (import.js's mapping table) — a text input the
   person can type into to filter, backed by a real list of the file's own
   column names so only a real column can end up selected. Same dropdown
   shape as .firm-switcher__menu (position, border, shadow), same input
   shape as .li-input. */
.col-combo { position: relative; }
.col-combo__input { width: 100%; min-width: 200px; height: 40px; padding: 0 10px; border: 1px solid var(--ink-100); border-radius: var(--r-control); font-family: var(--font-body); font-size: 0.9375rem; background: var(--white); }
.col-combo__input:focus { outline: none; border-color: var(--ink-900); box-shadow: 0 0 0 2px var(--green-600); }
.col-combo__list { position: absolute; top: calc(100% + 6px); left: 0; min-width: 100%; max-height: 240px; overflow-y: auto; background: var(--white); border: 1px solid var(--ink-100); border-radius: var(--r-card); box-shadow: 0 8px 24px rgba(18, 30, 24, 0.16); padding: 6px; z-index: 100; }
.col-combo__option { display: block; width: 100%; text-align: left; padding: 8px 10px; border: none; background: none; font-family: var(--font-body); font-size: 0.875rem; color: var(--ink-900); border-radius: var(--r-control); cursor: pointer; white-space: nowrap; }
.col-combo__option:hover { background: var(--ink-050); }
.col-combo__option--none { color: var(--ink-500); font-style: italic; border-bottom: 1px solid var(--ink-100); border-radius: 0; margin-bottom: 4px; padding-bottom: 10px; }
.col-combo__empty { padding: 8px 10px; font-size: 0.8125rem; color: var(--ink-500); }

/* Section divider inside the mapping table (import.js) — separates the
   per-line-item fields from the trailing "only if registering a new
   client" group, which would otherwise look like just more of the same
   list. */
.data-table tr.col-combo-divider td { background: var(--ink-050); padding: 10px var(--sp-4); border-top: 1px solid var(--ink-100); }
.data-table tr.col-combo-divider + tr td { border-top: none; }

/* ==========================================================================
   Spreadsheet import
   ========================================================================== */

.upload-drop {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  text-align: center;
  padding: var(--sp-8) var(--sp-5);
  border: 1.5px dashed var(--ink-300);
  border-radius: var(--r-card);
  cursor: pointer;
  transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease);
}
.upload-drop:hover, .upload-drop.is-dragover { border-color: var(--green-500); background: var(--ink-050); }
.upload-drop__title { font-family: var(--font-body); font-weight: 500; font-size: 1.0625rem; color: var(--ink-900); }
.upload-drop__hint { font-size: 0.8125rem; color: var(--ink-500); max-width: 40ch; }

.link-btn { background: none; border: none; padding: 0; color: var(--green-700); font-family: var(--font-body); font-size: inherit; text-decoration: underline; cursor: pointer; }

.import-summary { display: flex; gap: var(--sp-7); margin-top: var(--sp-4); }
.import-summary > div { display: flex; flex-direction: column; gap: 2px; }
.import-summary__num { font-size: 1.75rem; }

/* Inert demo-only controls: text stays legible, cursor and a title attribute carry the reason — never a bare grey box. */
.app-tab[aria-disabled="true"],
.btn[aria-disabled="true"] {
  cursor: not-allowed;
  opacity: 0.6;
}

/* ---------------------------------------------------------------------
   Admin dashboard (Phase 8) — admin.html / admin-business.html only.
   Sijil staff-facing, not a tenant page: a small "Admin" tag next to the
   wordmark, a Prospect status pill (info-blue, distinct from every
   existing status color), and the invoice-package/onboarding-fee
   editing patterns those two pages need on top of the shared data-table
   and card components above.
--------------------------------------------------------------------- */
.admin-tag { display: inline-flex; align-items: center; flex-shrink: 0; font-family: var(--font-data); font-size: 0.6875rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--green-200); border: 1px solid rgba(255,255,255,0.25); border-radius: var(--r-pill); padding: 3px 10px; margin-left: var(--sp-3); white-space: nowrap; }
.app-nav__email { color: rgba(255,255,255,0.7); font-size: 0.875rem; }
@media (max-width: 560px) { .app-nav__email { display: none; } }

.pill--prospect { background: var(--info-bg); color: var(--info-text); }
.pill--prospect::before { background: var(--info); }

.stat-block { display: flex; flex-direction: column; gap: 2px; }
.stat-block .data { font-size: 1.0625rem; }
.stat-block .caption-text { font-size: 0.75rem; }

.back-link-row { margin-bottom: var(--sp-3); }

.detail-head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--sp-5); flex-wrap: wrap; }
.detail-head__pills { display: flex; gap: var(--sp-2); margin-top: var(--sp-2); flex-wrap: wrap; }

.admin-section { margin-top: var(--sp-7); }
.admin-section-head { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4); margin-bottom: var(--sp-4); flex-wrap: wrap; }

/* Groups (Business setup / Business history) get the big section gap
   once; the subsections inside share a smaller gap between each other,
   sitting close under the group's own heading rather than repeating
   the same large gap for every subsection. */
.admin-group { margin-top: var(--sp-8); }
.admin-divider { border: none; border-top: 1px solid var(--ink-100); margin: var(--sp-4) 0 0; }
/* The divider already provides the visual gap above the group it
   introduces — its own default margin-top would double that up. */
.admin-divider + .admin-group { margin-top: var(--sp-6); }
.admin-group > .heading { margin-bottom: var(--sp-5); }
.admin-subsection + .admin-subsection { margin-top: var(--sp-6); }
.admin-grid-2col { display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1fr); gap: var(--sp-6); align-items: stretch; }
@media (max-width: 800px) { .admin-grid-2col { grid-template-columns: minmax(0,1fr); } }
/* Grid's own row-stretch only makes the two cells equal height — it
   doesn't reach the .status-card nested inside each one, so that has
   to flex-grow down through both intermediate layers to actually fill
   that height with real background/border, not just invisible space
   below a shorter card. */
.admin-grid-2col__cell { display: flex; flex-direction: column; }
.status-card-slot { flex: 1; display: flex; flex-direction: column; }

.fee-panel { display: flex; flex-direction: column; gap: var(--sp-4); max-width: 560px; }
.form-panel { padding: var(--sp-5); }
/* Direct-child combinator on purpose: this is only meant for a
   single-column stacked form-panel (fields with no .form-panel__cols
   wrapper). A descendant selector here would also match fields one
   level deeper, inside a .form-panel__cols grid row — margin-top on
   just columns 2+ shifts them down relative to column 1, breaking the
   row's alignment (the real cause behind "alignment is bad" in the
   Add-a-package and onboarding-fee grids, confirmed 2026-09). */
.form-panel > .field + .field { margin-top: var(--sp-3); }
.form-panel__cols { display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: var(--sp-3); }
/* Same root cause and same fix as .form-group__cols above: the global
   .field + .field rule (line ~239) still matches every field after the
   first in DOM order even inside this grid, pushing columns 2+ down by
   --sp-4 on top of everything else. */
.form-panel__cols > .field + .field { margin-top: 0; }
@media (max-width: 640px) { .form-panel__cols { grid-template-columns: minmax(0,1fr); } }
/* A name field reads as prose, not a number to right-align against the
   other two — it earns twice the column width instead of forcing "Growth"
   into the same narrow slot as "500" or "900.00". The button gets its own
   auto column so it lines up level with the fields, not stranded on its
   own row below them. */
.form-panel__cols--pkg { grid-template-columns: minmax(0,2fr) minmax(0,1fr) minmax(0,1fr) auto; }
@media (max-width: 720px) { .form-panel__cols--pkg { grid-template-columns: minmax(0,1fr); } }

/* ASP assignment: one free-text field (a curated datalist suggests the
   two ASPs Sijil has actually integrated so far, but this isn't a
   closed set — PRODUCT.md counts 42+ real ASPs) plus its own auto
   button column, same "field earns the row, button lines up beside it"
   reasoning as --pkg above. */
.form-panel__cols--asp { grid-template-columns: minmax(0,1fr) auto; }
@media (max-width: 480px) { .form-panel__cols--asp { grid-template-columns: minmax(0,1fr); } }

.fee-state-switch { display: flex; gap: var(--sp-2); margin-bottom: var(--sp-4); overflow-x: auto; flex-wrap: wrap; }
.fee-state-switch button { flex-shrink: 0; white-space: nowrap; background: var(--white); border: 1px solid var(--ink-100); border-radius: var(--r-pill); padding: 5px 14px; font-size: 0.75rem; font-family: var(--font-body); color: var(--ink-500); cursor: pointer; }
.fee-state-switch button.is-active { background: var(--ink-050); color: var(--ink-900); border-color: var(--ink-300); font-weight: 500; }
.fee-substate { display: none; }
.fee-substate.is-active { display: block; }

/* Applied to an inner wrapper, never the <td> itself — display:flex
   directly on a table cell drops it out of normal cell layout in some
   browsers, throwing off row height/vertical-alignment versus sibling
   cells that stay display:table-cell. */
.row-actions { display: flex; align-items: center; gap: var(--sp-3); height: 100%; }
.row-actions button { background: none; border: none; padding: 0; font-family: var(--font-body); font-size: 0.8125rem; font-weight: 500; color: var(--green-700); text-decoration: underline; cursor: pointer; }
.row-actions button.is-destructive { color: var(--error); }

.data-table tfoot td { padding: var(--sp-3) var(--sp-4); font-size: 0.9375rem; color: var(--ink-900); background: var(--ink-050); border-top: 1px solid var(--ink-100); }
.data-table tfoot td.num { text-align: right; font-family: var(--font-data); font-variant-numeric: tabular-nums; font-weight: 600; }

.lot-expiring { color: var(--warning-text); }
.lot-expired { color: var(--ink-300); text-decoration: line-through; }

/* Status card — ASP assignment and Onboarding fee (confirmed 2026-09,
   replacing the earlier plain .notice + separate .card, which read as
   two disconnected blocks). One card: a clear current-value header, an
   edit control that's either always open (nothing meaningful set yet)
   or collapsed behind a small toggle (there's already a settled value),
   never both an always-visible form AND a separate notice competing for
   attention. */
.status-card { background: var(--white); border: 1px solid var(--ink-100); border-radius: var(--r-card); padding: var(--sp-5); flex: 1; display: flex; flex-direction: column; }
.status-card__head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--sp-4); }
.status-card__value { font-family: var(--font-display); font-weight: 500; font-size: 1.375rem; color: var(--ink-900); margin-top: 4px; line-height: 1.2; }
.status-card__value.is-empty { font-family: var(--font-body); font-weight: 400; font-size: 1rem; color: var(--ink-500); }
.status-card__edit { margin-top: var(--sp-5); padding-top: var(--sp-5); border-top: 1px solid var(--ink-100); }
.status-card__checklist { margin-top: var(--sp-4); }
.status-card__foot { margin-top: var(--sp-4); }

.req-checklist { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; font-size: 0.9375rem; color: var(--ink-500); }
.req-checklist li.is-done { color: var(--green-600); }

/* Balance highlight — the one number an admin opening this page most
   likely came to check, so it doesn't wait in line behind ASP/fee/
   packages further down. Green-tinted, not a plain white card, so it
   visually reads as "the important number" at a glance. */
/* Balance/expiry, folded into the pill row right next to the business
   name (replacing an earlier separate highlighted block) — compact,
   and skipped entirely for a Prospect (nothing real to show yet). */
.data-pill--balance { font-weight: 500; color: var(--green-700); border-color: var(--green-200); background: var(--green-100); }
.data-pill--balance.is-low { color: var(--error); border-color: var(--error); background: var(--error-tint); }
