:root {
  --color-primary: #3ea76f;
  --color-primary-light: #ebf6f0;
  --color-primary-dark: #152d20;

  /* Label colour for text sitting ON --color-primary. Because --color-primary
     is overridden per tenant by the server-side branding block, a fixed label
     colour cannot suit every brand: white on this default green is 3.02:1,
     while dark ink on a blue tenant is 3.54:1 — each fails on the other.
     tenant_branding.py computes the readable pairing and re-declares this
     variable alongside --color-primary. The value here is the pairing for the
     default green (6.07:1) and is the fallback whenever branding is not
     injected, so this never resolves empty. */
  --color-on-primary: #230f10;

  --color-accent: #e77462;
  --color-accent-hover: #d4614f;

  --color-bg: #fafbf9;
  --color-surface: #ffffff;
  --color-text: #230f10;
  --color-text-secondary: #5c4a4b;
  /* Darkened from #8a7a7b (4.08:1 on white - failed WCAG AA) to 4.58:1.
     Same hue, 13% less luminance. Loaded by portal.css, login.html and
     invite.html only; admin.css and landing.css each define their own tokens
     and are unaffected. */
  --color-text-muted: #817273;

  /* Muted text on a TINTED surface. --color-text-muted clears AA on white
     (4.58:1) but only reaches 4.14:1 on --color-primary-light, so tinted
     panels use this instead. 4.57:1 on the tint, 5.06:1 on white. Derived by
     scaling the muted colour's luminance, not eyeballed. */
  --color-text-muted-strong: #7a6b6c;

  /* Brand green for TEXT on light backgrounds. --color-primary is a FILL
     colour: as text it measures 3.02:1 on white and 2.73:1 on the tint, both
     below AA. This is the same green darkened until it clears AA on both
     (5.04:1 on white, 4.55:1 on the tint). --color-primary itself is
     deliberately unchanged - fills, buttons and the sidebar keep the exact
     brand green. */
  --color-primary-text: #2d7d52;
  --color-border: #e2ddd8;
  --color-border-light: #f0ece8;

  --color-success: #3ea76f;
  --color-warning: #e7a84e;
  --color-error: #e77462;
  /* Dark red for high-urgency inline warnings (e.g. the low-balance notice):
     the error hue pulled down to a deep, readable red. */
  --color-danger-dark: oklch(from var(--color-error) 0.45 calc(c * 1.15) h);
  --color-info: #5b8ec9;

  --shadow-sm: 0 1px 2px rgba(35, 15, 16, 0.06);
  --shadow-md: 0 4px 12px rgba(35, 15, 16, 0.08);
  --shadow-lg: 0 8px 24px rgba(35, 15, 16, 0.12);

  --font-display: "DM Serif Display", Georgia, serif;
  --font-body: "DM Sans", -apple-system, sans-serif;
  --font-mono: "JetBrains Mono", monospace;

  --text-xs: 0.75rem;
  --text-sm: 0.875rem;
  --text-base: 1rem;
  --text-lg: 1.125rem;
  --text-xl: 1.25rem;
  --text-2xl: 1.5rem;
  --text-3xl: 1.875rem;
  --text-4xl: 2.25rem;
  --text-5xl: 3rem;

  /* Half-steps. The scale below jumps 0.25rem -> 0.5rem -> 0.75rem -> 1rem,
     which left the field-row rules on My Info / Company Info reaching for bare
     2px and 14px. At the default 16px root these are exactly those values, so
     the swap is pixel-identical. */
  --space-0-5: 0.125rem;
  --space-3-5: 0.875rem;

  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.5rem;
  --space-6: 2rem;
  --space-8: 3rem;
  --space-10: 4rem;
  --space-12: 6rem;

  --radius-sm: 6px;
  --radius-md: 10px;
  --radius-lg: 16px;
  --radius-full: 9999px;

  --max-width: 1200px;
  --sidebar-width: 260px;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  font-family: var(--font-body);
  color: var(--color-text);
  background: var(--color-bg);
}

a {
  color: inherit;
}
