style(web): 全站 font-mono → font-body (DM Mono 設計系統套用)
Some checks failed
E2E Health Check / e2e-health (push) Successful in 17s
CD Pipeline / build-and-deploy (push) Has been cancelled

45 個 component + 6 個 page 統一從舊 font-mono 遷移到
font-body (DM Mono),確保設計系統一致性。

font-body = DM Mono (等寬),視覺效果相同但走新設計 token。
保留: font-heading (Syne)、font-dot-matrix (VT323/DSEG7)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
OG T
2026-04-02 09:37:03 +08:00
parent db1aed81d9
commit 4d46e6b9a7
52 changed files with 338 additions and 338 deletions

View File

@@ -145,7 +145,7 @@ export function ApprovalCard({
{/* Risk Badge */}
<div
className={cn(
'inline-flex items-center gap-2 px-3 py-1 rounded-full border text-xs font-mono tracking-wider mb-3',
'inline-flex items-center gap-2 px-3 py-1 rounded-full border text-xs font-body tracking-wider mb-3',
riskStyle.bgColor,
riskStyle.borderColor,
riskStyle.color
@@ -174,12 +174,12 @@ export function ApprovalCard({
{/* Signature Counter */}
<div className="text-right shrink-0">
<div className="font-mono text-xs text-nothing-gray-500 mb-1">
<div className="font-body text-xs text-nothing-gray-500 mb-1">
{t('signatures')}
</div>
<div
className={cn(
'font-mono text-lg',
'font-body text-lg',
needsMoreSignatures ? 'text-status-warning' : 'text-status-healthy'
)}
>
@@ -193,40 +193,40 @@ export function ApprovalCard({
{/* Blast Radius Section */}
<div className="space-y-3">
<h4 className="font-mono text-xs text-nothing-gray-500 tracking-wider">
<h4 className="font-body text-xs text-nothing-gray-500 tracking-wider">
{tBlast('title')}
</h4>
<div className="grid grid-cols-2 gap-3">
{/* Affected Pods */}
<div className="bg-nothing-gray-900 rounded-card p-3">
<div className="font-mono text-xs text-nothing-gray-500 mb-1">
<div className="font-body text-xs text-nothing-gray-500 mb-1">
{tBlast('affectedPods')}
</div>
<div className="font-mono text-lg text-nothing-white">
<div className="font-body text-lg text-nothing-white">
{request.blastRadius?.affectedPods ?? 0}
</div>
</div>
{/* Estimated Downtime */}
<div className="bg-nothing-gray-900 rounded-card p-3">
<div className="font-mono text-xs text-nothing-gray-500 mb-1">
<div className="font-body text-xs text-nothing-gray-500 mb-1">
{tBlast('estimatedDowntime')}
</div>
<div className="font-mono text-lg text-nothing-white">
<div className="font-body text-lg text-nothing-white">
{request.blastRadius?.estimatedDowntime ?? '0'}
</div>
</div>
{/* Related Services */}
<div className="bg-nothing-gray-900 rounded-card p-3">
<div className="font-mono text-xs text-nothing-gray-500 mb-1">
<div className="font-body text-xs text-nothing-gray-500 mb-1">
{tBlast('relatedServices')}
</div>
<div className="flex flex-wrap gap-1 mt-1">
{(request.blastRadius?.relatedServices ?? []).map((service) => (
<span
key={service}
className="px-2 py-0.5 bg-nothing-gray-800 rounded text-xs font-mono text-nothing-gray-300"
className="px-2 py-0.5 bg-nothing-gray-800 rounded text-xs font-body text-nothing-gray-300"
>
{service}
</span>
@@ -236,10 +236,10 @@ export function ApprovalCard({
{/* Data Impact */}
<div className="bg-nothing-gray-900 rounded-card p-3">
<div className="font-mono text-xs text-nothing-gray-500 mb-1">
<div className="font-body text-xs text-nothing-gray-500 mb-1">
{tBlast('dataImpact')}
</div>
<div className={cn('font-mono text-lg', dataImpactStyle.color)}>
<div className={cn('font-body text-lg', dataImpactStyle.color)}>
{dataImpactLabel}
</div>
</div>
@@ -251,7 +251,7 @@ export function ApprovalCard({
{/* Dry-Run Checks */}
<div className="space-y-3">
<h4 className="font-mono text-xs text-nothing-gray-500 tracking-wider">
<h4 className="font-body text-xs text-nothing-gray-500 tracking-wider">
{tDryRun('validation')}
</h4>
<div className="space-y-2">
@@ -271,12 +271,12 @@ export function ApprovalCard({
>
{check.passed ? '✓' : '✗'}
</div>
<span className="font-mono text-sm text-nothing-white">
<span className="font-body text-sm text-nothing-white">
{check.name}
</span>
</div>
{check.message && (
<span className="font-mono text-xs text-nothing-gray-500">
<span className="font-body text-xs text-nothing-gray-500">
{check.message}
</span>
)}
@@ -291,7 +291,7 @@ export function ApprovalCard({
{/* Footer: Meta + Actions */}
<div className="flex items-center justify-between">
{/* Meta */}
<div className="font-mono text-xs text-nothing-gray-600">
<div className="font-body text-xs text-nothing-gray-600">
<span>{t('requestedBy')} </span>
<span className="text-nothing-gray-400">{request.requestedBy}</span>
<span className="mx-2">|</span>
@@ -304,7 +304,7 @@ export function ApprovalCard({
<button
onClick={handleReject}
className={cn(
'px-5 py-2 rounded-button font-mono text-sm transition-all',
'px-5 py-2 rounded-button font-body text-sm transition-all',
'border border-nothing-gray-700 text-nothing-gray-400',
'hover:border-nothing-red hover:text-nothing-red hover:bg-nothing-red/10'
)}
@@ -318,7 +318,7 @@ export function ApprovalCard({
onClick={handleApprove}
disabled={!allChecksPassed}
className={cn(
'px-5 py-2 rounded-button font-mono text-sm transition-all animate-pulse',
'px-5 py-2 rounded-button font-body text-sm transition-all animate-pulse',
'bg-nothing-red text-nothing-white border-2 border-nothing-red',
'hover:bg-nothing-red/80'
)}
@@ -330,7 +330,7 @@ export function ApprovalCard({
onClick={handleApprove}
disabled={!allChecksPassed}
className={cn(
'px-5 py-2 rounded-button font-mono text-sm transition-all',
'px-5 py-2 rounded-button font-body text-sm transition-all',
allChecksPassed
? isDestructive
? 'bg-nothing-red/20 text-nothing-red border border-nothing-red/50 hover:bg-nothing-red/30'

View File

@@ -190,7 +190,7 @@ export function DataPincer({
{showLabel && (
<div
className={cn(
'mt-6 font-mono tracking-wider uppercase',
'mt-6 font-body tracking-wider uppercase',
sizeClass.label,
hasError ? 'text-status-critical' : 'text-nothing-gray-400',
config.animate && 'animate-pulse'

View File

@@ -266,7 +266,7 @@ export function ThinkingTerminalOptimized({
</div>
<h2 className="font-display text-display-sm">{t('title')}</h2>
</div>
<span className="font-mono text-xs text-nothing-gray-500">
<span className="font-body text-xs text-nothing-gray-500">
v1.0 | DOM Bypass | {lineCount} lines
</span>
</div>
@@ -277,7 +277,7 @@ export function ThinkingTerminalOptimized({
onClick={startStream}
disabled={isStreaming}
className={cn(
'flex-1 py-3 px-4 rounded-button font-mono text-sm transition-all border',
'flex-1 py-3 px-4 rounded-button font-body text-sm transition-all border',
isStreaming
? 'bg-nothing-gray-800 text-nothing-gray-500 border-nothing-gray-700 cursor-not-allowed'
: 'bg-nothing-white text-nothing-black border-transparent hover:bg-nothing-gray-200'
@@ -289,7 +289,7 @@ export function ThinkingTerminalOptimized({
{isStreaming && (
<button
onClick={stopStream}
className="py-3 px-4 rounded-button font-mono text-sm bg-status-critical/20 text-status-critical border border-status-critical/50 hover:bg-status-critical/30"
className="py-3 px-4 rounded-button font-body text-sm bg-status-critical/20 text-status-critical border border-status-critical/50 hover:bg-status-critical/30"
>
{t('stop')}
</button>
@@ -299,7 +299,7 @@ export function ThinkingTerminalOptimized({
onClick={clearTerminal}
disabled={isStreaming || lineCount === 0}
className={cn(
'py-3 px-4 rounded-button font-mono text-sm border',
'py-3 px-4 rounded-button font-body text-sm border',
isStreaming || lineCount === 0
? 'bg-nothing-gray-800 text-nothing-gray-500 border-nothing-gray-700 cursor-not-allowed'
: 'bg-nothing-gray-800 text-nothing-gray-300 border-nothing-gray-700 hover:bg-nothing-gray-700'
@@ -312,7 +312,7 @@ export function ThinkingTerminalOptimized({
{/* Terminal Output - DOM Bypass Container */}
<div
ref={terminalRef}
className="bg-nothing-gray-900 rounded-card p-4 overflow-y-auto font-mono text-sm"
className="bg-nothing-gray-900 rounded-card p-4 overflow-y-auto font-body text-sm"
style={{ maxHeight, minHeight: '150px' }}
>
{/* Content appended directly via DOM manipulation */}
@@ -340,10 +340,10 @@ export function ThinkingTerminalOptimized({
{/* Footer */}
<div className="flex items-center justify-between pt-2 border-t border-nothing-gray-800">
<p className="font-mono text-xs text-nothing-gray-600">
<p className="font-body text-xs text-nothing-gray-600">
{t('stream')}
</p>
<p className="font-mono text-xs text-nothing-gray-600">
<p className="font-body text-xs text-nothing-gray-600">
{status === 'streaming' ? (
<span className="text-status-thinking animate-pulse"> LIVE</span>
) : (

View File

@@ -59,7 +59,7 @@ function DependencyPathVisualizer({
<div className="text-xs text-nothing-gray-500 mb-2">
{direction === 'upstream' ? t('blastRadius') : t('rootCauseChain')}
</div>
<div className="font-mono text-sm space-y-1">
<div className="font-body text-sm space-y-1">
{paths.map((path, i) => (
<div key={i} className="flex items-center gap-2">
<span className="text-nothing-gray-600">{i === 0 ? '>' : '|'}</span>
@@ -97,7 +97,7 @@ function ServiceChainVisualizer({
</div>
{/* ASCII Art 風格圖形 */}
<div className="font-mono text-xs leading-relaxed">
<div className="font-body text-xs leading-relaxed">
{isBlastRadius ? (
// Blast Radius: 向上展示誰會受影響
<>
@@ -200,7 +200,7 @@ function FinOpsVisualizer({ data }: { data: NonNullable<ThinkingStep['finopsData
</span>
<span
className={cn(
'font-mono',
'font-body',
action.risk === 'low' && 'text-status-healthy',
action.risk === 'medium' && 'text-status-warning',
action.risk === 'high' && 'text-status-critical'
@@ -338,7 +338,7 @@ export function ThinkingTerminal({
</div>
<h2 className="font-display text-display-sm">{t('title')}</h2>
</div>
<span className="font-mono text-xs text-nothing-gray-500">
<span className="font-body text-xs text-nothing-gray-500">
v0.1.0 | SSE
</span>
</div>
@@ -348,7 +348,7 @@ export function ThinkingTerminal({
onClick={() => startThinkingStream()}
disabled={isStreaming}
className={cn(
'w-full py-3 px-4 rounded-button font-mono text-sm transition-all border',
'w-full py-3 px-4 rounded-button font-body text-sm transition-all border',
isStreaming
? 'bg-nothing-gray-800 text-nothing-gray-500 border-nothing-gray-700 cursor-not-allowed'
: 'bg-nothing-white text-nothing-black border-transparent hover:bg-nothing-gray-200'
@@ -359,7 +359,7 @@ export function ThinkingTerminal({
{/* Terminal Output */}
<div
className="bg-nothing-gray-900 rounded-card p-4 overflow-y-auto font-mono text-sm"
className="bg-nothing-gray-900 rounded-card p-4 overflow-y-auto font-body text-sm"
style={{ maxHeight, minHeight: '150px' }}
>
{thinkingStream.length === 0 && !isStreaming && !error && (
@@ -383,10 +383,10 @@ export function ThinkingTerminal({
{/* Footer */}
<div className="flex items-center justify-between pt-2 border-t border-nothing-gray-800">
<p className="font-mono text-xs text-nothing-gray-600">
<p className="font-body text-xs text-nothing-gray-600">
{t('stream')}
</p>
<p className="font-mono text-xs text-nothing-gray-600">
<p className="font-body text-xs text-nothing-gray-600">
{t('events', { count: thinkingStream.length })}
</p>
</div>