@cyberskill/design 1.0.0 → 1.1.1

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 (266) hide show
  1. package/DESIGN.md +10 -9
  2. package/README.md +31 -28
  3. package/SKILL.md +13 -9
  4. package/VERSION +1 -1
  5. package/_ds_bundle.js +660 -202
  6. package/_ds_manifest.json +1 -1
  7. package/_esm/cs.mjs +14 -8
  8. package/_esm/react.d.ts +216 -0
  9. package/_esm/react.mjs +114 -0
  10. package/base/collections.css +31 -0
  11. package/base/components.css +3 -0
  12. package/base/data.css +33 -0
  13. package/base/forms.css +8 -0
  14. package/base/interaction.css +1 -0
  15. package/base/typography.css +6 -0
  16. package/components/_i18n/strings.js +8 -4
  17. package/components/ai/ai-conversation.card.html +2 -2
  18. package/components/ai/ai-lumi.card.html +2 -2
  19. package/components/ai/ai.card.html +2 -2
  20. package/components/brand/brand.card.html +2 -2
  21. package/components/button/buttons.card.html +2 -2
  22. package/components/data/AspectRatio.d.ts +16 -0
  23. package/components/data/AspectRatio.figma.tsx +12 -0
  24. package/components/data/AspectRatio.jsx +16 -0
  25. package/components/data/AspectRatio.prompt.md +7 -0
  26. package/components/data/Collapsible.d.ts +21 -0
  27. package/components/data/Collapsible.figma.tsx +12 -0
  28. package/components/data/Collapsible.jsx +49 -0
  29. package/components/data/Collapsible.prompt.md +7 -0
  30. package/components/data/Image.d.ts +4 -0
  31. package/components/data/Image.prompt.md +2 -2
  32. package/components/data/Item.d.ts +26 -0
  33. package/components/data/Item.figma.tsx +12 -0
  34. package/components/data/Item.jsx +63 -0
  35. package/components/data/Item.prompt.md +10 -0
  36. package/components/data/ScrollArea.d.ts +16 -0
  37. package/components/data/ScrollArea.figma.tsx +12 -0
  38. package/components/data/ScrollArea.jsx +25 -0
  39. package/components/data/ScrollArea.prompt.md +7 -0
  40. package/components/data/collections.card.html +15 -4
  41. package/components/data/data.card.html +15 -4
  42. package/components/datatable/datatable.card.html +2 -2
  43. package/components/dialog/dialog.card.html +2 -2
  44. package/components/feedback/feedback-2.card.html +2 -2
  45. package/components/feedback/feedback.card.html +2 -2
  46. package/components/forms/Cascader.jsx +5 -3
  47. package/components/forms/Editor.prompt.md +1 -1
  48. package/components/forms/InputGroup.d.ts +4 -0
  49. package/components/forms/InputGroup.jsx +38 -8
  50. package/components/forms/InputGroup.prompt.md +3 -3
  51. package/components/forms/NativeSelect.d.ts +22 -0
  52. package/components/forms/NativeSelect.figma.tsx +12 -0
  53. package/components/forms/NativeSelect.jsx +56 -0
  54. package/components/forms/NativeSelect.prompt.md +10 -0
  55. package/components/forms/NumberField.d.ts +5 -0
  56. package/components/forms/NumberField.jsx +51 -7
  57. package/components/forms/NumberField.prompt.md +2 -2
  58. package/components/forms/SegmentedControl.jsx +1 -1
  59. package/components/forms/TagInput.d.ts +3 -0
  60. package/components/forms/TagInput.jsx +62 -20
  61. package/components/forms/TagInput.prompt.md +2 -2
  62. package/components/forms/forms-2.card.html +2 -2
  63. package/components/forms/forms.card.html +5 -4
  64. package/components/icon/Icon.prompt.md +1 -1
  65. package/components/icon/icon.card.html +2 -2
  66. package/components/logo/Logo.jsx +2 -1
  67. package/components/logo/logo.card.html +2 -2
  68. package/components/navigation/Menu.jsx +14 -1
  69. package/components/navigation/navigation.card.html +2 -2
  70. package/components/navigation/shell.card.html +2 -2
  71. package/components/overlays/AlertDialog.d.ts +29 -0
  72. package/components/overlays/AlertDialog.figma.tsx +12 -0
  73. package/components/overlays/AlertDialog.jsx +142 -0
  74. package/components/overlays/AlertDialog.prompt.md +12 -0
  75. package/components/overlays/Drawer.jsx +1 -1
  76. package/components/overlays/Popconfirm.jsx +14 -1
  77. package/components/overlays/Popover.jsx +14 -1
  78. package/components/overlays/alertdialog.card.html +42 -0
  79. package/components/overlays/overlays.card.html +2 -2
  80. package/components/textfield/textfield.card.html +2 -2
  81. package/docs/benchmark-rubric.md +46 -0
  82. package/docs/ci-cd.md +17 -11
  83. package/docs/consumer-grant.md +37 -0
  84. package/docs/consuming.md +45 -16
  85. package/docs/contrast-report.md +91 -103
  86. package/docs/conventions.md +12 -9
  87. package/docs/decisions.md +33 -10
  88. package/docs/deploy.md +1 -1
  89. package/docs/design-styles.md +26 -8
  90. package/docs/figma.md +3 -3
  91. package/docs/live-hub.md +5 -3
  92. package/docs/products.md +13 -11
  93. package/docs/quality-gates.md +35 -21
  94. package/docs/release-notes.md +21 -3
  95. package/docs/status/assets/favicon.svg +5 -0
  96. package/docs/status/assets/status-legacy.css +399 -0
  97. package/docs/status/assets/status-legacy.js +505 -0
  98. package/docs/status/assets/status.css +644 -0
  99. package/docs/status/assets/status.js +1308 -0
  100. package/docs/status/data/status-feed.json +1 -0
  101. package/docs/status/data/task/TASK-REL-001.js +1 -0
  102. package/docs/status/data/task/TASK-REL-002.js +1 -0
  103. package/docs/status/index.html +42 -0
  104. package/docs/status/roadmap.html +4 -0
  105. package/docs/status/status-legacy.html +117 -0
  106. package/docs/storybook.md +5 -4
  107. package/docs/sync.md +3 -2
  108. package/docs/tasks/BACKLOG.md +26 -0
  109. package/docs/tasks/release/TASK-REL-001-launch-1-1-0/spec.md +55 -0
  110. package/docs/tasks/release/TASK-REL-002-republish-1-1-1/spec.md +54 -0
  111. package/docs/template-schema-v2.md +15 -3
  112. package/docs/vi/benchmark-rubric.md +46 -0
  113. package/docs/vi/ci-cd.md +17 -11
  114. package/docs/vi/consumer-grant.md +37 -0
  115. package/docs/vi/consuming.md +45 -16
  116. package/docs/vi/contrast-report.md +94 -106
  117. package/docs/vi/conventions.md +12 -9
  118. package/docs/vi/decisions.md +33 -10
  119. package/docs/vi/deploy.md +1 -1
  120. package/docs/vi/design-styles.md +26 -8
  121. package/docs/vi/figma.md +3 -3
  122. package/docs/vi/live-hub.md +5 -3
  123. package/docs/vi/products.md +13 -11
  124. package/docs/vi/quality-gates.md +35 -21
  125. package/docs/vi/release-notes.md +26 -8
  126. package/docs/vi/storybook.md +5 -4
  127. package/docs/vi/sync.md +3 -2
  128. package/docs/vi/template-schema-v2.md +15 -3
  129. package/docs/viewer.html +2 -2
  130. package/fonts/spacegrotesk-var-latin-ext.woff2 +0 -0
  131. package/fonts/spacegrotesk-var-latin.woff2 +0 -0
  132. package/fonts/spacegrotesk-var-vietnamese.woff2 +0 -0
  133. package/guidelines/atomic-view.html +40 -27
  134. package/guidelines/elements-geometry.html +69 -0
  135. package/guidelines/elements-variants.html +17 -17
  136. package/guidelines/type-families.html +16 -10
  137. package/llms.txt +17 -11
  138. package/package.json +38 -16
  139. package/styles.css +1 -0
  140. package/templates/ai-cluster-demo.html +29 -14
  141. package/templates/app-shell/support.js +4 -4
  142. package/templates/article/content-schema.json +6 -0
  143. package/templates/article/support.js +4 -4
  144. package/templates/auth/support.js +4 -4
  145. package/templates/bod-deck/support.js +4 -4
  146. package/templates/bod-investor-update/support.js +4 -4
  147. package/templates/bod-memo/support.js +4 -4
  148. package/templates/bod-minutes/content-schema.json +12 -0
  149. package/templates/bod-minutes/support.js +4 -4
  150. package/templates/bod-report/support.js +4 -4
  151. package/templates/bod-resolution/support.js +4 -4
  152. package/templates/culture-event-invite/support.js +4 -4
  153. package/templates/dashboard/support.js +4 -4
  154. package/templates/delivery-change-note/support.js +4 -4
  155. package/templates/delivery-kickoff/support.js +4 -4
  156. package/templates/delivery-qbr-deck/support.js +4 -4
  157. package/templates/delivery-runbook/content-schema.json +6 -0
  158. package/templates/delivery-runbook/support.js +4 -4
  159. package/templates/delivery-status-email/support.js +4 -4
  160. package/templates/doc-style-guide/DocStyleGuide.dc.html +2 -2
  161. package/templates/doc-style-guide/support.js +4 -4
  162. package/templates/doc-suite-index/support.js +4 -4
  163. package/templates/doc-templates/DocTemplates.dc.html +1 -1
  164. package/templates/doc-templates/support.js +4 -4
  165. package/templates/email/support.js +4 -4
  166. package/templates/email-safe/README.md +17 -4
  167. package/templates/email-safe/email-launch.html +3 -3
  168. package/templates/email-safe/email-newsletter.html +1 -1
  169. package/templates/finance-dunning-email/support.js +4 -4
  170. package/templates/finance-expense-report/support.js +4 -4
  171. package/templates/finance-invoice/support.js +4 -4
  172. package/templates/finance-quote/support.js +4 -4
  173. package/templates/hr-announcement/support.js +4 -4
  174. package/templates/hr-interview-kit/content-schema.json +12 -0
  175. package/templates/hr-interview-kit/support.js +4 -4
  176. package/templates/hr-offboarding/content-schema.json +12 -0
  177. package/templates/hr-offboarding/support.js +4 -4
  178. package/templates/hr-performance-review/content-schema.json +12 -0
  179. package/templates/hr-performance-review/support.js +4 -4
  180. package/templates/hr-pip/content-schema.json +12 -0
  181. package/templates/hr-pip/support.js +4 -4
  182. package/templates/legal-msa/content-schema.json +16 -0
  183. package/templates/legal-msa/support.js +4 -4
  184. package/templates/legal-sow/support.js +4 -4
  185. package/templates/marketing-campaign-brief/support.js +4 -4
  186. package/templates/marketing-case-study/support.js +4 -4
  187. package/templates/marketing-launch/support.js +4 -4
  188. package/templates/marketing-newsletter/support.js +4 -4
  189. package/templates/marketing-page/content-schema.json +0 -1
  190. package/templates/marketing-page/support.js +4 -4
  191. package/templates/marketing-press-release/support.js +4 -4
  192. package/templates/marketing-social-kit/support.js +4 -4
  193. package/templates/playground.html +8 -4
  194. package/templates/sales-one-pager/support.js +4 -4
  195. package/templates/sales-proposal-deck/support.js +4 -4
  196. package/templates/settings/Settings.dc.html +26 -14
  197. package/templates/settings/content-schema.json +36 -0
  198. package/templates/settings/support.js +4 -4
  199. package/templates/slide-deck/support.js +4 -4
  200. package/templates/team-meeting-agenda/content-schema.json +16 -0
  201. package/templates/team-meeting-agenda/support.js +4 -4
  202. package/templates/tech-incident-report/support.js +4 -4
  203. package/templates/tech-release-notes/support.js +4 -4
  204. package/templates/tech-retro/content-schema.json +12 -0
  205. package/templates/tech-retro/support.js +4 -4
  206. package/templates/tech-rfc/content-schema.json +6 -0
  207. package/templates/tech-rfc/support.js +4 -4
  208. package/templates/vn-appointment-transfer/support.js +4 -4
  209. package/templates/vn-certificate-of-employment/support.js +4 -4
  210. package/templates/vn-code-of-conduct/support.js +4 -4
  211. package/templates/vn-compensation-regulation/support.js +4 -4
  212. package/templates/vn-contract-amendment/support.js +4 -4
  213. package/templates/vn-contractor-agreement/support.js +4 -4
  214. package/templates/vn-data-protection-policy/support.js +4 -4
  215. package/templates/vn-disciplinary-case-file/support.js +4 -4
  216. package/templates/vn-disciplinary-schedule/content-schema.json +15 -0
  217. package/templates/vn-disciplinary-schedule/support.js +4 -4
  218. package/templates/vn-employee-request/support.js +4 -4
  219. package/templates/vn-exit-handover/support.js +4 -4
  220. package/templates/vn-foreign-employee-pack/support.js +4 -4
  221. package/templates/vn-grassroots-democracy/support.js +4 -4
  222. package/templates/vn-infosec-policy/support.js +4 -4
  223. package/templates/vn-internal-labor-regulations/support.js +4 -4
  224. package/templates/vn-internship-agreement/support.js +4 -4
  225. package/templates/vn-job-description/support.js +4 -4
  226. package/templates/vn-labor-contract/support.js +4 -4
  227. package/templates/vn-labour-management-book/content-schema.json +15 -0
  228. package/templates/vn-labour-management-book/support.js +4 -4
  229. package/templates/vn-mutual-nda/support.js +4 -4
  230. package/templates/vn-ndnca-ip/support.js +4 -4
  231. package/templates/vn-offer-letter/support.js +4 -4
  232. package/templates/vn-onboarding-checklist/support.js +4 -4
  233. package/templates/vn-pdpl-consent/support.js +4 -4
  234. package/templates/vn-performance-evaluation-regulation/support.js +4 -4
  235. package/templates/vn-performance-review-form/support.js +4 -4
  236. package/templates/vn-phantom-stock/support.js +4 -4
  237. package/templates/vn-probation-contract/support.js +4 -4
  238. package/templates/vn-receipt-acknowledgement/content-schema.json +15 -0
  239. package/templates/vn-receipt-acknowledgement/support.js +4 -4
  240. package/templates/vn-remote-work-policy/support.js +4 -4
  241. package/templates/vn-resignation-letter/support.js +4 -4
  242. package/templates/vn-salary-scale/content-schema.json +15 -0
  243. package/templates/vn-salary-scale/support.js +4 -4
  244. package/templates/vn-sow-appendix/support.js +4 -4
  245. package/templates/vn-termination-decision/support.js +4 -4
  246. package/templates/vn-total-rewards-appendix/support.js +4 -4
  247. package/templates/vn-training-commitment/support.js +4 -4
  248. package/templates/vn-travel-expense-policy/support.js +4 -4
  249. package/tokens/element-seeds.json +112 -0
  250. package/tokens/elements.css +274 -187
  251. package/tokens/fonts.css +12 -3
  252. package/tokens/native/CSTokens.kt +84 -68
  253. package/tokens/native/CSTokens.swift +84 -68
  254. package/tokens/native/cs_tokens.dart +84 -68
  255. package/tokens/provenance.json +9 -9
  256. package/tokens/styles.css +15 -0
  257. package/tokens/tokens.dtcg.json +258 -233
  258. package/tokens/tokens.js +168 -167
  259. package/tokens/tokens.json +167 -166
  260. package/tokens/typography.css +9 -1
  261. package/ui_kits/status-hub/README.md +1 -2
  262. package/ui_kits/status-hub/index.html +2 -2
  263. package/ui_kits/status-hub/settings.html +6 -3
  264. package/ui_kits/website/chat.html +2 -2
  265. package/ui_kits/website/index.html +2 -2
  266. package/ui_kits/status-hub/identity-lab.html +0 -134
