@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
@@ -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 · Thư mời nhận việc — Employment Offer Letter · 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,59 +14,59 @@
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>· Thư mời nhận việc</span><span style="margin-left:auto;font-family:var(--cs-font-family-mono)">Số/No. <span style="background:#FDE68A;padding:0 3px">.....</span>/2026/TMV-CYBERSKILL</span>
21
+ <b style="color:var(--cs-color-brand-umber)">CyberSkill</b><span>· Thư mời nhận việc</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/TMV-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>
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 style="font-size:10.5px;margin-top:4px">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></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>
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 style="font-size:10.5px;margin-top:4px">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></div></div>
25
26
  </div>
26
27
  <div class="cs-avoid" style="text-align:center;margin-bottom:18px">
27
28
  <h1 style="font-size:26px;font-weight:800;color:var(--cs-color-brand-umber);letter-spacing:-0.01em;margin:0 0 3px;line-height:1.25">THƯ MỜI NHẬN VIỆC</h1>
28
- <div style="font-size:14.5px;color:#3F4C55;font-style:italic">Employment Offer Letter</div>
29
- <div style="font-size:12px;margin-top:8px">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:14.5px;color:var(--cs-doc-slate);font-style:italic">Employment Offer Letter</div>
30
+ <div style="font-size:12px;margin-top:8px">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>
30
31
  <div style="color:var(--cs-accent);font-size:13px;letter-spacing:0.5em;margin-top:10px">◆ ◆ ◆</div>
31
32
  </div>
32
- <p style="font-size:14px;line-height:1.5;margin:0 0 2px">Kính gửi Ông/Bà: <span style="background:#FDE68A;padding:0 3px">..............................</span></p>
33
- <p style="font-size:12.5px;line-height:1.45;color:#3F4C55;font-style:italic;margin:0 0 10px">Dear Mr./Ms.: <span style="background:#FDE68A;padding:0 3px">..............................</span></p>
33
+ <p style="font-size:14px;line-height:1.5;margin:0 0 2px">Kính gửi Ông/Bà: <span style="background:var(--cs-doc-fill);padding:0 3px">..............................</span></p>
34
+ <p style="font-size:12.5px;line-height:1.45;color:var(--cs-doc-slate);font-style:italic;margin:0 0 10px">Dear Mr./Ms.: <span style="background:var(--cs-doc-fill);padding:0 3px">..............................</span></p>
34
35
  <p style="font-size:14px;line-height:1.5;margin:0 0 2px">Công ty hân hạnh mời Ông/Bà nhận vị trí công việc với các điều khoản chính sau đây:</p>
35
- <p style="font-size:12.5px;line-height:1.45;color:#3F4C55;font-style:italic;margin:0 0 12px">The Company is pleased to offer you the following position on the key terms below:</p>
36
+ <p style="font-size:12.5px;line-height:1.45;color:var(--cs-doc-slate);font-style:italic;margin:0 0 12px">The Company is pleased to offer you the following position on the key terms below:</p>
36
37
 
37
38
  <table class="cs-avoid" style="width:100%;border-collapse:collapse;font-size:12.5px;margin:0 0 18px">
38
- <thead><tr style="background:var(--cs-color-brand-umber);color:#fff"><th colspan="2" style="text-align:left;padding:6px 10px;font-size:11px">ĐIỀU KHOẢN CHÍNH <i style="font-weight:400">Key terms</i></th></tr></thead>
39
+ <thead><tr style="background:var(--cs-color-brand-umber);color:var(--cs-color-text-inverse,#fff)"><th colspan="2" style="text-align:left;padding:6px 10px;font-size:11px">ĐIỀU KHOẢN CHÍNH <i style="font-weight:400">Key terms</i></th></tr></thead>
39
40
  <tbody>
