/* FramaAI – design tokens.
   This is the ONLY file that may contain a colour literal. Every other stylesheet
   uses var(--token) or color-mix() on a token, so both themes stay in one place.
   A test (tests/test_style_tokens.py) fails the build if a hex colour appears in
   another app/static/*.css file.

   Load order of the stylesheets:
     tokens.css -> app.css (base) -> pages.css (page layouts)
     -> product-ui.css (components, PWA, polish) -> layout.css (side-menu preference)

   Scales: spacing 4/8/12/16/24/32/48, radius 10/16/24 (+ pill), type 11/12/13/15/20/2xl.
   Nothing smaller than --text-xs (11px) is allowed anywhere in the product. */

:root {
  color-scheme: light;

  /* ---- spacing ------------------------------------------------------ */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --space-7: 48px;

  /* ---- radii -------------------------------------------------------- */
  --radius-sm: 10px;   /* inputs, table chips, list rows */
  --radius-md: 16px;   /* buttons, alerts, controls inside a dialog */
  --radius-lg: 24px;   /* cards, tiles, dialog, app frame */
  --radius-pill: 999px;/* badges, nav pills, round icon buttons */
  --radius-card: var(--radius-lg);     /* legacy alias, kept for existing rules */
  --radius-control: var(--radius-md);  /* legacy alias, kept for existing rules */

  /* ---- type --------------------------------------------------------- */
  --text-xs: 11px;                      /* readable minimum: labels only */
  --text-sm: 12px;                      /* helper text, table-sub */
  --text-md: 13px;                      /* table cells, list rows */
  --text-base: 14px;                    /* body */
  --text-lg: 15px;                      /* h3, tile title */
  --text-xl: 20px;                      /* h2, card headings */
  --text-2xl: clamp(26px, 2.2vw, 34px); /* h1, the number on a tile */

  /* ---- surfaces and ink --------------------------------------------- */
  --bg: #f3f3f1;
  --surface: #fff;
  --surface-subtle: #f5f5f3;
  --surface-raised: #eaeae7;
  --ink: #292a28;
  --muted: #5d5f5a;    /* 6.5:1 on --surface; readable outdoors, not only at a desk */
  --line: #e2e2dd;
  --navy: #252624;
  --navy2: #333532;
  --white: #fff;
  /* Card and tile hairline: softer than a full --line border. */
  --card-line: color-mix(in srgb, var(--line) 60%, transparent);
  /* The wordmark is dark ink on transparency, so its plate stays light in both
     themes; in dark mode it is toned down instead of pure white. */
  --logo-plate: #fff;

  /* ---- FRAMA material ----------------------------------------------- */
  /* Matte graphite is the product's structural material. Champagne and
     copper only catch edges and active controls; they never carry meaning. */
  --graphite: #262724;
  --graphite-deep: #191a18;
  --graphite-soft: #343632;
  --on-graphite: #f6f3ec;
  --on-graphite-muted: #cbc8bf;
  --champagne: #d8bd91;
  --champagne-bright: #f2dfbd;
  --copper: #a85d3e;
  --material-line: #b88a6245;
  --material-glow: #d8bd9129;

  /* ---- light caught on the material ---------------------------------- */
  /* Every token below is mixed from the material above, so the dark block
     needs no copy of it: a custom property keeps its var() unresolved and
     resolves it on the element that uses it, under whichever theme is on.
     These are light, never meaning — the state palette above says what a
     thing is, and a word always says it next to the colour. */
  /* The channel the money runs along on the dashboard, and the light in it. */
  --flow-channel: color-mix(in srgb, var(--muted) 22%, transparent);
  --flow-light: color-mix(in srgb, var(--champagne-bright) 80%, var(--copper));
  --flow-node-line: color-mix(in srgb, var(--muted) 42%, transparent);
  /* Card and tile edges. Copper when something in the card waits for the
     owner, champagne when it is settled; at rest the --card-line hairline. */
  --edge-attention: color-mix(in srgb, var(--copper) 72%, transparent);
  --edge-settled: color-mix(in srgb, var(--champagne) 52%, transparent);
  /* The invoice sheet: its shadow on the desk and the warmth of the paper.
     The shadow follows the elevation colour of the theme, so the sheet is
     lifted by distance and blur, never by a second hue. */
  --paper-shadow: var(--shadow-raised-color);
  --paper-warm: color-mix(in srgb, var(--champagne) 10%, transparent);
  /* The single band of light that crosses the wordmark after a success. */
  --logo-sweep: color-mix(in srgb, var(--champagne-bright) 85%, transparent);

  /* ---- brand and accents -------------------------------------------- */
  --accent: #ad5230;   /* 5.2:1 on --surface, 4.7:1 on --bg: it is also used as text */
  --accent-soft: #f8e2d5;
  --accent-text: #733519;
  --primary-bg: #a45537;
  --primary-hover: #8e442b;
  --on-primary: #fffaf6;
  --teal: #5c7168;
  --teal-light: #eaf0eb;
  --link-hover: #933b20;
  --focus: #ad5334;

  /* ---- status palette ------------------------------------------------ */
  --success-bg: #e0f4ca;
  --success-text: #32602b;
  --warning-bg: #fbf0b9;
  --warning-text: #725c17;
  --error-bg: #f7dbc7;
  --error-text: #8e3e25;
  --info-bg: #e9eeeb;
  --info-text: #496258;
  --danger: #a93e39;
  --amber: #8e6d24;

  /* ---- money -------------------------------------------------------- */
  /* One reading for an amount, wherever it appears: a tile, a table cell,
     a total. Always paired with a word, never colour alone. */
  --money-paid: var(--success-text);
  --money-open: var(--ink);
  --money-overdue: var(--error-text);
  --money-draft: var(--muted);

  /* ---- document states ----------------------------------------------- */
  /* draft = not numbered, unsent = numbered but not delivered,
     open = issued and waiting, overdue = past due, paid = settled,
     advance = advance invoice / its tax document. */
  --state-draft-bg: var(--surface-raised);
  --state-draft-text: var(--muted);
  --state-unsent-bg: var(--info-bg);
  --state-unsent-text: var(--info-text);
  --state-open-bg: var(--warning-bg);
  --state-open-text: var(--warning-text);
  --state-overdue-bg: var(--error-bg);
  --state-overdue-text: var(--error-text);
  --state-paid-bg: var(--success-bg);
  --state-paid-text: var(--success-text);
  --state-advance-bg: var(--info-bg);
  --state-advance-text: var(--info-text);

  /* ---- charts -------------------------------------------------------- */
  --chart-issued: #d49a79;
  --chart-received: #7f9d8e;
  --chart-grid: color-mix(in srgb, var(--muted) 25%, transparent);
  /* Hatching on the issued bars; reads in both themes because it is mixed
     from the surface it sits on, not from white. */
  --chart-hatch: color-mix(in srgb, var(--surface) 45%, transparent);
  /* Categorical series for the report donut and legend, in order. */
  --chart-1: #77c9bd;
  --chart-2: #769cc2;
  --chart-3: #b1a5dc;
  --chart-4: #daa96c;
  --chart-5: #bf8298;
  --chart-6: #72859e;

  /* ---- elevation and overlay ----------------------------------------- */
  /* The two *-color tokens are the shadow colour only; each rule keeps its
     own offsets, so a popup and a dialog can differ in distance, not in hue. */
  --shadow: 0 1px 2px #2526200d, 0 10px 28px #25262009;
  --shadow-raised-color: #25262014;
  --shadow-overlay-color: #2526202e;
  --overlay: #10100f73;

  /* ---- motion & micro-interactions ----------------------------------- */
  --motion-fast: 130ms;
  --motion-panel: 200ms;
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-standard: cubic-bezier(0.4, 0, 0.2, 1);
  --selected-bg: color-mix(in srgb, var(--champagne) 22%, var(--surface));
  --selected-line: color-mix(in srgb, var(--copper) 65%, var(--line));

  /* ---- company accents ------------------------------------------------ */
  /* Ten curated hues a company can wear inside the app (app/branding.py
     ACCENTS). Each has a tone (lines, rings, active pills; at least 4.5:1
     on --surface and --bg) and a strong step (text and the filled primary
     button under white text, at least 6:1). The dark block redefines both
     as light steps on graphite. Copper is the house colour and the default. */
  --brand-copper: #ad5230;   --brand-copper-strong: #8f4026;
  --brand-ruby: #b8394a;     --brand-ruby-strong: #96283a;
  --brand-plum: #8e4a8a;     --brand-plum-strong: #723a6f;
  --brand-indigo: #4f58b8;   --brand-indigo-strong: #3d4596;
  --brand-ocean: #2c6ea3;    --brand-ocean-strong: #215684;
  --brand-teal: #1f7a7a;     --brand-teal-strong: #176262;
  --brand-sage: #45714f;     --brand-sage-strong: #375c40;
  --brand-olive: #686b25;    --brand-olive-strong: #55581d;
  --brand-gold: #85621a;     --brand-gold-strong: #6c4f13;
  --brand-graphite: #5c5f63; --brand-graphite-strong: #45484c;
  /* Hairline of the inputs and other controls a person must find: 3:1. */
  --line-strong: #8e9089;   /* 3.2:1 on --surface */
  /* Board backgrounds. Designed images, the same in both themes; the board
     view lays a theme scrim over them so columns and cards stay legible. */
  --board-graphite: radial-gradient(120% 90% at 85% 0%, #a85d3e59, transparent 55%), linear-gradient(160deg, #3a3c38, #1b1c1a 70%);
  --board-champagne: radial-gradient(90% 80% at 20% 0%, #fff4dccc, transparent 60%), linear-gradient(155deg, #e9d3ac, #c9a978 60%, #a88859);
  --board-copper: radial-gradient(100% 90% at 80% 10%, #f2b38a80, transparent 55%), linear-gradient(150deg, #b8653f, #7a3a24 60%, #3d1f15);
  --board-sage: radial-gradient(100% 80% at 15% 0%, #e2efd9a6, transparent 55%), linear-gradient(160deg, #8fae96, #557a62 55%, #2c4334);
  --board-slate: radial-gradient(110% 80% at 85% 0%, #b9c9dd8c, transparent 55%), linear-gradient(160deg, #6f8399, #3e4f63 55%, #1f2935);
  --board-sand: radial-gradient(100% 80% at 30% 0%, #fffaf0d9, transparent 60%), linear-gradient(160deg, #e6dccb, #cdbd9f 60%, #a99a7d);
  --board-dusk: radial-gradient(80% 60% at 75% 95%, #f6a77acc, transparent 60%), radial-gradient(90% 70% at 15% 20%, #7b4f9e99, transparent 60%), linear-gradient(170deg, #241c3d, #5b3a62 55%, #c27a6a);
  --board-aurora: radial-gradient(60% 50% at 25% 30%, #3fd1a7a6, transparent 70%), radial-gradient(55% 45% at 75% 20%, #4f8de0a6, transparent 70%), radial-gradient(70% 50% at 60% 80%, #8a5cd080, transparent 70%), linear-gradient(170deg, #0d1b2a, #10263a 60%, #0a141f);
  --board-ocean: radial-gradient(90% 70% at 80% 0%, #8fd3e8a6, transparent 60%), linear-gradient(165deg, #2f7fb3, #1c4f7a 50%, #0f2a45);
  --board-forest: radial-gradient(70% 90% at 30% 0%, #d8f0b880, transparent 60%), linear-gradient(170deg, #4d7a45, #2d5232 50%, #142a1a);
  --board-ember: radial-gradient(60% 55% at 70% 85%, #ff8a4cb3, transparent 65%), radial-gradient(50% 45% at 20% 30%, #c2303a8c, transparent 65%), linear-gradient(165deg, #2b1612, #1a0d0b);
  --board-terrazzo: radial-gradient(circle at 20% 30%, #b98a6a 0 2.5%, transparent 3%), radial-gradient(circle at 70% 60%, #7d8b86 0 2%, transparent 2.5%), radial-gradient(circle at 45% 80%, #d9b48f 0 3%, transparent 3.5%), radial-gradient(circle at 85% 15%, #8f6f5c 0 1.8%, transparent 2.3%), linear-gradient(160deg, #eee8df, #d9d1c4);
  --board-terrazzo-size: 140px 140px, 110px 110px, 170px 170px, 90px 90px, 100% 100%;
}

:root[data-theme="light"] {
  color-scheme: light;
}

:root[data-theme="dark"] {
  color-scheme: dark;

  --bg: #121212;
  --surface: #202020;
  --surface-subtle: #191919;
  --surface-raised: #2c2c2c;
  --ink: #f0f0ed;
  --muted: #afafaa;
  --line: #363634;
  --navy: #202020;
  --navy2: #2c2c2c;
  --logo-plate: #e9e9e5;

  --graphite: #20211f;
  --graphite-deep: #111210;
  --graphite-soft: #30322e;
  --on-graphite: #f5f1e8;
  --on-graphite-muted: #c9c4ba;
  --champagne: #dcbf91;
  --champagne-bright: #f4dfb8;
  --copper: #cc8765;
  --material-line: #d4ac7952;
  --material-glow: #dcbf912e;

  --accent: #d29879;
  --accent-soft: #46332b;
  --accent-text: #f0c1a5;
  --primary-bg: #cc9475;
  --primary-hover: #dcaa8e;
  --on-primary: #241d18;
  --teal: #a5b8aa;
  --teal-light: #29382e;
  --link-hover: #f0c1a5;
  --focus: #d29879;

  --success-bg: #2c402c;
  --success-text: #b9d3a5;
  --warning-bg: #443c26;
  --warning-text: #e6d493;
  --error-bg: #493128;
  --error-text: #efb097;
  --info-bg: #313b35;
  --info-text: #bed0c4;
  --danger: #efaaa0;
  --amber: #e6d493;

  --chart-issued: #c3977d;
  --chart-received: #8aa998;
  --chart-1: #8fd6cb;
  --chart-2: #93b6d8;
  --chart-3: #c3b9e8;
  --chart-4: #e8bd85;
  --chart-5: #d49aae;
  --chart-6: #93a5bc;

  --shadow: 0 4px 18px #0000000c;
  --shadow-raised-color: #00000059;
  --shadow-overlay-color: #00000073;
  --overlay: #0a0a09a6;

  /* Company accents as light steps on graphite: tone at least 6:1 on
     --surface, strong at least 9:1; the filled button carries dark ink. */
  --brand-copper: #d9a083;   --brand-copper-strong: #f0c1a5;
  --brand-ruby: #e88a96;     --brand-ruby-strong: #f4b3bb;
  --brand-plum: #c99bd0;     --brand-plum-strong: #e0c1e4;
  --brand-indigo: #a3aaf0;   --brand-indigo-strong: #c6cbf7;
  --brand-ocean: #84b6e3;    --brand-ocean-strong: #b4d3f0;
  --brand-teal: #74c4c0;     --brand-teal-strong: #a8dcd9;
  --brand-sage: #96c4a2;     --brand-sage-strong: #bfdcc6;
  --brand-olive: #c3c47a;    --brand-olive-strong: #dcdca8;
  --brand-gold: #dcbb6e;     --brand-gold-strong: #ecd59f;
  --brand-graphite: #b5b8bc; --brand-graphite-strong: #d6d8db;
  --line-strong: #6e6e6a;   /* 3.2:1 on --surface */
}

/* The accent a company wears. Any element may carry data-accent (a gateway
   tile does); --co and --co-strong then resolve under the current theme. */
[data-accent="copper"] { --co: var(--brand-copper); --co-strong: var(--brand-copper-strong); }
[data-accent="ruby"] { --co: var(--brand-ruby); --co-strong: var(--brand-ruby-strong); }
[data-accent="plum"] { --co: var(--brand-plum); --co-strong: var(--brand-plum-strong); }
[data-accent="indigo"] { --co: var(--brand-indigo); --co-strong: var(--brand-indigo-strong); }
[data-accent="ocean"] { --co: var(--brand-ocean); --co-strong: var(--brand-ocean-strong); }
[data-accent="teal"] { --co: var(--brand-teal); --co-strong: var(--brand-teal-strong); }
[data-accent="sage"] { --co: var(--brand-sage); --co-strong: var(--brand-sage-strong); }
[data-accent="olive"] { --co: var(--brand-olive); --co-strong: var(--brand-olive-strong); }
[data-accent="gold"] { --co: var(--brand-gold); --co-strong: var(--brand-gold-strong); }
[data-accent="graphite"] { --co: var(--brand-graphite); --co-strong: var(--brand-graphite-strong); }

/* Inside a company (/c/{id}/…, theme.js sets data-accent on <html>) the
   interactive accent follows the company. Copper keeps the house tokens
   above untouched; the material (graphite, champagne, wordmark) never moves. */
:root[data-accent]:not([data-accent="copper"]) {
  --accent: var(--co);
  --accent-text: var(--co-strong);
  --accent-soft: color-mix(in srgb, var(--co) 12%, var(--surface));
  --primary-bg: var(--co-strong);
  --primary-hover: color-mix(in srgb, var(--co-strong) 80%, var(--graphite-deep));
  --on-primary: var(--white);
  --link-hover: var(--co-strong);
  --focus: var(--co);
  --selected-bg: color-mix(in srgb, var(--co) 9%, var(--surface));
  --selected-line: color-mix(in srgb, var(--co) 60%, var(--line));
}
:root[data-theme="dark"][data-accent]:not([data-accent="copper"]) {
  --accent-soft: color-mix(in srgb, var(--co) 20%, var(--surface));
  --primary-bg: var(--co);
  --primary-hover: var(--co-strong);
  --on-primary: var(--graphite-deep);
  --selected-bg: color-mix(in srgb, var(--co) 14%, var(--surface));
}

/* The page background is declared once, here, so no theme switch flashes. */
html,
body {
  background: var(--bg);
}

body {
  color: var(--ink);
}