@@ -0,0 +1,46 @@
1
+ # Rubric benchmark Design System
2
+
3
+ Checklist tự kiểm khi tiến hóa CyberSkill Design System — chuẩn bên ngoài cộng rule CDS. Ghép với [`docs/vi/quality-gates.md`](quality-gates.md) (gate xác định) và [`docs/vi/design-styles.md`](design-styles.md) (hợp đồng màu Element).
4
+
5
+ ## Chuẩn bên ngoài
6
+
7
+ | Lĩnh vực | Chuẩn / thực hành | Cách đo |
8
+ |---|---|---|
9
+ | Sàn a11y pháp lý | WCAG 2.2 AA contrast (4.5:1 chữ thường / 3:1 chữ lớn / UI non-text ≥ 3:1) | `contrast-guard`, theme-overflow, axe-smoke |
10
+ | Đọc theo cảm nhận | APCA Bronze-style Lc (body ≥ 75, nhãn UI ≥ 60, lớn ≥ 45, non-text ≥ 15; dark max ~90) | `apca-dark-preview`, [`docs/vi/contrast-report.md`](contrast-report.md) |
11
+ | Không gian màu | Ramp OKLCH ưu tiên luminance; giữ hue qua mode | `element-geometry` + `npm run tokens:elements` |
12
+ | Kiến trúc token | W3C DTCG 2025.10 — primitive → semantic → component; leaf có `$type`; modifier đa chiều (theme × element) | `dtcg-typing`, token-format-parity, token-pipeline |
13
+ | Theming hai mode | Cùng họ hue light↔dark; remap role (không đảo hết) | `element-geometry` hue-lock |
14
+ | Audit dual-standard | Phân loại cặp: pass-both / fail-both / WCAG-only / APCA-only | Ghi trong workflow contrast-report sau đổi token |
15
+ | An toàn gamut | Ưu tiên chroma sRGB-safe; clamp trước khi emit | Generator + geometry gate |
16
+
17
+ ## Rule CDS sở hữu
18
+
19
+ | Rule | Thực thi |
20
+ |---|---|
21
+ | Trục = Theme × Element × Language × Style cho tới khi có Style Expansion Rule | `axis-guard` (Expression/Density đã nghỉ); doctrine trong design-styles |
22
+ | Chữ không trên mid `-accent`; focus Ochre không remap; màu status không remap | Hợp đồng `elements.css` · contrast-report · conventions |
23
+ | Một element mỗi bề mặt; gradient chỉ Tương sinh | Registry products · conventions |
24
+ | Registry product→element khóa; UI kit trung thành Thổ | [`docs/vi/products.md`](products.md) |
25
+ | Expansion Rule đủ + `_audit/run.html` xanh + docs EN·VI parity | CLAUDE.md · docs-consistency · docs-lang-parity |
26
+ | VERSION **1.1.1** post-LAUNCH | version-stamp · docs-consistency |
27
+ | Pack Element chỉ từ seed (30 bộ) | `element-geometry` · `tokens:elements` |
28
+
29
+ ## Checklist mở rộng style (`data-cs-style`)
30
+
31
+ Sole pack hôm nay: **liquid-glass** (`tokens/styles.css`, gate `_audit/style-contract.html`). Khi thêm style pack ngoài liquid-glass:
32
+
33
+ 1. Overlay token **tiêu thụ** 9 role `--cs-accent-*` sẵn có (không invent pack Element song song).
34
+ 2. Specimen card + Storybook / Atomic View nếu style chọn được ở sản phẩm.
35
+ 3. Adoption template / kit chỉ khi cố ý — UI kit giữ Thổ trừ khi quyết định nói khác.
36
+ 4. Regen contrast nếu style remap nền chứa chữ.
37
+ 5. Expansion Rule grep enum mới qua templates, docs EN+VI, gates.
38
+ 6. Mở rộng allowlist style-contract; giữ `_audit/run.html` xanh.
39
+ 7. Ghi quyết định trong [`docs/vi/decisions.md`](decisions.md).
40
+
41
+ ## Cách chạy một lượt benchmark
42
+
43
+ 1. `npm run tokens:elements` (nếu đổi seed) → regen native → `node scripts/generate-contrast-report.mjs`
44
+ 2. Fast board: mở `_audit/run.html` (hoặc CI `fast-gates`) — mọi hard gate xanh, gồm **Element geometry**
45
+ 3. Whole-set Atomic View / Elements Geometry: đủ **30** bộ (soft/middle/deep × light/dark × năm element) — soft là pastel wash, middle đồng bộ cường độ giữa các element, deep rõ ràng tối hơn, role hài hòa, light↔dark giữ cùng họ hue. Gate geometry yêu cầu **cả** `minDeltaE` và `minDeltaL` (cộng L đơn điệu) từ `tokens/element-seeds.json`
46
+ 4. Chỉ sửa rubric này khi chuẩn hoặc doctrine CDS đổi — giữ EN·VI parity
package/docs/vi/ci-cd.md CHANGED
@@ -12,15 +12,16 @@
12
12
 
