/* ────────────────────────────────────────────────────────────────────────── ms-haushalt · global tokens, reset, and base typography. See .impeccable.md for the design context this expresses. ────────────────────────────────────────────────────────────────────────── */ @import "@fontsource-variable/geist"; @import "@fontsource-variable/geist-mono"; /* Figtree Variable — display + body face. SIL OFL, served from public/fonts. Roman + italic axes, weight 300–900. */ @font-face { font-family: "Figtree Variable"; src: url("/fonts/Figtree-VariableFont_wght.woff2") format("woff2-variations"); font-weight: 300 900; font-style: normal; font-display: swap; } @font-face { font-family: "Figtree Variable"; src: url("/fonts/Figtree-Italic-VariableFont_wght.woff2") format("woff2-variations"); font-weight: 300 900; font-style: italic; font-display: swap; } :root { /* ── Color (OKLCH, paper-feeling, two-hue flow palette) ───────────── */ /* Background: warm uncoated stock, never pure white. Tinted toward the Aufwendungen hue family by 0.005-0.01 chroma per the impeccable "tint neutrals toward brand hue" principle. */ --paper: oklch(98.4% 0.006 60); --paper-deep: oklch(96.0% 0.008 60); /* Ink: warmed near-black. Same principle inverted. */ --ink: oklch(20% 0.02 50); --ink-soft: oklch(38% 0.02 55); --ink-mute: oklch(58% 0.015 60); /* Hairlines & faint surfaces. */ --rule: oklch(86% 0.012 60); --rule-soft: oklch(92% 0.008 60); /* Two-hue flow palette per design brief §9.5: deep purple for Aufwendungen (money leaving), orange for Erträge (money coming in). The two ranges sit on opposite sides of the label-contrast threshold so all labels on each flow's icicle can be a single colour: light text on the dark purples, dark text on the light oranges. Mirrors the JS PALETTE in src/lib/colors.ts. */ --flow-aufwand-h: 295; /* deep plum-purple */ --flow-aufwand-c: 0.19; --flow-ertrag-h: 55; /* warm orange / amber */ --flow-ertrag-c: 0.15; /* Solid ink-on-paper renders of each flow accent (used for active toggle state, breadcrumb separators, slider handle, etc.). The accent uses Ldark / Llight values that match the bar palette's darkest-purple and lightest-readable-orange respectively. */ --flow-aufwand: oklch(34% var(--flow-aufwand-c) var(--flow-aufwand-h)); --flow-ertrag: oklch(68% var(--flow-ertrag-c) var(--flow-ertrag-h)); /* ── Spacing (4pt scale, semantic names) ──────────────────────────── */ --space-2xs: 4px; --space-xs: 8px; --space-sm: 12px; --space-md: 16px; --space-lg: 24px; --space-xl: 32px; --space-2xl: 48px; --space-3xl: 64px; --space-4xl: 96px; /* ── Type scale ───────────────────────────────────────────────────── */ /* Display sizes are fluid (editorial, not app-chrome), per the typography rule. Body and UI sizes are fixed rem. The display range is intentionally tighter than the previous version — the hero needs to stay above the fold on a typical 13" laptop. */ --size-display-1: clamp(2.625rem, 5.5vw + 1rem, 5.25rem); /* hero stack */ --size-display-2: clamp(1.75rem, 2.5vw + 0.5rem, 2.5rem); /* sidebar heading */ --size-display-3: 1.375rem; /* secondary */ --size-body: 1rem; /* 16px */ --size-body-lg: 1.0625rem;/* 17px lede */ --size-caption: 0.8125rem;/* 13px */ --size-eyebrow: 0.6875rem;/* 11px small caps */ --size-micro: 0.75rem; /* 12px sidebar dt labels */ /* ── Faces ────────────────────────────────────────────────────────── */ /* Display + body: Figtree (variable, SIL OFL, served from public/fonts). Numbers: Geist Mono. The `--face-serif` / `--face-sans` token names are legacy aliases — both now point to Figtree since it carries display and body alike. */ --face-display: "Figtree Variable", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif; --face-serif: var(--face-display); --face-sans: var(--face-display); --face-mono: "Geist Mono Variable", "Geist Variable", ui-monospace, "SF Mono", "Menlo", monospace; /* ── Layout rhythm ────────────────────────────────────────────────── */ --measure: 65ch; --page-max: 1280px; --page-pad-x: clamp(1rem, 4vw, 3rem); } /* ── Reset ──────────────────────────────────────────────────────────── */ *, *::before, *::after { box-sizing: border-box; } html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; font-feature-settings: "kern" 1, "liga" 1, "calt" 1, "ss01" 1; /* German-specific OpenType: lining figures for tabular data, oldstyle elsewhere. Enabled per-element where useful. */ } body { margin: 0; background: var(--paper); color: var(--ink); font-family: var(--face-serif); font-size: var(--size-body); line-height: 1.55; font-feature-settings: "kern" 1, "liga" 1, "calt" 1; /* Slight optical correction for warmly-tinted paper background. */ -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } p { margin: 0 0 var(--space-md); max-width: var(--measure); } h1, h2, h3, h4 { margin: 0; font-family: var(--face-serif); font-weight: 800; line-height: 0.95; letter-spacing: -0.01em; font-variant-ligatures: discretionary-ligatures; } a { color: inherit; text-decoration-thickness: 1px; text-underline-offset: 0.18em; } button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; } /* ── Utility patterns we use repeatedly ─────────────────────────────── */ .eyebrow { font-family: var(--face-sans); font-size: var(--size-eyebrow); font-weight: 500; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-mute); } .caption { font-family: var(--face-sans); font-size: var(--size-caption); color: var(--ink-soft); line-height: 1.4; } .tabular { font-family: var(--face-mono); font-variant-numeric: tabular-nums lining-nums; font-feature-settings: "tnum" 1, "lnum" 1; letter-spacing: -0.01em; } @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; } }