Design System
午夜玻璃 設計系統
深色底 + 光暈 + 玻璃層,AI 產品與開發者工具的通用語言。
色彩
表面 Surfaces
由後往前:頁面底 → 區塊底 → 卡片 → 卡片內的內嵌面板。
canvas #0B0D12canvas-2 #0F121Asurface #161A25surface-2 #1E2331surface-inverse #F4F6FB文字 Ink
ink 是主文字,ink-2 是說明,ink-3 只能用在非必要資訊上。
ink #EAECF2ink-2 #98A0B4ink-3 #616B82ink-inverse #0B0D12強調 Accent
accent 只能當底色或圖形;當文字時一律用 accent-ink。
accent #7C5CFFaccent-2 #6A47FFaccent-soft rgb(124 92 255 / 0.16)accent-ink #A992FFon-accent #FFFFFF語意 Semantic
成功、警告、危險、資訊。每一個都有實心與淡色兩種。
success #34D399warning #FBBF24danger #FB7185info #22D3EE線條 Lines
line 是髮絲線,line-2 用在需要更明確分隔的地方。
line rgb(255 255 255 / 0.09)line-2 rgb(255 255 255 / 0.16)對比檢查
WCAG 2.1:一般文字要 4.5:1,大字與 UI 元件邊界要 3:1。 下面那一行「強調色當文字」故意留著,就是要讓你看見為什麼需要 accent-ink。
| 組合 | 比值 | 等級 | 樣子 |
|---|---|---|---|
| 主文字 / 頁面底 | 16.45 | AAA | 文字範例 Aa |
| 次文字 / 頁面底 | 7.42 | AAA | 文字範例 Aa |
| 三級文字 / 頁面底 | 3.64 | AA-large | 文字範例 Aa |
| 強調文字 / 頁面底 | 7.63 | AAA | 文字範例 Aa |
| 強調色當文字 / 頁面底 | 4.47 | AA-large | 文字範例 Aa |
| 按鈕文字 / 強調底 | 4.35 | AA-large | 文字範例 Aa |
| 反白文字 / 深色面板 | 17.97 | AAA | 文字範例 Aa |
字級
Display — 標題用字 AaBbCc 字體樣本
Body — 內文用字 AaBbCc 字體樣本
Mono — 0123456789 tabular nums
間距
space-1 space-2 space-3 space-4 space-5 space-6 space-7 space-8 space-9 space-10 space-11 space-12 圓角
xssmmdlgxlpill陰影
shadow-1shadow-2shadow-3元件與變體
Buttons
Inputs
說明文字放這裡。
說明錯在哪,以及怎麼修。
Badges & Chips
Feedback
這是一則說明訊息。
儲存成功。
額度快用完了。
上傳失敗,檔案超過 2GB。
Surfaces
卡片
預設卡片:邊框 + 圓角 + 可選陰影。
強調卡片
data-featured:加深邊框並抬高陰影。
內嵌深色面板
--ds-panel-bg
玻璃層 .ds-glass
Motion
dur-1dur-2dur-3滑過去看差別。系統設定「減少動態」時,全部會變成 0ms。
細節:Tooltip、捲軸、游標
三個最常被跳過、但一眼就看得出有沒有做的地方。每個風格都有自己的一套值。
Tooltip
滑過去,或用 Tab 聚焦 —— 兩種都會出現。
Scrollbar
主題化
項目 01
項目 02
項目 03
項目 04
項目 05
項目 06
項目 07
項目 08
項目 09
項目 10
hover 才出現
項目 01
項目 02
項目 03
項目 04
項目 05
項目 06
項目 07
項目 08
項目 09
項目 10
隱藏+淡出
項目 01
項目 02
項目 03
項目 04
項目 05
項目 06
項目 07
項目 08
項目 09
項目 10
Cursor
這個風格沿用系統游標。只有粗野等寬換成了自訂游標。
Spacing rhythm
標題上方的空間比下方大
因為標題屬於它下面的段落,不屬於上面的區塊。
這就是群組的方式
上下一樣大的話,整頁會看起來像一堵牆。
完整 token(60 個)
:root {
--ds-canvas: #0B0D12;
--ds-canvas-2: #0F121A;
--ds-surface: #161A25;
--ds-surface-2: #1E2331;
--ds-surface-inverse: #F4F6FB;
--ds-overlay: rgb(3 4 8 / 0.66);
--ds-ink: #EAECF2;
--ds-ink-2: #98A0B4;
--ds-ink-3: #616B82;
--ds-ink-inverse: #0B0D12;
--ds-ink-inverse-2: rgb(11 13 18 / 0.7);
--ds-accent: #7C5CFF;
--ds-accent-2: #6A47FF;
--ds-accent-soft: rgb(124 92 255 / 0.16);
--ds-accent-ink: #A992FF;
--ds-on-accent: #FFFFFF;
--ds-success: #34D399;
--ds-success-soft: rgb(52 211 153 / 0.16);
--ds-on-success: #0B0D12;
--ds-warning: #FBBF24;
--ds-warning-soft: rgb(251 191 36 / 0.16);
--ds-on-warning: #0B0D12;
--ds-danger: #FB7185;
--ds-danger-soft: rgb(251 113 133 / 0.16);
--ds-on-danger: #0B0D12;
--ds-info: #22D3EE;
--ds-info-soft: rgb(34 211 238 / 0.16);
--ds-on-info: #0B0D12;
--ds-danger-on-inverse: #FB7185;
--ds-line: rgb(255 255 255 / 0.09);
--ds-line-2: rgb(255 255 255 / 0.16);
--ds-line-inverse: rgb(0 0 0 / 0.12);
--ds-font-display: 'Space Grotesk', 'PingFang TC', 'Noto Sans TC', 'Microsoft JhengHei', sans-serif;
--ds-font-body: 'Space Grotesk', 'PingFang TC', 'Noto Sans TC', 'Microsoft JhengHei', sans-serif;
--ds-font-mono: 'JetBrains Mono', 'PingFang TC', 'Noto Sans TC', 'Microsoft JhengHei', sans-serif, monospace;
--ds-weight-display: 700;
--ds-tracking-display: -0.03em;
--ds-texture: radial-gradient(900px 500px at 12% -8%, rgb(124 92 255 / 0.20), transparent 62%), radial-gradient(700px 420px at 92% 8%, rgb(34 211 238 / 0.12), transparent 60%);
--ds-texture-size: cover;
--ds-panel-bg: linear-gradient(165deg, #1B2130, #0D1017);
--ds-panel-dots: radial-gradient(rgb(255 255 255 / 0.06) 1px, transparent 1.2px);
--ds-shadow-1: 0 0 0 1px rgb(255 255 255 / 0.07);
--ds-shadow-2: 0 2px 8px rgb(0 0 0 / 0.4), 0 18px 40px rgb(0 0 0 / 0.45);
--ds-shadow-3: 0 8px 20px rgb(0 0 0 / 0.5), 0 32px 80px rgb(0 0 0 / 0.6);
--ds-ring: 0 0 0 2px var(--ds-canvas), 0 0 0 4px var(--ds-accent);
--ds-glass-bg: rgb(255 255 255 / 0.055);
--ds-glass-backdrop: blur(20px) saturate(1.6);
--ds-glass-shadow: 0 0 0 1px rgb(255 255 255 / 0.08), inset 0 1px 0 rgb(255 255 255 / 0.14), 0 20px 50px rgb(0 0 0 / 0.5);
--ds-card-bg: rgb(255 255 255 / 0.035);
--ds-card-border: 1px solid rgb(255 255 255 / 0.09);
--ds-card-radius: calc(16px * var(--ds-radius-scale));
--ds-card-shadow: inset 0 1px 0 rgb(255 255 255 / 0.06);
--ds-input-bg: rgb(255 255 255 / 0.04);
--ds-label-tracking: 0.18em;
--ds-label-transform: uppercase;
--ds-tooltip-bg: #2A3142;
--ds-tooltip-ink: #EAECF2;
--ds-tooltip-shadow: 0 8px 20px rgb(0 0 0 / 0.6), inset 0 1px 0 rgb(255 255 255 / 0.12);
--ds-scrollbar-thumb: rgb(255 255 255 / 0.16);
--ds-scrollbar-thumb-hover: rgb(255 255 255 / 0.32);
}