jules bd87175b52 lib-theme-klein: initial import (bold/identity-forward set, 2026-07)
One of four divergent candidates for the bold consumer theme family
(committed saturated color at 30-60% surface coverage, strong display
type). Includes the post-diverge fixes: heading color:inherit so brand
slabs keep their foreground pairing, plus per-theme refinements.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 23:20:55 +10:00

lib-theme-klein

Klein — ultramarine drench. A bold, identity-forward Crema theme where the background field itself is committed, saturated Yves-Klein ultramarine.

Thesis

Most light themes are a neutral page with a colored accent. Klein inverts that: the field is the identity. :root (light mode) sets --background to a deep saturated ultramarine — oklch(0.44 0.20 265), a commitment, not a tint — carrying near-white ink. Content lives on clean near-white card panels that float on the blue with deep blue-black shadows (a drenched field casts blue shadow, never gray). By construction the brand blue carries 3060% of every screen.

One counterpoint does all the pointing: a warm amber-orange (oklch(0.72 0.17 60)) with dark ink on top — the primary action, focus ring, selection, link underlines, and the user chat bubble. Everything else stays inside the blue family: secondary/muted are deeper stripes of the same hue, the sidebar is a deeper band of ultramarine.

Dark mode is ultramarine at midnight: the field deepens to oklch(0.30 0.13 265), cards become deep blue panels stepping lighter off the field (bg 0.30 → card 0.36 → popover 0.385 → muted 0.40), ink stays near-white. The theme is unmistakably blue in both modes.

Border note: --border is a dark ink hairline because borders are drawn where hairlines live — on the white cards and inputs. Hairlines on the blue field itself are white-alpha and carried by --sidebar-border.

Fonts

Consuming apps load the fonts at the very top of their entry CSS (per the Crema token contract, themes never @import fonts):

@import url("https://fonts.googleapis.com/css2?family=Syne:wght@600;700;800&family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap");
  • Syne (600/700/800) — headings. The art-poster voice; the base heading rule uses 700, with 800 available for hero moments. Syne runs wide, so headings carry -0.015em tracking.
  • Inter (400/500/600/700) — body/UI. Legible, modern, stays out of the poster's way. Body register: 1rem / 1.6.
  • JetBrains Mono (400/500/600) — code, kbd, code blocks.

Register

Consumer: body 1rem/1.6, label 0.875rem, caption 0.75rem, subtitle 1.125rem, title 1.375rem, headline 1.75rem, display 2.5rem, hero 3.25rem. Radius is a generous 1rem. Motion is confident (150/300/450/600ms) with real gentle springs (--ease-spring-* are true overshoot curves, not aliases).

Validation

node create-crema-app/scripts/validate-theme.mjs lib-theme-klein/theme.css
# ✓ PASS — all mandatory tokens present, contrast floors met, no ban violations.
Description
Crema theme — klein (bold set, 2026-07). BROKEN REFERENCE: fails muted-vs-card validation; do not consume without redesign.
Readme 35 KiB
Languages
CSS 100%