13
13
  1. **`fast-gates`** — `npm ci` + Playwright Chromium cache, serve repo, mở `_audit/run.html` headless (`_audit/ci/run-gates.mjs`), fail khi hard-gate fail. Upload import-report khi fail. Hàng mới trên board (hardening Th7 2026 thêm 8: token-format-parity, version-stamp, support-runtime-identity, package-exports-integrity, template-lang-parity, dtcg-typing, design-md-parity, bundle-freshness) được nhận tự động — runner đọc `window.__run`, không phải danh sách gate phía job.
14
14
  2. **`token-provenance`** — kiểm Node không trình duyệt: natives + `provenance.json` khớp sha-256 nguồn DTCG.
15
- 3. **`unit-tests`** — `npm run test:unit` (8 contract test Node thuần; nối vào CI bởi hardening Th7 2026 — trước đó chỉ local).
15
+ 3. **`unit-tests`** — `npm run test:unit` (11 contract test Node thuần; nối vào CI bởi hardening Th7 2026 — trước đó chỉ local). Gồm `test-element-packs` (freshness `node scripts/generate-element-packs.mjs --check`).
16
16
  4. **`node-prechecks`** — authority Node không trình duyệt: `_audit/ci/check-bundle-freshness.mjs` (nguồn chân lý bundle-freshness — khám phá source đầy đủ gồm file mới/xóa; hàng board chỉ re-hash file ghi trong header) và `scripts/generate-design-md.mjs --check` (`DESIGN.md` gốc byte-equals regeneration).
17
17
  5. **`docs-consistency-blocker`** — merge blocker `docs-consistency` + `bilingual-parity`.
18
18
  6. **`whole-set-audits`** — quyết định B của owner: mọi push/PR, cộng nightly `0 3 * * *` và `workflow_dispatch` (responsive + language + theme overflow, ~15–20 phút).
19
- 7. **`figma-variables-push`** — trên push `main` + thủ công. Quyết định A (non-Enterprise): Variables REST soft-skip; secrets vẫn chứng minh mở file. Xem `docs/figma.md`.
20
- 8. **`code-connect`** — trên PR + `main` + thủ công. Quyết định 1C: dry-run luôn (config + 99 mapping); publish soft-skip khi thiếu `FIGMA_TOKEN` / `FIGMA_FILE_KEY` hoặc API 403/404/429. Xem `docs/figma.md`.
21
- 9. **`regenerate-tokens`** — path-filtered trên push/PR (`tokens.dtcg.json`, natives, generator, `VERSION`); luôn có trên schedule/manual. Output native deterministic; push với `contents: write` (hoặc `DS_PUSH_TOKEN`).
19
+ 7. **`figma-variables-push`** — trên push `main` + thủ công. **`FIGMA_TOKEN` / `FIGMA_FILE_KEY` trống → soft-skip** (exit 0 + report — cùng trung thực với Code Connect). Quyết định A (non-Enterprise): Variables REST cũng **soft-skip khi API 403** (và lỗi plan/scope liên quan) sau khi secret chứng minh mở file. Soft-skip ≠ sync Variables live. Xem `docs/figma.md`.
20
+ 8. **`code-connect`** — trên PR + `main` + thủ công. Quyết định 1C: dry-run luôn (config + 105 mapping); publish soft-skip khi thiếu `FIGMA_TOKEN` / `FIGMA_FILE_KEY` hoặc API 403/404/429. Xem `docs/figma.md`.
21
+ 9. **`regenerate-tokens`** (pull request) + **`regenerate-tokens-push`** (push `main` / schedule / thủ công) — path filter phủ element seeds/packs (`element-seeds.json`, `elements.css`, mirror JSON/JS/DTCG, `generate-element-packs.mjs`) cộng natives / `VERSION`. Regenerate chạy `npm run tokens:elements` rồi `node _audit/ci/generate-native-tokens.mjs`. Trên **pull request** job chạy với `contents: read`, không bao giờ push, và **exit 1** khi có drift: chạy cả hai ở local rồi commit. Chỉ job song sinh push/schedule/thủ công giữ `contents: write` và auto-commit với `DS_PUSH_TOKEN` (hoặc `github.token`).
22
+ 10. **`npm-hello-smoke`** — chứng minh consumer registry: `cd examples/npm-hello && npm ci && npm run smoke` (**hard fail**; package public). Path-filtered trên push/PR khi `examples/npm-hello/**`, bề mặt publish package, hoặc workflow này đổi; luôn chạy trên schedule / `workflow_dispatch`.
22
23
 
23
- Workflow riêng **`npm-publish`** (`.github/workflows/npm-publish.yml`): `workflow_dispatch` + tag `v*`; pack dry-run luôn; publish soft-skip khi thiếu `NPM_TOKEN`. Phiên bản giữ **1.0.0**; license **UNLICENSED**.
24
+ Workflow riêng **`npm-publish`** (`.github/workflows/npm-publish.yml`): `workflow_dispatch` + tag `v*`; pack dry-run luôn; publish qua **npm Trusted Publishing (OIDC)** (`id-token: write`, không `NPM_TOKEN` trên bước publish). Soft-skip khi auth / 403 / 404 / EOTP / conflict phiên bản. Phiên bản là **1.1.1**; license **UNLICENSED**. Trusted Publisher trên npmjs phải khớp filename workflow `npm-publish.yml`. Publishing access package: **Require 2FA and disallow tokens** (OIDC vẫn chạy; token classic bị từ chối).
24
25
 
25
26
  Workflow riêng **`native-store`** (`.github/workflows/native-store.yml`): PR + `main` (path-filtered) + `workflow_dispatch`; dry-run scaffold luôn; kiểm signed-release soft-skip khi thiếu `ASC_KEY_ID` / `ASC_ISSUER_ID` / `ASC_KEY_P8` / `PLAY_SERVICE_ACCOUNT_JSON`. **Không bao giờ submit** lên App Store / Play — sample vẫn là sample. Xem `examples/native/README.md`.
26
27
 
@@ -39,7 +40,7 @@ Node **22** trên runner (tránh deprecation action Node 20). Cache key Playwrig
39
40
 
40
41
  ## Quyền auto-commit token
41
42
 
42
- Job yêu cầu `permissions: contents: write`. Nếu org khóa default token read-only, đặt repository secret `DS_PUSH_TOKEN` (fine-grained PAT, Contents read/write) hoặc mở write tại org Actions settings. Xem ghi chú trước trong git history / org settings.
43
+ Chỉ `regenerate-tokens-push` yêu cầu `permissions: contents: write`; job song sinh cho pull request `regenerate-tokens` giữ `contents: read` và checkout không lưu credential, nên PR không bao giờ kích hoạt push của bot. Nếu org khóa default token read-only, đặt repository secret `DS_PUSH_TOKEN` (fine-grained PAT, Contents read/write) hoặc mở write tại org Actions settings. Xem ghi chú trước trong git history / org settings.
43
44
 
44
45
  ## Branch protection (khuyến nghị)
45
46
 
@@ -61,24 +62,29 @@ node _audit/ci/check-bundle-freshness.mjs
61
62
  node scripts/generate-design-md.mjs --check
62
63
  npm run test:unit
63
64
  node _audit/ci/run-single-gate.mjs http://127.0.0.1:8080/_audit/docs-consistency.html __docs
65
+ npm run tokens:elements
66
+ node scripts/generate-element-packs.mjs --check
64
67
  node _audit/ci/generate-native-tokens.mjs
65
68
  ```
66
69
 
67
70
  ## Những gì KHÔNG auto-fail (có chủ đích)
68
71
 
69
72
  - **Hàng visual / component baseline side-by-side** — chỉ advisory (drift đánh giá bằng mắt). So sánh `%` pixel Playwright là gate **hard** (job `pixel-diff` + hàng Pixel CI trên board).
70
- - **Figma Variables write trên non-Enterprise** — soft-skip kèm report artifact.
73
+ - **Figma Variables** — soft-skip khi thiếu secret (cùng trung thực với Code Connect) hoặc write Variables gặp non-Enterprise / API **403**; report artifact ghi lại skip. Soft-skip ≠ sync live.
71
74
  - **Code Connect publish** — soft-skip khi thiếu secret hoặc API 403/404/429 (Quyết định 1C).
72
- - **npm publish** — soft-skip khi thiếu `NPM_TOKEN` (Quyết định 1C).
75
+ - **npm publish** — Trusted Publishing (OIDC) trên `npm-publish.yml`; soft-skip khi auth / conflict (Quyết định 1C).
73
76
  - **Native store signed release** — soft-skip khi thiếu `ASC_*` / `PLAY_SERVICE_ACCOUNT_JSON` (Quyết định 1C); submit store vẫn tắt.
77
+ - **npm-hello registry smoke** — **hard fail** (`examples/npm-hello` → `npm ci` + `npm run smoke`); chứng minh đường install public `@cyberskill/design` (không soft-skip).
78
+
79
+ Job `figma-variables-push` hay `code-connect` xanh — và do đó badge hay hàng Status xanh — chỉ có nghĩa job exit 0; nó **không** chứng minh sync Figma live, vì soft-skip và publish thật nhìn từ ngoài giống hệt nhau. Mở report artifact của run (`figma-push-report.json` / `code-connect-report.json`) để biết cái nào đã xảy ra.
74
80
 
75
81
  ## Soft-skip dry-run (local)
76
82
 
77
83
  ```bash
