From ba45b8f6612bb95f19058e4185b52b30180797c4 Mon Sep 17 00:00:00 2001 From: Jakob Wennberg <149234542+jakobwennberg@users.noreply.github.com> Date: Wed, 13 May 2026 23:01:53 +0200 Subject: [PATCH] refactor(ui): editorial monochrome design refresh (#473) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor(ui): editorial monochrome design refresh Design-system layer only, no functional changes. Cascades app-wide from 8 files in the primitives + tokens layer. - Swap Fraunces → Hedvig Letters Serif for display typography (single-weight; drop font-medium from CardTitle and PageHeader) - Token sweep: pure white background, warm beige secondary (40 11% 89%), achromatic primary, calibrated 45 5% 85% border, halved-opacity shadows - Flatten Card: remove shadow, rounded-xl → rounded-lg, full-opacity border (was border-border/60) - Flatten Button: remove shadow-sm, remove active:scale-[0.98], drop outline border morph, transition-all 300ms → transition-colors 150ms - Soften Dialog overlay (bg-black/80 → bg-black/40 with dark variant) and use halved --shadow-md token on DialogContent - Sidebar: bg-card/90 → bg-background, full-opacity hairline border, warm-beige active state (bg-secondary), hover bg-secondary/60 - .hover-lift utility: replace translateY + box-shadow with flat background-color shift - PageHeader title: text-2xl font-medium → text-3xl md:text-4xl (no font-medium) - CLAUDE.md Brand & Aesthetic, Typography, and Forbidden Patterns sections rewritten to reflect new system Co-Authored-By: Claude Opus 4.7 (1M context) * refactor(ui): address PR review - Remove dead .hover-lift utility (no callers; CLAUDE.md now bans hover-lift patterns, so leaving the class would contradict the docs) - Bump Dialog overlay bg-black/40 → bg-black/50 — gives a more perceptible separation layer over the new pure-white background while keeping the lighter editorial feel Co-Authored-By: Claude Opus 4.7 (1M context) --------- Co-authored-by: Claude Opus 4.7 (1M context) --- CLAUDE.md | 24 +++++++---- app/globals.css | 59 ++++++++++----------------- app/layout.tsx | 9 ++-- components/dashboard/DashboardNav.tsx | 22 +++++----- components/ui/button.tsx | 10 ++--- components/ui/card.tsx | 4 +- components/ui/dialog.tsx | 4 +- components/ui/page-header.tsx | 2 +- 8 files changed, 63 insertions(+), 71 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index f87d627c..3572f86a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -354,13 +354,13 @@ Swedish sole traders (enskild firma) and small business owners (aktiebolag) who ### Brand & Aesthetic -**Minimal. Sharp. Efficient.** The interface should feel like a well-made instrument: considered, quiet, and confident. Reference: Mercury (banking). Anti-reference: enterprise software (SAP/Oracle density). +**Editorial monochrome.** Paper-white surfaces, hairline borders, serif headlines. The interface should feel like a well-made instrument — considered, quiet, confident. Anti-references: enterprise software (SAP/Oracle density), neon SaaS coldness. -- **Palette**: Grayscale foundation with restrained semantic colors — sage green (success/balance), terracotta (errors/overdue), ochre (warnings/attention). No loud brand color. -- **Typography**: Fraunces (serif) for display headings, Geist (sans) for body. Tabular numbers everywhere financial data appears. -- **Surfaces**: White/near-white cards on light gray backgrounds. Subtle borders (60% opacity). Soft shadows. Dark mode follows the same restraint. +- **Palette**: Achromatic foundation. Pure white background, warm beige (`40 11% 89%`) for chips / active sidebar / hover / secondary buttons. Achromatic primary (no cool tint). Semantic colors (`--success` sage, `--warning` ochre, `--destructive` terracotta) exist but are **data-only** — they appear in charts and financial numbers (positive/negative deltas), never as chrome backgrounds. In chrome, only `--destructive` survives. +- **Typography**: Hedvig Letters Serif for display headings, Geist (sans) for body, forms, and tables. Hedvig is single-weight (400) — do not apply `font-medium` to display text; its natural high-contrast strokes carry the weight. Tabular numbers everywhere financial data appears. +- **Surfaces**: Cards sit flat on the page — no shadow, full-opacity hairline border (`border-border`), `rounded-lg` (8px). Card background matches page background; the border carries hierarchy. Dark mode drops the warm tint from secondary for a pure-gray mood shift; light mode keeps the beige. - **Spacing**: Generous whitespace. Dense data (tables, ledgers) uses tighter spacing but never feels cramped. -- **Motion**: Subtle and purposeful. Stagger animations for list entry, spring easing for feedback. Never decorative. +- **Motion**: Functional, not decorative. No press-scale, no hover-lift, no spring overshoot. Hover state is a flat background shift (`bg-secondary/60`). `transition-colors duration-150` is the default. Stagger animations on list entry are fine. Respect `prefers-reduced-motion` (already wired). - **Icons**: Lucide — 15px in navigation, slightly larger in empty states. ### Design Principles @@ -426,11 +426,11 @@ Never render raw `{x.invoice_date}` directly — always route through `formatDat **Currency.** `formatCurrency(n, currency?)` from `lib/utils.ts`. Default SEK. **Typography.** -- Page title: `

` (or use `PageHeader`). -- Card title: `` for sections, default for primary cards. +- Page title: use `PageHeader` (renders `font-display text-3xl md:text-4xl tracking-tight`). Do not hand-roll an `

`. +- Card title: `` for sections, default for primary cards. The primitive already drops `font-medium` — do not add it back. - Section divider header inside a page: `

`. -- Headline number: `font-display text-xl font-medium tabular-nums`. -- Display font (`font-display`, Fraunces) reserved for h1/h2/h3 and primary financial numbers. +- Headline number: `font-display text-xl tabular-nums`. No `font-medium` — Hedvig's natural weight carries the gravitas. +- Display font (`font-display`, Hedvig Letters Serif) reserved for h1/h2/h3 and primary financial numbers. If a specific `font-display` numeral reads weak inside a compact metric card, override that call site with `font-sans tabular-nums` (Geist) — better legibility on small numerals. **Forbidden / dead patterns.** - Page descriptions that paraphrase the page title (e.g. ``) → drop the description. @@ -438,3 +438,9 @@ Never render raw `{x.invoice_date}` directly — always route through `formatDat - Mobile-specific `