/* FridgeMath — design tokens. Single source of truth; copy this file verbatim into the app stylesheet.
   Light is the default. Dark applies via [data-theme="dark"], or via the system preference when no
   data-theme is set on <html>. Every value in the design traces back to a name below.
   Breakpoints cannot be custom properties; they are fixed at: md = 48rem (768px), lg = 64rem (1024px).

   Palette: institutional navy for trust and action, a distinct growth green reserved for money in,
   gold for "needs a look", crisp cool neutrals with charcoal-slate ink for dense financial data. */
@import url("https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700;800&display=swap");

:root, [data-theme="light"] {
  color-scheme: light;
  /* Surfaces — crisp, cool, uncluttered; the data is the only thing with colour */
  --bg: #F7F9FC;             /* page background */
  --surface: #FFFFFF;        /* cards, rows, inputs, sidebar */
  --surface-2: #EDF1F7;      /* row hover, table header, skeleton base, secondary fills */
  --surface-3: #DFE5EE;      /* pressed / active fills */
  /* Text — charcoal slate, not black; maximum legibility at 12–14px in dense tables */
  --fg: #16202E;             /* primary text, icons */
  --muted: #55606F;          /* secondary text, captions, placeholders */
  /* Lines */
  --line: #DDE3EC;           /* decorative dividers, card borders */
  --line-strong: #6B7787;    /* control borders (inputs, checkboxes) — meets 3:1 */
  /* Brand — deep banking navy: trust, security, and every primary action */
  --primary: #1A3A6B;        /* primary buttons, links, active nav, progress fill */
  --primary-hover: #142E55;
  --primary-ink: #FFFFFF;    /* text on --primary */
  --primary-soft: #E4EBF6;   /* selected rows, quiet-button hover, tints */
  /* Secondary — violet. Means "FridgeMath worked this out; you haven't confirmed it." Learned
     category suggestions, detected recurring charges, import column guesses, insight prompts.
     Never used for something the user chose: selection, focus and every action stay --primary,
     so the two never compete. Always paired with a dashed border and the word "Suggested". */
  /* Co-equal with --primary in weight, never in role. Navy acts (filled buttons, links, focus,
     selection); violet is the app speaking (wordmark, outlined secondary buttons, chart series 2,
     the heatmap ramp, and anything it worked out but you have not confirmed). The two are NEVER
     adjacent solid fills — they measure 1.95:1 against each other — so primary is always filled
     and secondary always outlined, with a surface between them. */
  --secondary: #8046C9;
  --secondary-hover: #6B39AB;
  --secondary-ink: #FFFFFF;
  --secondary-soft: #F0E8FA;
  /* Growth — money in, and only money in. Never used for a neutral success or a UI accent. */
  --positive: #0B6E50;             /* income text, always paired with a leading + sign */
  --positive-hover: #095A41;       /* the far stop of --positive-grad */
  --positive-soft: #DFF3EA;
  /* Needs a look — gold. Never a failure state. */
  --attention: #E8A317;      /* attention fills that carry --attention-ink text */
  --attention-ink: #16202E;  /* text on --attention */
  --attention-fg: #8A5A00;   /* attention as text ("Over by $42.10") */
  --attention-strong: #B8700A; /* attention as a graphic: unreviewed bar, hatched over-budget fill */
  --attention-soft: #FBF0D7;
  /* Destructive / broken */
  --danger: #C0281E;         /* danger buttons, failed sync */
  --danger-hover: #9E1E16;
  --danger-ink: #FFFFFF;
  --danger-soft: #FAE6E4;
  /* Misc */
  --focus: #1A3A6B;          /* focus ring — 2px outline, 2px offset */
  --overlay: rgba(11, 18, 30, 0.5);
  --shadow-1: 0 1px 2px rgba(16, 32, 46, 0.07);
  --shadow-2: 0 4px 16px rgba(16, 32, 46, 0.12);
  --shadow-3: 0 16px 48px rgba(16, 32, 46, 0.22);
  --heat-0: #EDF1F7; --heat-1: #E1D5F5; --heat-2: #BE9BEC; --heat-3: #8046C9; --heat-4: #4E2380;
  --heat-ink-lo: #16202E; --heat-ink-hi: #FFFFFF;
  --logo: url("assets/fridgemath-logo-light.png");
  --skeleton-shine: #F7F9FC;
  /* Surface treatments — declared once so every panel shares the same recipe.
     A card is a hairline border PLUS a two-layer shadow: a tight 1px contact shadow and a
     softer ambient one. One-layer shadows are what make a card look like a 2013 box. */
  --elev-1: 0 1px 2px rgba(16,32,46,.06), 0 1px 1px rgba(16,32,46,.04);
  --elev-2: 0 1px 2px rgba(16,32,46,.06), 0 4px 12px rgba(16,32,46,.07);
  --elev-3: 0 2px 4px rgba(16,32,46,.08), 0 12px 32px rgba(16,32,46,.12);
  /* Section headers, and cards that carry a meaning: a barely-there wash so the band or the card
     reads as distinct without a second border. 2% is deliberate — anything stronger competes with
     the data. The angle is 135deg throughout, which is the mobile design's; every tone is written
     in terms of its own --*-soft and --surface, so the dark block needs no separate values.
     Discipline is unchanged: amber is "needs a look", never failure; red is a destructive action
     or a broken bank connection; violet is the app speaking; green is money in. A tinted card
     still carries the word as well as the colour. */
  --head-wash: linear-gradient(135deg, var(--surface-2) 0%, var(--surface) 100%);
  --card-wash: linear-gradient(135deg, var(--surface) 0%, var(--surface) 100%);
  --attention-wash: linear-gradient(135deg, var(--attention-soft) 0%, var(--surface) 100%);
  --danger-wash: linear-gradient(135deg, var(--danger-soft) 0%, var(--surface) 100%);
  --secondary-wash: linear-gradient(135deg, var(--secondary-soft) 0%, var(--surface) 100%);
  --positive-wash: linear-gradient(135deg, var(--positive-soft) 0%, var(--surface) 100%);
  /* Filled voices. The mobile design draws every filled button, the round ＋, the filters count
     badge and a row's review and delete panes as a 135deg gradient from the colour to its own
     hover stop rather than as a flat fill; written in terms of both so the dark block needs no
     separate values. --secondary-grad is declared for completeness and used by neither client:
     violet is the outlined voice, and a violet fill beside a navy one measures 1.95:1. */
  --primary-grad: linear-gradient(135deg, var(--primary) 0%, var(--primary-hover) 100%);
  --secondary-grad: linear-gradient(135deg, var(--secondary) 0%, var(--secondary-hover) 100%);
  --danger-grad: linear-gradient(135deg, var(--danger) 0%, var(--danger-hover) 100%);
  --positive-grad: linear-gradient(135deg, var(--positive) 0%, var(--positive-hover) 100%);
  --hair: 1px solid var(--line);
}