78
- npm run code-connect:dry-run # config + ≥99 mapping; không secret
84
+ npm run code-connect:dry-run # config + ≥105 mapping; không secret
79
85
  node _audit/ci/code-connect-publish.mjs # thiếu secret → SOFT SKIP missing_secrets
80
- npm run npm:pack-dry-run # inventory tarball; không NPM_TOKEN
81
- node _audit/ci/npm-publish.mjs # thiếu NPM_TOKEN → SOFT SKIP missing_secrets
86
+ npm run npm:pack-dry-run # inventory tarball; không auth
87
+ node _audit/ci/npm-publish.mjs # GHA OIDC; không thì SOFT SKIP (package disallow tokens)
82
88
  npm run native:store-dry-run # scaffold Fastlane + metadata; không ASC_*/Play JSON
83
89
  node _audit/ci/native-store-dry-run.mjs # thiếu secret → SOFT SKIP missing_secrets
84
90
  ```
@@ -0,0 +1,37 @@
1
+ # Grant consumer — `@cyberskill/design`
2
+
3
+ **Trạng thái: có hiệu lực** (Th7 2026). Văn bản chính sách — không phải secret. License trên package vẫn **UNLICENSED**; grant này là lớp duyệt dùng trong các sản phẩm đã nêu.
4
+
5
+ ## Grant
6
+
7
+ CyberSkill cấp cho **CyberSkill** (công ty và các team kỹ thuật sản phẩm dưới `cyberskill-official`) quyền **không độc quyền** cài và dùng **`@cyberskill/design`** trong các sản phẩm liệt kê ở registry đã khóa `docs/products.md`:
8
+
9
+ | Sản phẩm |
10
+ |---|
11
+ | Lumi — trợ lý điều ước |
12
+ | Status Hub — cổng portfolio khách hàng |
13
+ | CyberOS Agent Spine — hạ tầng agent, memory, gates |
14
+ | CyberSkill Design System — thư viện này |
15
+ | cyberskill.world — site studio |
16
+ | Client delivery suite — kickoff · QBR · runbooks |
17
+ | Board / investor collateral |
18
+ | HR / employment instruments |
19
+
20
+ Package vẫn **UNLICENSED**. Cài từ npm registry **không** tự cấp quyền redistribution. Redistribution ngoài các sản phẩm trên — gồm publish fork, đổi license, hoặc ship package như dependency của sản phẩm bên thứ ba không liên quan — cần **grant viết thêm** ghi trong file này (hoặc văn bản thay thế).
21
+
22
+ ## Ghi chú phạm vi
23
+
24
+ - **Clone / subtree / link tĩnh** repo này cho cùng các sản phẩm trên được cover giống npm install.
25
+ - **Tooling chỉ-host** (Storybook, `_audit/`) không nằm trong tarball npm và không redistribution theo grant này.
26
+ - Thêm sản phẩm CyberSkill mới: cập nhật `docs/products.md` (+ VI) qua quyết định maintainer, rồi thêm hàng sản phẩm tại đây trong cùng change.
27
+ - Duyệt **team/client bên ngoài**: thêm stanza grant có ngày bên dưới (team/org, sản phẩm đã nêu, liên hệ). Không invent ánh xạ product → element tại đây — giữ ở `docs/products.md`.
28
+
29
+ ## Grantee bổ sung
30
+
31
+ *(Chưa có. Thêm entry có ngày tại đây.)*
32
+
33
+ ## Liên quan
34
+
35
+ - Adopt / cài: `docs/consuming.md`
36
+ - Biên bản quyết định: `docs/decisions.md` §7
37
+ - Registry product → element: `docs/products.md`
@@ -8,18 +8,18 @@ Cách mọi project — do người hoặc agent điều khiển — áp dụng
8
8
 
9
9
  | Consumer | Bắt đầu tại | Hoạt động hôm nay | Không làm |
10
10
  |---|---|---|---|
11
- | **Claude Code** | `SKILL.md` → `README.md` → `styles.css` + `_esm/cs.mjs` / `_ds_bundle.js` (resolve theo prefix) | Mạnh — rules, components, prompts; gates qua full clone | Hardcode hậu tố bundle; coi Storybook host là hợp đồng portable |
11
+ | **Claude Code** | `SKILL.md` → `README.md` → `styles.css` + bundler `@cyberskill/design` / legacy `_esm/cs.mjs` / `_ds_bundle.js` (resolve theo prefix) | Mạnh — rules, components, prompts; gates qua full clone | Hardcode hậu tố bundle; coi Storybook host là hợp đồng portable; import `_esm/cs.mjs` hoặc `@cyberskill/design/legacy` vào bundler Next/SSR |
12
12
  | **Google Stitch** | `DESIGN.md` → `llms.txt` → `tokens/tokens.dtcg.json` | Mạnh cho doctrine + tokens + HTML tĩnh `.cs-*` | Coi `templates/**/*.dc.html` là SoT — không có tweaks / `__dcSetProps` / DC compiler |
13
13
  | **Claude Design** | Full repo + DC compiler | Full fidelity (tweaks, `x-import`, template bilingual) | Bỏ qua vòng sync trong `docs/sync.md` |
14
- | **npm** | `@cyberskill/design` | Hình dạng package đã gate; dry-run luôn | Giả định cài public đã duyệt — cần grant owner + `NPM_TOKEN` (soft-skip cho đến khi đó) |
14
+ | **npm** | `@cyberskill/design` | **1.1.1** trên registry; CI Trusted Publishing; grant tại `docs/consumer-grant.md` | Coi cài từ registry như license công khai (vẫn UNLICENSED) |
15
15
 
16
16
  **Quy tắc DC cho Stitch:** Stitch (và mọi tool non-DC) **không** được tiêu thụ `*.dc.html` như nguồn chân lý. Dùng pattern export tĩnh, `templates/kitchen-sink.html`, `examples/static-hello/`, và class `.cs-*` từ `styles.css`.
17
17
 
18
- **Tín hiệu release:** VERSION giữ **1.0.0** (không CHANGELOG). Coi **git tip SHA** là chân lý kỹ thuật; đọc điểm nổi bật sản phẩm curated trong `docs/release-notes.md`.
18
+ **Tín hiệu release:** đã LAUNCH ở **1.1.0**; pin hiện tại **1.1.1** (không CHANGELOG). Coi **git tip SHA** là chân lý kỹ thuật; đọc điểm nổi bật sản phẩm curated trong `docs/release-notes.md`.
19
19
 
20
20
  ## Đường nhanh cho AI agent (Claude Code, hoặc điều khiển một agent)
21
21
 
22
- **Bạn nhận:** `styles.css` (400+ token + class `.cs-*` + bề mặt Liquid Glass, `@import` `tokens/` + `base/`) · `_ds_bundle.js` (React component đã compile, không cần build) · `_esm/cs.mjs` (entry ESM re-export mọi component) · `_ds_manifest.json` (inventory máy đọc được) · mỗi component `Name.d.ts` (API) + `Name.prompt.md` (brief dùng) · `tokens/tokens.dtcg.json` (W3C DTCG) + `tokens.json`/`tokens.js`.
22
+ **Bạn nhận:** `styles.css` (400+ token + class `.cs-*` + bề mặt Liquid Glass, `@import` `tokens/` + `base/`) · `_ds_bundle.js` (React component đã compile, không cần build) · `_esm/react.mjs` (entry React bundler-native — React là peerDependency; mặc định `exports["."]`) · `_esm/cs.mjs` (browser / no-build legacy qua `exports["./legacy"]`) · `_ds_manifest.json` (inventory máy đọc được) · mỗi component `Name.d.ts` (API) + `Name.prompt.md` (brief dùng) · `tokens/tokens.dtcg.json` (W3C DTCG) + `tokens.json`/`tokens.js`.
23
23
 
24
24
  **Checkout repo** — clone hoặc copy cả cây; mọi thứ là static đường dẫn tương đối. Điểm vào: Storybook trên host site (`/` / `npm run storybook`) · `guidelines/atomic-view.html` (mọi component live, portable) · `templates/<slug>/` (điểm bắt đầu copy được — DC cho Claude Design; kitchen-sink / `.cs-*` cho Stitch). Đọc `SKILL.md` trước khi author bất kỳ thứ gì on-brand; reader Stitch bắt đầu tại `DESIGN.md`. Bản đồ sâu hơn ở `llms.txt` (inventory) và file này (hướng dẫn adopt + upgrade đầy đủ bên dưới).
25
25
 
@@ -38,18 +38,29 @@ Cách mọi project — do người hoặc agent điều khiển — áp dụng
38
38
 
39
39
  ## Adopt qua npm (tùy chọn)
40
40
 
41
- Package có thể publish (`private: false`, phiên bản cố định **1.0.0**). License vẫn **UNLICENSED** — cài từ registry (hoặc tarball đã pack) **không** tự cấp quyền redistribution. Đến khi owner chọn license mở, **consumer cần grant tường minh** từ CyberSkill để dùng package trong sản phẩm. Org `@cyberskill` và `NPM_TOKEN` trên repo đã sẵn sàng vận hành; chạy **Actions → npm-publish** một lần để `@cyberskill/design` lên registry. Thiếu `NPM_TOKEN` thì workflow **soft-skip** (exit 0 + report) — đó là trung thực, không phải release registry thành công. Xem `docs/decisions.md` và `docs/quality-gates.md`.
41
+ Package có thể publish (`private: false`, phiên bản **1.1.1**). License vẫn **UNLICENSED** — cài từ registry **không** tự cấp quyền redistribution. **LAUNCH là `@cyberskill/design@1.1.0`; pin hiện tại `@cyberskill/design@1.1.1` (publish qua tag `v1.1.1`).** CI republish qua **npm Trusted Publishing (OIDC)** trên workflow `npm-publish.yml` (không token publish dài hạn; Publishing access package **disallow tokens**). Dùng đã duyệt ghi tại **`docs/consumer-grant.md`** (sản phẩm portfolio CyberSkill từ `docs/products.md`). Xem `docs/decisions.md` và `docs/ci-cd.md`.
42
42
 
43
- **Grant consumer (chính sách owner — không phải secret).** Với mỗi team được duyệt, ghi lại kiểu: *CyberSkill cấp cho [Team/Org] quyền không độc quyền dùng `@cyberskill/design` trong [sản phẩm đã nêu]. Package vẫn UNLICENSED; redistribution ngoài các sản phẩm đó cần grant viết thêm.* Giữ văn bản grant nội bộ trừ khi muốn công khai.
43
+ **Grant consumer (chính sách owner — không phải secret).** Đã viết và có hiệu lực tại `docs/consumer-grant.md` (+ `docs/vi/consumer-grant.md`). Team bên ngoài cần stanza có ngày thêm vào đó; redistribution ngoài sản phẩm đã grant cần grant viết thêm.
44
44
 
45
45
  ```bash
