@cyberskill/design 1.1.1 → 1.3.8

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 (481) hide show
  1. package/DESIGN.md +28 -5
  2. package/README.md +23 -22
  3. package/SKILL.md +7 -7
  4. package/THIRD-PARTY-NOTICES.md +35 -0
  5. package/VERSION +1 -1
  6. package/_ds_bundle.js +1495 -1733
  7. package/_ds_manifest.json +1 -1
  8. package/_esm/cs.mjs +18 -4
  9. package/_esm/react.d.ts +2 -0
  10. package/_esm/react.mjs +7 -1
  11. package/_vendor/NOTICE.md +16 -0
  12. package/_vendor/babel/README.md +7 -0
  13. package/_vendor/babel/babel.min.js +4 -0
  14. package/_vendor/react/README.md +3 -0
  15. package/_vendor/react/react-dom.production.min.js +1 -0
  16. package/_vendor/react/react.production.min.js +1 -0
  17. package/assets/aurora-hoa.webp +0 -0
  18. package/assets/aurora-kim.webp +0 -0
  19. package/assets/aurora-moc.webp +0 -0
  20. package/assets/aurora-tho.webp +0 -0
  21. package/assets/aurora-thuy.webp +0 -0
  22. package/base/a11y.css +18 -0
  23. package/base/ai.css +9 -4
  24. package/base/collections.css +18 -7
  25. package/base/components.css +16 -4
  26. package/base/controls.css +116 -66
  27. package/base/data.css +4 -4
  28. package/base/feedback.css +14 -2
  29. package/base/forms.css +10 -4
  30. package/base/glass.css +7 -1
  31. package/base/interaction.css +6 -2
  32. package/base/navigation.css +9 -3
  33. package/base/reset.css +7 -1
  34. package/base/responsive.css +38 -12
  35. package/base/shell.css +15 -3
  36. package/components/_i18n/i18n.js +41 -4
  37. package/components/_i18n/strings.js +89 -22
  38. package/components/ai/ChatMessage.d.ts +2 -0
  39. package/components/ai/ChatMessage.jsx +8 -4
  40. package/components/ai/ConfidenceMeter.d.ts +2 -0
  41. package/components/ai/ConfidenceMeter.jsx +8 -6
  42. package/components/ai/HumanReviewGate.d.ts +2 -0
  43. package/components/ai/PromptInput.d.ts +2 -0
  44. package/components/ai/TypingIndicator.d.ts +2 -0
  45. package/components/ai/ai-conversation.card.html +3 -3
  46. package/components/ai/ai-lumi.card.html +3 -3
  47. package/components/ai/ai.card.html +3 -3
  48. package/components/brand/brand.card.html +3 -3
  49. package/components/button/buttons.card.html +3 -3
  50. package/components/data/Image.jsx +18 -2
  51. package/components/data/Sortable.d.ts +5 -1
  52. package/components/data/Sortable.jsx +42 -9
  53. package/components/data/Sortable.prompt.md +4 -2
  54. package/components/data/Terminal.jsx +3 -2
  55. package/components/data/Tooltip.d.ts +2 -0
  56. package/components/data/Tooltip.jsx +6 -3
  57. package/components/data/Tree.d.ts +2 -1
  58. package/components/data/Tree.jsx +137 -16
  59. package/components/data/Tree.prompt.md +1 -1
  60. package/components/data/Watermark.jsx +11 -3
  61. package/components/data/collections.card.html +3 -3
  62. package/components/data/data.card.html +3 -3
  63. package/components/datatable/DataGrid.jsx +10 -1
  64. package/components/datatable/DataTable.d.ts +24 -1
  65. package/components/datatable/DataTable.jsx +78 -5
  66. package/components/datatable/DataTable.prompt.md +2 -1
  67. package/components/datatable/datatable.card.html +20 -16
  68. package/components/dialog/Dialog.jsx +13 -45
  69. package/components/dialog/dialog.card.html +3 -3
  70. package/components/feedback/Alert.d.ts +2 -0
  71. package/components/feedback/Alert.jsx +8 -2
  72. package/components/feedback/EmptyState.d.ts +2 -0
  73. package/components/feedback/EmptyState.jsx +6 -3
  74. package/components/feedback/ProgressBar.d.ts +2 -0
  75. package/components/feedback/ProgressBar.jsx +9 -4
  76. package/components/feedback/Toast.jsx +15 -1
  77. package/components/feedback/Toast.prompt.md +2 -1
  78. package/components/feedback/feedback-2.card.html +3 -3
  79. package/components/feedback/feedback.card.html +3 -3
  80. package/components/forms/Cascader.jsx +76 -8
  81. package/components/forms/Editor.jsx +37 -2
  82. package/components/forms/FileUpload.d.ts +2 -0
  83. package/components/forms/FileUpload.jsx +22 -8
  84. package/components/forms/Form.d.ts +3 -1
  85. package/components/forms/Form.jsx +9 -1
  86. package/components/forms/Form.prompt.md +1 -1
  87. package/components/forms/Mentions.d.ts +1 -1
  88. package/components/forms/Mentions.jsx +59 -7
  89. package/components/forms/Mentions.prompt.md +3 -1
  90. package/components/forms/Rating.d.ts +3 -2
  91. package/components/forms/Rating.jsx +34 -3
  92. package/components/forms/Rating.prompt.md +1 -1
  93. package/components/forms/Select.d.ts +2 -0
  94. package/components/forms/Select.jsx +6 -2
  95. package/components/forms/Slider.d.ts +2 -0
  96. package/components/forms/Slider.jsx +5 -2
  97. package/components/forms/Switch.d.ts +2 -0
  98. package/components/forms/Switch.jsx +15 -3
  99. package/components/forms/TimePicker.jsx +3 -1
  100. package/components/forms/Toggle.d.ts +2 -0
  101. package/components/forms/Toggle.jsx +14 -2
  102. package/components/forms/forms-2.card.html +3 -3
  103. package/components/forms/forms.card.html +3 -3
  104. package/components/icon/Icon.d.ts +1 -1
  105. package/components/icon/Icon.jsx +1 -0
  106. package/components/icon/Icon.prompt.md +1 -1
  107. package/components/icon/icon.card.html +3 -3
  108. package/components/logo/logo.card.html +3 -3
  109. package/components/navigation/CommandPalette.d.ts +2 -0
  110. package/components/navigation/CommandPalette.jsx +22 -7
  111. package/components/navigation/Menu.d.ts +2 -0
  112. package/components/navigation/Menu.jsx +60 -6
  113. package/components/navigation/Steps.d.ts +2 -0
  114. package/components/navigation/Steps.jsx +6 -3
  115. package/components/navigation/Tabs.d.ts +2 -0
  116. package/components/navigation/Tabs.jsx +6 -3
  117. package/components/navigation/Toolbar.d.ts +3 -2
  118. package/components/navigation/Toolbar.jsx +119 -12
  119. package/components/navigation/Toolbar.prompt.md +1 -1
  120. package/components/navigation/navigation.card.html +3 -3
  121. package/components/navigation/shell.card.html +3 -3
  122. package/components/overlays/AlertDialog.jsx +19 -49
  123. package/components/overlays/ContextMenu.d.ts +2 -0
  124. package/components/overlays/ContextMenu.jsx +6 -3
  125. package/components/overlays/Drawer.d.ts +2 -0
  126. package/components/overlays/Drawer.jsx +24 -20
  127. package/components/overlays/OverlayManager.d.ts +40 -0
  128. package/components/overlays/OverlayManager.jsx +214 -0
  129. package/components/overlays/OverlayManager.prompt.md +12 -0
  130. package/components/overlays/Tour.jsx +14 -7
  131. package/components/overlays/alertdialog.card.html +3 -3
  132. package/components/overlays/overlays.card.html +3 -3
  133. package/components/textfield/textfield.card.html +3 -3
  134. package/dist/styles.min.css +2252 -0
  135. package/docs/benchmark-rubric.md +1 -1
  136. package/docs/ci-cd.md +19 -12
  137. package/docs/consumer-grant.md +3 -0
  138. package/docs/consuming.md +13 -13
  139. package/docs/contrast-report.md +79 -1
  140. package/docs/conventions.md +21 -8
  141. package/docs/decisions.md +45 -7
  142. package/docs/deploy.md +17 -6
  143. package/docs/design-styles.md +2 -2
  144. package/docs/quality-gates.md +35 -15
  145. package/docs/release-notes.md +2 -2
  146. package/docs/release-runbook.md +78 -0
  147. package/docs/sync.md +2 -2
  148. package/docs/vi/benchmark-rubric.md +1 -1
  149. package/docs/vi/ci-cd.md +17 -12
  150. package/docs/vi/consumer-grant.md +3 -0
  151. package/docs/vi/consuming.md +13 -13
  152. package/docs/vi/contrast-report.md +79 -1
  153. package/docs/vi/conventions.md +20 -7
  154. package/docs/vi/decisions.md +43 -6
  155. package/docs/vi/deploy.md +17 -6
  156. package/docs/vi/quality-gates.md +34 -15
  157. package/docs/vi/release-notes.md +2 -2
  158. package/docs/vi/release-runbook.md +78 -0
  159. package/docs/vi/sync.md +2 -2
  160. package/docs/viewer.html +2 -2
  161. package/fonts/OFL.txt +98 -0
  162. package/guidelines/atomic-view.html +13 -9
  163. package/guidelines/brand-imagery.html +1 -1
  164. package/guidelines/elements-variants.html +5 -5
  165. package/guidelines/spacing-breakpoints.html +2 -1
  166. package/guidelines/surfaces-glass.html +1 -1
  167. package/llms.txt +5 -5
  168. package/package.json +38 -10
  169. package/templates/_ds-base.canonical.js +55 -0
  170. package/templates/ai-cluster-demo.html +2 -2
  171. package/templates/app-shell/AppShell.dc.html +7 -5
  172. package/templates/app-shell/content-schema.json +7 -0
  173. package/templates/app-shell/ds-base.js +33 -1
  174. package/templates/app-shell/support.js +13 -20
  175. package/templates/article/Article.dc.html +7 -3
  176. package/templates/article/content-schema.json +7 -0
  177. package/templates/article/ds-base.js +33 -1
  178. package/templates/article/support.js +13 -20
  179. package/templates/auth/Auth.dc.html +33 -12
  180. package/templates/auth/content-schema.json +37 -0
  181. package/templates/auth/ds-base.js +33 -1
  182. package/templates/auth/support.js +13 -20
  183. package/templates/bod-deck/BodDeck.dc.html +11 -10
  184. package/templates/bod-deck/ds-base.js +33 -1
  185. package/templates/bod-deck/support.js +13 -20
  186. package/templates/bod-investor-update/BodInvestorUpdate.dc.html +4 -3
  187. package/templates/bod-investor-update/ds-base.js +33 -1
  188. package/templates/bod-investor-update/support.js +13 -20
  189. package/templates/bod-memo/BodMemo.dc.html +6 -5
  190. package/templates/bod-memo/ds-base.js +33 -1
  191. package/templates/bod-memo/support.js +13 -20
  192. package/templates/bod-minutes/BodMinutes.dc.html +2 -1
  193. package/templates/bod-minutes/ds-base.js +33 -1
  194. package/templates/bod-minutes/support.js +13 -20
  195. package/templates/bod-report/BodReport.dc.html +3 -2
  196. package/templates/bod-report/ds-base.js +33 -1
  197. package/templates/bod-report/support.js +13 -20
  198. package/templates/bod-resolution/BodResolution.dc.html +5 -4
  199. package/templates/bod-resolution/ds-base.js +33 -1
  200. package/templates/bod-resolution/support.js +13 -20
  201. package/templates/culture-event-invite/CultureEventInvite.dc.html +3 -2
  202. package/templates/culture-event-invite/ds-base.js +33 -1
  203. package/templates/culture-event-invite/support.js +13 -20
  204. package/templates/dashboard/Dashboard.dc.html +10 -6
  205. package/templates/dashboard/content-schema.json +7 -0
  206. package/templates/dashboard/ds-base.js +33 -1
  207. package/templates/dashboard/support.js +13 -20
  208. package/templates/delivery-change-note/DeliveryChangeNote.dc.html +4 -3
  209. package/templates/delivery-change-note/ds-base.js +33 -1
  210. package/templates/delivery-change-note/support.js +13 -20
  211. package/templates/delivery-kickoff/DeliveryKickoff.dc.html +3 -2
  212. package/templates/delivery-kickoff/ds-base.js +33 -1
  213. package/templates/delivery-kickoff/support.js +13 -20
  214. package/templates/delivery-qbr-deck/DeliveryQbrDeck.dc.html +6 -5
  215. package/templates/delivery-qbr-deck/ds-base.js +33 -1
  216. package/templates/delivery-qbr-deck/support.js +13 -20
  217. package/templates/delivery-runbook/DeliveryRunbook.dc.html +5 -4
  218. package/templates/delivery-runbook/ds-base.js +33 -1
  219. package/templates/delivery-runbook/support.js +13 -20
  220. package/templates/delivery-status-email/DeliveryStatusEmail.dc.html +3 -2
  221. package/templates/delivery-status-email/ds-base.js +33 -1
  222. package/templates/delivery-status-email/support.js +13 -20
  223. package/templates/doc-style-guide/DocStyleGuide.dc.html +67 -64
  224. package/templates/doc-style-guide/ds-base.js +33 -1
  225. package/templates/doc-style-guide/support.js +13 -20
  226. package/templates/doc-suite-index/DocSuiteIndex.dc.html +46 -45
  227. package/templates/doc-suite-index/ds-base.js +33 -1
  228. package/templates/doc-suite-index/support.js +13 -20
  229. package/templates/doc-templates/DocTemplates.dc.html +42 -41
  230. package/templates/doc-templates/ds-base.js +33 -1
  231. package/templates/doc-templates/support.js +13 -20
  232. package/templates/email/Email.dc.html +3 -2
  233. package/templates/email/ds-base.js +33 -1
  234. package/templates/email/support.js +13 -20
  235. package/templates/email-safe/email-announcement.html +2 -2
  236. package/templates/email-safe/email-dunning.html +2 -2
  237. package/templates/email-safe/email-investor.html +2 -2
  238. package/templates/email-safe/email-launch.html +2 -2
  239. package/templates/email-safe/email-newsletter.html +2 -2
  240. package/templates/email-safe/email-status.html +2 -2
  241. package/templates/email-safe/email-transactional.html +2 -2
  242. package/templates/finance-dunning-email/FinanceDunningEmail.dc.html +6 -5
  243. package/templates/finance-dunning-email/ds-base.js +33 -1
  244. package/templates/finance-dunning-email/support.js +13 -20
  245. package/templates/finance-expense-report/FinanceExpenseReport.dc.html +4 -3
  246. package/templates/finance-expense-report/ds-base.js +33 -1
  247. package/templates/finance-expense-report/support.js +13 -20
  248. package/templates/finance-invoice/FinanceInvoice.dc.html +6 -5
  249. package/templates/finance-invoice/ds-base.js +33 -1
  250. package/templates/finance-invoice/support.js +13 -20
  251. package/templates/finance-quote/FinanceQuote.dc.html +6 -5
  252. package/templates/finance-quote/ds-base.js +33 -1
  253. package/templates/finance-quote/support.js +13 -20
  254. package/templates/hr-announcement/HrAnnouncement.dc.html +5 -4
  255. package/templates/hr-announcement/ds-base.js +33 -1
  256. package/templates/hr-announcement/support.js +13 -20
  257. package/templates/hr-interview-kit/HrInterviewKit.dc.html +5 -4
  258. package/templates/hr-interview-kit/ds-base.js +33 -1
  259. package/templates/hr-interview-kit/support.js +13 -20
  260. package/templates/hr-offboarding/HrOffboarding.dc.html +2 -1
  261. package/templates/hr-offboarding/ds-base.js +33 -1
  262. package/templates/hr-offboarding/support.js +13 -20
  263. package/templates/hr-performance-review/HrPerformanceReview.dc.html +2 -1
  264. package/templates/hr-performance-review/ds-base.js +33 -1
  265. package/templates/hr-performance-review/support.js +13 -20
  266. package/templates/hr-pip/HrPip.dc.html +2 -1
  267. package/templates/hr-pip/ds-base.js +33 -1
  268. package/templates/hr-pip/support.js +13 -20
  269. package/templates/kitchen-sink.html +9 -4
  270. package/templates/legal-msa/LegalMsa.dc.html +2 -1
  271. package/templates/legal-msa/ds-base.js +33 -1
  272. package/templates/legal-msa/support.js +13 -20
  273. package/templates/legal-sow/LegalSow.dc.html +2 -1
  274. package/templates/legal-sow/ds-base.js +33 -1
  275. package/templates/legal-sow/support.js +13 -20
  276. package/templates/marketing-campaign-brief/MarketingCampaignBrief.dc.html +3 -2
  277. package/templates/marketing-campaign-brief/ds-base.js +33 -1
  278. package/templates/marketing-campaign-brief/support.js +13 -20
  279. package/templates/marketing-case-study/MarketingCaseStudy.dc.html +6 -5
  280. package/templates/marketing-case-study/ds-base.js +33 -1
  281. package/templates/marketing-case-study/support.js +13 -20
  282. package/templates/marketing-launch/MarketingLaunch.dc.html +6 -5
  283. package/templates/marketing-launch/ds-base.js +33 -1
  284. package/templates/marketing-launch/support.js +13 -20
  285. package/templates/marketing-newsletter/MarketingNewsletter.dc.html +13 -12
  286. package/templates/marketing-newsletter/ds-base.js +33 -1
  287. package/templates/marketing-newsletter/support.js +13 -20
  288. package/templates/marketing-page/MarketingPage.dc.html +19 -14
  289. package/templates/marketing-page/content-schema.json +1 -0
  290. package/templates/marketing-page/ds-base.js +33 -1
  291. package/templates/marketing-page/support.js +13 -20
  292. package/templates/marketing-press-release/MarketingPressRelease.dc.html +2 -1
  293. package/templates/marketing-press-release/ds-base.js +33 -1
  294. package/templates/marketing-press-release/support.js +13 -20
  295. package/templates/marketing-social-kit/MarketingSocialKit.dc.html +5 -4
  296. package/templates/marketing-social-kit/ds-base.js +33 -1
  297. package/templates/marketing-social-kit/support.js +13 -20
  298. package/templates/sales-one-pager/SalesOnePager.dc.html +5 -4
  299. package/templates/sales-one-pager/ds-base.js +33 -1
  300. package/templates/sales-one-pager/support.js +13 -20
  301. package/templates/sales-proposal-deck/SalesProposalDeck.dc.html +7 -6
  302. package/templates/sales-proposal-deck/ds-base.js +33 -1
  303. package/templates/sales-proposal-deck/support.js +13 -20
  304. package/templates/settings/Settings.dc.html +7 -3
  305. package/templates/settings/content-schema.json +7 -0
  306. package/templates/settings/ds-base.js +33 -1
  307. package/templates/settings/support.js +13 -20
  308. package/templates/slide-deck/SlideDeck.dc.html +5 -4
  309. package/templates/slide-deck/ds-base.js +33 -1
  310. package/templates/slide-deck/support.js +13 -20
  311. package/templates/team-meeting-agenda/TeamMeetingAgenda.dc.html +2 -1
  312. package/templates/team-meeting-agenda/ds-base.js +33 -1
  313. package/templates/team-meeting-agenda/support.js +13 -20
  314. package/templates/tech-incident-report/TechIncidentReport.dc.html +3 -2
  315. package/templates/tech-incident-report/ds-base.js +33 -1
  316. package/templates/tech-incident-report/support.js +13 -20
  317. package/templates/tech-release-notes/TechReleaseNotes.dc.html +6 -5
  318. package/templates/tech-release-notes/ds-base.js +33 -1
  319. package/templates/tech-release-notes/support.js +13 -20
  320. package/templates/tech-retro/TechRetro.dc.html +4 -3
  321. package/templates/tech-retro/ds-base.js +33 -1
  322. package/templates/tech-retro/support.js +13 -20
  323. package/templates/tech-rfc/TechRfc.dc.html +3 -2
  324. package/templates/tech-rfc/ds-base.js +33 -1
  325. package/templates/tech-rfc/support.js +13 -20
  326. package/templates/vn-appointment-transfer/VnAppointmentTransfer.dc.html +36 -35
  327. package/templates/vn-appointment-transfer/ds-base.js +33 -1
  328. package/templates/vn-appointment-transfer/support.js +13 -20
  329. package/templates/vn-certificate-of-employment/VnCertificateOfEmployment.dc.html +27 -26
  330. package/templates/vn-certificate-of-employment/ds-base.js +33 -1
  331. package/templates/vn-certificate-of-employment/support.js +13 -20
  332. package/templates/vn-code-of-conduct/VnCodeOfConduct.dc.html +44 -43
  333. package/templates/vn-code-of-conduct/ds-base.js +33 -1
  334. package/templates/vn-code-of-conduct/support.js +13 -20
  335. package/templates/vn-compensation-regulation/VnCompensationRegulation.dc.html +53 -52
  336. package/templates/vn-compensation-regulation/ds-base.js +33 -1
  337. package/templates/vn-compensation-regulation/support.js +13 -20
  338. package/templates/vn-contract-amendment/VnContractAmendment.dc.html +41 -40
  339. package/templates/vn-contract-amendment/ds-base.js +33 -1
  340. package/templates/vn-contract-amendment/support.js +13 -20
  341. package/templates/vn-contractor-agreement/VnContractorAgreement.dc.html +50 -49
  342. package/templates/vn-contractor-agreement/ds-base.js +33 -1
  343. package/templates/vn-contractor-agreement/support.js +13 -20
  344. package/templates/vn-data-protection-policy/VnDataProtectionPolicy.dc.html +54 -53
  345. package/templates/vn-data-protection-policy/ds-base.js +33 -1
  346. package/templates/vn-data-protection-policy/support.js +13 -20
  347. package/templates/vn-disciplinary-case-file/VnDisciplinaryCaseFile.dc.html +72 -71
  348. package/templates/vn-disciplinary-case-file/ds-base.js +33 -1
  349. package/templates/vn-disciplinary-case-file/support.js +13 -20
  350. package/templates/vn-disciplinary-schedule/VnDisciplinarySchedule.dc.html +21 -20
  351. package/templates/vn-disciplinary-schedule/ds-base.js +33 -1
  352. package/templates/vn-disciplinary-schedule/support.js +13 -20
  353. package/templates/vn-employee-request/VnEmployeeRequest.dc.html +54 -53
  354. package/templates/vn-employee-request/ds-base.js +33 -1
  355. package/templates/vn-employee-request/support.js +13 -20
  356. package/templates/vn-exit-handover/VnExitHandover.dc.html +122 -121
  357. package/templates/vn-exit-handover/ds-base.js +33 -1
  358. package/templates/vn-exit-handover/support.js +13 -20
  359. package/templates/vn-foreign-employee-pack/VnForeignEmployeePack.dc.html +31 -30
  360. package/templates/vn-foreign-employee-pack/ds-base.js +33 -1
  361. package/templates/vn-foreign-employee-pack/support.js +13 -20
  362. package/templates/vn-grassroots-democracy/VnGrassrootsDemocracy.dc.html +54 -53
  363. package/templates/vn-grassroots-democracy/ds-base.js +33 -1
  364. package/templates/vn-grassroots-democracy/support.js +13 -20
  365. package/templates/vn-infosec-policy/VnInfosecPolicy.dc.html +50 -49
  366. package/templates/vn-infosec-policy/ds-base.js +33 -1
  367. package/templates/vn-infosec-policy/support.js +13 -20
  368. package/templates/vn-internal-labor-regulations/VnInternalLaborRegulations.dc.html +84 -83
  369. package/templates/vn-internal-labor-regulations/ds-base.js +33 -1
  370. package/templates/vn-internal-labor-regulations/support.js +13 -20
  371. package/templates/vn-internship-agreement/VnInternshipAgreement.dc.html +44 -43
  372. package/templates/vn-internship-agreement/ds-base.js +33 -1
  373. package/templates/vn-internship-agreement/support.js +13 -20
  374. package/templates/vn-job-description/VnJobDescription.dc.html +28 -27
  375. package/templates/vn-job-description/ds-base.js +33 -1
  376. package/templates/vn-job-description/support.js +13 -20
  377. package/templates/vn-labor-contract/VnLaborContract.dc.html +109 -108
  378. package/templates/vn-labor-contract/ds-base.js +33 -1
  379. package/templates/vn-labor-contract/support.js +13 -20
  380. package/templates/vn-labour-management-book/VnLabourManagementBook.dc.html +32 -31
  381. package/templates/vn-labour-management-book/ds-base.js +33 -1
  382. package/templates/vn-labour-management-book/support.js +13 -20
  383. package/templates/vn-mutual-nda/VnMutualNda.dc.html +45 -44
  384. package/templates/vn-mutual-nda/ds-base.js +33 -1
  385. package/templates/vn-mutual-nda/support.js +13 -20
  386. package/templates/vn-ndnca-ip/VnNdncaIp.dc.html +73 -72
  387. package/templates/vn-ndnca-ip/ds-base.js +33 -1
  388. package/templates/vn-ndnca-ip/support.js +13 -20
  389. package/templates/vn-offer-letter/VnOfferLetter.dc.html +32 -31
  390. package/templates/vn-offer-letter/ds-base.js +33 -1
  391. package/templates/vn-offer-letter/support.js +13 -20
  392. package/templates/vn-onboarding-checklist/VnOnboardingChecklist.dc.html +16 -15
  393. package/templates/vn-onboarding-checklist/ds-base.js +33 -1
  394. package/templates/vn-onboarding-checklist/support.js +13 -20
  395. package/templates/vn-pdpl-consent/VnPdplConsent.dc.html +43 -42
  396. package/templates/vn-pdpl-consent/ds-base.js +33 -1
  397. package/templates/vn-pdpl-consent/support.js +13 -20
  398. package/templates/vn-performance-evaluation-regulation/VnPerformanceEvaluationRegulation.dc.html +65 -64
  399. package/templates/vn-performance-evaluation-regulation/ds-base.js +33 -1
  400. package/templates/vn-performance-evaluation-regulation/support.js +13 -20
  401. package/templates/vn-performance-review-form/VnPerformanceReviewForm.dc.html +49 -48
  402. package/templates/vn-performance-review-form/ds-base.js +33 -1
  403. package/templates/vn-performance-review-form/support.js +13 -20
  404. package/templates/vn-phantom-stock/VnPhantomStock.dc.html +41 -40
  405. package/templates/vn-phantom-stock/ds-base.js +33 -1
  406. package/templates/vn-phantom-stock/support.js +13 -20
  407. package/templates/vn-probation-contract/VnProbationContract.dc.html +56 -55
  408. package/templates/vn-probation-contract/ds-base.js +33 -1
  409. package/templates/vn-probation-contract/support.js +13 -20
  410. package/templates/vn-receipt-acknowledgement/VnReceiptAcknowledgement.dc.html +28 -27
  411. package/templates/vn-receipt-acknowledgement/ds-base.js +33 -1
  412. package/templates/vn-receipt-acknowledgement/support.js +13 -20
  413. package/templates/vn-remote-work-policy/VnRemoteWorkPolicy.dc.html +44 -43
  414. package/templates/vn-remote-work-policy/ds-base.js +33 -1
  415. package/templates/vn-remote-work-policy/support.js +13 -20
  416. package/templates/vn-resignation-letter/VnResignationLetter.dc.html +20 -19
  417. package/templates/vn-resignation-letter/ds-base.js +33 -1
  418. package/templates/vn-resignation-letter/support.js +13 -20
  419. package/templates/vn-salary-scale/VnSalaryScale.dc.html +39 -38
  420. package/templates/vn-salary-scale/ds-base.js +33 -1
  421. package/templates/vn-salary-scale/support.js +13 -20
  422. package/templates/vn-sow-appendix/VnSowAppendix.dc.html +21 -20
  423. package/templates/vn-sow-appendix/ds-base.js +33 -1
  424. package/templates/vn-sow-appendix/support.js +13 -20
  425. package/templates/vn-termination-decision/VnTerminationDecision.dc.html +25 -24
  426. package/templates/vn-termination-decision/ds-base.js +33 -1
  427. package/templates/vn-termination-decision/support.js +13 -20
  428. package/templates/vn-total-rewards-appendix/VnTotalRewardsAppendix.dc.html +63 -62
  429. package/templates/vn-total-rewards-appendix/ds-base.js +33 -1
  430. package/templates/vn-total-rewards-appendix/support.js +13 -20
  431. package/templates/vn-training-commitment/VnTrainingCommitment.dc.html +39 -38
  432. package/templates/vn-training-commitment/ds-base.js +33 -1
  433. package/templates/vn-training-commitment/support.js +13 -20
  434. package/templates/vn-travel-expense-policy/VnTravelExpensePolicy.dc.html +50 -49
  435. package/templates/vn-travel-expense-policy/ds-base.js +33 -1
  436. package/templates/vn-travel-expense-policy/support.js +13 -20
  437. package/tokens/colors.css +19 -1
  438. package/tokens/component-tokens.css +1 -0
  439. package/tokens/element-seeds.json +2 -2
  440. package/tokens/elements.css +228 -21
  441. package/tokens/elevation.css +8 -2
  442. package/tokens/native/CSTokens.kt +37 -2
  443. package/tokens/native/CSTokens.swift +37 -2
  444. package/tokens/native/cs_tokens.dart +37 -2
  445. package/tokens/provenance.json +12 -12
  446. package/tokens/spacing.css +4 -1
  447. package/tokens/tokens.dtcg.json +129 -16
  448. package/tokens/tokens.js +59 -18
  449. package/tokens/tokens.json +58 -17
  450. package/tokens/typography.css +2 -0
  451. package/ui_kits/deck/index.html +4 -0
  452. package/ui_kits/status-hub/StatusHub.jsx +30 -4
  453. package/ui_kits/status-hub/index.html +3 -3
  454. package/ui_kits/status-hub/login.html +55 -9
  455. package/ui_kits/status-hub/project.html +4 -0
  456. package/ui_kits/status-hub/settings.html +35 -13
  457. package/ui_kits/status-hub/status.css +5 -1
  458. package/ui_kits/website/Website.jsx +25 -3
  459. package/ui_kits/website/careers.html +5 -1
  460. package/ui_kits/website/chat.html +5 -3
  461. package/ui_kits/website/index.html +3 -3
  462. package/ui_kits/website/site.css +3 -3
  463. package/ui_kits/website/work.html +5 -1
  464. package/assets/aurora-hoa.png +0 -0
  465. package/assets/aurora-kim.png +0 -0
  466. package/assets/aurora-moc.png +0 -0
  467. package/assets/aurora-thuy.png +0 -0
  468. package/docs/status/assets/favicon.svg +0 -5
  469. package/docs/status/assets/status-legacy.css +0 -399
  470. package/docs/status/assets/status-legacy.js +0 -505
  471. package/docs/status/assets/status.css +0 -644
  472. package/docs/status/assets/status.js +0 -1308
  473. package/docs/status/data/status-feed.json +0 -1
  474. package/docs/status/data/task/TASK-REL-001.js +0 -1
  475. package/docs/status/data/task/TASK-REL-002.js +0 -1
  476. package/docs/status/index.html +0 -42
  477. package/docs/status/roadmap.html +0 -4
  478. package/docs/status/status-legacy.html +0 -117
  479. package/docs/tasks/BACKLOG.md +0 -26
  480. package/docs/tasks/release/TASK-REL-001-launch-1-1-0/spec.md +0 -55
  481. package/docs/tasks/release/TASK-REL-002-republish-1-1-1/spec.md +0 -54
