Theme System
Full shadcn/ui theme compliance — 17 CSS variables, pair pattern, class-based dark mode.
Typography
Three fonts loaded via next/font/google. Chinese text automatically uses Noto Serif SC as a fallback.
The quick brown fox jumps over the lazy dog. 0123456789
你好世界,这是一段中文内容。思源宋体
The quick brown fox jumps over the lazy dog.
你好世界,中文字体回退
const font = "Noto Serif SC"; // 代码块
Overview
This site uses shadcn/ui's theme pattern — the most popular design system for Next.js. Colors are defined as raw HSL triplets in CSS variables, mapped to Tailwind utilities. Theme = a class that sets variable values.
Every color has a partner. --card is the background. --card-foreground is the text on that background. Variables hold the actual rendered color — no opacity modifiers needed in components.
The Pair Pattern
shadcn/ui uses a naming convention: --{name} for background, --{name}-foreground for text on that background.
--background is the deepest layer — the page itself. --foreground is the color of all text by default.
Text must be readable on the page. White text on dark background = high contrast. This pair never changes because readability is non-negotiable.
bg-backgroundtext-foregroundThis text uses text-foreground on bg-background.
--card is the actual rendered surface color per theme — solid white in light mode, subtle dark in dark mode. Just use bg-card. The variable handles the rest. --card-foreground is the text on cards.
Variables define the actual color, not a base to apply opacity to. This means components never need dark: prefixes — the variable changes when the theme class changes.
bg-cardtext-card-foregroundbg-card — adapts automatically per theme
--popover is the background for floating elements. Currently matches --card. --popover-foreground is text on popovers.
Floating elements may need a different background than cards (e.g., darker in dark mode for more contrast). Separate variable allows this without affecting cards.
bg-popovertext-popover-foreground--primary is the main interactive color — buttons, toggles, active indicators. --primary-foreground is text on primary surfaces.
primary is for interactive elements.accent is for decorative highlights. This semantic split means a future theme could use different colors for each.
bg-primarytext-primary-foregroundPrimary button
Primary at 10%
--secondary is a muted surface color for secondary actions. Less prominent than primary. --secondary-foreground is text on secondary surfaces.
Not every button should be primary. Secondary provides a toned-down alternative for less important actions (Cancel, Skip, etc.).
bg-secondarytext-secondary-foreground--accent is for decorative highlights — code syntax, category pills, subtle emphasis. Not for interactive elements. --accent-foreground is text on accent surfaces.
Separating accent from primary means decorative colors can change independently of interactive colors. A theme could use rose for accent but blue for primary.
bg-accentbg-accent/10text-accent-foreground--ring is the color for focus rings and active state indicators. Set to foreground color for maximum visibility.
Focus rings must be visible on any background. Using the foreground color ensures contrast. ring-accent is for decorative rings, ring is for accessibility.
ringring-2 ringfocus-visible:ring-2 focus-visible:ring--muted is stone-800 — slightly lighter than the page background. --muted-foreground is gray — dimmer than default text.
Not everything should be equally prominent. Muted creates visual hierarchy — secondary info (dates, labels, code blocks) recedes while primary content stands out.
bg-mutedtext-muted-foregroundThis is muted-foreground on muted background — secondary info.
--destructive is red — universally understood as danger. --destructive-foreground is near-white — text on red.
Red = danger is a universal convention. Changing it per theme would confuse users. If the theme is blue, destructive actions should still be red — not blue.
bg-destructivetext-destructive-foreground--border and --input define the color for borders and form controls. Use border-border or border-input.
Borders should be barely visible — they create structure without drawing attention. White at 10% opacity is subtle but visible on dark backgrounds.
border-border/10border-input/10Fixed vs Theme Variables
Fixed variables are always neutral. Theme variables change per theme — they carry the site's identity.
These form the foundation. Always neutral so text is always readable.
These define the site's color identity. Change --accent and --primary to swap the entire feel.
--primary: 356 89% 60%; /* rose */Usage Guide
Each variable has a clear role. Use the right one for the right context.
bg-primary + text-primary-foreground for main actions.bg-secondary + text-secondary-foreground for less prominent actions.ring for keyboard focus indicators. Uses --ring (foreground-based) for maximum visibility.bg-accent for decorative highlights — code syntax, category pills, subtle emphasis. Not for interactive elements.bg-destructive + text-destructive-foreground. Red = danger is universal — never changes per theme.Color Palette
Button Examples
Theme Colors
The site uses Terracotta (light) and Rose (dark) as the primary/accent colors. Change --primary and --accent in globals.css to swap the entire feel.
Quick Reference
| Variable | Tailwind | Use for | Changes? |
|---|---|---|---|
--background | bg-background | Page canvas | Theme |
--foreground | text-foreground | Default text | Theme |
--card | bg-card | Card surfaces | Theme |
--card-foreground | text-card-foreground | Text on cards | Theme |
--popover | bg-popover | Floating surfaces | Theme |
--popover-foreground | text-popover-foreground | Text on popovers | Theme |
--primary | bg-primary | Buttons, interactive | Theme |
--primary-foreground | text-primary-foreground | Text on primary | Theme |
--secondary | bg-secondary | Secondary actions | Theme |
--secondary-foreground | text-secondary-foreground | Text on secondary | Theme |
--muted | bg-muted | Subtle backgrounds | Theme |
--muted-foreground | text-muted-foreground | Secondary text | Theme |
--accent | bg-accent | Decorative highlights | Theme |
--accent-foreground | text-accent-foreground | Text on accent | Theme |
--destructive | bg-destructive | Errors, danger | Fixed |
--destructive-foreground | text-destructive-foreground | Text on errors | Fixed |
--border | border-border | Borders | Theme |
--input | border-input | Form controls | Theme |
--ring | ring | Focus indicators | Theme |
--radius | rounded-lg | Border radius | Fixed |