style(web): unify design system across default frontend

🔤 Typography
- Fix --font-sans stack: 'Public Sans Variable' was never applied (wrong family name), add CJK fallbacks (PingFang SC / Microsoft YaHei UI / Noto Sans SC)
- Sync <html lang> with i18n language for correct CJK glyph selection
- Remove dead fake font system (font-provider.tsx, config/fonts.ts, --font-inter/--font-manrope)
- Typography contract: 3-tier headings, arbitrary text-[10px]/[11px] → text-xs (46 files), no uppercase table headers, font-bold → font-semibold
- Numbers use tabular-nums only; font-mono reserved for keys/IDs/code (29 files)

🎨 Color discipline
- Retire StatusBadge string-hash rainbow (autoColor → neutral); all variants resolve to 5 semantic voices
- Add tintedBadgeClassMap as the single tinted-pill recipe
- Replace hardcoded emerald/amber/rose/sky classes with semantic tokens across ~30 files (timing badges, progress bars, system panels, pricing, rankings, log row tints)
- Drop all !important text overrides and [font-family:var(--font-body)] hacks

🧘 Motion restraint
- Remove admin entrance animations: table row stagger, card hover lift/shadow, button press scale, dashboard shimmer line
- Neuter page-transition stagger components into plain wrappers; page transitions reduced to pure opacity fade
- Decorative motion stays landing-only

📐 Shape
- Single radius source: --radius 1rem → 0.625rem
- Sparklines use solid chart tokens instead of decorative gradients
- PanelWrapper: border-only (no shadow), align radius with Card

📏 Guardrails
- Add "Design System Discipline" section (3.10.1) to web/default/AGENTS.md

 Verified: tsgo typecheck clean, rsbuild production build passes
This commit is contained in:
t0ng7u
2026-07-11 02:02:11 +08:00
parent 0cb741d8da
commit 262ab93123
97 changed files with 561 additions and 863 deletions
@@ -74,14 +74,13 @@ const INSTANCE_SKELETON_KEYS = [
]
const STATUS_CLASS_NAME: Record<SystemInstanceStatus, string> = {
online:
'bg-emerald-50 text-emerald-700 dark:bg-emerald-500/15 dark:text-emerald-300',
stale: 'bg-amber-50 text-amber-700 dark:bg-amber-500/15 dark:text-amber-300',
online: 'bg-success/10 text-success',
stale: 'bg-warning/10 text-warning',
}
const STATUS_DOT_CLASS_NAME: Record<SystemInstanceStatus, string> = {
online: 'bg-emerald-500',
stale: 'bg-amber-500',
online: 'bg-success',
stale: 'bg-warning',
}
function roleLabel(instance: SystemInstance) {
@@ -136,9 +135,9 @@ function formatBytes(bytes?: number): string {
function ringColorClass(percent: number | null) {
if (percent === null) return 'text-muted-foreground/40'
if (percent >= 90) return 'text-red-500'
if (percent >= 70) return 'text-amber-500'
return 'text-emerald-500'
if (percent >= 90) return 'text-destructive'
if (percent >= 70) return 'text-warning'
return 'text-success'
}
type RingProgressProps = {
@@ -205,9 +204,7 @@ function ResourceCell(props: ResourceCellProps) {
const content = (
<div className='flex items-center gap-2'>
<RingProgress percent={percent} />
<span className='font-mono text-[11px] tabular-nums'>
{formatPercent(props.value)}
</span>
<span className='text-xs tabular-nums'>{formatPercent(props.value)}</span>
</div>
)
@@ -304,7 +301,7 @@ function SystemInstancesList(props: SystemInstancesTableProps) {
>
<Badge
variant='outline'
className='border-amber-200 bg-amber-50 text-amber-700 dark:border-amber-500/30 dark:bg-amber-500/15 dark:text-amber-300'
className='border-warning/30 bg-warning/10 text-warning'
>
<AlertTriangle
className='size-3'
@@ -328,7 +325,7 @@ function SystemInstancesList(props: SystemInstancesTableProps) {
<div className='mb-1 font-medium'>
{t('Example')}
</div>
<code className='bg-muted block rounded-md px-2 py-1.5 font-mono text-[11px] break-all'>
<code className='bg-muted block rounded-md px-2 py-1.5 font-mono text-xs break-all'>
NODE_NAME=new-api-master-1
</code>
</div>
@@ -342,7 +339,7 @@ function SystemInstancesList(props: SystemInstancesTableProps) {
</Popover>
)}
</div>
<div className='text-muted-foreground truncate font-mono text-[11px]'>
<div className='text-muted-foreground truncate font-mono text-xs'>
{instance.info?.host?.hostname || '-'}
</div>
</div>
@@ -53,26 +53,23 @@ const STATUS_VARIANT: Record<SystemTaskStatus, 'secondary' | 'destructive'> = {
}
const STATUS_CLASS_NAME: Record<SystemTaskStatus, string> = {
pending:
'bg-amber-50 text-amber-700 dark:bg-amber-500/15 dark:text-amber-300',
running:
'bg-sky-50 text-sky-700 dark:bg-sky-500/15 dark:text-sky-300 [&_span]:bg-sky-500',
succeeded:
'bg-emerald-50 text-emerald-700 dark:bg-emerald-500/15 dark:text-emerald-300',
pending: 'bg-warning/10 text-warning',
running: 'bg-info/10 text-info [&_span]:bg-info',
succeeded: 'bg-success/10 text-success',
failed: '',
}
const STATUS_DOT_CLASS_NAME: Record<SystemTaskStatus, string> = {
pending: 'bg-amber-500',
running: 'bg-sky-500',
succeeded: 'bg-emerald-500',
pending: 'bg-warning',
running: 'bg-info',
succeeded: 'bg-success',
failed: 'bg-destructive',
}
const PROGRESS_BAR_CLASS_NAME: Record<SystemTaskStatus, string> = {
pending: '[&_[data-slot=progress-indicator]]:bg-amber-500',
running: '[&_[data-slot=progress-indicator]]:bg-sky-500',
succeeded: '[&_[data-slot=progress-indicator]]:bg-emerald-500',
pending: '[&_[data-slot=progress-indicator]]:bg-warning',
running: '[&_[data-slot=progress-indicator]]:bg-info',
succeeded: '[&_[data-slot=progress-indicator]]:bg-success',
failed: '[&_[data-slot=progress-indicator]]:bg-destructive',
}
@@ -142,7 +139,7 @@ function SystemTasksTable(props: SystemTasksTableProps) {
<div className='font-medium'>
{t(TYPE_LABEL[task.type] ?? task.type)}
</div>
<div className='text-muted-foreground font-mono text-[11px]'>
<div className='text-muted-foreground font-mono text-xs'>
{TYPE_DISPLAY_ID[task.type] ?? task.type}
</div>
</div>
@@ -256,7 +253,7 @@ export function SystemTasksPanel() {
<span
className={cn(
'size-1.5 rounded-full',
hasActiveTasks ? 'bg-emerald-500' : 'bg-muted-foreground/40'
hasActiveTasks ? 'bg-success' : 'bg-muted-foreground/40'
)}
aria-hidden='true'
/>