46
- # sau khi workflow npm-publish chạy thành công (hoặc từ tarball đã pack)
47
- npm install @cyberskill/design@1.0.0
46
+ npm install @cyberskill/design@1.1.1
48
47
  ```
49
48
 
50
- Rồi link styles và import từ entry package (`_esm/cs.mjs` qua `exports["."]`) , hoặc tiếp tục dùng đường cây tĩnh bên dưới. Tarball đã publish là **cả cây portable** (styles, tokens, components, templates, guidelines, docs, UI kits) — không phải subset “chỉ lib” tối thiểu. Tooling chỉ-host (Storybook, `_audit/`) không nằm trong `files[]`.
49
+ Rồi link styles và import component. **App Next.js / Vite / SSR** dùng entry mặc định (bundler-native):
51
50
 
52
- **Đường publish (maintainer):** `prepublishOnly` chạy `build:bundle` + `build:design-md --check`. Workflow `.github/workflows/npm-publish.yml` trên `workflow_dispatch` / tag `v*`; publish cần `NPM_TOKEN` (`node _audit/ci/npm-publish.mjs --dry-run` luôn liệt kê tarball). Xem `docs/ci-cd.md` và `docs/decisions.md`.
51
+ ```ts
52
+ import { Button, TextField } from "@cyberskill/design";
53
+ // tương đương: import { Button } from "@cyberskill/design/react";
54
+ import "@cyberskill/design/styles.css";
55
+ ```
56
+
57
+ Thêm `transpilePackages: ["@cyberskill/design"]` trong Next.js (JSX ship dạng source). React và react-dom là **peerDependencies** — app của bạn cung cấp. Types publish dùng `export type *` (**TypeScript 5.0+**). **Không** import `_esm/cs.mjs` (hay `@cyberskill/design/legacy`) vào bundler SSR; đường đó self-ensure React qua CDN và side-load `_ds_bundle.js` chỉ cho browser.
58
+
59
+ **Browser / no-build:** import `@cyberskill/design/legacy` (`_esm/cs.mjs`) hoặc tiếp tục dùng đường cây tĩnh bên dưới. Tarball đã publish là **cả cây portable** (styles, tokens, components, templates, guidelines, docs, UI kits) — không phải subset “chỉ lib” tối thiểu. Tooling chỉ-host (Storybook, `_audit/`) không nằm trong `files[]`.
60
+
61
+ **Cài thật đầu tiên (Lumi).** Consumer **browser** copy-paste: `examples/npm-hello/` — cài `@cyberskill/design@1.1.1` từ registry, link `styles.css`, mount `Button` qua entry **legacy** (`_esm/cs.mjs`), scope **Lumi** với `data-cs-element="hoa" data-cs-variant="plasma"` (hàng đã khóa trong `docs/products.md`). Trong thư mục đó: `npm install && npm run smoke && npm start` → mở `http://127.0.0.1:8766/`. Team Status Hub dùng cùng install và đổi sang `data-cs-element="thuy"` — không invent ánh xạ. Cho app Next/SSR (ví dụ Lumi landing), dùng `import { Button } from "@cyberskill/design"` như trên — không dùng import map của npm-hello.
62
+
63
+ **Đường publish (maintainer):** `prepublishOnly` chạy `build:bundle` + `build:design-md --check`. Workflow `.github/workflows/npm-publish.yml` trên `workflow_dispatch` / tag `v*` dùng **Trusted Publishing** (`permissions.id-token: write`; không đặt `NODE_AUTH_TOKEN` trên bước publish). `node _audit/ci/npm-publish.mjs --dry-run` luôn liệt kê tarball. Xem `docs/ci-cd.md` và `docs/decisions.md`.
53
64
 
54
65
  ## Adopt (hai đường, cộng shortcut module)
55
66
 
