/* /css/tokens.css - design/layout tokens, loaded before every other sheet.
   Colors are tokens only, so a theme is a token swap -- data-theme on <html>
   holds the resolved light/dark mode; theme.ts resolves "system" so CSS
   never queries the OS. */

:root,
:root[data-theme='light'] {
	--bg: #f4f2f0;
	--fg: #1a1a1a;
	--muted: #666;
	--muted-strong: #444;
	--subtle: #888;
	--help: #555;
	--border: #d0d0d0;
	--accent: #2c5f8a;
	/* Light's second hue, so the palette isn't navy doing every job.
	   Deliberately not dark's amber: a vermillion at amber's lightness and
	   weight. Accepted tradeoff: it sits within ~20 degrees of --warn-fg and
	   --amount-neg, so all three read as one warm family where they meet
	   (the Rules tab). Lightness set to clear AA as body-size text on every
	   light surface (4.60:1 on --bg, the lowest). */
	--heading: #cf3100;
	/* 80% white: 5.00:1 on the navy, and lets the fill soften through. */
	--accent-fg: rgb(255 255 255 / 0.8);
	/* A surface that is dark blue in both themes (dark's --accent is a light
	   blue, so it can't serve). Same as --accent here. */
	--navy: #2c5f8a;
	--navy-fg: rgb(255 255 255 / 0.8);
	/* Solid accent surface (checked segment, active tab, checked option,
	   .has-subs). Aliases the accent pair here; only dark diverges. */
	--accent-fill: var(--accent);
	--accent-fill-fg: var(--accent-fg);
	/* The default fill of any button that sets none of its own
	   (css/base.css): white here, black in dark. */
	--button-bg: #fff;
	/* Hover tints toward this button's own accent; --surface-alt is a neutral
	   and reads as gray rather than as belonging to this control's family. */
	--button-accent: var(--heading);
	--button-bg-hover: color-mix(in srgb, var(--button-accent) var(--button-hover-tint), var(--surface));
	/* --button-accent as a solid fill (the Dashboard card-view filter):
	   white clears 5.13:1 on light's vermillion. Dark reuses white too (as
	   a test) at only 3.19:1 on its amber -- clears the 3:1 non-text/icon
	   floor but not 4.5:1; --amber-fill-fg's black (6.59:1) is the safer
	   fallback if this doesn't read well. */
	--button-accent-fg: #fff;
	--surface: #fff;
	--surface-alt: #f4f7fa;
	--warn-bg: #fdf6e3;
	/* Serves as both a fill (--amber-fill: 4.50:1 under white) and text
	   (3.88:1 on #eee -- below AA, accepted). No single value clears both
	   brighter than #a35700; anything warmer buys the fill at the text's
	   expense. */
	--warn-fg: #c2570a;
	--warn-border: #e3c98f;
	--logo-a: #b2c9da;
	--logo-b: #036594;
	--amount-neg: #a3322c;
	--amount-pos: #1f6b3a;
	/* The *-fg partners below are the label color on that hue used as a
	   solid fill (the register filter strip's segments); the base hue stays
	   tuned for text/border use. */
	--amount-pos-fg: #fff;
	--fuchsia: #a02ca8;
	--fuchsia-fg: #fff;
	--amber-fill: var(--warn-fg);
	--amber-fill-fg: #fff;
	/* Notification-badge red, same in both themes. Distinct from
	   --amount-neg, which is tuned as text, not as a fill under white. */
	--danger: #dc2626;
	--danger-fg: #fff;
	--cyan: #0e7490;
	--cyan-fg: #fff;
	/* The H/Q/M mode picker's fill: every other named hue is already claimed
	   by a control in the same row or card (months, years, transfer). */
	--green: #15803d;
	--green-fg: #fff;
	color-scheme: light;
}