40
- <tr style="border-bottom:1px solid var(--cs-color-border-default)"><td style="padding:6px 10px;width:200px;vertical-align:top">Vị trí<div style="color:#3F4C55;font-style:italic;font-size:11px">Position</div></td><td style="padding:6px 10px"><span style="background:#FDE68A;padding:0 3px">..............................</span></td></tr>
41
- <tr style="border-bottom:1px solid var(--cs-color-border-default)"><td style="padding:6px 10px;vertical-align:top">Bộ phận<div style="color:#3F4C55;font-style:italic;font-size:11px">Department</div></td><td style="padding:6px 10px"><span style="background:#FDE68A;padding:0 3px">..............................</span></td></tr>
42
- <tr style="border-bottom:1px solid var(--cs-color-border-default)"><td style="padding:6px 10px;vertical-align:top">Cấp báo cáo<div style="color:#3F4C55;font-style:italic;font-size:11px">Reports to</div></td><td style="padding:6px 10px"><span style="background:#FDE68A;padding:0 3px">..............................</span></td></tr>
43
- <tr style="border-bottom:1px solid var(--cs-color-border-default)"><td style="padding:6px 10px;vertical-align:top">Loại hợp đồng<div style="color:#3F4C55;font-style:italic;font-size:11px">Contract type</div></td><td style="padding:6px 10px">☐ Xác định thời hạn ☐ Không xác định thời hạn<div style="color:#3F4C55;font-style:italic;font-size:11px">☐ Definite-term ☐ Indefinite-term</div></td></tr>
44
- <tr style="border-bottom:1px solid var(--cs-color-border-default)"><td style="padding:6px 10px;vertical-align:top">Ngày bắt đầu dự kiến<div style="color:#3F4C55;font-style:italic;font-size:11px">Expected start date</div></td><td style="padding:6px 10px"><span style="background:#FDE68A;padding:0 3px">...../...../......</span></td></tr>
45
- <tr style="border-bottom:1px solid var(--cs-color-border-default)"><td style="padding:6px 10px;vertical-align:top">Thử việc<div style="color:#3F4C55;font-style:italic;font-size:11px">Probation</div></td><td style="padding:6px 10px"><span style="background:#FDE68A;padding:0 3px">......</span> ngày (nếu áp dụng)<div style="color:#3F4C55;font-style:italic;font-size:11px"><span style="background:#FDE68A;padding:0 3px">......</span> days (if applicable)</div></td></tr>
46
- <tr style="border-bottom:1px solid var(--cs-color-border-default)"><td style="padding:6px 10px;vertical-align:top">Mức lương<div style="color:#3F4C55;font-style:italic;font-size:11px">Salary (VND/month)</div></td><td style="padding:6px 10px"><span style="background:#FDE68A;padding:0 3px">..............................</span></td></tr>
47
- <tr style="border-bottom:1px solid var(--cs-color-border-default)"><td style="padding:6px 10px;vertical-align:top">Đãi ngộ khác<div style="color:#3F4C55;font-style:italic;font-size:11px">Other rewards</div></td><td style="padding:6px 10px">Theo Phụ lục Đãi ngộ Toàn diện & Lộ trình Phát triển<div style="color:#3F4C55;font-style:italic;font-size:11px">Per the Total Rewards & Career Path Appendix</div></td></tr>
48
- <tr style="border-bottom:1px solid var(--cs-color-border-default)"><td style="padding:6px 10px;vertical-align:top">Địa điểm làm việc<div style="color:#3F4C55;font-style:italic;font-size:11px">Place of work</div></td><td style="padding:6px 10px">Tầng 1, 207A Nguyễn Văn Thủ, Phường Tân Định, TP. Hồ Chí Minh<div style="color:#3F4C55;font-style:italic;font-size:11px">1st Floor, 207A Nguyen Van Thu Street, Tan Dinh Ward, HCMC</div></td></tr>
49
- <tr><td style="padding:6px 10px;vertical-align:top">Giờ làm việc<div style="color:#3F4C55;font-style:italic;font-size:11px">Working hours</div></td><td style="padding:6px 10px">40 giờ/tuần, thứ Hai đến thứ Sáu<div style="color:#3F4C55;font-style:italic;font-size:11px">40 hours/week, Monday to Friday</div></td></tr>
41
+ <tr style="border-bottom:1px solid var(--cs-color-border-default)"><td style="padding:6px 10px;width:200px;vertical-align:top">Vị trí<div style="color:var(--cs-doc-slate);font-style:italic;font-size:11px">Position</div></td><td style="padding:6px 10px"><span style="background:var(--cs-doc-fill);padding:0 3px">..............................</span></td></tr>
42
+ <tr style="border-bottom:1px solid var(--cs-color-border-default)"><td style="padding:6px 10px;vertical-align:top">Bộ phận<div style="color:var(--cs-doc-slate);font-style:italic;font-size:11px">Department</div></td><td style="padding:6px 10px"><span style="background:var(--cs-doc-fill);padding:0 3px">..............................</span></td></tr>
43
+ <tr style="border-bottom:1px solid var(--cs-color-border-default)"><td style="padding:6px 10px;vertical-align:top">Cấp báo cáo<div style="color:var(--cs-doc-slate);font-style:italic;font-size:11px">Reports to</div></td><td style="padding:6px 10px"><span style="background:var(--cs-doc-fill);padding:0 3px">..............................</span></td></tr>
44
+ <tr style="border-bottom:1px solid var(--cs-color-border-default)"><td style="padding:6px 10px;vertical-align:top">Loại hợp đồng<div style="color:var(--cs-doc-slate);font-style:italic;font-size:11px">Contract type</div></td><td style="padding:6px 10px">☐ Xác định thời hạn ☐ Không xác định thời hạn<div style="color:var(--cs-doc-slate);font-style:italic;font-size:11px">☐ Definite-term ☐ Indefinite-term</div></td></tr>
45
+ <tr style="border-bottom:1px solid var(--cs-color-border-default)"><td style="padding:6px 10px;vertical-align:top">Ngày bắt đầu dự kiến<div style="color:var(--cs-doc-slate);font-style:italic;font-size:11px">Expected start date</div></td><td style="padding:6px 10px"><span style="background:var(--cs-doc-fill);padding:0 3px">...../...../......</span></td></tr>
46
+ <tr style="border-bottom:1px solid var(--cs-color-border-default)"><td style="padding:6px 10px;vertical-align:top">Thử việc<div style="color:var(--cs-doc-slate);font-style:italic;font-size:11px">Probation</div></td><td style="padding:6px 10px"><span style="background:var(--cs-doc-fill);padding:0 3px">......</span> ngày (nếu áp dụng)<div style="color:var(--cs-doc-slate);font-style:italic;font-size:11px"><span style="background:var(--cs-doc-fill);padding:0 3px">......</span> days (if applicable)</div></td></tr>
47
+ <tr style="border-bottom:1px solid var(--cs-color-border-default)"><td style="padding:6px 10px;vertical-align:top">Mức lương<div style="color:var(--cs-doc-slate);font-style:italic;font-size:11px">Salary (VND/month)</div></td><td style="padding:6px 10px"><span style="background:var(--cs-doc-fill);padding:0 3px">..............................</span></td></tr>
48
+ <tr style="border-bottom:1px solid var(--cs-color-border-default)"><td style="padding:6px 10px;vertical-align:top">Đãi ngộ khác<div style="color:var(--cs-doc-slate);font-style:italic;font-size:11px">Other rewards</div></td><td style="padding:6px 10px">Theo Phụ lục Đãi ngộ Toàn diện & Lộ trình Phát triển<div style="color:var(--cs-doc-slate);font-style:italic;font-size:11px">Per the Total Rewards & Career Path Appendix</div></td></tr>
49
+ <tr style="border-bottom:1px solid var(--cs-color-border-default)"><td style="padding:6px 10px;vertical-align:top">Địa điểm làm việc<div style="color:var(--cs-doc-slate);font-style:italic;font-size:11px">Place of work</div></td><td style="padding:6px 10px">Tầng 1, 207A Nguyễn Văn Thủ, Phường Tân Định, TP. Hồ Chí Minh<div style="color:var(--cs-doc-slate);font-style:italic;font-size:11px">1st Floor, 207A Nguyen Van Thu Street, Tan Dinh Ward, HCMC</div></td></tr>
50
+ <tr><td style="padding:6px 10px;vertical-align:top">Giờ làm việc<div style="color:var(--cs-doc-slate);font-style:italic;font-size:11px">Working hours</div></td><td style="padding:6px 10px">40 giờ/tuần, thứ Hai đến thứ Sáu<div style="color:var(--cs-doc-slate);font-style:italic;font-size:11px">40 hours/week, Monday to Friday</div></td></tr>
50
51
  </tbody>
