@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
@@ -139,6 +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" }}>{lang === "vi" ? "Bỏ qua đến nội dung" : "Skip to content"}</a>
142
143
  <header className="hd">
143
144
  <div className="hd-in">
144
145
  <div className="hd-id">
@@ -156,7 +157,7 @@ function StatusHub() {
156
157
  </div>
157
158
  </header>
158
159
 
159
- <div className="wrap">
160
+ <main id="main" className="wrap">
160
161
  <div className="deck">
161
162
  <section className="panel">
162
163
  <h2>{t.portfolio}</h2>
@@ -195,9 +196,34 @@ function StatusHub() {
195
196
  <div className="bar">
196
197
  <div className="bar-top">
197
198
  <label className="srch"><SearchGlyph /><input placeholder={t.search} value={q} onChange={(e) => setQ(e.target.value)} /></label>
198
- <div className="lenses" role="tablist" aria-label={t.view}>
199
+ <div
200
+ className="lenses"
201
+ role="tablist"
202
+ aria-label={t.view}
203
+ onKeyDown={(e) => {
204
+ const order = ["board", "table", "releases"];
205
+ const i = order.indexOf(lens);
206
+ let next = i;
207
+ if (e.key === "ArrowRight") next = (i + 1) % order.length;
208
+ else if (e.key === "ArrowLeft") next = (i - 1 + order.length) % order.length;
209
+ else if (e.key === "Home") next = 0;
210
+ else if (e.key === "End") next = order.length - 1;
211
+ else return;
212
+ e.preventDefault();
213
+ setLens(order[next]);
214
+ const tabs = e.currentTarget.querySelectorAll('[role="tab"]');
215
+ tabs[next] && tabs[next].focus && tabs[next].focus();
216
+ }}
217
+ >
199
218
  {["board", "table", "releases"].map((l) => (
200
- <button key={l} className="ln" role="tab" aria-selected={lens === l} onClick={() => setLens(l)}>{t.lenses[l]}</button>
219
+ <button
220
+ key={l}
221
+ className="ln"
222
+ role="tab"
223
+ aria-selected={lens === l}
224
+ tabIndex={lens === l ? 0 : -1}
225
+ onClick={() => setLens(l)}
226
+ >{t.lenses[l]}</button>
201
227
  ))}
202
228
  </div>
203
229
  <label className="facet">{t.status}
@@ -260,7 +286,7 @@ function StatusHub() {
260
286
  <p className="ft">{lang === "vi"
261
287
  ? <>CyberSkill Status Hub — bản tái hiện UI kit của design system. Dựng trên token <span className="mono">styles.css</span>. Turn Your Will Into Real.</>
262
288
  : <>CyberSkill Status Hub — a design-system UI kit recreation. Built on <span className="mono">styles.css</span> tokens. Turn Your Will Into Real.</>}</p>
263
- </div>
289
+ </main>
264
290
 
265
291
  <Drawer p={sel && loc(sel)} onClose={() => setSel(null)} t={t} />
266
292
  </div>
@@ -9,9 +9,9 @@
9
9
  <link rel="stylesheet" href="../../styles.css" />
10
10
  <link rel="stylesheet" href="status.css" />
11
11
  <style>html,body{margin:0;background:var(--cs-color-surface-page);min-height:100vh}</style>
12
- <script src="https://unpkg.com/umd-react@19.2.8/dist/react.development.js" integrity="sha384-r22tQd8qRIHDPIkmdXZcVtvPi1Tj2x1QaW2tmFQHEvHscATUnHQ5siTyxWw5PMUs" crossorigin="anonymous"></script>
13
- <script src="https://unpkg.com/umd-react@19.2.8/dist/react-dom.development.js" integrity="sha384-gJZYmumEmwqVmX3JVsLZq+4QrxoPGh/BW47Rk7SqNPCPFpTGnRtvmeRPJ7//ZDPk" crossorigin="anonymous"></script>
14
- <script src="https://unpkg.com/@babel/standalone@7.29.0/babel.min.js" integrity="sha384-m08KidiNqLdpJqLq95G/LEi8Qvjl/xUYll3QILypMoQ65QorJ9Lvtp2RXYGBFj1y" crossorigin="anonymous"></script>
12
+ <script src="../../_vendor/react/react.production.min.js"></script>
13
+ <script src="../../_vendor/react/react-dom.production.min.js"></script>
14
+ <script src="../../_vendor/babel/babel.min.js"></script>
15
15
  <script src="data.js"></script>
16
16
  </head>
17
17
  <body>
@@ -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,34 +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>
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>
37
+ <main id="main">
38
+
32
39
  <div class="login">
33
40
  <div class="pane-brand">
34
41
  <div class="brand-lock"><img src="../../assets/logo-mark.svg" alt="" />CyberSkill</div>
35
- <h2>Turn Your Will Into Real</h2>
42
+ <p class="brand-headline">Turn Your Will Into Real</p>
36
43
  <p>Sign in to the Status Hub — one page, three lenses across every wish in flight.</p>
37
44
  </div>
38
45
  <div class="pane-form">
39
46
  <div class="box">
40
47
  <h1>Sign in</h1>
41
48
  <p class="sub">Welcome back. Đăng nhập để tiếp tục.</p>
42
- <form onsubmit="return false">
43
- <label class="cs-field"><span class="cs-field__label">Work email</span><input class="cs-field__control" type="email" placeholder="you@cyberskill.world" /></label>
44
- <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>
45
59
  <div class="rowbetween">
46
- <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>
47
61
  <a href="#">Forgot password?</a>
48
62
  </div>
49
- <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>
50
64
  <button type="button" class="cs-button cs-button--ghost cs-button--full">✦ Talk to Lumi instead</button>
51
65
  </form>
52
66
  <p class="fine">New here? <a href="#">Ask for access</a></p>
53
67
  </div>
54
68
  </div>
55
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>
56
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>
57
81
  <script>
58
82
  document.getElementById("themeToggle").addEventListener("click", function () {
@@ -60,6 +84,28 @@
60
84
  el.setAttribute("data-theme", dark ? "light" : "dark");
61
85
  this.textContent = dark ? "☾" : "☀";
62
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);
63
108
  </script>
109
+ </main>
64
110
  </body>
65
111
  </html>
@@ -36,6 +36,9 @@
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">Bỏ qua đến nội dung</a>
40
+ <main id="main">
41
+
39
42
  <div class="sh">
40
43
  <header class="hd">
41
44
  <div class="hd-in">
@@ -133,5 +136,6 @@
133
136
  this.textContent = dark ? "☾" : "☀";
134
137
  });
135
138
  </script>
139
+ </main>
136
140
  </body>
137
141
  </html>
@@ -22,9 +22,12 @@
22
22
  .danger .t { font-weight: 700; }
23
23
  .actions { display: flex; gap: 10px; justify-content: flex-end; }
24
24
  @media (max-width: 700px) { .field-row { grid-template-columns: 1fr; } }
25
+ .cs-skip{position:absolute;left:-999px;top:auto;width:1px;height:1px;overflow:hidden}
26
+ .cs-skip:focus{position:fixed;left:12px;top:12px;z-index:9999;width:auto;height:auto;padding:10px 14px;background:var(--cs-color-surface-panel);color:var(--cs-color-text-primary);border:2px solid var(--cs-color-brand-ochre);border-radius:8px;overflow:visible}
25
27
  </style>
26
28
  </head>
27
29
  <body>
30
+ <a class="cs-skip" href="#main">Bỏ qua đến nội dung</a>
28
31
  <div class="sh">
29
32
  <header class="hd">
30
33
  <div class="hd-in">
@@ -36,15 +39,15 @@
36
39
  </div>
37
40
  </header>
38
41
 
39
- <div class="wrap">
40
- <nav class="cs-tabs" style="margin-top:24px" aria-label="Settings sections">
41
- <button class="cs-tab" aria-selected="true">Profile</button>
42
- <button class="cs-tab">Notifications</button>
43
- <button class="cs-tab">Appearance</button>
44
- <button class="cs-tab">Team <span class="cs-tab__count">6</span></button>
45
- </nav>
42
+ <main id="main" class="wrap">
43
+ <div class="cs-tabs" style="margin-top:24px;overflow-x:auto" role="tablist" aria-label="Settings sections">
44
+ <button type="button" class="cs-tab" role="tab" aria-selected="true" tabindex="0" id="tab-profile" aria-controls="panel-settings">Profile</button>
45
+ <button type="button" class="cs-tab" role="tab" aria-selected="false" tabindex="-1" id="tab-notifications" aria-controls="panel-settings">Notifications</button>
46
+ <button type="button" class="cs-tab" role="tab" aria-selected="false" tabindex="-1" id="tab-appearance" aria-controls="panel-settings">Appearance</button>
47
+ <button type="button" class="cs-tab" role="tab" aria-selected="false" tabindex="-1" id="tab-team" aria-controls="panel-settings">Team <span class="cs-tab__count">6</span></button>
48
+ </div>
46
49
 
47
- <div class="set-grid">
50
+ <div class="set-grid" id="panel-settings" role="tabpanel" aria-labelledby="tab-profile">
48
51
  <section class="panel">
49
52
  <h3 class="sec">Profile</h3>
50
53
  <p class="hint">This is how you appear across the Status Hub.</p>
@@ -60,10 +63,10 @@
60
63
  <h3 class="sec">Notifications</h3>
61
64
  <p class="hint">We keep it quiet — only what you ask for.</p>
62
65
  <div class="cs-scroll-area" style="max-block-size:220px;padding-inline-end:6px" tabindex="0" aria-label="Notification preferences">
63
- <div class="toggle-row"><div><div class="t">Release notes</div><div class="d">A summary each time a project ships. Bilingual (EN + VN).</div></div><label class="cs-switch"><input type="checkbox" role="switch" checked /><span class="cs-switch__track"></span></label></div>
64
- <div class="toggle-row"><div><div class="t">Blocked-project alerts</div><div class="d">Get pinged when a project moves to Blocked.</div></div><label class="cs-switch"><input type="checkbox" role="switch" checked /><span class="cs-switch__track"></span></label></div>
65
- <div class="toggle-row"><div><div class="t">Weekly velocity digest</div><div class="d">Tasks shipped per week, every Monday morning.</div></div><label class="cs-switch"><input type="checkbox" role="switch" /><span class="cs-switch__track"></span></label></div>
66
- <div class="toggle-row"><div><div class="t">Quiet hours</div><div class="d">No pings between 22:00 and 07:00 local time.</div></div><label class="cs-switch"><input type="checkbox" role="switch" checked /><span class="cs-switch__track"></span></label></div>
66
+ <div class="toggle-row"><div><div class="t" id="lbl-release">Release notes</div><div class="d">A summary each time a project ships. Bilingual (EN + VN).</div></div><label class="cs-switch"><input type="checkbox" role="switch" checked aria-labelledby="lbl-release" /><span class="cs-switch__track"></span></label></div>
67
+ <div class="toggle-row"><div><div class="t" id="lbl-blocked">Blocked-project alerts</div><div class="d">Get pinged when a project moves to Blocked.</div></div><label class="cs-switch"><input type="checkbox" role="switch" checked aria-labelledby="lbl-blocked" /><span class="cs-switch__track"></span></label></div>
68
+ <div class="toggle-row"><div><div class="t" id="lbl-digest">Weekly velocity digest</div><div class="d">Tasks shipped per week, every Monday morning.</div></div><label class="cs-switch"><input type="checkbox" role="switch" aria-labelledby="lbl-digest" /><span class="cs-switch__track"></span></label></div>
69
+ <div class="toggle-row"><div><div class="t" id="lbl-quiet">Quiet hours</div><div class="d">No pings between 22:00 and 07:00 local time.</div></div><label class="cs-switch"><input type="checkbox" role="switch" checked aria-labelledby="lbl-quiet" /><span class="cs-switch__track"></span></label></div>
67
70
  </div>
68
71
  </section>
69
72
 
@@ -77,7 +80,7 @@
77
80
  <button class="cs-button cs-button--primary">Save changes</button>
78
81
  </div>
79
82
  </div>
80
- </div>
83
+ </main>
81
84
  </div>
82
85
  <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>
83
86
  <script>
@@ -86,6 +89,25 @@
86
89
  el.setAttribute("data-theme", dark ? "light" : "dark");
87
90
  this.textContent = dark ? "☾" : "☀";
88
91
  });