:root[data-theme='dark'] {
	--bg: #14181c;
	--fg: #e6e8ea;
	--muted: #9aa3ab;
	--muted-strong: #b9c0c7;
	--subtle: #7d868e;
	--help: #9aa3ab;
	--heading: #d97706;
	/* Every edge is navy in this palette. The select popup uses the neutral
	   #333b42 directly (css/select-picker.css -- tokens can't reach it). */
	--border: #2c5f8a;
	/* Navy is unreadable as text on dark (1.94:1), so the text/border
	   accent is a light blue under a near-black label (7.17:1). */
	--accent: #6aa9d6;
	--accent-fg: #10161a;
	--navy: #2c5f8a;
	--navy-fg: rgb(255 255 255 / 0.8);
	/* A solid accent surface takes the light theme's navy-and-dimmed-white
	   look rather than the light blue, which read as a heavy, flat slab.
	   --accent stays the light blue for text/border roles (status line,
	   focus ring, the asterisk reset). */
	--accent-fill: var(--navy);
	--accent-fill-fg: var(--navy-fg);
	--button-bg: #000;
	--button-accent: var(--heading);
	--button-bg-hover: color-mix(in srgb, var(--button-accent) var(--button-hover-tint), var(--surface));
	--button-accent-fg: #fff;
	--surface: #1b2025;
	--surface-alt: #232a30;
	--warn-bg: #3a2f18;
	--warn-fg: #e3c98f;
	--warn-border: #6b5626;
	--logo-a: #3f5a6b;
	--logo-b: #6aa9d6;
	--amount-neg: #e0857d;
	--amount-pos: #6fbf8b;
	/* Dark-mode fills are pale, so their labels are near-black. */
	--amount-pos-fg: #10161a;
	--fuchsia: #e07fef;
	--fuchsia-fg: #10161a;
	/* Bright rather than light's darkened orange: keeps a black label legible
	   (6.59:1) and separates from the chrome (5.60:1 vs --bg). */
	--amber-fill: #d97706;
	--amber-fill-fg: #000;
	--danger: #dc2626;
	--danger-fg: #fff;
	--cyan: #67e8f9;
	--cyan-fg: #10161a;
	--green: #4ade80;
	--green-fg: #000;
	color-scheme: dark;
}

:root {
	/* The register's width; the dashboard grid derives from it so both lists
	   share a right edge. */
	--register-width: 900px;
	--register-gap: 1rem;
	/* The register banner and the register list under it: one maximum width
	   for both, so they read as a single stack and shrink together on a
	   narrow screen. Named for what it measures rather than reusing
	   --register-width, because this is a *cap* (max-width), not a fixed
	   size -- the panels fill whatever the viewport gives them below it. */
	--account-register: var(--register-width);
	/* Side-by-side register columns share one row; each column can shrink, but
	   its banner never drops below this width so the account identity + range/
	   filter controls stay legible. Txn cards flow 100% of whatever the column
	   gives them (no per-card width cap). Also the gap between adjacent columns
	   and the page's outer padding a column keeps clear of its scrollbar. */
	--register-banner-min-width: 325px;
	--register-col-gap: 1.5rem;
	--register-scroll-gap: 0.75rem;
	/* Fallback top offset (the sticky header + card-view strip + carousel row +
	   gaps + padding) subtracted from 100dvh for each register column's
	   max-height. layoutRegisterHeight() (ts/dashboard.ts) measures the real
	   value at runtime and overrides this inline, so this token is only the
	   pre-first-measure default. */
	--register-column-top-offset: 15rem;
	/* The floor a register column's height is allowed to shrink to (see the
	   max-height rule that consumes both tokens, css/dashboard.css). The
	   column itself scrolls as one unit -- banner and rows together, no child
	   pinned in place -- so every row is always reachable regardless of this
	   value; the floor isn't protecting anything from being squeezed to zero.
	   It just keeps a cramped viewport (a small phone, or an iPad portrait
	   column once the banner's own content grows) from rendering a column
	   that's technically scrollable but shows almost nothing at a time. */
	--register-column-min-height: 600px;
	/* A grid card's fixed width (200px). The row is a horizontal overlap
	   strip now, so the cards share one size rather than splitting the
	   register width; every card is this wide, uniform regardless of content.
	   The overlap margin derives from this same token, so a width change
	   keeps the 33% overlap proportional. */
	--card-width: 12.5rem;
	/* Shared by every form control, including the register's smaller ones.
	   --control-height is the modest one the three pickers in a .ledger-range
	   row share (css/range.css); every .ledger-range takes a taller one
	   back once the row itself is narrow, whichever page it is on, because
	   the row then becomes a stack of full-width bars and each segment has
	   to be a finger-sized target. */
	--control-radius: 4px;
	--control-height: 1.5rem;
	/* Shared by every top-level card/panel. Re-declared in
	   css/select-picker.css, since tokens don't inherit into
	   ::picker(select). */
	--panel-radius: 6px;
	/* Books and Accounts tables have different column counts, so a
	   percentage width would differ between their name inputs. */
	--name-input-width: 18rem;
	/* How far each card kind's gray base leans toward its tint: an influence
	   on the gray, never a replacement. Shared by the Dashboard cards and the
	   register's txn cards. The tints are literals, not --amber-fill, which
	   is theme-tuned and would shift a card's hue with the theme. */
	--card-tint: 10%;
	/* The single hover tint both themes mix at; a per-theme value would make
	   "the same tint level" a thing to re-verify on every theme edit. */
	--button-hover-tint: 12%;
	--tinted-account-base: color-mix(in srgb, #d97706 var(--card-tint), #888888);
	--tinted-book-base: color-mix(in srgb, var(--navy) var(--card-tint), #888888);
	--font-mono: ui-monospace, 'SF Mono', 'Cascadia Code', 'Segoe UI Mono', Consolas, monospace;
}