@@ -65,7 +76,9 @@ Rồi link styles và import từ entry package (`_esm/cs.mjs` qua `exports["."]
65
76
  </script>
66
77
  ```
67
78
  Đây đúng là những gì `_audit/consumer-smoke-test.html` chạy (và assert xanh) — và `ds-base.js` của templates làm tương tự, publish alias ổn định `window.CyberSkillDS`.
68
- **2b. Đường ESM (module) — một import, không build.** `import { Button, TextField } from "<path>/_esm/cs.mjs"` — module tự ensure React (pinned; bỏ qua khi đã có `window.React`), side-load `_ds_bundle.js` một lần, resolve namespace theo prefix, và re-export mọi component (`_audit/esm-smoke-test.html` giữ danh sách export khóa với manifest). Vẫn tự link `styles.css`.
79
+ **2b. React bundler-native (Next / Vite / SSR) — entry package mặc định.** `import { Button, TextField } from "@cyberskill/design"` resolve tới `_esm/react.mjs` (cũng export như `@cyberskill/design/react`). Re-export mọi component từ JSX source với **React là peer external** — không CDN, không side-load `_ds_bundle.js`. Bundler của bạn phải transpile package (Next: `transpilePackages: ["@cyberskill/design"]`). Vẫn tự link `styles.css`. Regenerated bằng `npm run build:react-entry`; parity được gate bởi `package-exports-integrity` + `test:react-entry`.
80
+
81
+ **2c. ESM browser legacy — một import, không build.** `import { Button, TextField } from "@cyberskill/design/legacy"` (hoặc `"<path>/_esm/cs.mjs"`) — module tự ensure React qua **umd-react@19.2.8** (CDN pin SRI; React 19 chính thức không còn UMD; bỏ qua khi đã có `window.React`), side-load `_ds_bundle.js` một lần, resolve namespace theo prefix, và re-export mọi component (`_audit/esm-smoke-test.html` giữ danh sách export khóa với manifest). Vẫn tự link `styles.css`. **Không dùng cho Next/SSR.** App bundler vẫn cung cấp peer `react` / `react-dom` (`^18 || ^19`).
69
82
 
70
83
  **Templates.** Mỗi `templates/<slug>/` là Design Component seed từ `ds-base.js` (một dòng `base` để rebind đường dẫn tới nơi hệ thống này nằm tương đối với trang tiêu thụ). Copy thư mục và sửa copy/tweaks.
71
84
 
@@ -73,13 +86,17 @@ Rồi link styles và import từ entry package (`_esm/cs.mjs` qua `exports["."]
73
86
 
74
87
  **HTML tĩnh / không React / không build tooling.** Link `styles.css` và compose bằng class `.cs-*` — catalog đầy đủ trong `templates/kitchen-sink.html`.
75
88
 
76
- ## Ba trục
89
+ **Font, kể cả mặt chữ display.** Cả ba họ chữ brand đều self-host trong `fonts/` và khai báo ở `tokens/fonts.css` (được `styles.css` `@import`): **Be Vietnam Pro** (`--cs-font-family-ui`), **JetBrains Mono** (`--cs-font-family-mono`), và **Space Grotesk** (`--cs-font-family-display`, variable 300–700, có subset tiếng Việt). Mặt chữ display là **opt-in** — không thứ gì trong DS trỏ vào nó. Sản phẩm muốn mặt chữ tiêu đề thêm `class="cs-display-face"` (hoặc đặt `--cs-heading-family: var(--cs-font-family-display)`) trên scope; các utility heading theo sau, body copy vẫn ở mặt chữ UI.
90
+
91
+ Consumer bỏ qua `styles.css` để tự kiểm soát font loading (`cyberskill.world` / Lumi import riêng các sheet token + base và giữ chiến lược `font-display: optional` của mình) có thể chuyển từ `brand-fonts.css` tự chế sang package: hoặc `@import "@cyberskill/design/tokens/fonts.css"` để lấy face đóng gói, hoặc giữ block `@font-face` cục bộ và trỏ `--cs-heading-family` vào `var(--cs-font-family-display)` để **role** đến từ DS ngay cả khi **byte** vẫn phục vụ cục bộ. Cách nào thì mặt chữ display cũng thôi là ngoại lệ riêng của một sản phẩm. Space Grotesk không có weight 800, nên `--cs-heading-weight-strong` (800) dưới `.cs-display-face` clamp về 700 trong Space Grotesk — CSS không nhảy sang Be Vietnam Pro vì thiếu weight.
77
92
 
78
- Đặt Theme (`data-theme`), Element (`data-cs-element` + `data-cs-variant`), và Language (`lang` / Language tweak trên template) trên một container; mọi thứ bên trong re-skin không cần đổi code (xem `templates/playground.html`). Mặc định: `light · tho · en`. Xử lý bề mặt là liquid-glass (cố định). Bilingual: component resolve chuỗi từ `lang` (`lang="vi"` trên mọi container → tiếng Việt đầy đủ).
93
+ ## Bốn trục
94
+
95
+ Đặt Theme (`data-theme` — light / dark / system), Element (`data-cs-element` + `data-cs-variant`), Language (`lang` / Language tweak trên template), và Style (`data-cs-style`) trên một container; mọi thứ bên trong re-skin không cần đổi code (xem `templates/playground.html`). Mặc định: `light · tho · en · liquid-glass` (vắng theme / style ≡ các mặc định đó). Bilingual: component resolve chuỗi từ `lang` (`lang="vi"` trên mọi container → tiếng Việt đầy đủ).
79
96
 
80
97
  ## Nâng cấp
81
98
 
82
- - **Phiên bản cố định.** `VERSION` và `package.json` giữ **1.0.0**. Không có file changelog design-system — coi **git tip SHA** là chân lý kỹ thuật, và đọc **Release Notes** curated (Storybook + `docs/release-notes.md`) cho điểm nổi bật hướng sản phẩm.
99
+ - **Phiên bản cố định.** `VERSION` và `package.json` là **1.1.1**. Không có file changelog design-system — coi **git tip SHA** là chân lý kỹ thuật, và đọc **Release Notes** curated (Storybook + `docs/release-notes.md`) cho điểm nổi bật hướng sản phẩm.
83
100
 
84
101
  - Anchors (Umber/Ochre), tên class `.cs-*`, và tên token `--cs-*` là hợp đồng ổn định — an toàn để phụ thuộc. Đổi tên phá vỡ những hợp đồng đó phải hiếm và được gọi ra trong PR/docs khi xảy ra.
85
102
 
@@ -87,10 +104,22 @@ Rồi link styles và import từ entry package (`_esm/cs.mjs` qua `exports["."]
87
104
 
88
105
  ## Host Storybook (tùy chọn)
89
106
 
90
- Site live phục vụ Storybook tại `/` như **bề mặt sản phẩm** cho operator (Theme × Element × Language + ma trận điều khiển). Đó là **tooling chỉ-host** — đừng phụ thuộc Storybook trong product app. Atomic View portable vẫn ở `guidelines/atomic-view.html`. Xem `docs/storybook.md` và `docs/live-hub.md`.
107
+ Site live phục vụ Storybook tại `/` như **bề mặt sản phẩm** cho operator (Theme × Element × Language × Style + ma trận điều khiển). Đó là **tooling chỉ-host** — đừng phụ thuộc Storybook trong product app. Atomic View portable vẫn ở `guidelines/atomic-view.html`. Xem `docs/storybook.md` và `docs/live-hub.md`.
91
108
 
92
109
  ## Spike consumer năm phút
93
110
 
111
+ **Đường registry (ưu tiên cho product app):**
112
+
113
+ ```bash
114
+ cd examples/npm-hello
115
+ npm install
116
+ npm run smoke
117
+ npm start
118
+ # mở http://127.0.0.1:8766/
119
+ ```
120
+
121
+ **Đường clone / tĩnh (không npm):**
122
+
94
123
  ```bash
95
124
  # từ monorepo root
96
125
  python3 -m http.server 8765 --bind 127.0.0.1
@@ -102,7 +131,7 @@ Sửa `examples/static-hello/index.html`: flip `data-theme="dark"` hoặc `data-
102
131
 
103
132
  ## Native sample hosts (tùy chọn)
104
133
 
105
- Sample đa màn hình (Sign in · Home · Settings) nằm dưới `examples/native/swiftui`, `compose`, và `flutter`. Chúng sync token generate qua `node examples/native/sync-tokens.mjs`. Xem `examples/native/README.md`. Không bắt buộc cho web consumer.
134
+ Sample đa màn hình (Sign in · Home · Settings) nằm dưới `examples/native/swiftui`, `compose`, và `flutter`. Chúng sync token generate qua `node examples/native/sync-tokens.mjs`. Compose mở bằng **Android Studio** (không commit `gradlew` — CLI cần JDK 17+ + SDK; xem `examples/native/README.md`). Không bắt buộc cho web consumer.
106
135
 
107
136
  ## Mở rộng
108
137
 
@@ -1,11 +1,11 @@
1
1
  # Báo cáo contrast — cặp elemental (APCA)
2
2
 
3
- Sinh 2026-07-22 · sweep tại pin VERSION 1.0.0.
3
+ Tạo 2026-07-27 · quét tại pin VERSION 1.1.1.
4
4
 
5
- **Doctrine mã hóa bởi sweep này:** chữ nằm trên `-bright` hoặc `-tint`, không bao giờ trên mid-tone `-accent` — ở mọi kích thước. Accent chỉ cho thanh, border, progress fill, và fill không-chữ. (Quy tắc trong `tokens/elements.css` và conventions.)
5
+ **Doctrine của sweep này:** chữ ngồi trên `-bright` hoặc `-tint`, không bao giờ trên mid-tone `-accent`. Accent chỉ cho bar, border, progress, fill không chữ. (Rule trong `tokens/elements.css` và conventions.)
6
6
 
7
- Nudge token cho v2.0: bright làm sáng cho clay, hoa, lava, plasma, thủy, ocean, forest, titanium; `-on` đảo tối cho lava, ocean, forest, titanium.
8
- | Phạm vi | Cặp | fg / bg | Lc | Kết quả |
7
+ Pack được generate từ `tokens/element-seeds.json` (thang soft / middle / deep, khóa hue light↔dark). Gate hình học: `_audit/element-geometry.html`.
8
+ | Scope | Pairing | fg / bg | Lc | Verdict |
9
9
  |---|---|---|---|---|
10
10
  | root (Thổ default) | text-accent on white (bold labels) | #6E3B0E / #FFFFFF | 90.7 | ✓ |
11
11
  | root (Thổ default) | text-accent on tint (bold labels) | #6E3B0E / #FBF4E9 | 84.6 | ✓ |
@@ -16,110 +16,98 @@ Nudge token cho v2.0: bright làm sáng cho clay, hoa, lava, plasma, thủy, oce
16
16
  | tho | text-accent on tint (bold labels) | #6E3B0E / #FBF4E9 | 84.6 | ✓ |
17
17
  | tho | accent-bright on ink (headings) | #F4BA17 / #45210E | 66.3 | ✓ |
18
18
  | tho | accent-on on accent-bright (CTA text) | #45210E / #F4BA17 | 66.3 | ✓ |
19
- | tho | accent-bright on dark panel (dark labels) | #F4BA17 / #221710 | 69.2 | ✓ |
20
- | tho · clay | text-accent on white (bold labels) | #8F5230 / #FFFFFF | 80.4 | ✓ |
21
- | tho · clay | text-accent on tint (bold labels) | #8F5230 / #F8EDE4 | 70.7 | ✓ |
22
- | tho · clay | accent-bright on ink (headings) | #EDBF9D / #2E1607 | 71.6 | ✓ |
23
- | tho · clay | accent-on on accent-bright (CTA text) | #2E1607 / #EDBF9D | 72 | ✓ |
24
- | tho · clay | accent-bright on dark panel (dark labels) | #EDBF9D / #221710 | 72 | ✓ |
25
- | tho · sand | text-accent on white (bold labels) | #8A6F3C / #FFFFFF | 72.9 | ✓ |
26
- | tho · sand | text-accent on tint (bold labels) | #8A6F3C / #FAF3E3 | 66 | ✓ |
27
- | tho · sand | accent-bright on ink (headings) | #EFDCB2 / #3A2A10 | 82 | ✓ |
28
- | tho · sand | accent-on on accent-bright (CTA text) | #3A2A10 / #EFDCB2 | 80.8 | ✓ |
29
- | tho · sand | accent-bright on dark panel (dark labels) | #EFDCB2 / #221710 | 85.1 | ✓ |
30
- | hoa | text-accent on white (bold labels) | #A93E14 / #FFFFFF | 80 | ✓ |
31
- | hoa | text-accent on tint (bold labels) | #A93E14 / #FBEADF | 69.3 | ✓ |
32
- | hoa | accent-bright on ink (headings) | #F6A26B / #231007 | 62 | ✓ |
33
- | hoa | accent-on on accent-bright (CTA text) | #231007 / #F6A26B | 63.3 | ✓ |
34
- | hoa | accent-bright on dark panel (dark labels) | #F6A26B / #221710 | 61.6 | ✓ |
35
- | hoa · lava | text-accent on white (bold labels) | #9B2D14 / #FFFFFF | 85.1 | ✓ |
36
- | hoa · lava | text-accent on tint (bold labels) | #9B2D14 / #FAE5DC | 72.1 | ✓ |
37
- | hoa · lava | accent-bright on ink (headings) | #F6AC85 / #1D0B05 | 66.5 | ✓ |
38
- | hoa · lava | accent-on on accent-bright (CTA text) | #1D0B05 / #F6AC85 | 67.6 | ✓ |
39
- | hoa · lava | accent-bright on dark panel (dark labels) | #F6AC85 / #221710 | 65.7 | ✓ |
40
- | hoa · plasma | text-accent on white (bold labels) | #B02348 / #FFFFFF | 81.2 | ✓ |
41
- | hoa · plasma | text-accent on tint (bold labels) | #B02348 / #FBE6EB | 69.3 | ✓ |
42
- | hoa · plasma | accent-bright on ink (headings) | #F7A8B8 / #200812 | 66.8 | ✓ |
43
- | hoa · plasma | accent-on on accent-bright (CTA text) | #200812 / #F7A8B8 | 67.9 | ✓ |
44
- | hoa · plasma | accent-bright on dark panel (dark labels) | #F7A8B8 / #221710 | 66.1 | ✓ |
45
- | thuy | text-accent on white (bold labels) | #2F5E6B / #FFFFFF | 84.7 | ✓ |
46
- | thuy | text-accent on tint (bold labels) | #2F5E6B / #E6F1F2 | 75.1 | ✓ |
47
- | thuy | accent-bright on ink (headings) | #A6D0DA / #0E1D20 | 72.4 | ✓ |
48
- | thuy | accent-on on accent-bright (CTA text) | #0E1D20 / #A6D0DA | 72.8 | ✓ |
49
- | thuy | accent-bright on dark panel (dark labels) | #A6D0DA / #221710 | 72.5 | ✓ |
50
- | thuy · ocean | text-accent on white (bold labels) | #1C3E56 / #FFFFFF | 95.7 | ✓ |
51
- | thuy · ocean | text-accent on tint (bold labels) | #1C3E56 / #E4EEF4 | 84.7 | ✓ |
52
- | thuy · ocean | accent-bright on ink (headings) | #A9CCE0 / #0B161E | 71.8 | ✓ |
53
- | thuy · ocean | accent-on on accent-bright (CTA text) | #0B161E / #A9CCE0 | 72.6 | ✓ |
54
- | thuy · ocean | accent-bright on dark panel (dark labels) | #A9CCE0 / #221710 | 71.4 | ✓ |
55
- | thuy · mist | text-accent on white (bold labels) | #4A686E / #FFFFFF | 80 | ✓ |
56
- | thuy · mist | text-accent on tint (bold labels) | #4A686E / #F0F6F7 | 73.9 | ✓ |
57
- | thuy · mist | accent-bright on ink (headings) | #C4DADD / #16262A | 78.9 | ✓ |
58
- | thuy · mist | accent-on on accent-bright (CTA text) | #16262A / #C4DADD | 78.5 | ✓ |
59
- | thuy · mist | accent-bright on dark panel (dark labels) | #C4DADD / #221710 | 80.3 | ✓ |
60
- | moc | text-accent on white (bold labels) | #4C6B35 / #FFFFFF | 80.2 | ✓ |
61
- | moc | text-accent on tint (bold labels) | #4C6B35 / #EEF3E2 | 71.8 | ✓ |
62
- | moc | accent-bright on ink (headings) | #A9C177 / #18200F | 62.3 | ✓ |
63
- | moc | accent-on on accent-bright (CTA text) | #18200F / #A9C177 | 63.2 | ✓ |
64
- | moc | accent-bright on dark panel (dark labels) | #A9C177 / #221710 | 62.8 | ✓ |
65
- | moc · bamboo | text-accent on white (bold labels) | #5B7237 / #FFFFFF | 76.7 | ✓ |
66
- | moc · bamboo | text-accent on tint (bold labels) | #5B7237 / #F3F7E8 | 70.8 | ✓ |
67
- | moc · bamboo | accent-bright on ink (headings) | #C4D69B / #1C240F | 75 | ✓ |
68
- | moc · bamboo | accent-on on accent-bright (CTA text) | #1C240F / #C4D69B | 75 | ✓ |
69
- | moc · bamboo | accent-bright on dark panel (dark labels) | #C4D69B / #221710 | 76 | ✓ |
70
- | moc · forest | text-accent on white (bold labels) | #31481F / #FFFFFF | 93.4 | ✓ |
71
- | moc · forest | text-accent on tint (bold labels) | #31481F / #E9EFE1 | 82.6 | ✓ |
72
- | moc · forest | accent-bright on ink (headings) | #B3CE9B / #101708 | 71 | ✓ |
73
- | moc · forest | accent-on on accent-bright (CTA text) | #101708 / #B3CE9B | 71.8 | ✓ |
74
- | moc · forest | accent-bright on dark panel (dark labels) | #B3CE9B / #221710 | 70.5 | ✓ |
75
- | kim | text-accent on white (bold labels) | #6E6151 / #FFFFFF | 80.1 | ✓ |
76
- | kim | text-accent on tint (bold labels) | #6E6151 / #F3EFE6 | 70.7 | ✓ |
77
- | kim | accent-bright on ink (headings) | #D8CCB6 / #221C12 | 74.7 | ✓ |
78
- | kim | accent-on on accent-bright (CTA text) | #221C12 / #D8CCB6 | 74.9 | ✓ |
79
- | kim | accent-bright on dark panel (dark labels) | #D8CCB6 / #221710 | 75.1 | ✓ |
80
- | kim · steel | text-accent on white (bold labels) | #565C5E / #FFFFFF | 83.5 | ✓ |
81
- | kim · steel | text-accent on tint (bold labels) | #565C5E / #EFF1F1 | 74.9 | ✓ |
82
- | kim · steel | accent-bright on ink (headings) | #C2C6C6 / #191D1E | 70 | ✓ |
83
- | kim · steel | accent-on on accent-bright (CTA text) | #191D1E / #C2C6C6 | 70.6 | ✓ |
84
- | kim · steel | accent-bright on dark panel (dark labels) | #C2C6C6 / #221710 | 70.3 | ✓ |
85
- | kim · titanium | text-accent on white (bold labels) | #56504A / #FFFFFF | 87.6 | ✓ |
86
- | kim · titanium | text-accent on tint (bold labels) | #56504A / #EFEBE5 | 76 | ✓ |
87
- | kim · titanium | accent-bright on ink (headings) | #D9CFC0 / #171310 | 77.5 | ✓ |
88
- | kim · titanium | accent-on on accent-bright (CTA text) | #171310 / #D9CFC0 | 77.9 | ✓ |
89
- | kim · titanium | accent-bright on dark panel (dark labels) | #D9CFC0 / #221710 | 76.9 | ✓ |
19
+ | tho | accent-bright on dark panel (dark labels) | #FEC42C / #221710 | 75 | ✓ |
20
+ | tho · sand | text-accent on white (bold labels) | #90825E / #FFFFFF | 65.4 | ✓ |
21
+ | tho · sand | text-accent on tint (bold labels) | #90825E / #FBF7EA | 60.6 | ✓ |
22
+ | tho · sand | accent-bright on ink (headings) | #F6EBCC / #292414 | 92.3 | ✓ |
23
+ | tho · sand | accent-on on accent-bright (CTA text) | #292414 / #F6EBCC | 90.8 | ✓ |
24
+ | tho · sand | accent-bright on dark panel (dark labels) | #F6EBCC / #221710 | 93.8 | ✓ |
25
+ | tho · clay | text-accent on white (bold labels) | #201300 / #FFFFFF | 104.8 | ✓ |
26
+ | tho · clay | text-accent on tint (bold labels) | #201300 / #FFF6E7 | 100 | ✓ |
27
+ | tho · clay | accent-bright on ink (headings) | #DEC7A2 / #2D220E | 71.7 | ✓ |
28
+ | tho · clay | accent-on on accent-bright (CTA text) | #2D220E / #DEC7A2 | 71.8 | ✓ |
29
+ | tho · clay | accent-bright on dark panel (dark labels) | #E4CDA8 / #221710 | 76.7 | ✓ |
30
+ | hoa | text-accent on white (bold labels) | #B47054 / #FFFFFF | 66.2 | ✓ |
31
+ | hoa | text-accent on tint (bold labels) | #B47054 / #FFF4F0 | 60.9 | ✓ |
32
+ | hoa | accent-bright on ink (headings) | #FED3C3 / #381B10 | 82.8 | ✓ |
33
+ | hoa | accent-on on accent-bright (CTA text) | #381B10 / #FED3C3 | 82.1 | ✓ |
34
+ | hoa | accent-bright on dark panel (dark labels) | #FED3C3 / #221710 | 84.2 | ✓ |
35
+ | hoa · plasma | text-accent on white (bold labels) | #967C75 / #FFFFFF | 66.1 | ✓ |
36
+ | hoa · plasma | text-accent on tint (bold labels) | #967C75 / #FEF4F2 | 60.7 | ✓ |
37
+ | hoa · plasma | accent-bright on ink (headings) | #FCE6DF / #2C211E | 91.8 | ✓ |
38
+ | hoa · plasma | accent-on on accent-bright (CTA text) | #2C211E / #FCE6DF | 90.4 | ✓ |
39
+ | hoa · plasma | accent-bright on dark panel (dark labels) | #FCE6DF / #221710 | 93.2 | ✓ |
40
+ | hoa · lava | text-accent on white (bold labels) | #280D00 / #FFFFFF | 104.7 | ✓ |
41
+ | hoa · lava | text-accent on tint (bold labels) | #280D00 / #FFF4EF | 99.4 | ✓ |
42
+ | hoa · lava | accent-bright on ink (headings) | #F1BEA4 / #361D0F | 71 | ✓ |
43
+ | hoa · lava | accent-on on accent-bright (CTA text) | #361D0F / #F1BEA4 | 71.2 | ✓ |
44
+ | hoa · lava | accent-bright on dark panel (dark labels) | #F8C4AA / #221710 | 76.2 | ✓ |
45
+ | thuy | text-accent on white (bold labels) | #108EA0 / #FFFFFF | 65.8 | ✓ |
46
+ | thuy | text-accent on tint (bold labels) | #108EA0 / #E7FBFF | 61.2 | ✓ |
47
+ | thuy | accent-bright on ink (headings) | #99EEFF / #012A30 | 85.3 | ✓ |
48
+ | thuy | accent-on on accent-bright (CTA text) | #012A30 / #99EEFF | 84.3 | ✓ |
49
+ | thuy | accent-bright on dark panel (dark labels) | #99EEFF / #221710 | 87.2 | ✓ |
50
+ | thuy · mist | text-accent on white (bold labels) | #5A8A90 / #FFFFFF | 65.8 | ✓ |
51
+ | thuy · mist | text-accent on tint (bold labels) | #5A8A90 / #EBFAFC | 61.1 | ✓ |
52
+ | thuy · mist | accent-bright on ink (headings) | #CDF4F9 / #13282B | 93.1 | ✓ |
53
+ | thuy · mist | accent-on on accent-bright (CTA text) | #13282B / #CDF4F9 | 91.5 | ✓ |
54
+ | thuy · mist | accent-bright on dark panel (dark labels) | #CDF4F9 / #221710 | 94.7 | ✓ |
55
+ | thuy · ocean | text-accent on white (bold labels) | #011A21 / #FFFFFF | 104.5 | ✓ |
56
+ | thuy · ocean | text-accent on tint (bold labels) | #011A21 / #EAFAFF | 99.8 | ✓ |
57
+ | thuy · ocean | accent-bright on ink (headings) | #A8D3E0 / #10282F | 72.7 | ✓ |
58
+ | thuy · ocean | accent-on on accent-bright (CTA text) | #10282F / #A8D3E0 | 72.6 | ✓ |
59
+ | thuy · ocean | accent-bright on dark panel (dark labels) | #ABD6E3 / #221710 | 76.1 | ✓ |
60
+ | moc | text-accent on white (bold labels) | #629122 / #FFFFFF | 64.9 | ✓ |
61
+ | moc | text-accent on tint (bold labels) | #629122 / #EFFCE3 | 60.5 | ✓ |
62
+ | moc | accent-bright on ink (headings) | #C5ED9C / #182A00 | 85.2 | ✓ |
63
+ | moc | accent-on on accent-bright (CTA text) | #182A00 / #C5ED9C | 84.2 | ✓ |
64
+ | moc | accent-bright on dark panel (dark labels) | #C5ED9C / #221710 | 86.9 | ✓ |
65
+ | moc · bamboo | text-accent on white (bold labels) | #7C8965 / #FFFFFF | 64.9 | ✓ |
66
+ | moc · bamboo | text-accent on tint (bold labels) | #7C8965 / #F4F9ED | 60.2 | ✓ |
67
+ | moc · bamboo | accent-bright on ink (headings) | #E5F1D2 / #212617 | 93 | ✓ |
68
+ | moc · bamboo | accent-on on accent-bright (CTA text) | #212617 / #E5F1D2 | 91.4 | ✓ |
69
+ | moc · bamboo | accent-bright on dark panel (dark labels) | #E5F1D2 / #221710 | 94.5 | ✓ |
70
+ | moc · forest | text-accent on white (bold labels) | #051D00 / #FFFFFF | 104.4 | ✓ |
71
+ | moc · forest | text-accent on tint (bold labels) | #051D00 / #ECFDE7 | 100.2 | ✓ |
72
+ | moc · forest | accent-bright on ink (headings) | #B0D8A3 / #162A0E | 73.2 | ✓ |
73
+ | moc · forest | accent-on on accent-bright (CTA text) | #162A0E / #B0D8A3 | 73.2 | ✓ |
74
+ | moc · forest | accent-bright on dark panel (dark labels) | #B0D8A3 / #221710 | 75 | ✓ |
75
+ | kim | text-accent on white (bold labels) | #AC780B / #FFFFFF | 65.8 | ✓ |
76
+ | kim | text-accent on tint (bold labels) | #AC780B / #FFF5E7 | 60.5 | ✓ |
77
+ | kim | accent-bright on ink (headings) | #FDD89F / #312002 | 83.5 | ✓ |
78
+ | kim | accent-on on accent-bright (CTA text) | #312002 / #FDD89F | 82.8 | ✓ |
79
+ | kim | accent-bright on dark panel (dark labels) | #FDD89F / #221710 | 85 | ✓ |
80
+ | kim · titanium | text-accent on white (bold labels) | #947F65 / #FFFFFF | 65.8 | ✓ |
81
+ | kim · titanium | text-accent on tint (bold labels) | #947F65 / #FDF5ED | 60.5 | ✓ |
82
+ | kim · titanium | accent-bright on ink (headings) | #FBE8D2 / #2B2217 | 92 | ✓ |
83
+ | kim · titanium | accent-on on accent-bright (CTA text) | #2B2217 / #FBE8D2 | 90.6 | ✓ |
84
+ | kim · titanium | accent-bright on dark panel (dark labels) | #FBE8D2 / #221710 | 93.4 | ✓ |
85
+ | kim · steel | text-accent on white (bold labels) | #1F1400 / #FFFFFF | 104.8 | ✓ |
86
+ | kim · steel | text-accent on tint (bold labels) | #1F1400 / #FEF6E7 | 99.8 | ✓ |
87
+ | kim · steel | accent-bright on ink (headings) | #DCC8A2 / #2D220E | 71.8 | ✓ |
88
+ | kim · steel | accent-on on accent-bright (CTA text) | #2D220E / #DCC8A2 | 71.9 | ✓ |
89
+ | kim · steel | accent-bright on dark panel (dark labels) | #DFCBA5 / #221710 | 75.1 | ✓ |
90
90
 
91
- **Thất bại: 0.** Mọi cặp chữ pass Lc ≥ 60.
91
+ **Failures: 0.** All text pairings pass Lc ≥ 60.
92
92
 
93
- ## Màu semantic dark-theme (WCAG, thêm v2.8.0)
93
+ ## Dark pack APCA floors (gate twin)
94
94
 
95
- Foreground semantic light-theme fail trên bề mặt tối (~2.5:1), nên dark theme override chúng. Contrast WCAG trên panel tối `#221710` (và khi làm fill kèm dark ink `#1a1108`):
96
- | Vai trò | Giá trị dark | trên panel | làm fill w/ ink | Kết quả |
95
+ Targets match `_audit/apca-dark-preview.html`: bright ≥ 75 · accent ≥ 60 · on/strong ≥ 75 · ink-on-tint ≥ 75.
96
+ | Pack | bright | accent | on | ink |
97
97
  |---|---|---|---|---|
98
- | success | #4ADE80 | 10.06 | 10.69 | ✓ |
99
- | danger | #F87171 | 6.34 | 6.73 | ✓ |
100
- | warning | #FBBF24 | 10.50 | 11.16 | ✓ |
101
- | info | #7CB2FB | 8.03 | 8.53 | ✓ |
98
+ | tho | 75 | 69.2 | 75.6 | 76.8 |
99
+ | tho · sand | 93.8 | 92.7 | 75.6 | 91.5 |
100
+ | tho · clay | 76.7 | 60.4 | 94.1 | 76.2 |
101
+ | hoa | 84.2 | 68.2 | 75.1 | 81.9 |
102
+ | hoa · plasma | 93.2 | 91.2 | 75 | 90.9 |
103
+ | hoa · lava | 76.2 | 61.1 | 94 | 75.7 |
104
+ | thuy | 87.2 | 72.8 | 76 | 84.4 |
105
+ | thuy · mist | 94.7 | 94 | 75.9 | 92 |
106
+ | thuy · ocean | 76.1 | 60.1 | 93.9 | 75.1 |
107
+ | moc | 86.9 | 71.8 | 75.4 | 84.4 |
108
+ | moc · bamboo | 94.5 | 93.6 | 75.3 | 92 |
109
+ | moc · forest | 75 | 60.8 | 93.7 | 76.3 |
110
+ | kim | 85 | 69.2 | 75.6 | 82.6 |
111
+ | kim · titanium | 93.4 | 92.1 | 75.8 | 91.1 |
112
+ | kim · steel | 75.1 | 60.7 | 94 | 76.4 |
102
113
 
103
- Core dark cũng remap nút primary sang Ochre (`#f4ba17` trên `#1a1108`) và làm ấm border field — để không control dark nào low-contrast. Shadow dark nhuốm umber (yếu trên nền tối vốn vậy); hairline border dark tách panel thay thế.
104
- File này được generate — chạy lại script APCA sweep sau mọi đổi token.
105
-
106
- ## Pack elemental dark — xác minh APCA (v4.0.0, Th7 2026)
107
-
108
- Sinh với pack dark đã owner duyệt; đo bằng cùng implementation SAPC-4g như `_audit/apca-dark-preview.html` (cũng là regression gate). Mục tiêu: bright ≥ 75 · accent ≥ 60 · button ink ≥ 75 · ink-on-tint ≥ 75 — **15/15 pack pass**.
109
- | Pack | bright | accent | on/strong | ink/tint |
110
- |---|---|---|---|---|
111
- | tho | 75 | 69.2 | 75.1 | 75.3 |
112
- | tho · clay | 75.7 | 61.5 | 76 | 76.1 |
113
- | tho · sand | 85.1 | 74.3 | 75.7 | 83.6 |
114
- | hoa | 75.1 | 61.5 | 75.6 | 75.9 |
115
- | hoa · lava | 75 | 60.6 | 83.5 | 75.8 |
116
- | hoa · plasma | 75.9 | 60.8 | 75.4 | 76.7 |
117
- | thuy | 76.6 | 61.6 | 76.7 | 76.6 |
118
- | thuy · ocean | 77.2 | 60 | 86.6 | 75.5 |
119
- | thuy · mist | 80.3 | 66.6 | 76 | 78.7 |
120
- | moc | 76 | 60.1 | 76 | 76.1 |
121
- | moc · bamboo | 76 | 62.8 | 75 | 76.2 |
122
- | moc · forest | 76.4 | 60.9 | 88.6 | 76.6 |
123
- | kim | 75.1 | 60.1 | 75.2 | 75.4 |
124
- | kim · steel | 76.3 | 61.1 | 76 | 76.6 |
125
- | kim · titanium | 76.9 | 60.9 | 79.4 | 75.5 |