@cyberskill/design 1.1.0 → 1.2.0

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 (358) hide show
  1. package/DESIGN.md +25 -3
  2. package/README.md +7 -7
  3. package/SKILL.md +4 -4
  4. package/VERSION +1 -1
  5. package/_ds_bundle.js +819 -416
  6. package/_ds_manifest.json +1 -1
  7. package/_esm/cs.mjs +18 -4
  8. package/_esm/react.d.ts +2 -0
  9. package/_esm/react.mjs +1 -0
  10. package/base/a11y.css +18 -0
  11. package/base/ai.css +2 -2
  12. package/base/collections.css +8 -3
  13. package/base/components.css +11 -2
  14. package/base/controls.css +61 -48
  15. package/base/data.css +3 -3
  16. package/base/feedback.css +5 -0
  17. package/base/forms.css +9 -3
  18. package/base/glass.css +6 -0
  19. package/base/navigation.css +8 -2
  20. package/base/reset.css +1 -1
  21. package/base/responsive.css +25 -0
  22. package/base/shell.css +7 -1
  23. package/components/_i18n/i18n.js +13 -1
  24. package/components/_i18n/strings.js +52 -3
  25. package/components/ai/ConfidenceMeter.jsx +8 -6
  26. package/components/data/Watermark.jsx +11 -3
  27. package/components/datatable/DataGrid.jsx +10 -1
  28. package/components/dialog/Dialog.jsx +13 -45
  29. package/components/feedback/ProgressBar.jsx +4 -2
  30. package/components/forms/Cascader.jsx +69 -6
  31. package/components/forms/Editor.jsx +37 -2
  32. package/components/forms/FileUpload.jsx +22 -8
  33. package/components/forms/Switch.jsx +16 -2
  34. package/components/forms/TimePicker.jsx +3 -1
  35. package/components/icon/Icon.jsx +1 -0
  36. package/components/navigation/CommandPalette.jsx +22 -7
  37. package/components/navigation/Toolbar.jsx +2 -1
  38. package/components/overlays/AlertDialog.jsx +19 -49
  39. package/components/overlays/Drawer.jsx +24 -20
  40. package/components/overlays/OverlayManager.d.ts +40 -0
  41. package/components/overlays/OverlayManager.jsx +214 -0
  42. package/components/overlays/OverlayManager.prompt.md +12 -0
  43. package/components/overlays/Tour.jsx +14 -7
  44. package/dist/styles.min.css +2004 -0
  45. package/docs/benchmark-rubric.md +1 -1
  46. package/docs/ci-cd.md +3 -1
  47. package/docs/consuming.md +6 -6
  48. package/docs/contrast-report.md +1 -1
  49. package/docs/conventions.md +4 -4
  50. package/docs/decisions/container-query-migration.md +18 -0
  51. package/docs/decisions/overlay-manager-design.md +101 -0
  52. package/docs/decisions.md +5 -5
  53. package/docs/design-styles.md +1 -1
  54. package/docs/plans/cyberskill-design-system-audit-and-12-month-evolution-plan.md +1490 -0
  55. package/docs/quality-gates.md +21 -9
  56. package/docs/release-notes.md +10 -2
  57. package/docs/status/data/status-feed.json +1 -1
  58. package/docs/status/data/task/TASK-REL-002.js +1 -0
  59. package/docs/status/index.html +7 -6
  60. package/docs/status/status-legacy.html +13 -12
  61. package/docs/sync.md +1 -1
  62. package/docs/tasks/BACKLOG.md +1 -0
  63. package/docs/tasks/_state/commit-links.yaml +14 -0
  64. package/docs/tasks/release/TASK-REL-002-republish-1-1-1/spec.md +54 -0
  65. package/docs/vi/benchmark-rubric.md +1 -1
  66. package/docs/vi/ci-cd.md +3 -1
  67. package/docs/vi/consuming.md +6 -6
  68. package/docs/vi/contrast-report.md +1 -1
  69. package/docs/vi/conventions.md +2 -2
  70. package/docs/vi/decisions.md +5 -5
  71. package/docs/vi/quality-gates.md +21 -9
  72. package/docs/vi/release-notes.md +10 -2
  73. package/docs/vi/sync.md +1 -1
  74. package/guidelines/atomic-view.html +11 -7
  75. package/llms.txt +5 -5
  76. package/package.json +14 -6
  77. package/templates/_ds-base.canonical.js +55 -0
  78. package/templates/ai-cluster-demo.html +2 -2
  79. package/templates/app-shell/AppShell.dc.html +5 -3
  80. package/templates/app-shell/ds-base.js +33 -1
  81. package/templates/app-shell/support.js +13 -20
  82. package/templates/article/Article.dc.html +5 -1
  83. package/templates/article/ds-base.js +33 -1
  84. package/templates/article/support.js +13 -20
  85. package/templates/auth/Auth.dc.html +10 -5
  86. package/templates/auth/content-schema.json +12 -0
  87. package/templates/auth/ds-base.js +33 -1
  88. package/templates/auth/support.js +13 -20
  89. package/templates/bod-deck/BodDeck.dc.html +11 -10
  90. package/templates/bod-deck/ds-base.js +33 -1
  91. package/templates/bod-deck/support.js +13 -20
  92. package/templates/bod-investor-update/BodInvestorUpdate.dc.html +4 -3
  93. package/templates/bod-investor-update/ds-base.js +33 -1
  94. package/templates/bod-investor-update/support.js +13 -20
  95. package/templates/bod-memo/BodMemo.dc.html +6 -5
  96. package/templates/bod-memo/ds-base.js +33 -1
  97. package/templates/bod-memo/support.js +13 -20
  98. package/templates/bod-minutes/BodMinutes.dc.html +2 -1
  99. package/templates/bod-minutes/ds-base.js +33 -1
  100. package/templates/bod-minutes/support.js +13 -20
  101. package/templates/bod-report/BodReport.dc.html +3 -2
  102. package/templates/bod-report/ds-base.js +33 -1
  103. package/templates/bod-report/support.js +13 -20
  104. package/templates/bod-resolution/BodResolution.dc.html +5 -4
  105. package/templates/bod-resolution/ds-base.js +33 -1
  106. package/templates/bod-resolution/support.js +13 -20
  107. package/templates/culture-event-invite/CultureEventInvite.dc.html +3 -2
  108. package/templates/culture-event-invite/ds-base.js +33 -1
  109. package/templates/culture-event-invite/support.js +13 -20
  110. package/templates/dashboard/Dashboard.dc.html +7 -3
  111. package/templates/dashboard/ds-base.js +33 -1
  112. package/templates/dashboard/support.js +13 -20
  113. package/templates/delivery-change-note/DeliveryChangeNote.dc.html +2 -1
  114. package/templates/delivery-change-note/ds-base.js +33 -1
  115. package/templates/delivery-change-note/support.js +13 -20
  116. package/templates/delivery-kickoff/DeliveryKickoff.dc.html +3 -2
  117. package/templates/delivery-kickoff/ds-base.js +33 -1
  118. package/templates/delivery-kickoff/support.js +13 -20
  119. package/templates/delivery-qbr-deck/DeliveryQbrDeck.dc.html +6 -5
  120. package/templates/delivery-qbr-deck/ds-base.js +33 -1
  121. package/templates/delivery-qbr-deck/support.js +13 -20
  122. package/templates/delivery-runbook/DeliveryRunbook.dc.html +3 -2
  123. package/templates/delivery-runbook/ds-base.js +33 -1
  124. package/templates/delivery-runbook/support.js +13 -20
  125. package/templates/delivery-status-email/DeliveryStatusEmail.dc.html +3 -2
  126. package/templates/delivery-status-email/ds-base.js +33 -1
  127. package/templates/delivery-status-email/support.js +13 -20
  128. package/templates/doc-style-guide/DocStyleGuide.dc.html +67 -64
  129. package/templates/doc-style-guide/ds-base.js +33 -1
  130. package/templates/doc-style-guide/support.js +13 -20
  131. package/templates/doc-suite-index/DocSuiteIndex.dc.html +46 -45
  132. package/templates/doc-suite-index/ds-base.js +33 -1
  133. package/templates/doc-suite-index/support.js +13 -20
  134. package/templates/doc-templates/DocTemplates.dc.html +42 -41
  135. package/templates/doc-templates/ds-base.js +33 -1
  136. package/templates/doc-templates/support.js +13 -20
  137. package/templates/email/Email.dc.html +3 -2
  138. package/templates/email/ds-base.js +33 -1
  139. package/templates/email/support.js +13 -20
  140. package/templates/finance-dunning-email/FinanceDunningEmail.dc.html +4 -3
  141. package/templates/finance-dunning-email/ds-base.js +33 -1
  142. package/templates/finance-dunning-email/support.js +13 -20
  143. package/templates/finance-expense-report/FinanceExpenseReport.dc.html +4 -3
  144. package/templates/finance-expense-report/ds-base.js +33 -1
  145. package/templates/finance-expense-report/support.js +13 -20
  146. package/templates/finance-invoice/FinanceInvoice.dc.html +4 -3
  147. package/templates/finance-invoice/ds-base.js +33 -1
  148. package/templates/finance-invoice/support.js +13 -20
  149. package/templates/finance-quote/FinanceQuote.dc.html +4 -3
  150. package/templates/finance-quote/ds-base.js +33 -1
  151. package/templates/finance-quote/support.js +13 -20
  152. package/templates/hr-announcement/HrAnnouncement.dc.html +5 -4
  153. package/templates/hr-announcement/ds-base.js +33 -1
  154. package/templates/hr-announcement/support.js +13 -20
  155. package/templates/hr-interview-kit/HrInterviewKit.dc.html +4 -3
  156. package/templates/hr-interview-kit/ds-base.js +33 -1
  157. package/templates/hr-interview-kit/support.js +13 -20
  158. package/templates/hr-offboarding/HrOffboarding.dc.html +2 -1
  159. package/templates/hr-offboarding/ds-base.js +33 -1
  160. package/templates/hr-offboarding/support.js +13 -20
  161. package/templates/hr-performance-review/HrPerformanceReview.dc.html +2 -1
  162. package/templates/hr-performance-review/ds-base.js +33 -1
  163. package/templates/hr-performance-review/support.js +13 -20
  164. package/templates/hr-pip/HrPip.dc.html +2 -1
  165. package/templates/hr-pip/ds-base.js +33 -1
  166. package/templates/hr-pip/support.js +13 -20
  167. package/templates/kitchen-sink.html +9 -4
  168. package/templates/legal-msa/LegalMsa.dc.html +2 -1
  169. package/templates/legal-msa/ds-base.js +33 -1
  170. package/templates/legal-msa/support.js +13 -20
  171. package/templates/legal-sow/LegalSow.dc.html +2 -1
  172. package/templates/legal-sow/ds-base.js +33 -1
  173. package/templates/legal-sow/support.js +13 -20
  174. package/templates/marketing-campaign-brief/MarketingCampaignBrief.dc.html +3 -2
  175. package/templates/marketing-campaign-brief/ds-base.js +33 -1
  176. package/templates/marketing-campaign-brief/support.js +13 -20
  177. package/templates/marketing-case-study/MarketingCaseStudy.dc.html +5 -4
  178. package/templates/marketing-case-study/ds-base.js +33 -1
  179. package/templates/marketing-case-study/support.js +13 -20
  180. package/templates/marketing-launch/MarketingLaunch.dc.html +6 -5
  181. package/templates/marketing-launch/ds-base.js +33 -1
  182. package/templates/marketing-launch/support.js +13 -20
  183. package/templates/marketing-newsletter/MarketingNewsletter.dc.html +13 -12
  184. package/templates/marketing-newsletter/ds-base.js +33 -1
  185. package/templates/marketing-newsletter/support.js +13 -20
  186. package/templates/marketing-page/MarketingPage.dc.html +17 -12
  187. package/templates/marketing-page/ds-base.js +33 -1
  188. package/templates/marketing-page/support.js +13 -20
  189. package/templates/marketing-press-release/MarketingPressRelease.dc.html +2 -1
  190. package/templates/marketing-press-release/ds-base.js +33 -1
  191. package/templates/marketing-press-release/support.js +13 -20
  192. package/templates/marketing-social-kit/MarketingSocialKit.dc.html +5 -4
  193. package/templates/marketing-social-kit/ds-base.js +33 -1
  194. package/templates/marketing-social-kit/support.js +13 -20
  195. package/templates/sales-one-pager/SalesOnePager.dc.html +5 -4
  196. package/templates/sales-one-pager/ds-base.js +33 -1
  197. package/templates/sales-one-pager/support.js +13 -20
  198. package/templates/sales-proposal-deck/SalesProposalDeck.dc.html +7 -6
  199. package/templates/sales-proposal-deck/ds-base.js +33 -1
  200. package/templates/sales-proposal-deck/support.js +13 -20
  201. package/templates/settings/Settings.dc.html +5 -1
  202. package/templates/settings/ds-base.js +33 -1
  203. package/templates/settings/support.js +13 -20
  204. package/templates/slide-deck/SlideDeck.dc.html +5 -4
  205. package/templates/slide-deck/ds-base.js +33 -1
  206. package/templates/slide-deck/support.js +13 -20
  207. package/templates/team-meeting-agenda/TeamMeetingAgenda.dc.html +2 -1
  208. package/templates/team-meeting-agenda/ds-base.js +33 -1
  209. package/templates/team-meeting-agenda/support.js +13 -20
  210. package/templates/tech-incident-report/TechIncidentReport.dc.html +3 -2
  211. package/templates/tech-incident-report/ds-base.js +33 -1
  212. package/templates/tech-incident-report/support.js +13 -20
  213. package/templates/tech-release-notes/TechReleaseNotes.dc.html +6 -5
  214. package/templates/tech-release-notes/ds-base.js +33 -1
  215. package/templates/tech-release-notes/support.js +13 -20
  216. package/templates/tech-retro/TechRetro.dc.html +4 -3
  217. package/templates/tech-retro/ds-base.js +33 -1
  218. package/templates/tech-retro/support.js +13 -20
  219. package/templates/tech-rfc/TechRfc.dc.html +3 -2
  220. package/templates/tech-rfc/ds-base.js +33 -1
  221. package/templates/tech-rfc/support.js +13 -20
  222. package/templates/vn-appointment-transfer/VnAppointmentTransfer.dc.html +36 -35
  223. package/templates/vn-appointment-transfer/ds-base.js +33 -1
  224. package/templates/vn-appointment-transfer/support.js +13 -20
  225. package/templates/vn-certificate-of-employment/VnCertificateOfEmployment.dc.html +27 -26
  226. package/templates/vn-certificate-of-employment/ds-base.js +33 -1
  227. package/templates/vn-certificate-of-employment/support.js +13 -20
  228. package/templates/vn-code-of-conduct/VnCodeOfConduct.dc.html +44 -43
  229. package/templates/vn-code-of-conduct/ds-base.js +33 -1
  230. package/templates/vn-code-of-conduct/support.js +13 -20
  231. package/templates/vn-compensation-regulation/VnCompensationRegulation.dc.html +53 -52
  232. package/templates/vn-compensation-regulation/ds-base.js +33 -1
  233. package/templates/vn-compensation-regulation/support.js +13 -20
  234. package/templates/vn-contract-amendment/VnContractAmendment.dc.html +41 -40
  235. package/templates/vn-contract-amendment/ds-base.js +33 -1
  236. package/templates/vn-contract-amendment/support.js +13 -20
  237. package/templates/vn-contractor-agreement/VnContractorAgreement.dc.html +50 -49
  238. package/templates/vn-contractor-agreement/ds-base.js +33 -1
  239. package/templates/vn-contractor-agreement/support.js +13 -20
  240. package/templates/vn-data-protection-policy/VnDataProtectionPolicy.dc.html +54 -53
  241. package/templates/vn-data-protection-policy/ds-base.js +33 -1
  242. package/templates/vn-data-protection-policy/support.js +13 -20
  243. package/templates/vn-disciplinary-case-file/VnDisciplinaryCaseFile.dc.html +72 -71
  244. package/templates/vn-disciplinary-case-file/ds-base.js +33 -1
  245. package/templates/vn-disciplinary-case-file/support.js +13 -20
  246. package/templates/vn-disciplinary-schedule/VnDisciplinarySchedule.dc.html +21 -20
  247. package/templates/vn-disciplinary-schedule/ds-base.js +33 -1
  248. package/templates/vn-disciplinary-schedule/support.js +13 -20
  249. package/templates/vn-employee-request/VnEmployeeRequest.dc.html +54 -53
  250. package/templates/vn-employee-request/ds-base.js +33 -1
  251. package/templates/vn-employee-request/support.js +13 -20
  252. package/templates/vn-exit-handover/VnExitHandover.dc.html +122 -121
  253. package/templates/vn-exit-handover/ds-base.js +33 -1
  254. package/templates/vn-exit-handover/support.js +13 -20
  255. package/templates/vn-foreign-employee-pack/VnForeignEmployeePack.dc.html +31 -30
  256. package/templates/vn-foreign-employee-pack/ds-base.js +33 -1
  257. package/templates/vn-foreign-employee-pack/support.js +13 -20
  258. package/templates/vn-grassroots-democracy/VnGrassrootsDemocracy.dc.html +54 -53
  259. package/templates/vn-grassroots-democracy/ds-base.js +33 -1
  260. package/templates/vn-grassroots-democracy/support.js +13 -20
  261. package/templates/vn-infosec-policy/VnInfosecPolicy.dc.html +50 -49
  262. package/templates/vn-infosec-policy/ds-base.js +33 -1
  263. package/templates/vn-infosec-policy/support.js +13 -20
  264. package/templates/vn-internal-labor-regulations/VnInternalLaborRegulations.dc.html +84 -83
  265. package/templates/vn-internal-labor-regulations/ds-base.js +33 -1
  266. package/templates/vn-internal-labor-regulations/support.js +13 -20
  267. package/templates/vn-internship-agreement/VnInternshipAgreement.dc.html +44 -43
  268. package/templates/vn-internship-agreement/ds-base.js +33 -1
  269. package/templates/vn-internship-agreement/support.js +13 -20
  270. package/templates/vn-job-description/VnJobDescription.dc.html +28 -27
  271. package/templates/vn-job-description/ds-base.js +33 -1
  272. package/templates/vn-job-description/support.js +13 -20
  273. package/templates/vn-labor-contract/VnLaborContract.dc.html +109 -108
  274. package/templates/vn-labor-contract/ds-base.js +33 -1
  275. package/templates/vn-labor-contract/support.js +13 -20
  276. package/templates/vn-labour-management-book/VnLabourManagementBook.dc.html +32 -31
  277. package/templates/vn-labour-management-book/ds-base.js +33 -1
  278. package/templates/vn-labour-management-book/support.js +13 -20
  279. package/templates/vn-mutual-nda/VnMutualNda.dc.html +45 -44
  280. package/templates/vn-mutual-nda/ds-base.js +33 -1
  281. package/templates/vn-mutual-nda/support.js +13 -20
  282. package/templates/vn-ndnca-ip/VnNdncaIp.dc.html +73 -72
  283. package/templates/vn-ndnca-ip/ds-base.js +33 -1
  284. package/templates/vn-ndnca-ip/support.js +13 -20
  285. package/templates/vn-offer-letter/VnOfferLetter.dc.html +32 -31
  286. package/templates/vn-offer-letter/ds-base.js +33 -1
  287. package/templates/vn-offer-letter/support.js +13 -20
  288. package/templates/vn-onboarding-checklist/VnOnboardingChecklist.dc.html +16 -15
  289. package/templates/vn-onboarding-checklist/ds-base.js +33 -1
  290. package/templates/vn-onboarding-checklist/support.js +13 -20
  291. package/templates/vn-pdpl-consent/VnPdplConsent.dc.html +43 -42
  292. package/templates/vn-pdpl-consent/ds-base.js +33 -1
  293. package/templates/vn-pdpl-consent/support.js +13 -20
  294. package/templates/vn-performance-evaluation-regulation/VnPerformanceEvaluationRegulation.dc.html +65 -64
  295. package/templates/vn-performance-evaluation-regulation/ds-base.js +33 -1
  296. package/templates/vn-performance-evaluation-regulation/support.js +13 -20
  297. package/templates/vn-performance-review-form/VnPerformanceReviewForm.dc.html +49 -48
  298. package/templates/vn-performance-review-form/ds-base.js +33 -1
  299. package/templates/vn-performance-review-form/support.js +13 -20
  300. package/templates/vn-phantom-stock/VnPhantomStock.dc.html +41 -40
  301. package/templates/vn-phantom-stock/ds-base.js +33 -1
  302. package/templates/vn-phantom-stock/support.js +13 -20
  303. package/templates/vn-probation-contract/VnProbationContract.dc.html +56 -55
  304. package/templates/vn-probation-contract/ds-base.js +33 -1
  305. package/templates/vn-probation-contract/support.js +13 -20
  306. package/templates/vn-receipt-acknowledgement/VnReceiptAcknowledgement.dc.html +28 -27
  307. package/templates/vn-receipt-acknowledgement/ds-base.js +33 -1
  308. package/templates/vn-receipt-acknowledgement/support.js +13 -20
  309. package/templates/vn-remote-work-policy/VnRemoteWorkPolicy.dc.html +44 -43
  310. package/templates/vn-remote-work-policy/ds-base.js +33 -1
  311. package/templates/vn-remote-work-policy/support.js +13 -20
  312. package/templates/vn-resignation-letter/VnResignationLetter.dc.html +20 -19
  313. package/templates/vn-resignation-letter/ds-base.js +33 -1
  314. package/templates/vn-resignation-letter/support.js +13 -20
  315. package/templates/vn-salary-scale/VnSalaryScale.dc.html +39 -38
  316. package/templates/vn-salary-scale/ds-base.js +33 -1
  317. package/templates/vn-salary-scale/support.js +13 -20
  318. package/templates/vn-sow-appendix/VnSowAppendix.dc.html +21 -20
  319. package/templates/vn-sow-appendix/ds-base.js +33 -1
  320. package/templates/vn-sow-appendix/support.js +13 -20
  321. package/templates/vn-termination-decision/VnTerminationDecision.dc.html +25 -24
  322. package/templates/vn-termination-decision/ds-base.js +33 -1
  323. package/templates/vn-termination-decision/support.js +13 -20
  324. package/templates/vn-total-rewards-appendix/VnTotalRewardsAppendix.dc.html +63 -62
  325. package/templates/vn-total-rewards-appendix/ds-base.js +33 -1
  326. package/templates/vn-total-rewards-appendix/support.js +13 -20
  327. package/templates/vn-training-commitment/VnTrainingCommitment.dc.html +39 -38
  328. package/templates/vn-training-commitment/ds-base.js +33 -1
  329. package/templates/vn-training-commitment/support.js +13 -20
  330. package/templates/vn-travel-expense-policy/VnTravelExpensePolicy.dc.html +50 -49
  331. package/templates/vn-travel-expense-policy/ds-base.js +33 -1
  332. package/templates/vn-travel-expense-policy/support.js +13 -20
  333. package/tokens/colors.css +19 -1
  334. package/tokens/component-tokens.css +1 -0
  335. package/tokens/elements.css +35 -2
  336. package/tokens/elevation.css +8 -2
  337. package/tokens/native/CSTokens.kt +35 -1
  338. package/tokens/native/CSTokens.swift +35 -1
  339. package/tokens/native/cs_tokens.dart +35 -1
  340. package/tokens/provenance.json +12 -12
  341. package/tokens/spacing.css +2 -0
  342. package/tokens/tokens.dtcg.json +111 -3
  343. package/tokens/tokens.js +46 -6
  344. package/tokens/tokens.json +45 -5
  345. package/tokens/typography.css +2 -0
  346. package/ui_kits/deck/index.html +4 -0
  347. package/ui_kits/status-hub/StatusHub.jsx +30 -4
  348. package/ui_kits/status-hub/index.html +3 -3
  349. package/ui_kits/status-hub/login.html +4 -0
  350. package/ui_kits/status-hub/project.html +4 -0
  351. package/ui_kits/status-hub/settings.html +35 -13
  352. package/ui_kits/status-hub/status.css +5 -1
  353. package/ui_kits/website/Website.jsx +25 -3
  354. package/ui_kits/website/careers.html +4 -0
  355. package/ui_kits/website/chat.html +5 -3
  356. package/ui_kits/website/index.html +3 -3
  357. package/ui_kits/website/site.css +2 -2
  358. package/ui_kits/website/work.html +4 -0