[data-theme="dark"] {
  color-scheme: dark;
  --bg: #0E1420;
  --surface: #161E2C;
  --surface-2: #1F2937;
  --surface-3: #2A3543;
  --fg: #E8EDF4;
  --muted: #9AA6B6;
  --line: #263140;
  --line-strong: #7B8798;
  --primary: #7FA8F0;        /* navy inverts to a bright azure so it can carry dark ink */
  --primary-hover: #9BBDF5;
  --primary-ink: #0B1526;
  --primary-soft: #1B2C48;
  --secondary: #B98FF0; --secondary-hover: #C9A8F5; --secondary-ink: #1B0B33; --secondary-soft: #2E2050;
  --positive: #4ECF9B;
  --positive-hover: #3FB88A;
  --positive-soft: #14352A;
  --attention: #E8A317;
  --attention-ink: #16202E;
  --attention-fg: #F0B84E;
  --attention-strong: #E8A317;
  --attention-soft: #3B2C10;
  --danger: #F58A80;
  --danger-hover: #F9A9A1;
  --danger-ink: #2A0906;
  --danger-soft: #3D1714;
  --focus: #7FA8F0;
  --overlay: rgba(0, 0, 0, 0.62);
  --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.45);
  --shadow-2: 0 4px 16px rgba(0, 0, 0, 0.55);
  --shadow-3: 0 16px 48px rgba(0, 0, 0, 0.65);
  --heat-0: #1F2937; --heat-1: #302351; --heat-2: #55408C; --heat-3: #9C7BE0; --heat-4: #B98FF0;
  --heat-ink-lo: #E8EDF4; --heat-ink-hi: #0B1526;
  --logo: url("assets/fridgemath-logo-dark.png");
  --skeleton-shine: #2A3543;
  --elev-1: 0 1px 2px rgba(0,0,0,.4), 0 1px 1px rgba(0,0,0,.3);
  --elev-2: 0 1px 2px rgba(0,0,0,.4), 0 4px 12px rgba(0,0,0,.45);
  --elev-3: 0 2px 4px rgba(0,0,0,.5), 0 12px 32px rgba(0,0,0,.6);
  --head-wash: linear-gradient(135deg, var(--surface-2) 0%, var(--surface) 100%);
  --card-wash: linear-gradient(135deg, var(--surface) 0%, var(--surface) 100%);
  --attention-wash: linear-gradient(135deg, var(--attention-soft) 0%, var(--surface) 100%);
  --danger-wash: linear-gradient(135deg, var(--danger-soft) 0%, var(--surface) 100%);
  --secondary-wash: linear-gradient(135deg, var(--secondary-soft) 0%, var(--surface) 100%);
  --positive-wash: linear-gradient(135deg, var(--positive-soft) 0%, var(--surface) 100%);
  /* Filled voices. The mobile design draws every filled button, the round ＋, the filters count
     badge and a row's review and delete panes as a 135deg gradient from the colour to its own
     hover stop rather than as a flat fill; written in terms of both so the dark block needs no
     separate values. --secondary-grad is declared for completeness and used by neither client:
     violet is the outlined voice, and a violet fill beside a navy one measures 1.95:1. */
  --primary-grad: linear-gradient(135deg, var(--primary) 0%, var(--primary-hover) 100%);
  --secondary-grad: linear-gradient(135deg, var(--secondary) 0%, var(--secondary-hover) 100%);
  --danger-grad: linear-gradient(135deg, var(--danger) 0%, var(--danger-hover) 100%);
  --positive-grad: linear-gradient(135deg, var(--positive) 0%, var(--positive-hover) 100%);

}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --bg: #0E1420;
    --surface: #161E2C;
    --surface-2: #1F2937;
    --surface-3: #2A3543;
    --fg: #E8EDF4;
    --muted: #9AA6B6;
    --line: #263140;
    --line-strong: #7B8798;
    --primary: #7FA8F0;
    --primary-hover: #9BBDF5;
    --primary-ink: #0B1526;
    --primary-soft: #1B2C48;
    --secondary: #B98FF0; --secondary-hover: #C9A8F5; --secondary-ink: #1B0B33; --secondary-soft: #2E2050;
    --positive: #4ECF9B;
    --positive-hover: #3FB88A;
    --positive-soft: #14352A;
    --attention: #E8A317;
    --attention-ink: #16202E;
    --attention-fg: #F0B84E;
    --attention-strong: #E8A317;
    --attention-soft: #3B2C10;
    --danger: #F58A80;
    --danger-hover: #F9A9A1;
    --danger-ink: #2A0906;
    --danger-soft: #3D1714;
    --focus: #7FA8F0;
    --overlay: rgba(0, 0, 0, 0.62);
    --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.45);
    --shadow-2: 0 4px 16px rgba(0, 0, 0, 0.55);
    --shadow-3: 0 16px 48px rgba(0, 0, 0, 0.65);
    --heat-0: #1F2937; --heat-1: #302351; --heat-2: #55408C; --heat-3: #9C7BE0; --heat-4: #B98FF0;
  --heat-ink-lo: #E8EDF4; --heat-ink-hi: #0B1526;
  --logo: url("assets/fridgemath-logo-dark.png");
  --skeleton-shine: #2A3543;
  --elev-1: 0 1px 2px rgba(0,0,0,.4), 0 1px 1px rgba(0,0,0,.3);
  --elev-2: 0 1px 2px rgba(0,0,0,.4), 0 4px 12px rgba(0,0,0,.45);
  --elev-3: 0 2px 4px rgba(0,0,0,.5), 0 12px 32px rgba(0,0,0,.6);
  --head-wash: linear-gradient(135deg, var(--surface-2) 0%, var(--surface) 100%);
  --card-wash: linear-gradient(135deg, var(--surface) 0%, var(--surface) 100%);
  --attention-wash: linear-gradient(135deg, var(--attention-soft) 0%, var(--surface) 100%);
  --danger-wash: linear-gradient(135deg, var(--danger-soft) 0%, var(--surface) 100%);
  --secondary-wash: linear-gradient(135deg, var(--secondary-soft) 0%, var(--surface) 100%);
  --positive-wash: linear-gradient(135deg, var(--positive-soft) 0%, var(--surface) 100%);
  /* Filled voices. The mobile design draws every filled button, the round ＋, the filters count
     badge and a row's review and delete panes as a 135deg gradient from the colour to its own
     hover stop rather than as a flat fill; written in terms of both so the dark block needs no
     separate values. --secondary-grad is declared for completeness and used by neither client:
     violet is the outlined voice, and a violet fill beside a navy one measures 1.95:1. */
  --primary-grad: linear-gradient(135deg, var(--primary) 0%, var(--primary-hover) 100%);
  --secondary-grad: linear-gradient(135deg, var(--secondary) 0%, var(--secondary-hover) 100%);
  --danger-grad: linear-gradient(135deg, var(--danger) 0%, var(--danger-hover) 100%);
  --positive-grad: linear-gradient(135deg, var(--positive) 0%, var(--positive-hover) 100%);

  }
}

