Spaces:
Sleeping
Sleeping
新增 docs/design.md 設計系統文件
Browse files依千卉既有 DESIGN.md 慣例格式(YAML frontmatter 機器可讀 tokens +
Markdown 本文說明判斷準則),從 assets/app.css 與需求彙整文件第十一節
「視覺規範」萃取本案設計系統:雙主題配色(WCAG AA 驗算通過)、字體
(Crimson Pro 英文數字 + Noto Sans TC 中文)、造型間距、圖示規範、
已知技術限制(Gradio CSS pipeline 的 :root 前綴問題等)。
- docs/design.md +188 -0
docs/design.md
ADDED
|
@@ -0,0 +1,188 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
version: 1.0
|
| 3 |
+
project: SpectraEngine(譯彩紛呈 II 分析引擎)
|
| 4 |
+
brand: 致理科技大學應日系 鄧老師委託案
|
| 5 |
+
last_updated: 2026-08-05
|
| 6 |
+
source: assets/app.css(E4 抽出前為 app_agent.py 內嵌 _CUSTOM_CSS 常數)
|
| 7 |
+
|
| 8 |
+
colors:
|
| 9 |
+
light:
|
| 10 |
+
bg: "#f8fafc"
|
| 11 |
+
surface: "#ffffff"
|
| 12 |
+
surface2: "#f1f5f9"
|
| 13 |
+
surface3: "#ffffff"
|
| 14 |
+
surface3-border: "#e2e8f0"
|
| 15 |
+
border: "rgba(2,132,199,.16)"
|
| 16 |
+
border-hover: "rgba(2,132,199,.35)"
|
| 17 |
+
accent: "#0284c7"
|
| 18 |
+
accent-strong: "#0369a1"
|
| 19 |
+
accent2: "#4f46e5"
|
| 20 |
+
accent2-strong: "#4338ca"
|
| 21 |
+
accent3: "#9333ea"
|
| 22 |
+
text: "#1e293b"
|
| 23 |
+
text-soft: "#334155"
|
| 24 |
+
text-muted: "#475569"
|
| 25 |
+
text-subtle: "#64748b"
|
| 26 |
+
success: "#047857"
|
| 27 |
+
warn: "#b45309"
|
| 28 |
+
user-bubble-bg: "#dcfce7"
|
| 29 |
+
user-bubble-border: "#86efac"
|
| 30 |
+
user-bubble-text: "#166534"
|
| 31 |
+
dark:
|
| 32 |
+
bg: "#020617"
|
| 33 |
+
surface: "#0d1526"
|
| 34 |
+
surface2: "#111827"
|
| 35 |
+
surface3: "#1e293b"
|
| 36 |
+
surface3-border: "#334155"
|
| 37 |
+
border: "rgba(14,165,233,.11)"
|
| 38 |
+
border-hover: "rgba(14,165,233,.30)"
|
| 39 |
+
accent: "#0ea5e9"
|
| 40 |
+
accent-strong: "#38bdf8"
|
| 41 |
+
accent2: "#818cf8"
|
| 42 |
+
accent2-strong: "#a5b4fc"
|
| 43 |
+
accent3: "#c084fc"
|
| 44 |
+
text: "#e2e8f0"
|
| 45 |
+
text-soft: "#cbd5e1"
|
| 46 |
+
text-muted: "#94a3b8"
|
| 47 |
+
text-subtle: "#475569"
|
| 48 |
+
success: "#34d399"
|
| 49 |
+
warn: "#fbbf24"
|
| 50 |
+
user-bubble-bg: "rgba(34,197,94,.18)"
|
| 51 |
+
user-bubble-border: "rgba(34,197,94,.42)"
|
| 52 |
+
user-bubble-text: "#bbf7d0"
|
| 53 |
+
primary-cta-gradient: "linear-gradient(135deg, #0284c7 0%, #4f46e5 100%)"
|
| 54 |
+
accent-gradient: "linear-gradient(100deg, var(--c-accent) 10%, var(--c-accent2) 90%)"
|
| 55 |
+
heading-gradient: "linear-gradient(120deg, var(--c-accent-strong) 0%, var(--c-accent2) 55%, var(--c-accent3) 100%)"
|
| 56 |
+
|
| 57 |
+
typography:
|
| 58 |
+
fontFamily:
|
| 59 |
+
ui: "Inter, Noto Sans TC, system-ui, sans-serif"
|
| 60 |
+
mono: "JetBrains Mono, monospace"
|
| 61 |
+
heading-latin: "Crimson Pro"
|
| 62 |
+
heading-zh: "Noto Sans TC"
|
| 63 |
+
unit: rem
|
| 64 |
+
remBase: "16px"
|
| 65 |
+
base:
|
| 66 |
+
fontSize: "0.875rem"
|
| 67 |
+
cssVar: "--font-size-base"
|
| 68 |
+
note: "全站內文字級唯一來源,任何內文字級改動一律引用這個變數,不手寫 rem 數值"
|
| 69 |
+
scale:
|
| 70 |
+
display-lg: "2.1rem"
|
| 71 |
+
display-md: "1.8rem"
|
| 72 |
+
display-sm: "1.6rem"
|
| 73 |
+
title-lg: "1.4rem"
|
| 74 |
+
title-md: "1.25rem"
|
| 75 |
+
title-sm: "1.15rem"
|
| 76 |
+
body-lg: "1.05rem"
|
| 77 |
+
body-base: "var(--font-size-base)"
|
| 78 |
+
caption: "0.78rem"
|
| 79 |
+
badge: "0.70rem"
|
| 80 |
+
step-pill: "0.62rem"
|
| 81 |
+
|
| 82 |
+
rounded:
|
| 83 |
+
sm: "4px"
|
| 84 |
+
md: "9px"
|
| 85 |
+
lg: "10px"
|
| 86 |
+
xl: "12px"
|
| 87 |
+
card: "14px"
|
| 88 |
+
card-lg: "16px"
|
| 89 |
+
pill: "20px"
|
| 90 |
+
|
| 91 |
+
shadow:
|
| 92 |
+
card: "0 4px 16px rgba(15,23,42,.18)"
|
| 93 |
+
card-hover: "0 16px 40px rgba(79,70,229,.35)"
|
| 94 |
+
card-hover-strong: "0 20px 46px rgba(79,70,229,.45)"
|
| 95 |
+
overlay: "0 16px 50px rgba(15,23,42,.20)"
|
| 96 |
+
drawer: "4px 0 24px rgba(15,23,42,.28)"
|
| 97 |
+
|
| 98 |
+
layout:
|
| 99 |
+
columns: "nav-col : chat-col : canvas-col = 2 : 3 : 7(gr.Column scale)"
|
| 100 |
+
nav-col-width: "220px(收合 60px,@media min-width:901px 才套用收合樣式)"
|
| 101 |
+
chat-col-min-width: "280px"
|
| 102 |
+
canvas-col-min-width: "380px"
|
| 103 |
+
homepage-max-width: "50rem"
|
| 104 |
+
base-padding: "16px(nav-col/輸入框基準,20px canvas 內容區)"
|
| 105 |
+
---
|
| 106 |
+
|
| 107 |
+
# SpectraEngine 設計系統
|
| 108 |
+
|
| 109 |
+
> 本文件包含兩層:YAML front matter 為機器可讀的 design tokens(供 AI agent 或 Stitch 等工具直接使用);Markdown 本文記錄「為什麼」與人的判斷準則。實作以 `assets/app.css` 為準——這份 CSS 原本內嵌在 `app_agent.py`,2026-08-05(E4)抽成獨立檔案,改用 `app.launch(css_paths=...)` 載入。
|
| 110 |
+
|
| 111 |
+
---
|
| 112 |
+
|
| 113 |
+
## 專案定位
|
| 114 |
+
|
| 115 |
+
`SpectraEngine`(譯彩紛呈 II 分析引擎)是一套針對重譯文本語言特徵的量化分析平台,技術上是 Python + Gradio 單頁研究工具,服務對象是進行重譯研究的學術使用者(大學教師、研究生)。介面分兩種截然不同的使用情境,視覺語言刻意分兩派:
|
| 116 |
+
|
| 117 |
+
- **對話區**(左側導覽+對話串+輸入框):參考 **AI-Native UI** 風格——訊息泡泡、打字中三點跳動動畫、串流文字顯示,對應報告撰寫等待期間的載入體感需求。介面語彙上參考 Claude.ai/ChatGPT 網頁版的排版與操作體驗。
|
| 118 |
+
- **結果分頁**(表格/圖表區):參考 **Data-Dense Dashboard** 風格——多圖表/資料表並存、緊湊排版、最大化資訊密度,對應 75 項指標表格與 4 種統計圖表的呈現需求。
|
| 119 |
+
|
| 120 |
+
兩種風格共用同一套色彩與間距 token,差異只在密度與動效,不是兩套獨立設計系統。
|
| 121 |
+
|
| 122 |
+
---
|
| 123 |
+
|
| 124 |
+
## 配色
|
| 125 |
+
|
| 126 |
+
雙主題(淺色/深色)系統,經 WCAG AA 對比度驗算(叫 ui-ux-pro-max skill 對執行中實機量測,非套用通則):淺色模式主要文字對比度約 7.24–14.63:1、深色模式約 7.87–14.78:1,9 個關鍵文字元素全數通過 AA。
|
| 127 |
+
|
| 128 |
+
**配色決策原則:本次改版不重新設計配色**——業主原本版本已建立完整雙主題 token(sky + indigo + slate 系),驗算品質良好,只在使用場景上做微調,不更換色相。
|
| 129 |
+
|
| 130 |
+
### 一般強調色 vs 加強強調色
|
| 131 |
+
|
| 132 |
+
淺色模式的一般強調色 `#0284c7`(accent)用於一般大小的內文文字時,對比度 4.09:1 略低於 WCAG AA 的 4.5:1 門檻,但用於按鈕/圖示/大字等允許 3:1 門檻的地方完全合格。系統另外準備了 `accent-strong`(`#0369a1`,5.93:1)供小字/連結專用。**兩者不能混用**:一般強調色用在按鈕/圖示/大字,加強強調色用在小字/連結文字。
|
| 133 |
+
|
| 134 |
+
### 漸層文字與漸層背景的已知踩坑
|
| 135 |
+
|
| 136 |
+
`background: linear-gradient(...)` 簡寫在這版瀏覽器會把 `background-image` 這個子屬性解析成空值(實測用 devtools 讀 `getPropertyValue('background-image')` 回傳空字串),視覺上等於文字消失。**規則:漸層一律寫 `background-image: linear-gradient(...)` 這個子屬性本身,不用 `background` 簡寫**。全站三處漸層文字/按鈕(`.app-header .title-line`、`.homepage-hero h1`、CTA 按鈕)都遵守這條。
|
| 137 |
+
|
| 138 |
+
判斷漸層文字的 WCAG 對比度時,不能用 `getComputedStyle().color`(漸層文字用 `-webkit-text-fill-color:transparent`,會讀到透明),要用截圖取樣實際渲染像素計算。
|
| 139 |
+
|
| 140 |
+
---
|
| 141 |
+
|
| 142 |
+
## 字體
|
| 143 |
+
|
| 144 |
+
- **英文/數字**:Crimson Pro(學術感、研究工具調性),標題與強調數字用
|
| 145 |
+
- **中文本文**:Noto Sans TC(維持業主原設定;Stitch 等工具的字體庫多為西文導向、不含中文字體,中西混搭是人工判斷後的決定,非工具庫建議)
|
| 146 |
+
- **UI 介面文字**:Inter(Gradio 主題 `font=` 設定,中文 fallback 到 Noto Sans TC)
|
| 147 |
+
- **等寬/資料**:JetBrains Mono(指標數值、程式碼片段)
|
| 148 |
+
|
| 149 |
+
### 字級規範
|
| 150 |
+
|
| 151 |
+
全站基礎內文字級統一 `0.875rem`(14px),**唯一來源是 CSS 變數 `--font-size-base`,任何內文字級改動都要引用這個變數,不允許手寫 rem 數值**(2026-07-24 曾經手寫 `.88rem` 被業主當場糾正,需求文件第十一節的既有規範)。標題、步驟列 pill、小徽章這類刻意做出層級差異的地方例外,可以有自己的固定字級(見 YAML `typography.scale`)。
|
| 152 |
+
|
| 153 |
+
---
|
| 154 |
+
|
| 155 |
+
## 造型與間距
|
| 156 |
+
|
| 157 |
+
- **圓角**:卡片類 14–16px、按鈕/輸入框 9–10px、徽章/pill 20px(全圓)
|
| 158 |
+
- **陰影**:僅用在懸浮/強調狀態(卡片 hover、彈窗、抽屜),靜態卡片不加陰影——2026-07-23 業主實機回饋「原本的強調色外框+大範圍陰影+漸層底色讓卡片像浮起來的彈窗」,改成扁平化:外框、陰影、底色拿掉,只留圓角與內距維持呼吸空間;彈出動畫保留(負責「這塊剛出現」的狀態提示,跟視覺重量無關)
|
| 159 |
+
- **版面比例**:三欄式工作區 `nav-col : chat-col : canvas-col = 2 : 3 : 7`,寬螢幕滿版貼齊左右邊界(不做置中留白),首頁例外維持 `max-width: 50rem` 置中,避免寬螢幕上被拉滿版
|
| 160 |
+
- **基準留白**:導覽列與輸入框四邊留白 16px 為基準,其餘區塊(對話氣泡、Canvas 內容區)對齊同一基準線,避免同一頁面出現兩種留白邏輯
|
| 161 |
+
|
| 162 |
+
---
|
| 163 |
+
|
| 164 |
+
## 圖示
|
| 165 |
+
|
| 166 |
+
Heroicons outline 風格 SVG,24×24、`stroke-width="1.75"`、`fill="none"`,手繪 path(非套件逐點對照)。業主明確否決沿用專案既有的 emoji 慣例。
|
| 167 |
+
|
| 168 |
+
深色模式處理:`gr.Button(icon=...)` 在這版 Gradio 渲染成 `<img>` 標籤而非行內 `<svg>`,CSS `currentColor` 對它無效,因此淺色版固定 stroke 顏色,深色模式改用 `filter: grayscale(1) invert(1) brightness(1.55) contrast(.85)` 反相逼近深色版文字色,不另外準備第二份深色 SVG 檔案。需要 `currentColor` 正常運作(例如收合鈕、明暗切換鈕這類不需要 Python `.click()` 的裝飾性圖示)則改用 `gr.HTML()` 內嵌行內 SVG。
|
| 169 |
+
|
| 170 |
+
---
|
| 171 |
+
|
| 172 |
+
## 動效
|
| 173 |
+
|
| 174 |
+
- 對話訊息串流顯示、打字中三點跳動動畫(AI-Native UI 語彙)
|
| 175 |
+
- 運算中狀態用轉圈動畫,避免使用 Gradio 預設的 `.generating` 呼吸藍框(視覺上與本站的呼吸動畫語彙衝突,需求文件已列為既有修正項)
|
| 176 |
+
- 手機抽屜/確認彈窗用 `transform` 位移或 overlay 淡入,不做過度炫技的轉場
|
| 177 |
+
|
| 178 |
+
---
|
| 179 |
+
|
| 180 |
+
## 已知技術限制(設計時務必納入考量)
|
| 181 |
+
|
| 182 |
+
- **沒有測試套件**,任何視覺改動都要手動走一次流程驗證,純美感/主觀判斷的改動先截圖給業主看過再定案
|
| 183 |
+
- Gradio 6 的 CSS pipeline 會自動幫 `css=`/`css_paths=` 內的所有選擇器加上 `.gradio-container .contain` 前綴,`:root` 選擇器包進 `@media` 區塊後永遠無法命中;系統深色模式的 token 覆寫因此改放在 `app.launch(head=...)` 注入的獨立 `<style>`(見 `_DARK_MODE_HEAD_CSS`),繞過這個轉換管線
|
| 184 |
+
- 部分 Gradio 原生元件(`gr.Column(visible=False)` 等)在特定時序下會有可見性狀態的非直覺行為,改版面配置前建議先查 `app_agent.py` 裡累積的相關踩坑註解,避免重踩
|
| 185 |
+
|
| 186 |
+
---
|
| 187 |
+
|
| 188 |
+
*本文件為本次 UI/UX 改版團隊(吳千卉)依既有實作彙整,非全新設計提案。配色與整體風格方向延續業主原有版本,未��調整請同步更新本文件與 `assets/app.css`,保持兩者一致。*
|