@@ -1,9 +1,10 @@
1
1
  // Loads this design system into the template. In a consuming project, point
2
2
  // base at the bound DS folder relative to this file (e.g. '_ds/<folder>' at
3
3
  // the project root, '../_ds/<folder>' one level down) — one line to edit.
4
+ // Artifact head standard (UX-002 / B1): ensure <html lang> + <title> from @template.
4
5
  (() => {
5
6
  const base = '../..';
6
- for (const p of ['styles.css']) {
7
+ for (const p of ['dist/styles.min.css']) {
7
8
  const l = document.createElement('link');
8
9
  l.rel = 'stylesheet'; l.href = base + '/' + p;
9
10
  document.head.appendChild(l);
@@ -20,4 +21,35 @@
20
21
  };
21
22
  s.onerror = () => console.error('ds-base.js: failed to load ' + s.src + ' — if this is a consuming project, point the base line in ds-base.js at the bound _ds/<folder> tree relative to this page (e.g. _ds/<folder> at the project root, ../_ds/<folder> one level down); in a fresh design system this can just mean the bundle is not compiled yet');
22
23
  document.head.appendChild(s);
24
+
25
+ const syncLang = () => {
26
+ try {
27
+ const a = document.querySelector('[lang]');
28
+ const v = a && a.getAttribute('lang');
29
+ // Ignore unresolved DC holes like {{ langAttr }}
30
+ if (v && v.indexOf('{{') === -1) document.documentElement.setAttribute('lang', v);
31
+ else if (!document.documentElement.getAttribute('lang')) document.documentElement.setAttribute('lang', 'en');
32
+ } catch (e) { /* authoring host may sandbox */ }
33
+ };
34
+ const ensureHead = () => {
35
+ try {
36
+ if (!document.title || !document.title.trim()) {
37
+ const src = document.documentElement.innerHTML;
38
+ const m = src.match(/@template\s+name="([^"]+)"/);
39
+ if (m) document.title = m[1] + ' · CyberSkill';
40
+ }
41
+ syncLang();
42
+ const obs = new MutationObserver(syncLang);
43
+ obs.observe(document.body || document.documentElement, {
44
+ attributes: true,
45
+ attributeFilter: ['lang'],
46
+ subtree: true,
47
+ });
48
+ } catch (e) { /* authoring host may sandbox */ }
49
+ };
50
+ if (document.readyState === 'loading') {
51
+ document.addEventListener('DOMContentLoaded', ensureHead);
52
+ } else {
53
+ ensureHead();
54
+ }
23
55
  })();
