登陸頁面設計師(提案回合)
此方法說明如何以回合方式提案登陸頁面、每個決策的依據,以及頁面在任何人看到之前必須通過的檢查。此技能的上游為 website-concept-architect(定義網站是什麼)。下游為 ui-ux-architect(將設計移植到應用程式中)。
0. 任務,以及它不是什麼
- 繪製,而非重構。 輸出為
<proposals-dir>/<date>/<product>/下的提案。不得觸碰應用程式的發行版程式碼;除非所有者同意,否則不得提交或推送。 - 頁面只有在 通過驗證欄(第 8 節) 且其宣稱的內容皆有跡可循(第 2 節)時才算完成。
- 以回合方式進行。每個回合產出新的方向,保留舊的方向作為靈感庫,並以一個推薦方案及其勝出原因作為結束。
1. 標準(「令人印象深刻」的定義)
以這個清單來評判每個螢幕截圖。
- 五秒鐘。 一個陌生人僅從第一個視口就能說出產品的用途、目標用戶以及與眾不同之處。
- 一個裝置。 頁面因一個特定的、產品獨有的東西而被記住,而不是一個顏色。好的裝置是具體的:在 Logo 中使用真的游標;一個會動的真實數字;將代理對伺服器的呼叫如實呈現為兩次真實呼叫;在複製的文字描述的瞬間,一封推播通知抵達手機。
- 具體,而非抽象。 每個宣稱都指向產品或其程式碼中的某個東西。
- 真實像素勝過插圖。 正在運行之產品的裁切截圖勝過任何產品的繪圖。
- 說出取捨。 文案需說明其用途、目標用戶,以及為了獲得它所必須接受的一件事(自託管:你自己的更新與備份;單一共用服務:多一個依賴項;僅限傳遞:政策保留在應用程式中)。
- 禁止事項: 圖庫照片、紫色漸層、每個放一個圖示的灰色卡片 Bento 網格、「被 10,000 個團隊信任」、虛構的客戶推薦、虛假指標。
2. 先研究:附來源的事實
在繪製之前,為每個產品建立一個事實表格:宣稱、數值、來源檔案。閱讀程式碼,而非行銷素材。
- 查看哪裡:
README.md、AGENTS.md/CLAUDE.md、設計文件和 ADR、CHANGELOG.md、驗證器和錯誤代碼、工具/端點註冊、wire/proto 對應、worker/retry 常數、品牌標誌元件、主題權杖檔案、現有的登陸畫面。 - 值得尋找的事實: 確切的工具名稱及其破壞性數量;錯誤代碼與訊息;常數(重試次數、退避基礎值與上限、輪詢間隔、信任限制);請求欄位(在 wire 對應中計算,而非文件);路由;真實的快速入門指令。
- 在程式碼中驗證計數與名稱。 文件會偏離:文件說的「六個欄位」在程式碼中可能是八個;README 可能指向一個已不存在的目錄;英雄範例可能使用伺服器拒絕的單位。
- 標記,絕不默默修正。 不一致之處(截圖中的過時品牌、截圖之間的矛盾、文件與程式碼不一致)需寫入
NOTES.md,並依情況呈現在頁面上。 - 在頁面上標記說明用數據(範例條目、ID、時間、通知文字)。讀者必須無需閱讀備註就能分辨真實與範例。
3. 品牌與家族
- 每個產品保留自己的標誌和強調色。 從其元件複製真實的標誌路徑,並從權杖檔案複製真實的權杖(背景、文字、柔和色、強調色、強調文字色、語意色彩),包含兩種主題。
- 字體:僅使用產品自身的字體,複製為 woff2 格式放入
fonts/目錄。在選擇字體性格前先檢查它們:一個在其完整粗細範圍內宣告的可變字體,可以為一個產品提供髮絲般的數字,為另一個產品提供動態的粗體,而無需新增字體。python -c "from fontTools.ttLib import TTFont; t=TTFont('inter-latin.woff2'); print([(a.axisTag,a.minValue,a.maxValue) for a in t['fvar'].axes])" - 組織的品牌指南是家族,不是範本。 將其用於細微的共同細節(一個小標記、一個
currentColor的頁尾 credit),絕不能作為產品自身的識別。 - 家族層: 一個共享檔案,包含間距、字體與動態權杖、頁首、按鈕、小標題、區塊欄、影片控制、複製按鈕、頁尾以及動態工具包。產品則可覆蓋顏色、字體性格與構圖。數個頁面應看起來像是具有鮮明個性的兄弟姊妹。
4. 每個產品的藝術指導
在規劃版面之前決定一個個性;讓它驅動字體、網格、顏色重量與節奏。可行的範例:
| 個性 | 字體性格 | 構圖與節奏 |
|---|---|---|
| 平靜、評論式(金融) | 淺色粗細的巨大英雄字體搭配表格數字;記帳線使用等寬字體 | 大量留白、不對稱網格、一個夜間色帶、一個滿版真實截圖 |
| 大聲、動感(健身) | 黑色粗細、緊密字距、超大數字 | 滿版強調色帶搭配跑馬燈、硬邊界、大聲與安靜區塊交替 |
| 技術性、精確(身份識別) | 等寬字體標註、大型等寬數字 | 髮絲網格基底、帶標題的編號圖示、註解圖表 |
| 簡潔、有節奏感(通知) | 巨大的等寬狀態單字 | 時間尺規作為重複主題、留白、一個固定區塊 |
- 避免預設框架(眉毛區、h1、導言、兩個按鈕、信任清單、光暈),除非你刻意改變它。一個回合中所有產品共用一個框架就是失敗。
- 像電影一樣安排長頁面的節奏:一個安靜區塊、一個大聲區塊、一個滿版時刻、一個暗色帶、一次背景變化。均勻的間距讀起來感覺像是拼接的。
- 刻意設計 390 px 寬度: 為手機自行裁切截圖、可重新排列(堆疊、側邊匯流排)而非縮小的圖表、折疊線以上的影片內容。
- 聯絡頁面檢查: 將所有產品的第一個視口並排渲染(兩種主題,1440 和 390 寬度)。檢查是否有雷同之處以及家族間的斷裂。
5. 英雄影片
每個產品一個精心編排的序列,在 4 到 8 秒內講述產品故事,並停留在一個靜態的最終狀態。
- 最終狀態就是普通的 HTML。 關閉 JS 和減少動態設定時會立即顯示;影片僅朝向它做動畫(起始狀態用一個
reset(),步驟[ms, fn(instant)],end()清理)。 - 進入視野時播放一次,永不循環;分頁隱藏時暫停;有一個可見的暫停/重播控制項(WCAG 2.2.2)。影片內的打字行為由影片時間軸驅動,因此暫停時打字也會凍結。
- 按順序陳述事實。 使用真實行為作為情節:請求 → 被拒絕並顯示真實錯誤 → 重新發送 → 儲存;三份副本 → 合併為一份;排隊 → 輪詢 → 已發送。不要偽造數據不支援的強調效果。
- 共用元素移動(一個總數飛入英雄字體、表格飛入一個資料庫)可以構成一個場景,而不是一系列揭示。
- 可及性文字:可見的打字層是
aria-hidden;完整句子則放在一個.srspan 元素中。
6. 動態規則
- 閘門: 內容預設可見;僅當
prefers-reduced-motion允許時,一個頭部腳本才添加html.anim;每個隱藏或動畫規則都放在.anim之下。 - 僅在一次性揭示中使用透明度(IntersectionObserver,結束於 1)。卷軸關聯效果(
animation-timeline: view()/scroll()、固定位置擦洗)只能對 transform、clip-path 或 stroke 進行動畫:半透明的文字狀態在 axe 中會造成對比度失敗。 - 允許的:帶有靜態備援的 CSS 卷軸驅動動畫、用於主題切換的 View Transitions(從切換按鈕開始的圓形擦除)、CSS
linear()彈簧、可變粗細動畫、關閉動畫時寫入最終文字的計數器。 - 自動移動的內容(跑馬燈、自動播放)需要一個暫停控制項,並在滑鼠懸停/聚焦時暫停。
- 測量版面位移;為計數器和打字文字保留空間。
7. 截圖
- 僅來自正在運行的產品,絕非其模型。確定性地播種示範數據,以便各截圖間的數字一致(或在頁面上說明它們不一致)。
- 有目的地裁切(每個重點一個面板),兩種主題,2 倍解析度,加上獨立的手機裁切。
- 裁切掉過時的品牌標誌並標記它。當 UI 語言與頁面語言不同時,在圖說中說明。
- 實作為一個淺色/深色
<img>成對標籤,附帶height:auto、有意義的alt,以及定位在截圖座標空間內的標記(需測量;標記會漂移)。 - 如果建置被阻擋(私有套件、缺少權杖),請說明原因,將繪製的數據標記為說明性質,並列出確切的阻礙項目。
8. 硬性要求與驗證欄
每個頁面:
- 自包含 HTML,內嵌 CSS 與 SVG,無 CDN,僅使用產品自身的字體;小於 200 KB(不包含截圖)。
- 透過
data-theme支援淺色與深色模式,並提供切換按鈕(儲存偏好設定、系統預設值)。 - 地標、一個
h1、無間斷的標題順序、跳至內容連結、focus-visible、44 px 的點擊目標、forced-colors備援。
檢查(全部必須通過才能展示給任何人):
verify.js: 在 390x844 和 1440x800 × 淺色/深色 × 動態/減少動態 = 8 次執行,零違規 的情況下執行 axe-core(wcag2a/2aa/21aa/22aa + 最佳實踐)。在動態模式下,先滾動整個頁面以使揭示效果觸發。同時檢查:無水平捲軸;圖片被封鎖時仍可閱讀;JS 關閉時仍可閱讀。- HTML 解析器檢查 以防止文字被吞掉:原始文字中的
<token>或<no-reply@…>會變成標籤,而 axe 不會告訴你。請將其跳脫為<。 - 每個頁面的冒煙測試:在 1440 和 390 寬度下點擊每個控制項,在
pageerror時失敗,並在互動結束狀態(對話框開啟、套用後)再次執行 axe。 - 螢幕截圖: 影片靜止狀態與減少動態狀態,兩種主題,兩種寬度。仔細審視它們,並以嚴格的藝術總監身分至少迭代兩次。
- 說明未涵蓋的項目: 螢幕閱讀器、Safari/Firefox、真實裝置、針對五秒鐘宣稱的使用者測試。
9. 陷阱(每個都會耗費時間)
- CSS 特異性:一個針對圖案的主題切換規則必須勝過元件規則(需使用
img.sl,而非.crop img)。 - 測量隱藏元素會得到 0(鏡頭、縮放):先顯示,再測量。
- 用透明度調暗的非活躍步驟會導致對比度失敗:應用邊框/背景來強調。
role="list"需要listitem子元素;章節標題不可從h1跳到h3。- 光暈/網格背景需要滿版、遮罩以及
body{overflow-x:clip}。 - 網格儲存格中不可斷行的
<code>會在 390 px 寬度時造成水平捲軸;可滾動的pre會導致scrollable-region-focusable失敗(請賦予其tabindex="0"、role="region"和唯一標籤,或使用pre-wrap)。 - 通用類別名稱會在共享樣式與產品 CSS 之間衝突(如
.tl、.copy):請為家族類別加上命名空間。 cqw是相對於祖先容器解析,而非元素本身。- 與可見文字不同的
aria-label會導致 label-in-name 錯誤:請將額外上下文放在一個.srspan 中。 - Python 樣板字串缺少
f前綴會導致{label}洩漏到可及性名稱中:請 grep 檢查輸出。 loading="lazy"的圖片會從全頁截圖中遺失;這不是缺陷。- 透過提取組裝的頁面,當來源變更時不會更新,除非重新執行組裝器。
10. 流程
- 閱讀簡報/交接文件、產品程式碼與文件;建立事實表格與標記(第 2 節)。
- 盤點品牌: 標誌路徑、權杖、字體(軸)、現有截圖及其問題。
- 方向提案回合: 每個產品 3 個小型、不同的方向,每個方向圍繞一個裝置構建。保留它們作為靈感庫。
- 所有者回饋 → 將最佳想法合併為一個長頁面(區塊欄、常見問題、附複製按鈕的真實快速入門、一個有權重的「你接受什麼」區塊)。
- 提升天花板: 先建立一個共享的家族層,然後為每個產品建立一個藝術指導的頁面,並附帶英雄影片。獨立產品可以平行構建(每個產品一個代理,家族層設為唯讀,建議回報並一次性套用,然後重建並重新驗證所有頁面)。
- 一起審查: 聯絡頁面、家族層的一致性修正、完整的重新驗證。
- 交付: 每個產品一個
NOTES.md(概念、真實與範例、標記、驗證表格);一個供下次工作階段使用的HANDOFF.md(目標、決策、標記、弱點、下一步想法);僅供檢視的獨立預覽版本,內嵌字體與截圖;一份簡短摘要,每個產品包含一個推薦方案及其勝出原因。
11. 檔案與工具
<proposals-dir>/<date>/
HANDOFF.md 下一次工作階段的簡報
<product>/direction-N.html 頁面;NOTES.md;fonts/;shots/
_tools/verify.js axe x8、溢出、圖片封鎖、JS 關閉
_tools/family.py 共享外殼、權杖、動態工具包(影片、計數、字體、onView)
_tools/build_<product>.py 每個產品一個生成器
_tools/settled.js 影片靜止後擷取螢幕截圖
_tools/standalone.py 僅供檢視的副本,內嵌字體與截圖
_tools/smoke_<product>.js 互動冒煙測試
生成器攜帶建立它們的工作階段的硬編碼路徑;在執行前需修正 sys.path 和輸出路徑。verify.js 期望 [email protected] 安裝在同級目錄 verify/node_modules 中。
12. 展示頁面前的檢查清單
- 第一個視口通過五秒鐘測試;那個裝置在該視口中可見。
- 每個數字和名稱都可追溯到一個檔案;範例數據在頁面上標示;標記記錄在
NOTES.md中。 - 取捨被清楚陳述並賦予視覺權重。
- 英雄影片會靜止;最終狀態是預設的 HTML;暫停/重播功能正常;減少動態與 JS 關閉時可閱讀。
- 卷軸關聯效果僅使用 transform/clip/stroke;揭示為一次性。
- 已設計 390 px 寬度(自行裁切、可重新排列的圖表),而非僅是垂直堆疊。
- verify.js 全部通過(8 次執行),解析器檢查通過,冒煙測試通過,小於 200 KB。
- 已檢視螢幕截圖(兩種主題、兩種寬度),並因所見而做出修改。