Updated DESIGN.md to reflect a new editorial design approach with a navy palette and refined typography. Enhanced global styles in globals.css, including new color tokens and layout adjustments. Refactored components in AppShell, Sidebar, and Topbar for improved consistency and theming. Introduced a ThemeToggle component for user theme preferences and updated various pages to utilize new styles and components, ensuring a cohesive user experience across the application.
18 KiB
#070b16) holding off-white ink (#f1f5ff); the light canvas is a cool off-white (#f3f5fb) holding deep-navy ink (#0c1426). Brand voltage is photographic, not chromatic — soft pastel atmospheric gradient orbs (mint → peach → lavender → sky → rose) drift behind hero copy as the only "color" moments. Display runs Cormorant Garamond Light at weight 300 — the editorial signature; Inter carries body, navigation, captions. CTAs are subtle pills: a deep-navy ink pill in light, inverting to an off-white pill in dark. There is no neon accent and no saturated CTA color.
colors:
primary: "#1b2741"
primary-active: "#0c1426"
ink: "#0c1426"
body: "#44516c"
body-strong: "#1b2741"
muted: "#5d6b86"
muted-soft: "#94a0bd"
hairline: "#e3e7f1"
hairline-soft: "#eef1f8"
hairline-strong: "#cbd3e4"
canvas: "#f3f5fb"
canvas-soft: "#f9fafd"
surface-card: "#ffffff"
surface-strong: "#e9edf7"
on-primary: "#ffffff"
gradient-mint: "#a7e5d3"
gradient-peach: "#f4c5a8"
gradient-lavender: "#c8b8e0"
gradient-sky: "#a8c8e8"
gradient-rose: "#e8b8c4"
semantic-error: "#dc2626"
semantic-success: "#16a34a"
colors-dark:
primary: "#e8edf9"
primary-foreground: "#0c1426"
ink: "#f1f5ff"
foreground: "#e8edf9"
body: "#a6b2cb"
muted: "#93a0bb"
muted-soft: "#6c7a96"
hairline: "#1b2740"
hairline-soft: "#141d30"
hairline-strong: "#283450"
canvas: "#070b16"
canvas-soft: "#0b1322"
surface-card: "#0e1626"
surface-strong: "#18233a"
gradient-mint: "#5fae9b"
gradient-peach: "#c08a6b"
gradient-lavender: "#8a78ad"
gradient-sky: "#5f86b8"
gradient-rose: "#b07d8c"
semantic-error: "#f87171"
semantic-success: "#4ade80"
typography:
display-mega:
fontFamily: "'Cormorant Garamond', 'Times New Roman', serif"
fontSize: clamp(2.5rem, 5vw, 4rem)
fontWeight: 300
lineHeight: 1.05
letterSpacing: -0.03em
display-xl:
fontFamily: "'Cormorant Garamond', serif"
fontSize: clamp(2rem, 4vw, 3rem)
fontWeight: 300
lineHeight: 1.08
letterSpacing: -0.02em
display-lg:
fontFamily: "'Cormorant Garamond', serif"
fontSize: 36px
fontWeight: 300
lineHeight: 1.17
letterSpacing: -0.01em
display-md:
fontFamily: "'Cormorant Garamond', serif"
fontSize: 32px
fontWeight: 300
lineHeight: 1.13
letterSpacing: -0.01em
display-sm:
fontFamily: "'Cormorant Garamond', serif"
fontSize: 24px
fontWeight: 300
lineHeight: 1.2
letterSpacing: 0
title-md:
fontFamily: "'Inter', sans-serif"
fontSize: 20px
fontWeight: 500
lineHeight: 1.35
letterSpacing: 0
title-sm:
fontFamily: "'Inter', sans-serif"
fontSize: 18px
fontWeight: 500
lineHeight: 1.44
letterSpacing: 0
body-md:
fontFamily: "'Inter', sans-serif"
fontSize: 16px
fontWeight: 400
lineHeight: 1.5
letterSpacing: 0.01em
body-strong:
fontFamily: "'Inter', sans-serif"
fontSize: 16px
fontWeight: 500
lineHeight: 1.5
letterSpacing: 0.01em
body-sm:
fontFamily: "'Inter', sans-serif"
fontSize: 15px
fontWeight: 400
lineHeight: 1.47
letterSpacing: 0.01em
caption:
fontFamily: "'Inter', sans-serif"
fontSize: 14px
fontWeight: 400
lineHeight: 1.5
letterSpacing: 0
caption-label:
fontFamily: "'Inter', sans-serif"
fontSize: 12px
fontWeight: 600
lineHeight: 1.4
letterSpacing: 0.08em
textTransform: uppercase
button:
fontFamily: "'Inter', sans-serif"
fontSize: 14px
fontWeight: 500
lineHeight: 1.0
letterSpacing: 0
nav-link:
fontFamily: "'Inter', sans-serif"
fontSize: 14px
fontWeight: 400
lineHeight: 1.4
letterSpacing: 0
rounded:
none: 0px
sm: "calc(0.75rem * 0.6)" # ~7px
md: "calc(0.75rem * 0.8)" # ~10px
lg: 0.75rem # 12px (--radius)
xl: "calc(0.75rem * 1.4)" # ~17px
2xl: "calc(0.75rem * 1.8)" # ~22px
3xl: "calc(0.75rem * 2.2)" # ~26px
pill: 9999px
full: 9999px
spacing:
xxs: 4px
xs: 8px
sm: 12px
base: 16px
md: 20px
lg: 24px
xl: 32px
xxl: 48px
section: 96px
components:
app-shell:
backgroundColor: "{colors.canvas}"
textColor: "{colors.ink}"
typography: "{typography.body-md}"
sidebar:
backgroundColor: "{colors.surface-card}"
textColor: "{colors.body}"
borderColor: "{colors.hairline}"
width: 252px
width-collapsed: 76px
topbar:
backgroundColor: "{colors.canvas}"
textColor: "{colors.ink}"
borderColor: "{colors.hairline}"
height: 81px
button-primary:
backgroundColor: "{colors.primary}"
textColor: "{colors.on-primary}"
typography: "{typography.button}"
rounded: "{rounded.pill}"
height: 40px
button-outline:
backgroundColor: transparent
textColor: "{colors.ink}"
typography: "{typography.button}"
rounded: "{rounded.pill}"
borderColor: "{colors.hairline-strong}"
height: 40px
nav-item:
backgroundColor: transparent
textColor: "{colors.muted}"
typography: "{typography.nav-link}"
rounded: "{rounded.pill}"
height: 44px
nav-item-active:
backgroundColor: "{colors.surface-strong}"
textColor: "{colors.ink}"
hero-band:
backgroundColor: "{colors.canvas-soft}"
textColor: "{colors.ink}"
typography: "{typography.display-xl}"
rounded: "{rounded.3xl}"
borderColor: "{colors.hairline}"
padding: 64px
feature-card:
backgroundColor: "{colors.surface-card}"
textColor: "{colors.ink}"
typography: "{typography.title-sm}"
rounded: "{rounded.2xl}"
borderColor: "{colors.hairline}"
padding: 24px
section-card:
backgroundColor: "{colors.surface-card}"
textColor: "{colors.ink}"
rounded: "{rounded.2xl}"
borderColor: "{colors.hairline}"
padding: 24px
icon-plate:
backgroundColor: "{colors.surface-strong}"
textColor: "{colors.ink}"
rounded: "{rounded.full}"
size: 40px
text-input:
backgroundColor: "{colors.canvas}"
textColor: "{colors.ink}"
typography: "{typography.body-md}"
rounded: "{rounded.md}"
borderColor: "{colors.hairline-strong}"
badge-pill:
backgroundColor: "{colors.surface-strong}"
textColor: "{colors.muted}"
typography: "{typography.caption-label}"
rounded: "{rounded.pill}"
padding: 4px 12px
brand-icon:
backgroundColor: "{colors.primary} + sky/lavender gradient orb overlay"
textColor: "{colors.on-primary}"
rounded: "{rounded.xl}"
size: 44px
avatar:
backgroundColor: "{colors.primary} + sky gradient orb overlay"
textColor: "{colors.on-primary}"
rounded: "{rounded.full}"
size: 32px
gradient-orb:
background: "radial-gradient with one of {colors.gradient-*}"
blur: 48-64px
opacity: 0.45-0.6
Overview
AI 视频助手管理台 reads like a quietly editorial print magazine that happens to be an admin console. It ships in two themes built from one navy palette:
- Dark navy (default): deep-navy canvas
{colors-dark.canvas}(#070b16) holding off-white ink{colors-dark.ink}(#f1f5ff). - Light navy: cool off-white canvas
{colors.canvas}(#f3f5fb) holding deep-navy ink{colors.ink}(#0c1426).
The brand voltage is photographic, not chromatic: soft pastel atmospheric gradient orbs (mint, peach, lavender, sky, rose) drift behind hero/feature panels as the only "color" moments. There is no neon accent, no saturated CTA color, and no cyan/blue dev-console gradient anymore.
Type pairs Cormorant Garamond Light (display serif at weight 300 — the open-source substitute for Waldenburg) with Inter for body, navigation, captions, and buttons. The display weight at 300 is the editorial signature — never bold. Latin display runs in the serif; CJK display falls back to the system serif/sans at weight 300 (still light/editorial).
CTAs are subtle pills: in light mode the primary is a deep-navy ink pill ({component.button-primary}); in dark mode it inverts to an off-white pill ({colors-dark.primary} → off-white, text {colors-dark.primary-foreground}). The secondary is a transparent hairline-outline pill.
Key Characteristics:
- One navy palette, two themes; dark is the default, persisted to
localStoragewith a no-flash bootstrap script inlayout.tsx. - Off-white / deep-navy ink. No saturated CTA color — ink pill only.
- Display runs Cormorant Garamond Light at weight 300 — editorial voice.
- Body runs Inter at 400/500 with subtle +0.01em tracking.
- Pastel gradient orbs (5 tokens) used as atmospheric decoration only.
- Pill geometry (
{rounded.pill}) for every CTA, nav item, and badge;{rounded.2xl}for cards,{rounded.3xl}for hero bands. - Hairline borders + a single soft shadow tier — no layered-surface dev-console stack.
- 96px section rhythm; ~40px page padding; 1180px max content width.
Colors
The two colors / colors-dark blocks above are the source of truth and are wired into globals.css as the shadcn variables (--background, --foreground, --card, --primary, --border, --muted-foreground, …) plus editorial extras (--ink, --body-text, --surface-strong, --hairline*, --canvas-soft, --gradient-*). Tailwind utilities like bg-background, text-ink, border-hairline, bg-surface-strong, and text-muted-foreground resolve to the active theme automatically.
Primary (CTA)
- Light
{colors.primary}(#1b2741): deep-navy ink pill, white text. Press →{colors.primary-active}(#0c1426). - Dark
{colors-dark.primary}(#e8edf9): off-white pill, deep-navy text (#0c1426). The editorial inversion — used scarcely.
Surfaces
- Canvas — page floor. Light #f3f5fb / Dark #070b16.
- Canvas Soft — hero/placeholder bands. Light #f9fafd / Dark #0b1322.
- Surface Card — content cards, popovers. Light #ffffff / Dark #0e1626.
- Surface Strong — icon plates, badges, active nav. Light #e9edf7 / Dark #18233a.
Hairlines
- Hairline — default 1px divider/card outline. Light #e3e7f1 / Dark #1b2740.
- Hairline Soft — lighter divider. Light #eef1f8 / Dark #141d30.
- Hairline Strong — input/outline-button border. Light #cbd3e4 / Dark #283450.
Text
- Ink — display & primary text. Light #0c1426 / Dark #f1f5ff.
- Body — running copy. Light #44516c / Dark #a6b2cb.
- Muted — descriptions, sub-labels. Light #5d6b86 / Dark #93a0bb.
- Muted Soft — captions, placeholders. Light #94a0bd / Dark #6c7a96.
Atmospheric Gradient Orbs (signature)
Five pastel stops — gradient-mint, gradient-peach, gradient-lavender, gradient-sky, gradient-rose. In dark mode they shift to lower-chroma navy-compatible variants (e.g. sky #a8c8e8 → #5f86b8). They appear ONLY as soft, blurred radial blooms behind hero/feature/placeholder copy and as the orb overlay on the brand icon/avatar. Never as button fills, text colors, or flat card surfaces.
Semantic
- Success — Light #16a34a / Dark #4ade80.
- Error — Light #dc2626 / Dark #f87171.
Typography
Font Family
Cormorant Garamond is the display serif (--font-display, weight 300) — the open-source substitute for the licensed Waldenburg Light. Inter carries body, navigation, captions, and buttons (--font-sans). Geist Mono is loaded for monospace. Helper classes in globals.css: .font-display, .display-mega/-xl/-lg/-md/-sm, .caption-label.
Hierarchy
| Token | Size | Weight | Tracking | Use |
|---|---|---|---|---|
{typography.display-mega} |
clamp 40–64px | 300 | -0.03em | Marketing-scale hero |
{typography.display-xl} |
clamp 32–48px | 300 | -0.02em | Homepage hero h1 |
{typography.display-lg} |
36px | 300 | -0.01em | Page titles |
{typography.display-md} |
32px | 300 | -0.01em | Section heads |
{typography.display-sm} |
24px | 300 | 0 | Card group titles |
{typography.title-md} |
20px | 500 | 0 | Component titles (Inter) |
{typography.title-sm} |
18px | 500 | 0 | List labels |
{typography.body-md} |
16px | 400 | +0.01em | Default body |
{typography.body-strong} |
16px | 500 | +0.01em | Emphasized body |
{typography.body-sm} |
15px | 400 | +0.01em | Compact body |
{typography.caption-label} |
12px | 600 | +0.08em, UPPER | Section labels, badges |
{typography.button} |
14px | 500 | 0 | CTA pill |
{typography.nav-link} |
14px | 400 | 0 | Sidebar nav |
Principles
- Display weight stays at 300. Cormorant Garamond Light is the editorial signature. Never bold display copy.
- Subtle tracking on body. Inter at +0.01em (applied globally on
body). - Negative tracking on display. Tighter as size grows (-0.01em → -0.03em).
- Caption labels are the editorial section marker — uppercase, 600, +0.08em.
Layout
Spacing & Container
- Base unit 4px; section rhythm 96px (
{spacing.section}). - Page padding:
px-8 py-10. Max content width 1180px. - Sidebar: 252px expanded, 76px collapsed.
Whitespace Philosophy
Generous editorial pacing. Hero bands get large internal padding (64px) with a gradient orb in a corner; content cards sit 16–24px apart.
Elevation & Depth
The system uses hairline + soft drop. Cards float above the canvas via a 1px hairline and a single subtle shadow tier (shadow-sm, deepening to shadow-md on hover). Atmospheric depth comes from the gradient orbs, not from layered surface steps.
| Level | Treatment | Use |
|---|---|---|
| Canvas | {colors.canvas} |
App background, topbar |
| Card | {colors.surface-card} |
Content cards, popovers |
| Hairline border | 1px {colors.hairline} |
Card/input outlines |
| Soft drop | shadow-sm → shadow-md on hover |
Card elevation |
| Gradient orb | blurred radial bloom, opacity 0.45–0.6 | Atmospheric depth only |
Shapes
Border Radius Scale (--radius: 0.75rem = 12px)
| Token | Approx | Use |
|---|---|---|
{rounded.md} |
~10px | Form inputs |
{rounded.lg} |
12px | Compact elements |
{rounded.xl} |
~17px | Brand icon |
{rounded.2xl} |
~22px | Feature/section cards |
{rounded.3xl} |
~26px | Hero/placeholder bands |
{rounded.pill} |
9999px | All buttons, nav items, badges |
{rounded.full} |
9999px | Avatars, icon plates |
Components
App Shell
app-shell — bg-background text-foreground. Flex row: sidebar left, main column right (topbar + scrollable content at px-8 py-10).
Sidebar
sidebar — bg-sidebar, border-right {colors.hairline}, width 252/76px. Brand block: gradient-orb brand icon + serif wordmark + uppercase 管理台 caption-label. Nav items are pill-shaped (44px); active uses bg-sidebar-accent with foreground text.
Top Bar
topbar — bg-background, border-bottom hairline, height 81px. Right-aligned: Help outline pill, theme toggle (sun/moon), notification bell, user avatar pill — all hairline-outline style.
Buttons (pills)
button-primary — ink pill (light) / off-white pill (dark), {rounded.pill}, height 40px (size="lg").
button-outline — transparent pill, 1px {colors.hairline-strong} border, text ink; hover bg-surface-strong.
Hero & Atmospheric
hero-band — bg-canvas-soft, {rounded.3xl}, hairline border, 64px padding, with 1–2 blurred gradient orbs (sky + lavender) behind editorial display copy, a caption-label eyebrow, and two CTAs.
gradient-orb — blurred radial bloom in one of the five pastel tokens; pure atmosphere, holds no content.
Cards
feature-card / section-card — bg-card, {rounded.2xl}, hairline border, shadow-sm. Icon plate is a 40px {colors.surface-strong} circle with neutral foreground icon (no colored accent).
Forms & Tags
text-input — bg-background, text ink, 1px {colors.hairline-strong} border, {rounded.md}; focus thickens border to ring.
badge-pill — bg-surface-strong, caption-label text, {rounded.pill}.
Brand Elements
brand-icon / avatar — {colors.primary} base with a sky/lavender gradient-orb overlay, {rounded.xl} (icon) / {rounded.full} (avatar). The pastel orb replaces the old cyan→blue gradient.
Theming
- Two themes from one palette:
.darktoggles the variable set inglobals.css. Dark is the default<html className="dark">. - A
ThemeToggle(sun/moon) in the topbar flipsdocumentElement.classListand writeslocalStorage.theme. - A no-flash inline script in
layout.tsxapplies the stored theme before paint (defaults to dark).
Do's and Don'ts
Do
- Reserve
{colors.primary}(ink/off-white pill) for primary CTAs. - Use Cormorant Garamond Light at weight 300 for every display headline. Never bold.
- Use Inter at +0.01em tracking for body.
- Use atmospheric gradient orbs (mint/peach/lavender/sky/rose) as decoration only.
- Use the pill shape for every CTA, nav item, and badge.
- Drive color from semantic tokens (
bg-card,text-ink,border-hairline) so both themes work — never inline hex.
Don't
- Don't reintroduce the cyan/blue dev-console accent or layered-navy surface stack.
- Don't bold display copy — it sits at weight 300.
- Don't use gradient orbs as button fills, text colors, or flat card backgrounds.
- Don't use sharp 0px or
{rounded.xl}corners on CTAs — pill geometry is the brand button. - Don't drop body Inter to weight 300 to match the serif — body stays at 400/500.
Responsive Behavior
| Name | Width | Key Changes |
|---|---|---|
| Mobile | < 640px | Feature grid 1-up; sidebar collapsed; user name hidden; display sizes shrink via clamp |
| Tablet | 640–1024px | Feature grid 2-up |
| Desktop | 1024–1280px | Feature grid 3-up; full sidebar |
| Wide | > 1280px | Content caps at 1180px |
Touch Targets
- Nav items 44px; primary buttons 40px (
size="lg"). - Sidebar collapses to 76px icon-only via toggle.
Known Gaps
- Cormorant Garamond covers Latin only; CJK display headings fall back to the system serif/sans at weight 300. A bundled light CJK serif (e.g. a Noto Serif SC weight) is not yet wired in.
- Several inner pages (Components, History, Test, Workflow, Profile) currently use the shared
PlaceholderPageeditorial header and await real content. - Animation timings (orb drift, hero entrance, theme cross-fade) out of scope.
- Form validation states beyond focus not yet documented.