@@ -1070,16 +1070,15 @@
1070
1070
  }
1071
1071
 
1072
1072
  // src/cdn.ts
1073
- var REACT_URL = "https://unpkg.com/umd-react@19.2.8/dist/react.production.min.js";
1074
- var REACT_SRI = "sha384-/nh8CKeV7Pk42Gpda6L4DM1JtZ2bwPOi+eh9O7+a1Y22UkGs8+mw3aW1shQ9FV30";
1075
- var REACT_DOM_URL = "https://unpkg.com/umd-react@19.2.8/dist/react-dom.production.min.js";
1076
- var REACT_DOM_SRI = "sha384-rhLCB72qrpcezgY2QW0panvW9IeO32m94nvuDVRD/iEGHXoUbjtijL6Xi/Z5/mzu";
1077
- var BABEL_URL = "https://unpkg.com/@babel/standalone@7.29.0/babel.min.js";
1078
- var BABEL_SRI = "sha384-m08KidiNqLdpJqLq95G/LEi8Qvjl/xUYll3QILypMoQ65QorJ9Lvtp2RXYGBFj1y";
1079
- function cdnScriptFor(url, sri) {
1073
+ var REACT_LOCAL = "../../_vendor/react/react.production.min.js";
1074
+ var REACT_DOM_LOCAL = "../../_vendor/react/react-dom.production.min.js";
1075
+ var BABEL_LOCAL = "../../_vendor/babel/babel.min.js";
1076
+ // Product surfaces are offline-first (UX-026 / D4): no third-party script origins.
1077
+ // Host editors may still remap via window.__resources[localPath].
1078
+ function localScriptFor(path) {
1080
1079
  const res = window.__resources;
1081
- const v = res ? res[url] : void 0;
1082
- return typeof v === "string" && v ? { src: v } : { src: url, integrity: sri };
1080
+ const v = res ? res[path] : void 0;
1081
+ return typeof v === "string" && v ? v : path;
1083
1082
  }
1084
1083
 
1085
1084
  // src/external.ts
@@ -1106,16 +1105,12 @@
1106
1105
  function ensureBabel() {
1107
1106
  if (window.Babel) return Promise.resolve();
1108
1107
  if (babelLoading) return babelLoading;
1109
- const babel = cdnScriptFor(BABEL_URL, BABEL_SRI);
1108
+ const src = localScriptFor(BABEL_LOCAL);
1110
1109
  babelLoading = new Promise((res, rej) => {
1111
1110
  const s = document.createElement("script");
1112
- s.src = babel.src;
1113
- if (babel.integrity) {
1114
- s.integrity = babel.integrity;
1115
- s.crossOrigin = "anonymous";
1116
- }
1111
+ s.src = src;
1117
1112
  s.onload = () => res();
1118
- s.onerror = rej;
1113
+ s.onerror = () => rej(new Error("failed to load local Babel: " + src));
1119
1114
  document.head.appendChild(s);
1120
1115
  });
1121
1116
  return babelLoading;
@@ -1768,11 +1763,9 @@
1768
1763
  function loadReactUmd() {
1769
1764
  const w = window;
1770
1765
  if (w.React && w.ReactDOM) return Promise.resolve();
1771
- const react = cdnScriptFor(REACT_URL, REACT_SRI);
1772
- const reactDom = cdnScriptFor(REACT_DOM_URL, REACT_DOM_SRI);
1773
1766
  return Promise.all([
1774
- loadScript(react.src, react.integrity),
1775
- loadScript(reactDom.src, reactDom.integrity)
1767
+ loadScript(localScriptFor(REACT_LOCAL)),
1768
+ loadScript(localScriptFor(REACT_DOM_LOCAL))
1776
1769
  ]).then(() => void 0);
1777
1770
  }
1778
1771
  function init() {
@@ -1,6 +1,7 @@
1
1
  <!DOCTYPE html>
2
- <html>
2
+ <html lang="en">
3
3
  <head>
4
+ <title>Tech · RFC / design doc · CyberSkill</title>
4
5
  <meta charset="utf-8">
5
6
  <meta name="viewport" content="width=device-width, initial-scale=1">
6
7
  <script src="./support.js"></script>
@@ -13,7 +14,7 @@
13
14
  </helmet>
14
15
  <div data-theme="{{ rootTheme }}" lang="{{ langAttr }}" data-cs-element="{{ elAttr }}" data-cs-variant="{{ vaAttr }}" style="background:var(--cs-color-surface-raised);min-height:100vh;padding:40px 16px;font-family:var(--cs-font-family-ui);color:var(--cs-color-text-primary)">
15
16
  <div style="max-width:820px;margin:0 auto;background:var(--cs-color-surface-panel);border:1px solid var(--cs-color-border-default);border-radius:var(--cs-radius-lg);box-shadow:var(--cs-shadow-sm);overflow:hidden">
16
- <header style="background:var(--cs-accent-strong);color:#fff;padding:26px 48px;display:flex;align-items:center;gap:12px">
17
+ <header style="background:var(--cs-accent-strong);color:var(--cs-accent-on-strong);padding:26px 48px;display:flex;align-items:center;gap:12px">
17
18
  <x-import component-from-global-scope="CyberSkillDS.Logo" size="28" hint-size="28px,28px"></x-import>
18
19
  <span style="font-weight:800;font-size:16px">CyberSkill · RFC</span>
19
20
  <span style="margin-left:auto"><x-import component-from-global-scope="CyberSkillDS.Badge" variant="ochre" hint-size="90px,22px">{{ badge }}</x-import></span>
@@ -1,9 +1,10 @@
1
1
  // Loads this design system into the template. In a consuming project, point
2
2
  // base at the bound DS folder relative to this file (e.g. '_ds/<folder>' at
3
3
  // the project root, '../_ds/<folder>' one level down) — one line to edit.
4
+ // Artifact head standard (UX-002 / B1): ensure <html lang> + <title> from @template.
4
5
  (() => {
5
6
  const base = '../..';
6
- for (const p of ['styles.css']) {
7
+ for (const p of ['dist/styles.min.css']) {
7
8
  const l = document.createElement('link');
8
9
  l.rel = 'stylesheet'; l.href = base + '/' + p;
9
10
  document.head.appendChild(l);
@@ -20,4 +21,35 @@
20
21
  };
21
22
  s.onerror = () => console.error('ds-base.js: failed to load ' + s.src + ' — if this is a consuming project, point the base line in ds-base.js at the bound _ds/<folder> tree relative to this page (e.g. _ds/<folder> at the project root, ../_ds/<folder> one level down); in a fresh design system this can just mean the bundle is not compiled yet');
22
23
  document.head.appendChild(s);
24
+
25
+ const syncLang = () => {
26
+ try {
27
+ const a = document.querySelector('[lang]');
28
+ const v = a && a.getAttribute('lang');
29
+ // Ignore unresolved DC holes like {{ langAttr }}
30
+ if (v && v.indexOf('{{') === -1) document.documentElement.setAttribute('lang', v);
31
+ else if (!document.documentElement.getAttribute('lang')) document.documentElement.setAttribute('lang', 'en');
32
+ } catch (e) { /* authoring host may sandbox */ }
33
+ };
34
+ const ensureHead = () => {
35
+ try {
36
+ if (!document.title || !document.title.trim()) {
37
+ const src = document.documentElement.innerHTML;
38
+ const m = src.match(/@template\s+name="([^"]+)"/);
39
+ if (m) document.title = m[1] + ' · CyberSkill';
40
+ }
41
+ syncLang();
42
+ const obs = new MutationObserver(syncLang);
43
+ obs.observe(document.body || document.documentElement, {
44
+ attributes: true,
45
+ attributeFilter: ['lang'],
46
+ subtree: true,
47
+ });
48
+ } catch (e) { /* authoring host may sandbox */ }
49
+ };
50
+ if (document.readyState === 'loading') {
51
+ document.addEventListener('DOMContentLoaded', ensureHead);
52
+ } else {
53
+ ensureHead();
54
+ }
23
55
  })();
@@ -1070,16 +1070,15 @@
1070
1070
  }
1071
1071
 
1072
1072
  // src/cdn.ts
1073
- var REACT_URL = "https://unpkg.com/umd-react@19.2.8/dist/react.production.min.js";
1074
- var REACT_SRI = "sha384-/nh8CKeV7Pk42Gpda6L4DM1JtZ2bwPOi+eh9O7+a1Y22UkGs8+mw3aW1shQ9FV30";
1075
- var REACT_DOM_URL = "https://unpkg.com/umd-react@19.2.8/dist/react-dom.production.min.js";
1076
- var REACT_DOM_SRI = "sha384-rhLCB72qrpcezgY2QW0panvW9IeO32m94nvuDVRD/iEGHXoUbjtijL6Xi/Z5/mzu";
1077
- var BABEL_URL = "https://unpkg.com/@babel/standalone@7.29.0/babel.min.js";
1078
- var BABEL_SRI = "sha384-m08KidiNqLdpJqLq95G/LEi8Qvjl/xUYll3QILypMoQ65QorJ9Lvtp2RXYGBFj1y";
1079
- function cdnScriptFor(url, sri) {
1073
+ var REACT_LOCAL = "../../_vendor/react/react.production.min.js";
1074
+ var REACT_DOM_LOCAL = "../../_vendor/react/react-dom.production.min.js";
1075
+ var BABEL_LOCAL = "../../_vendor/babel/babel.min.js";
1076
+ // Product surfaces are offline-first (UX-026 / D4): no third-party script origins.
1077
+ // Host editors may still remap via window.__resources[localPath].
1078
+ function localScriptFor(path) {
1080
1079
  const res = window.__resources;
1081
- const v = res ? res[url] : void 0;
1082
- return typeof v === "string" && v ? { src: v } : { src: url, integrity: sri };
1080
+ const v = res ? res[path] : void 0;
1081
+ return typeof v === "string" && v ? v : path;
1083
1082
  }
1084
1083
 
1085
1084
  // src/external.ts
@@ -1106,16 +1105,12 @@
1106
1105
  function ensureBabel() {
1107
1106
  if (window.Babel) return Promise.resolve();
1108
1107
  if (babelLoading) return babelLoading;
1109
- const babel = cdnScriptFor(BABEL_URL, BABEL_SRI);
1108
+ const src = localScriptFor(BABEL_LOCAL);
1110
1109
  babelLoading = new Promise((res, rej) => {
1111
1110
  const s = document.createElement("script");
1112
- s.src = babel.src;
1113
- if (babel.integrity) {
1114
- s.integrity = babel.integrity;
1115
- s.crossOrigin = "anonymous";
1116
- }
1111
+ s.src = src;
1117
1112
  s.onload = () => res();
1118
- s.onerror = rej;
1113
+ s.onerror = () => rej(new Error("failed to load local Babel: " + src));
1119
1114
  document.head.appendChild(s);
1120
1115
  });
1121
1116
  return babelLoading;
@@ -1768,11 +1763,9 @@
1768
1763
  function loadReactUmd() {
1769
1764
  const w = window;
1770
1765
  if (w.React && w.ReactDOM) return Promise.resolve();
1771
- const react = cdnScriptFor(REACT_URL, REACT_SRI);
1772
- const reactDom = cdnScriptFor(REACT_DOM_URL, REACT_DOM_SRI);
1773
1766
  return Promise.all([
1774
- loadScript(react.src, react.integrity),
1775
- loadScript(reactDom.src, reactDom.integrity)
1767
+ loadScript(localScriptFor(REACT_LOCAL)),
1768
+ loadScript(localScriptFor(REACT_DOM_LOCAL))
1776
1769
  ]).then(() => void 0);
1777
1770
  }
1778
1771
  function init() {
@@ -1,6 +1,7 @@
1
1
  <!DOCTYPE html>
2
- <html>
2
+ <html lang="en">
3
3
  <head>
4
+ <title>HR Suite · Quyết định bổ nhiệm / điều chuyển — Appointment & Transfer Decision · CyberSkill</title>
4
5
  <meta charset="utf-8">
5
6
  <meta name="viewport" content="width=device-width, initial-scale=1">
6
7
  <meta name="omelette-owns-print" content="1">
@@ -13,76 +14,76 @@
13
14
  <script src="./ds-base.js"></script>
14
15
  <style>@page{size:A4;margin:23mm 20mm 20mm 20mm}@media print{html,body{background:#fff!important}.cs-desk{background:#fff!important;padding:0!important;min-height:0!important}.cs-sheet{box-shadow:none!important;border:none!important;max-width:none!important;border-radius:0!important;padding:0!important}.cs-avoid{break-inside:avoid}}</style>
15
16
  </helmet>
16
- <div lang="vi" data-cs-element="{{ elAttr }}" data-cs-variant="{{ vaAttr }}" class="cs-desk" style="background:#efe6d8;min-height:100vh;padding:40px 16px;font-family:var(--cs-font-family-ui);color:#1A1614">
17
+ <div lang="vi" data-cs-element="{{ elAttr }}" data-cs-variant="{{ vaAttr }}" class="cs-desk" style="background:#efe6d8;min-height:100vh;padding:40px 16px;font-family:var(--cs-font-family-ui);color:var(--cs-doc-ink)">
17
18
  <div class="cs-sheet" style="max-width:794px;margin:0 auto;background:#fff;border:1px solid var(--cs-color-border-default);border-radius:12px;box-shadow:var(--cs-shadow-md);padding:56px 60px;text-align:left">
18
19
  <div style="display:flex;align-items:center;gap:8px;font-size:10.5px;color:var(--cs-color-text-muted);padding-bottom:6px;border-bottom:1px solid var(--cs-color-border-default);margin-bottom:14px">
19
20
  <x-import component-from-global-scope="CyberSkillDS.Logo" size="18" hint-size="18px,18px"></x-import>
20
- <b style="color:var(--cs-color-brand-umber)">CyberSkill</b><span>· Quyết định bổ nhiệm / điều chuyển</span><span style="margin-left:auto;font-family:var(--cs-font-family-mono)">Số/No. <span style="background:#FDE68A;padding:0 3px">.....</span>/2026/QĐBN-CYBERSKILL</span>
21
+ <b style="color:var(--cs-color-brand-umber)">CyberSkill</b><span>· Quyết định bổ nhiệm / điều chuyển</span><span style="margin-left:auto;font-family:var(--cs-font-family-mono)">Số/No. <span style="background:var(--cs-doc-fill);padding:0 3px">.....</span>/2026/QĐBN-CYBERSKILL</span>
21
22
  </div>
22
23
  <div class="cs-avoid" style="display:grid;grid-template-columns:1.15fr 1fr;gap:20px;margin-bottom:18px">
23
- <div><div style="font-weight:800;font-size:11.5px;line-height:1.45">CÔNG TY CỔ PHẦN TƯ VẤN VÀ PHÁT TRIỂN GIẢI PHÁP PHẦN MỀM CYBERSKILL</div><div style="font-size:10px;color:#3F4C55;font-style:italic;line-height:1.45;margin-top:2px">CYBERSKILL SOFTWARE SOLUTIONS CONSULTANCY AND DEVELOPMENT JOINT STOCK COMPANY</div><div style="font-size:10.5px;margin-top:4px">Hiện Thực Hoá Ý Chí · <span style="color:#3F4C55;font-style:italic">Turn Your Will Into Real</span></div></div>
24
- <div style="text-align:center"><div style="font-weight:800;font-size:11.5px;line-height:1.5">CỘNG HÒA XÃ HỘI CHỦ NGHĨA VIỆT NAM</div><div style="font-weight:700;font-size:11px">Độc lập – Tự do – Hạnh phúc</div><div style="letter-spacing:0.1em;font-size:10px;margin:1px 0">———————————</div><div style="font-size:9.5px;color:#3F4C55;font-style:italic;line-height:1.4">The Socialist Republic of Vietnam · Independence – Freedom – Happiness</div></div>
24
+ <div><div style="font-weight:800;font-size:11.5px;line-height:1.45">CÔNG TY CỔ PHẦN TƯ VẤN VÀ PHÁT TRIỂN GIẢI PHÁP PHẦN MỀM CYBERSKILL</div><div style="font-size:10px;color:var(--cs-doc-slate);font-style:italic;line-height:1.45;margin-top:2px">CYBERSKILL SOFTWARE SOLUTIONS CONSULTANCY AND DEVELOPMENT JOINT STOCK COMPANY</div><div style="font-size:10.5px;margin-top:4px">Hiện Thực Hoá Ý Chí · <span style="color:var(--cs-doc-slate);font-style:italic">Turn Your Will Into Real</span></div></div>
25
+ <div style="text-align:center"><div style="font-weight:800;font-size:11.5px;line-height:1.5">CỘNG HÒA XÃ HỘI CHỦ NGHĨA VIỆT NAM</div><div style="font-weight:700;font-size:11px">Độc lập – Tự do – Hạnh phúc</div><div style="letter-spacing:0.1em;font-size:10px;margin:1px 0">———————————</div><div style="font-size:9.5px;color:var(--cs-doc-slate);font-style:italic;line-height:1.4">The Socialist Republic of Vietnam · Independence – Freedom – Happiness</div></div>
25
26
  </div>
26
27
  <div class="cs-avoid" style="text-align:center;margin-bottom:14px">
27
28
  <h1 style="font-size:23px;font-weight:800;color:var(--cs-color-brand-umber);letter-spacing:-0.01em;margin:0 0 3px;line-height:1.25">QUYẾT ĐỊNH BỔ NHIỆM / ĐIỀU CHUYỂN</h1>
28
- <div style="font-size:13.5px;color:#3F4C55;font-style:italic">Appointment / Transfer Decision</div>
29
- <div style="font-size:12.5px;margin-top:8px">Số / No.: <span style="background:#FDE68A;padding:0 3px">......</span>/2026/QĐBN-CYBERSKILL</div>
30
- <div style="font-size:12px;margin-top:2px">Phiên bản / Version 1.0 · Hiệu lực từ / Effective from: <span style="background:#FDE68A;padding:0 3px">......</span> / <span style="background:#FDE68A;padding:0 3px">......</span> / <span style="background:#FDE68A;padding:0 3px">......</span></div>
29
+ <div style="font-size:13.5px;color:var(--cs-doc-slate);font-style:italic">Appointment / Transfer Decision</div>
30
+ <div style="font-size:12.5px;margin-top:8px">Số / No.: <span style="background:var(--cs-doc-fill);padding:0 3px">......</span>/2026/QĐBN-CYBERSKILL</div>
31
+ <div style="font-size:12px;margin-top:2px">Phiên bản / Version 1.0 · Hiệu lực từ / Effective from: <span style="background:var(--cs-doc-fill);padding:0 3px">......</span> / <span style="background:var(--cs-doc-fill);padding:0 3px">......</span> / <span style="background:var(--cs-doc-fill);padding:0 3px">......</span></div>
31
32
  <div style="color:var(--cs-accent);font-size:13px;letter-spacing:0.5em;margin-top:10px">◆ ◆ ◆</div>
32
33
  </div>
33
34
  <p style="font-size:13px;line-height:1.5;margin:0 0 1px">Căn cứ Bộ luật Lao động số 45/2019/QH14; căn cứ Điều lệ và cơ cấu tổ chức của Công ty; căn cứ nhu cầu công việc và năng lực của người lao động,</p>
34
- <p style="font-size:12px;line-height:1.4;color:#3F4C55;font-style:italic;margin:0 0 6px">Pursuant to the Labor Code No. 45/2019/QH14; pursuant to the Company's charter and organizational structure; and on the basis of business need and the employee's capability,</p>
35
+ <p style="font-size:12px;line-height:1.4;color:var(--cs-doc-slate);font-style:italic;margin:0 0 6px">Pursuant to the Labor Code No. 45/2019/QH14; pursuant to the Company's charter and organizational structure; and on the basis of business need and the employee's capability,</p>
35
36
  <p style="font-size:13px;font-weight:700;line-height:1.5;margin:0 0 1px">TỔNG GIÁM ĐỐC QUYẾT ĐỊNH:</p>
36
- <p style="font-size:12px;font-weight:700;line-height:1.4;color:#3F4C55;font-style:italic;margin:0 0 12px">THE CHIEF EXECUTIVE OFFICER DECIDES:</p>
37
+ <p style="font-size:12px;font-weight:700;line-height:1.4;color:var(--cs-doc-slate);font-style:italic;margin:0 0 12px">THE CHIEF EXECUTIVE OFFICER DECIDES:</p>
37
38
 
38
- <h2 class="cs-avoid" style="font-size:12.5px;font-weight:800;color:var(--cs-color-brand-umber);margin:0 0 6px">ĐIỀU 1 · LOẠI QUYẾT ĐỊNH <span style="font-weight:400;font-size:11px;color:#3F4C55;font-style:italic">Article 1 · Type of decision</span></h2>
39
+ <h2 class="cs-avoid" style="font-size:12.5px;font-weight:800;color:var(--cs-color-brand-umber);margin:0 0 6px">ĐIỀU 1 · LOẠI QUYẾT ĐỊNH <span style="font-weight:400;font-size:11px;color:var(--cs-doc-slate);font-style:italic">Article 1 · Type of decision</span></h2>
39
40
  <div style="display:grid;gap:6px;margin-bottom:8px">
40
- <div><p style="font-size:13px;line-height:1.45;margin:0">☐ Bổ nhiệm (thăng chức, giao thêm chức vụ quản lý)</p><p style="font-size:12px;line-height:1.4;color:#3F4C55;font-style:italic;margin:1px 0 0">☐ Appointment (promotion, or taking on a management role)</p></div>
41
- <div><p style="font-size:13px;line-height:1.45;margin:0">☐ Điều chuyển thường xuyên (thay đổi vị trí lâu dài — cần Phụ lục sửa đổi HĐLĐ)</p><p style="font-size:12px;line-height:1.4;color:#3F4C55;font-style:italic;margin:1px 0 0">☐ Permanent transfer (a lasting change of role — requires a Labor Contract Amendment Appendix)</p></div>
42
- <div><p style="font-size:13px;line-height:1.45;margin:0">☐ Điều chuyển tạm thời theo Điều 29 Bộ luật Lao động (tối đa 60 ngày làm việc cộng dồn trong 01 năm, báo trước ít nhất 03 ngày làm việc)</p><p style="font-size:12px;line-height:1.4;color:#3F4C55;font-style:italic;margin:1px 0 0">☐ Temporary reassignment under Article 29 of the Labor Code (maximum 60 cumulative working days in a year, on at least 03 working days' notice)</p></div>
43
- <div><p style="font-size:13px;line-height:1.45;margin:0">☐ Miễn nhiệm / thôi giữ chức vụ</p><p style="font-size:12px;line-height:1.4;color:#3F4C55;font-style:italic;margin:1px 0 0">☐ Removal from a position</p></div>
41
+ <div><p style="font-size:13px;line-height:1.45;margin:0">☐ Bổ nhiệm (thăng chức, giao thêm chức vụ quản lý)</p><p style="font-size:12px;line-height:1.4;color:var(--cs-doc-slate);font-style:italic;margin:1px 0 0">☐ Appointment (promotion, or taking on a management role)</p></div>
42
+ <div><p style="font-size:13px;line-height:1.45;margin:0">☐ Điều chuyển thường xuyên (thay đổi vị trí lâu dài — cần Phụ lục sửa đổi HĐLĐ)</p><p style="font-size:12px;line-height:1.4;color:var(--cs-doc-slate);font-style:italic;margin:1px 0 0">☐ Permanent transfer (a lasting change of role — requires a Labor Contract Amendment Appendix)</p></div>
43
+ <div><p style="font-size:13px;line-height:1.45;margin:0">☐ Điều chuyển tạm thời theo Điều 29 Bộ luật Lao động (tối đa 60 ngày làm việc cộng dồn trong 01 năm, báo trước ít nhất 03 ngày làm việc)</p><p style="font-size:12px;line-height:1.4;color:var(--cs-doc-slate);font-style:italic;margin:1px 0 0">☐ Temporary reassignment under Article 29 of the Labor Code (maximum 60 cumulative working days in a year, on at least 03 working days' notice)</p></div>
44
+ <div><p style="font-size:13px;line-height:1.45;margin:0">☐ Miễn nhiệm / thôi giữ chức vụ</p><p style="font-size:12px;line-height:1.4;color:var(--cs-doc-slate);font-style:italic;margin:1px 0 0">☐ Removal from a position</p></div>
44
45
  </div>
45
46
  <div class="cs-avoid" style="background:#FBF4E9;border:1px solid var(--cs-color-border-default);border-radius:8px;padding:9px 13px;margin-bottom:14px">
46
47
  <p style="font-size:12px;line-height:1.45;margin:0 0 1px"><b>Ghi chú soạn thảo:</b> Điều chuyển THƯỜNG XUYÊN là thay đổi hợp đồng lao động: phải có sự đồng ý của người lao động và phải ký Phụ lục sửa đổi HĐLĐ. Điều chuyển TẠM THỜI theo Điều 29 thì không cần đồng ý, nhưng bị giới hạn 60 ngày và phải báo trước.</p>
47
- <p style="font-size:11px;line-height:1.4;color:#3F4C55;font-style:italic;margin:0"><b>Drafting note:</b> A PERMANENT transfer changes the labor contract: it needs the employee's agreement and a signed Amendment Appendix. A TEMPORARY reassignment under Article 29 does not need agreement, but is capped at 60 days and requires notice.</p>
48
+ <p style="font-size:11px;line-height:1.4;color:var(--cs-doc-slate);font-style:italic;margin:0"><b>Drafting note:</b> A PERMANENT transfer changes the labor contract: it needs the employee's agreement and a signed Amendment Appendix. A TEMPORARY reassignment under Article 29 does not need agreement, but is capped at 60 days and requires notice.</p>
48
49
  </div>
49
50
 
50
- <h2 class="cs-avoid" style="font-size:12.5px;font-weight:800;color:var(--cs-color-brand-umber);margin:0 0 6px">ĐIỀU 2 · NGƯỜI LAO ĐỘNG <span style="font-weight:400;font-size:11px;color:#3F4C55;font-style:italic">Article 2 · The employee</span></h2>
51
+ <h2 class="cs-avoid" style="font-size:12.5px;font-weight:800;color:var(--cs-color-brand-umber);margin:0 0 6px">ĐIỀU 2 · NGƯỜI LAO ĐỘNG <span style="font-weight:400;font-size:11px;color:var(--cs-doc-slate);font-style:italic">Article 2 · The employee</span></h2>
51
52
  <table class="cs-avoid" style="width:100%;border-collapse:collapse;font-size:12px;margin:0 0 14px">
52
- <thead><tr style="background:var(--cs-color-brand-umber);color:#fff"><th style="text-align:left;padding:5px 9px;font-size:10px;width:170px">Nội dung <i style="font-weight:400">Item</i></th><th style="text-align:left;padding:5px 9px;font-size:10px">Hiện tại <i style="font-weight:400">Current</i></th><th style="text-align:left;padding:5px 9px;font-size:10px">Sau quyết định <i style="font-weight:400">After</i></th></tr></thead>
53
+ <thead><tr style="background:var(--cs-color-brand-umber);color:var(--cs-color-text-inverse,#fff)"><th style="text-align:left;padding:5px 9px;font-size:10px;width:170px">Nội dung <i style="font-weight:400">Item</i></th><th style="text-align:left;padding:5px 9px;font-size:10px">Hiện tại <i style="font-weight:400">Current</i></th><th style="text-align:left;padding:5px 9px;font-size:10px">Sau quyết định <i style="font-weight:400">After</i></th></tr></thead>
53
54
  <tbody>
54
- <tr style="border-bottom:1px solid var(--cs-color-border-default)"><td style="padding:6px 9px;font-weight:600">Họ và tên<div style="color:#3F4C55;font-style:italic;font-size:10.5px">Full name</div></td><td style="padding:6px 9px"><span style="background:#FDE68A;padding:0 3px">..................</span></td><td style="padding:6px 9px">—</td></tr>
55
- <tr style="border-bottom:1px solid var(--cs-color-border-default)"><td style="padding:6px 9px;font-weight:600">Chức danh<div style="color:#3F4C55;font-style:italic;font-size:10.5px">Position</div></td><td style="padding:6px 9px"><span style="background:#FDE68A;padding:0 3px">..................</span></td><td style="padding:6px 9px"><span style="background:#FDE68A;padding:0 3px">..................</span></td></tr>
56
- <tr style="border-bottom:1px solid var(--cs-color-border-default)"><td style="padding:6px 9px;font-weight:600">Bộ phận<div style="color:#3F4C55;font-style:italic;font-size:10.5px">Department</div></td><td style="padding:6px 9px"><span style="background:#FDE68A;padding:0 3px">..................</span></td><td style="padding:6px 9px"><span style="background:#FDE68A;padding:0 3px">..................</span></td></tr>
57
- <tr style="border-bottom:1px solid var(--cs-color-border-default)"><td style="padding:6px 9px;font-weight:600">Quản lý trực tiếp<div style="color:#3F4C55;font-style:italic;font-size:10.5px">Line manager</div></td><td style="padding:6px 9px"><span style="background:#FDE68A;padding:0 3px">..................</span></td><td style="padding:6px 9px"><span style="background:#FDE68A;padding:0 3px">..................</span></td></tr>
58
- <tr style="border-bottom:1px solid var(--cs-color-border-default)"><td style="padding:6px 9px;font-weight:600">Bậc lương (P1)<div style="color:#3F4C55;font-style:italic;font-size:10.5px">Salary grade (P1)</div></td><td style="padding:6px 9px"><span style="background:#FDE68A;padding:0 3px">..................</span></td><td style="padding:6px 9px"><span style="background:#FDE68A;padding:0 3px">..................</span></td></tr>
59
- <tr><td style="padding:6px 9px;font-weight:600">Mức lương P1 (VNĐ/tháng)<div style="color:#3F4C55;font-style:italic;font-size:10.5px">P1 salary (VND/month)</div></td><td style="padding:6px 9px"><span style="background:#FDE68A;padding:0 3px">..................</span></td><td style="padding:6px 9px"><span style="background:#FDE68A;padding:0 3px">..................</span></td></tr>
55
+ <tr style="border-bottom:1px solid var(--cs-color-border-default)"><td style="padding:6px 9px;font-weight:600">Họ và tên<div style="color:var(--cs-doc-slate);font-style:italic;font-size:10.5px">Full name</div></td><td style="padding:6px 9px"><span style="background:var(--cs-doc-fill);padding:0 3px">..................</span></td><td style="padding:6px 9px">—</td></tr>
56
+ <tr style="border-bottom:1px solid var(--cs-color-border-default)"><td style="padding:6px 9px;font-weight:600">Chức danh<div style="color:var(--cs-doc-slate);font-style:italic;font-size:10.5px">Position</div></td><td style="padding:6px 9px"><span style="background:var(--cs-doc-fill);padding:0 3px">..................</span></td><td style="padding:6px 9px"><span style="background:var(--cs-doc-fill);padding:0 3px">..................</span></td></tr>
57
+ <tr style="border-bottom:1px solid var(--cs-color-border-default)"><td style="padding:6px 9px;font-weight:600">Bộ phận<div style="color:var(--cs-doc-slate);font-style:italic;font-size:10.5px">Department</div></td><td style="padding:6px 9px"><span style="background:var(--cs-doc-fill);padding:0 3px">..................</span></td><td style="padding:6px 9px"><span style="background:var(--cs-doc-fill);padding:0 3px">..................</span></td></tr>
58
+ <tr style="border-bottom:1px solid var(--cs-color-border-default)"><td style="padding:6px 9px;font-weight:600">Quản lý trực tiếp<div style="color:var(--cs-doc-slate);font-style:italic;font-size:10.5px">Line manager</div></td><td style="padding:6px 9px"><span style="background:var(--cs-doc-fill);padding:0 3px">..................</span></td><td style="padding:6px 9px"><span style="background:var(--cs-doc-fill);padding:0 3px">..................</span></td></tr>
59
+ <tr style="border-bottom:1px solid var(--cs-color-border-default)"><td style="padding:6px 9px;font-weight:600">Bậc lương (P1)<div style="color:var(--cs-doc-slate);font-style:italic;font-size:10.5px">Salary grade (P1)</div></td><td style="padding:6px 9px"><span style="background:var(--cs-doc-fill);padding:0 3px">..................</span></td><td style="padding:6px 9px"><span style="background:var(--cs-doc-fill);padding:0 3px">..................</span></td></tr>
60
+ <tr><td style="padding:6px 9px;font-weight:600">Mức lương P1 (VNĐ/tháng)<div style="color:var(--cs-doc-slate);font-style:italic;font-size:10.5px">P1 salary (VND/month)</div></td><td style="padding:6px 9px"><span style="background:var(--cs-doc-fill);padding:0 3px">..................</span></td><td style="padding:6px 9px"><span style="background:var(--cs-doc-fill);padding:0 3px">..................</span></td></tr>
60
61
  </tbody>
61
62
  </table>
62
63
 
63
- <h2 class="cs-avoid" style="font-size:12.5px;font-weight:800;color:var(--cs-color-brand-umber);margin:0 0 5px">ĐIỀU 3 · HIỆU LỰC <span style="font-weight:400;font-size:11px;color:#3F4C55;font-style:italic">Article 3 · Effect</span></h2>
64
+ <h2 class="cs-avoid" style="font-size:12.5px;font-weight:800;color:var(--cs-color-brand-umber);margin:0 0 5px">ĐIỀU 3 · HIỆU LỰC <span style="font-weight:400;font-size:11px;color:var(--cs-doc-slate);font-style:italic">Article 3 · Effect</span></h2>
64
65
  <div style="display:grid;gap:8px;margin-bottom:14px">
65
- <div><p style="font-size:13px;line-height:1.5;margin:0 0 1px">3.1. Quyết định có hiệu lực kể từ ngày <span style="background:#FDE68A;padding:0 3px">...... / ...... / ......</span>.</p><p style="font-size:12px;line-height:1.4;color:#3F4C55;font-style:italic;margin:0">3.1. This Decision takes effect on <span style="background:#FDE68A;padding:0 3px">...... / ...... / ......</span>.</p></div>
66
- <div><p style="font-size:13px;line-height:1.5;margin:0 0 1px">3.2. Đối với điều chuyển tạm thời: thời hạn từ <span style="background:#FDE68A;padding:0 3px">.../.../...</span> đến <span style="background:#FDE68A;padding:0 3px">.../.../...</span> (tối đa 60 ngày làm việc cộng dồn trong 01 năm). Tiền lương trả theo công việc mới; nếu thấp hơn thì giữ nguyên mức cũ trong 30 ngày làm việc, sau đó ít nhất bằng 85% mức cũ và không thấp hơn lương tối thiểu vùng (Điều 29 khoản 3).</p><p style="font-size:12px;line-height:1.4;color:#3F4C55;font-style:italic;margin:0">3.2. For a temporary reassignment: from <span style="background:#FDE68A;padding:0 3px">.../.../...</span> to <span style="background:#FDE68A;padding:0 3px">.../.../...</span> (maximum 60 cumulative working days in a year). Pay is at the rate for the new work; where that is lower, the previous rate is kept for 30 working days, and thereafter is at least 85% of it and not below the regional minimum wage (Article 29.3).</p></div>
67
- <div><p style="font-size:13px;line-height:1.5;margin:0 0 1px">3.3. Đối với bổ nhiệm hoặc điều chuyển thường xuyên: Phụ lục sửa đổi HĐLĐ số <span style="background:#FDE68A;padding:0 3px">..................</span> được ký kèm theo Quyết định này.</p><p style="font-size:12px;line-height:1.4;color:#3F4C55;font-style:italic;margin:0">3.3. For an appointment or a permanent transfer: Labor Contract Amendment Appendix no. <span style="background:#FDE68A;padding:0 3px">..................</span> is signed together with this Decision.</p></div>
68
- <div><p style="font-size:13px;line-height:1.5;margin:0 0 1px">3.4. Bản mô tả công việc mới được ban hành kèm theo và người lao động ký xác nhận.</p><p style="font-size:12px;line-height:1.4;color:#3F4C55;font-style:italic;margin:0">3.4. A new Job Description is issued with this Decision and acknowledged by the employee.</p></div>
66
+ <div><p style="font-size:13px;line-height:1.5;margin:0 0 1px">3.1. Quyết định có hiệu lực kể từ ngày <span style="background:var(--cs-doc-fill);padding:0 3px">...... / ...... / ......</span>.</p><p style="font-size:12px;line-height:1.4;color:var(--cs-doc-slate);font-style:italic;margin:0">3.1. This Decision takes effect on <span style="background:var(--cs-doc-fill);padding:0 3px">...... / ...... / ......</span>.</p></div>
67
+ <div><p style="font-size:13px;line-height:1.5;margin:0 0 1px">3.2. Đối với điều chuyển tạm thời: thời hạn từ <span style="background:var(--cs-doc-fill);padding:0 3px">.../.../...</span> đến <span style="background:var(--cs-doc-fill);padding:0 3px">.../.../...</span> (tối đa 60 ngày làm việc cộng dồn trong 01 năm). Tiền lương trả theo công việc mới; nếu thấp hơn thì giữ nguyên mức cũ trong 30 ngày làm việc, sau đó ít nhất bằng 85% mức cũ và không thấp hơn lương tối thiểu vùng (Điều 29 khoản 3).</p><p style="font-size:12px;line-height:1.4;color:var(--cs-doc-slate);font-style:italic;margin:0">3.2. For a temporary reassignment: from <span style="background:var(--cs-doc-fill);padding:0 3px">.../.../...</span> to <span style="background:var(--cs-doc-fill);padding:0 3px">.../.../...</span> (maximum 60 cumulative working days in a year). Pay is at the rate for the new work; where that is lower, the previous rate is kept for 30 working days, and thereafter is at least 85% of it and not below the regional minimum wage (Article 29.3).</p></div>
68
+ <div><p style="font-size:13px;line-height:1.5;margin:0 0 1px">3.3. Đối với bổ nhiệm hoặc điều chuyển thường xuyên: Phụ lục sửa đổi HĐLĐ số <span style="background:var(--cs-doc-fill);padding:0 3px">..................</span> được ký kèm theo Quyết định này.</p><p style="font-size:12px;line-height:1.4;color:var(--cs-doc-slate);font-style:italic;margin:0">3.3. For an appointment or a permanent transfer: Labor Contract Amendment Appendix no. <span style="background:var(--cs-doc-fill);padding:0 3px">..................</span> is signed together with this Decision.</p></div>
69
+ <div><p style="font-size:13px;line-height:1.5;margin:0 0 1px">3.4. Bản mô tả công việc mới được ban hành kèm theo và người lao động ký xác nhận.</p><p style="font-size:12px;line-height:1.4;color:var(--cs-doc-slate);font-style:italic;margin:0">3.4. A new Job Description is issued with this Decision and acknowledged by the employee.</p></div>
69
70
  </div>
70
71
 
71
72
  <div class="cs-avoid" style="background:var(--cs-color-surface-raised);border:1px solid var(--cs-color-border-default);border-radius:8px;padding:9px 13px;margin-bottom:16px">
72
73
  <p style="font-size:12px;line-height:1.45;margin:0 0 1px"><b>Nơi nhận:</b> Người lao động; quản lý trực tiếp cũ và mới; bộ phận nhân sự; lưu hồ sơ.</p>
73
- <p style="font-size:11px;line-height:1.4;color:#3F4C55;font-style:italic;margin:0"><b>Recipients:</b> The employee; the outgoing and incoming line managers; HR; the personnel file.</p>
74
+ <p style="font-size:11px;line-height:1.4;color:var(--cs-doc-slate);font-style:italic;margin:0"><b>Recipients:</b> The employee; the outgoing and incoming line managers; HR; the personnel file.</p>
74
75
  </div>
75
76
 
76
77
  <div class="cs-avoid">
77
- <p style="font-size:13px;line-height:1.5;margin:0 0 1px">Thành phố Hồ Chí Minh, ngày <span style="background:#FDE68A;padding:0 3px">......</span> tháng <span style="background:#FDE68A;padding:0 3px">......</span> năm <span style="background:#FDE68A;padding:0 3px">......</span></p>
78
- <p style="font-size:12px;line-height:1.4;color:#3F4C55;font-style:italic;margin:0 0 14px">Ho Chi Minh City, <span style="background:#FDE68A;padding:0 3px">......</span> / <span style="background:#FDE68A;padding:0 3px">......</span> / <span style="background:#FDE68A;padding:0 3px">......</span></p>
78
+ <p style="font-size:13px;line-height:1.5;margin:0 0 1px">Thành phố Hồ Chí Minh, ngày <span style="background:var(--cs-doc-fill);padding:0 3px">......</span> tháng <span style="background:var(--cs-doc-fill);padding:0 3px">......</span> năm <span style="background:var(--cs-doc-fill);padding:0 3px">......</span></p>
79
+ <p style="font-size:12px;line-height:1.4;color:var(--cs-doc-slate);font-style:italic;margin:0 0 14px">Ho Chi Minh City, <span style="background:var(--cs-doc-fill);padding:0 3px">......</span> / <span style="background:var(--cs-doc-fill);padding:0 3px">......</span> / <span style="background:var(--cs-doc-fill);padding:0 3px">......</span></p>
79
80
  <div style="display:grid;grid-template-columns:1fr 1fr;gap:44px">
80
- <div style="text-align:center"><div style="font-weight:700;font-size:12.5px">NGƯỜI LAO ĐỘNG (đã nhận và đồng ý)</div><div style="font-size:11px;color:#3F4C55;font-style:italic">The Employee (received and agreed)</div><div style="font-size:10.5px;margin-top:1px">(Ký, ghi rõ họ tên / <i style="color:#3F4C55">Sign and state full name</i>)</div><div style="height:60px"></div><div style="border-top:1px solid #1A1614;width:70%;margin:0 auto"></div></div>
81
- <div style="text-align:center"><div style="font-weight:700;font-size:12.5px">TỔNG GIÁM ĐỐC</div><div style="font-size:11px;color:#3F4C55;font-style:italic">Chief Executive Officer</div><div style="font-size:10.5px;margin-top:1px">(Ký, ghi rõ họ tên và đóng dấu / <i style="color:#3F4C55">Sign, full name, and affix seal</i>)</div><div style="height:60px"></div><div style="border-top:1px solid #1A1614;width:70%;margin:0 auto"></div></div>
81
+ <div style="text-align:center"><div style="font-weight:700;font-size:12.5px">NGƯỜI LAO ĐỘNG (đã nhận và đồng ý)</div><div style="font-size:11px;color:var(--cs-doc-slate);font-style:italic">The Employee (received and agreed)</div><div style="font-size:10.5px;margin-top:1px">(Ký, ghi rõ họ tên / <i style="color:var(--cs-doc-slate)">Sign and state full name</i>)</div><div style="height:60px"></div><div style="border-top:1px solid var(--cs-doc-ink);width:70%;margin:0 auto"></div></div>
82
+ <div style="text-align:center"><div style="font-weight:700;font-size:12.5px">TỔNG GIÁM ĐỐC</div><div style="font-size:11px;color:var(--cs-doc-slate);font-style:italic">Chief Executive Officer</div><div style="font-size:10.5px;margin-top:1px">(Ký, ghi rõ họ tên và đóng dấu / <i style="color:var(--cs-doc-slate)">Sign, full name, and affix seal</i>)</div><div style="height:60px"></div><div style="border-top:1px solid var(--cs-doc-ink);width:70%;margin:0 auto"></div></div>
82
83
  </div>
83
84
  </div>
84
85
 
85
- <div style="border-top:1px solid var(--cs-color-border-default);padding-top:8px;margin-top:20px;display:flex;gap:10px;font-size:10.5px;color:var(--cs-color-text-muted);flex-wrap:wrap">Hiện Thực Hoá Ý Chí · <i style="color:#3F4C55">Turn Your Will Into Real</i><span>·</span>MST: 0316475200<span>·</span>info@cyberskill.world<span>·</span>(+84) 906 878 091<span style="margin-left:auto">Trang / Page 1</span></div>
86
+ <div style="border-top:1px solid var(--cs-color-border-default);padding-top:8px;margin-top:20px;display:flex;gap:10px;font-size:10.5px;color:var(--cs-color-text-muted);flex-wrap:wrap">Hiện Thực Hoá Ý Chí · <i style="color:var(--cs-doc-slate)">Turn Your Will Into Real</i><span>·</span>MST: 0316475200<span>·</span>info@cyberskill.world<span>·</span>(+84) 906 878 091<span style="margin-left:auto">Trang / Page 1</span></div>
86
87
  </div>
87
88
  </div>
88
89
  </x-dc>
@@ -1,9 +1,10 @@
1
1
  // Loads this design system into the template. In a consuming project, point
2
2
  // base at the bound DS folder relative to this file (e.g. '_ds/<folder>' at
3
3
  // the project root, '../_ds/<folder>' one level down) — one line to edit.
4
+ // Artifact head standard (UX-002 / B1): ensure <html lang> + <title> from @template.
4
5
  (() => {
5
6
  const base = '../..';
6
- for (const p of ['styles.css']) {
7
+ for (const p of ['dist/styles.min.css']) {
7
8
  const l = document.createElement('link');
8
9
  l.rel = 'stylesheet'; l.href = base + '/' + p;
9
10
  document.head.appendChild(l);
@@ -20,4 +21,35 @@
20
21
  };
21
22
  s.onerror = () => console.error('ds-base.js: failed to load ' + s.src + ' — if this is a consuming project, point the base line in ds-base.js at the bound _ds/<folder> tree relative to this page (e.g. _ds/<folder> at the project root, ../_ds/<folder> one level down); in a fresh design system this can just mean the bundle is not compiled yet');
22
23
  document.head.appendChild(s);
24
+
25
+ const syncLang = () => {
26
+ try {
27
+ const a = document.querySelector('[lang]');
28
+ const v = a && a.getAttribute('lang');
29
+ // Ignore unresolved DC holes like {{ langAttr }}
30
+ if (v && v.indexOf('{{') === -1) document.documentElement.setAttribute('lang', v);
31
+ else if (!document.documentElement.getAttribute('lang')) document.documentElement.setAttribute('lang', 'en');
32
+ } catch (e) { /* authoring host may sandbox */ }
33
+ };
34
+ const ensureHead = () => {
35
+ try {
36
+ if (!document.title || !document.title.trim()) {
37
+ const src = document.documentElement.innerHTML;
38
+ const m = src.match(/@template\s+name="([^"]+)"/);
39
+ if (m) document.title = m[1] + ' · CyberSkill';
40
+ }
41
+ syncLang();
42
+ const obs = new MutationObserver(syncLang);
43
+ obs.observe(document.body || document.documentElement, {
44
+ attributes: true,
45
+ attributeFilter: ['lang'],
46
+ subtree: true,
47
+ });
48
+ } catch (e) { /* authoring host may sandbox */ }
49
+ };
50
+ if (document.readyState === 'loading') {
51
+ document.addEventListener('DOMContentLoaded', ensureHead);
52
+ } else {
53
+ ensureHead();
54
+ }
23
55
  })();
@@ -1070,16 +1070,15 @@
1070
1070
  }
1071
1071
 
1072
1072
  // src/cdn.ts
1073
- var REACT_URL = "https://unpkg.com/umd-react@19.2.8/dist/react.production.min.js";
1074
- var REACT_SRI = "sha384-/nh8CKeV7Pk42Gpda6L4DM1JtZ2bwPOi+eh9O7+a1Y22UkGs8+mw3aW1shQ9FV30";
1075
- var REACT_DOM_URL = "https://unpkg.com/umd-react@19.2.8/dist/react-dom.production.min.js";
1076
- var REACT_DOM_SRI = "sha384-rhLCB72qrpcezgY2QW0panvW9IeO32m94nvuDVRD/iEGHXoUbjtijL6Xi/Z5/mzu";
1077
- var BABEL_URL = "https://unpkg.com/@babel/standalone@7.29.0/babel.min.js";
1078
- var BABEL_SRI = "sha384-m08KidiNqLdpJqLq95G/LEi8Qvjl/xUYll3QILypMoQ65QorJ9Lvtp2RXYGBFj1y";
1079
- function cdnScriptFor(url, sri) {
1073
+ var REACT_LOCAL = "../../_vendor/react/react.production.min.js";
1074
+ var REACT_DOM_LOCAL = "../../_vendor/react/react-dom.production.min.js";
1075
+ var BABEL_LOCAL = "../../_vendor/babel/babel.min.js";
1076
+ // Product surfaces are offline-first (UX-026 / D4): no third-party script origins.
1077
+ // Host editors may still remap via window.__resources[localPath].
1078
+ function localScriptFor(path) {
1080
1079
  const res = window.__resources;
1081
- const v = res ? res[url] : void 0;
1082
- return typeof v === "string" && v ? { src: v } : { src: url, integrity: sri };
1080
+ const v = res ? res[path] : void 0;
1081
+ return typeof v === "string" && v ? v : path;
1083
1082
  }
1084
1083
 
1085
1084
  // src/external.ts
@@ -1106,16 +1105,12 @@
1106
1105
  function ensureBabel() {
1107
1106
  if (window.Babel) return Promise.resolve();
1108
1107
  if (babelLoading) return babelLoading;
1109
- const babel = cdnScriptFor(BABEL_URL, BABEL_SRI);
1108
+ const src = localScriptFor(BABEL_LOCAL);
1110
1109
  babelLoading = new Promise((res, rej) => {
1111
1110
  const s = document.createElement("script");
1112
- s.src = babel.src;
1113
- if (babel.integrity) {
1114
- s.integrity = babel.integrity;
1115
- s.crossOrigin = "anonymous";
1116
- }
1111
+ s.src = src;
1117
1112
  s.onload = () => res();
1118
- s.onerror = rej;
1113
+ s.onerror = () => rej(new Error("failed to load local Babel: " + src));
1119
1114
  document.head.appendChild(s);
1120
1115
  });
1121
1116
  return babelLoading;
@@ -1768,11 +1763,9 @@
1768
1763
  function loadReactUmd() {
1769
1764
  const w = window;
1770
1765
  if (w.React && w.ReactDOM) return Promise.resolve();
1771
- const react = cdnScriptFor(REACT_URL, REACT_SRI);
1772
- const reactDom = cdnScriptFor(REACT_DOM_URL, REACT_DOM_SRI);
1773
1766
  return Promise.all([
1774
- loadScript(react.src, react.integrity),
1775
- loadScript(reactDom.src, reactDom.integrity)
1767
+ loadScript(localScriptFor(REACT_LOCAL)),
1768
+ loadScript(localScriptFor(REACT_DOM_LOCAL))
1776
1769
  ]).then(() => void 0);
1777
1770
  }
1778
1771
  function init() {