@cyberskill/design 1.2.0 → 1.3.9

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 (232) hide show
  1. package/DESIGN.md +11 -9
  2. package/README.md +28 -24
  3. package/SKILL.md +18 -9
  4. package/THIRD-PARTY-NOTICES.md +35 -0
  5. package/VERSION +1 -1
  6. package/_ds_bundle.js +701 -1342
  7. package/_esm/cs.mjs +2 -2
  8. package/_esm/react.mjs +6 -1
  9. package/_vendor/NOTICE.md +16 -0
  10. package/_vendor/babel/README.md +7 -0
  11. package/_vendor/babel/babel.min.js +4 -0
  12. package/_vendor/react/README.md +3 -0
  13. package/_vendor/react/react-dom.production.min.js +1 -0
  14. package/_vendor/react/react.production.min.js +1 -0
  15. package/assets/aurora-hoa.webp +0 -0
  16. package/assets/aurora-kim.webp +0 -0
  17. package/assets/aurora-moc.webp +0 -0
  18. package/assets/aurora-tho.webp +0 -0
  19. package/assets/aurora-thuy.webp +0 -0
  20. package/base/ai.css +8 -3
  21. package/base/collections.css +10 -4
  22. package/base/components.css +5 -2
  23. package/base/controls.css +58 -21
  24. package/base/data.css +1 -1
  25. package/base/feedback.css +9 -2
  26. package/base/forms.css +1 -1
  27. package/base/glass.css +1 -1
  28. package/base/interaction.css +6 -2
  29. package/base/navigation.css +1 -1
  30. package/base/reset.css +7 -1
  31. package/base/responsive.css +13 -12
  32. package/base/shell.css +8 -2
  33. package/components/_i18n/i18n.js +28 -3
  34. package/components/_i18n/strings.js +42 -24
  35. package/components/ai/ChatMessage.d.ts +2 -0
  36. package/components/ai/ChatMessage.jsx +8 -4
  37. package/components/ai/ConfidenceMeter.d.ts +2 -0
  38. package/components/ai/HumanReviewGate.d.ts +2 -0
  39. package/components/ai/PromptInput.d.ts +2 -0
  40. package/components/ai/TypingIndicator.d.ts +2 -0
  41. package/components/ai/ai-conversation.card.html +3 -3
  42. package/components/ai/ai-lumi.card.html +3 -3
  43. package/components/ai/ai.card.html +3 -3
  44. package/components/brand/brand.card.html +3 -3
  45. package/components/button/buttons.card.html +3 -3
  46. package/components/data/Image.jsx +18 -2
  47. package/components/data/Sortable.d.ts +5 -1
  48. package/components/data/Sortable.jsx +42 -9
  49. package/components/data/Sortable.prompt.md +4 -2
  50. package/components/data/Terminal.jsx +3 -2
  51. package/components/data/Tooltip.d.ts +2 -0
  52. package/components/data/Tooltip.jsx +6 -3
  53. package/components/data/Tree.d.ts +2 -1
  54. package/components/data/Tree.jsx +137 -16
  55. package/components/data/Tree.prompt.md +1 -1
  56. package/components/data/collections.card.html +3 -3
  57. package/components/data/data.card.html +3 -3
  58. package/components/datatable/DataTable.d.ts +24 -1
  59. package/components/datatable/DataTable.jsx +78 -5
  60. package/components/datatable/DataTable.prompt.md +2 -1
  61. package/components/datatable/datatable.card.html +20 -16
  62. package/components/dialog/dialog.card.html +3 -3
  63. package/components/feedback/Alert.d.ts +2 -0
  64. package/components/feedback/Alert.jsx +8 -2
  65. package/components/feedback/EmptyState.d.ts +2 -0
  66. package/components/feedback/EmptyState.jsx +6 -3
  67. package/components/feedback/ProgressBar.d.ts +2 -0
  68. package/components/feedback/ProgressBar.jsx +6 -3
  69. package/components/feedback/Toast.jsx +15 -1
  70. package/components/feedback/Toast.prompt.md +2 -1
  71. package/components/feedback/feedback-2.card.html +3 -3
  72. package/components/feedback/feedback.card.html +3 -3
  73. package/components/forms/Cascader.jsx +7 -2
  74. package/components/forms/FileUpload.d.ts +2 -0
  75. package/components/forms/Form.d.ts +3 -1
  76. package/components/forms/Form.jsx +9 -1
  77. package/components/forms/Form.prompt.md +1 -1
  78. package/components/forms/Mentions.d.ts +1 -1
  79. package/components/forms/Mentions.jsx +59 -7
  80. package/components/forms/Mentions.prompt.md +3 -1
  81. package/components/forms/Rating.d.ts +3 -2
  82. package/components/forms/Rating.jsx +34 -3
  83. package/components/forms/Rating.prompt.md +1 -1
  84. package/components/forms/Select.d.ts +2 -0
  85. package/components/forms/Select.jsx +6 -2
  86. package/components/forms/Slider.d.ts +2 -0
  87. package/components/forms/Slider.jsx +5 -2
  88. package/components/forms/Switch.d.ts +2 -0
  89. package/components/forms/Switch.jsx +7 -9
  90. package/components/forms/Toggle.d.ts +2 -0
  91. package/components/forms/Toggle.jsx +14 -2
  92. package/components/forms/forms-2.card.html +3 -3
  93. package/components/forms/forms.card.html +3 -3
  94. package/components/icon/Icon.d.ts +1 -1
  95. package/components/icon/Icon.prompt.md +1 -1
  96. package/components/icon/icon.card.html +3 -3
  97. package/components/logo/logo.card.html +3 -3
  98. package/components/navigation/CommandPalette.d.ts +2 -0
  99. package/components/navigation/Menu.d.ts +2 -0
  100. package/components/navigation/Menu.jsx +60 -6
  101. package/components/navigation/Steps.d.ts +2 -0
  102. package/components/navigation/Steps.jsx +6 -3
  103. package/components/navigation/Tabs.d.ts +2 -0
  104. package/components/navigation/Tabs.jsx +6 -3
  105. package/components/navigation/Toolbar.d.ts +3 -2
  106. package/components/navigation/Toolbar.jsx +117 -11
  107. package/components/navigation/Toolbar.prompt.md +1 -1
  108. package/components/navigation/navigation.card.html +3 -3
  109. package/components/navigation/shell.card.html +3 -3
  110. package/components/overlays/ContextMenu.d.ts +2 -0
  111. package/components/overlays/ContextMenu.jsx +6 -3
  112. package/components/overlays/Drawer.d.ts +2 -0
  113. package/components/overlays/alertdialog.card.html +3 -3
  114. package/components/overlays/overlays.card.html +3 -3
  115. package/components/textfield/textfield.card.html +3 -3
  116. package/dist/styles.min.css +312 -64
  117. package/docs/benchmark-rubric.md +2 -2
  118. package/docs/ci-cd.md +18 -13
  119. package/docs/consumer-grant.md +4 -1
  120. package/docs/consuming.md +16 -12
  121. package/docs/contrast-report.md +81 -1
  122. package/docs/conventions.md +18 -5
  123. package/docs/decisions.md +41 -3
  124. package/docs/deploy.md +19 -6
  125. package/docs/design-styles.md +2 -2
  126. package/docs/doctrine.md +51 -0
  127. package/docs/figma.md +2 -0
  128. package/docs/live-hub.md +3 -1
  129. package/docs/products.md +1 -1
  130. package/docs/quality-gates.md +24 -12
  131. package/docs/release-notes.md +1 -1
  132. package/docs/release-runbook.md +78 -0
  133. package/docs/storybook.md +3 -3
  134. package/docs/sync.md +8 -8
  135. package/docs/template-schema-v2.md +1 -1
  136. package/docs/vi/benchmark-rubric.md +2 -2
  137. package/docs/vi/ci-cd.md +17 -14
  138. package/docs/vi/consumer-grant.md +4 -1
  139. package/docs/vi/consuming.md +16 -12
  140. package/docs/vi/contrast-report.md +81 -1
  141. package/docs/vi/conventions.md +19 -6
  142. package/docs/vi/decisions.md +40 -3
  143. package/docs/vi/deploy.md +19 -6
  144. package/docs/vi/design-styles.md +1 -1
  145. package/docs/vi/doctrine.md +51 -0
  146. package/docs/vi/figma.md +2 -0
  147. package/docs/vi/live-hub.md +3 -1
  148. package/docs/vi/products.md +1 -1
  149. package/docs/vi/quality-gates.md +23 -12
  150. package/docs/vi/release-notes.md +1 -1
  151. package/docs/vi/release-runbook.md +78 -0
  152. package/docs/vi/storybook.md +3 -3
  153. package/docs/vi/sync.md +7 -7
  154. package/docs/vi/template-schema-v2.md +1 -1
  155. package/docs/viewer.html +16 -5
  156. package/fonts/OFL.txt +98 -0
  157. package/guidelines/atomic-view.html +2 -2
  158. package/guidelines/brand-imagery.html +1 -1
  159. package/guidelines/elements-variants.html +5 -5
  160. package/guidelines/spacing-breakpoints.html +2 -1
  161. package/guidelines/surfaces-glass.html +1 -1
  162. package/llms.txt +18 -11
  163. package/package.json +28 -8
  164. package/templates/app-shell/AppShell.dc.html +3 -3
  165. package/templates/app-shell/content-schema.json +7 -0
  166. package/templates/article/Article.dc.html +3 -3
  167. package/templates/article/content-schema.json +7 -0
  168. package/templates/auth/Auth.dc.html +26 -10
  169. package/templates/auth/content-schema.json +25 -0
  170. package/templates/dashboard/Dashboard.dc.html +4 -4
  171. package/templates/dashboard/content-schema.json +7 -0
  172. package/templates/delivery-change-note/DeliveryChangeNote.dc.html +2 -2
  173. package/templates/delivery-runbook/DeliveryRunbook.dc.html +2 -2
  174. package/templates/email-safe/email-announcement.html +2 -2
  175. package/templates/email-safe/email-dunning.html +2 -2
  176. package/templates/email-safe/email-investor.html +2 -2
  177. package/templates/email-safe/email-launch.html +2 -2
  178. package/templates/email-safe/email-newsletter.html +2 -2
  179. package/templates/email-safe/email-status.html +2 -2
  180. package/templates/email-safe/email-transactional.html +2 -2
  181. package/templates/finance-dunning-email/FinanceDunningEmail.dc.html +2 -2
  182. package/templates/finance-expense-report/FinanceExpenseReport.dc.html +2 -2
  183. package/templates/finance-invoice/FinanceInvoice.dc.html +2 -2
  184. package/templates/finance-quote/FinanceQuote.dc.html +4 -4
  185. package/templates/hr-interview-kit/HrInterviewKit.dc.html +1 -1
  186. package/templates/marketing-case-study/MarketingCaseStudy.dc.html +1 -1
  187. package/templates/marketing-page/MarketingPage.dc.html +3 -3
  188. package/templates/marketing-page/content-schema.json +1 -0
  189. package/templates/settings/Settings.dc.html +3 -3
  190. package/templates/settings/content-schema.json +7 -0
  191. package/tokens/element-seeds.json +2 -2
  192. package/tokens/elements.css +193 -19
  193. package/tokens/native/CSTokens.kt +3 -2
  194. package/tokens/native/CSTokens.swift +3 -2
  195. package/tokens/native/cs_tokens.dart +3 -2
  196. package/tokens/provenance.json +8 -8
  197. package/tokens/spacing.css +2 -1
  198. package/tokens/tokens.dtcg.json +19 -14
  199. package/tokens/tokens.js +16 -15
  200. package/tokens/tokens.json +15 -14
  201. package/ui_kits/deck/index.html +1 -1
  202. package/ui_kits/status-hub/StatusHub.jsx +1 -1
  203. package/ui_kits/status-hub/login.html +52 -10
  204. package/ui_kits/status-hub/project.html +1 -1
  205. package/ui_kits/status-hub/settings.html +1 -1
  206. package/ui_kits/website/Website.jsx +1 -1
  207. package/ui_kits/website/careers.html +2 -2
  208. package/ui_kits/website/chat.html +1 -1
  209. package/ui_kits/website/site.css +1 -1
  210. package/ui_kits/website/work.html +2 -2
  211. package/assets/aurora-hoa.png +0 -0
  212. package/assets/aurora-kim.png +0 -0
  213. package/assets/aurora-moc.png +0 -0
  214. package/assets/aurora-thuy.png +0 -0
  215. package/docs/decisions/container-query-migration.md +0 -18
  216. package/docs/decisions/overlay-manager-design.md +0 -101
  217. package/docs/plans/cyberskill-design-system-audit-and-12-month-evolution-plan.md +0 -1490
  218. package/docs/status/assets/favicon.svg +0 -5
  219. package/docs/status/assets/status-legacy.css +0 -399
  220. package/docs/status/assets/status-legacy.js +0 -505
  221. package/docs/status/assets/status.css +0 -644
  222. package/docs/status/assets/status.js +0 -1308
  223. package/docs/status/data/status-feed.json +0 -1
  224. package/docs/status/data/task/TASK-REL-001.js +0 -1
  225. package/docs/status/data/task/TASK-REL-002.js +0 -1
  226. package/docs/status/index.html +0 -46
  227. package/docs/status/roadmap.html +0 -4
  228. package/docs/status/status-legacy.html +0 -122
  229. package/docs/tasks/BACKLOG.md +0 -26
  230. package/docs/tasks/_state/commit-links.yaml +0 -14
  231. package/docs/tasks/release/TASK-REL-001-launch-1-1-0/spec.md +0 -55
  232. package/docs/tasks/release/TASK-REL-002-republish-1-1-1/spec.md +0 -54