92
+
93
+ (function(){
94
+ var tabs=[].slice.call(document.querySelectorAll('[role="tablist"] [role="tab"]'));
95
+ tabs.forEach(function(tab,i){
96
+ tab.addEventListener('click',function(){
97
+ tabs.forEach(function(x,j){ x.setAttribute('aria-selected', j===i?'true':'false'); x.tabIndex=j===i?0:-1; });
98
+ });
99
+ tab.addEventListener('keydown',function(e){
100
+ var cur=tabs.indexOf(document.activeElement); if(cur<0) return;
101
+ var next=cur;
102
+ if(e.key==='ArrowRight') next=(cur+1)%tabs.length;
103
+ else if(e.key==='ArrowLeft') next=(cur-1+tabs.length)%tabs.length;
104
+ else if(e.key==='Home') next=0;
105
+ else if(e.key==='End') next=tabs.length-1;
106
+ else return;
107
+ e.preventDefault(); tabs[next].focus(); tabs[next].click();
108
+ });
109
+ });
110
+ })();
89
111
  </script>
90
112
  </body>
91
113
  </html>
@@ -129,7 +129,7 @@
129
129
  .chip.hold { background: var(--cs-color-semantic-danger); color: var(--cs-status-on-fill); border-color: transparent; }
130
130
 
