范解讀:六條設計規(guī)則、Token 體系與 style-guard 強制檢查)
后端前端人工智能RAG知識圖譜知識管理搜索引擎【免費下載鏈接】utopiaWorlds first open-source enterprise world model.項目地址https://gitcode.com/gh_mirrors/ont/utopia點擊查看免費下載Utopia 是一個開源的企業(yè)級世界模型world model項目其 Web 界面web/目錄是一套基于 React 19 Tailwind CSS 4 shadcn/ui 的單頁應用。本文以倉庫內的 web/DESIGN.md 為骨架結合 web/src/styles.css、web/src/ui/index.tsx、web/scripts/style-guard.mjs 等源碼完整解讀這套界面背后的六條設計規(guī)則字號五檔、間距六步、圓角四檔、顏色令牌化、狀態(tài)內聚于組件、面板即內容的槽。讀完本文你將掌握這套設計體系的每一處數值、它在源碼中的落地位置以及它如何通過 CI 守衛(wèi)強制被執(zhí)行。設計體系概覽中性玻璃、兩種主題、三層結構Utopia 的界面外觀chrome遵循一個總原則中性玻璃neutral glass提供暗色與淺色兩種主題。界面本體不引入任何色相hue文字使用 Geist 字體品牌字標wordmark使用 Manrope顏色只保留給兩類用途——數據如圖譜節(jié)點、實體色和少數語義狀態(tài)成功、警告、危險、爭議、紫色。組件層采用三層結構shadcn/uiRadix 基礎、Nova preset位于 web/src/components/ui/由shadcn add生成是純粹的供應層薄殼層web/src/ui/index.tsx封裝 shadcn 組件定義本項目的組件詞匯Button、Input、Dropdown、Status、SettingsCard等頁面層只允許使用殼層組件與styles.css中定義的語義類不得直接書寫原始控件、顏色值或狀態(tài)偽類。設計語言本身記錄在 web/src/styles.css共 1814 行而六條規(guī)則則被 web/scripts/style-guard.mjs 轉成可執(zhí)行的正則檢查。正如 DESIGN.md 開頭所言如果沒有這些規(guī)則一個頁面可能從十二種像素字號、十四種內距、任意一種灰色里各挑一個——守衛(wèi)的作用就是讓這種熵不再發(fā)生。規(guī)則一五檔字號按名字引用而不是按像素字號只有五檔且每檔同時規(guī)定字號與行高名字字號 / 行高用途text-fine11 / 16元數據、芯片文字、表頭、控件下方的提示text-small12 / 18次要文字、密集行、說明文字text-body14 / 22其余一切正文、控件、菜單text-title16 / 24區(qū)塊與對話框標題聊天正文按此檔閱讀text-display20 / 28頁面標題且僅限頁面標題規(guī)則的核心約束是不使用text-xs/text-sm/text-[11px]這類任意值。如果某個元素在兩個檔位之間需要一個尺寸說明是元素選錯了檔位而不是刻度有問題。字重方面控件和標題用font-medium只有主按鈕用font-semibold界面中不使用font-bold。數字在界面中一律用 Geist u-numtabular figures等寬數字不用等寬字體font-mono只留給密鑰、ID、代碼與 URL。在源碼中的落地styles.css的theme塊通過 CSS 變量定義了這五檔web/src/styles.css并附有一段注釋說明這套刻度經歷過一次整體上移——從前是 11/12/13/15/20三檔擠在 11–13px 之間1px 的字號差人眼幾乎分辨不出層次名義上有五級實際靠顏色區(qū)分現在正文落到 14px最常用的那一檔成為真正可讀的正文。style-guard.mjs中的type-scale規(guī)則用正則\btext-(xs|sm|base|lg|\d*xl|\[[0-9.](px|rem)\])\b直接禁止這些寫法unknown-text規(guī)則則動態(tài)地從styles.css中讀取全部--text-*與--color-*令牌任何不在白名單內的text-詞都會報錯web/scripts/style-guard.mjs。規(guī)則二六檔間距12 以上只用于版面間距步進為1 2 3 4 6 8對應 4、8、12、16、24、32 px內距padding、外邊距margin和間距gap一視同仁不允許半檔、不允許任意像素值。12 及以上屬于版面layout而非節(jié)奏rhythm——浮動欄下方的空隙、頁腳的呼吸空間這類場景允許使用??丶詭染囗撁娼^不直接給按鈕或輸入框設置 padding。頁面級經驗值頁面左右邊距gutter6或8兩個相鄰控件的間距2兩組控件之間4兩個區(qū)塊之間6。style-guard.mjs的spacing規(guī)則禁止p-0.5、m-1.5、gap-2.5、space-x-3.5等半檔寫法以及p-[…]任意值12 以上由正則放行因為那是版面凈空并且這條規(guī)則不適用于組件目錄——組件的內部間距是組件自己的事web/scripts/style-guard.mjs。規(guī)則三四檔圓角按角色命名圓角不叫rounded-sm/rounded-lg而是按角色命名rounded-cell芯片、表格單元格、kbd、小圖標目標rounded-control按鈕、輸入框、下拉框、分段控件rounded-panel卡片、列表、對話框主體、代碼塊rounded-overlay菜單、popover、toast、懸浮??棵姘濉魏螒腋≡陧撁嫔戏降臇|西rounded-full只用于真正的圓形頭像、狀態(tài)點、色板、圖譜節(jié)點。命名的意義在于rounded-panel說明了這是一個面板就像text-ink-2說明了這個灰色是干什么用的——守衛(wèi)能檢查的是角色是否用錯而不是數字是否正確。四個半徑也不是各自拍腦袋定出來的而是從 shadcn 的單一--radius10px派生cell ×0.8、control ×1、overlay ×1、panel ×1.4。在源碼中可以看到具體實現--radius-cell: calc(var(--radius) * 0.8); --radius-control: var(--radius); --radius-panel: calc(var(--radius) * 1.4); --radius-overlay: var(--radius);web/src/styles.css。這遵循 shadcn 自己的比例——卡片比懸浮在它上方的 popover 更圓。曾經這套值由手工挑選4、6、8、12結果與 shadcn 10px 的按鈕并排時按鈕比它所在的卡片還要圓?,F在整個界面的圓潤度只有一個旋鈕改--radius一處控件與面板一起動。這個比例還帶來一個結構性推論overlay 比 panel 更平所以panel 不能放進 overlay 內部——否則它的角會向外凸出。規(guī)則六已經排除了這種情形對話框里的表單不是面板。規(guī)則四顏色是令牌永遠不是值顏色體系是整個規(guī)范中最深的一層可以拆成幾條子規(guī)則1兩級文字、三級表面、兩級線條。文字只用text-ink內容本身與text-ink-2關于內容的說明不存在第三檔更淡的文字——注釋、時間戳、占位符的次要地位已經由位置和字號交代過了再淡一檔只會損害可讀性。線條是border-line與border-line-strong。填充面是bg-surface靜止、bg-surface-2懸停、bg-surface-3選中。2五個語義色只在有意義處出現。ok、warn、danger、contest、violet這五個語義色只用于狀態(tài)、爭議邊、破壞性操作絕不作為裝飾。neutral-500、white/10、rose-400、[var(--u-…)]這類寫法在頁面中一律禁止令牌在styles.css中定義一次通過 Tailwind 的theme暴露為顏色工具類如text-danger、bg-surface-2這是頁面拿到顏色的唯一入口web/src/styles.css。3狀態(tài)是彩色圓點 普通文字不是彩色膠囊。一列填色膠囊會讓眼睛先讀到一片顏色而不是那一列在說什么Status組件把顏色放在圓點上文字用text-ink-2。Chip則留給不是狀態(tài)的東西——計數、庫名、derived 這類標記它們是貼在內容上的標簽需要一個盒子圈起來。對應實現可看 web/src/ui/index.tsx 中的Status與Chip組件Status渲染一個bg-ok/bg-warn/bg-danger的圓點加普通文字Chip復用 shadcn Badge 的骨架但覆蓋為rounded-cell方角與項目語義色。4玻璃是表面處理不是顏色。glass用于余光中的面板glass-strong用于正在被閱讀的面板兩者在指針移入時都轉為實底對應--u-surface-strong-hover。頁面不得書寫backdrop-blur。styles.css中--u-surface-strong從 0.68 調到 0.78 再到 0.86 的注釋記錄了這一演變加上saturate(0.3)去色之后半透明像紙的膩感消失于是可以吃回厚度web/src/styles.css。5值只存在于令牌塊主題切換有兩條軌道。一個顏色值#rrggbb、rgba(…)不允許出現在任何.ts/.tsx文件或styles.css的規(guī)則里只允許出現在令牌塊中。令牌分兩個家族本項目令牌--u-*ink、線條、表面、語義色以及畫布繪制所需的一切。暗色在:root淺色在:root[data-themelight]shadcn 令牌--background、--border、--input、--ring等shadcn 組件讀取的值。淺色在:root暗色在.dark。web/src/theme.ts 在切換主題時同時在html上設置data-theme與.dark類——這樣從 shadcn registry 取來的組件無需任何修改就能跟隨主題而畫布與語義色繼續(xù)讀取data-theme。主題選擇system/light/dark存放在瀏覽器localStorage的utopia.theme鍵中不經過后端initTheme還會監(jiān)聽系統偏好變化僅當用戶選擇system時。6只有兩個文件允許讀取令牌值。web/src/pages/graphVisuals.ts 通過getComputedStyle(document.documentElement).getPropertyValue(name)讀取畫布需要的令牌——canvas 無法解析var()且主題變化時需要重新讀取web/src/palette.ts 持有實體顏色屬于數據必須與 crates/utopia-store/src/palette.rs 中的ENTITY_PALETTE逐字節(jié)一致Rust 端有測試盯著改漏了會紅。一個細節(jié)很有說服力值被讀回來時是壓縮器處理過的形態(tài)#ffffff變成#fffrgba(176,120,20,0.6)變成#b0781499所以讀者函數必須解析每一種CSS 顏色拼寫一個只認識六位 hex 的解析器會靜默回退為灰色——這正是淺色主題下所有圖譜節(jié)點一度渲染成灰色團塊的原因。白色或黑色的陰影寫作rgba(var(--u-ink-rgb), α)/rgba(var(--u-ground-rgb), α)alpha 留在使用處alpha 描述層級三元組才隨主題切換rgba(0,0,0,0)是透明而非顏色允許通過。規(guī)則五狀態(tài)活在組件里hover、focus、active、disabled 與動效只在組件中定義一次頁面絕不書寫hover:、focus:、transition或duration-。具體要求每個控件都有可見的焦點環(huán)鍵盤可達性底線每個禁用控件都要變暗opacity-50且不響應交互每個 hover 進入動效為--u-fast120ms離開為--u-base260ms。具體而言頁面不渲染任何原始button、input、textarea或select而是使用殼層導出的Button、IconButton、Input、Textarea、Dropdown、SearchSelect、MenuSelect。項目里沒有任何原生select它的彈出層由操作系統繪制、無法主題化會在一頁里出現兩種下拉。小而有界的枚舉用Dropdown成百上千的選項本體的類、部署中的人用SearchSelect。確認操作走DangerConfirm或Dialog不用window.confirm懸停提示用Tooltip不用 span 上的裸title。style-guard.mjs對這條規(guī)則的執(zhí)行非常嚴格raw-control規(guī)則掃描button|textarea|select與input文件選擇框除外state-in-page規(guī)則匹配hover:、focus:、transition、duration-native-confirm規(guī)則禁止window.confirm/alertweb/scripts/style-guard.mjs。殼層組件在 web/src/ui/index.tsx 中實現例如Button用四個項目語義變體primary/secondary/ghost/danger映射到 shadcn 的default/outline/ghost/destructiveInput額外提供icon圖標槽與bare無皮形態(tài)裝在別的面里兩個 shadcn 沒有的能力。規(guī)則六面板是內容的槽前五條規(guī)則回答面板長什么樣第六條回答什么時候該有面板、周圍的東西怎么擺放。一個面板裝幾樣同類的東西——表格的行、列表的項。一組表單字段、一段正文、頁面主區(qū)域里的唯一內容都不需要面板。頁面本身就是它們的容器邊框、填充和圓角都在宣稱這是一個與周圍分離的對象花在單個對象上毫無信息量只會壓平周圍的層級。列表是一個帶行的面板不是一行一張卡片。每項一張卡片會在同一層級上擺出七八個盒子每張卡片同時充當面板和可點擊對象——槽因此獲得了它不該有的 hover 狀態(tài)。用行的話hover 屬于行hover:bg-surface-2即 web/src/ui/index.tsx 中 Table 的既有模式面板從不響應指針。記錄列表就是表格。如果每行攜帶同樣的字段成員、令牌、知識庫、規(guī)則就應該跨行閱讀同一事實必須落在同一列Table/Th/Td計數用u-num右對齊。替代方案每行堆一個名字、幾個芯片、一行點分隔的小字會讓同一事實在每行處于不同的水平位置無從比較。行內操作收斂為一個圖標。每一行都寫出完整動作文字會讓remove和deactivate成為頁面上最響亮的詞。行尾的單個圖標在指針停留該行時顯現REVEAL配合行上的group菜單打開期間保持可見它打開一個菜單DropdownMenu如會話列表或一個對話框FormDialog如成員表的鉛筆按鈕。只有一個顯然操作的行如停用賬戶上的 Restore可以直接顯示為按鈕。REVEAL的實際使用可見于 web/src/pages/Members.tsx、web/src/pages/Graph.tsx 等頁面。作用于面板內容的控件過濾、搜索、排序、分頁位于面板之外放在頁頭或面板上方——它們不是內容當過濾器把列表清空時面板必須呈現空狀態(tài)而不能順手帶走唯一改變過濾器的途徑。過濾器欄是一行搜索框在最前w-64帶放大鏡然后是下拉框。下拉標簽里的計數放在括號中Pending (3)而不是分隔點之后——點表示和計數不是第二個字段。以決策結尾的卡片Review 隊列的卡片把操作放進一個統一的頁腳形態(tài)CARD_ACTIONS操作位于左下角、貼著卡片左緣這樣一列卡片的每個決策都垂直對齊指針幾乎不用移動頁腳允許換行因為有些卡片有五六個選項破壞性操作放在最后因為最左的位置是指針最先到達的地方。解釋這張卡片的內容這對為什么在隊列里、當前階段、agent 的建議放在內容上方、先于決策被讀到而不是按鈕旁邊的角落里。面板也可以是一個動作的管轄范圍設置卡片SettingsCard的頁腳里放 Save它只提交邊框圈住的字段。邊框的價值就是回答這個按鈕發(fā)送什么——一頁這樣的卡片就是一頁獨立的小保存而不是一個底部單按鈕、悄悄提交整屏字段的長表單。只有一個這種卡片的頁面不需要它頁面本身就是邊界。設置頁等讀一列字段的頁面居中且限寬mx-auto max-w-4xl不拉伸到窗口。例外Graph 與 Ontology 上的浮動面板。它們是畫布上方的glass-strong表面職責是壓住畫布以便閱讀——這是另一個問題。這類浮動面板只展示、不編輯類、屬性、實體、事實的區(qū)間在這里閱讀一切變更創(chuàng)建、編輯、刪除、連接都打開FormDialog。對話框有一個標題和一個表單Cancel / Save 在右下破壞性操作單獨放在左下——通常是一個也可以是多個權重不同的操作成員的 Deactivate 切斷其整個部署的訪問而 Remove 只把它移出當前工作區(qū)。面板關閉鍵旁邊的鉛筆是進入編輯的途徑。專用對話框位于 web/src/pages/ontologyDialogs.tsx 與 web/src/pages/graphDialogs.tsx。這些規(guī)則如何被執(zhí)行style-guard 與 CIweb/scripts/style-guard.mjs 掃描web/src/**/*.{ts,tsx}命中任一規(guī)則即以非零退出碼失敗type-scale禁止 Tailwind 默認字號與任意 px 字號unknown-texttext-*只能是五檔字號、顏色令牌或對齊/換行工具其余沒有定義raw-palette禁止text-neutral-500、bg-rose-400等色板寫法raw-white白與黑不是令牌深色塊上的字用on-accent/on-dangertoken-by-hand禁止text-[var(--u-danger)]——令牌已經是 Tailwind 顏色radius圓角只能是四檔角色名rounded-none除外它表示頂到邊spacing禁止半檔與任意值間距raw-control頁面不得出現原生控件標簽state-in-page頁面不得寫 hover / focus / transition / durationraw-colour色值只允許出現在令牌塊例外是兩個讀者文件與測試 fixtureraw-shadow陰影只有u-lift/u-lift-strong兩檔native-confirm禁止window.confirm。幾個重要的執(zhí)行細節(jié)塊注釋被忽略所以規(guī)則可以在注釋中被引用和解釋raw-colour規(guī)則跳過 web/src/pages/graphVisuals.ts 與 web/src/palette.ts 兩個讀者文件以及*.test.ts(x)fixturesrc/components/ui/shadcn 生成層整體跳過守衛(wèi)中以VENDOR標記——它們按 Tailwind 原生刻度書寫由shadcn add重新生成不手工編輯但使用這些組件的頁面照常受檢spacing與raw-control、state-in-page等規(guī)則不作用于src/ui/組件目錄——組件的內部狀態(tài)本來就是組件的事存在一個遷移名單style-guard.baseline.json尚未遷移的頁面暫時豁免每遷一頁就刪一行名單只允許縮短新文件從第一個提交起就受檢。守衛(wèi)在 CI 中先于構建運行web任務的pnpm build腳本為node scripts/style-guard.mjs tsc --noEmit vite buildweb/package.json破壞規(guī)則的頁面無法合入。也可以單獨運行pnpm guard本地檢查。樣式從何而來殼層與 shadcn 的職責劃分web/src/ui/index.tsx 是殼層web/src/components/ui/ 是 shadcn。頁面按動作的重量調用殼層——Button variantprimary | secondary | ghost | danger——殼層再映射到 shadcn 的變體secondary變?yōu)?shadcn 的outlinedanger變?yōu)閐estructive。因此頁面在觀感遷移到 shadcn 時無需改動未來預設更換也不會改。無法使用組件的地方殼層導出類字符串buttonLike、chipLike。殼層保留而 shadcn 沒有的能力包括圖標槽與Input的bare形態(tài)、浮在圖譜畫布上的輸入框所需的實底填充、Status、MenuSelect、CARD_ACTIONS以及FormDialog的一或若干危險操作。新控件以全部五種狀態(tài)加入殼層后再使用新 shadcn 組件用shadcn add添加——絕不粘貼進來手工修改因為下一次add會覆蓋掉修改。實踐建議與延伸閱讀想快速驗證頁面是否合規(guī)在web/目錄運行pnpm guard或直接查看pnpm build中守衛(wèi)先于tsc與vite build的執(zhí)行順序。想理解令牌如何落到 Tailwind閱讀 web/src/styles.css 的theme塊字號、顏色、圓角全部在此定義一次與:root/:root[data-themelight]兩個令牌族。想觀察規(guī)則的實戰(zhàn)形態(tài)對比 web/src/pages/Members.tsx行內操作REVEAL、表格化列表、web/src/pages/Graph.tsx畫布浮動面板與 web/src/pages/ontologyDialogs.tsx / web/src/pages/graphDialogs.tsx只讀面板 表單對話框的分離。想了解數據色為何必須與后端一致對照 crates/utopia-store/src/palette.rs 的ENTITY_PALETTE、color_for_keyFNV-1a 確定性哈??邕M程穩(wěn)定與前端 web/src/palette.ts兩處配色必須逐字節(jié)相同并有測試守護。這六條規(guī)則的價值不在于把界面鎖死而在于讓界面語言本身成為可討論、可檢查、可演進的對象數值收斂為令牌、角色取代數字、狀態(tài)內聚于組件最終由一段不足 230 行的正則腳本守住整條 CI。對任何希望建立長期一致前端規(guī)范、并讓規(guī)范真正可執(zhí)行的項目而言Utopia 的這套文檔 令牌 守衛(wèi)組合是一個值得對照的實現樣本。贊分享后端前端人工智能RAG知識圖譜知識管理搜索引擎【免費下載鏈接】utopiaWorlds first open-source enterprise world model.項目地址https://gitcode.com/gh_mirrors/ont/utopia點擊查看免費下載相關推薦gbrain 設計系統解析從 Voice 規(guī)則、設計 Token 到服務端 SVG 圖表的完整設計規(guī)范gbrain 設計系統解析從 Voice 規(guī)則、設計 Token 到服務端 SVG 圖表的完整設計規(guī)范 gbrain 的 DESIGN.md 是管理后臺ad人工智能RAGAgent 記憶MCP 服務知識管理Zulip前端設計系統組件庫建設與設計規(guī)范制定Zulip前端設計系統組件庫建設與設計規(guī)范制定 Zulip作為開源團隊聊天工具其前端設計系統支撐著復雜的實時交互場景與多端適配需求。本文將從組件庫架構、設計即時通訊后端前端WebSocketLangflow 前端代碼質量規(guī)則深度解析cn()、設計令牌體系與狀態(tài)管理規(guī)范Langflow 前端代碼質量規(guī)則深度解析cn 、設計令牌體系與狀態(tài)管理規(guī)范 本文基于 Langflow 倉庫中的前端代碼質量規(guī)則目錄 code qualit人工智能大模型AI AgentRAG后端前端MCP 服務工作流自動化上一篇完整教程用 Taro UI 四步搭好一個電商小程序首頁下一篇Komorebi 五分鐘裝好 Linux 動態(tài)壁紙創(chuàng)作聲明:本文部分內容由AI輔助生成(AIGC),僅供參考