package/base/feedback.css CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  /* Badge — compact status label */
4
4
  .cs-badge { display: inline-flex; align-items: center; gap: 5px; font-family: var(--cs-font-family-ui); font-size: var(--cs-font-size-xs); font-weight: 700; line-height: 1; padding: 4px 9px; border-radius: var(--cs-radius-full); text-transform: uppercase; letter-spacing: 0.04em; background: var(--cs-color-surface-raised); color: var(--cs-color-text-accent); border: 1px solid var(--cs-color-border-default); }
5
- .cs-badge--solid { border-color: transparent; color: #fff; background: var(--cs-color-brand-umber); }
5
+ .cs-badge--solid { border-color: transparent; color: #fff; /* on-brand-umber ink (allowlisted; text-inverse flips in dark) */ background: var(--cs-color-brand-umber); }
6
6
  .cs-badge--ochre { background: var(--cs-color-brand-ochre); color: var(--cs-color-brand-umber); border-color: transparent; }
7
7
  .cs-badge--success { background: var(--cs-color-semantic-success); color: var(--cs-color-text-inverse); border-color: transparent; }
8
8
  .cs-badge--danger { background: var(--cs-color-semantic-danger); color: var(--cs-color-text-inverse); border-color: transparent; }
@@ -16,10 +16,13 @@
16
16
  .cs-tag__close:hover { background: color-mix(in oklab, var(--cs-color-brand-umber) 12%, transparent); }
17
17
 
18
18
  /* Alert / Banner */
19
- .cs-alert { display: grid; grid-template-columns: auto 1fr; gap: 12px; padding: 14px 16px; border-radius: var(--cs-radius-md); border: 1px solid var(--cs-color-border-default); background: var(--cs-color-surface-panel); color: var(--cs-color-text-primary); }
19
+ .cs-alert { display: grid; grid-template-columns: auto 1fr auto; gap: 12px; padding: 14px 16px; border-radius: var(--cs-radius-md); border: 1px solid var(--cs-color-border-default); background: var(--cs-color-surface-panel); color: var(--cs-color-text-primary); align-items: start; }
20
20
  .cs-alert__icon { color: var(--cs-color-text-accent); display: grid; place-items: start; padding-block-start: 1px; }
21
21
  .cs-alert__title { font-weight: 700; margin: 0 0 2px; }
22
22
  .cs-alert__body { margin: 0; color: var(--cs-color-text-muted); font-size: var(--cs-font-size-sm); }
23
+ .cs-alert__dismiss { appearance: none; border: 0; background: transparent; color: var(--cs-color-text-muted); cursor: pointer; font-size: var(--cs-font-size-md, 1.125rem); line-height: 1; padding: 0 2px; border-radius: var(--cs-radius-sm); }
24
+ .cs-alert__dismiss:hover { color: var(--cs-color-text-primary); }
25
+ .cs-alert__dismiss:focus-visible { outline: 2px solid var(--cs-color-focus-ring, var(--cs-accent-bright)); outline-offset: 2px; }
23
26
  .cs-alert--info { border-inline-start: 4px solid var(--cs-color-semantic-info); }
24
27
  .cs-alert--info .cs-alert__icon { color: var(--cs-color-semantic-info); }
25
28
  .cs-alert--success { border-inline-start: 4px solid var(--cs-color-semantic-success); }
@@ -33,7 +36,11 @@
33
36
  .cs-toast-stack { position: fixed; inset-block-end: 20px; inset-inline-end: 20px; z-index: var(--cs-depth-toast); display: grid; gap: 10px; max-inline-size: min(380px, calc(100vw - 40px)); }
34
37
  .cs-toast { display: grid; grid-template-columns: auto 1fr auto; gap: 12px; align-items: start; padding: 12px 14px; border-radius: var(--cs-radius-md); background: var(--cs-color-surface-panel); border: 1px solid var(--cs-color-border-default); box-shadow: var(--cs-shadow-md); color: var(--cs-color-text-primary); animation: cs-toast-in var(--cs-duration-base) var(--cs-ease-entrance); }
35
38
  .cs-toast__icon { color: var(--cs-color-text-accent); }
39
+ .cs-toast--default { border-inline-start: 4px solid var(--cs-color-semantic-info); }
40
+ .cs-toast--default .cs-toast__icon { color: var(--cs-color-semantic-info); }
41
+ .cs-toast--success { border-inline-start: 4px solid var(--cs-color-semantic-success); }
36
42
  .cs-toast--success .cs-toast__icon { color: var(--cs-color-semantic-success); }
43
+ .cs-toast--danger { border-inline-start: 4px solid var(--cs-color-semantic-danger); }
37
44
  .cs-toast--danger .cs-toast__icon { color: var(--cs-color-semantic-danger); }
38
45
  .cs-toast__title { font-weight: 700; font-size: var(--cs-font-size-sm); }
39
46
  .cs-toast__body { font-size: var(--cs-font-size-sm); color: var(--cs-color-text-muted); margin-block-start: 2px; }
@@ -58,3 +65,8 @@
58
65
  .cs-skeleton--circle { border-radius: 50%; }
59
66
  @keyframes cs-shimmer { from { background-position: 100% 0; } to { background-position: 0 0; } }
60
67
  @media (prefers-reduced-motion: reduce) { .cs-skeleton { animation: none; } }
68
+
69
+ /* ---- system-theme dark parity (UX-010 / CDS-THEME-001) ---- */
70
+ @media (prefers-color-scheme: dark) {
71
+ [data-theme="system"] .cs-spinner { border-color: color-mix(in oklab, var(--cs-color-brand-ochre) 26%, transparent); border-top-color: var(--cs-color-brand-ochre); }
72
+ }
package/base/forms.css CHANGED
@@ -5,13 +5,13 @@
5
5
  .cs-select { position: relative; display: block; }
6
6
  .cs-select select.cs-field__control { appearance: none; -webkit-appearance: none; width: 100%; padding-inline-end: 38px; cursor: pointer; background: var(--cs-color-surface-panel); }
7
7
  .cs-select__chevron { position: absolute; inset-inline-end: 12px; inset-block-start: 50%; transform: translateY(-50%); pointer-events: none; color: var(--cs-color-text-muted); display: grid; place-items: center; }
8
- .cs-select select.cs-field__control:focus-visible { outline: 3px solid var(--cs-color-accent-ochre); outline-offset: 2px; border-color: var(--cs-color-brand-ochre); }
8
+ .cs-select select.cs-field__control:focus-visible { outline: var(--cs-focus-ring, 3px) solid var(--cs-color-accent-ochre); outline-offset: 2px; border-color: var(--cs-color-brand-ochre); }
9
9
 
10
10
  /* NativeSelect — lean progressive-enhancement companion beside Select */
11
11
  .cs-native-select { position: relative; display: block; }
12
12
  .cs-native-select select.cs-field__control { appearance: none; -webkit-appearance: none; width: 100%; padding-inline-end: 38px; cursor: pointer; background: var(--cs-color-surface-panel); }
13
13
  .cs-native-select__chevron { position: absolute; inset-inline-end: 12px; inset-block-start: 50%; transform: translateY(-50%); pointer-events: none; color: var(--cs-color-text-muted); display: grid; place-items: center; }
14
- .cs-native-select select.cs-field__control:focus-visible { outline: 3px solid var(--cs-color-accent-ochre); outline-offset: 2px; border-color: var(--cs-color-brand-ochre); }
14
+ .cs-native-select select.cs-field__control:focus-visible { outline: var(--cs-focus-ring, 3px) solid var(--cs-color-accent-ochre); outline-offset: 2px; border-color: var(--cs-color-brand-ochre); }
15
15
  .cs-native-select--sm select.cs-field__control { min-block-size: 36px; padding-block: 6px; font-size: var(--cs-font-size-sm); }
16
16
  .cs-native-select--md select.cs-field__control { min-block-size: 44px; }
17
17
 
@@ -29,12 +29,18 @@
29
29
  .cs-switch { display: inline-flex; align-items: center; gap: 10px; cursor: pointer; font-family: var(--cs-font-family-ui); color: var(--cs-color-text-primary); }
30
30
  .cs-switch input { position: absolute; opacity: 0; width: 0; height: 0; }
31
31
  .cs-switch__track { inline-size: 44px; block-size: 26px; border-radius: 999px; background: var(--cs-color-border-default); position: relative; transition: background var(--cs-duration-fast) var(--cs-ease-standard); flex: none; }
32
- .cs-switch__track::after { content: ""; position: absolute; inset-block-start: 3px; inset-inline-start: 3px; inline-size: 20px; block-size: 20px; border-radius: 50%; background: #fff; box-shadow: var(--cs-shadow-xs); transition: transform var(--cs-duration-fast) var(--cs-ease-standard); }
32
+ .cs-switch__track::after { content: ""; position: absolute; inset-block-start: 3px; inset-inline-start: 3px; inline-size: 20px; block-size: 20px; border-radius: 50%; background: var(--cs-color-surface-panel, #fff); box-shadow: var(--cs-shadow-xs); transition: transform var(--cs-duration-fast) var(--cs-ease-standard); }
33
33
  .cs-switch input:checked + .cs-switch__track { background: var(--cs-color-brand-umber); }
34
34
  [data-theme="dark"] .cs-switch input:checked + .cs-switch__track { background: var(--cs-color-brand-ochre); }
35
35
  .cs-switch input:checked + .cs-switch__track::after { transform: translateX(18px); }
36
- .cs-switch input:focus-visible + .cs-switch__track { outline: 3px solid var(--cs-color-accent-ochre); outline-offset: 2px; }
36
+ .cs-switch input:focus-visible + .cs-switch__track { outline: var(--cs-focus-ring, 3px) solid var(--cs-color-accent-ochre); outline-offset: 2px; }
37
37
  .cs-switch.is-disabled { opacity: 0.55; cursor: not-allowed; }
38
38
 
39
39
  /* Textarea reuses .cs-field; give it sane sizing */
40
40
  textarea.cs-field__control { min-height: 96px; resize: vertical; line-height: var(--cs-font-lineHeight-body); }
41
+
42
+ /* ---- system-theme dark parity (UX-010 / CDS-THEME-001) ---- */
43
+ @media (prefers-color-scheme: dark) {
44
+ [data-theme="system"] .cs-check input, [data-theme="system"] .cs-radio input { accent-color: var(--cs-color-brand-ochre); }
45
+ [data-theme="system"] .cs-switch input:checked + .cs-switch__track { background: var(--cs-color-brand-ochre); }
46
+ }
package/base/glass.css CHANGED
@@ -114,6 +114,12 @@
114
114
  radial-gradient(90% 120% at 12% -10%, color-mix(in oklab, var(--cs-color-brand-ochre) 46%, transparent), transparent 55%),
115
115
  radial-gradient(70% 90% at 88% 8%, color-mix(in oklab, #ffcf5c 32%, transparent), transparent 60%),
116
116
  radial-gradient(120% 120% at 50% 120%, color-mix(in oklab, #1a1108 60%, transparent), transparent 60%);
117
- color: #fff;
117
+ color: #fff; /* on-aurora wash */
118
118
  }
119
119
  .cs-aurora--photo { background-size: cover; background-position: center; }
120
+
121
+ /* ---- system-theme dark parity (UX-010 / CDS-THEME-001) ---- */
122
+ @media (prefers-color-scheme: dark) {
123
+ /* ---- 5. Dark-mode border tuning ---- */
124
+ [data-theme="system"] { --cs-color-border-default: #4a3a2c; }
125
+ }
@@ -22,15 +22,19 @@
22
22
  box-shadow: var(--cs-shadow-xs);
23
23
  }
24
24
 
25
- /* ---- 2. Soft ochre focus glow — layered on the immutable 3px ring ---- */
25
+ /* ---- 2. Focus halo — ochre brand ring outside the high-contrast contour (FIND-032) ---- */
26
26
  .cs-button:focus-visible,
27
27
  .cs-field__control:focus-visible,
28
28
  .cs-select select.cs-field__control:focus-visible,
29
29
  .cs-native-select select.cs-field__control:focus-visible,
30
30
  .cs-search:focus-within,
31
+ .cs-stepper:focus-within,
32
+ .cs-prompt:focus-within,
33
+ .cs-cmdk__search:focus-within,
34
+ .cs-terminal:focus-within,
31
35
  .cs-ai-disclosure__badge:focus-visible,
32
36
  .cs-switch input:focus-visible + .cs-switch__track {
33
- box-shadow: 0 0 0 5px color-mix(in oklab, var(--cs-color-accent-ochre) 26%, transparent);
37
+ box-shadow: 0 0 0 5px var(--cs-color-accent-ochre);
34
38
  }
35
39
 
36
40
  /* ---- 3. Entrance motion utilities (opt-in) + a gentle Dialog entrance ---- */
@@ -6,7 +6,7 @@
6
6
  .cs-tab:hover { color: var(--cs-color-text-primary); }
7
7
  .cs-tab[aria-selected="true"] { color: var(--cs-color-brand-umber); border-block-end-color: var(--cs-color-brand-ochre); }
8
8
  [data-theme="dark"] .cs-tab[aria-selected="true"] { color: var(--cs-color-brand-ochre); }
9
- .cs-tab:focus-visible { outline: 3px solid var(--cs-color-accent-ochre); outline-offset: -3px; border-radius: var(--cs-radius-sm); }
9
+ .cs-tab:focus-visible { outline: var(--cs-focus-ring, 3px) solid var(--cs-color-accent-ochre); outline-offset: -3px; border-radius: var(--cs-radius-sm); }
10
10
  .cs-tab__count { font-family: var(--cs-font-family-mono); font-size: var(--cs-font-size-xs); background: var(--cs-color-surface-raised); border-radius: var(--cs-radius-full); padding: 1px 7px; }
11
11
 
12
12
  /* Breadcrumb */
@@ -28,12 +28,18 @@
28
28
 
29
29
  /* Menu / Dropdown */
30
30
  .cs-menu { position: relative; display: inline-block; }
31
- .cs-menu__list { position: absolute; inset-block-start: calc(100% + 6px); inset-inline-start: 0; min-inline-size: 200px; background: var(--cs-color-surface-panel); border: 1px solid var(--cs-color-border-default); border-radius: var(--cs-radius-md); box-shadow: var(--cs-shadow-md); padding: 6px; z-index: var(--cs-depth-toast); display: grid; gap: 2px; }
31
+ .cs-menu__list { position: absolute; inset-block-start: calc(100% + 6px); inset-inline-start: 0; min-inline-size: 200px; background: var(--cs-color-surface-panel); border: 1px solid var(--cs-color-border-default); border-radius: var(--cs-radius-md); box-shadow: var(--cs-shadow-md); padding: 6px; z-index: var(--cs-depth-dropdown, 60); display: grid; gap: 2px; }
32
32
  .cs-menu__list--end { inset-inline-start: auto; inset-inline-end: 0; }
33
33
  .cs-menu__item { display: flex; align-items: center; gap: 10px; inline-size: 100%; text-align: start; border: 0; background: transparent; font: inherit; font-family: var(--cs-font-family-ui); font-size: var(--cs-font-size-sm); color: var(--cs-color-text-primary); padding: 8px 10px; border-radius: var(--cs-radius-sm); cursor: pointer; }
34
34
  .cs-menu__item:hover { background: var(--cs-color-surface-raised); }
35
- .cs-menu__item:focus-visible { background: var(--cs-color-surface-raised); outline: 3px solid var(--cs-color-accent-ochre); outline-offset: -3px; }
35
+ .cs-menu__item:focus-visible { background: var(--cs-color-surface-raised); outline: var(--cs-focus-ring, 3px) solid var(--cs-color-accent-ochre); outline-offset: -3px; }
36
36
  .cs-menu__item--danger { color: var(--cs-color-semantic-danger); }
37
37
  .cs-menu__item--danger:hover { background: color-mix(in oklab, var(--cs-color-semantic-danger) 10%, transparent); }
38
38
  .cs-menu__sep { block-size: 1px; background: var(--cs-color-border-default); margin: 4px 2px; }
39
39
  .cs-menu__label { font-size: var(--cs-font-size-xs); text-transform: uppercase; letter-spacing: var(--cs-letter-spacing-caps); color: var(--cs-color-text-muted); padding: 6px 10px 2px; }
40
+
41
+ /* ---- system-theme dark parity (UX-010 / CDS-THEME-001) ---- */
42
+ @media (prefers-color-scheme: dark) {
43
+ [data-theme="system"] .cs-tab[aria-selected="true"] { color: var(--cs-color-brand-ochre); }
44
+ [data-theme="system"] .cs-pagination button[aria-current="page"] { background: var(--cs-color-brand-ochre); color: var(--cs-color-brand-umber); }
45
+ }
package/base/reset.css CHANGED
@@ -14,4 +14,10 @@ body {
14
14
  :where(h1, h2, h3, h4, h5, h6) { line-height: var(--cs-font-lineHeight-heading, 1.35); text-wrap: balance; }
15
15
  :where(p) { text-wrap: pretty; }
16
16
  :where(code, pre, kbd, samp) { font-family: var(--cs-font-family-mono, ui-monospace, monospace); }
17
- :where(:focus-visible) { outline: 2px solid var(--cs-color-accent-ochre, #f4ba17); outline-offset: 2px; }
17
+ /* Composite focus indicator (FIND-032): high-contrast text-primary contour (≥3:1
18
+ * on light + dark surfaces) + ochre outer brand halo. Ochre alone is ~1.7:1 on cream. */
19
+ :where(:focus-visible) {
20
+ outline: 2px solid var(--cs-color-text-primary, #45210e);
21
+ outline-offset: 2px;
22
+ box-shadow: 0 0 0 5px var(--cs-color-accent-ochre, #f4ba17);
23
+ }
@@ -1,4 +1,5 @@
1
1
  /* CyberSkill — global responsive layer (loaded LAST so it can adapt any surface).
2
+ * FIND-007: width stops ⊆ token breakpoints (incl. justified `phone` 360).
2
3
  * The system is desktop-first but every artifact must read on tablet and phone.
3
4
  * Strategy: (1) media never overflows; (2) the print-doc archetype (cs-desk /
4
5
  * cs-sheet) relaxes its generous desktop padding on small screens; (3) shared class
@@ -13,28 +14,38 @@
13
14
  /* 1 — Media and embeds never blow out a column */
14
15
  img, svg, video, canvas { max-width: 100%; height: auto; }
15
16
 
17
+ /* G1 / CDS-RESP-001 — container-query migration (compatibility layer).
18
+ * Opt-in hosts mark a sizing context with `.cs-cq`. Children can use
19
+ * `@container (max-width: …)` without waiting for a full layout rewrite.
20
+ * Media queries above remain the default until packs generate CQ variants. */
21
+ .cs-cq { container-type: inline-size; container-name: cs; }
22
+ @container cs (max-width: 640px) {
23
+ .cs-cq-stack { display: flex !important; flex-direction: column !important; }
24
+ .cs-cq-stack > * { min-inline-size: 0; max-inline-size: 100%; }
25
+ }
26
+
16
27
  /* 2 — Print-doc archetype: shrink desk + sheet chrome as the screen narrows.
17
28
  * cs-desk is the grey backing; cs-sheet is the white page. */
18
- @media screen and (max-width: 900px) {
29
+ @media screen and (max-width: 768px) {
19
30
  .cs-desk { padding: 24px 10px !important; }
20
31
  .cs-sheet { padding: 40px 40px !important; }
21
32
  }
22
- @media screen and (max-width: 620px) {
33
+ @media screen and (max-width: 640px) {
23
34
  .cs-desk { padding: 12px 6px !important; }
24
35
  .cs-sheet { padding: 26px 20px !important; border-radius: 8px !important; }
25
36
  }
26
- @media screen and (max-width: 460px) {
37
+ @media screen and (max-width: 360px) {
27
38
  .cs-sheet { padding: 20px 15px !important; }
28
39
  }
29
40
 
30
41
  /* 3 — Wide tables inside sheets/panels scroll horizontally instead of clipping */
31
- @media screen and (max-width: 760px) {
42
+ @media screen and (max-width: 768px) {
32
43
  .cs-sheet table, .cs-table-scroll { display: block; overflow-x: auto; -webkit-overflow-scrolling: touch; }
33
44
  }
34
45
 
35
46
  /* 4 — App shell: the sidebar + main is a fixed two-column inline grid on desktop.
36
47
  * Collapse it to a stacked layout; the sidebar becomes a horizontal nav strip. */
37
- @media screen and (max-width: 760px) {
48
+ @media screen and (max-width: 768px) {
38
49
  .cs-sidebar { position: static !important; width: auto !important; height: auto !important;
39
50
  display: flex !important; flex-wrap: wrap !important; gap: 4px 10px !important;
40
51
  align-items: center !important; border-inline-end: 0 !important;
@@ -49,12 +60,12 @@ img, svg, video, canvas { max-width: 100%; height: auto; }
49
60
  * even on a laptop (≈1280), which otherwise overflowed the document. The legible
50
61
  * min-width floor for the inner track only applies once the window itself is narrow. */
51
62
  .cs-canvas-desk { overflow-x: auto; -webkit-overflow-scrolling: touch; }
52
- @media screen and (max-width: 1120px) {
63
+ @media screen and (max-width: 1280px) {
53
64
  .cs-canvas-desk > * { min-width: 960px; }
54
65
  }
55
66
 
56
67
  /* 6 — Very wide section padding eases in on phones */
57
- @media screen and (max-width: 620px) {
68
+ @media screen and (max-width: 640px) {
58
69
  section[style*="padding: 84px"], section[style*="padding: 80px"],
59
70
  section[style*="padding: 72px"] { padding-inline: 22px !important; }
60
71
  }
@@ -66,13 +77,13 @@ img, svg, video, canvas { max-width: 100%; height: auto; }
66
77
  * Tablet: 3+ cols → 2. Phone: everything → 1 (declared after, so it wins at the
67
78
  * narrow width). Print is unaffected — the @page is wide, so these screen
68
79
  * breakpoints never fire during print/export. */
69
- @media screen and (max-width: 900px) {
80
+ @media screen and (max-width: 768px) {
70
81
  [style*="grid-template-columns: repeat(3"],
71
82
  [style*="grid-template-columns: repeat(4"],
72
83
  [style*="grid-template-columns: repeat(5"],
73
84
  [style*="grid-template-columns: repeat(6"] { grid-template-columns: repeat(2, 1fr) !important; }
74
85
  }
75
- @media screen and (max-width: 600px) {
86
+ @media screen and (max-width: 640px) {
76
87
  [style*="grid-template-columns: repeat(2"],
77
88
  [style*="grid-template-columns: repeat(3"],
78
89
  [style*="grid-template-columns: repeat(4"],
@@ -93,7 +104,7 @@ img, svg, video, canvas { max-width: 100%; height: auto; }
93
104
  /* 8 — Touch targets reach the 44px minimum on phones/tablets (the system's a11y
94
105
  * floor). Base sidebar nav rows (39px) and the topbar search input (26px) are
95
106
  * fine for mouse on desktop but too small to tap; grow them on small screens. */
96
- @media screen and (max-width: 760px) {
107
+ @media screen and (max-width: 768px) {
97
108
  .cs-sidebar .cs-nav-item, .cs-nav-item { min-height: 44px; }
98
109
  .cs-search { display: flex; align-items: center; min-height: 44px; }
99
110
  .cs-search input, .cs-search select { min-height: 44px; }
@@ -108,7 +119,7 @@ img, svg, video, canvas { max-width: 100%; height: auto; }
108
119
  * being propped open. It only breaks a token when it would otherwise overflow, so
109
120
  * ordinary prose is untouched. Scoped to the print-doc wrapper; the print @page is
110
121
  * wide, so this screen breakpoint never fires during export. */
111
- @media screen and (max-width: 760px) {
122
+ @media screen and (max-width: 768px) {
112
123
  .cs-desk, .cs-sheet { overflow-wrap: anywhere; }
113
124
  }
114
125
 
@@ -120,9 +131,24 @@ img, svg, video, canvas { max-width: 100%; height: auto; }
120
131
  * attribute selector reliably overrides an inline grid-template-columns (a class
121
132
  * selector does not). Then let the app-region grids shrink (min-width:0) and the data
122
133
  * table scroll inside its panel instead of forcing the page wide. */
123
- @media screen and (max-width: 760px) {
134
+ @media screen and (max-width: 768px) {
124
135
  [style*="grid-template-columns: 248px 1fr"] { grid-template-columns: 1fr !important; }
125
136
  main { min-width: 0; }
126
137
  main > * { min-width: 0; }
127
138
  .cs-table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
128
139
  }
140
+
141
+ /* ---- 320 reflow (UX-003 / WCAG 1.4.10) ---- */
142
+ @media (max-width: 360px) {
143
+ .cs-tabs { overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: thin; }
144
+ .cs-pagination { flex-wrap: wrap; max-inline-size: 100%; }
145
+ .cs-pagination button { min-inline-size: 32px; }
146
+ .cs-otp { gap: 4px; }
147
+ .cs-otp__box { inline-size: 36px; block-size: 40px; font-size: var(--cs-font-size-base); }
148
+ .cs-dl { grid-template-columns: 1fr; }
149
+ .cs-field { min-inline-size: 0; }
150
+ .cs-field__control { min-inline-size: 0; }
151
+ .card, button.card, article.case { min-width: 0 !important; }
152
+ [style*="minmax(320px"] { grid-template-columns: 1fr !important; }
153
+ [style*="grid-template-columns: 248px 1fr"] { grid-template-columns: 1fr !important; }
154
+ }
package/base/shell.css CHANGED
@@ -16,8 +16,8 @@
16
16
  .cs-steps { display: flex; gap: 0; }
17
17
  .cs-step { flex: 1; display: flex; flex-direction: column; align-items: flex-start; gap: 8px; position: relative; padding-inline-end: 12px; }
18
18
  .cs-step:not(:last-child)::after { content: ""; position: absolute; inset-block-start: 13px; inset-inline-start: 34px; inline-size: calc(100% - 46px); block-size: 2px; background: var(--cs-color-border-default); }
19
- .cs-step__marker { inline-size: 28px; block-size: 28px; border-radius: 50%; display: grid; place-items: center; font-family: var(--cs-font-family-mono); font-weight: 700; font-size: 13px; background: var(--cs-color-surface-raised); color: var(--cs-color-text-muted); border: 1px solid var(--cs-color-border-default); z-index: 1; }
20
- .cs-step--done .cs-step__marker { background: var(--cs-color-brand-umber); color: #fff; border-color: transparent; }
19
+ .cs-step__marker { inline-size: 28px; block-size: 28px; border-radius: 50%; display: grid; place-items: center; font-family: var(--cs-font-family-mono); font-weight: 700; font-size: var(--cs-font-size-sm); background: var(--cs-color-surface-raised); color: var(--cs-color-text-muted); border: 1px solid var(--cs-color-border-default); z-index: 1; }
20
+ .cs-step--done .cs-step__marker { background: var(--cs-color-brand-umber); color: #fff; /* on-brand-umber ink */ border-color: transparent; }
21
21
  .cs-step--done:not(:last-child)::after { background: var(--cs-color-brand-umber); }
22
22
  .cs-step--active .cs-step__marker { background: var(--cs-color-brand-ochre); color: var(--cs-color-brand-umber); border-color: transparent; box-shadow: 0 0 0 4px color-mix(in oklab, var(--cs-color-brand-ochre) 28%, transparent); }
23
23
  .cs-step__title { font-weight: 700; font-size: var(--cs-font-size-sm); }
@@ -25,7 +25,7 @@
25
25
 
26
26
  /* Popover */
27
27
  .cs-popover { position: relative; display: inline-block; }
28
- .cs-popover__panel { position: absolute; inset-block-start: calc(100% + 8px); inset-inline-start: 0; min-inline-size: 240px; background: var(--cs-color-surface-panel); border: 1px solid var(--cs-color-border-default); border-radius: var(--cs-radius-md); box-shadow: var(--cs-shadow-md); padding: 14px; z-index: var(--cs-depth-toast); }
28
+ .cs-popover__panel { position: absolute; inset-block-start: calc(100% + 8px); inset-inline-start: 0; min-inline-size: 240px; background: var(--cs-color-surface-panel); border: 1px solid var(--cs-color-border-default); border-radius: var(--cs-radius-md); box-shadow: var(--cs-shadow-md); padding: 14px; z-index: var(--cs-depth-dropdown, 60); }
29
29
  .cs-popover__panel--end { inset-inline-start: auto; inset-inline-end: 0; }
30
30
 
31
31
  /* Drawer */
@@ -48,8 +48,20 @@
48
48
  .cs-cmdk__search { display: flex; align-items: center; gap: 10px; padding: 14px 18px; border-block-end: 1px solid var(--cs-color-border-default); }
49
49
  .cs-cmdk__search svg { color: var(--cs-color-text-muted); }
50
50
  .cs-cmdk__search input { flex: 1; border: 0; outline: 0; background: transparent; font: inherit; font-family: var(--cs-font-family-ui); font-size: var(--cs-font-size-md); color: var(--cs-color-text-primary); }
51
+ /* Wrapper ring — search input clears outline; focus-within restores ≥3:1 indicator (FIND-038). */
52
+ .cs-cmdk__search:focus-within {
53
+ outline: 2px solid var(--cs-color-text-primary);
54
+ outline-offset: -2px;
55
+ box-shadow: inset 0 0 0 2px var(--cs-color-accent-ochre);
56
+ }
51
57
  .cs-cmdk__list { max-block-size: 340px; overflow: auto; padding: 8px; display: grid; gap: 2px; }
52
58
  .cs-cmdk__label { font-size: var(--cs-font-size-xs); text-transform: uppercase; letter-spacing: var(--cs-letter-spacing-caps); color: var(--cs-color-text-muted); padding: 8px 10px 2px; }
53
59
  .cs-cmdk__item { display: flex; align-items: center; gap: 11px; inline-size: 100%; text-align: start; border: 0; background: transparent; font: inherit; font-family: var(--cs-font-family-ui); font-size: var(--cs-font-size-sm); color: var(--cs-color-text-primary); padding: 10px 12px; border-radius: var(--cs-radius-md); cursor: pointer; }
54
60
  .cs-cmdk__item:hover, .cs-cmdk__item[aria-selected="true"] { background: var(--cs-color-surface-raised); }
55
61
  .cs-cmdk__item .cs-kbd { margin-inline-start: auto; }
62
+
63
+ /* ---- system-theme dark parity (UX-010 / CDS-THEME-001) ---- */
64
+ @media (prefers-color-scheme: dark) {
65
+ [data-theme="system"] .cs-nav-item.is-active { color: var(--cs-color-brand-ochre); }
66
+ [data-theme="system"] .cs-nav-item.is-active .cs-nav-item__icon { color: var(--cs-color-brand-ochre); }
67
+ }
@@ -31,7 +31,19 @@ export function makeT(component, lang) { return (key) => tr(component, key, lang
31
31
  export function useLang(propLang) {
32
32
  const ref = React.useRef(null);
33
33
  const [lang, setLang] = React.useState(() => resolveLang(propLang, null));
34
- React.useLayoutEffect(() => { setLang(resolveLang(propLang, ref.current)); }, [propLang]);
34
+ React.useLayoutEffect(() => {
35
+ const el = ref.current;
36
+ setLang(resolveLang(propLang, el));
37
+ if (!el || propLang) return undefined;
38
+ // Re-resolve when an ancestor [lang] changes (template Language axis / __dcSetProps).
39
+ const obs = new MutationObserver(() => setLang(resolveLang(propLang, el)));
40
+ let node = el.parentElement;
41
+ while (node) {
42
+ obs.observe(node, { attributes: true, attributeFilter: ["lang"] });
43
+ node = node.parentElement;
44
+ }
45
+ return () => obs.disconnect();
46
+ }, [propLang]);
35
47
  return [ref, lang];
36
48
  }
37
49
 
@@ -49,8 +61,33 @@ export function formatDate(d, lang) {
49
61
  }
50
62
  export function monthName(i, lang) { return lang === "vi" ? VI_MONTHS[i] : new Date(2000, i, 1).toLocaleDateString("en-US", { month: "long" }); }
51
63
  export function formatNumber(n, lang) { if (n == null || isNaN(n)) return ""; return new Intl.NumberFormat(lang === "vi" ? "vi-VN" : "en-US").format(n); }
52
- /** VN currency = "1.234.567 ₫"; EN = "$1,234,567". */
53
- export function formatCurrency(n, lang) {
64
+
65
+ /**
66
+ * Format a money amount. Currency is independent of display language when options are used.
67
+ *
68
+ * Call shapes (FIND-025):
69
+ * - Legacy: `formatCurrency(amount, "en"|"vi")` — preserves prior presentation
70
+ * (EN→USD-style `$1,234,567`; VI→`1.234.567 ₫`).
71
+ * - Preferred: `formatCurrency(amount, { currency, locale?, lang? })` —
72
+ * `Intl.NumberFormat(locale, { style: "currency", currency })`.
73
+ * `locale` defaults from `lang` (`vi`→`vi-VN`, else `en-US`).
74
+ */
75
+ export function formatCurrency(n, langOrOpts) {
54
76
  if (n == null || isNaN(n)) return "";
55
- return lang === "vi" ? new Intl.NumberFormat("vi-VN").format(n) + "\u00a0₫" : "$" + new Intl.NumberFormat("en-US").format(n);
77
+ const opts = langOrOpts && typeof langOrOpts === "object" ? langOrOpts : null;
78
+ if (opts && opts.currency) {
79
+ let locale = opts.locale;
80
+ if (!locale) {
81
+ locale = opts.lang === "vi" ? "vi-VN" : "en-US";
82
+ }
83
+ return new Intl.NumberFormat(locale, {
84
+ style: "currency",
85
+ currency: String(opts.currency).toUpperCase(),
86
+ currencyDisplay: "symbol",
87
+ }).format(Number(n));
88
+ }
89
+ const lang = typeof langOrOpts === "string" ? langOrOpts : (opts && opts.lang) || "en";
90
+ return lang === "vi"
91
+ ? new Intl.NumberFormat("vi-VN").format(n) + "\u00a0₫"
92
+ : "$" + new Intl.NumberFormat("en-US").format(n);
56
93
  }
@@ -1,4 +1,4 @@
1
- /* CyberSkill — central bilingual string registry (v3 Batch 0/1).
1
+ /* CyberSkill — central bilingual string registry (v3 Batch 0/1/2).
2
2
  * Every component with BUILT-IN UI text (text the consumer does NOT pass as a prop)
3
3
  * registers its strings here, EN + VI. _audit/bilingual-parity.html enforces:
4
4
  * • each component has both `en` and `vi`
@@ -17,8 +17,8 @@ export const strings = {
17
17
  vi: { label: "Đường dẫn" },
18
18
  },
19
19
  CommandPalette: {
20
- en: { placeholder: "Type a command or search…", empty: "No results found", aria: "Command palette", esc: "Esc" },
21
- vi: { placeholder: "Nhập lệnh hoặc tìm kiếm…", empty: "Không tìm thấy kết quả", aria: "Bảng lệnh", esc: "Esc" },
20
+ en: { placeholder: "Type a command or search…", empty: "No results", aria: "Command palette", esc: "Esc" },
21
+ vi: { placeholder: "Nhập lệnh hoặc tìm kiếm…", empty: "Không có kết quả", aria: "Bảng lệnh", esc: "Esc" },
22
22
  },
23
23
  SearchField: {
24
24
  en: { placeholder: "Search…", clear: "Clear search" },
@@ -41,12 +41,22 @@ export const strings = {
41
41
  vi: { confirm: "Xác nhận", cancel: "Hủy" },
42
42
  },
43
43
  Drawer: {
44
- en: { close: "Close", panel: "Panel" },
45
- vi: { close: "Đóng", panel: "Bảng" },
44
+ en: { close: "Close", panel: "Side panel" },
45
+ vi: { close: "Đóng", panel: "Bảng bên" },
46
46
  },
47
47
  DataTable: {
48
- en: { empty: "No records" },
49
- vi: { empty: "Không có bản ghi" },
48
+ en: {
49
+ empty: "No results",
50
+ loading: "Loading table",
51
+ error: "We couldn't load this table",
52
+ errorHint: "Check your connection, then try again.",
53
+ },
54
+ vi: {
55
+ empty: "Không có kết quả",
56
+ loading: "Đang tải bảng",
57
+ error: "Không tải được bảng này",
58
+ errorHint: "Kiểm tra kết nối, rồi thử lại.",
59
+ },
50
60
  },
51
61
  ConfidenceMeter: {
52
62
  en: { label: "Confidence", low: "Low", medium: "Medium", high: "High" },
@@ -58,10 +68,10 @@ export const strings = {
58
68
  },
59
69
  Tag: {
60
70
  en: { remove: "Remove" },
61
- vi: { remove: "Gỡ bỏ" },
71
+ vi: { remove: "Gỡ" },
62
72
  },
63
73
  Toast: {
64
- en: { notifications: "Notifications", dismiss: "Dismiss" },
74
+ en: { notifications: "Notifications", dismiss: "Close" },
65
75
  vi: { notifications: "Thông báo", dismiss: "Đóng" },
66
76
  },
67
77
  TypingIndicator: {
@@ -73,12 +83,12 @@ export const strings = {
73
83
  vi: { toolbar: "Định dạng", bold: "Đậm", italic: "Nghiêng", list: "Danh sách", area: "Văn bản" },
74
84
  },
75
85
  Terminal: {
76
- en: { input: "Terminal input" },
77
- vi: { input: "Ô nhập lệnh" },
86
+ en: { input: "Terminal input", title: "cyberskill — zsh" },
87
+ vi: { input: "Ô nhập lệnh", title: "cyberskill — zsh" },
78
88
  },
79
89
  DataGrid: {
80
- en: { empty: "No records", selectAll: "Select all rows", selectRow: "Select row" },
81
- vi: { empty: "Không có bản ghi", selectAll: "Chọn tất cả", selectRow: "Chọn dòng" },
90
+ en: { empty: "No results", selectAll: "Select all rows", selectRow: "Select row", pin: "Pin this column", pinNamed: "Pin column {name}" },
91
+ vi: { empty: "Không có kết quả", selectAll: "Chọn tất cả", selectRow: "Chọn dòng", pin: "Ghim cột này", pinNamed: "Ghim cột {name}" },
82
92
  },
83
93
  Splitter: {
84
94
  en: { label: "Resize panes" },
@@ -112,9 +122,13 @@ export const strings = {
112
122
  en: { placeholder: "Add a note — @ to mention" },
113
123
  vi: { placeholder: "Thêm ghi chú — gõ @ để nhắc tên" },
114
124
  },
125
+ Sortable: {
126
+ en: { moveUp: "Move up", moveDown: "Move down" },
127
+ vi: { moveUp: "Di chuyển lên", moveDown: "Di chuyển xuống" },
128
+ },
115
129
  Form: {
116
- en: { summary: "Please fix the following:", required: "required", requiredField: "This field is required" },
117
- vi: { summary: "Vui lòng sửa các mục sau:", required: "bắt buộc", requiredField: "Trường này là bắt buộc" },
130
+ en: { summary: "Please fix the following:", required: "required", requiredField: "Enter a value" },
131
+ vi: { summary: "Vui lòng sửa các mục sau:", required: "bắt buộc", requiredField: "Vui lòng nhập giá trị" },
118
132
  },
119
133
  BackTop: {
120
134
  en: { label: "Back to top" },
@@ -122,7 +136,7 @@ export const strings = {
122
136
  },
123
137
  Carousel: {
124
138
  en: { prev: "Previous slide", next: "Next slide", slide: "Slide" },
125
- vi: { prev: "Trang trước", next: "Trang sau", slide: "Trang" },
139
+ vi: { prev: "Ảnh trước", next: "Ảnh sau", slide: "Ảnh" },
126
140
  },
127
141
  Comment: {
128
142
  en: { reply: "Reply" },
@@ -137,12 +151,12 @@ export const strings = {
137
151
  vi: { more: "Thao tác khác" },
138
152
  },
139
153
  Popconfirm: {
140
- en: { ok: "OK", cancel: "Cancel" },
141
- vi: { ok: "Đồng ý", cancel: "Hủy" },
154
+ en: { ok: "Confirm", cancel: "Cancel" },
155
+ vi: { ok: "Xác nhận", cancel: "Hủy" },
142
156
  },
143
157
  Result: {
144
- en: { success: "Done", error: "Something went wrong", warning: "Please check", info: "For your information" },
145
- vi: { success: "Hoàn tất", error: "Đã có lỗi xảy ra", warning: "Vui lòng kiểm tra", info: "Thông tin" },
158
+ en: { success: "Done", error: "We couldn't complete that", warning: "Please check", info: "Here's what happened" },
159
+ vi: { success: "Hoàn tất", error: "Chúng tôi chưa hoàn tất được", warning: "Vui lòng kiểm tra", info: "Đây là điều đã xảy ra" },
146
160
  },
147
161
  InlineEdit: {
148
162
  en: { edit: "Edit", empty: "Add text" },
@@ -161,8 +175,8 @@ export const strings = {
161
175
  vi: { label: "Giờ" },
162
176
  },
163
177
  Combobox: {
164
- en: { placeholder: "Select or type…", empty: "No matches" },
165
- vi: { placeholder: "Chọn hoặc nhập…", empty: "Không có kết quả phù hợp" },
178
+ en: { placeholder: "Select or type…", empty: "No results" },
179
+ vi: { placeholder: "Chọn hoặc nhập…", empty: "Không có kết quả" },
166
180
  },
167
181
  InputGroup: {
168
182
  en: { clear: "Clear", show: "Show password", hide: "Hide password", input: "Input" },
@@ -188,4 +202,57 @@ export const strings = {
188
202
  en: { aria: "Human review gate", risk: "review required", approve: "Approve", reject: "Reject", reviewer: "Reviewer" },
189
203
  vi: { aria: "Cổng kiểm duyệt của con người", risk: "cần xem xét", approve: "Phê duyệt", reject: "Từ chối", reviewer: "Người duyệt" },
190
204
  },
205
+
206
+ Switch: {
207
+ en: { on: "On", off: "Off" },
208
+ vi: { on: "Bật", off: "Tắt" },
209
+ },
210
+ Tabs: {
211
+ en: { list: "Tabs" },
212
+ vi: { list: "Tab" },
213
+ },
214
+ EmptyState: {
215
+ en: { title: "Nothing here yet", action: "Create your first item" },
216
+ vi: { title: "Chưa có gì ở đây", action: "Tạo mục đầu tiên" },
217
+ },
218
+ Alert: {
219
+ en: { dismiss: "Close" },
220
+ vi: { dismiss: "Đóng" },
221
+ },
222
+ Select: {
223
+ en: { placeholder: "Select…" },
224
+ vi: { placeholder: "Chọn…" },
225
+ },
226
+ Slider: {
227
+ en: { label: "Slider" },
228
+ vi: { label: "Thanh trượt" },
229
+ },
230
+ Steps: {
231
+ en: { label: "Steps" },
232
+ vi: { label: "Các bước" },
233
+ },
234
+ Toggle: {
235
+ en: { pressed: "Pressed", unpressed: "Not pressed" },
236
+ vi: { pressed: "Đang bật", unpressed: "Chưa bật" },
237
+ },
238
+ Menu: {
239
+ en: { menu: "Menu" },
240
+ vi: { menu: "Trình đơn" },
241
+ },
242
+ ContextMenu: {
243
+ en: { menu: "Context menu" },
244
+ vi: { menu: "Trình đơn ngữ cảnh" },
245
+ },
246
+ Tooltip: {
247
+ en: { label: "Tooltip" },
248
+ vi: { label: "Chú thích" },
249
+ },
250
+ ProgressBar: {
251
+ en: { label: "Progress" },
252
+ vi: { label: "Tiến độ" },
253
+ },
254
+ ChatMessage: {
255
+ en: { you: "You" },
256
+ vi: { you: "Bạn" },
257
+ },
191
258
  };
@@ -11,6 +11,8 @@ export interface ChatMessageProps {
11
11
  name?: ReactNode;
12
12
  avatar?: ReactNode;
13
13
  children?: ReactNode;
14
+ /** "en" | "vi" — else resolved from the nearest [lang] ancestor (vi default). */
15
+ lang?: string;
14
16
  className?: string;
15
17
  }
16
18
 
@@ -1,20 +1,24 @@
1
1
  import React from "react";
2
+ import { makeT, useLang } from "../_i18n/i18n.js";
2
3
  import { cx } from "../_utils/cx.js";
3
4
 
4
5
  /**
5
6
  * CyberSkill ChatMessage — one turn in a Lumi conversation. role "lumi" (genie,
6
7
  * Ochre avatar) or "user" (Umber, right-aligned). Pass `avatar` to override.
7
8
  */
8
- export function ChatMessage({ role = "lumi", name, avatar, children, className }) {
9
+ export function ChatMessage({ role = "lumi", name, avatar, lang, className, children }) {
9
10
  const isUser = role === "user";
11
+ const [ref, L] = useLang(lang);
12
+ const t = makeT("ChatMessage", L);
13
+ const you = t("you");
10
14
  const defaultAvatar = isUser
11
- ? <span aria-hidden="true">You</span>
15
+ ? <span aria-hidden="true">{you}</span>
12
16
  : <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.9" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true"><path d="M12 3l1.8 5.4L19 10l-5.2 1.6L12 17l-1.8-5.4L5 10l5.2-1.6z" /></svg>;
13
17
  return (
14
- <div className={cx("cs-chat-msg", isUser ? "cs-chat-msg--user" : "cs-chat-msg--lumi", className)}>
18
+ <div ref={ref} className={cx("cs-chat-msg", isUser ? "cs-chat-msg--user" : "cs-chat-msg--lumi", className)}>
15
19
  <div className="cs-chat-msg__avatar">{avatar ?? defaultAvatar}</div>
16
20
  <div className="cs-chat-msg__col">
17
- <div className="cs-chat-msg__name">{name ?? (isUser ? "You" : "Lumi")}</div>
21
+ <div className="cs-chat-msg__name">{name ?? (isUser ? you : "Lumi")}</div>
18
22
  <div className="cs-chat-msg__bubble">{children}</div>
19
23
  </div>
20
24
  </div>
@@ -11,6 +11,8 @@ export interface ConfidenceMeterProps {
11
11
  level?: "low" | "medium" | "high";
12
12
  segments?: number;
13
13
  label?: ReactNode;
14
+ /** "en" | "vi" — else resolved from the nearest [lang] ancestor (vi default). */
15
+ lang?: string;
14
16
  className?: string;
15
17
  }
16
18