131
131
  /* board */
132
- .grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(330px, 1fr)); gap: var(--cs-space-4); }
132
+ .grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr)); gap: var(--cs-space-4); }
133
133
  .card { background: var(--cs-color-surface-panel); border: 1px solid var(--cs-color-border-default);
134
134
  border-radius: 14px; padding: var(--cs-space-4); cursor: pointer; text-align: left; font: inherit; color: inherit; }
135
135
  .card:hover { border-color: var(--cs-color-brand-ochre); }
@@ -197,3 +197,7 @@ table.tbl { border-collapse: collapse; width: 100%; font-size: 13px; }
197
197
  .ft { margin: var(--cs-space-12) 0 var(--cs-space-16); text-align: center; font-size: 12px; color: var(--cs-color-text-muted); }
198
198
 
199
199
  @media (max-width: 900px) { .deck { grid-template-columns: 1fr; } .hd-meta { text-align: left; } }
200
+
201
+ /* UX-024 readable measure */
202
+ .panel p, .notes, .release-body, article p { max-inline-size: var(--cs-prose-measure, 45rem); }
203
+ .card, button.card { min-width: 0; }
@@ -53,12 +53,21 @@ function Website() {
53
53
  const [seed, setSeed] = useState("");
54
54
  const [wish, setWish] = useState("");
55
55
  const [sent, setSent] = useState(false);
56
+ const [fabVisible, setFabVisible] = useState(false);
56
57
  const t = window.SITE_COPY[loc];
57
58
 
58
59
  function openChat(s) { setSeed(s || ""); setChat(true); }
59
60
 
61
+ useEffect(() => {
62
+ const sync = () => setFabVisible(window.scrollY > 140);
63
+ sync();
64
+ window.addEventListener("scroll", sync, { passive: true });
65
+ return () => window.removeEventListener("scroll", sync);
66
+ }, []);
67
+
60
68
  return (
61
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" }}>{loc === "vi" ? "Bỏ qua đến nội dung" : "Skip to content"}</a>
62
71
  <header className="hdr cs-surface-light">
63
72
  <div className="container hdr-in">
64
73
  <a className="brand" href="#top"><img src="../../assets/logo-mark.svg" alt="" />CyberSkill</a>
@@ -66,10 +75,11 @@ function Website() {
66
75
  <div className="hdr-side">
67
76
  <button className="mini" onClick={() => setLoc(loc === "en" ? "vi" : "en")}>{t.langLabel}</button>
68
77
  <button className="mini icon" onClick={() => setDark(!dark)} aria-label="Toggle theme"><I name={dark ? "sun" : "moon"} size={18} /></button>
69
- <button className="mini" style={{ background: "var(--cs-color-brand-umber)", color: "#fff", borderColor: "transparent" }} onClick={() => openChat("")}>{t.talk}</button>
78
+ <button className="mini" style={{ background: "var(--cs-color-brand-umber)", color: "var(--cs-color-text-inverse,#fff)", borderColor: "transparent" }} onClick={() => openChat("")}>{t.talk}</button>
70
79
  </div>
71
80
  </div>
72
81
  </header>
82
+ <main id="main">
73
83
 
74
84
  <section className="hero" id="top">
75
85
  <div className="container hero-in">
@@ -81,7 +91,6 @@ function Website() {
81
91
  <div className="wish">
82
92
  <input value={wish} onChange={(e) => setWish(e.target.value)} onKeyDown={(e) => e.key === "Enter" && openChat(wish)} placeholder={t.wishPlaceholder} aria-label={t.wishPlaceholder} />
83
93
  <button className="btn-gold" onClick={() => openChat(wish)}><I name="sparkle" size={18} />{t.wishCta}</button>
84
- <button className="btn-ghost-light" onClick={() => openChat("")}>{t.talk}</button>
85
94
  </div>
86
95
  </div>
87
96
  <div className="hero-art"><img src="../../assets/lumi-poster.webp" alt="Lumi, the golden genie" /></div>
@@ -149,6 +158,7 @@ function Website() {
149
158
  )}
150
159
  </div>
151
160
  </section>
161
+ </main>
152
162
 
153
163
  <footer className="ft">
154
164
  <div className="container ft-in">
@@ -158,7 +168,19 @@ function Website() {
158
168
  </div>
159
169
  </footer>
160
170
 
161
- {!chat && <button className="fab" onClick={() => openChat("")}><img src="../../assets/lumi-poster.webp" alt="" />{t.talk}</button>}
171
+ {!chat && (
172
+ <button
173
+ className="fab"
174
+ type="button"
175
+ data-fab-deferred="1"
176
+ onClick={() => openChat("")}
177
+ style={{ opacity: fabVisible ? 1 : 0, pointerEvents: fabVisible ? "auto" : "none", transition: "opacity 160ms ease" }}
178
+ aria-hidden={!fabVisible}
179
+ tabIndex={fabVisible ? 0 : -1}
180
+ >
181
+ <img src="../../assets/lumi-poster.webp" alt="" />{t.talk}
182
+ </button>
183
+ )}
162
184
  {chat && <Chat t={t} seed={seed} onClose={() => setChat(false)} />}
163
185
  </div>
164
186
  );
@@ -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,6 +29,9 @@
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">Bỏ qua đến nội dung</a>
33
+ <main id="main">
34
+
32
35
  <div class="site">
33
36
  <header class="hdr cs-surface-light">
34
37
  <div class="container hdr-in">
@@ -105,5 +108,6 @@
105
108
  if(link) link.addEventListener("click", function(e){e.preventDefault(); apply(document.documentElement.getAttribute("lang")!=="vi");});
106
109
  })();
107
110
  </script>
111
+ </main>
108
112
  </body>
109
113
  </html>
@@ -30,12 +30,14 @@
30
30
  .lumi-answer-meta { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
31
31
  @media (max-width: 820px) { .lumi-page { grid-template-columns: 1fr; } .lumi-side { display: none; } }
32
32
  </style>
33
- <script src="https://unpkg.com/umd-react@19.2.8/dist/react.development.js" integrity="sha384-r22tQd8qRIHDPIkmdXZcVtvPi1Tj2x1QaW2tmFQHEvHscATUnHQ5siTyxWw5PMUs" crossorigin="anonymous"></script>
34
- <script src="https://unpkg.com/umd-react@19.2.8/dist/react-dom.development.js" integrity="sha384-gJZYmumEmwqVmX3JVsLZq+4QrxoPGh/BW47Rk7SqNPCPFpTGnRtvmeRPJ7//ZDPk" crossorigin="anonymous"></script>
35
- <script src="https://unpkg.com/@babel/standalone@7.29.0/babel.min.js" integrity="sha384-m08KidiNqLdpJqLq95G/LEi8Qvjl/xUYll3QILypMoQ65QorJ9Lvtp2RXYGBFj1y" crossorigin="anonymous"></script>
33
+ <script src="../../_vendor/react/react.production.min.js"></script>
34
+ <script src="../../_vendor/react/react-dom.production.min.js"></script>
35
+ <script src="../../_vendor/babel/babel.min.js"></script>
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">Bỏ qua đến nội dung</a>
40
+
39
41
  <div id="root"></div>
40
42
  <script type="text/babel">
41
43
  const CS = window[Object.keys(window).find(k=>/^CyberSkillDesignSystem_[0-9a-f]{6}$/.test(k))] || {};
@@ -9,9 +9,9 @@
9
9
  <link rel="stylesheet" href="../../styles.css" />
10
10
  <link rel="stylesheet" href="site.css" />
11
11
  <style>html,body{margin:0}</style>
12
- <script src="https://unpkg.com/umd-react@19.2.8/dist/react.development.js" integrity="sha384-r22tQd8qRIHDPIkmdXZcVtvPi1Tj2x1QaW2tmFQHEvHscATUnHQ5siTyxWw5PMUs" crossorigin="anonymous"></script>
13
- <script src="https://unpkg.com/umd-react@19.2.8/dist/react-dom.development.js" integrity="sha384-gJZYmumEmwqVmX3JVsLZq+4QrxoPGh/BW47Rk7SqNPCPFpTGnRtvmeRPJ7//ZDPk" crossorigin="anonymous"></script>
14
- <script src="https://unpkg.com/@babel/standalone@7.29.0/babel.min.js" integrity="sha384-m08KidiNqLdpJqLq95G/LEi8Qvjl/xUYll3QILypMoQ65QorJ9Lvtp2RXYGBFj1y" crossorigin="anonymous"></script>
12
+ <script src="../../_vendor/react/react.production.min.js"></script>
13
+ <script src="../../_vendor/react/react-dom.production.min.js"></script>
14
+ <script src="../../_vendor/babel/babel.min.js"></script>
15
15
  <script src="copy.js"></script>
16
16
  </head>
17
17
  <body>
@@ -23,13 +23,13 @@
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); }
30
30
  .hero h1 { font-size: clamp(40px, 6vw, 68px); font-weight: 800; letter-spacing: -.02em; line-height: 1.05; margin: 14px 0 6px; color: var(--cs-color-brand-ochre); }