51
52
  </table>
52
53
 
53
- <h2 class="cs-avoid" style="font-size:13px;font-weight:800;color:var(--cs-color-brand-umber);margin:0 0 6px">ĐIỀU KIỆN CỦA LỜI MỜI <span style="font-weight:400;font-size:11.5px;color:#3F4C55;font-style:italic">Conditions of this offer</span></h2>
54
+ <h2 class="cs-avoid" style="font-size:13px;font-weight:800;color:var(--cs-color-brand-umber);margin:0 0 6px">ĐIỀU KIỆN CỦA LỜI MỜI <span style="font-weight:400;font-size:11.5px;color:var(--cs-doc-slate);font-style:italic">Conditions of this offer</span></h2>
54
55
  <p style="font-size:14px;line-height:1.5;margin:0 0 2px">a) Ông/Bà hoàn tất hồ sơ nhân sự và cung cấp giấy tờ hợp lệ; b) hai Bên ký Hợp đồng lao động và Thỏa thuận Bảo mật, Không cạnh tranh và Sở hữu trí tuệ; c) kết quả xác minh thông tin đạt yêu cầu.</p>
55
- <p style="font-size:12.5px;line-height:1.45;color:#3F4C55;font-style:italic;margin:0 0 10px">a) You complete the personnel file and provide valid documents; b) the Parties sign the Labor Contract and the NDNCA & IP Agreement; c) background verification is satisfactory.</p>
56
- <p style="font-size:14px;line-height:1.5;margin:0 0 2px">Thư mời này không phải là hợp đồng lao động và có hiệu lực đến hết ngày <span style="background:#FDE68A;padding:0 3px">...../...../......</span>. Quan hệ lao động phát sinh khi hai Bên ký Hợp đồng lao động.</p>
57
- <p style="font-size:12.5px;line-height:1.45;color:#3F4C55;font-style:italic;margin:0 0 16px">This letter is not a Labor Contract and is valid until <span style="background:#FDE68A;padding:0 3px">...../...../......</span>. The employment relationship arises when the Parties sign the Labor Contract.</p>
56
+ <p style="font-size:12.5px;line-height:1.45;color:var(--cs-doc-slate);font-style:italic;margin:0 0 10px">a) You complete the personnel file and provide valid documents; b) the Parties sign the Labor Contract and the NDNCA & IP Agreement; c) background verification is satisfactory.</p>
57
+ <p style="font-size:14px;line-height:1.5;margin:0 0 2px">Thư mời này không phải là hợp đồng lao động và có hiệu lực đến hết ngày <span style="background:var(--cs-doc-fill);padding:0 3px">...../...../......</span>. Quan hệ lao động phát sinh khi hai Bên ký Hợp đồng lao động.</p>
58
+ <p style="font-size:12.5px;line-height:1.45;color:var(--cs-doc-slate);font-style:italic;margin:0 0 16px">This letter is not a Labor Contract and is valid until <span style="background:var(--cs-doc-fill);padding:0 3px">...../...../......</span>. The employment relationship arises when the Parties sign the Labor Contract.</p>
58
59
 
