For the complete documentation index, see llms.txt. Markdown variants are available by appending .md to any URL or sending an Accept: text/markdown header. An agent skill is available at /.well-known/agent-skills/site-skill.md.
0
Sponsor

Color & Surface

Color communicates status and draws attention, while surfaces establish spatial depth. Learn how to maintain consistent visual hierarchy across both light and dark themes.

Color and surfaces have two distinct responsibilities in UI design:

  • Color communicates state, intent, and semantic meaning (such as destructive actions, success states, or active focus).
  • Surfaces establish spatial elevation and stacking order (where an element sits in the layout hierarchy).

A component should define its surface elevation based on its nesting context rather than relying on arbitrary fills that break when switching between light and dark themes.


1. Surface Levels across Themes

A component that draws its own surface on the page canvas must pick a true elevation level (bg-card with border-border), not a fill.

  • ❌ The Error: Borrowing bg-muted as a container surface. In light mode, muted (0.97) is darker than the page (1.0), so the card reads as recessed into the canvas. In dark mode, muted (0.269) is brighter than the page (0.145), making it float forward. A fill has no stable elevation across themes.
  • ✅ The Fix: Use bg-card with border-border. A card maintains consistent elevation in both light and dark modes without inverting perceived depth.
Wrongbg-muted fill
Usage
12,480 requests
Light Canvas
Usage
12,480 requests
Dark Canvas
Rightbg-card with border
Usage
12,480 requests
Light Canvas
Usage
12,480 requests
Dark Canvas
import { DesignCase } from "@/components/design-case";
import { cn } from "@/lib/utils";

The 3-Tier Surface Scale

Every container on screen should pick from three canonical surface levels:

Elevation LevelSemantic TokenIntended Usage
Page Basebg-backgroundThe root page canvas
In-place Surfacebg-card with border-borderCards, tables, sidebars, content modules
Floating Surfacebg-popover with shadowDropdowns, menus, tooltips, dialogs

2. Action Hierarchy and Visual Salience

A common temptation when styling action bars or modal footers is giving every button high-contrast visual weight.

  • ❌ The Error: Styling every action button with a primary solid fill (bg-primary). When every action shouts at equal volume, the user experiences decision paralysis and must read every single label to find the intended path.
  • ✅ The Fix: Strictly apply the Single Primary Action rule. Reserve bg-primary for the single most critical or forward-progressing step. Downgrade supporting actions to outline, ghost, or secondary.
WrongAll primary
PublishPreviewDuplicateArchive
RightSingle primary
PublishPreviewDuplicateArchive
import { DesignCase } from "@/components/design-case";

const ACTIONS = ["Publish", "Preview", "Duplicate", "Archive"];

💡 Accessibility Note: Never rely on color alone to convey state or danger. Always accompany color cues with descriptive text, icons, or standard ARIA roles so interfaces remain clear under grayscale, high-contrast, or forced-color modes.


3. Color Proportion: The 60-30-10 Rule

A common temptation when styling promotion or feature cards is painting large structural areas with the primary brand color to make the block feel "important".

  • ❌ The Error: Flooding the header with a solid primary banner (bg-primary). A decorative banner consumes ~40% of the card's surface. Because saturated color is the strongest visual attractor, the non-interactive header overpowers the actual CTA button below. When accent color is everywhere, it ceases to function as a focal cue.
  • ✅ The Fix: Strictly apply the 60-30-10 Rule (6-3-1 原则) to allocate visual real estate:
    • 60% Dominant Base: A clean, unified neutral canvas (bg-card) provides negative space and reading clarity.
    • 30% Structural Secondary: Content hierarchy is established purely through typography and subtle dividers (text-muted-foreground, border-border), keeping the body calm.
    • 10% Targeted Accent: The primary color is held strictly in reserve for the interactive CTA button (bg-primary), giving the user an instant, unmistakable focal anchor.
WrongAccent header banner
Autonomous Agents

Unlimited background tools and deep multi-step reasoning loops.

Compute budget100 hrs/mo
Right60-30-10 distribution
Autonomous Agents
Pro

Unlimited background tools and deep multi-step reasoning loops.

Compute budget100 hrs/mo
import { Sparkles } from "lucide-react";

import { DesignCase } from "@/components/design-case";

The 60-30-10 Allocation Table

Visual RoleTarget AreaSemantic TokensInterface Responsibility
Dominant Base~60%bg-card, bg-backgroundNegative space, reading canvas, visual calm
Structural Secondary~30%border-border, text-muted-foreground, bg-mutedContainer boundaries, metadata labels, divider rules
Targeted Accent~10%bg-primary, text-primary-foregroundPrimary CTA button, interactive focal point

Rules and Boundaries

  • Semantic Tokens Only: Always use semantic design tokens like bg-card, text-muted-foreground, and border-border. Avoid hardcoded palette values like bg-zinc-800 or #1c1c1c, which break theme customization and dark mode.
  • When Literal Colors Are Valid: Literal color values (e.g. rgba(0,0,0,0.5)) are only appropriate when measuring against user-uploaded content (like image scrims), SVG mask stops, or shadows over photography.