31
31
  .hero .vn { font-size: 20px; font-weight: 600; opacity: .9; margin-bottom: 18px; }
32
- .hero .lead { font-size: 18px; line-height: 1.55; max-width: 620px; opacity: .95; }
32
+ .hero .lead { font-size: 18px; line-height: 1.55; max-width: min(620px, var(--cs-prose-measure, 45rem)); opacity: .95; }
33
33
  .wish { display: flex; gap: 10px; margin-top: 26px; max-width: 620px; flex-wrap: wrap; }
34
34
  .wish input { flex: 1 1 300px; min-height: 52px; border-radius: var(--cs-radius-full); border: 1px solid rgba(255,255,255,.28); background: rgba(255,255,255,.1); backdrop-filter: blur(8px); color: #fff; padding: 0 22px; font: 400 15px/1 var(--cs-font-family-ui); }
35
35
  .wish input::placeholder { color: rgba(255,255,255,.72); }
@@ -53,7 +53,7 @@
53
53
  .sec { padding: 88px 0; }
54
54
  .sec-alt { background: var(--cs-color-surface-raised); }
55
55
  .sec h2 { font-size: clamp(28px, 4vw, 40px); font-weight: 800; letter-spacing: -.02em; margin: 8px 0 10px; }
56
- .sec-lead { font-size: 17px; color: var(--cs-color-text-muted); max-width: 620px; margin: 0 0 40px; }
56
+ .sec-lead { font-size: 17px; color: var(--cs-color-text-muted); max-width: min(620px, var(--cs-prose-measure, 45rem)); margin: 0 0 40px; }
57
57
 
58
58
  /* services */
59
59
  .svc-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--cs-space-5); }
@@ -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,6 +35,9 @@
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">Bỏ qua đến nội dung</a>
39
+ <main id="main">
40
+
38
41
  <div class="site">
39
42
  <header class="hdr cs-surface-light">
40
43
  <div class="container hdr-in">
@@ -115,5 +118,6 @@
115
118
  if(link) link.addEventListener("click", function(e){e.preventDefault(); apply(document.documentElement.getAttribute("lang")!=="vi");});
116
119
  })();
117
120
  </script>
121
+ </main>
118
122
  </body>
119
123
  </html>
Binary file
Binary file
Binary file
Binary file
@@ -1,5 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
2
- <rect width="64" height="64" rx="14" fill="#45210E"/>
3
- <rect y="50" width="64" height="14" fill="#F4BA17"/>
4
- <text x="32" y="42" font-family="Georgia, 'Times New Roman', serif" font-size="34" font-weight="700" fill="#ffffff" text-anchor="middle">D</text>
5
- </svg>