ultrahand: theme
建立專案的主題,並從此持續發展它。主題是一個設計記號檔案加上其決策的簡短記錄,存放在專案中,以便後續的所有設計和審查都能建立在相同的基礎上,而不是每次都從頭開始。檔案格式請參閱 shared/theme/README.md;規則位於 shared/theme/rules.md,每一條規則都引用了 shared/theme/sources.md。
每個主題都保留不可協商規則(NN-1 到 NN-12:層級、8 點網格、雙色版模式、對比度、真實的字級比例等),並在每一條創意軸線(CR-1 到 CR-10:色相、中性色、字體風格、邊角、深度、密度……)上做出全新的選擇。這些規則是固定的,因此每個主題都感覺製作精良;軸線是開放的,因此沒有兩個產品看起來一樣。開始之前請先閱讀 rules.md。
以下腳本位於 ${CLAUDE_PLUGIN_ROOT}/shared/theme/。
1. 查找現有內容
先查看再詢問。對於僅以畫布成品存在的設計,列出該成品的檔案並從該處讀取 design/。在專案中搜尋 design/THEME.md、*.tokens.json、tokens/、Style Dictionary 配置,以及平台的佈景主題程式碼:CSS 自訂屬性、tailwind.config.*、Flutter ThemeData / ColorScheme、SwiftUI 色彩資源、Compose MaterialTheme。結果將決定對應的模式:
| 找到的內容 | 模式 |
|---|---|
| 主題檔案和 THEME.md | 演進(步驟 4)。切勿重新產生。 |
| 沒有主題檔案,但有已設定樣式的程式碼 | 提取(步驟 2),然後演進。 |
| 無任何內容(全新產品) | 建立(步驟 3)。 |
2. 提取程式碼中已包含的主題
目標是捕捉目前的外觀,經過清理,而不是重新設計。
- 執行
node scan.mjs <src dir>(加上--json可取得完整清單)。它會列出每個顏色、間距值、邊框圓角和字體大小,並附帶計數和位置,對近似重複的顏色進行分組,並標記偏離網格的間距。同時閱讀平台的佈景主題程式碼:主題物件中命名的值是預期的值,而散落的原始值則是偏離的部分。 - 命名角色。 對於每個顏色叢集,找出它的用途(頁面背景、正文、按鈕、邊框、錯誤),並將其對應到語義角色(README.md 列出了必要的角色)。一個角色對應一個值:當兩個近似重複的顏色服務於同一個角色時,保留使用較多的那個。
- 對齊規則。 將間距折疊到 NN-2 比例上,尺寸折疊到字級比例(NN-6)上,邊框圓角折疊到短比例(NN-7)上。透過沿著相同色相的色調階梯移動(NN-4)來修正對比度失敗。每次變更都會對產品造成可見的影響,因此請以表格形式列出它們(例如
13px → 12px, 4 處)供擁有者批准,並保留他們希望保持不變的任何內容。 - 填補空白。 大多數程式碼沒有深色模式、沒有焦點環、也沒有
on-角色。請在主題自己的調色盤中設計它們(NN-3, NN-10),而不是添加通用角色。 - 盤點元件。 列出可重複使用的元件(查看
components/、ui/、widgets/、views/)、它們的變體以及每個元件的定義位置。注意是否有任何工作由兩個不同的元件完成:這是一個合併候選項(EV-4),而不是要複製到主題中的內容。 - 記錄它已有的個性。 將現有外觀放在每一條創意軸線上,並寫入 THEME.md。品牌給定的選擇(標誌色相、授權字體)是
locked(鎖定);其餘的是open(開放)。
然後寫入檔案(步驟 5)。
3. 建立新主題
- 個性。 詢問三個形容詞以及目標使用者,再加上任何固定的內容:品牌顏色、標誌、字體、平台(原生 iOS 或 Android 應用程式傾向於使用系統字體和顏色;主題映射到它們之上 [HIG-COLOR] [M3-COMPOSE])。
- 三個方向。 提出三個在至少三條創意軸線上有所不同的方向,每個方向附帶一句與形容詞相關的理由。除非擁有者要求,否則避免使用 rules.md 中描述的預設外觀。並排展示它們(步驟 6),讓擁有者選擇其中一個或混合使用。
- 建構它。
- 調色盤: 對於每個關鍵顏色(主要、中性,加上錯誤和任何強調色),建立一個約 10–13 階的色調比例,從深到淺 [M3-HCT] [M3-COMPOSE],以便每個角色都能在兩個色版模式中找到符合對比度的階梯。
- 語義顏色: 每個必要的角色,每個角色都有其深色值,每個
on-X都是針對X設計的。 - 間距: NN-2 比例,然後根據工作進行語義間距:
inset階梯用於內距,以及gap-related、gap-group和gap-section,以便群組之間的間距明顯大於群組內部的間距(shared/composition/principles.md 中的 SEC-2)這一構圖規則內建於其中。 - 字體: 一個來自所選比例(CR-5)的字級系統,包含角色 display、headline、title、body、label;body 使用平台的預設值(Web 上為 16,iOS 上為 17 pt;僅針對密集的桌面工具使用 13–14,請參閱 NN-6)。
- 形狀、深度、動畫、焦點: 在所選的邊角樣式中建立邊框圓角比例;在所選的深度方法中建立陰影層級;持續時間和緩動記號;一個 2px 或更大的焦點環。
- 元件: 僅包含元件需要與其角色區分開來的元件記號(EV-2)。大多數元件不需要任何記號。
每個值都從版本 1.0.0 開始。
4. 演進現有主題
對於像是「新增警告顏色」、「我們需要更密集的表格」、「讓它感覺更溫暖」這類請求,或由設計技能或 theme-review 提出的新增項目:
- 首先讀取 THEME.md 和記號(EV-1)。尊重
locked(鎖定)的決定;如果請求需要更改其中一個,請說明並詢問。 - 如果現有角色適用,則重複使用它(EV-2)。僅在真正有缺口時才新增記號,並將其別名到現有的基礎色階(EV-3)。
- 廣泛的變更(「更溫暖」、「更有趣」)會移動一條
open(開放)的創意軸線:移動基礎色階,保留所有語義名稱,並重新執行對比度檢查。名稱在品牌重塑期間保持真實(NN-11)。 - 使用
$deprecated標記退役,並指定替代品;在後續版本中移除(EV-6)。 - 提升版本號碼並在變更日誌中新增一行,說明變更了什麼以及哪些畫面需要它(EV-5)。
5. 撰寫與檢查
- 撰寫
design/theme.tokens.json(或專案現有的記號位置)和design/THEME.md,遵循 README.md。example.tokens.json 展示了結構。 - 執行
node check.mjs design/theme.tokens.json並修正每個錯誤。警告需要在 THEME.md 中提供修正或理由。 - 交給程式碼。 對於 Web,執行
node css.mjs design/theme.tokens.json --out <path>/theme.css來產生內建深色模式的 CSS 自訂屬性。對於其他平台,或一次處理多個平台,建議使用 Style Dictionary,它讀取此格式並輸出 Swift、Android、Compose 和 Flutter [STYLE-DICT]。提議用記號取代掃描發現的原始值;未經詢問請不要執行此操作,因為它會影響每個有樣式的檔案。
6. 展示主題
在插件畫布上建立一個樣本(shared/canvas/;其 README 有合約),讓擁有者看到主題的實際運作,而不僅僅是一串十六進制代碼:
node "${CLAUDE_PLUGIN_ROOT}/shared/theme/css.mjs" design/theme.tokens.json --style --out theme.html
node "${CLAUDE_PLUGIN_ROOT}/shared/canvas/build.mjs" \
--presets "${CLAUDE_PLUGIN_ROOT}/skills/desktop/references/presets.md" \
--head theme.html --screen screen.html --title "<Product> theme" --out index.html
樣本中的 screen.html 僅使用主題的自訂屬性,並展示:顏色角色以 on-X 文字顯示在 X 上,並附帶測量到的對比度;字級比例搭配真實文案;間距比例;邊框圓角和陰影層級;每個盤點過的元件及其狀態;以及一個由該主題構建的小型真實畫面(一個清單和一個表單)。畫布的「淺色/深色」和「200% 文字」切換開關可測試兩個色版模式和文字縮放。如果主題需要網路字體,請將其 <link> 放在同一個 head 檔案中。
比較方向(步驟 3):不帶 --style 發出每個方向,使用 --selector '[data-state="a"]'(然後是 b、c)進行範圍限定,並將它們貼到畫面模板自己的 <style> 頂部:畫布在畫面內部設定 data-state,頁面 head 無法觸及。在 config.json 中宣告 states a、b、c,並將方向名稱作為標籤,「狀態」選擇器可在它們之間切換。
將 index.html 發佈為成品。當設計本身就是一個成品時,請將使用主題構建的成品(--head theme.html)重新發佈,並包含兩個 design/ 檔案。
7. 呈現
分享成品連結。用幾行文字說明:模式(建立、提取或演進)、版本號碼、個性在創意軸線上的位置及其原因、什麼是鎖定的、什麼是開放的、任何需要擁有者批准的對齊變更、檢查結果,以及下一步:使用它進行設計(mobile、tablet 和 desktop 技能會讀取它),或使用 theme-review 審查程式碼是否符合主題。