@wycm9527/morganite 0.0.0-stage → 0.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/CHANGELOG.md +171 -0
  2. package/LICENSE +33 -0
  3. package/README.md +62 -2
  4. package/bridge/base.css +138 -0
  5. package/bridge/echarts.d.ts +44 -0
  6. package/bridge/echarts.js +217 -0
  7. package/bridge/element-plus.css +785 -0
  8. package/bridge/fonts.css +124 -0
  9. package/bridge/icon-merge.d.ts +5 -0
  10. package/bridge/icon-merge.js +103 -0
  11. package/bridge/iconpark.config.ts +75 -0
  12. package/bridge/iconpark.css +29 -0
  13. package/bridge/react/ConfirmBar.tsx +43 -0
  14. package/bridge/react/EChart.tsx +45 -0
  15. package/bridge/react/PageHeader.tsx +24 -0
  16. package/bridge/react/SectionHeader.tsx +17 -0
  17. package/bridge/react/StatCard.tsx +33 -0
  18. package/bridge/react/TableSkeleton.tsx +11 -0
  19. package/bridge/react/TrendChart.tsx +8 -0
  20. package/bridge/recipes.css +444 -0
  21. package/bridge/shadcn-globals.css +6 -0
  22. package/bridge/shadcn.css +238 -0
  23. package/bridge/vue/ConfirmBar.vue +23 -0
  24. package/bridge/vue/EChart.vue +43 -0
  25. package/bridge/vue/KitchenSink.vue +507 -0
  26. package/bridge/vue/PageHeader.vue +23 -0
  27. package/bridge/vue/SectionHeader.vue +15 -0
  28. package/bridge/vue/StatCard.vue +33 -0
  29. package/bridge/vue/TableSkeleton.vue +14 -0
  30. package/bridge/vue/TrendChart.vue +11 -0
  31. package/bridge/vue/confirm.js +18 -0
  32. package/bridge/vue/inlineConfirm.js +21 -0
  33. package/design-system/AUDIT.md +277 -0
  34. package/design-system/DESIGN.md +176 -0
  35. package/design-system/contrast.md +71 -0
  36. package/design-system/preview/drawer.html +38 -0
  37. package/design-system/preview/form.html +40 -0
  38. package/design-system/preview/index.html +21 -0
  39. package/design-system/preview/preview.css +190 -0
  40. package/design-system/preview/preview.local.css +17 -0
  41. package/design-system/preview/shell.html +50 -0
  42. package/design-system/scope-map.json +4 -0
  43. package/design-system/style-dictionary.config.mjs +172 -0
  44. package/design-system/theme-map.json +16 -0
  45. package/design-system/themes/dark/THEME.md +29 -0
  46. package/design-system/themes/dark/tokens/semantic.tokens.json +354 -0
  47. package/design-system/token-board.html +137 -0
  48. package/design-system/tokens/primitives.tokens.json +1898 -0
  49. package/design-system/tokens/semantic.tokens.json +1080 -0
  50. package/design-system.json +217 -0
  51. package/migration/roles.json +743 -0
  52. package/package.json +82 -4
  53. package/templates/AGENTS.md +13 -0
  54. package/templates/KitchenSink.tsx +179 -0
  55. package/templates/accept.config.mjs +28 -0
  56. package/templates/entry-css.css +6 -0
  57. package/templates/entry-element-plus.css +9 -0
  58. package/templates/entry-shadcn.css +7 -0
  59. package/templates/notes-css.md +4 -0
  60. package/templates/notes-element-plus.md +7 -0
  61. package/templates/notes-shadcn.md +7 -0