package/tokens/tokens.js CHANGED
@@ -1,8 +1,8 @@
1
- // CyberSkill design tokens — generated from tokens/*.css (v1.2.0). Do not edit by hand.
1
+ // CyberSkill design tokens — generated from tokens/*.css (v1.3.9). Do not edit by hand.
2
2
  export const tokens = {
3
3
  "$meta": {
4
4
  "system": "CyberSkill Design System",
5
- "version": "1.2.0",
5
+ "version": "1.3.9",
6
6
  "generated": "2026-07-23",
7
7
  "note": "Generated from tokens/*.css. Root grouped by category; theme/element scopes carry overrides only. Regenerate after any token change (see docs/conventions.md)."
8
8
  },
@@ -66,7 +66,7 @@ export const tokens = {
66
66
  "--cs-accent-ink": "#45210E",
67
67
  "--cs-accent-glow": "rgba(244, 186, 23, 0.48)",
68
68
  "--cs-accent-grad-a": "#F4BA17",
69
- "--cs-accent-grad-b": "#FCAF91",
69
+ "--cs-accent-grad-b": "#F3B958",
70
70
  "--cs-accent-on-strong": "#1A1108"
71
71
  },
72
72
  "depth": {
@@ -135,6 +135,7 @@ export const tokens = {
135
135
  },
136
136
  "breakpoint": {
137
137
  "--cs-breakpoint-xs": "0px",
138
+ "--cs-breakpoint-phone": "360px",
138
139
  "--cs-breakpoint-sm": "640px",
139
140
  "--cs-breakpoint-md": "768px",
140
141
  "--cs-breakpoint-lg": "1024px",
@@ -274,9 +275,9 @@ export const tokens = {
274
275
  "--cs-accent-ink": "#292414",
275
276
  "--cs-accent-glow": "rgba(248, 233, 192, 0.48)",
276
277
  "--cs-accent-grad-a": "#F8E9C0",
277
- "--cs-accent-grad-b": "#FCAF91",
278
+ "--cs-accent-grad-b": "#F3B958",
278
279
  "--cs-color-text-accent": "#90825E",
279
- "--cs-color-link": "#90825E"
280
+ "--cs-color-link": "#7B6D4A"
280
281
  },
281
282
  "tho": {
282
283
  "--cs-accent": "#F4BA17",
@@ -288,7 +289,7 @@ export const tokens = {
288
289
  "--cs-accent-ink": "#45210E",
289
290
  "--cs-accent-glow": "rgba(244, 186, 23, 0.48)",
290
291
  "--cs-accent-grad-a": "#F4BA17",
291
- "--cs-accent-grad-b": "#FCAF91"
292
+ "--cs-accent-grad-b": "#F3B958"
292
293
  },
293
294
  "tho.clay": {
294
295
  "--cs-accent": "#513801",
@@ -300,7 +301,7 @@ export const tokens = {
300
301
  "--cs-accent-ink": "#2D220E",
301
302
  "--cs-accent-glow": "rgba(81, 56, 1, 0.48)",
302
303
  "--cs-accent-grad-a": "#513801",
303
- "--cs-accent-grad-b": "#FCAF91",
304
+ "--cs-accent-grad-b": "#F3B958",
304
305
  "--cs-color-text-accent": "#201300",
305
306
  "--cs-color-link": "#201300"
306
307
  },
@@ -316,7 +317,7 @@ export const tokens = {
316
317
  "--cs-accent-grad-a": "#FFE1D8",
317
318
  "--cs-accent-grad-b": "#F4BA17",
318
319
  "--cs-color-text-accent": "#967C75",
319
- "--cs-color-link": "#967C75"
320
+ "--cs-color-link": "#846B64"
320
321
  },
321
322
  "hoa": {
322
323
  "--cs-accent": "#FCAF91",
@@ -330,7 +331,7 @@ export const tokens = {
330
331
  "--cs-accent-grad-a": "#FCAF91",
331
332
  "--cs-accent-grad-b": "#F4BA17",
332
333
  "--cs-color-text-accent": "#B47054",
333
- "--cs-color-link": "#B47054"
334
+ "--cs-color-link": "#A15E43"
334
335
  },
335
336
  "hoa.lava": {
336
337
  "--cs-accent": "#622B06",
@@ -358,7 +359,7 @@ export const tokens = {
358
359
  "--cs-accent-grad-a": "#C0F5FC",
359
360
  "--cs-accent-grad-b": "#A3D768",
360
361
  "--cs-color-text-accent": "#5A8A90",
361
- "--cs-color-link": "#5A8A90"
362
+ "--cs-color-link": "#48787E"
362
363
  },
363
364
  "thuy": {
364
365
  "--cs-accent": "#2EDBF7",
@@ -372,7 +373,7 @@ export const tokens = {
372
373
  "--cs-accent-grad-a": "#2EDBF7",
373
374
  "--cs-accent-grad-b": "#A3D768",
374
375
  "--cs-color-text-accent": "#108EA0",
375
- "--cs-color-link": "#108EA0"
376
+ "--cs-color-link": "#027B8B"
376
377
  },
377
378
  "thuy.ocean": {
378
379
  "--cs-accent": "#004554",
@@ -400,7 +401,7 @@ export const tokens = {
400
401
  "--cs-accent-grad-a": "#E1F1C8",
401
402
  "--cs-accent-grad-b": "#FCAF91",
402
403
  "--cs-color-text-accent": "#7C8965",
403
- "--cs-color-link": "#7C8965"
404
+ "--cs-color-link": "#687451"
404
405
  },
405
406
  "moc": {
406
407
  "--cs-accent": "#A3D768",
@@ -414,7 +415,7 @@ export const tokens = {
414
415
  "--cs-accent-grad-a": "#A3D768",
415
416
  "--cs-accent-grad-b": "#FCAF91",
416
417
  "--cs-color-text-accent": "#629122",
417
- "--cs-color-link": "#629122"
418
+ "--cs-color-link": "#517B13"
418
419
  },
419
420
  "moc.forest": {
420
421
  "--cs-accent": "#1A4A01",
@@ -442,7 +443,7 @@ export const tokens = {
442
443
  "--cs-accent-grad-a": "#FEE5C7",
443
444
  "--cs-accent-grad-b": "#2EDBF7",
444
445
  "--cs-color-text-accent": "#947F65",
445
- "--cs-color-link": "#947F65"
446
+ "--cs-color-link": "#826D54"
446
447
  },
447
448
  "kim": {
448
449
  "--cs-accent": "#F3B958",
@@ -456,7 +457,7 @@ export const tokens = {
456
457
  "--cs-accent-grad-a": "#F3B958",
457
458
  "--cs-accent-grad-b": "#2EDBF7",
458
459
  "--cs-color-text-accent": "#AC780B",
459
- "--cs-color-link": "#AC780B"
460
+ "--cs-color-link": "#966700"
460
461
  },
461
462
  "kim.steel": {
462
463
  "--cs-accent": "#503901",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$meta": {
3
3
  "system": "CyberSkill Design System",
4
- "version": "1.2.0",
4
+ "version": "1.3.9",
5
5
  "generated": "2026-07-23",
6
6
  "note": "Generated from tokens/*.css. Root grouped by category; theme/element scopes carry overrides only. Regenerate after any token change (see docs/conventions.md)."
7
7
  },
@@ -65,7 +65,7 @@
65
65
  "--cs-accent-ink": "#45210E",
66
66
  "--cs-accent-glow": "rgba(244, 186, 23, 0.48)",
67
67
  "--cs-accent-grad-a": "#F4BA17",
68
- "--cs-accent-grad-b": "#FCAF91",
68
+ "--cs-accent-grad-b": "#F3B958",
69
69
  "--cs-accent-on-strong": "#1A1108"
70
70
  },
71
71
  "depth": {
@@ -134,6 +134,7 @@
134
134
  },
135
135
  "breakpoint": {
136
136
  "--cs-breakpoint-xs": "0px",
137
+ "--cs-breakpoint-phone": "360px",
137
138
  "--cs-breakpoint-sm": "640px",
138
139
  "--cs-breakpoint-md": "768px",
139
140
  "--cs-breakpoint-lg": "1024px",
@@ -273,9 +274,9 @@
273
274
  "--cs-accent-ink": "#292414",
274
275
  "--cs-accent-glow": "rgba(248, 233, 192, 0.48)",
275
276
  "--cs-accent-grad-a": "#F8E9C0",
276
- "--cs-accent-grad-b": "#FCAF91",
277
+ "--cs-accent-grad-b": "#F3B958",
277
278
  "--cs-color-text-accent": "#90825E",
278
- "--cs-color-link": "#90825E"
279
+ "--cs-color-link": "#7B6D4A"
279
280
  },
280
281
  "tho": {
281
282
  "--cs-accent": "#F4BA17",
@@ -287,7 +288,7 @@
287
288
  "--cs-accent-ink": "#45210E",
288
289
  "--cs-accent-glow": "rgba(244, 186, 23, 0.48)",
289
290
  "--cs-accent-grad-a": "#F4BA17",
290
- "--cs-accent-grad-b": "#FCAF91"
291
+ "--cs-accent-grad-b": "#F3B958"
291
292
  },
292
293
  "tho.clay": {
293
294
  "--cs-accent": "#513801",
@@ -299,7 +300,7 @@
299
300
  "--cs-accent-ink": "#2D220E",
300
301
  "--cs-accent-glow": "rgba(81, 56, 1, 0.48)",
301
302
  "--cs-accent-grad-a": "#513801",
302
- "--cs-accent-grad-b": "#FCAF91",
303
+ "--cs-accent-grad-b": "#F3B958",
303
304
  "--cs-color-text-accent": "#201300",
304
305
  "--cs-color-link": "#201300"
305
306
  },
@@ -315,7 +316,7 @@
315
316
  "--cs-accent-grad-a": "#FFE1D8",
316
317
  "--cs-accent-grad-b": "#F4BA17",
317
318
  "--cs-color-text-accent": "#967C75",
318
- "--cs-color-link": "#967C75"
319
+ "--cs-color-link": "#846B64"
319
320
  },
320
321
  "hoa": {
321
322
  "--cs-accent": "#FCAF91",
@@ -329,7 +330,7 @@
329
330
  "--cs-accent-grad-a": "#FCAF91",
330
331
  "--cs-accent-grad-b": "#F4BA17",
331
332
  "--cs-color-text-accent": "#B47054",
332
- "--cs-color-link": "#B47054"
333
+ "--cs-color-link": "#A15E43"
333
334
  },
334
335
  "hoa.lava": {
335
336
  "--cs-accent": "#622B06",
@@ -357,7 +358,7 @@
357
358
  "--cs-accent-grad-a": "#C0F5FC",
358
359
  "--cs-accent-grad-b": "#A3D768",
359
360
  "--cs-color-text-accent": "#5A8A90",
360
- "--cs-color-link": "#5A8A90"
361
+ "--cs-color-link": "#48787E"
361
362
  },
362
363
  "thuy": {
363
364
  "--cs-accent": "#2EDBF7",
@@ -371,7 +372,7 @@
371
372
  "--cs-accent-grad-a": "#2EDBF7",
372
373
  "--cs-accent-grad-b": "#A3D768",
373
374
  "--cs-color-text-accent": "#108EA0",
374
- "--cs-color-link": "#108EA0"
375
+ "--cs-color-link": "#027B8B"
375
376
  },
376
377
  "thuy.ocean": {
377
378
  "--cs-accent": "#004554",
@@ -399,7 +400,7 @@
399
400
  "--cs-accent-grad-a": "#E1F1C8",
400
401
  "--cs-accent-grad-b": "#FCAF91",
401
402
  "--cs-color-text-accent": "#7C8965",
402
- "--cs-color-link": "#7C8965"
403
+ "--cs-color-link": "#687451"
403
404
  },
404
405
  "moc": {
405
406
  "--cs-accent": "#A3D768",
@@ -413,7 +414,7 @@
413
414
  "--cs-accent-grad-a": "#A3D768",
414
415
  "--cs-accent-grad-b": "#FCAF91",
415
416
  "--cs-color-text-accent": "#629122",
416
- "--cs-color-link": "#629122"
417
+ "--cs-color-link": "#517B13"
417
418
  },
418
419
  "moc.forest": {
419
420
  "--cs-accent": "#1A4A01",
@@ -441,7 +442,7 @@
441
442
  "--cs-accent-grad-a": "#FEE5C7",
442
443
  "--cs-accent-grad-b": "#2EDBF7",
443
444
  "--cs-color-text-accent": "#947F65",
444
- "--cs-color-link": "#947F65"
445
+ "--cs-color-link": "#826D54"
445
446
  },
446
447
  "kim": {
447
448
  "--cs-accent": "#F3B958",
@@ -455,7 +456,7 @@
455
456
  "--cs-accent-grad-a": "#F3B958",
456
457
  "--cs-accent-grad-b": "#2EDBF7",
457
458
  "--cs-color-text-accent": "#AC780B",
458
- "--cs-color-link": "#AC780B"
459
+ "--cs-color-link": "#966700"
459
460
  },
460
461
  "kim.steel": {
461
462
  "--cs-accent": "#503901",
@@ -40,7 +40,7 @@
40
40
  </style>
41
41
  </head>
42
42
  <body>
43
- <a class="cs-skip" href="#main" style="position:absolute;left:-999px;width:1px;height:1px;overflow:hidden">Skip to content</a>
43
+ <a class="cs-skip" href="#main" style="position:absolute;left:-999px;width:1px;height:1px;overflow:hidden">Bỏ qua đến nội dung</a>
44
44
  <main id="main">
45
45
 
46
46
  <deck-stage width="1920" height="1080">
@@ -139,7 +139,7 @@ function StatusHub() {
139
139
 
140
140
  return (
141
141
  <div className="sh" lang={lang} data-theme={dark ? "dark" : undefined}>
142
- <a className="cs-skip" href="#main" style={{ position: "absolute", left: -999, width: 1, height: 1, overflow: "hidden" }}>Skip to content</a>
142
+ <a className="cs-skip" href="#main" style={{ position: "absolute", left: -999, width: 1, height: 1, overflow: "hidden" }}>{lang === "vi" ? "Bỏ qua đến nội dung" : "Skip to content"}</a>
143
143
  <header className="hd">
144
144
  <div className="hd-in">
145
145
  <div className="hd-id">
@@ -1,4 +1,4 @@
1
- <!-- @dsCard group="Status Hub" viewport="1280x760" name="Status Hub — sign in" subtitle="Umber split login with brand panel + form controls" -->
1
+ <!-- @dsCard group="Status Hub" viewport="1280x760" name="Status Hub — sign in" subtitle="Umber split login with brand panel + form controls (default / loading / error / invalid)" -->
2
2
  <!DOCTYPE html>
3
3
  <html lang="en">
4
4
  <head>
@@ -11,12 +11,12 @@
11
11
  html, body { margin: 0; min-height: 100vh; }
12
12
  .login { display: grid; grid-template-columns: 1.05fr 1fr; min-height: 100vh; }
13
13
  .pane-brand { position: relative; overflow: hidden; background: var(--cs-color-brand-umber); color: #fff; padding: 56px 60px; display: flex; flex-direction: column; }
14
- .pane-brand::before { content: ""; position: absolute; inset: 0; background-image: url("../../assets/aurora-gold.jpg"); background-size: cover; background-position: center; opacity: .42; }
14
+ .pane-brand::before { content: ""; position: absolute; inset: 0; background-image: url("../../assets/aurora-tho.webp"); background-size: cover; background-position: center; opacity: .42; }
15
15
  .pane-brand::after { content: ""; position: absolute; inset: 0; background: linear-gradient(160deg, rgba(26,17,8,.35), rgba(26,17,8,.8)); }
16
16
  .pane-brand > * { position: relative; z-index: 1; }
17
17
  .brand-lock { display: flex; align-items: center; gap: 12px; font-weight: 800; font-size: 20px; }
18
18
  .brand-lock img { width: 40px; height: 40px; }
19
- .pane-brand h2 { font-size: 40px; font-weight: 800; letter-spacing: -.02em; line-height: 1.08; color: var(--cs-color-brand-ochre); margin: auto 0 8px; }
19
+ .pane-brand .brand-headline { font-size: 40px; font-weight: 800; letter-spacing: -.02em; line-height: 1.08; color: var(--cs-color-brand-ochre); margin: auto 0 8px; }
20
20
  .pane-brand p { font-size: 17px; opacity: .9; margin: 0; max-width: 420px; }
21
21
  .pane-form { display: grid; place-items: center; padding: 40px 24px; background: var(--cs-color-surface-page); }
22
22
  .box { width: min(400px, 100%); }
@@ -25,37 +25,58 @@
25
25
  form { display: grid; gap: 16px; }
26
26
  .rowbetween { display: flex; align-items: center; justify-content: space-between; }
27
27
  .fine { text-align: center; font-size: 13px; color: var(--cs-color-text-muted); margin-top: 4px; }
28
+ .state-bar { position: fixed; left: 20px; bottom: 20px; z-index: 60; display: flex; gap: 8px; flex-wrap: wrap; align-items: center; padding: 10px 12px; border: 1px solid var(--cs-color-border-default); background: var(--cs-color-surface-panel); border-radius: 12px; box-shadow: var(--cs-shadow-md); font-size: 13px; }
29
+ .state-bar label { display: flex; align-items: center; gap: 6px; color: var(--cs-color-text-muted); }
30
+ .state-bar select { font: inherit; }
31
+ [hidden] { display: none !important; }
28
32
  @media (max-width: 820px) { .login { grid-template-columns: 1fr; } .pane-brand { display: none; } }
29
33
  </style>
30
34
  </head>
31
35
  <body>
32
- <a class="cs-skip" href="#main" style="position:absolute;left:-999px;width:1px;height:1px;overflow:hidden">Skip to content</a>
36
+ <a class="cs-skip" href="#main" style="position:absolute;left:-999px;width:1px;height:1px;overflow:hidden">Bỏ qua đến nội dung</a>
33
37
  <main id="main">
34
38
 
35
39
  <div class="login">
36
40
  <div class="pane-brand">
37
41
  <div class="brand-lock"><img src="../../assets/logo-mark.svg" alt="" />CyberSkill</div>
38
- <h2>Turn Your Will Into Real</h2>
42
+ <p class="brand-headline">Turn Your Will Into Real</p>
39
43
  <p>Sign in to the Status Hub — one page, three lenses across every wish in flight.</p>
40
44
  </div>
41
45
  <div class="pane-form">
42
46
  <div class="box">
43
47
  <h1>Sign in</h1>
44
48
  <p class="sub">Welcome back. Đăng nhập để tiếp tục.</p>
45
- <form onsubmit="return false">
46
- <label class="cs-field"><span class="cs-field__label">Work email</span><input class="cs-field__control" type="email" placeholder="you@cyberskill.world" /></label>
47
- <label class="cs-field"><span class="cs-field__label">Password</span><input class="cs-field__control" type="password" placeholder="••••••••" value="wishgranted" /></label>
49
+ <form id="loginForm" onsubmit="return false">
50
+ <div id="errBanner" class="cs-alert cs-alert--danger" role="status" hidden>
51
+ <span class="cs-alert__icon" aria-hidden="true">!</span>
52
+ <div>
53
+ <p class="cs-alert__title">Sign-in failed</p>
54
+ <div class="cs-alert__body">Check your email and password, then try again.</div>
55
+ </div>
56
+ </div>
57
+ <label id="emailField" class="cs-field"><span class="cs-field__label">Work email</span><input id="emailInput" class="cs-field__control" type="email" placeholder="you@cyberskill.world" /><span id="emailError" class="cs-field__error" role="alert" hidden>Enter a valid work email.</span></label>
58
+ <label class="cs-field"><span class="cs-field__label">Password</span><input class="cs-field__control" type="password" placeholder="••••••••" value="" /></label>
48
59
  <div class="rowbetween">
49
- <label class="cs-switch"><input type="checkbox" role="switch" checked /><span class="cs-switch__track"></span><span class="cs-switch__label">Remember me</span></label>
60
+ <label class="cs-switch"><input type="checkbox" role="switch" /><span class="cs-switch__track"></span><span class="cs-switch__label">Remember me</span></label>
50
61
  <a href="#">Forgot password?</a>
51
62
  </div>
52
- <button type="submit" class="cs-button cs-button--primary cs-button--full">Sign in</button>
63
+ <button id="submitBtn" type="submit" class="cs-button cs-button--primary cs-button--full">Sign in</button>
53
64
  <button type="button" class="cs-button cs-button--ghost cs-button--full">✦ Talk to Lumi instead</button>
54
65
  </form>
55
66
  <p class="fine">New here? <a href="#">Ask for access</a></p>
56
67
  </div>
57
68
  </div>
58
69
  </div>
70
+ <div class="state-bar" aria-label="Demo form state">
71
+ <label>Form state
72
+ <select id="formState">
73
+ <option value="default" selected>default</option>
74
+ <option value="loading">loading</option>
75
+ <option value="error">error</option>
76
+ <option value="invalid">invalid</option>
77
+ </select>
78
+ </label>
79
+ </div>
59
80
  <button id="themeToggle" aria-label="Toggle theme" style="position:fixed;right:20px;bottom:20px;z-index:60;border:1px solid var(--cs-color-border-default);background:var(--cs-color-surface-panel);color:var(--cs-color-text-primary);width:44px;height:44px;border-radius:999px;cursor:pointer;box-shadow:var(--cs-shadow-md)">☾</button>
60
81
  <script>
61
82
  document.getElementById("themeToggle").addEventListener("click", function () {
@@ -63,6 +84,27 @@
63
84
  el.setAttribute("data-theme", dark ? "light" : "dark");
64
85
  this.textContent = dark ? "☾" : "☀";
65
86
  });
87
+ function applyState(state) {
88
+ var banner = document.getElementById("errBanner");
89
+ var emailField = document.getElementById("emailField");
90
+ var emailInput = document.getElementById("emailInput");
91
+ var emailError = document.getElementById("emailError");
92
+ var btn = document.getElementById("submitBtn");
93
+ banner.hidden = state !== "error";
94
+ var invalid = state === "invalid";
95
+ emailField.classList.toggle("is-invalid", invalid);
96
+ emailInput.setAttribute("aria-invalid", invalid ? "true" : "false");
97
+ if (!invalid) emailInput.removeAttribute("aria-invalid");
98
+ emailError.hidden = !invalid;
99
+ var loading = state === "loading";
100
+ btn.classList.toggle("is-loading", loading);
101
+ btn.disabled = loading;
102
+ btn.setAttribute("aria-busy", loading ? "true" : "false");
103
+ btn.textContent = loading ? "Signing in…" : "Sign in";
104
+ }
105
+ var sel = document.getElementById("formState");
106
+ sel.addEventListener("change", function () { applyState(sel.value); });
107
+ applyState(sel.value);
66
108
  </script>
67
109
  </main>
68
110
  </body>
@@ -36,7 +36,7 @@
36
36
  </style>
37
37
  </head>
38
38
  <body>
39
- <a class="cs-skip" href="#main" style="position:absolute;left:-999px;width:1px;height:1px;overflow:hidden">Skip to content</a>
39
+ <a class="cs-skip" href="#main" style="position:absolute;left:-999px;width:1px;height:1px;overflow:hidden">Bỏ qua đến nội dung</a>
40
40
  <main id="main">
41
41
 
42
42
  <div class="sh">
@@ -27,7 +27,7 @@
27
27
  </style>
28
28
  </head>
29
29
  <body>
30
- <a class="cs-skip" href="#main">Skip to content</a>
30
+ <a class="cs-skip" href="#main">Bỏ qua đến nội dung</a>
31
31
  <div class="sh">
32
32
  <header class="hd">
33
33
  <div class="hd-in">
@@ -67,7 +67,7 @@ function Website() {
67
67
 
68
68
  return (
69
69
  <div className="site" data-theme={dark ? "dark" : undefined}>
70
- <a className="cs-skip" href="#main" style={{ position: "absolute", left: -999, width: 1, height: 1, overflow: "hidden" }}>Skip to content</a>
70
+ <a className="cs-skip" href="#main" style={{ position: "absolute", left: -999, width: 1, height: 1, overflow: "hidden" }}>{loc === "vi" ? "Bỏ qua đến nội dung" : "Skip to content"}</a>
71
71
  <header className="hdr cs-surface-light">
72
72
  <div className="container hdr-in">
73
73
  <a className="brand" href="#top"><img src="../../assets/logo-mark.svg" alt="" />CyberSkill</a>
@@ -11,7 +11,7 @@
11
11
  <style>
12
12
  html, body { margin: 0; }
13
13
  .car-hero { background: var(--cs-color-brand-umber); color: #fff; padding: 76px 0 64px; position: relative; overflow: hidden; }
14
- .car-hero::before { content: ""; position: absolute; inset: 0; background-image: url("../../assets/aurora-gold.jpg"); background-size: cover; background-position: center; opacity: .32; }
14
+ .car-hero::before { content: ""; position: absolute; inset: 0; background-image: url("../../assets/aurora-tho.webp"); background-size: cover; background-position: center; opacity: .32; }
15
15
  .car-hero::after { content: ""; position: absolute; inset: 0; background: linear-gradient(180deg, rgba(26,17,8,.28), rgba(26,17,8,.78)); }
16
16
  .car-hero .container { position: relative; z-index: 1; }
17
17
  .car-hero h1 { font-size: clamp(36px, 5vw, 54px); font-weight: 800; letter-spacing: -.02em; color: var(--cs-color-brand-ochre); margin: 12px 0 6px; }
@@ -29,7 +29,7 @@
29
29
  </style>
30
30
  </head>
31
31
  <body>
32
- <a class="cs-skip" href="#main" style="position:absolute;left:-999px;width:1px;height:1px;overflow:hidden">Skip to content</a>
32
+ <a class="cs-skip" href="#main" style="position:absolute;left:-999px;width:1px;height:1px;overflow:hidden">Bỏ qua đến nội dung</a>
33
33
  <main id="main">
34
34
 
35
35
  <div class="site">
@@ -36,7 +36,7 @@
36
36
  <script src="../../_ds_bundle.js"></script>
37
37
  </head>
38
38
  <body>
39
- <a class="cs-skip" href="#main" style="position:absolute;left:-999px;width:1px;height:1px;overflow:hidden">Skip to content</a>
39
+ <a class="cs-skip" href="#main" style="position:absolute;left:-999px;width:1px;height:1px;overflow:hidden">Bỏ qua đến nội dung</a>
40
40
 
41
41
  <div id="root"></div>
42
42
  <script type="text/babel">
@@ -23,7 +23,7 @@
23
23
 
24
24
  /* hero */
25
25
  .hero { position: relative; overflow: hidden; background: var(--cs-color-brand-umber); color: #fff; }
26
- .hero::before { content: ""; position: absolute; inset: 0; background-image: url("../../assets/aurora-gold.jpg"); background-size: cover; background-position: center; opacity: .5; }
26
+ .hero::before { content: ""; position: absolute; inset: 0; background-image: url("../../assets/aurora-tho.webp"); background-size: cover; background-position: center; opacity: .5; }
27
27
  .hero::after { content: ""; position: absolute; inset: 0; background: linear-gradient(180deg, rgba(26,17,8,.35), rgba(26,17,8,.82) 78%); }
28
28
  .hero-in { position: relative; z-index: 1; display: grid; grid-template-columns: 1.35fr .65fr; gap: var(--cs-space-8); align-items: center; padding: 84px 0 96px; }
29
29
  .hero .eyebrow { color: var(--cs-color-brand-ochre); }
@@ -11,7 +11,7 @@
11
11
  <style>
12
12
  html, body { margin: 0; }
13
13
  .work-hero { background: var(--cs-color-brand-umber); color: #fff; padding: 72px 0 60px; position: relative; overflow: hidden; }
14
- .work-hero::before { content: ""; position: absolute; inset: 0; background-image: url("../../assets/aurora-gold.jpg"); background-size: cover; background-position: center; opacity: .34; }
14
+ .work-hero::before { content: ""; position: absolute; inset: 0; background-image: url("../../assets/aurora-tho.webp"); background-size: cover; background-position: center; opacity: .34; }
15
15
  .work-hero::after { content: ""; position: absolute; inset: 0; background: linear-gradient(180deg, rgba(26,17,8,.3), rgba(26,17,8,.75)); }
16
16
  .work-hero .container { position: relative; z-index: 1; }
17
17
  .work-hero h1 { font-size: clamp(36px, 5vw, 54px); font-weight: 800; letter-spacing: -.02em; color: var(--cs-color-brand-ochre); margin: 12px 0 6px; }
@@ -35,7 +35,7 @@
35
35
  </style>
36
36
  </head>
37
37
  <body>
38
- <a class="cs-skip" href="#main" style="position:absolute;left:-999px;width:1px;height:1px;overflow:hidden">Skip to content</a>
38
+ <a class="cs-skip" href="#main" style="position:absolute;left:-999px;width:1px;height:1px;overflow:hidden">Bỏ qua đến nội dung</a>
39
39
  <main id="main">
40
40
 
41
41
  <div class="site">
Binary file
Binary file
Binary file
Binary file
@@ -1,18 +0,0 @@
1
- # Container-query migration (G1 / CDS-RESP-001)
2
-
3
- Status: **started Phase 4** (2026-08-08) — compatibility layer only.
4
- Owner: design-system maintainer.
5
-
6
- ## Decision
7
-
8
- Begin container-query adoption **behind a compatibility CSS opt-in**, without rewriting every template grid in one pass.
9
-
10
- 1. Hosts opt in with `.cs-cq` (`container-type: inline-size`).
11
- 2. Children may use `@container cs (max-width: …)` rules; first helper: `.cs-cq-stack`.
12
- 3. Existing `@media` rules in `base/responsive.css` remain the default authority until generated layout classes land.
13
-
14
- ## Acceptance for later waves
15
-
16
- - Kit card grids and Status Hub lenses can size from parent width, not only viewport.
17
- - No regression on `_audit/responsive-overflow-320.html` or zoom-text-spacing.
18
- - Document any permanent media-only exceptions in this file.
@@ -1,101 +0,0 @@
1
- # Overlay manager design (C8 / CDS-ARCH-001)
2
-
3
- Status: **landed in Phase 3** (operator decision D5=A, 2026-08-08) — see `components/overlays/OverlayManager.jsx`.
4
- Owner: design-system maintainer · Related: UX-009 depth tokens, CDS-A11Y-003 keyboard models.
5
-
6
- ## Problem
7
-
8
- Overlays (Dialog, AlertDialog, Drawer, Popover, Menu, CommandPalette, Toast, Tour) currently each own:
9
-
10
- - z-index (with dialog hardcoding `1000` historically — now tokenized to `--cs-depth-modal`)
11
- - focus trap / restore
12
- - body scroll-lock
13
- - Escape handling
14
-
15
- Nested overlays (toast while modal open; confirm inside drawer) race on DOM order and scroll-lock count. Keyboard models for complex widgets (CDS-A11Y-003) need a single stack authority.
16
-
17
- ## Goals
18
-
19
- 1. One stack owns paint order (depth tokens), focus scope, Escape routing, and scroll-lock refcount.
20
- 2. Toasts always paint above modals (`--cs-depth-toast` > `--cs-depth-modal`) — already the token doctrine.
21
- 3. Nested overlays: only the topmost modal-layer traps focus; Escape closes topmost first.
22
- 4. No third-party floating library required for v1; Floating UI may be adopted later for positioning only.
23
-
24
- ## Non-goals (v1)
25
-
26
- - Rewriting every popover positioner
27
- - Changing public component props (additive `layer` / `portal` opts only)
28
- - SSR portal polyfills beyond “no `window` during render” (Tour already fixed)
29
-
30
- ## API sketch
31
-
32
- ```ts
33
- // components/overlays/OverlayManager.jsx (Phase 3 land)
34
-
35
- type LayerKind = 'dropdown' | 'popover' | 'modal' | 'toast' | 'tour';
36
-
37
- type LayerRegistration = {
38
- id: string;
39
- kind: LayerKind;
40
- /** Focus trap when kind is modal */
41
- trapFocus?: boolean;
42
- onEscape?: () => void;
43
- /** Element that receives restore focus */
44
- restoreEl?: HTMLElement | null;
45
- };
46
-
47
- type OverlayManagerApi = {
48
- register(layer: LayerRegistration): () => void; // unregister
49
- top(): LayerRegistration | null;
50
- /** Refcount scroll lock — lock while any modal registered */
51
- scrollLocked: boolean;
52
- };
53
-
54
- // React context
55
- const OverlayContext = React.createContext<OverlayManagerApi | null>(null);
56
- function OverlayProvider({ children }: { children: React.ReactNode }): JSX.Element;
57
- function useOverlayLayer(opts: Omit<LayerRegistration, 'id'>): { id: string };
58
- ```
59
-
60
- ### Depth mapping
61
-
62
- | Kind | Token | Notes |
63
- |------|-------|--------|
64
- | dropdown | `--cs-depth-dropdown` (60) | Menus under sticky nav |
65
- | popover | `--cs-depth-overlay` | HoverCard, Popover |
66
- | modal | `--cs-depth-modal` (100) | Dialog, AlertDialog, Drawer, CommandPalette |
67
- | toast | `--cs-depth-toast` (200) | Above modals |
68
- | tour | `--cs-depth-toast` or dedicated | Full-viewport coachmarks |
69
-
70
- ### Focus & Escape
71
-
72
- - Modal registration pushes a focus scope; Tab cycles within the topmost modal host (`.cs-dialog-layer` / drawer panel).
73
- - Escape invokes `onEscape` of `top()` only; if none, bubbles.
74
- - Unregister restores focus to `restoreEl` when that layer was topmost at close.
75
-
76
- ### Scroll-lock
77
-
78
- - `document.documentElement` / `body` overflow hidden while `count(modal) > 0`.
79
- - Nested modals increment; close decrements — no flicker unlock.
80
-
81
- ### Portal host
82
-
83
- ```html
84
- <div id="cs-overlay-root" data-cs-overlay-root></div>
85
- ```
86
-
87
- Components portal into `#cs-overlay-root` when present; otherwise document.body (today’s behavior). Kits and Atomic View mount the root once.
88
-
89
- ## Migration (Phase 3)
90
-
91
- 1. Ship `OverlayProvider` + `useOverlayLayer` beside existing components (no breaking change).
92
- 2. Wire Dialog / AlertDialog / Drawer / CommandPalette / ToastStack first.
93
- 3. Add a11y-gate rows: nested dialog+toast, nested dialog+alertdialog Escape order, scroll-lock refcount.
94
- 4. Then E3 keyboard models for Cascader / TreeSelect / Menubar adopt the same focus-scope helper.
95
-
96
- ## Acceptance
97
-
98
- - Toast visible above open dialog (behavior gate — already green; keep).
99
- - Nested AlertDialog inside Dialog: Escape closes alert first; focus returns to dialog.
100
- - Zero raw `z-index` > 20 in `base/` outside token vars (token-contract).
101
- - Design note remains the SoT until Phase 3 lands code under `components/overlays/`.