59
- <h2 class="cs-avoid" style="font-size:13px;font-weight:800;color:var(--cs-color-brand-umber);margin:0 0 6px">XÁC NHẬN <span style="font-weight:400;font-size:11.5px;color:#3F4C55;font-style:italic">Acceptance</span></h2>
60
- <p style="font-size:14px;line-height:1.5;margin:0 0 2px">Nếu đồng ý, Ông/Bà vui lòng ký xác nhận bên dưới và phản hồi cho Công ty trước ngày <span style="background:#FDE68A;padding:0 3px">...../...../......</span>.</p>
61
- <p style="font-size:12.5px;line-height:1.45;color:#3F4C55;font-style:italic;margin:0 0 18px">If you agree, please sign below and reply to the Company by <span style="background:#FDE68A;padding:0 3px">...../...../......</span>.</p>
60
+ <h2 class="cs-avoid" style="font-size:13px;font-weight:800;color:var(--cs-color-brand-umber);margin:0 0 6px">XÁC NHẬN <span style="font-weight:400;font-size:11.5px;color:var(--cs-doc-slate);font-style:italic">Acceptance</span></h2>
61
+ <p style="font-size:14px;line-height:1.5;margin:0 0 2px">Nếu đồng ý, Ông/Bà vui lòng ký xác nhận bên dưới và phản hồi cho Công ty trước ngày <span style="background:var(--cs-doc-fill);padding:0 3px">...../...../......</span>.</p>
62
+ <p style="font-size:12.5px;line-height:1.45;color:var(--cs-doc-slate);font-style:italic;margin:0 0 18px">If you agree, please sign below and reply to the Company by <span style="background:var(--cs-doc-fill);padding:0 3px">...../...../......</span>.</p>
62
63
 
