@cyberskill/design 1.1.1 → 1.3.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/DESIGN.md +28 -5
- package/README.md +23 -22
- package/SKILL.md +7 -7
- package/THIRD-PARTY-NOTICES.md +35 -0
- package/VERSION +1 -1
- package/_ds_bundle.js +1495 -1733
- package/_ds_manifest.json +1 -1
- package/_esm/cs.mjs +18 -4
- package/_esm/react.d.ts +2 -0
- package/_esm/react.mjs +7 -1
- package/_vendor/NOTICE.md +16 -0
- package/_vendor/babel/README.md +7 -0
- package/_vendor/babel/babel.min.js +4 -0
- package/_vendor/react/README.md +3 -0
- package/_vendor/react/react-dom.production.min.js +1 -0
- package/_vendor/react/react.production.min.js +1 -0
- package/assets/aurora-hoa.webp +0 -0
- package/assets/aurora-kim.webp +0 -0
- package/assets/aurora-moc.webp +0 -0
- package/assets/aurora-tho.webp +0 -0
- package/assets/aurora-thuy.webp +0 -0
- package/base/a11y.css +18 -0
- package/base/ai.css +9 -4
- package/base/collections.css +18 -7
- package/base/components.css +16 -4
- package/base/controls.css +116 -66
- package/base/data.css +4 -4
- package/base/feedback.css +14 -2
- package/base/forms.css +10 -4
- package/base/glass.css +7 -1
- package/base/interaction.css +6 -2
- package/base/navigation.css +9 -3
- package/base/reset.css +7 -1
- package/base/responsive.css +38 -12
- package/base/shell.css +15 -3
- package/components/_i18n/i18n.js +41 -4
- package/components/_i18n/strings.js +89 -22
- package/components/ai/ChatMessage.d.ts +2 -0
- package/components/ai/ChatMessage.jsx +8 -4
- package/components/ai/ConfidenceMeter.d.ts +2 -0
- package/components/ai/ConfidenceMeter.jsx +8 -6
- package/components/ai/HumanReviewGate.d.ts +2 -0
- package/components/ai/PromptInput.d.ts +2 -0
- package/components/ai/TypingIndicator.d.ts +2 -0
- package/components/ai/ai-conversation.card.html +3 -3
- package/components/ai/ai-lumi.card.html +3 -3
- package/components/ai/ai.card.html +3 -3
- package/components/brand/brand.card.html +3 -3
- package/components/button/buttons.card.html +3 -3
- package/components/data/Image.jsx +18 -2
- package/components/data/Sortable.d.ts +5 -1
- package/components/data/Sortable.jsx +42 -9
- package/components/data/Sortable.prompt.md +4 -2
- package/components/data/Terminal.jsx +3 -2
- package/components/data/Tooltip.d.ts +2 -0
- package/components/data/Tooltip.jsx +6 -3
- package/components/data/Tree.d.ts +2 -1
- package/components/data/Tree.jsx +137 -16
- package/components/data/Tree.prompt.md +1 -1
- package/components/data/Watermark.jsx +11 -3
- package/components/data/collections.card.html +3 -3
- package/components/data/data.card.html +3 -3
- package/components/datatable/DataGrid.jsx +10 -1
- package/components/datatable/DataTable.d.ts +24 -1
- package/components/datatable/DataTable.jsx +78 -5
- package/components/datatable/DataTable.prompt.md +2 -1
- package/components/datatable/datatable.card.html +20 -16
- package/components/dialog/Dialog.jsx +13 -45
- package/components/dialog/dialog.card.html +3 -3
- package/components/feedback/Alert.d.ts +2 -0
- package/components/feedback/Alert.jsx +8 -2
- package/components/feedback/EmptyState.d.ts +2 -0
- package/components/feedback/EmptyState.jsx +6 -3
- package/components/feedback/ProgressBar.d.ts +2 -0
- package/components/feedback/ProgressBar.jsx +9 -4
- package/components/feedback/Toast.jsx +15 -1
- package/components/feedback/Toast.prompt.md +2 -1
- package/components/feedback/feedback-2.card.html +3 -3
- package/components/feedback/feedback.card.html +3 -3
- package/components/forms/Cascader.jsx +76 -8
- package/components/forms/Editor.jsx +37 -2
- package/components/forms/FileUpload.d.ts +2 -0
- package/components/forms/FileUpload.jsx +22 -8
- package/components/forms/Form.d.ts +3 -1
- package/components/forms/Form.jsx +9 -1
- package/components/forms/Form.prompt.md +1 -1
- package/components/forms/Mentions.d.ts +1 -1
- package/components/forms/Mentions.jsx +59 -7
- package/components/forms/Mentions.prompt.md +3 -1
- package/components/forms/Rating.d.ts +3 -2
- package/components/forms/Rating.jsx +34 -3
- package/components/forms/Rating.prompt.md +1 -1
- package/components/forms/Select.d.ts +2 -0
- package/components/forms/Select.jsx +6 -2
- package/components/forms/Slider.d.ts +2 -0
- package/components/forms/Slider.jsx +5 -2
- package/components/forms/Switch.d.ts +2 -0
- package/components/forms/Switch.jsx +15 -3
- package/components/forms/TimePicker.jsx +3 -1
- package/components/forms/Toggle.d.ts +2 -0
- package/components/forms/Toggle.jsx +14 -2
- package/components/forms/forms-2.card.html +3 -3
- package/components/forms/forms.card.html +3 -3
- package/components/icon/Icon.d.ts +1 -1
- package/components/icon/Icon.jsx +1 -0
- package/components/icon/Icon.prompt.md +1 -1
- package/components/icon/icon.card.html +3 -3
- package/components/logo/logo.card.html +3 -3
- package/components/navigation/CommandPalette.d.ts +2 -0
- package/components/navigation/CommandPalette.jsx +22 -7
- package/components/navigation/Menu.d.ts +2 -0
- package/components/navigation/Menu.jsx +60 -6
- package/components/navigation/Steps.d.ts +2 -0
- package/components/navigation/Steps.jsx +6 -3
- package/components/navigation/Tabs.d.ts +2 -0
- package/components/navigation/Tabs.jsx +6 -3
- package/components/navigation/Toolbar.d.ts +3 -2
- package/components/navigation/Toolbar.jsx +119 -12
- package/components/navigation/Toolbar.prompt.md +1 -1
- package/components/navigation/navigation.card.html +3 -3
- package/components/navigation/shell.card.html +3 -3
- package/components/overlays/AlertDialog.jsx +19 -49
- package/components/overlays/ContextMenu.d.ts +2 -0
- package/components/overlays/ContextMenu.jsx +6 -3
- package/components/overlays/Drawer.d.ts +2 -0
- package/components/overlays/Drawer.jsx +24 -20
- package/components/overlays/OverlayManager.d.ts +40 -0
- package/components/overlays/OverlayManager.jsx +214 -0
- package/components/overlays/OverlayManager.prompt.md +12 -0
- package/components/overlays/Tour.jsx +14 -7
- package/components/overlays/alertdialog.card.html +3 -3
- package/components/overlays/overlays.card.html +3 -3
- package/components/textfield/textfield.card.html +3 -3
- package/dist/styles.min.css +2252 -0
- package/docs/benchmark-rubric.md +1 -1
- package/docs/ci-cd.md +19 -12
- package/docs/consumer-grant.md +3 -0
- package/docs/consuming.md +13 -13
- package/docs/contrast-report.md +79 -1
- package/docs/conventions.md +21 -8
- package/docs/decisions.md +45 -7
- package/docs/deploy.md +17 -6
- package/docs/design-styles.md +2 -2
- package/docs/quality-gates.md +35 -15
- package/docs/release-notes.md +2 -2
- package/docs/release-runbook.md +78 -0
- package/docs/sync.md +2 -2
- package/docs/vi/benchmark-rubric.md +1 -1
- package/docs/vi/ci-cd.md +17 -12
- package/docs/vi/consumer-grant.md +3 -0
- package/docs/vi/consuming.md +13 -13
- package/docs/vi/contrast-report.md +79 -1
- package/docs/vi/conventions.md +20 -7
- package/docs/vi/decisions.md +43 -6
- package/docs/vi/deploy.md +17 -6
- package/docs/vi/quality-gates.md +34 -15
- package/docs/vi/release-notes.md +2 -2
- package/docs/vi/release-runbook.md +78 -0
- package/docs/vi/sync.md +2 -2
- package/docs/viewer.html +2 -2
- package/fonts/OFL.txt +98 -0
- package/guidelines/atomic-view.html +13 -9
- package/guidelines/brand-imagery.html +1 -1
- package/guidelines/elements-variants.html +5 -5
- package/guidelines/spacing-breakpoints.html +2 -1
- package/guidelines/surfaces-glass.html +1 -1
- package/llms.txt +5 -5
- package/package.json +38 -10
- package/templates/_ds-base.canonical.js +55 -0
- package/templates/ai-cluster-demo.html +2 -2
- package/templates/app-shell/AppShell.dc.html +7 -5
- package/templates/app-shell/content-schema.json +7 -0
- package/templates/app-shell/ds-base.js +33 -1
- package/templates/app-shell/support.js +13 -20
- package/templates/article/Article.dc.html +7 -3
- package/templates/article/content-schema.json +7 -0
- package/templates/article/ds-base.js +33 -1
- package/templates/article/support.js +13 -20
- package/templates/auth/Auth.dc.html +33 -12
- package/templates/auth/content-schema.json +37 -0
- package/templates/auth/ds-base.js +33 -1
- package/templates/auth/support.js +13 -20
- package/templates/bod-deck/BodDeck.dc.html +11 -10
- package/templates/bod-deck/ds-base.js +33 -1
- package/templates/bod-deck/support.js +13 -20
- package/templates/bod-investor-update/BodInvestorUpdate.dc.html +4 -3
- package/templates/bod-investor-update/ds-base.js +33 -1
- package/templates/bod-investor-update/support.js +13 -20
- package/templates/bod-memo/BodMemo.dc.html +6 -5
- package/templates/bod-memo/ds-base.js +33 -1
- package/templates/bod-memo/support.js +13 -20
- package/templates/bod-minutes/BodMinutes.dc.html +2 -1
- package/templates/bod-minutes/ds-base.js +33 -1
- package/templates/bod-minutes/support.js +13 -20
- package/templates/bod-report/BodReport.dc.html +3 -2
- package/templates/bod-report/ds-base.js +33 -1
- package/templates/bod-report/support.js +13 -20
- package/templates/bod-resolution/BodResolution.dc.html +5 -4
- package/templates/bod-resolution/ds-base.js +33 -1
- package/templates/bod-resolution/support.js +13 -20
- package/templates/culture-event-invite/CultureEventInvite.dc.html +3 -2
- package/templates/culture-event-invite/ds-base.js +33 -1
- package/templates/culture-event-invite/support.js +13 -20
- package/templates/dashboard/Dashboard.dc.html +10 -6
- package/templates/dashboard/content-schema.json +7 -0
- package/templates/dashboard/ds-base.js +33 -1
- package/templates/dashboard/support.js +13 -20
- package/templates/delivery-change-note/DeliveryChangeNote.dc.html +4 -3
- package/templates/delivery-change-note/ds-base.js +33 -1
- package/templates/delivery-change-note/support.js +13 -20
- package/templates/delivery-kickoff/DeliveryKickoff.dc.html +3 -2
- package/templates/delivery-kickoff/ds-base.js +33 -1
- package/templates/delivery-kickoff/support.js +13 -20
- package/templates/delivery-qbr-deck/DeliveryQbrDeck.dc.html +6 -5
- package/templates/delivery-qbr-deck/ds-base.js +33 -1
- package/templates/delivery-qbr-deck/support.js +13 -20
- package/templates/delivery-runbook/DeliveryRunbook.dc.html +5 -4
- package/templates/delivery-runbook/ds-base.js +33 -1
- package/templates/delivery-runbook/support.js +13 -20
- package/templates/delivery-status-email/DeliveryStatusEmail.dc.html +3 -2
- package/templates/delivery-status-email/ds-base.js +33 -1
- package/templates/delivery-status-email/support.js +13 -20
- package/templates/doc-style-guide/DocStyleGuide.dc.html +67 -64
- package/templates/doc-style-guide/ds-base.js +33 -1
- package/templates/doc-style-guide/support.js +13 -20
- package/templates/doc-suite-index/DocSuiteIndex.dc.html +46 -45
- package/templates/doc-suite-index/ds-base.js +33 -1
- package/templates/doc-suite-index/support.js +13 -20
- package/templates/doc-templates/DocTemplates.dc.html +42 -41
- package/templates/doc-templates/ds-base.js +33 -1
- package/templates/doc-templates/support.js +13 -20
- package/templates/email/Email.dc.html +3 -2
- package/templates/email/ds-base.js +33 -1
- package/templates/email/support.js +13 -20
- package/templates/email-safe/email-announcement.html +2 -2
- package/templates/email-safe/email-dunning.html +2 -2
- package/templates/email-safe/email-investor.html +2 -2
- package/templates/email-safe/email-launch.html +2 -2
- package/templates/email-safe/email-newsletter.html +2 -2
- package/templates/email-safe/email-status.html +2 -2
- package/templates/email-safe/email-transactional.html +2 -2
- package/templates/finance-dunning-email/FinanceDunningEmail.dc.html +6 -5
- package/templates/finance-dunning-email/ds-base.js +33 -1
- package/templates/finance-dunning-email/support.js +13 -20
- package/templates/finance-expense-report/FinanceExpenseReport.dc.html +4 -3
- package/templates/finance-expense-report/ds-base.js +33 -1
- package/templates/finance-expense-report/support.js +13 -20
- package/templates/finance-invoice/FinanceInvoice.dc.html +6 -5
- package/templates/finance-invoice/ds-base.js +33 -1
- package/templates/finance-invoice/support.js +13 -20
- package/templates/finance-quote/FinanceQuote.dc.html +6 -5
- package/templates/finance-quote/ds-base.js +33 -1
- package/templates/finance-quote/support.js +13 -20
- package/templates/hr-announcement/HrAnnouncement.dc.html +5 -4
- package/templates/hr-announcement/ds-base.js +33 -1
- package/templates/hr-announcement/support.js +13 -20
- package/templates/hr-interview-kit/HrInterviewKit.dc.html +5 -4
- package/templates/hr-interview-kit/ds-base.js +33 -1
- package/templates/hr-interview-kit/support.js +13 -20
- package/templates/hr-offboarding/HrOffboarding.dc.html +2 -1
- package/templates/hr-offboarding/ds-base.js +33 -1
- package/templates/hr-offboarding/support.js +13 -20
- package/templates/hr-performance-review/HrPerformanceReview.dc.html +2 -1
- package/templates/hr-performance-review/ds-base.js +33 -1
- package/templates/hr-performance-review/support.js +13 -20
- package/templates/hr-pip/HrPip.dc.html +2 -1
- package/templates/hr-pip/ds-base.js +33 -1
- package/templates/hr-pip/support.js +13 -20
- package/templates/kitchen-sink.html +9 -4
- package/templates/legal-msa/LegalMsa.dc.html +2 -1
- package/templates/legal-msa/ds-base.js +33 -1
- package/templates/legal-msa/support.js +13 -20
- package/templates/legal-sow/LegalSow.dc.html +2 -1
- package/templates/legal-sow/ds-base.js +33 -1
- package/templates/legal-sow/support.js +13 -20
- package/templates/marketing-campaign-brief/MarketingCampaignBrief.dc.html +3 -2
- package/templates/marketing-campaign-brief/ds-base.js +33 -1
- package/templates/marketing-campaign-brief/support.js +13 -20
- package/templates/marketing-case-study/MarketingCaseStudy.dc.html +6 -5
- package/templates/marketing-case-study/ds-base.js +33 -1
- package/templates/marketing-case-study/support.js +13 -20
- package/templates/marketing-launch/MarketingLaunch.dc.html +6 -5
- package/templates/marketing-launch/ds-base.js +33 -1
- package/templates/marketing-launch/support.js +13 -20
- package/templates/marketing-newsletter/MarketingNewsletter.dc.html +13 -12
- package/templates/marketing-newsletter/ds-base.js +33 -1
- package/templates/marketing-newsletter/support.js +13 -20
- package/templates/marketing-page/MarketingPage.dc.html +19 -14
- package/templates/marketing-page/content-schema.json +1 -0
- package/templates/marketing-page/ds-base.js +33 -1
- package/templates/marketing-page/support.js +13 -20
- package/templates/marketing-press-release/MarketingPressRelease.dc.html +2 -1
- package/templates/marketing-press-release/ds-base.js +33 -1
- package/templates/marketing-press-release/support.js +13 -20
- package/templates/marketing-social-kit/MarketingSocialKit.dc.html +5 -4
- package/templates/marketing-social-kit/ds-base.js +33 -1
- package/templates/marketing-social-kit/support.js +13 -20
- package/templates/sales-one-pager/SalesOnePager.dc.html +5 -4
- package/templates/sales-one-pager/ds-base.js +33 -1
- package/templates/sales-one-pager/support.js +13 -20
- package/templates/sales-proposal-deck/SalesProposalDeck.dc.html +7 -6
- package/templates/sales-proposal-deck/ds-base.js +33 -1
- package/templates/sales-proposal-deck/support.js +13 -20
- package/templates/settings/Settings.dc.html +7 -3
- package/templates/settings/content-schema.json +7 -0
- package/templates/settings/ds-base.js +33 -1
- package/templates/settings/support.js +13 -20
- package/templates/slide-deck/SlideDeck.dc.html +5 -4
- package/templates/slide-deck/ds-base.js +33 -1
- package/templates/slide-deck/support.js +13 -20
- package/templates/team-meeting-agenda/TeamMeetingAgenda.dc.html +2 -1
- package/templates/team-meeting-agenda/ds-base.js +33 -1
- package/templates/team-meeting-agenda/support.js +13 -20
- package/templates/tech-incident-report/TechIncidentReport.dc.html +3 -2
- package/templates/tech-incident-report/ds-base.js +33 -1
- package/templates/tech-incident-report/support.js +13 -20
- package/templates/tech-release-notes/TechReleaseNotes.dc.html +6 -5
- package/templates/tech-release-notes/ds-base.js +33 -1
- package/templates/tech-release-notes/support.js +13 -20
- package/templates/tech-retro/TechRetro.dc.html +4 -3
- package/templates/tech-retro/ds-base.js +33 -1
- package/templates/tech-retro/support.js +13 -20
- package/templates/tech-rfc/TechRfc.dc.html +3 -2
- package/templates/tech-rfc/ds-base.js +33 -1
- package/templates/tech-rfc/support.js +13 -20
- package/templates/vn-appointment-transfer/VnAppointmentTransfer.dc.html +36 -35
- package/templates/vn-appointment-transfer/ds-base.js +33 -1
- package/templates/vn-appointment-transfer/support.js +13 -20
- package/templates/vn-certificate-of-employment/VnCertificateOfEmployment.dc.html +27 -26
- package/templates/vn-certificate-of-employment/ds-base.js +33 -1
- package/templates/vn-certificate-of-employment/support.js +13 -20
- package/templates/vn-code-of-conduct/VnCodeOfConduct.dc.html +44 -43
- package/templates/vn-code-of-conduct/ds-base.js +33 -1
- package/templates/vn-code-of-conduct/support.js +13 -20
- package/templates/vn-compensation-regulation/VnCompensationRegulation.dc.html +53 -52
- package/templates/vn-compensation-regulation/ds-base.js +33 -1
- package/templates/vn-compensation-regulation/support.js +13 -20
- package/templates/vn-contract-amendment/VnContractAmendment.dc.html +41 -40
- package/templates/vn-contract-amendment/ds-base.js +33 -1
- package/templates/vn-contract-amendment/support.js +13 -20
- package/templates/vn-contractor-agreement/VnContractorAgreement.dc.html +50 -49
- package/templates/vn-contractor-agreement/ds-base.js +33 -1
- package/templates/vn-contractor-agreement/support.js +13 -20
- package/templates/vn-data-protection-policy/VnDataProtectionPolicy.dc.html +54 -53
- package/templates/vn-data-protection-policy/ds-base.js +33 -1
- package/templates/vn-data-protection-policy/support.js +13 -20
- package/templates/vn-disciplinary-case-file/VnDisciplinaryCaseFile.dc.html +72 -71
- package/templates/vn-disciplinary-case-file/ds-base.js +33 -1
- package/templates/vn-disciplinary-case-file/support.js +13 -20
- package/templates/vn-disciplinary-schedule/VnDisciplinarySchedule.dc.html +21 -20
- package/templates/vn-disciplinary-schedule/ds-base.js +33 -1
- package/templates/vn-disciplinary-schedule/support.js +13 -20
- package/templates/vn-employee-request/VnEmployeeRequest.dc.html +54 -53
- package/templates/vn-employee-request/ds-base.js +33 -1
- package/templates/vn-employee-request/support.js +13 -20
- package/templates/vn-exit-handover/VnExitHandover.dc.html +122 -121
- package/templates/vn-exit-handover/ds-base.js +33 -1
- package/templates/vn-exit-handover/support.js +13 -20
- package/templates/vn-foreign-employee-pack/VnForeignEmployeePack.dc.html +31 -30
- package/templates/vn-foreign-employee-pack/ds-base.js +33 -1
- package/templates/vn-foreign-employee-pack/support.js +13 -20
- package/templates/vn-grassroots-democracy/VnGrassrootsDemocracy.dc.html +54 -53
- package/templates/vn-grassroots-democracy/ds-base.js +33 -1
- package/templates/vn-grassroots-democracy/support.js +13 -20
- package/templates/vn-infosec-policy/VnInfosecPolicy.dc.html +50 -49
- package/templates/vn-infosec-policy/ds-base.js +33 -1
- package/templates/vn-infosec-policy/support.js +13 -20
- package/templates/vn-internal-labor-regulations/VnInternalLaborRegulations.dc.html +84 -83
- package/templates/vn-internal-labor-regulations/ds-base.js +33 -1
- package/templates/vn-internal-labor-regulations/support.js +13 -20
- package/templates/vn-internship-agreement/VnInternshipAgreement.dc.html +44 -43
- package/templates/vn-internship-agreement/ds-base.js +33 -1
- package/templates/vn-internship-agreement/support.js +13 -20
- package/templates/vn-job-description/VnJobDescription.dc.html +28 -27
- package/templates/vn-job-description/ds-base.js +33 -1
- package/templates/vn-job-description/support.js +13 -20
- package/templates/vn-labor-contract/VnLaborContract.dc.html +109 -108
- package/templates/vn-labor-contract/ds-base.js +33 -1
- package/templates/vn-labor-contract/support.js +13 -20
- package/templates/vn-labour-management-book/VnLabourManagementBook.dc.html +32 -31
- package/templates/vn-labour-management-book/ds-base.js +33 -1
- package/templates/vn-labour-management-book/support.js +13 -20
- package/templates/vn-mutual-nda/VnMutualNda.dc.html +45 -44
- package/templates/vn-mutual-nda/ds-base.js +33 -1
- package/templates/vn-mutual-nda/support.js +13 -20
- package/templates/vn-ndnca-ip/VnNdncaIp.dc.html +73 -72
- package/templates/vn-ndnca-ip/ds-base.js +33 -1
- package/templates/vn-ndnca-ip/support.js +13 -20
- package/templates/vn-offer-letter/VnOfferLetter.dc.html +32 -31
- package/templates/vn-offer-letter/ds-base.js +33 -1
- package/templates/vn-offer-letter/support.js +13 -20
- package/templates/vn-onboarding-checklist/VnOnboardingChecklist.dc.html +16 -15
- package/templates/vn-onboarding-checklist/ds-base.js +33 -1
- package/templates/vn-onboarding-checklist/support.js +13 -20
- package/templates/vn-pdpl-consent/VnPdplConsent.dc.html +43 -42
- package/templates/vn-pdpl-consent/ds-base.js +33 -1
- package/templates/vn-pdpl-consent/support.js +13 -20
- package/templates/vn-performance-evaluation-regulation/VnPerformanceEvaluationRegulation.dc.html +65 -64
- package/templates/vn-performance-evaluation-regulation/ds-base.js +33 -1
- package/templates/vn-performance-evaluation-regulation/support.js +13 -20
- package/templates/vn-performance-review-form/VnPerformanceReviewForm.dc.html +49 -48
- package/templates/vn-performance-review-form/ds-base.js +33 -1
- package/templates/vn-performance-review-form/support.js +13 -20
- package/templates/vn-phantom-stock/VnPhantomStock.dc.html +41 -40
- package/templates/vn-phantom-stock/ds-base.js +33 -1
- package/templates/vn-phantom-stock/support.js +13 -20
- package/templates/vn-probation-contract/VnProbationContract.dc.html +56 -55
- package/templates/vn-probation-contract/ds-base.js +33 -1
- package/templates/vn-probation-contract/support.js +13 -20
- package/templates/vn-receipt-acknowledgement/VnReceiptAcknowledgement.dc.html +28 -27
- package/templates/vn-receipt-acknowledgement/ds-base.js +33 -1
- package/templates/vn-receipt-acknowledgement/support.js +13 -20
- package/templates/vn-remote-work-policy/VnRemoteWorkPolicy.dc.html +44 -43
- package/templates/vn-remote-work-policy/ds-base.js +33 -1
- package/templates/vn-remote-work-policy/support.js +13 -20
- package/templates/vn-resignation-letter/VnResignationLetter.dc.html +20 -19
- package/templates/vn-resignation-letter/ds-base.js +33 -1
- package/templates/vn-resignation-letter/support.js +13 -20
- package/templates/vn-salary-scale/VnSalaryScale.dc.html +39 -38
- package/templates/vn-salary-scale/ds-base.js +33 -1
- package/templates/vn-salary-scale/support.js +13 -20
- package/templates/vn-sow-appendix/VnSowAppendix.dc.html +21 -20
- package/templates/vn-sow-appendix/ds-base.js +33 -1
- package/templates/vn-sow-appendix/support.js +13 -20
- package/templates/vn-termination-decision/VnTerminationDecision.dc.html +25 -24
- package/templates/vn-termination-decision/ds-base.js +33 -1
- package/templates/vn-termination-decision/support.js +13 -20
- package/templates/vn-total-rewards-appendix/VnTotalRewardsAppendix.dc.html +63 -62
- package/templates/vn-total-rewards-appendix/ds-base.js +33 -1
- package/templates/vn-total-rewards-appendix/support.js +13 -20
- package/templates/vn-training-commitment/VnTrainingCommitment.dc.html +39 -38
- package/templates/vn-training-commitment/ds-base.js +33 -1
- package/templates/vn-training-commitment/support.js +13 -20
- package/templates/vn-travel-expense-policy/VnTravelExpensePolicy.dc.html +50 -49
- package/templates/vn-travel-expense-policy/ds-base.js +33 -1
- package/templates/vn-travel-expense-policy/support.js +13 -20
- package/tokens/colors.css +19 -1
- package/tokens/component-tokens.css +1 -0
- package/tokens/element-seeds.json +2 -2
- package/tokens/elements.css +228 -21
- package/tokens/elevation.css +8 -2
- package/tokens/native/CSTokens.kt +37 -2
- package/tokens/native/CSTokens.swift +37 -2
- package/tokens/native/cs_tokens.dart +37 -2
- package/tokens/provenance.json +12 -12
- package/tokens/spacing.css +4 -1
- package/tokens/tokens.dtcg.json +129 -16
- package/tokens/tokens.js +59 -18
- package/tokens/tokens.json +58 -17
- package/tokens/typography.css +2 -0
- package/ui_kits/deck/index.html +4 -0
- package/ui_kits/status-hub/StatusHub.jsx +30 -4
- package/ui_kits/status-hub/index.html +3 -3
- package/ui_kits/status-hub/login.html +55 -9
- package/ui_kits/status-hub/project.html +4 -0
- package/ui_kits/status-hub/settings.html +35 -13
- package/ui_kits/status-hub/status.css +5 -1
- package/ui_kits/website/Website.jsx +25 -3
- package/ui_kits/website/careers.html +5 -1
- package/ui_kits/website/chat.html +5 -3
- package/ui_kits/website/index.html +3 -3
- package/ui_kits/website/site.css +3 -3
- package/ui_kits/website/work.html +5 -1
- package/assets/aurora-hoa.png +0 -0
- package/assets/aurora-kim.png +0 -0
- package/assets/aurora-moc.png +0 -0
- package/assets/aurora-thuy.png +0 -0
- package/docs/status/assets/favicon.svg +0 -5
- package/docs/status/assets/status-legacy.css +0 -399
- package/docs/status/assets/status-legacy.js +0 -505
- package/docs/status/assets/status.css +0 -644
- package/docs/status/assets/status.js +0 -1308
- package/docs/status/data/status-feed.json +0 -1
- package/docs/status/data/task/TASK-REL-001.js +0 -1
- package/docs/status/data/task/TASK-REL-002.js +0 -1
- package/docs/status/index.html +0 -42
- package/docs/status/roadmap.html +0 -4
- package/docs/status/status-legacy.html +0 -117
- package/docs/tasks/BACKLOG.md +0 -26
- package/docs/tasks/release/TASK-REL-001-launch-1-1-0/spec.md +0 -55
- package/docs/tasks/release/TASK-REL-002-republish-1-1-1/spec.md +0 -54
|
@@ -1070,16 +1070,15 @@
|
|
|
1070
1070
|
}
|
|
1071
1071
|
|
|
1072
1072
|
// src/cdn.ts
|
|
1073
|
-
var
|
|
1074
|
-
var
|
|
1075
|
-
var
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
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[
|
|
1082
|
-
return typeof v === "string" && v ?
|
|
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
|
|
1108
|
+
const src = localScriptFor(BABEL_LOCAL);
|
|
1110
1109
|
babelLoading = new Promise((res, rej) => {
|
|
1111
1110
|
const s = document.createElement("script");
|
|
1112
|
-
s.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(
|
|
1775
|
-
loadScript(
|
|
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>Article · 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>
|
|
@@ -12,6 +13,8 @@
|
|
|
12
13
|
<script src="./ds-base.js"></script>
|
|
13
14
|
</helmet>
|
|
14
15
|
<div data-theme="{{ rootTheme }}" lang="{{ langAttr }}" data-cs-element="{{ elAttr }}" data-cs-variant="{{ vaAttr }}" style="font-family:var(--cs-font-family-ui);color:var(--cs-color-text-primary);background:var(--cs-color-surface-page);min-height:100vh">
|
|
16
|
+
<a class="cs-skip" href="#main" style="position:absolute;left:-999px;top:auto;width:1px;height:1px;overflow:hidden">{{ skipLabel }}</a>
|
|
17
|
+
<main id="main">
|
|
15
18
|
<article style="max-width:720px;margin:0 auto;padding:56px 28px 80px">
|
|
16
19
|
<div style="font-size:12px;font-weight:700;text-transform:uppercase;letter-spacing:0.12em;color:var(--cs-color-text-accent)">{{ eyebrow }}</div>
|
|
17
20
|
<h1 style="font-size:clamp(32px,5vw,46px);font-weight:800;letter-spacing:-0.02em;line-height:1.14;margin:12px 0 16px">{{ h1 }}</h1>
|
|
@@ -32,6 +35,7 @@
|
|
|
32
35
|
</div>
|
|
33
36
|
<p style="font-size:17px;line-height:1.7;margin:0 0 18px">{{ p3 }}</p>
|
|
34
37
|
</article>
|
|
38
|
+
</main>
|
|
35
39
|
</div>
|
|
36
40
|
</x-dc>
|
|
37
41
|
<script type="text/x-dc" data-dc-script data-props="{
|
|
@@ -45,14 +49,14 @@ class Component extends DCLogic {
|
|
|
45
49
|
const [elAttr, vaAttr] = EL[this.props.element] || EL["Thổ · studio"];
|
|
46
50
|
const vn = this.props.language === "Tiếng Việt";
|
|
47
51
|
const code = '<div class="cs-glass-card">\n <h3>Design System v1.6</h3>\n</div>';
|
|
48
|
-
const en = {
|
|
52
|
+
const en = { skipLabel:"Skip to content",
|
|
49
53
|
eyebrow:"Engineering · Design systems", h1:"Liquid Glass, now bound to components", meta:"18 Jul 2026 · 6 min read", badge:"New", authorTeam:"Platform",
|
|
50
54
|
lede:"Five glass materials over the immutable Umber and Ochre anchors — and now they are one class away on any surface. Here's how the bindings work, and when to reach for each.",
|
|
51
55
|
p1:"Liquid Glass is CyberSkill's default surface treatment: translucent, refractive layers that let warm gold light show through. The material scalars live in tokens; this release wires them to real components so a card, a nav, or a modal can opt in with a single class.",
|
|
52
56
|
h2:"When to reach for glass", p2:"Keep dense content on solid surfaces. Reserve glass for nav, cards over imagery, and modals — always after an APCA check against the backdrop.",
|
|
53
57
|
alertTitle:"Rule of thumb", alertBody:"If text sits directly on a busy photo, step up one glass tier or drop to a solid surface.",
|
|
54
58
|
p3:"That's the whole surface. Everything paints from the same anchors — warm, honest, and Vietnamese-first by default."};
|
|
55
|
-
const vi = {
|
|
59
|
+
const vi = { skipLabel:"Bỏ qua nội dung",
|
|
56
60
|
eyebrow:"Kỹ thuật · Design system", h1:"Liquid Glass, nay gắn vào component", meta:"18/07/2026 · đọc 6 phút", badge:"Mới", authorTeam:"Nền tảng",
|
|
57
61
|
lede:"Năm vật liệu kính trên hai màu neo bất biến Umber và Ochre — và giờ chỉ cách một class trên mọi bề mặt. Đây là cách các liên kết hoạt động, và khi nào nên dùng từng loại.",
|
|
58
62
|
p1:"Liquid Glass là lớp bề mặt mặc định của CyberSkill: những lớp mờ, khúc xạ, để ánh vàng ấm hiện qua. Hệ số vật liệu nằm trong token; bản phát hành này gắn chúng vào component thật, để một card, một nav hay một modal có thể bật lên chỉ bằng một class.",
|
|
@@ -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
|
|
1074
|
-
var
|
|
1075
|
-
var
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
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[
|
|
1082
|
-
return typeof v === "string" && v ?
|
|
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
|
|
1108
|
+
const src = localScriptFor(BABEL_LOCAL);
|
|
1110
1109
|
babelLoading = new Promise((res, rej) => {
|
|
1111
1110
|
const s = document.createElement("script");
|
|
1112
|
-
s.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(
|
|
1775
|
-
loadScript(
|
|
1767
|
+
loadScript(localScriptFor(REACT_LOCAL)),
|
|
1768
|
+
loadScript(localScriptFor(REACT_DOM_LOCAL))
|
|
1776
1769
|
]).then(() => void 0);
|
|
1777
1770
|
}
|
|
1778
1771
|
function init() {
|
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
<!DOCTYPE html>
|
|
2
|
-
<html>
|
|
2
|
+
<html lang="en">
|
|
3
3
|
<head>
|
|
4
|
+
<title>Sign in · 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>
|
|
7
8
|
</head>
|
|
8
9
|
<body>
|
|
9
10
|
<x-dc>
|
|
10
|
-
<!-- @template name="Sign in" description="CyberSkill split sign-in — umber brand panel + form built from TextField, Switch, and
|
|
11
|
+
<!-- @template name="Sign in" description="CyberSkill split sign-in — umber brand panel + form built from TextField, Switch, Button, and Alert. formState tweak: default | loading | error | invalid. Bilingual (English · Tiếng Việt)." -->
|
|
11
12
|
<helmet>
|
|
12
13
|
<script src="./ds-base.js"></script>
|
|
13
14
|
</helmet>
|
|
14
15
|
<style>
|
|
15
16
|
.cs-auth-shell{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);min-height:100vh;font-family:var(--cs-font-family-ui);color:var(--cs-color-text-primary);background:var(--cs-color-surface-page)}
|
|
16
|
-
.cs-auth-brand{position:relative;overflow:hidden;background:var(--cs-
|
|
17
|
+
.cs-auth-brand{position:relative;overflow:hidden;background:var(--cs-color-brand-umber);color:#FFFDF8;padding:56px 60px;display:flex;flex-direction:column;min-width:0}
|
|
17
18
|
.cs-auth-form{display:grid;place-items:center;padding:40px 24px;min-width:0}
|
|
18
19
|
.cs-auth-form-inner{width:min(400px,100%);max-width:100%;box-sizing:border-box}
|
|
19
20
|
@media (max-width:820px){
|
|
@@ -24,6 +25,8 @@
|
|
|
24
25
|
}
|
|
25
26
|
</style>
|
|
26
27
|
<div class="cs-auth-shell" data-theme="{{ rootTheme }}" lang="{{ langAttr }}" data-cs-element="{{ elAttr }}" data-cs-variant="{{ vaAttr }}">
|
|
28
|
+
<a class="cs-skip" href="#main" style="position:absolute;left:-999px;top:auto;width:1px;height:1px;overflow:hidden">{{ skipLabel }}</a>
|
|
29
|
+
<main id="main">
|
|
27
30
|
<sc-if value="{{ showBrand }}" hint-placeholder-val="{{ true }}">
|
|
28
31
|
<div class="cs-auth-brand">
|
|
29
32
|
<div class="cs-aurora-wash" style="position:absolute;inset:0;opacity:0.4"></div>
|
|
@@ -31,7 +34,7 @@
|
|
|
31
34
|
<div style="position:relative;z-index:1;display:flex;align-items:center;gap:12px;font-weight:800;font-size:20px">
|
|
32
35
|
<x-import component-from-global-scope="CyberSkillDS.Logo" size="40" hint-size="40px,40px"></x-import>CyberSkill
|
|
33
36
|
</div>
|
|
34
|
-
<
|
|
37
|
+
<p style="position:relative;z-index:1;font-size:40px;font-weight:800;letter-spacing:-0.02em;line-height:1.08;color:var(--cs-accent-bright);margin:auto 0 8px">{{ brandH }}</p>
|
|
35
38
|
<p style="position:relative;z-index:1;font-size:17px;opacity:0.9;margin:0;max-width:420px">{{ brandP }}</p>
|
|
36
39
|
</div>
|
|
37
40
|
</sc-if>
|
|
@@ -40,31 +43,49 @@
|
|
|
40
43
|
<h1 style="font-size:30px;font-weight:800;letter-spacing:-0.02em;margin:0 0 4px">{{ title }}</h1>
|
|
41
44
|
<p style="color:var(--cs-color-text-muted);margin:0 0 28px">{{ sub }}</p>
|
|
42
45
|
<div style="display:grid;gap:16px">
|
|
43
|
-
<
|
|
46
|
+
<sc-if value="{{ showError }}" hint-placeholder-val="{{ false }}">
|
|
47
|
+
<x-import component-from-global-scope="CyberSkillDS.Alert" variant="danger" title="{{ errTitle }}" hint-size="100%,64px">{{ errBody }}</x-import>
|
|
48
|
+
</sc-if>
|
|
49
|
+
<x-import component-from-global-scope="CyberSkillDS.TextField" label="{{ emailL }}" type="email" placeholder="you@cyberskill.world" error="{{ emailError }}" hint-size="100%,74px"></x-import>
|
|
44
50
|
<x-import component-from-global-scope="CyberSkillDS.TextField" label="{{ pwL }}" type="password" placeholder="••••••••" hint-size="100%,74px"></x-import>
|
|
45
|
-
<x-import component-from-global-scope="CyberSkillDS.Switch" label="{{ rememberL }}" hint-size="140px,26px"></x-import>
|
|
46
|
-
<x-import component-from-global-scope="CyberSkillDS.Button" variant="primary" full-width="{{ true }}" hint-size="100%,44px">{{ signInBtn }}</x-import>
|
|
51
|
+
<x-import component-from-global-scope="CyberSkillDS.Switch" label="{{ rememberL }}" checked="{{ false }}" hint-size="140px,26px"></x-import>
|
|
52
|
+
<x-import component-from-global-scope="CyberSkillDS.Button" variant="primary" full-width="{{ true }}" loading="{{ isLoading }}" hint-size="100%,44px">{{ signInBtn }}</x-import>
|
|
47
53
|
<x-import component-from-global-scope="CyberSkillDS.Button" variant="ghost" full-width="{{ true }}" hint-size="100%,44px">{{ lumiBtn }}</x-import>
|
|
48
54
|
</div>
|
|
49
55
|
<p style="text-align:center;font-size:13px;color:var(--cs-color-text-muted);margin-top:16px">{{ newHere }} <a href="#">{{ askAccess }}</a></p>
|
|
56
|
+
<p style="text-align:center;font-size:12px;color:var(--cs-color-text-muted);margin-top:8px">{{ resetHint }} <a href="mailto:admin@cyberskill.world?subject=Password%20reset">{{ resetLink }}</a></p>
|
|
50
57
|
</div>
|
|
51
58
|
</div>
|
|
59
|
+
</main>
|
|
52
60
|
</div>
|
|
53
61
|
</x-dc>
|
|
54
62
|
<script type="text/x-dc" data-dc-script data-props="{
|
|
55
63
|
"language": {"editor":"enum","options":["English","Tiếng Việt"],"default":"English","tsType":"\"English\" | \"Tiếng Việt\"","section":"Content"},
|
|
56
64
|
"element": {"editor":"enum","options":["Thổ · studio","Thổ · clay","Thổ · sand","Hỏa · ember","Hỏa · lava","Hỏa · plasma","Thủy · river","Thủy · ocean","Thủy · mist","Mộc · leaf","Mộc · bamboo","Mộc · forest","Kim · champagne","Kim · steel","Kim · titanium"],"default":"Thổ · studio","tsType":"string","section":"Element (Ngũ Hành)"},
|
|
57
65
|
"theme": {"editor":"enum","options":["light","dark"],"default":"light","tsType":"\"light\" | \"dark\"","section":"Theme"},
|
|
58
|
-
"showBrandPanel": {"editor":"boolean","default":true,"tsType":"boolean","section":"Layout"}
|
|
66
|
+
"showBrandPanel": {"editor":"boolean","default":true,"tsType":"boolean","section":"Layout"},
|
|
67
|
+
"formState": {"editor":"enum","options":["default","loading","error","invalid"],"default":"default","tsType":"\"default\" | \"loading\" | \"error\" | \"invalid\"","section":"Form states"}
|
|
59
68
|
}">
|
|
60
69
|
class Component extends DCLogic {
|
|
61
70
|
renderVals() {
|
|
62
71
|
const EL = {"Thổ · studio":["tho",""],"Thổ · clay":["tho","clay"],"Thổ · sand":["tho","sand"],"Hỏa · ember":["hoa",""],"Hỏa · lava":["hoa","lava"],"Hỏa · plasma":["hoa","plasma"],"Thủy · river":["thuy",""],"Thủy · ocean":["thuy","ocean"],"Thủy · mist":["thuy","mist"],"Mộc · leaf":["moc",""],"Mộc · bamboo":["moc","bamboo"],"Mộc · forest":["moc","forest"],"Kim · champagne":["kim",""],"Kim · steel":["kim","steel"],"Kim · titanium":["kim","titanium"]};
|
|
63
72
|
const [elAttr, vaAttr] = EL[this.props.element] || EL["Thổ · studio"];
|
|
64
|
-
const vn = this.props.language === "Tiếng Việt";
|
|
65
|
-
const
|
|
66
|
-
const
|
|
67
|
-
|
|
73
|
+
const vn = this.props.language === "Tiếng Việt";
|
|
74
|
+
const state = this.props.formState || "default";
|
|
75
|
+
const en = { skipLabel:"Skip to content", brandH:"Turn Your Will Into Real", brandP:"Sign in to your workspace — one page, three lenses across every wish in flight.", title:"Sign in", sub:"Welcome back. Sign in to continue.", emailL:"Work email", pwL:"Password", rememberL:"Remember me", signInBtn: state === "loading" ? "Signing in…" : "Sign in", lumiBtn:"✦ Talk to Lumi instead", newHere:"New here?", askAccess:"Ask for access", resetHint:"Forgot password?", resetLink:"Email your workspace admin to reset.", errTitle:"Sign-in failed", errBody:"Check your email and password, then try again.", emailErr:"Enter a valid work email." };
|
|
76
|
+
const vi = { skipLabel:"Bỏ qua nội dung", brandH:"Hiện Thực Hoá Ý Chí", brandP:"Đăng nhập vào không gian làm việc — một trang, ba lăng kính cho mọi điều ước đang chạy.", title:"Đăng nhập", sub:"Mừng bạn quay lại. Đăng nhập để tiếp tục.", emailL:"Email công việc", pwL:"Mật khẩu", rememberL:"Ghi nhớ đăng nhập", signInBtn: state === "loading" ? "Đang đăng nhập…" : "Đăng nhập", lumiBtn:"✦ Trò chuyện với Lumi", newHere:"Lần đầu?", askAccess:"Xin quyền truy cập", resetHint:"Quên mật khẩu?", resetLink:"Gửi email cho quản trị không gian làm việc để đặt lại.", errTitle:"Đăng nhập thất bại", errBody:"Kiểm tra email và mật khẩu, rồi thử lại.", emailErr:"Nhập email công việc hợp lệ." };
|
|
77
|
+
const copy = vn ? vi : en;
|
|
78
|
+
return Object.assign({
|
|
79
|
+
langAttr: (this.props.language ?? "English") === "Tiếng Việt" ? "vi" : "en",
|
|
80
|
+
elAttr, vaAttr,
|
|
81
|
+
rootTheme: this.props.theme === "dark" ? "dark" : "",
|
|
82
|
+
showBrand: this.props.showBrandPanel ?? true,
|
|
83
|
+
showError: state === "error",
|
|
84
|
+
isLoading: state === "loading",
|
|
85
|
+
emailError: state === "invalid" ? copy.emailErr : "",
|
|
86
|
+
errTitle: copy.errTitle,
|
|
87
|
+
errBody: copy.errBody
|
|
88
|
+
}, copy);
|
|
68
89
|
}
|
|
69
90
|
}
|
|
70
91
|
</script>
|
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
"$schemaVersion": "2.0",
|
|
3
3
|
"template": "auth",
|
|
4
4
|
"slots": [
|
|
5
|
+
{
|
|
6
|
+
"id": "skipLabel",
|
|
7
|
+
"type": "text",
|
|
8
|
+
"label": "Skip-to-content link label",
|
|
9
|
+
"maxLength": 40,
|
|
10
|
+
"required": true
|
|
11
|
+
},
|
|
5
12
|
{
|
|
6
13
|
"id": "brandH",
|
|
7
14
|
"type": "text",
|
|
@@ -69,6 +76,36 @@
|
|
|
69
76
|
"type": "text",
|
|
70
77
|
"label": "Ask-for-access link label",
|
|
71
78
|
"maxLength": 24
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"id": "resetHint",
|
|
82
|
+
"type": "text",
|
|
83
|
+
"label": "Password-reset hint",
|
|
84
|
+
"maxLength": 40
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"id": "resetLink",
|
|
88
|
+
"type": "text",
|
|
89
|
+
"label": "Password-reset action link",
|
|
90
|
+
"maxLength": 64
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"id": "errTitle",
|
|
94
|
+
"type": "text",
|
|
95
|
+
"label": "Sign-in error alert title (error/invalid states)",
|
|
96
|
+
"maxLength": 40
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"id": "errBody",
|
|
100
|
+
"type": "text",
|
|
101
|
+
"label": "Sign-in error alert body",
|
|
102
|
+
"maxLength": 120
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"id": "emailError",
|
|
106
|
+
"type": "text",
|
|
107
|
+
"label": "Email field validation error (invalid state)",
|
|
108
|
+
"maxLength": 64
|
|
72
109
|
}
|
|
73
110
|
]
|
|
74
111
|
}
|
|
@@ -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
|
|
1074
|
-
var
|
|
1075
|
-
var
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
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[
|
|
1082
|
-
return typeof v === "string" && v ?
|
|
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
|
|
1108
|
+
const src = localScriptFor(BABEL_LOCAL);
|
|
1110
1109
|
babelLoading = new Promise((res, rej) => {
|
|
1111
1110
|
const s = document.createElement("script");
|
|
1112
|
-
s.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(
|
|
1775
|
-
loadScript(
|
|
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>Board · Meeting deck · 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>
|
|
@@ -14,7 +15,7 @@
|
|
|
14
15
|
<div data-theme="{{ rootTheme }}" lang="{{ langAttr }}" data-cs-element="{{ elAttr }}" data-cs-variant="{{ vaAttr }}" class="cs-canvas-desk" style="background:#2a1a0d;padding:28px;font-family:var(--cs-font-family-ui)">
|
|
15
16
|
<div style="display:grid;gap:28px;max-width:1280px;margin:0 auto">
|
|
16
17
|
|
|
17
|
-
<section style="position:relative;width:100%;aspect-ratio:16/9;background:var(--cs-
|
|
18
|
+
<section style="position:relative;width:100%;aspect-ratio:16/9;background:var(--cs-color-brand-umber);color:#FFFDF8;border-radius:var(--cs-radius-lg);overflow:hidden;box-shadow:var(--cs-shadow-xl);display:flex;flex-direction:column;justify-content:center;padding:0 88px">
|
|
18
19
|
<div style="display:flex;align-items:center;gap:14px;margin-bottom:26px">
|
|
19
20
|
<x-import component-from-global-scope="CyberSkillDS.Logo" size="46" hint-size="46px,46px"></x-import>
|
|
20
21
|
<span style="font-weight:800;font-size:22px;letter-spacing:-0.01em">CyberSkill</span>
|
|
@@ -30,10 +31,10 @@
|
|
|
30
31
|
<div style="font-size:14px;font-weight:700;text-transform:uppercase;letter-spacing:0.12em;color:var(--cs-color-text-accent)">{{ s2kicker }}</div>
|
|
31
32
|
<h2 style="font-size:44px;font-weight:800;letter-spacing:-0.02em;margin:10px 0 40px">{{ s2h }}</h2>
|
|
32
33
|
<div style="display:grid;grid-template-columns:repeat(4,1fr);gap:40px">
|
|
33
|
-
<div><div style="font-size:60px;font-weight:800;color:var(--cs-accent-
|
|
34
|
-
<div><div style="font-size:60px;font-weight:800;color:var(--cs-accent-
|
|
35
|
-
<div><div style="font-size:60px;font-weight:800;color:var(--cs-accent-
|
|
36
|
-
<div><div style="font-size:60px;font-weight:800;color:var(--cs-accent-
|
|
34
|
+
<div><div style="font-size:60px;font-weight:800;color:var(--cs-accent-strong);line-height:1;letter-spacing:-0.02em">+18%</div><div style="font-size:19px;color:var(--cs-color-text-muted);margin-top:10px">{{ n1 }}</div></div>
|
|
35
|
+
<div><div style="font-size:60px;font-weight:800;color:var(--cs-accent-strong);line-height:1;letter-spacing:-0.02em">14</div><div style="font-size:19px;color:var(--cs-color-text-muted);margin-top:10px">{{ n2 }}</div></div>
|
|
36
|
+
<div><div style="font-size:60px;font-weight:800;color:var(--cs-accent-strong);line-height:1;letter-spacing:-0.02em">{{ runway }}</div><div style="font-size:19px;color:var(--cs-color-text-muted);margin-top:10px">{{ n3 }}</div></div>
|
|
37
|
+
<div><div style="font-size:60px;font-weight:800;color:var(--cs-accent-strong);line-height:1;letter-spacing:-0.02em">38</div><div style="font-size:19px;color:var(--cs-color-text-muted);margin-top:10px">{{ n4 }}</div></div>
|
|
37
38
|
</div>
|
|
38
39
|
<sc-if value="{{ showNumbers }}"><div style="position:absolute;bottom:40px;right:88px;font-family:var(--cs-font-family-mono);font-size:14px;color:var(--cs-color-text-muted)">02 / 05</div></sc-if>
|
|
39
40
|
</section>
|
|
@@ -49,17 +50,17 @@
|
|
|
49
50
|
<sc-if value="{{ showNumbers }}"><div style="position:absolute;bottom:40px;right:88px;font-family:var(--cs-font-family-mono);font-size:14px;color:var(--cs-color-text-muted)">03 / 05</div></sc-if>
|
|
50
51
|
</section>
|
|
51
52
|
|
|
52
|
-
<section style="position:relative;width:100%;aspect-ratio:16/9;background:var(--cs-
|
|
53
|
+
<section style="position:relative;width:100%;aspect-ratio:16/9;background:var(--cs-color-brand-umber);color:#FFFDF8;border-radius:var(--cs-radius-lg);overflow:hidden;box-shadow:var(--cs-shadow-xl);padding:64px 88px;display:flex;flex-direction:column;justify-content:center">
|
|
53
54
|
<div style="font-size:14px;font-weight:700;text-transform:uppercase;letter-spacing:0.14em;color:var(--cs-accent-bright)">{{ s4kicker }}</div>
|
|
54
55
|
<h2 style="font-size:44px;font-weight:800;letter-spacing:-0.02em;color:var(--cs-accent-bright);margin:10px 0 34px">{{ s4h }}</h2>
|
|
55
56
|
<div style="display:grid;gap:22px;font-size:24px;line-height:1.4;max-width:1000px">
|
|
56
|
-
<div style="display:flex;gap:16px"><span style="color:var(--cs-accent-
|
|
57
|
-
<div style="display:flex;gap:16px"><span style="color:var(--cs-accent-
|
|
57
|
+
<div style="display:flex;gap:16px"><span style="color:var(--cs-accent-strong);font-weight:800">1.</span><div><b>{{ r1b }}</b> <span style="opacity:0.85">{{ r1t }}</span></div></div>
|
|
58
|
+
<div style="display:flex;gap:16px"><span style="color:var(--cs-accent-strong);font-weight:800">2.</span><div><b>{{ r2b }}</b> <span style="opacity:0.85">{{ r2t }}</span></div></div>
|
|
58
59
|
</div>
|
|
59
60
|
<sc-if value="{{ showNumbers }}"><div style="position:absolute;bottom:40px;right:88px;font-family:var(--cs-font-family-mono);font-size:14px;color:var(--cs-accent-bright)">04 / 05</div></sc-if>
|
|
60
61
|
</section>
|
|
61
62
|
|
|
62
|
-
<section style="position:relative;width:100%;aspect-ratio:16/9;background:var(--cs-
|
|
63
|
+
<section style="position:relative;width:100%;aspect-ratio:16/9;background:var(--cs-color-brand-umber);color:#FFFDF8;border-radius:var(--cs-radius-lg);overflow:hidden;box-shadow:var(--cs-shadow-xl);display:flex;flex-direction:column;justify-content:center;align-items:center;text-align:center;padding:0 88px">
|
|
63
64
|
<x-import component-from-global-scope="CyberSkillDS.Logo" size="72" hint-size="72px,72px"></x-import>
|
|
64
65
|
<h2 style="font-size:56px;font-weight:800;letter-spacing:-0.02em;color:var(--cs-accent-bright);margin:24px 0 10px">{{ closeH }}</h2>
|
|
65
66
|
<p style="font-size:22px;opacity:0.9;margin:0">{{ closeP }}</p>
|
|
@@ -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
|
})();
|