# 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.

> For the complete documentation index, see [llms.txt](/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](/.well-known/agent-skills/site-skill.md).





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 [#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.

<ComponentPreview name="design/color-and-surface/surface-levels">
  <SurfaceLevelsDemo />
</ComponentPreview>

### The 3-Tier Surface Scale [#the-3-tier-surface-scale]

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

| Elevation Level      | Semantic Token                 | Intended Usage                           |
| :------------------- | :----------------------------- | :--------------------------------------- |
| **Page Base**        | `bg-background`                | The root page canvas                     |
| **In-place Surface** | `bg-card` with `border-border` | Cards, tables, sidebars, content modules |
| **Floating Surface** | `bg-popover` with shadow       | Dropdowns, menus, tooltips, dialogs      |

***

## 2. Action Hierarchy and Visual Salience [#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`.

<ComponentPreview name="design/color-and-surface/emphasis">
  <EmphasisDemo />
</ComponentPreview>

> **💡 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 [#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.

<ComponentPreview name="design/color-and-surface/color-proportion">
  <ColorProportionDemo />
</ComponentPreview>

### The 60-30-10 Allocation Table [#the-60-30-10-allocation-table]

| Visual Role              | Target Area | Semantic Tokens                                      | Interface Responsibility                             |
| :----------------------- | :---------- | :--------------------------------------------------- | :--------------------------------------------------- |
| **Dominant Base**        | \~60%       | `bg-card`, `bg-background`                           | Negative space, reading canvas, visual calm          |
| **Structural Secondary** | \~30%       | `border-border`, `text-muted-foreground`, `bg-muted` | Container boundaries, metadata labels, divider rules |
| **Targeted Accent**      | \~10%       | `bg-primary`, `text-primary-foreground`              | Primary CTA button, interactive focal point          |

***

## Rules and Boundaries [#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.
