/* ============================================================
   Spend Crumbs — design system
   Direction: Ledger. The interface carries no colour; colour
   appears only where a decision is needed.
   Settled 2026-09-09. The identity carries one colour, verdigris;
   the data never does. See the brand block below.
   ============================================================ */

:root {
  /* ---- ground and ink (light / default) ---- */
  --ground:      #E9EFE8;  /* ledger paper — the app background */
  --paper:       #FAFCF9;  /* panels, cards, table body */
  --head:        #E2EAE0;  /* table headers, meter troughs, insets */
  --ink:         #16211C;  /* body text, buttons, the mark */
  --muted:       #5C6A62;  /* labels, secondary text, "nothing to do" */
  --rule:        #D3DCD1;  /* every border and divider */
  --rule-strong: #C6D1C4;  /* outer edges */

  /* ---- decisions. the only colour in the product ---- */
  --act:    #A32218;  /* reorder now, stop buying — do it today */
  --review: #B45309;  /* plan reorder, review slow — look at it */
  --settled: var(--muted);  /* keep stable — deliberately colourless */

  --act-wash:    rgba(163, 34, 24, .09);
  --review-wash: rgba(180, 83, 9, .09);

  /* ---- brand. IDENTITY ONLY ---- */
  /* Verdigris. It appears in the mark, the wordmark and the report masthead
     and nowhere else — never on a figure, a row or a decision. That is what
     keeps it from colliding with act/review, and it is only available at all
     because this product has no semantic green: "keep stable" is colourless,
     so the green family was never spoken for. Do not spend it on data. */
  --brand:       #0C6B5F;  /* on paper and ledger grounds */
  --brand-on-ink: #3FA795;  /* on the ink band, in either theme */

  /* ---- inverse (buttons, the mark's badge) ---- */
  --on-ink: #FAFCF9;

  /* ---- focus ---- */
  --focus: #16211C;
  --focus-offset: #FAFCF9;

  /* ---- type ---- */
  --font-ui:  "IBM Plex Sans", "Segoe UI", system-ui, -apple-system, sans-serif;
  --font-num: "IBM Plex Mono", ui-monospace, "Cascadia Mono", Consolas, monospace;

  --fs-label: 0.6875rem;  /* 11px — uppercase labels only, never body */
  --fs-xs:    0.78125rem; /* 12.5px — captions, branch names */
  --fs-sm:    0.8125rem;  /* 13px — table cells */
  --fs-base:  0.875rem;   /* 14px — dense UI body */
  --fs-md:    1rem;       /* 16px — reading text, marketing body */
  --fs-lg:    1.25rem;    /* 20px */
  --fs-xl:    1.4375rem;  /* 23px — the lead decision */
  --fs-2xl:   2rem;       /* 32px */
  --fs-3xl:   2.625rem;   /* 42px — marketing site only */

  --lh-tight: 1.2;
  --lh-snug:  1.35;
  --lh-body:  1.55;

  --ls-label: .15em;   /* uppercase labels */
  --ls-tight: -.025em; /* headings */
  --ls-num:   -.03em;  /* large figures */

  /* ---- spacing. dense dashboard scale, 4px base ---- */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 20px;
  --sp-6: 24px;
  --sp-8: 32px;
  --sp-10: 40px;
  --sp-12: 48px;

  /* ---- form ---- */
  --radius:    3px;   /* the product is square-ish; ledgers are ruled, not rounded */
  --radius-lg: 8px;   /* outer panels only */
  --border:    1px;

  /* ---- motion. subtle tier — see README ---- */
  --t-fast: 120ms;
  --t-base: 180ms;
  --ease:   cubic-bezier(.2, .6, .3, 1);
}

/* ---- dark. same ink temperature, not an inversion ---- */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ground:      #121815;
    --paper:       #19211D;
    --head:        #1E2721;
    --ink:         #E8EEE9;
    --muted:       #8D9B93;
    --rule:        #26312B;
    --rule-strong: #2E3A33;

    --act:    #E4796C;
    --review: #DFA24A;

    --act-wash:    rgba(228, 121, 108, .13);
    --review-wash: rgba(223, 162, 74, .13);

    --brand:       #3FA795;
    --brand-on-ink: #3FA795;
    --on-ink: #121815;
    --focus: #E8EEE9;
    --focus-offset: #121815;
  }
}

:root[data-theme="dark"] {
  --ground:      #121815;
  --paper:       #19211D;
  --head:        #1E2721;
  --ink:         #E8EEE9;
  --muted:       #8D9B93;
  --rule:        #26312B;
  --rule-strong: #2E3A33;

  --act:    #E4796C;
  --review: #DFA24A;

  --act-wash:    rgba(228, 121, 108, .13);
  --review-wash: rgba(223, 162, 74, .13);

  --brand:       #3FA795;
  --brand-on-ink: #3FA795;
  --on-ink: #121815;
  --focus: #E8EEE9;
  --focus-offset: #121815;
}

/* ============================================================
   base
   ============================================================ */

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

/* Any explicit `display` beats the hidden attribute's user-agent rule, so a
   flex or grid container stays on screen with hidden="" set. Everything this
   app shows and hides is one of those. */
[hidden] { display: none !important; }

html { color-scheme: light dark; }

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: var(--fs-base);
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
}

/* every figure lines up in its column, everywhere, always */
.num, td.num, .figure {
  font-family: var(--font-num);
  font-variant-numeric: tabular-nums;
}

/* uppercase label — the one place letter-spacing is used */
.label {
  font-family: var(--font-num);
  font-size: var(--fs-label);
  font-weight: 500;
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--muted);
}

:where(a, button, input, select, textarea, [tabindex]):focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

/* decision states — form as well as colour, so it survives greyscale */
.decision { display: inline-flex; align-items: center; gap: var(--sp-2); font-weight: 600; white-space: nowrap; }
.decision::before { content: ""; width: 6px; height: 6px; flex: none; background: currentColor; }
.decision--act     { color: var(--act); }
.decision--review  { color: var(--review); }
.decision--settled { color: var(--settled); font-weight: 400; }
.decision--settled::before { background: none; border: 1px solid currentColor; }

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