63
64
  <div class="cs-avoid" style="display:grid;grid-template-columns:1fr 1fr;gap:44px;margin-top:6px">
64
- <div style="text-align:center"><div style="font-weight:700;font-size:12.5px">ỨNG VIÊN</div><div style="font-size:11px;color:#3F4C55;font-style:italic">The Candidate (accepts the above terms)</div><div style="font-size:11px;margin-top:1px">(đồng ý các điều khoản trên)</div><div style="font-size:10.5px;color:#3F4C55;font-style:italic">(Sign, full name)</div><div style="height:64px"></div><div style="border-top:1px solid #1A1614;width:70%;margin:0 auto"></div></div>
65
- <div style="text-align:center"><div style="font-weight:700;font-size:12.5px">ĐẠI DIỆN CÔNG TY</div><div style="font-size:11px;color:#3F4C55;font-style:italic">For and on behalf of the Company</div><div style="font-size:11px;margin-top:1px">(Ký, ghi rõ họ tên)</div><div style="font-size:10.5px;color:#3F4C55;font-style:italic">(Sign, full name)</div><div style="height:64px"></div><div style="border-top:1px solid #1A1614;width:70%;margin:0 auto"></div></div>
65
+ <div style="text-align:center"><div style="font-weight:700;font-size:12.5px">ỨNG VIÊN</div><div style="font-size:11px;color:var(--cs-doc-slate);font-style:italic">The Candidate (accepts the above terms)</div><div style="font-size:11px;margin-top:1px">(đồng ý các điều khoản trên)</div><div style="font-size:10.5px;color:var(--cs-doc-slate);font-style:italic">(Sign, full name)</div><div style="height:64px"></div><div style="border-top:1px solid var(--cs-doc-ink);width:70%;margin:0 auto"></div></div>
66
+ <div style="text-align:center"><div style="font-weight:700;font-size:12.5px">ĐẠI DIỆN CÔNG TY</div><div style="font-size:11px;color:var(--cs-doc-slate);font-style:italic">For and on behalf of the Company</div><div style="font-size:11px;margin-top:1px">(Ký, ghi rõ họ tên)</div><div style="font-size:10.5px;color:var(--cs-doc-slate);font-style:italic">(Sign, full name)</div><div style="height:64px"></div><div style="border-top:1px solid var(--cs-doc-ink);width:70%;margin:0 auto"></div></div>
66
67
  </div>
67
68
 
68
- <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>
69
+ <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>
69
70
  </div>
70
71
  </div>
