Operator's Notebook design register — a dense BI/admin dashboard visual language built on OKLCH ink-blue tokens, hairline dividers, Bricolage Grotesque display, and 60/30/10 accent discipline. Use when designing or migrating admin dashboards, internal tools, BI consoles, or operator-facing surfaces that need editorial clarity over SaaS chrome. Triggers on tasks involving shadcn/ui dashboards, Next.js admin apps, Tailwind v4 token migration, or rewriting "default shadcn" SaaS-flavored UIs into a disciplined editorial register.
Operator's Notebook design register — a dense BI/admin dashboard visual language built on OKLCH ink-blue tokens, hairline dividers, Bricolage Grotesque display, and 60/30/10 accent discipline. Use when designing or migrating admin dashboards, internal tools, BI consoles, or operator-facing surfaces that need editorial clarity over SaaS chrome. Triggers on tasks involving shadcn/ui dashboards, Next.js admin apps, Tailwind v4 token migration, or rewriting "default shadcn" SaaS-flavored UIs into a disciplined editorial register.
Operator's Notebook
A complete design register for dense, glance-and-decide internal dashboards. Cool off-white canvas biased toward ink-blue, hairlines instead of card shadow, editorial display type, semantic-token-only color discipline. The visual opposite of "default shadcn SaaS."
Semantic mapping (the only text-*/bg-* color utilities allowed in app code)
Role
Token
Canvas
bg-background
Card / popover surface
bg-card (visually equal to background)
Primary ink
text-foreground
Faded ink (labels, captions)
text-muted-foreground
Active / confirmed / positive
text-primary, bg-primary/5, border-primary/40
Negative / destructive
text-destructive, bg-destructive/5
Hairline
border-border
Subtle fill
bg-muted, bg-accent/55
Nobg-emerald-*, bg-green-*, bg-amber-*, bg-blue-*, bg-purple-*, bg-sky-*, text-red-500 or any raw Tailwind color. Map every existing literal to a semantic token. The grep grep -rE "(bg|text)-(emerald|green|amber|sky|purple|red|blue|gray|slate|zinc|neutral)-[0-9]" should return zero hits in app code (UI primitives excepted only if they ship with the shadcn defaults you haven't yet touched).
Type stack
Role
Font
CSS variable
Notes
Body
Noto Sans SC / Noto Sans JP / Inter
--font-body
Match the user-facing language. Weights 400/500/600/700.
Order matters. Don't skip phases — token drift propagates fast.
Phase 1 — Foundation: rewrite globals.css to the OKLCH contract, delete .dark block + tw-animate-css + next-themes, wire three fonts via next/font/google, set lang correctly
Hairlines, not chrome. A border border-border carries more hierarchy in this register than any shadow.
One accent per screen. Primary tint is the 10% of the 60/30/10 — it marks the single most-watched metric, the active nav row, the confirmed CTA. If two things on screen claim "primary," the screen is wrong.
Semantic tokens, always. Never reach for bg-emerald-100. If you can't name the role (positive, destructive, muted, foreground), the color doesn't belong.
Density beats whitespace. A 5-cell metric strip + chart + table on one viewport is the goal, not a 3-card grid with breathing room.
Editorial type, not SaaS type. Bricolage Grotesque on display moments + Sometype Mono on every number creates the voice. The body font carries language; the display and mono do the lifting.
CSS for chrome motion, framer-motion for orchestration. Sidebar/header/nav are pure transitions. Modals and multi-step forms can still use framer-motion where genuine orchestration helps.
No dark mode unless explicitly required. The register is light-mode canonical. Adding dark tokens without testing every screen creates drift.