:root {
  /* Chart palette — ONE set for both themes, which is the binding constraint: every series must
     measure ≥3:1 against #F7F9FC AND #0E1420, so each colour sits in the luminance band 0.12–0.28.
     Hues are spread ~45° apart and lightness is varied within the band, so neighbouring series
     differ in weight as well as hue. Series are still never distinguished by colour alone: each
     carries a direct label, and bars take a pattern fill once there are more than four series.
     Order is assignment order — 1 is the default single-series colour. */
  --chart-1: #3A6BC4;  /* azure — the navy voice leads */
  --chart-2: #8046C9;  /* violet — the second voice, so both appear in any chart with 2+ series */
  --chart-3: #C4830E;  /* gold */
  --chart-4: #C2417F;  /* magenta */
  --chart-5: #0F8A63;  /* green — placed late so a chart series never reads as "money in" */
  --chart-6: #C4453A;  /* coral */
  --chart-7: #6F8C1F;  /* olive */
  --chart-8: #6E7A8A;  /* slate — always "Other" */
  --chart-grid: var(--line);       /* 1px gridlines */
  --chart-axis: var(--muted);      /* 12/16 axis labels; the only place amounts may abbreviate */
  --chart-pattern: 3px;            /* hatch period for pattern fills */

  /* Spacing scale — the only spacing values allowed */
  --s-1: 4px;
  --s-2: 8px;
  --s-3: 12px;
  --s-4: 16px;
  --s-5: 24px;
  --s-6: 32px;
  --s-7: 48px;
  --s-8: 64px;

  /* Type — one family, two weights, tabular numerals on every amount */
  /* Nunito — the logo's typeface. Rounded terminals and a single-storey g, which carries the
     "kind, not punishing" mandate into the type itself. Weights 400 and 600 for UI; 700/800 only
     for the wordmark and hero amounts. Tabular numerals are switched on globally below: Nunito's
     default figures are proportional, and a proportional 1 in a column of amounts is a defect. */
  --font: "Nunito", system-ui, -apple-system, "Segoe UI", sans-serif;
  --t-1: 12px; --lh-1: 16px;   /* captions, pills, table meta */
  --t-2: 14px; --lh-2: 20px;   /* body, rows, controls (desktop) */
  --t-3: 16px; --lh-3: 24px;   /* body on mobile, inputs on mobile, card titles */
  --t-4: 20px; --lh-4: 28px;   /* section titles */
  --t-5: 24px; --lh-5: 32px;   /* page titles */
  --t-6: 32px; --lh-6: 40px;   /* hero amounts */
  --w-regular: 400;
  --w-semibold: 600;
  --w-bold: 700;    /* wordmark, hero amounts */

  /* Radius */
  --r-1: 4px;      /* checkbox, small chips */
  --r-2: 8px;      /* buttons, inputs, selects */
  --r-3: 12px;     /* cards, dialogs, sheets */
  --r-pill: 999px; /* pills, toggles */

  /* Motion */
  --dur-1: 120ms;  /* hover, focus, toggles */
  --dur-2: 200ms;  /* panels, sheets, dialogs */
  --ease: cubic-bezier(0.2, 0, 0, 1);

  /* Layout */
  --sidebar: 240px;
  --rail: 64px;
  --bottombar: 64px;
  --control-h: 36px;          /* desktop controls */
  --control-h-touch: 44px;    /* controls below md */
  --row-compact: 32px;        /* desktop density: compact */
  --row-comfortable: 44px;    /* desktop density: comfortable (default) */
  --row-card: 64px;           /* mobile list card */
  --row: var(--row-comfortable); /* resolved row height; the density setting sets data-density on <html> */
  --target-min: 24px;
  --target-touch: 44px;
  --content-max: 1200px;
}

[data-density="compact"] { --row: var(--row-compact); }
[data-density="comfortable"] { --row: var(--row-comfortable); }

/* Global rules that belong to the token layer */
body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font: var(--w-regular) var(--t-2) / var(--lh-2) var(--font);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  font-feature-settings: "tnum" 1, "lnum" 1;  /* every figure tabular and lining, everywhere */
}
a { color: var(--primary); }
a:hover { color: var(--primary-hover); }
:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
::selection { background: var(--primary-soft); color: var(--fg); }

/* Brand lockup. Trimmed to ink bounds, so both files render at the same visual size in one box.
   Light file = navy wordmark for light surfaces; dark file = white wordmark for dark surfaces. */
.fm-logo {
  display: block;
  background-image: var(--logo);
  background-repeat: no-repeat;
  background-position: left center;
  background-size: contain;
}
[dir="rtl"] .fm-logo { background-position: right center; }

@keyframes fm-shimmer { from { background-position: 200% 0; } to { background-position: -200% 0; } }
@keyframes fm-spin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
  :root { --dur-1: 0ms; --dur-2: 0ms; }
  * { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; }
}