71
72
  </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() {
@@ -1,6 +1,7 @@
1
1
  <!DOCTYPE html>
2
- <html>
2
+ <html lang="en">
3
3
  <head>
4
+ <title>HR Suite · Danh mục hồ sơ & checklist nhận việc — Onboarding Checklist · 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,47 +14,47 @@
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>· Checklist nhận việc</span><span style="margin-left:auto;font-family:var(--cs-font-family-mono)">Số/No. <span style="background:#FDE68A;padding:0 3px">.....</span>/2026/CL-CYBERSKILL</span>
21
+ <b style="color:var(--cs-color-brand-umber)">CyberSkill</b><span>· Checklist nhận việc</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/CL-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>
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 style="font-size:10.5px;margin-top:4px">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></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>
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 style="font-size:10.5px;margin-top:4px">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></div></div>
25
26
  </div>
26
27
  <div class="cs-avoid" style="text-align:center;margin-bottom:16px">
27
28
  <h1 style="font-size:24px;font-weight:800;color:var(--cs-color-brand-umber);letter-spacing:-0.01em;margin:0 0 3px;line-height:1.25">DANH MỤC HỒ SƠ &amp; CHECKLIST NHẬN VIỆC</h1>
28
- <div style="font-size:14px;color:#3F4C55;font-style:italic">Onboarding &amp; Personnel File Checklist</div>
29
- <div style="font-size:12px;margin-top:8px">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:14px;color:var(--cs-doc-slate);font-style:italic">Onboarding &amp; Personnel File Checklist</div>
30
+ <div style="font-size:12px;margin-top:8px">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>
30
31
  <div style="color:var(--cs-accent);font-size:13px;letter-spacing:0.5em;margin-top:10px">◆ ◆ ◆</div>
31
32
  </div>
32
33
  <table class="cs-avoid" style="width:100%;border-collapse:collapse;font-size:12.5px;margin:0 0 18px">
33
34
  <tbody>
34
- <tr style="border-bottom:1px solid var(--cs-color-border-default)"><td style="padding:5px 10px;width:200px;vertical-align:top">Nhân sự<div style="color:#3F4C55;font-style:italic;font-size:11px">Employee</div></td><td style="padding:5px 10px"><span style="background:#FDE68A;padding:0 3px">..............................</span></td></tr>
35
- <tr style="border-bottom:1px solid var(--cs-color-border-default)"><td style="padding:5px 10px;vertical-align:top">Vị trí / Bộ phận<div style="color:#3F4C55;font-style:italic;font-size:11px">Position / Department</div></td><td style="padding:5px 10px"><span style="background:#FDE68A;padding:0 3px">..............................</span></td></tr>
36
- <tr><td style="padding:5px 10px;vertical-align:top">Ngày bắt đầu<div style="color:#3F4C55;font-style:italic;font-size:11px">Start date</div></td><td style="padding:5px 10px"><span style="background:#FDE68A;padding:0 3px">...../...../......</span></td></tr>
35
+ <tr style="border-bottom:1px solid var(--cs-color-border-default)"><td style="padding:5px 10px;width:200px;vertical-align:top">Nhân sự<div style="color:var(--cs-doc-slate);font-style:italic;font-size:11px">Employee</div></td><td style="padding:5px 10px"><span style="background:var(--cs-doc-fill);padding:0 3px">..............................</span></td></tr>
36
+ <tr style="border-bottom:1px solid var(--cs-color-border-default)"><td style="padding:5px 10px;vertical-align:top">Vị trí / Bộ phận<div style="color:var(--cs-doc-slate);font-style:italic;font-size:11px">Position / Department</div></td><td style="padding:5px 10px"><span style="background:var(--cs-doc-fill);padding:0 3px">..............................</span></td></tr>
37
+ <tr><td style="padding:5px 10px;vertical-align:top">Ngày bắt đầu<div style="color:var(--cs-doc-slate);font-style:italic;font-size:11px">Start date</div></td><td style="padding:5px 10px"><span style="background:var(--cs-doc-fill);padding:0 3px">...../...../......</span></td></tr>
37
38
  </tbody>
38
39
  </table>
39
40
 
40
41
  <sc-for list="{{ groups }}" as="g" hint-placeholder-count="3">
41
42
  <div class="cs-avoid" style="margin-bottom:16px">
42
- <h2 style="font-size:12.5px;font-weight:800;color:var(--cs-color-brand-umber);margin:0 0 8px;padding-bottom:3px;border-bottom:1px solid var(--cs-color-border-default)">{{ g.vi }} <span style="font-weight:400;font-size:11px;color:#3F4C55;font-style:italic">{{ g.en }}</span></h2>
43
+ <h2 style="font-size:12.5px;font-weight:800;color:var(--cs-color-brand-umber);margin:0 0 8px;padding-bottom:3px;border-bottom:1px solid var(--cs-color-border-default)">{{ g.vi }} <span style="font-weight:400;font-size:11px;color:var(--cs-doc-slate);font-style:italic">{{ g.en }}</span></h2>
43
44
  <div style="display:grid;grid-template-columns:1fr 1fr;gap:7px 24px">
44
45
  <sc-for list="{{ g.items }}" as="it" hint-placeholder-count="8">
45
- <div style="display:flex;gap:9px;align-items:flex-start"><span style="font-size:14px;line-height:1.3">☐</span><div><div style="font-size:13px;line-height:1.35">{{ it.vi }}</div><div style="font-size:11px;line-height:1.3;color:#3F4C55;font-style:italic">{{ it.en }}</div></div></div>
46
+ <div style="display:flex;gap:9px;align-items:flex-start"><span style="font-size:14px;line-height:1.3">☐</span><div><div style="font-size:13px;line-height:1.35">{{ it.vi }}</div><div style="font-size:11px;line-height:1.3;color:var(--cs-doc-slate);font-style:italic">{{ it.en }}</div></div></div>
46
47
  </sc-for>
47
48
  </div>
48
49
  </div>
49
50
  </sc-for>
50
51
 
51
52
  <div class="cs-avoid" style="display:grid;grid-template-columns:1fr 1fr;gap:44px;margin-top:14px">
52
- <div style="text-align:center"><div style="font-weight:700;font-size:12.5px">NHÂN SỰ</div><div style="font-size:11px;color:#3F4C55;font-style:italic">Employee</div><div style="font-size:10.5px;margin-top:1px">(Ký, ghi rõ họ tên)</div><div style="height:60px"></div><div style="border-top:1px solid #1A1614;width:70%;margin:0 auto"></div></div>
53
- <div style="text-align:center"><div style="font-weight:700;font-size:12.5px">BỘ PHẬN NHÂN SỰ</div><div style="font-size:11px;color:#3F4C55;font-style:italic">HR</div><div style="font-size:10.5px;margin-top:1px">(Ký, ghi rõ họ tên)</div><div style="height:60px"></div><div style="border-top:1px solid #1A1614;width:70%;margin:0 auto"></div></div>
53
+ <div style="text-align:center"><div style="font-weight:700;font-size:12.5px">NHÂN SỰ</div><div style="font-size:11px;color:var(--cs-doc-slate);font-style:italic">Employee</div><div style="font-size:10.5px;margin-top:1px">(Ký, ghi rõ họ tên)</div><div style="height:60px"></div><div style="border-top:1px solid var(--cs-doc-ink);width:70%;margin:0 auto"></div></div>
54
+ <div style="text-align:center"><div style="font-weight:700;font-size:12.5px">BỘ PHẬN NHÂN SỰ</div><div style="font-size:11px;color:var(--cs-doc-slate);font-style:italic">HR</div><div style="font-size:10.5px;margin-top:1px">(Ký, ghi rõ họ tên)</div><div style="height:60px"></div><div style="border-top:1px solid var(--cs-doc-ink);width:70%;margin:0 auto"></div></div>
54
55
  </div>
55
56
 
56
- <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>
57
+ <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>
57
58
  </div>
58
59
  </div>
59
60
  </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() {