package/package.json CHANGED
@@ -1,6 +1,84 @@
1
1
  {
2
2
  "name": "@wycm9527/morganite",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.3.4",
4
+ "description": "Morganite 玫瑰金 · 中后台设计系统种子:Ant Design Pro v6 底座,玫瑰金 #B98D44 金底白字 + antd 纯灰骨架,DTCG token(亮 / 暗)、DESIGN 规范、Element Plus / shadcn/ui / ECharts / IconPark 桥接、页面骨架配方与 Vue / React 配方组件,自带数字字体 D-DIN。纯数据包:接入 / 更新由 design-system-adopter skill 驱动(识别 design-system.json)。",
5
+ "license": "(MIT AND OFL-1.1)",
6
+ "type": "module",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/WYCM9527/Design-System.git",
10
+ "directory": "morganite/seeds/morganite"
11
+ },
12
+ "keywords": [
13
+ "design-system",
14
+ "design-tokens",
15
+ "dtcg",
16
+ "ant-design",
17
+ "element-plus",
18
+ "shadcn",
19
+ "tailwind",
20
+ "echarts"
21
+ ],
22
+ "engines": {
23
+ "node": ">=22"
24
+ },
25
+ "files": [
26
+ "bridge",
27
+ "design-system",
28
+ "!design-system/dist",
29
+ "!design-system/preview/shots",
30
+ "!design-system/preview/static",
31
+ "design-system.json",
32
+ "templates",
33
+ "migration",
34
+ "README.md",
35
+ "CHANGELOG.md"
36
+ ],
37
+ "exports": {
38
+ "./package.json": "./package.json",
39
+ "./design-system/*": "./design-system/*",
40
+ "./bridge/*": "./bridge/*",
41
+ "./echarts": {
42
+ "default": "./bridge/echarts.js",
43
+ "types": "./bridge/echarts.d.ts"
44
+ },
45
+ "./iconpark.config": "./bridge/iconpark.config.ts",
46
+ "./icon-merge": {
47
+ "default": "./bridge/icon-merge.js",
48
+ "types": "./bridge/icon-merge.d.ts"
49
+ },
50
+ "./vue/*": "./bridge/vue/*",
51
+ "./react/*": "./bridge/react/*.tsx"
52
+ },
53
+ "peerDependencies": {
54
+ "@icon-park/vue-next": "^1.4.0",
55
+ "echarts": "^5.0.0 || ^6.0.0",
56
+ "element-plus": "^2.7.0",
57
+ "react": "^18.0.0 || ^19.0.0",
58
+ "vue": "^3.4.0"
59
+ },
60
+ "peerDependenciesMeta": {
61
+ "@icon-park/vue-next": {
62
+ "optional": true
63
+ },
64
+ "echarts": {
65
+ "optional": true
66
+ },
67
+ "element-plus": {
68
+ "optional": true
69
+ },
70
+ "react": {
71
+ "optional": true
72
+ },
73
+ "vue": {
74
+ "optional": true
75
+ }
76
+ },
77
+ "homepage": "https://github.com/WYCM9527/Design-System/tree/main/morganite#readme",
78
+ "bugs": {
79
+ "url": "https://github.com/WYCM9527/Design-System/issues"
80
+ },
81
+ "publishConfig": {
82
+ "access": "public"
83
+ }
84
+ }
@@ -0,0 +1,13 @@
1
+ # {{PROJECT}} · Agent 规则
2
+
3
+ ## 设计系统(design-system-steward 三行规则)
4
+
5
+ 1. 所有 UI 修改先阅读 `design-system/DESIGN.md` 与当前 Scope/Theme 的登记和说明,只使用已管理的设计决定。
6
+ 2. 若需求需要新增、修改或跨页面复用的视觉决定,先提出提案;确认后先更新设计系统源、构建并运行 Guard,再实现页面。
7
+ 3. 不要手改 `design-system/dist/`;一次性差异先作为 Drift 或实验处理,不自动升级为规范。
8
+
9
+ ## 项目接线({{SYSTEM_NAME}} · {{STACK_LABEL}})
10
+
11
+ {{STACK_NOTES}}
12
+ - **上游快照只读**:`design-systems/{{SYSTEM_ID}}/` 是设计系统的上游快照,永不手改(改了 `ds.mjs status` 会报警);项目需要的差异写在自己的 `app.css` / 工作副本 `design-system/`(scope / 豁免),需要共享的向上游提提案。配方不够用时**不在页面上补样式**;效果预览里有、配方里没有的样式也先提案,不照着预览另写一套。
13
+ - **验收**:改完 UI 运行 `npm run build` 与 `npx {{ACCEPT_COMMAND}}`(页面 / 组件 / 三端 / 焦点;清单 `accept.config.mjs` 按种子 `templates/accept.config.mjs` 建,已批准的对比度例外写在它的 `APPROVED_CONTRAST`,需要 `@wycm9527/citrine-tools` ≥ 1.2.0);steward `guard.mjs --project $PWD` 应为 `current`,`status.mjs` 页面字面量清零;对比度基线用 `check-contrast.mjs --system design-system`。
@@ -0,0 +1,179 @@
1
+ // 组件走查页模板(shadcn/ui 项目):核心组件的静息 / 选中 / 禁用 / 出错状态铺在一页,配方层公共类同页对照,供 citrine-accept components 做 hover / focus 走查。
2
+ // 用法:拷进项目(如 src/pages/KitchenSink.tsx),挂到 /kitchen 路由,accept.config.mjs 的 KITCHEN 填 '#/kitchen'。它 import 项目里的 shadcn 组件(默认别名 @/components/ui/*,
3
+ // 按项目实际调整)与包里的配方组件。浮层触发器带 data-ks-open(走查脚本逐个点开),弹层触发器带 data-ks-modal;每个 <section class="ks" data-ks="…"> 是一组(≥ 10 组走查脚本才认为页面就绪)。
4
+ import * as React from 'react'
5
+ import { Info, MoreHorizontal, Plus, Search } from 'lucide-react'
6
+ import { Button } from '@/components/ui/button'
7
+ import { Badge } from '@/components/ui/badge'
8
+ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
9
+ import { Input } from '@/components/ui/input'
10
+ import { Textarea } from '@/components/ui/textarea'
11
+ import { Label } from '@/components/ui/label'
12
+ import { Checkbox } from '@/components/ui/checkbox'
13
+ import { Switch } from '@/components/ui/switch'
14
+ import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group'
15
+ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'
16
+ import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
17
+ import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, DialogClose } from '@/components/ui/dialog'
18
+ import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger } from '@/components/ui/alert-dialog'
19
+ import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger } from '@/components/ui/dropdown-menu'
20
+ import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'
21
+ import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'
22
+ import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'
23
+ import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert'
24
+ import { Skeleton } from '@/components/ui/skeleton'
25
+ import { Progress } from '@/components/ui/progress'
26
+ import { Separator } from '@/components/ui/separator'
27
+ import { StatCard } from '@wycm9527/morganite/react/StatCard'
28
+ import { TableSkeleton } from '@wycm9527/morganite/react/TableSkeleton'
29
+ import { PageHeader } from '@wycm9527/morganite/react/PageHeader'
30
+ import { SectionHeader } from '@wycm9527/morganite/react/SectionHeader'
31
+
32
+ function Sec({ id, title, children }: { id: string; title: string; children: React.ReactNode }) {
33
+ return (
34
+ <section className="ks card-block" data-ks={id}>
35
+ <div className="card-head"><h2>{title}</h2></div>
36
+ <div className="ks-body">{children}</div>
37
+ </section>
38
+ )
39
+ }
40
+
41
+ export function KitchenSink() {
42
+ const [checked, setChecked] = React.useState(true)
43
+ return (
44
+ <>
45
+ <PageHeader title="组件走查" subtitle="shadcn/ui 核心组件 × Morganite 桥接 · 亮 / 暗两种模式下强制 hover / focus 扫描" />
46
+
47
+ <Sec id="page-head" title="页头与板块标题(配方组件 PageHeader / SectionHeader)">
48
+ <PageHeader title="采购申请" subtitle="全部部门的申请,默认按提交时间倒序" actions={<><Button variant="outline">导出</Button><Button>新建申请</Button></>} />
49
+ <Separator className="my-4" />
50
+ <PageHeader title="CG-20260910-0001" status={<span className="status info">采购中</span>} actions={<Button variant="outline">返回</Button>} />
51
+ <Separator className="my-4" />
52
+ <SectionHeader title="经营概览" actions={<Button variant="outline">导出日报</Button>} />
53
+ </Sec>
54
+
55
+ <Sec id="buttons" title="按钮">
56
+ <div className="row">
57
+ <Button>主操作</Button><Button variant="secondary">次要</Button><Button variant="outline">描边</Button><Button variant="ghost">quiet</Button><Button variant="destructive">删除</Button>
58
+ <Button disabled>禁用</Button><Button size="sm">小号</Button><Button size="lg">大号</Button><Button size="icon" aria-label="更多"><MoreHorizontal /></Button><Button><Plus />带图标</Button>
59
+ </div>
60
+ </Sec>
61
+
62
+ <Sec id="badges" title="徽标与状态胶囊">
63
+ <div className="row">
64
+ <Badge variant="secondary">次要</Badge><Badge variant="outline">描边</Badge><Badge variant="destructive">危险</Badge>
65
+ <span className="status success">已完成</span><span className="status warning">待审批</span><span className="status error">已取消</span><span className="status info">采购中</span><span className="status neutral">草稿</span><span className="badge brand">管理员</span>
66
+ </div>
67
+ </Sec>
68
+
69
+ <Sec id="inputs" title="输入">
70
+ <div className="grid2">
71
+ <div className="field"><Label htmlFor="k-name">名称</Label><Input id="k-name" placeholder="请输入供应商名称" /></div>
72
+ <div className="field"><Label htmlFor="k-search">搜索</Label><div className="with-icon"><Search className="i-icon--sm i-icon--muted" aria-hidden="true" /><Input id="k-search" placeholder="申请编号 / 供应商 / 申请人" /></div></div>
73
+ <div className="field"><Label htmlFor="k-disabled">禁用</Label><Input id="k-disabled" disabled value="不可编辑" readOnly /></div>
74
+ <div className="field"><Label htmlFor="k-invalid">出错</Label><Input id="k-invalid" aria-invalid defaultValue="abc" /><span className="help err">请输入 11 位手机号</span></div>
75
+ <div className="field span2"><Label htmlFor="k-textarea">备注</Label><Textarea id="k-textarea" placeholder="选填,最多 300 字" /></div>
76
+ </div>
77
+ </Sec>
78
+
79
+ <Sec id="choices" title="勾选 / 开关 / 单选">
80
+ <div className="row">
81
+ <label className="inline"><Checkbox defaultChecked aria-label="已勾选" /> 已勾选</label>
82
+ <label className="inline"><Checkbox aria-label="未勾选" /> 未勾选</label>
83
+ <label className="inline"><Checkbox disabled aria-label="禁用" /> 禁用</label>
84
+ <label className="inline"><Switch checked={checked} onCheckedChange={setChecked} aria-label="开关" /> 开关</label>
85
+ <label className="inline"><Switch disabled aria-label="禁用开关" /> 禁用</label>
86
+ <RadioGroup defaultValue="a" className="inline-radios" aria-label="优先级">
87
+ <label className="inline"><RadioGroupItem value="a" id="r-a" /> 普通</label>
88
+ <label className="inline"><RadioGroupItem value="b" id="r-b" /> 紧急</label>
89
+ </RadioGroup>
90
+ </div>
91
+ </Sec>
92
+
93
+ <Sec id="select" title="下拉选择">
94
+ <div className="row">
95
+ <Select defaultValue="all">
96
+ <SelectTrigger className="w-44" aria-label="申请状态" data-ks-open data-ks-type="select"><SelectValue /></SelectTrigger>
97
+ <SelectContent><SelectItem value="all">全部状态</SelectItem><SelectItem value="pending">待审批</SelectItem><SelectItem value="done">已完成</SelectItem><SelectItem value="cancel" disabled>已取消</SelectItem></SelectContent>
98
+ </Select>
99
+ <DropdownMenu>
100
+ <DropdownMenuTrigger asChild><Button variant="outline" data-ks-open data-ks-type="dropdown">更多操作</Button></DropdownMenuTrigger>
101
+ <DropdownMenuContent><DropdownMenuLabel>申请</DropdownMenuLabel><DropdownMenuItem>转交</DropdownMenuItem><DropdownMenuItem>催办</DropdownMenuItem><DropdownMenuSeparator /><DropdownMenuItem variant="destructive">撤回申请</DropdownMenuItem></DropdownMenuContent>
102
+ </DropdownMenu>
103
+ <Popover>
104
+ <PopoverTrigger asChild><Button variant="outline" data-ks-open data-ks-type="popover">口径说明</Button></PopoverTrigger>
105
+ <PopoverContent><p className="text-sm">报表按提交日期范围统计;工作台按通过时间统计,两者口径不同。</p></PopoverContent>
106
+ </Popover>
107
+ <Tooltip><TooltipTrigger asChild><Button variant="ghost" size="icon" aria-label="说明"><Info /></Button></TooltipTrigger><TooltipContent>悬停提示</TooltipContent></Tooltip>
108
+ </div>
109
+ </Sec>
110
+
111
+ <Sec id="tabs" title="标签页">
112
+ <Tabs defaultValue="overview">
113
+ <TabsList><TabsTrigger value="overview">概览</TabsTrigger><TabsTrigger value="logs">日志</TabsTrigger><TabsTrigger value="settle" disabled>结算</TabsTrigger></TabsList>
114
+ <TabsContent value="overview"><p className="muted">概览内容</p></TabsContent>
115
+ <TabsContent value="logs"><p className="muted">日志内容</p></TabsContent>
116
+ </Tabs>
117
+ </Sec>
118
+
119
+ <Sec id="table" title="表格(shadcn Table + 配方层胶囊)">
120
+ <Table>
121
+ <TableHeader><TableRow><TableHead>申请编号</TableHead><TableHead>供应商</TableHead><TableHead className="text-right">金额</TableHead><TableHead>状态</TableHead><TableHead>操作</TableHead></TableRow></TableHeader>
122
+ <TableBody>
123
+ {[['CG-20260908-0412', '蓝海电子', '¥156.70', 'success', '已完成'], ['CG-20260908-0411', '云帆物流', '¥47.80', 'warning', '待审批'], ['CG-20260908-0410', '恒信办公', '¥1,225.90', 'error', '已取消']].map(([no, m, amt, tone, st]) => (
124
+ <TableRow key={no}><TableCell><a className="link mono" href="#/orders">{no}</a></TableCell><TableCell>{m}</TableCell><TableCell className="text-right num">{amt}</TableCell><TableCell><span className={`status ${tone}`}>{st}</span></TableCell><TableCell><a className="act" href="#/orders">详情</a><button className="act" type="button">转交</button><button className="act danger" type="button">取消</button></TableCell></TableRow>
125
+ ))}
126
+ </TableBody>
127
+ </Table>
128
+ </Sec>
129
+
130
+ <Sec id="overlays" title="弹窗 / 确认">
131
+ <div className="row">
132
+ <Dialog>
133
+ <DialogTrigger asChild><Button variant="outline" data-ks-modal="dialog">打开弹窗</Button></DialogTrigger>
134
+ <DialogContent>
135
+ <DialogHeader><DialogTitle>转交申请</DialogTitle><DialogDescription>选择一名审批人接手该申请。</DialogDescription></DialogHeader>
136
+ <div className="field"><Label htmlFor="d-rider">审批人</Label><Input id="d-rider" placeholder="搜索成员" /></div>
137
+ <DialogFooter><DialogClose asChild><Button variant="outline">取消</Button></DialogClose><Button>确认转交</Button></DialogFooter>
138
+ </DialogContent>
139
+ </Dialog>
140
+ <AlertDialog>
141
+ <AlertDialogTrigger asChild><Button variant="destructive" data-ks-modal="alert">删除供应商</Button></AlertDialogTrigger>
142
+ <AlertDialogContent>
143
+ <AlertDialogHeader><AlertDialogTitle>确认删除「恒信办公」?</AlertDialogTitle><AlertDialogDescription>删除后不可恢复,历史申请仍会保留。</AlertDialogDescription></AlertDialogHeader>
144
+ <AlertDialogFooter><AlertDialogCancel>取消</AlertDialogCancel><AlertDialogAction className="bg-destructive text-white hover:bg-destructive/90">确认删除</AlertDialogAction></AlertDialogFooter>
145
+ </AlertDialogContent>
146
+ </AlertDialog>
147
+ </div>
148
+ </Sec>
149
+
150
+ <Sec id="feedback" title="提示 / 进度 / 骨架">
151
+ <div className="stack">
152
+ <Alert><Info /><AlertTitle>今日有 7 家供应商资质即将过期</AlertTitle><AlertDescription>请在到期前完成复审。</AlertDescription></Alert>
153
+ <Alert variant="destructive"><Info /><AlertTitle>提交失败</AlertTitle><AlertDescription>网络超时,请重试。</AlertDescription></Alert>
154
+ <Progress value={62} aria-label="进度 62%" />
155
+ <div className="row"><Skeleton className="h-4 w-40" /><Skeleton className="h-4 w-24" /><Skeleton className="size-9 rounded-full" /></div>
156
+ <TableSkeleton rows={2} cols={[160, 120, 100]} />
157
+ </div>
158
+ </Sec>
159
+
160
+ <Sec id="cards" title="卡片与统计卡">
161
+ <div className="stats">
162
+ <StatCard label="本月申请" value="12,480" delta="+8.2%" note="较昨日" />
163
+ <StatCard label="取消率" value="1.8%" delta="-0.4%" up={false} positive hint="按下单时间统计" />
164
+ <StatCard label="GMV(元)" value="¥386,210" />
165
+ <Card><CardHeader><CardTitle>shadcn Card</CardTitle><CardDescription>卡片描述文字</CardDescription></CardHeader><CardContent><p className="text-sm">卡片内容。</p></CardContent></Card>
166
+ </div>
167
+ <Separator className="my-4" />
168
+ <div className="row">
169
+ <span className="chip">状态:待审批 <button type="button" className="x" aria-label="移除条件 状态">×</button></span>
170
+ <a className="go" href="#/orders">查看全部 <span aria-hidden="true">›</span></a>
171
+ </div>
172
+ </Sec>
173
+
174
+ <Sec id="recipes-form" title="配方层表单页脚">
175
+ <div className="form-foot"><Button variant="ghost">取消</Button><Button variant="outline">保存草稿</Button><Button>提交申请</Button></div>
176
+ </Sec>
177
+ </>
178
+ )
179
+ }
@@ -0,0 +1,28 @@
1
+ // {{PROJECT}} 的验收清单(@wycm9527/citrine-tools 的 citrine-accept 读取;APPROVED_CONTRAST 要 citrine-tools ≥ 1.2.0,品牌金审计要 ≥ 1.3.0)。
2
+ // 演示参数放在 # 之前(?theme=dark、?state=empty),页面用 location.search 读;名字 → 「?演示参数#路由」。
3
+ // 亮暗两遍:工具用 ?theme=light|dark 打开每个页面——项目要在首屏把它落成 <html class="dark">(先读 URL 再读 localStorage,避免闪烁)。
4
+ export const DARK_SELECTOR = 'html.dark';
5
+ export const PAGES = [
6
+ ['dashboard', '#/'],
7
+ // ['orders', '#/orders'], ['orders-empty', '?state=empty#/orders'], …
8
+ ];
9
+ export const DEFAULT_QUERY = {}; // 每个页面缺省带的参数(如 { role: 'admin' })
10
+ export const KITCHEN = '#/kitchen'; // 全组件走查页:Element 项目挂种子的 @wycm9527/morganite/vue/KitchenSink.vue,shadcn 项目拷 templates/KitchenSink.tsx;null 会跳过 components 走查
11
+ // 三端:窄屏档按 layout.breakpoint.narrow(992)侧栏折叠,手机档侧栏离屏 + 汉堡可开合;各档都不允许文档级横向溢出。
12
+ // 走查页含固定宽度的组件面板,不属于「手机可用」目标,可用档位自己的 pages 把它剔出手机档
13
+ export const NARROW = {
14
+ widths: [{ name: 'narrow', width: 992, expect: 'collapsed' }, { name: 'mobile', width: 390, expect: 'offcanvas' }],
15
+ pages: [['dashboard', '#/']]
16
+ };
17
+ export const FOCUS = { pages: { dashboard: '#/' }, steps: 80, inputBorder: true }; // Tab 焦点遍历;输入类控件按 DESIGN 只把边线换成 border.focus、不加外环,焦点检查按边线认
18
+ // 品牌金审计:判色范围与允许出现金色的位置登记在设计系统身份文件 design-system.json 的 accept.brand(依据 DESIGN;要 citrine-tools ≥ 1.3.0);
19
+ // 本项目另有合法位置时追加在这里并写明理由,如 ['.welcome-banner']
20
+ export const BRAND_ALLOW = [];
21
+ // 已批准的对比度例外:Morganite AUDIT「对比度基线」已登记例外的镜像(系统改了例外,这里跟着改;不要为了过验收在这里加新例外)。
22
+ // citrine-tools 内置的 Citrine 例外按 design-system/.adopter.json 的 system 只对 Citrine 项目生效,这里不用写 CITRINE_APPROVED
23
+ export const APPROVED_CONTRAST = [
24
+ { fg: '#FFFFFF', bg: '#B98D44', why: '金底白字 3.02:1:主按钮、分页当前页、侧栏当前项、选中日、主色徽标、深色 / 勾选标签、当前步骤' },
25
+ { fg: 'rgba(0, 0, 0, 0.45)', why: '亮色占位符(占位符底线 3:1)' },
26
+ { fg: 'rgba(255, 255, 255, 0.45)', why: '暗色占位符(占位符底线 3:1)' },
27
+ { fg: '#B98D44', minRatio: 4.2, why: '暗色链接 / 文字按钮压在悬停行、气泡上约 4.3:1' }
28
+ ];
@@ -0,0 +1,6 @@
1
+ /* 样式入口(Morganite 玫瑰金 · 纯 CSS 栈)。顺序:设计系统构建产物 → 基础桥接 → 项目补充。
2
+ 构建产物与桥接的路径由 design-system-adopter 按来源解析后填入(npm 安装是 <npm 包名>/bridge,文件夹快照是相对 design-systems/<id>/bridge 的路径)。
3
+ 除本文件与 app.css 外,页面样式只引用 token 变量(--color-* / --spacing-* / --space-* / --text-* / --control-* / --radius-* / --border-* / --elevation-*),不写色值与像素字面量。 */
4
+ @import "{{DIST}}/index.css";
5
+ @import "{{BRIDGE}}/base.css";
6
+ @import "./app.css";
@@ -0,0 +1,9 @@
1
+ /* 样式入口(Morganite 玫瑰金 · Vue 3 + Element Plus)。顺序:组件库基础样式 → 设计系统构建产物 → 桥接(组件库 / 图标)→ 配方层(页面骨架与页面形态)→ 项目补充。
2
+ 桥接与构建产物的路径由 design-system-adopter 按来源(npm 包 / 文件夹快照)解析后填入。不引 base.css:Element 自己重置了基础元素,桥接补齐其余部分(标题字号 / 行高 / 字重、按钮继承字体)。
3
+ 不要再引 Element 的 dark css-vars(另一模式由 dist/themes/*.css 生效);除本文件与 app.css 外,页面样式只引用 token 变量。 */
4
+ @import "element-plus/dist/index.css";
5
+ @import "{{DIST}}/index.css";
6
+ @import "{{BRIDGE}}/element-plus.css";
7
+ @import "{{BRIDGE}}/iconpark.css";
8
+ @import "{{BRIDGE}}/recipes.css";
9
+ @import "./app.css";
@@ -0,0 +1,7 @@
1
+ /* 样式入口(Morganite 玫瑰金 · React + Tailwind v4 + shadcn/ui)。顺序:Tailwind → 设计系统构建产物 → 桥接(契约变量 + 组件级接管)→ 配方层 → 项目补充。
2
+ 桥接与构建产物的路径由 design-system-adopter 按来源(npm 包 / 文件夹快照)解析后填入。桥接从 Citrine 拷入、按本系统 token 重新接线,接入前先看 design-system/AUDIT.md「桥接缺口」。 */
3
+ @import "tailwindcss";
4
+ @import "{{DIST}}/index.css";
5
+ @import "{{BRIDGE}}/shadcn.css";
6
+ @import "{{BRIDGE}}/recipes.css";
7
+ @import "./app.css";
@@ -0,0 +1,4 @@
1
+ - **样式来源**:样式入口按顺序引入 `design-system/dist/index.css`(token:默认模式 + 其他模式 delta)→ 基础桥接 `{{BRIDGE}}/base.css`(body / 标题 / 链接 / 表单控件 / 焦点 / 减少动态效果)→ 项目补充 `app.css`。桥接是上游只读快照 / npm 包,不改;页面样式与 `app.css` 只引用 token 变量(`--color-*`、`--spacing-*`、`--space-*`、`--text-*`、`--control-*`、`--radius-*`、`--border-*`、`--elevation-*`、`--motion-*`、`--layer-*`),不写色值与像素字面量。像素只允许出现在按内容定的宽度(表格列宽、筛选控件宽度)上。
2
+ - **组件怎么写**:按 `design-system/DESIGN.md`「组件配方」表逐个角色取变量——主按钮 `--color-action-primary` + `--color-text-on-primary`,高度 `--control-height-md`,圆角按容器层级取 `--radius-*`;卡片 `--color-bg-surface` + `--color-border-default` + `box-shadow: 0 var(--elevation-card-y) var(--elevation-card-blur) var(--elevation-card-color)`;状态胶囊 `--color-status-<x>` 配 `--color-status-<x>-bg`。配方表里写「待确认」的行接入前先确认。
3
+ - **另一模式(如暗色)**:按 `design-system/theme-map.json` 的激活方式切换(class 激活 = `<html class="dark">`,data 属性激活 = `<html data-theme="dark">`,媒体激活 = 跟随系统偏好、无需切换代码)。首屏前读 localStorage / `?theme=` 避免闪烁;运行时所有者在 `themes/<id>/THEME.md` 里登记。
4
+ - **组件库**:这个栈只用基础桥接。项目用 Element Plus 或 shadcn/ui 时改接对应的栈(`ds.mjs init --stack element-plus` / `shadcn`,带逐组件接管的桥接);其他组件库(Ant Design 等)的默认外观不会自动跟随 token——需要一份逐组件接管的桥接,那是系统层工作,向设计系统维护者提提案,不在页面上就地补样式。
@@ -0,0 +1,7 @@
1
+ - **样式来源**:样式入口按顺序引入 Element Plus → `design-system/dist/index.css` → 桥接 `{{BRIDGE}}/{element-plus.css, iconpark.css}` → 配方层 `{{BRIDGE}}/recipes.css` → 项目补充 `app.css`(不引 `base.css`,桥接自带标题字号 / 行高 / 字重、按钮继承字体这些基础规则)。桥接与配方是上游只读快照 / npm 包,不改;页面 `<style scoped>` 与 `app.css` 只引用 token 变量(`--color-*`、`--spacing-*`、`--space-*`、`--text-*`、`--control-*`、`--radius-*`、`--border-*`、`--elevation-*`),不写色值与像素字面量。像素只允许出现在按内容定的宽度(表格列宽)上。
2
+ - **桥接按 DESIGN 与效果预览逐组件接管**:Element 的 `--el-*` 变量与写死的主色 / 焦点 / 色表都接到语义 token 上,尺寸、字号、圆角、选中态与效果预览一致(分段类是灰轨道上的白块,其余选中走主色系);已在 Element Plus 2.14 上用完整项目实测过(种子仓库 `morganite/testbed/mall-ops`)。接入后挂走查页 `{{IMPORT}}/vue/KitchenSink.vue` 到 `/kitchen`,亮 / 暗两种模式下逐组件看一遍 hover / focus / disabled。
3
+ - **页面骨架与页面形态用配方类,不自己重写**(`recipes.css`):每页自上而下是顶栏 → 页头 → 可选标签 / 筛选 → 业务内容。壳层 `.app/.sidebar/.topbar`(顶栏左侧统一放 `el-breadcrumb`,工作台也是,分隔符由桥接画成细箭头、`separator="/"` 照传;头像区 `<button class="user">` + `.avatar`)、页头用配方组件 `PageHeader`(`title` / `subtitle`,`#status` 放标题旁的状态胶囊,`#actions` 放页面级操作;每个一级页面一个,副标题没必要就不传),看板页在 H1 下用 `SectionHeader` 分板块(H2 + 右侧只管这一板块的筛选),次要分组才用小标签 `.section-label`;块间距全由内容区 `.content` 的 gap 给,页面不自己加 margin-top;看板 `.board` + 看板卡 `<el-card class="flat panel">`、两栏 `.two-col`、纵向堆叠 `.stack`、卡片栅格 `.card-grid`、设置行 `.setting`、横向表单 `.hform`、附件行 `.file-row`、登录页 `.login*`、图例 `.legend` / 占比列表 `.alloc-list` / 目标进度 `.goals`(分类色 `.c1–.c6`)、筛选栏 `.filter`(控件宽度 `.w-search` / `.w-select` / `.w-date`)、状态胶囊 `.status.*`、操作胶囊 `.act`(一组放进 `.act-group`)、表单页 `.form-page`(只给单列竖向表单)、统计卡 `.stats`;配方组件在 `{{IMPORT}}/vue/*`(PageHeader / SectionHeader / StatCard / EChart / TrendChart / TableSkeleton / ConfirmBar),图表主题来自 `{{IMPORT}}/echarts`(运行时读 token);柱子端头由 EChart 容器套 `withBarEnds`,不经容器直接 `echarts.init` 的图表,option 自己先过 `withBarEnds`。
4
+ - **Element 用法约定**:表格放进 `<el-card class="flat">` 贴边(首尾列自动让出卡片内边距),勾选列宽 48;卡片顶部的 `el-tabs` 自动当卡片标题头:标签与卡片内边距对齐、与带标题的卡片头同高、底线贯穿卡片,不用另加类;直接放在内容区、只切换下方内容的 `el-tabs`(pane 留空)下边距自动归零,只剩一个标签时整个标签栏 `v-if` 掉;步骤条用 `finish-status="success"`(已完成显示勾)、不加 `align-center`(桥接排成效果预览的横排);通栏按钮 `class="is-block"`;弹窗 `class="is-sm"`(确认)/ `"is-md"`(表单)并 `append-to-body`;金额、日期列 `class-name="num"`(正文字体 + 等宽数字),单号包 `.mono`;统计数字用 `el-statistic` 或 `StatCard`(D-DIN-PRO)。
5
+ - **图标**:IconPark 在根组件 `setup()` 里 `IconProvider({ ...DEFAULT_ICON_CONFIGS, ...iconParkDefaults })`(`{{IMPORT}}/iconpark.config`),尺寸 / 颜色用 `.i-icon--*` 类,不在图标上写 size / fill / stroke-width;`main.js` 里 `app.mount()` 之后调一次 `mergeIcons()`(`{{IMPORT}}/icon-merge`)。描边由桥接按屏幕上的 `icon.stroke.width`(1.4px)画,`mergeIcons()` 把每只图标的多段描边合并后一次上色——不调的话,半透明的图标色在描边交叠处会叠深一块。
6
+ - **页面状态与权限**(DESIGN「页面状态与权限」):加载用 `TableSkeleton`(列宽与真实表格一致),空用 `.empty`(插图 + 一句说明 + 至多一个主操作),区域出错用 `.error-box` + 重试按钮,无权限的地址进 403 结果页 `.result`;按角色禁用的按钮外包一层 `<span>` 挂 `el-tooltip` 写明缺的权限(禁用按钮不触发悬停),只读角色用只读态。
7
+ - **另一模式**:按 `design-system/theme-map.json` 的激活方式切换(class 激活 = `<html class="dark">`);不要引 Element 的 dark css-vars。
@@ -0,0 +1,7 @@
1
+ - **样式来源**:`globals.css` 按顺序引入 Tailwind → `design-system/dist/index.css` → 桥接 `{{BRIDGE}}/shadcn.css`(契约变量 `--primary` 等指向语义 token、`@theme inline`、按 `data-slot` 的组件级接管)→ 配方层 `{{BRIDGE}}/recipes.css` → 项目补充 `app.css`。页面里的 Tailwind 类只用主题里已经映射到 token 的颜色 / 字号 / 间距,不写任意值(`bg-[#…]`、`p-[13px]`)。
2
+ - **shadcn 没有的组件用配方**:分页 `.pagination` + `.page`、中性类别标签 `.tag`、状态胶囊 `.status.*`、顶栏搜索 `<label class="search">` + 图标 + input,样式与效果预览一致,页面不要自己写一套。
3
+ - **桥接是从 Citrine 拷来的起点**:契约变量的映射对任何系统都成立,但组件级接管里带着 Citrine 的品牌决定(`Button variant="link"` 不用、`Badge` 默认色不用、Tabs 选中用灰轨道上的白块、控件三档高度接 antd 的 24 / 32 / 40)。第一次接入前照 `design-system/AUDIT.md`「桥接缺口」补齐缺的 token 或删掉对应规则;配方组件在 `{{IMPORT}}/react/*`(PageHeader / SectionHeader / StatCard / EChart / TrendChart / TableSkeleton / ConfirmBar):每页自上而下是顶栏(左侧 `.crumbs` 面包屑,分隔符由配方画成细箭头)→ `PageHeader`(每个一级页面一个 H1,`subtitle` 没必要就不传,`status` 放标题旁的状态胶囊,`actions` 放页面级操作)→ 可选标签 / 筛选 → 业务内容,看板页在 H1 下用 `SectionHeader` 分板块,块间距全由内容区 `.content` 的 gap 给;不经 EChart 容器直接 `echarts.init` 的图表,option 先过 `{{IMPORT}}/echarts` 的 `withBarEnds`(柱子端头)。
4
+ - **图标**:lucide-react,尺寸 / 弱化色用配方的 `i-icon--*` 类(`recipes.css`),不传 `size` / `strokeWidth`;`main.tsx` 里 `render()` 之后调一次 `mergeIcons()`(`{{IMPORT}}/icon-merge`)。描边由桥接按屏幕上的 `icon.stroke.width`(1.4px)画,`mergeIcons()` 把每只图标的多段描边合并后一次上色——不调的话,半透明的图标色在描边交叠处会叠深一块。
5
+ - **根字号保持 16px**:Tailwind 的 rem 刻度依赖它;recipes 只在 `body` 设正文字号,不动 `html`。
6
+ - **另一模式**:按 `design-system/theme-map.json` 的激活方式切换(class 激活 = `<html class="dark">`,可用 next-themes)。
7
+ - **走查页**:把种子的 `templates/KitchenSink.tsx` 拷进项目、挂到 `/kitchen`(验收清单的 `KITCHEN` 填 `'#/kitchen'`),亮 / 暗两种模式下逐组件看一遍 hover / focus / disabled。