@cosmicdrift/kumiko-renderer 0.374.0 → 0.378.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.
- package/README.md +2 -2
- package/dist/app/action-form-support.d.ts +9 -2
- package/dist/app/action-form-support.js +24 -2
- package/dist/app/client-actions.d.ts +2 -2
- package/dist/app/column-renderers.js +1 -1
- package/dist/app/config-edit-shim.js +1 -1
- package/dist/app/content-preview.js +1 -6
- package/dist/app/custom-screens.js +1 -1
- package/dist/app/dashboard-body.d.ts +1 -1
- package/dist/app/entity-list-expanded-row.d.ts +1 -1
- package/dist/app/form-schema.d.ts +1 -1
- package/dist/app/form-schema.js +2 -2
- package/dist/app/kumiko-screen.d.ts +1 -1
- package/dist/app/kumiko-screen.js +10 -7
- package/dist/app/list-empty-content.d.ts +1 -1
- package/dist/app/list-facets.d.ts +1 -1
- package/dist/app/nav.js +2 -2
- package/dist/app/query-state-banners.d.ts +1 -1
- package/dist/app/reference-link.d.ts +1 -1
- package/dist/app/row-actions.d.ts +1 -1
- package/dist/app/secret-mint-body.d.ts +1 -1
- package/dist/app/secrets-edit-body.d.ts +1 -1
- package/dist/app/use-record-actions.d.ts +1 -1
- package/dist/app/write-failed-error.d.ts +1 -1
- package/dist/components/availability-options-select.d.ts +1 -1
- package/dist/components/embedded-list-field.d.ts +1 -1
- package/dist/components/embedded-list-field.js +1 -1
- package/dist/components/file-list-field.d.ts +1 -1
- package/dist/components/form-derivation-patch.d.ts +8 -0
- package/dist/components/form-derivation-patch.js +24 -0
- package/dist/components/form-screen-layout.d.ts +13 -0
- package/dist/components/form-screen-layout.js +13 -0
- package/dist/components/grid-cell-for-field.d.ts +1 -1
- package/dist/components/multi-select-checkboxes.d.ts +1 -1
- package/dist/components/multi-select-checkboxes.js +1 -1
- package/dist/components/query-options-select.d.ts +1 -1
- package/dist/components/related-list-section.d.ts +1 -1
- package/dist/components/render-edit-logic.d.ts +1 -1
- package/dist/components/render-edit-types.d.ts +6 -3
- package/dist/components/render-edit.d.ts +1 -1
- package/dist/components/render-edit.js +18 -3
- package/dist/components/render-field.d.ts +1 -1
- package/dist/components/render-field.js +12 -2
- package/dist/components/render-list.d.ts +1 -1
- package/dist/components/render-list.js +20 -4
- package/dist/components/write-form-section.d.ts +1 -1
- package/dist/components/write-form-section.js +1 -1
- package/dist/context/dispatcher-context.d.ts +1 -1
- package/dist/file-ids-of.d.ts +1 -0
- package/dist/file-ids-of.js +7 -0
- package/dist/flow-diagram/icons.d.ts +3 -0
- package/dist/flow-diagram/icons.js +14 -0
- package/dist/flow-diagram/index.d.ts +2 -0
- package/dist/flow-diagram/index.js +1 -0
- package/dist/flow-diagram/render.d.ts +3 -0
- package/dist/flow-diagram/render.js +234 -0
- package/dist/flow-diagram/types.d.ts +18 -0
- package/dist/flow-diagram/types.js +1 -0
- package/dist/format-when.js +1 -1
- package/dist/headless/apex/css.d.ts +3 -0
- package/dist/headless/apex/css.js +298 -0
- package/dist/headless/apex/index.d.ts +236 -0
- package/dist/headless/apex/index.js +377 -0
- package/dist/headless/apex/lightbox.d.ts +4 -0
- package/dist/headless/apex/lightbox.js +81 -0
- package/dist/headless/contracts/asset.d.ts +15 -0
- package/dist/headless/contracts/asset.js +17 -0
- package/dist/headless/contracts/index.d.ts +3 -0
- package/dist/headless/contracts/index.js +1 -0
- package/dist/headless/contracts/locale.d.ts +7 -0
- package/dist/headless/contracts/locale.js +11 -0
- package/dist/headless/contracts/primitives.d.ts +93 -0
- package/dist/headless/contracts/primitives.js +21 -0
- package/dist/headless/dispatcher/index.d.ts +2 -0
- package/dist/headless/dispatcher/index.js +1 -0
- package/dist/headless/dispatcher/types.d.ts +86 -0
- package/dist/headless/dispatcher/types.js +34 -0
- package/dist/headless/form/form-controller.d.ts +2 -0
- package/dist/headless/form/form-controller.js +409 -0
- package/dist/headless/form/index.d.ts +3 -0
- package/dist/headless/form/index.js +2 -0
- package/dist/headless/form/types.d.ts +76 -0
- package/dist/headless/form/types.js +1 -0
- package/dist/headless/form/zod-bridge.d.ts +10 -0
- package/dist/headless/form/zod-bridge.js +103 -0
- package/dist/headless/format/document-values.d.ts +12 -0
- package/dist/headless/format/document-values.js +70 -0
- package/dist/headless/format/escape.d.ts +5 -0
- package/dist/headless/format/escape.js +75 -0
- package/dist/headless/format/html-template.d.ts +9 -0
- package/dist/headless/format/html-template.js +39 -0
- package/dist/headless/format/index.d.ts +12 -0
- package/dist/headless/format/index.js +237 -0
- package/dist/headless/format/money.d.ts +3 -0
- package/dist/headless/format/money.js +39 -0
- package/dist/headless/index.d.ts +14 -0
- package/dist/headless/index.js +9 -0
- package/dist/headless/locale-routing/index.d.ts +41 -0
- package/dist/headless/locale-routing/index.js +145 -0
- package/dist/headless/nav/index.d.ts +2 -0
- package/dist/headless/nav/index.js +1 -0
- package/dist/headless/nav/resolve.d.ts +2 -0
- package/dist/headless/nav/resolve.js +71 -0
- package/dist/headless/nav/types.d.ts +26 -0
- package/dist/headless/nav/types.js +1 -0
- package/dist/headless/store/create-store.d.ts +2 -0
- package/dist/headless/store/create-store.js +43 -0
- package/dist/headless/store/equality.d.ts +1 -0
- package/dist/headless/store/equality.js +34 -0
- package/dist/headless/store/index.d.ts +3 -0
- package/dist/headless/store/index.js +2 -0
- package/dist/headless/store/types.d.ts +7 -0
- package/dist/headless/store/types.js +10 -0
- package/dist/headless/view-model/edit.d.ts +21 -0
- package/dist/headless/view-model/edit.js +512 -0
- package/dist/headless/view-model/embedded-list.d.ts +27 -0
- package/dist/headless/view-model/embedded-list.js +63 -0
- package/dist/headless/view-model/index.d.ts +7 -0
- package/dist/headless/view-model/index.js +3 -0
- package/dist/headless/view-model/list-file-display.d.ts +3 -0
- package/dist/headless/view-model/list-file-display.js +27 -0
- package/dist/headless/view-model/list.d.ts +16 -0
- package/dist/headless/view-model/list.js +229 -0
- package/dist/headless/view-model/types.d.ts +382 -0
- package/dist/headless/view-model/types.js +1 -0
- package/dist/hooks/use-ai-text.d.ts +1 -1
- package/dist/hooks/use-form.d.ts +1 -1
- package/dist/hooks/use-form.js +1 -1
- package/dist/hooks/use-mutation.d.ts +1 -1
- package/dist/hooks/use-query.d.ts +1 -1
- package/dist/hooks/use-store.d.ts +1 -1
- package/dist/hooks/use-store.js +7 -7
- package/dist/hooks/use-stream-handler.d.ts +1 -1
- package/dist/i18n-defaults.js +6 -0
- package/dist/i18n.d.ts +1 -1
- package/dist/i18n.js +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +5 -4
- package/dist/live/csrf.d.ts +2 -0
- package/dist/live/csrf.js +60 -0
- package/dist/live/dispatcher-live.d.ts +7 -0
- package/dist/live/dispatcher-live.js +286 -0
- package/dist/live/envelopes.d.ts +101 -0
- package/dist/live/envelopes.js +35 -0
- package/dist/live/error-mapping.d.ts +16 -0
- package/dist/live/error-mapping.js +82 -0
- package/dist/live/index.d.ts +7 -0
- package/dist/live/index.js +5 -0
- package/dist/live/locale.d.ts +2 -0
- package/dist/live/locale.js +25 -0
- package/dist/live/sse-stream.d.ts +14 -0
- package/dist/live/sse-stream.js +128 -0
- package/dist/primitives.d.ts +45 -36
- package/dist/primitives.js +1 -1
- package/dist/session/session-ended.d.ts +1 -1
- package/dist/tokens.d.ts +3 -4
- package/dist/tokens.js +4 -5
- package/dist/web/app/app-schema-boot.d.ts +19 -0
- package/dist/web/app/app-schema-boot.js +124 -0
- package/dist/web/app/browser-locale.d.ts +22 -0
- package/dist/web/app/browser-locale.js +78 -0
- package/dist/web/app/client-plugin.d.ts +106 -0
- package/dist/web/app/client-plugin.js +12 -0
- package/dist/web/app/create-app.d.ts +104 -0
- package/dist/web/app/create-app.js +498 -0
- package/dist/web/app/create-public-surface.d.ts +36 -0
- package/dist/web/app/create-public-surface.js +40 -0
- package/dist/web/app/dashboard-body.d.ts +3 -0
- package/dist/web/app/dashboard-body.js +865 -0
- package/dist/web/app/dashboard-refresh.d.ts +6 -0
- package/dist/web/app/dashboard-refresh.js +15 -0
- package/dist/web/app/document-lang-sync.d.ts +4 -0
- package/dist/web/app/document-lang-sync.js +27 -0
- package/dist/web/app/draft-storage.d.ts +11 -0
- package/dist/web/app/draft-storage.js +53 -0
- package/dist/web/app/nav-providers-context.d.ts +13 -0
- package/dist/web/app/nav-providers-context.js +18 -0
- package/dist/web/app/nav.d.ts +40 -0
- package/dist/web/app/nav.js +231 -0
- package/dist/web/app/plain-content-editor.d.ts +3 -0
- package/dist/web/app/plain-content-editor.js +30 -0
- package/dist/web/app/relative-time.d.ts +10 -0
- package/dist/web/app/relative-time.js +56 -0
- package/dist/web/app/resolvers-context.d.ts +12 -0
- package/dist/web/app/resolvers-context.js +10 -0
- package/dist/web/app/rich-content-editor.d.ts +3 -0
- package/dist/web/app/rich-content-editor.js +15 -0
- package/dist/web/app/root-error-fallback.d.ts +2 -0
- package/dist/web/app/root-error-fallback.js +21 -0
- package/dist/web/app/screen-error-fallback.d.ts +6 -0
- package/dist/web/app/screen-error-fallback.js +17 -0
- package/dist/web/app/tiptap-editor.d.ts +3 -0
- package/dist/web/app/tiptap-editor.js +120 -0
- package/dist/web/app/toast-action-notifier.d.ts +5 -0
- package/dist/web/app/toast-action-notifier.js +17 -0
- package/dist/web/components/config-cascade.d.ts +13 -0
- package/dist/web/components/config-cascade.js +155 -0
- package/dist/web/components/config-source-badge.d.ts +6 -0
- package/dist/web/components/config-source-badge.js +55 -0
- package/dist/web/default-color-scheme.d.ts +2 -0
- package/dist/web/default-color-scheme.js +3 -0
- package/dist/web/icons.d.ts +94 -0
- package/dist/web/icons.js +100 -0
- package/dist/web/index.d.ts +78 -0
- package/dist/web/index.js +53 -0
- package/dist/web/layout/app-layout.d.ts +21 -0
- package/dist/web/layout/app-layout.js +8 -0
- package/dist/web/layout/avatar.d.ts +12 -0
- package/dist/web/layout/avatar.js +63 -0
- package/dist/web/layout/default-app-shell.d.ts +41 -0
- package/dist/web/layout/default-app-shell.js +16 -0
- package/dist/web/layout/editor-panel.d.ts +10 -0
- package/dist/web/layout/editor-panel.js +29 -0
- package/dist/web/layout/fill-classes.d.ts +9 -0
- package/dist/web/layout/fill-classes.js +15 -0
- package/dist/web/layout/filter-app-schema-navs.d.ts +7 -0
- package/dist/web/layout/filter-app-schema-navs.js +68 -0
- package/dist/web/layout/header-action-group.d.ts +6 -0
- package/dist/web/layout/header-action-group.js +8 -0
- package/dist/web/layout/header-overflow-menu.d.ts +4 -0
- package/dist/web/layout/header-overflow-menu.js +8 -0
- package/dist/web/layout/language-menu-items.d.ts +8 -0
- package/dist/web/layout/language-menu-items.js +16 -0
- package/dist/web/layout/language-switcher.d.ts +25 -0
- package/dist/web/layout/language-switcher.js +46 -0
- package/dist/web/layout/nav-tree.d.ts +19 -0
- package/dist/web/layout/nav-tree.js +536 -0
- package/dist/web/layout/page-header-slot.d.ts +25 -0
- package/dist/web/layout/page-header-slot.js +50 -0
- package/dist/web/layout/profile-menu.d.ts +13 -0
- package/dist/web/layout/profile-menu.js +6 -0
- package/dist/web/layout/shell-breadcrumb.d.ts +11 -0
- package/dist/web/layout/shell-breadcrumb.js +34 -0
- package/dist/web/layout/shell-header.d.ts +12 -0
- package/dist/web/layout/shell-header.js +159 -0
- package/dist/web/layout/sidebar-brand.d.ts +15 -0
- package/dist/web/layout/sidebar-brand.js +9 -0
- package/dist/web/layout/sidebar-panel.d.ts +41 -0
- package/dist/web/layout/sidebar-panel.js +107 -0
- package/dist/web/layout/sidebar-user.d.ts +8 -0
- package/dist/web/layout/sidebar-user.js +17 -0
- package/dist/web/layout/sidebar.d.ts +17 -0
- package/dist/web/layout/sidebar.js +11 -0
- package/dist/web/layout/target-resolver-stub.d.ts +13 -0
- package/dist/web/layout/target-resolver-stub.js +61 -0
- package/dist/web/layout/target-url.d.ts +12 -0
- package/dist/web/layout/target-url.js +77 -0
- package/dist/web/layout/theme-label.d.ts +15 -0
- package/dist/web/layout/theme-label.js +35 -0
- package/dist/web/layout/theme-menu-item.d.ts +12 -0
- package/dist/web/layout/theme-menu-item.js +16 -0
- package/dist/web/layout/theme-toggle.d.ts +17 -0
- package/dist/web/layout/theme-toggle.js +22 -0
- package/dist/web/layout/topbar.d.ts +8 -0
- package/dist/web/layout/topbar.js +4 -0
- package/dist/web/layout/workspace-shell.d.ts +63 -0
- package/dist/web/layout/workspace-shell.js +220 -0
- package/dist/web/layout/workspace-switcher.d.ts +15 -0
- package/dist/web/layout/workspace-switcher.js +36 -0
- package/dist/web/lib/accept-attr.d.ts +1 -0
- package/dist/web/lib/accept-attr.js +6 -0
- package/dist/web/lib/clamp.d.ts +1 -0
- package/dist/web/lib/clamp.js +3 -0
- package/dist/web/lib/cn.d.ts +6 -0
- package/dist/web/lib/cn.js +9 -0
- package/dist/web/lib/download.d.ts +2 -0
- package/dist/web/lib/download.js +24 -0
- package/dist/web/lib/file-ref-download.d.ts +15 -0
- package/dist/web/lib/file-ref-download.js +62 -0
- package/dist/web/lib/file-upload-form-data.d.ts +7 -0
- package/dist/web/lib/file-upload-form-data.js +11 -0
- package/dist/web/lib/resize-image.d.ts +1 -0
- package/dist/web/lib/resize-image.js +66 -0
- package/dist/web/lib/upload-file-ref.d.ts +9 -0
- package/dist/web/lib/upload-file-ref.js +29 -0
- package/dist/web/primitives/action-menu.d.ts +34 -0
- package/dist/web/primitives/action-menu.js +30 -0
- package/dist/web/primitives/calendar-popover.d.ts +13 -0
- package/dist/web/primitives/calendar-popover.js +76 -0
- package/dist/web/primitives/combobox.d.ts +56 -0
- package/dist/web/primitives/combobox.js +127 -0
- package/dist/web/primitives/date-field.d.ts +18 -0
- package/dist/web/primitives/date-field.js +74 -0
- package/dist/web/primitives/date-input.d.ts +1 -0
- package/dist/web/primitives/date-input.js +5 -0
- package/dist/web/primitives/date-parse.d.ts +11 -0
- package/dist/web/primitives/date-parse.js +159 -0
- package/dist/web/primitives/dialog.d.ts +3 -0
- package/dist/web/primitives/dialog.js +42 -0
- package/dist/web/primitives/drawer.d.ts +3 -0
- package/dist/web/primitives/drawer.js +17 -0
- package/dist/web/primitives/dropdown-menu.d.ts +15 -0
- package/dist/web/primitives/dropdown-menu.js +56 -0
- package/dist/web/primitives/embedded-list-input.d.ts +9 -0
- package/dist/web/primitives/embedded-list-input.js +382 -0
- package/dist/web/primitives/file-thumbnail.d.ts +31 -0
- package/dist/web/primitives/file-thumbnail.js +90 -0
- package/dist/web/primitives/file-upload.d.ts +21 -0
- package/dist/web/primitives/file-upload.js +56 -0
- package/dist/web/primitives/file-value-list.d.ts +3 -0
- package/dist/web/primitives/file-value-list.js +22 -0
- package/dist/web/primitives/index.d.ts +34 -0
- package/dist/web/primitives/index.js +2023 -0
- package/dist/web/primitives/json-view.d.ts +7 -0
- package/dist/web/primitives/json-view.js +84 -0
- package/dist/web/primitives/layout.d.ts +27 -0
- package/dist/web/primitives/layout.js +30 -0
- package/dist/web/primitives/lightbox.d.ts +3 -0
- package/dist/web/primitives/lightbox.js +36 -0
- package/dist/web/primitives/locale-number.d.ts +2 -0
- package/dist/web/primitives/locale-number.js +54 -0
- package/dist/web/primitives/located-timestamp-input.d.ts +22 -0
- package/dist/web/primitives/located-timestamp-input.js +22 -0
- package/dist/web/primitives/metric.d.ts +5 -0
- package/dist/web/primitives/metric.js +18 -0
- package/dist/web/primitives/modal-shell.d.ts +17 -0
- package/dist/web/primitives/modal-shell.js +9 -0
- package/dist/web/primitives/modal.d.ts +3 -0
- package/dist/web/primitives/modal.js +13 -0
- package/dist/web/primitives/money-input.d.ts +18 -0
- package/dist/web/primitives/money-input.js +122 -0
- package/dist/web/primitives/narrow-pinned-footer.d.ts +12 -0
- package/dist/web/primitives/narrow-pinned-footer.js +153 -0
- package/dist/web/primitives/number-input.d.ts +18 -0
- package/dist/web/primitives/number-input.js +53 -0
- package/dist/web/primitives/option-groups.d.ts +11 -0
- package/dist/web/primitives/option-groups.js +27 -0
- package/dist/web/primitives/page-header.d.ts +3 -0
- package/dist/web/primitives/page-header.js +52 -0
- package/dist/web/primitives/promo-panel.d.ts +3 -0
- package/dist/web/primitives/promo-panel.js +11 -0
- package/dist/web/primitives/segmented-select.d.ts +21 -0
- package/dist/web/primitives/segmented-select.js +62 -0
- package/dist/web/primitives/share-actions.d.ts +4 -0
- package/dist/web/primitives/share-actions.js +56 -0
- package/dist/web/primitives/status-badge.d.ts +3 -0
- package/dist/web/primitives/status-badge.js +5 -0
- package/dist/web/primitives/sticky-action-bar.d.ts +5 -0
- package/dist/web/primitives/sticky-action-bar.js +15 -0
- package/dist/web/primitives/tabs.d.ts +3 -0
- package/dist/web/primitives/tabs.js +107 -0
- package/dist/web/primitives/timestamp-input.d.ts +27 -0
- package/dist/web/primitives/timestamp-input.js +87 -0
- package/dist/web/primitives/toast.d.ts +19 -0
- package/dist/web/primitives/toast.js +63 -0
- package/dist/web/primitives/tz-input.d.ts +11 -0
- package/dist/web/primitives/tz-input.js +8 -0
- package/dist/web/primitives/tz-options.d.ts +4 -0
- package/dist/web/primitives/tz-options.js +17 -0
- package/dist/web/primitives/use-keyboard-inset.d.ts +1 -0
- package/dist/web/primitives/use-keyboard-inset.js +28 -0
- package/dist/web/primitives/use-narrow-viewport.d.ts +4 -0
- package/dist/web/primitives/use-narrow-viewport.js +46 -0
- package/dist/web/react-css-custom-properties.d.ts +6 -0
- package/dist/web/react-css-custom-properties.js +1 -0
- package/dist/web/sse/live-events.d.ts +15 -0
- package/dist/web/sse/live-events.js +148 -0
- package/dist/web/theme-plugin.d.ts +41 -0
- package/dist/web/theme-plugin.js +123 -0
- package/dist/web/tokens.d.ts +24 -0
- package/dist/web/tokens.js +203 -0
- package/dist/web/ui/avatar.d.ts +11 -0
- package/dist/web/ui/avatar.js +25 -0
- package/dist/web/ui/badge.d.ts +9 -0
- package/dist/web/ui/badge.js +26 -0
- package/dist/web/ui/breadcrumb.d.ts +11 -0
- package/dist/web/ui/breadcrumb.js +29 -0
- package/dist/web/ui/button.d.ts +10 -0
- package/dist/web/ui/button.js +37 -0
- package/dist/web/ui/checkbox.d.ts +4 -0
- package/dist/web/ui/checkbox.js +11 -0
- package/dist/web/ui/input.d.ts +3 -0
- package/dist/web/ui/input.js +8 -0
- package/dist/web/ui/label.d.ts +4 -0
- package/dist/web/ui/label.js +10 -0
- package/dist/web/ui/resizable.d.ts +7 -0
- package/dist/web/ui/resizable.js +16 -0
- package/dist/web/ui/separator.d.ts +4 -0
- package/dist/web/ui/separator.js +10 -0
- package/dist/web/ui/sheet.d.ts +14 -0
- package/dist/web/ui/sheet.js +42 -0
- package/dist/web/ui/sidebar.d.ts +73 -0
- package/dist/web/ui/sidebar.js +211 -0
- package/dist/web/ui/skeleton.d.ts +2 -0
- package/dist/web/ui/skeleton.js +7 -0
- package/dist/web/ui/switch.d.ts +6 -0
- package/dist/web/ui/switch.js +10 -0
- package/dist/web/ui/table.d.ts +10 -0
- package/dist/web/ui/table.js +30 -0
- package/dist/web/ui/tabs.d.ts +11 -0
- package/dist/web/ui/tabs.js +31 -0
- package/dist/web/ui/textarea.d.ts +3 -0
- package/dist/web/ui/textarea.js +8 -0
- package/dist/web/ui/tooltip.d.ts +7 -0
- package/dist/web/ui/tooltip.js +19 -0
- package/dist/web/ui/use-mobile.d.ts +1 -0
- package/dist/web/ui/use-mobile.js +16 -0
- package/dist/web/version/update-checker.d.ts +9 -0
- package/dist/web/version/update-checker.js +88 -0
- package/dist/web/widgets/ai-text-field.d.ts +36 -0
- package/dist/web/widgets/ai-text-field.js +137 -0
- package/dist/web/widgets/bounded-load-cache.d.ts +1 -0
- package/dist/web/widgets/bounded-load-cache.js +25 -0
- package/dist/web/widgets/chart-window.d.ts +58 -0
- package/dist/web/widgets/chart-window.js +190 -0
- package/dist/web/widgets/charts.d.ts +208 -0
- package/dist/web/widgets/charts.js +685 -0
- package/dist/web/widgets/collapsible-section.d.ts +10 -0
- package/dist/web/widgets/collapsible-section.js +17 -0
- package/dist/web/widgets/dashboard-list.d.ts +21 -0
- package/dist/web/widgets/dashboard-list.js +45 -0
- package/dist/web/widgets/detail-list.d.ts +15 -0
- package/dist/web/widgets/detail-list.js +8 -0
- package/dist/web/widgets/drawer.d.ts +65 -0
- package/dist/web/widgets/drawer.js +177 -0
- package/dist/web/widgets/feed-list.d.ts +13 -0
- package/dist/web/widgets/feed-list.js +9 -0
- package/dist/web/widgets/floating-panel.d.ts +30 -0
- package/dist/web/widgets/floating-panel.js +242 -0
- package/dist/web/widgets/form-fields.d.ts +93 -0
- package/dist/web/widgets/form-fields.js +50 -0
- package/dist/web/widgets/index.d.ts +28 -0
- package/dist/web/widgets/index.js +31 -0
- package/dist/web/widgets/infinity-list.d.ts +46 -0
- package/dist/web/widgets/infinity-list.js +211 -0
- package/dist/web/widgets/mode-switch.d.ts +21 -0
- package/dist/web/widgets/mode-switch.js +25 -0
- package/dist/web/widgets/pdf-preview.d.ts +10 -0
- package/dist/web/widgets/pdf-preview.js +140 -0
- package/dist/web/widgets/photo-slots.d.ts +29 -0
- package/dist/web/widgets/photo-slots.js +52 -0
- package/dist/web/widgets/plan-card.d.ts +36 -0
- package/dist/web/widgets/plan-card.js +13 -0
- package/dist/web/widgets/progress-bar.d.ts +19 -0
- package/dist/web/widgets/progress-bar.js +24 -0
- package/dist/web/widgets/progress-list.d.ts +19 -0
- package/dist/web/widgets/progress-list.js +11 -0
- package/dist/web/widgets/public-shell.d.ts +22 -0
- package/dist/web/widgets/public-shell.js +15 -0
- package/dist/web/widgets/query-table.d.ts +29 -0
- package/dist/web/widgets/query-table.js +30 -0
- package/dist/web/widgets/result-panel.d.ts +69 -0
- package/dist/web/widgets/result-panel.js +30 -0
- package/dist/web/widgets/section-card.d.ts +12 -0
- package/dist/web/widgets/section-card.js +9 -0
- package/dist/web/widgets/sheet-parts.d.ts +9 -0
- package/dist/web/widgets/sheet-parts.js +11 -0
- package/dist/web/widgets/side-by-side-table.d.ts +31 -0
- package/dist/web/widgets/side-by-side-table.js +11 -0
- package/dist/web/widgets/stat.d.ts +54 -0
- package/dist/web/widgets/stat.js +65 -0
- package/dist/web/widgets/states.d.ts +23 -0
- package/dist/web/widgets/states.js +20 -0
- package/dist/web/widgets/status-badge.d.ts +15 -0
- package/dist/web/widgets/status-badge.js +24 -0
- package/dist/web/widgets/step-bar.d.ts +35 -0
- package/dist/web/widgets/step-bar.js +60 -0
- package/dist/web/widgets/upload-zone.d.ts +24 -0
- package/dist/web/widgets/upload-zone.js +108 -0
- package/dist/web/widgets/use-draft.d.ts +20 -0
- package/dist/web/widgets/use-draft.js +21 -0
- package/dist/web/widgets/use-pointer-drag.d.ts +21 -0
- package/dist/web/widgets/use-pointer-drag.js +53 -0
- package/package.json +114 -7
- package/src/changes.json +92 -0
- package/src/web/fonts/OFL.txt +93 -0
- package/src/web/fonts/ibm-plex-mono-latin-400.woff2 +0 -0
- package/src/web/fonts/ibm-plex-mono-latin-500.woff2 +0 -0
- package/src/web/fonts/ibm-plex-mono-latin-ext-400.woff2 +0 -0
- package/src/web/fonts/ibm-plex-mono-latin-ext-500.woff2 +0 -0
- package/src/web/fonts/ibm-plex-sans-latin-400.woff2 +0 -0
- package/src/web/fonts/ibm-plex-sans-latin-500.woff2 +0 -0
- package/src/web/fonts/ibm-plex-sans-latin-600.woff2 +0 -0
- package/src/web/fonts/ibm-plex-sans-latin-ext-400.woff2 +0 -0
- package/src/web/fonts/ibm-plex-sans-latin-ext-500.woff2 +0 -0
- package/src/web/fonts/ibm-plex-sans-latin-ext-600.woff2 +0 -0
- package/src/web/styles.css +405 -0
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
// Structural CSS for the Apex marketing surface — shared by every app's static
|
|
2
|
+
// landing. Brand TOKEN VALUES (:root custom properties) and @font-face stay
|
|
3
|
+
// app-side (passed as brand.tokensCss / brand.fontFaceCss); this file owns only
|
|
4
|
+
// the structure: layout, grids, cards, buttons, header/footer, responsive.
|
|
5
|
+
//
|
|
6
|
+
// Two themes ship together; the <body class> selects one (see renderApexPage):
|
|
7
|
+
// - light (default): chrome on light backgrounds — translucent blurred header.
|
|
8
|
+
// - .apex-dark: header/hero/final-cta/footer sit on --primary with --on-dark
|
|
9
|
+
// text + inverted buttons (the "dark sandwich"). Requires the app's tokens
|
|
10
|
+
// to define --on-dark / --on-dark-muted / --on-dark-border.
|
|
11
|
+
//
|
|
12
|
+
// Token divergence is absorbed by CSS fallbacks, not parameters:
|
|
13
|
+
// --font-mono unset → .price-amount stays in body font (var(--font-mono, inherit))
|
|
14
|
+
// --accent-hover unset → eyebrow falls back to --primary
|
|
15
|
+
// --hero-tagline-max unset → hero tagline runs full column (var(--hero-tagline-max, none))
|
|
16
|
+
// icon tint → color-mix derives a faint --primary wash, no hardcoded rgba
|
|
17
|
+
const BASE_LAYOUT = `
|
|
18
|
+
* { box-sizing: border-box; }
|
|
19
|
+
html, body { margin: 0; padding: 0; }
|
|
20
|
+
body {
|
|
21
|
+
font-family: var(--font-body, "Inter Variable", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif);
|
|
22
|
+
background: var(--bg); color: var(--fg); line-height: 1.6;
|
|
23
|
+
-webkit-font-smoothing: antialiased;
|
|
24
|
+
min-height: 100vh; display: flex; flex-direction: column;
|
|
25
|
+
}
|
|
26
|
+
main { flex: 1; }
|
|
27
|
+
a { color: var(--primary); text-decoration: none; }
|
|
28
|
+
a:hover { color: var(--primary-hover); }
|
|
29
|
+
h1, h2, h3 { letter-spacing: -0.02em; }
|
|
30
|
+
.container { max-width: 1120px; margin: 0 auto; padding: 0 1.5rem; width: 100%; }
|
|
31
|
+
.container-narrow { max-width: 760px; margin: 0 auto; padding: 0 1.5rem; width: 100%; }
|
|
32
|
+
.btn {
|
|
33
|
+
display: inline-block; padding: 0.6rem 1.15rem; border-radius: 0.5rem;
|
|
34
|
+
font-weight: 600; font-size: 0.9375rem; border: 1px solid transparent;
|
|
35
|
+
cursor: pointer; transition: background 0.15s, border-color 0.15s, transform 0.05s;
|
|
36
|
+
}
|
|
37
|
+
.btn:active { transform: translateY(1px); }
|
|
38
|
+
.btn-primary { background: var(--primary); color: var(--primary-fg); }
|
|
39
|
+
.btn-primary:hover { background: var(--primary-hover); color: var(--primary-fg); }
|
|
40
|
+
.btn-secondary { background: var(--bg-card); color: var(--fg); border-color: var(--border); }
|
|
41
|
+
.btn-secondary:hover { border-color: var(--fg-muted); color: var(--fg); }
|
|
42
|
+
|
|
43
|
+
section { padding: 5rem 0; }
|
|
44
|
+
.section-head { text-align: center; max-width: 640px; margin: 0 auto 3rem; }
|
|
45
|
+
.section-head h2 { font-size: clamp(1.6rem, 3.5vw, 2.25rem); margin: 0 0 0.75rem; }
|
|
46
|
+
.section-head p { color: var(--fg-muted); margin: 0; font-size: 1.0625rem; }
|
|
47
|
+
.eyebrow { display: inline-block; font-size: 0.8125rem; font-weight: 600; letter-spacing: 0.04em;
|
|
48
|
+
text-transform: uppercase; color: var(--accent-hover, var(--primary)); margin-bottom: 0.75rem; }
|
|
49
|
+
`;
|
|
50
|
+
const HERO = `
|
|
51
|
+
.hero { padding: 4.5rem 0 4rem; }
|
|
52
|
+
.hero-grid { display: grid; grid-template-columns: 1.05fr 1fr; gap: 3.5rem; align-items: center; }
|
|
53
|
+
.hero-pony { width: 88px; height: 88px; margin: 0 0 1.1rem; display: block; }
|
|
54
|
+
.hero h1 { font-size: clamp(2.1rem, 4.5vw, 3.4rem); line-height: 1.08; margin: 0 0 1.1rem; font-weight: 700; }
|
|
55
|
+
.hero .tagline { font-size: clamp(1.05rem, 1.6vw, 1.25rem); color: var(--fg-muted); margin: 0 0 1.75rem; max-width: var(--hero-tagline-max, none); }
|
|
56
|
+
.hero-cta { display: flex; gap: 0.75rem; flex-wrap: wrap; }
|
|
57
|
+
.hero-meta { margin-top: 1.5rem; font-size: 0.875rem; color: var(--fg-subtle); }
|
|
58
|
+
.hero-meta strong { color: var(--fg-muted); font-weight: 600; }
|
|
59
|
+
.shot-frame { border-radius: 0.75rem; border: 1px solid var(--border); background: var(--bg-card);
|
|
60
|
+
box-shadow: var(--shadow); overflow: hidden; cursor: zoom-in; }
|
|
61
|
+
.shot-bar { display: flex; gap: 0.4rem; padding: 0.6rem 0.85rem; border-bottom: 1px solid var(--border); background: var(--bg-muted); }
|
|
62
|
+
.shot-bar span { width: 0.65rem; height: 0.65rem; border-radius: 50%; background: var(--border); }
|
|
63
|
+
.shot-frame img { display: block; width: 100%; height: auto; }
|
|
64
|
+
.apex-lightbox { border: none; padding: 0; margin: auto; max-width: 95vw; max-height: 90vh;
|
|
65
|
+
background: transparent; overflow: visible; }
|
|
66
|
+
.apex-lightbox::backdrop { background: rgba(15, 23, 42, 0.72); }
|
|
67
|
+
.apex-lightbox__img { display: block; max-width: 90vw; max-height: 85vh; width: auto; height: auto;
|
|
68
|
+
border-radius: 0.75rem; border: 1px solid var(--border); box-shadow: var(--shadow); }
|
|
69
|
+
.apex-lightbox__close { position: fixed; top: 1rem; right: 1rem; z-index: 1; width: 2.5rem; height: 2.5rem;
|
|
70
|
+
border: 1px solid var(--border); border-radius: 0.5rem; background: var(--bg-card); color: var(--fg);
|
|
71
|
+
font-size: 1.5rem; line-height: 1; cursor: pointer; }
|
|
72
|
+
.apex-lightbox__close:hover { background: var(--bg-muted); }
|
|
73
|
+
.apex-lightbox__prev, .apex-lightbox__next { position: fixed; top: 50%; transform: translateY(-50%); z-index: 1;
|
|
74
|
+
width: 2.5rem; height: 2.5rem; border: 1px solid var(--border); border-radius: 0.5rem;
|
|
75
|
+
background: var(--bg-card); color: var(--fg); font-size: 1.75rem; line-height: 1; cursor: pointer; }
|
|
76
|
+
.apex-lightbox__prev { left: 1rem; }
|
|
77
|
+
.apex-lightbox__next { right: 1rem; }
|
|
78
|
+
.apex-lightbox__prev:hover, .apex-lightbox__next:hover { background: var(--bg-muted); }
|
|
79
|
+
.apex-lightbox__prev[hidden], .apex-lightbox__next[hidden] { display: none; }
|
|
80
|
+
.apex-dark .apex-lightbox__prev, .apex-dark .apex-lightbox__next { background: var(--on-dark); color: var(--primary); border-color: var(--on-dark-border); }
|
|
81
|
+
.apex-dark .apex-lightbox__close { background: var(--on-dark); color: var(--primary); border-color: var(--on-dark-border); }
|
|
82
|
+
`;
|
|
83
|
+
const FEATURES = `
|
|
84
|
+
.features { background: var(--bg-muted); }
|
|
85
|
+
.feature-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.5rem; }
|
|
86
|
+
.feature { background: var(--bg-card); border: 1px solid var(--border); border-radius: 0.75rem; padding: 1.75rem; }
|
|
87
|
+
.feature-icon { width: 2.5rem; height: 2.5rem; border-radius: 0.6rem; display: flex; align-items: center;
|
|
88
|
+
justify-content: center; background: color-mix(in srgb, var(--primary) 9%, transparent); color: var(--primary); margin-bottom: 1rem; }
|
|
89
|
+
.feature-icon svg { width: 1.35rem; height: 1.35rem; }
|
|
90
|
+
.feature h3 { font-size: 1.0625rem; margin: 0 0 0.4rem; }
|
|
91
|
+
.feature p { color: var(--fg-muted); margin: 0; font-size: 0.9375rem; }
|
|
92
|
+
`;
|
|
93
|
+
const PRICING = `
|
|
94
|
+
.price-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1.25rem; align-items: stretch; }
|
|
95
|
+
.price-card { position: relative; background: var(--bg-card); border: 1px solid var(--border);
|
|
96
|
+
border-radius: 0.75rem; padding: 1.75rem 1.5rem; display: flex; flex-direction: column; gap: 0.85rem; }
|
|
97
|
+
.price-card--featured { border-color: var(--primary); box-shadow: var(--shadow); }
|
|
98
|
+
.price-badge { position: absolute; top: -0.7rem; left: 50%; transform: translateX(-50%);
|
|
99
|
+
background: var(--accent, var(--primary)); color: var(--accent-fg, var(--primary-fg)); font-size: 0.75rem; font-weight: 700;
|
|
100
|
+
padding: 0.2rem 0.7rem; border-radius: 999px; white-space: nowrap; }
|
|
101
|
+
.price-card h3 { margin: 0; font-size: 1.25rem; }
|
|
102
|
+
.price-tagline { margin: 0; color: var(--fg-subtle); font-size: 0.875rem; }
|
|
103
|
+
.price-amount { font-size: 2rem; font-weight: 700; font-family: var(--font-mono, inherit); }
|
|
104
|
+
.price-amount span { font-size: 0.9375rem; font-weight: 500; color: var(--fg-subtle); font-family: inherit; }
|
|
105
|
+
.price-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.55rem; flex: 1; }
|
|
106
|
+
.price-list li { position: relative; padding-left: 1.5rem; font-size: 0.9rem; color: var(--fg-muted); }
|
|
107
|
+
.price-list li::before { content: ""; position: absolute; left: 0; top: 0.45rem; width: 0.7rem; height: 0.4rem;
|
|
108
|
+
border-left: 2px solid var(--status-ok); border-bottom: 2px solid var(--status-ok); transform: rotate(-45deg); }
|
|
109
|
+
.price-list li.price-cap { font-weight: 600; color: var(--fg); }
|
|
110
|
+
.price-card .btn { text-align: center; margin-top: 0.5rem; }
|
|
111
|
+
`;
|
|
112
|
+
const TRUST = `
|
|
113
|
+
.trust-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 2rem; }
|
|
114
|
+
.trust-item h3 { font-size: 1.0625rem; margin: 0 0 0.4rem; }
|
|
115
|
+
.trust-item p { color: var(--fg-muted); margin: 0; font-size: 0.9375rem; }
|
|
116
|
+
`;
|
|
117
|
+
const FINAL_CTA = `
|
|
118
|
+
.final-cta { text-align: center; }
|
|
119
|
+
.final-cta-pony { width: 96px; height: auto; display: block; margin: 0 auto 1rem; }
|
|
120
|
+
.final-cta h2 { font-size: clamp(1.6rem, 3.5vw, 2.25rem); margin: 0 0 0.75rem; }
|
|
121
|
+
.final-cta p { color: var(--fg-muted); margin: 0 0 1.75rem; font-size: 1.0625rem; }
|
|
122
|
+
`;
|
|
123
|
+
// Light chrome (default). Header floats translucent over the page; footer is a
|
|
124
|
+
// muted band. Dark theme overrides both below.
|
|
125
|
+
const CHROME_LIGHT = `
|
|
126
|
+
header { position: sticky; top: 0; z-index: 10;
|
|
127
|
+
background: color-mix(in srgb, var(--bg) 85%, transparent);
|
|
128
|
+
backdrop-filter: saturate(140%) blur(8px);
|
|
129
|
+
border-bottom: 1px solid var(--border); }
|
|
130
|
+
.nav { position: relative; display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding-block: 0.85rem; }
|
|
131
|
+
.brand { display: flex; align-items: center; gap: 0.55rem; font-weight: 700; font-size: 1.125rem; color: var(--fg); }
|
|
132
|
+
.brand a { color: var(--fg); display: inline-flex; align-items: center; gap: 0.55rem; }
|
|
133
|
+
.brand a:hover { color: var(--fg); }
|
|
134
|
+
.brand img { width: 1.7rem; height: 1.7rem; border-radius: 0.4rem; }
|
|
135
|
+
.nav-links { display: flex; gap: 1.5rem; align-items: center; font-size: 0.9375rem; }
|
|
136
|
+
.nav-links a { color: var(--fg-muted); }
|
|
137
|
+
.nav-links a:hover { color: var(--fg); }
|
|
138
|
+
.nav-actions { display: flex; gap: 0.75rem; align-items: center; font-size: 0.9375rem; }
|
|
139
|
+
.nav-actions > a:not(.btn) { color: var(--fg-muted); }
|
|
140
|
+
.nav-actions > a:not(.btn):hover { color: var(--fg); }
|
|
141
|
+
@media (max-width: 640px) { .nav-links { display: none; } }
|
|
142
|
+
|
|
143
|
+
footer { border-top: 1px solid var(--border); color: var(--fg-subtle); padding: 3.5rem 0 2.5rem; font-size: 0.9rem; }
|
|
144
|
+
.footer-grid { display: grid; gap: 2rem; grid-template-columns: 1.6fr repeat(var(--footer-cols, 2), 1fr); }
|
|
145
|
+
.footer-brand { display: flex; align-items: center; gap: 0.55rem; font-weight: 700; color: var(--fg); margin-bottom: 0.75rem; }
|
|
146
|
+
.footer-brand img { width: 1.6rem; height: 1.6rem; border-radius: 0.4rem; }
|
|
147
|
+
.footer-tagline { color: var(--fg-subtle); max-width: 34ch; margin: 0; }
|
|
148
|
+
.footer-col h4 { font-size: 0.8125rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--fg-subtle); margin: 0 0 0.85rem; }
|
|
149
|
+
.footer-col a { display: block; color: var(--fg-muted); margin-bottom: 0.5rem; }
|
|
150
|
+
.footer-col a:hover { color: var(--fg); }
|
|
151
|
+
.footer-bottom { margin-top: 2.5rem; padding-top: 1.5rem; border-top: 1px solid var(--border);
|
|
152
|
+
display: flex; flex-wrap: wrap; justify-content: space-between; gap: 0.75rem; }
|
|
153
|
+
`;
|
|
154
|
+
// Dark sandwich: header/hero/final-cta/footer ride on --primary. Buttons invert
|
|
155
|
+
// (a --primary button on --primary would vanish) → light button, --primary text.
|
|
156
|
+
const CHROME_DARK = `
|
|
157
|
+
.apex-dark header { background: var(--primary); backdrop-filter: none; border-bottom: 1px solid var(--on-dark-border); }
|
|
158
|
+
.apex-dark .brand, .apex-dark .brand a, .apex-dark .brand a:hover { color: var(--on-dark); }
|
|
159
|
+
.apex-dark .nav-links a { color: var(--on-dark-muted); }
|
|
160
|
+
.apex-dark .nav-links a:hover { color: var(--on-dark); }
|
|
161
|
+
.apex-dark .nav-actions > a:not(.btn) { color: var(--on-dark-muted); }
|
|
162
|
+
.apex-dark .nav-actions > a:not(.btn):hover { color: var(--on-dark); }
|
|
163
|
+
.apex-dark header .btn-primary { background: var(--on-dark); color: var(--primary); }
|
|
164
|
+
.apex-dark header .btn-primary:hover { background: rgba(255,255,255,0.85); color: var(--primary-hover); }
|
|
165
|
+
|
|
166
|
+
.apex-dark .hero { background: var(--primary); color: var(--on-dark); }
|
|
167
|
+
.apex-dark .hero h1 { color: var(--on-dark); }
|
|
168
|
+
.apex-dark .hero .tagline { color: var(--on-dark-muted); }
|
|
169
|
+
.apex-dark .hero .btn-primary, .apex-dark .final-cta .btn-primary { background: var(--on-dark); color: var(--primary); }
|
|
170
|
+
.apex-dark .hero .btn-primary:hover, .apex-dark .final-cta .btn-primary:hover { background: rgba(255,255,255,0.85); color: var(--primary-hover); }
|
|
171
|
+
.apex-dark .hero .btn-secondary { background: rgba(255,255,255,0.08); color: var(--on-dark); border-color: rgba(255,255,255,0.30); }
|
|
172
|
+
.apex-dark .hero .btn-secondary:hover { background: rgba(255,255,255,0.16); color: var(--on-dark); border-color: rgba(255,255,255,0.5); }
|
|
173
|
+
.apex-dark .hero-meta { color: rgba(255,255,255,0.55); }
|
|
174
|
+
.apex-dark .hero-meta strong { color: var(--on-dark-muted); }
|
|
175
|
+
|
|
176
|
+
.apex-dark .final-cta { background: var(--primary); color: var(--on-dark); }
|
|
177
|
+
.apex-dark .final-cta h2 { color: var(--on-dark); }
|
|
178
|
+
.apex-dark .final-cta p { color: var(--on-dark-muted); }
|
|
179
|
+
|
|
180
|
+
.apex-dark footer { background: var(--primary); color: var(--on-dark-muted); border-top: none; }
|
|
181
|
+
.apex-dark .footer-brand { color: var(--on-dark); }
|
|
182
|
+
.apex-dark .footer-tagline { color: var(--on-dark-muted); }
|
|
183
|
+
.apex-dark .footer-col h4 { color: var(--on-dark-muted); }
|
|
184
|
+
.apex-dark .footer-col a { color: var(--on-dark-muted); }
|
|
185
|
+
.apex-dark .footer-col a:hover { color: var(--on-dark); }
|
|
186
|
+
.apex-dark .footer-bottom { border-top: 1px solid var(--on-dark-border); }
|
|
187
|
+
`;
|
|
188
|
+
const RESPONSIVE = `
|
|
189
|
+
@media (max-width: 900px) {
|
|
190
|
+
.hero-grid { grid-template-columns: 1fr; gap: 2.5rem; }
|
|
191
|
+
.feature-grid { grid-template-columns: repeat(2, 1fr); }
|
|
192
|
+
.price-grid { grid-template-columns: repeat(2, 1fr); }
|
|
193
|
+
.footer-grid { grid-template-columns: 1fr 1fr; }
|
|
194
|
+
}
|
|
195
|
+
@media (max-width: 640px) {
|
|
196
|
+
section { padding: 3.5rem 0; }
|
|
197
|
+
.feature-grid, .price-grid, .trust-grid, .footer-grid { grid-template-columns: 1fr; }
|
|
198
|
+
}
|
|
199
|
+
`;
|
|
200
|
+
// header renders navLinks TWICE (renderApexHeader): a plain always-visible
|
|
201
|
+
// .nav-links row, plus a copy nested in .nav-toggle for < 640px — a closed
|
|
202
|
+
// <details> can't be forced "always open" on desktop via CSS (Chrome keeps
|
|
203
|
+
// its content unpainted regardless of a child's own `display`), so two
|
|
204
|
+
// copies sidestep that instead of fighting it. Exported standalone so a
|
|
205
|
+
// consumer rendering its own header chrome can include just this. A
|
|
206
|
+
// consumer using renderApexHeader() outside renderApexPage also needs
|
|
207
|
+
// APEX_NAV_TOGGLE_RESPONSIVE_CSS below for the mobile toggle to open.
|
|
208
|
+
export const APEX_NAV_MENU_CSS = `
|
|
209
|
+
.nav-toggle { display: none; }
|
|
210
|
+
.nav-toggle__trigger { display: none; align-items: center; justify-content: center;
|
|
211
|
+
width: 2.25rem; height: 2.25rem; border-radius: 0.5rem; cursor: pointer;
|
|
212
|
+
color: var(--fg-muted); list-style: none; }
|
|
213
|
+
.nav-toggle__trigger::-webkit-details-marker { display: none; }
|
|
214
|
+
.nav-toggle__trigger:hover { color: var(--fg); background: var(--bg-muted); }
|
|
215
|
+
.nav-toggle__trigger svg { width: 1.35rem; height: 1.35rem; }
|
|
216
|
+
.apex-dark .nav-toggle__trigger { color: var(--on-dark-muted); }
|
|
217
|
+
.apex-dark .nav-toggle__trigger:hover { color: var(--on-dark); background: rgba(255,255,255,0.08); }
|
|
218
|
+
|
|
219
|
+
.nav-menu { position: relative; display: inline-flex; }
|
|
220
|
+
.nav-menu__trigger { display: inline-flex; align-items: center; gap: 0.3rem;
|
|
221
|
+
font: inherit; font-size: 0.9375rem; color: var(--fg-muted);
|
|
222
|
+
cursor: pointer; list-style: none; }
|
|
223
|
+
.nav-menu__trigger::-webkit-details-marker { display: none; }
|
|
224
|
+
.nav-menu__trigger:hover { color: var(--fg); }
|
|
225
|
+
.nav-menu__chev { display: inline-flex; transition: transform 0.15s; opacity: 0.7; }
|
|
226
|
+
.nav-menu__chev svg { width: 0.95em; height: 0.95em; }
|
|
227
|
+
.nav-menu[open] .nav-menu__chev { transform: rotate(180deg); }
|
|
228
|
+
.nav-menu__panel { position: absolute; top: calc(100% + 0.5rem); left: 0; z-index: 20;
|
|
229
|
+
min-width: 21rem; padding: 0.5rem; background: var(--bg-card); color: var(--fg);
|
|
230
|
+
border: 1px solid var(--border); border-radius: 0.75rem; box-shadow: var(--shadow);
|
|
231
|
+
flex-direction: column; gap: 0.125rem; }
|
|
232
|
+
.nav-menu[open] .nav-menu__panel { display: flex; }
|
|
233
|
+
.nav-menu__item { display: flex; gap: 0.75rem; align-items: flex-start;
|
|
234
|
+
padding: 0.6rem 0.7rem; border-radius: 0.5rem; color: var(--fg); }
|
|
235
|
+
.nav-menu__item:hover { background: var(--bg-muted); color: var(--fg); }
|
|
236
|
+
.nav-menu__icon { flex: none; display: inline-flex; align-items: center; justify-content: center;
|
|
237
|
+
width: 2rem; height: 2rem; border-radius: 0.5rem;
|
|
238
|
+
background: color-mix(in srgb, var(--primary) 12%, transparent); color: var(--primary); }
|
|
239
|
+
.nav-menu__icon svg { width: 1.1rem; height: 1.1rem; }
|
|
240
|
+
.nav-menu__text { display: flex; flex-direction: column; gap: 0.1rem; }
|
|
241
|
+
.nav-menu__title { font-weight: 600; font-size: 0.9rem; line-height: 1.2; }
|
|
242
|
+
.nav-menu__desc { font-size: 0.8rem; color: var(--fg-muted); line-height: 1.35; }
|
|
243
|
+
.nav-menu__sep { height: 1px; background: var(--border); margin: 0.375rem 0.3rem; }
|
|
244
|
+
.nav-menu__more { display: inline-flex; padding: 0.4rem 0.7rem; font-size: 0.85rem; font-weight: 600; color: var(--primary); }
|
|
245
|
+
.nav-menu__more:hover { color: var(--primary-hover); }
|
|
246
|
+
.apex-dark .nav-menu__trigger { color: var(--on-dark-muted); }
|
|
247
|
+
.apex-dark .nav-menu__trigger:hover { color: var(--on-dark); }
|
|
248
|
+
/* The panel is a light popover; its links must NOT inherit the dark-chrome
|
|
249
|
+
nav-link color (.apex-dark .nav-links a, specificity 0,2,1) or a consumer's
|
|
250
|
+
own .nav-links a. Pin both link types with matching specificity (0,2,1) so
|
|
251
|
+
titles + the footer link stay readable in the dark theme. */
|
|
252
|
+
.nav-menu__panel a.nav-menu__item { color: var(--fg); }
|
|
253
|
+
.nav-menu__panel a.nav-menu__item:hover { color: var(--fg); }
|
|
254
|
+
.nav-menu__panel a.nav-menu__more { color: var(--primary); }
|
|
255
|
+
.nav-menu__panel a.nav-menu__more:hover { color: var(--primary-hover); }
|
|
256
|
+
`;
|
|
257
|
+
// Standalone mobile-open rules for .nav-toggle, split out of RESPONSIVE so a
|
|
258
|
+
// consumer calling renderApexHeader() outside renderApexPage (money-horse,
|
|
259
|
+
// show-pony, the docs sample) can include just this alongside
|
|
260
|
+
// APEX_NAV_MENU_CSS, without pulling in the rest of RESPONSIVE's page-level
|
|
261
|
+
// grid breakpoints. The two "show" rules use the `.nav ` prefix (matching
|
|
262
|
+
// renderApexHeader's `<div class="container nav">` wrapper) to raise their
|
|
263
|
+
// specificity above APEX_NAV_MENU_CSS's bare `.nav-toggle`/`.nav-toggle__trigger`
|
|
264
|
+
// "display: none" defaults — that makes them win regardless of concatenation
|
|
265
|
+
// order, since a standalone consumer controls the order, not this file.
|
|
266
|
+
// Also declares `.nav { position: relative; }`: the open dropdown positions
|
|
267
|
+
// itself against .nav (`top/left/right` below), and renderApexPage's own
|
|
268
|
+
// CHROME_LIGHT already sets that, but a standalone consumer's own header CSS
|
|
269
|
+
// generally doesn't — without it the dropdown would anchor to the viewport
|
|
270
|
+
// instead of the header and open off-screen. Redeclaring it here is a no-op
|
|
271
|
+
// inside APEX_STRUCTURAL_CSS (same value, harmless if repeated).
|
|
272
|
+
export const APEX_NAV_TOGGLE_RESPONSIVE_CSS = `
|
|
273
|
+
@media (max-width: 640px) {
|
|
274
|
+
.nav { position: relative; }
|
|
275
|
+
.nav .nav-toggle { display: inline-flex; }
|
|
276
|
+
.nav .nav-toggle__trigger { display: inline-flex; }
|
|
277
|
+
.nav-toggle[open] > .nav-links { display: flex; flex-direction: column; align-items: stretch;
|
|
278
|
+
gap: 0.25rem; position: absolute; top: calc(100% + 0.5rem); left: 0; right: 0; z-index: 30;
|
|
279
|
+
background: var(--bg-card); border: 1px solid var(--border); border-radius: 0.75rem;
|
|
280
|
+
box-shadow: var(--shadow); padding: 0.75rem; }
|
|
281
|
+
.nav-toggle[open] > .nav-links > a { color: var(--fg); padding: 0.4rem 0.25rem; }
|
|
282
|
+
.nav-toggle[open] > .nav-links > a:hover { color: var(--fg); }
|
|
283
|
+
.nav-toggle .nav-menu { display: block; }
|
|
284
|
+
.nav-toggle .nav-menu__panel { position: static; min-width: 0;
|
|
285
|
+
margin-top: 0.375rem; box-shadow: none; }
|
|
286
|
+
}
|
|
287
|
+
`;
|
|
288
|
+
export const APEX_STRUCTURAL_CSS = BASE_LAYOUT +
|
|
289
|
+
HERO +
|
|
290
|
+
FEATURES +
|
|
291
|
+
PRICING +
|
|
292
|
+
TRUST +
|
|
293
|
+
FINAL_CTA +
|
|
294
|
+
CHROME_LIGHT +
|
|
295
|
+
CHROME_DARK +
|
|
296
|
+
APEX_NAV_MENU_CSS +
|
|
297
|
+
APEX_NAV_TOGGLE_RESPONSIVE_CSS +
|
|
298
|
+
RESPONSIVE;
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import type { TenantId } from "@cosmicdrift/kumiko-framework/engine";
|
|
2
|
+
export { APEX_NAV_MENU_CSS, APEX_NAV_TOGGLE_RESPONSIVE_CSS, APEX_STRUCTURAL_CSS } from "./css.ts";
|
|
3
|
+
export { APEX_LIGHTBOX_HTML, APEX_LIGHTBOX_SCRIPT, APEX_LIGHTBOX_SCRIPT_CSP_HASH, } from "./lightbox.ts";
|
|
4
|
+
export type ApexTheme = "light" | "dark";
|
|
5
|
+
/** Brand is raw CSS the app owns: the :root token block and optional @font-face.
|
|
6
|
+
* Token names referenced by the structural CSS: --bg --bg-card --bg-muted
|
|
7
|
+
* --border --fg --fg-muted --fg-subtle --primary --primary-hover --primary-fg
|
|
8
|
+
* --status-ok --shadow. Optional: --accent --accent-fg --font-mono --font-body,
|
|
9
|
+
* and (dark theme) --on-dark --on-dark-muted --on-dark-border. */
|
|
10
|
+
export type ApexBrand = {
|
|
11
|
+
readonly tokensCss: string;
|
|
12
|
+
readonly fontFaceCss?: string;
|
|
13
|
+
};
|
|
14
|
+
export type ApexCtaVariant = "primary" | "secondary" | "link";
|
|
15
|
+
export type ApexCta = {
|
|
16
|
+
readonly label: string;
|
|
17
|
+
/** App-authored only, no user input — escapeHtml encodes entities but does
|
|
18
|
+
* NOT sanitize the URL scheme (a `javascript:`/`data:` URI survives it
|
|
19
|
+
* unchanged). Trust boundary is the deploy-time apex config, not runtime. */
|
|
20
|
+
readonly href: string;
|
|
21
|
+
/** "link" renders a plain anchor (no .btn). Default "primary". */
|
|
22
|
+
readonly variant?: ApexCtaVariant;
|
|
23
|
+
};
|
|
24
|
+
export type ApexLink = {
|
|
25
|
+
readonly kind?: "link";
|
|
26
|
+
readonly label: string;
|
|
27
|
+
readonly href: string;
|
|
28
|
+
};
|
|
29
|
+
/** One entry inside a dropdown nav menu: icon + title + optional description. */
|
|
30
|
+
export type ApexNavMenuItem = {
|
|
31
|
+
/** Inner SVG markup (paths), wrapped by the standard 24px icon <svg>.
|
|
32
|
+
* ponytail: rendered verbatim, no sanitizer — trusted because it's
|
|
33
|
+
* app-authored at deploy time, same trust boundary as ApexCta.href. If an
|
|
34
|
+
* app ever sources this from tenant/user content, sanitize at that
|
|
35
|
+
* construction boundary before it reaches here. */
|
|
36
|
+
readonly icon?: string;
|
|
37
|
+
readonly title: string;
|
|
38
|
+
readonly desc?: string;
|
|
39
|
+
readonly href: string;
|
|
40
|
+
};
|
|
41
|
+
/** A header nav entry that opens a dropdown (icon/title/desc rows) instead of
|
|
42
|
+
* navigating. CSS-only: reveals on hover + keyboard focus. */
|
|
43
|
+
export type ApexNavMenu = {
|
|
44
|
+
readonly kind: "menu";
|
|
45
|
+
readonly label: string;
|
|
46
|
+
readonly items: readonly ApexNavMenuItem[];
|
|
47
|
+
/** Optional link under a divider at the foot of the panel (e.g. "See all →"). */
|
|
48
|
+
readonly footer?: ApexLink;
|
|
49
|
+
};
|
|
50
|
+
/** A header nav entry: a plain link, or a dropdown menu. */
|
|
51
|
+
export type ApexNavEntry = ApexLink | ApexNavMenu;
|
|
52
|
+
export type ApexImage = {
|
|
53
|
+
readonly src: string;
|
|
54
|
+
readonly alt: string;
|
|
55
|
+
readonly width?: number;
|
|
56
|
+
readonly height?: number;
|
|
57
|
+
};
|
|
58
|
+
export type ApexHeader = {
|
|
59
|
+
readonly brand: {
|
|
60
|
+
readonly href: string;
|
|
61
|
+
readonly label: string;
|
|
62
|
+
readonly logoSrc?: string;
|
|
63
|
+
};
|
|
64
|
+
/** Plain links and/or dropdown menus, in order. */
|
|
65
|
+
readonly navLinks?: readonly ApexNavEntry[];
|
|
66
|
+
readonly actions?: readonly ApexCta[];
|
|
67
|
+
/** aria-label for the mobile hamburger trigger (< 640px). Default "Menu". */
|
|
68
|
+
readonly menuLabel?: string;
|
|
69
|
+
};
|
|
70
|
+
export type ApexFooterColumn = {
|
|
71
|
+
readonly heading: string;
|
|
72
|
+
readonly links: readonly ApexLink[];
|
|
73
|
+
};
|
|
74
|
+
export type ApexFooter = {
|
|
75
|
+
readonly brand: {
|
|
76
|
+
readonly label: string;
|
|
77
|
+
readonly logoSrc?: string;
|
|
78
|
+
};
|
|
79
|
+
readonly tagline?: string;
|
|
80
|
+
readonly columns?: readonly ApexFooterColumn[];
|
|
81
|
+
/** Plain text — use unicode (© ·), not HTML entities; rendered escaped. */
|
|
82
|
+
readonly bottomLeft?: string;
|
|
83
|
+
readonly bottomRight?: string;
|
|
84
|
+
};
|
|
85
|
+
export type ApexHeroSection = {
|
|
86
|
+
readonly kind: "hero";
|
|
87
|
+
readonly logo?: ApexImage;
|
|
88
|
+
readonly title: string;
|
|
89
|
+
readonly tagline: string;
|
|
90
|
+
readonly ctas?: readonly ApexCta[];
|
|
91
|
+
/** App-authored trusted HTML (e.g. <strong>…<br/>); rendered verbatim. */
|
|
92
|
+
readonly metaHtml?: string;
|
|
93
|
+
readonly screenshot?: ApexImage;
|
|
94
|
+
};
|
|
95
|
+
export type ApexFeature = {
|
|
96
|
+
/** Inner SVG markup (paths), wrapped by the standard 24px icon <svg>.
|
|
97
|
+
* ponytail: rendered verbatim, no sanitizer — trusted because it's
|
|
98
|
+
* app-authored at deploy time, same trust boundary as ApexCta.href. If an
|
|
99
|
+
* app ever sources this from tenant/user content, sanitize at that
|
|
100
|
+
* construction boundary before it reaches here. */
|
|
101
|
+
readonly icon?: string;
|
|
102
|
+
readonly title: string;
|
|
103
|
+
readonly desc: string;
|
|
104
|
+
};
|
|
105
|
+
export type ApexFeatureGridSection = {
|
|
106
|
+
readonly kind: "feature-grid";
|
|
107
|
+
readonly id?: string;
|
|
108
|
+
readonly eyebrow?: string;
|
|
109
|
+
readonly heading: string;
|
|
110
|
+
readonly sub?: string;
|
|
111
|
+
/** Sit on the muted band (.features). Default true. */
|
|
112
|
+
readonly muted?: boolean;
|
|
113
|
+
readonly items: readonly ApexFeature[];
|
|
114
|
+
};
|
|
115
|
+
export type ApexPricingTier = {
|
|
116
|
+
readonly name: string;
|
|
117
|
+
readonly tagline?: string;
|
|
118
|
+
/** App-formatted ("4,99 €", "0 €", "auf Anfrage"). */
|
|
119
|
+
readonly amount: string;
|
|
120
|
+
/** Localized suffix after the amount ("/Monat", "/month"). */
|
|
121
|
+
readonly priceSuffix?: string;
|
|
122
|
+
readonly featured?: boolean;
|
|
123
|
+
readonly badge?: string;
|
|
124
|
+
readonly capLine?: string;
|
|
125
|
+
readonly benefits: readonly string[];
|
|
126
|
+
readonly cta: ApexCta;
|
|
127
|
+
};
|
|
128
|
+
export type ApexPricingGridSection = {
|
|
129
|
+
readonly kind: "pricing-grid";
|
|
130
|
+
readonly id?: string;
|
|
131
|
+
readonly eyebrow?: string;
|
|
132
|
+
readonly heading: string;
|
|
133
|
+
readonly sub?: string;
|
|
134
|
+
readonly tiers: readonly ApexPricingTier[];
|
|
135
|
+
};
|
|
136
|
+
export type ApexInfoItem = {
|
|
137
|
+
readonly title: string;
|
|
138
|
+
readonly desc: string;
|
|
139
|
+
};
|
|
140
|
+
export type ApexInfoGridSection = {
|
|
141
|
+
readonly kind: "info-grid";
|
|
142
|
+
readonly id?: string;
|
|
143
|
+
readonly eyebrow?: string;
|
|
144
|
+
readonly heading?: string;
|
|
145
|
+
readonly sub?: string;
|
|
146
|
+
readonly muted?: boolean;
|
|
147
|
+
readonly items: readonly ApexInfoItem[];
|
|
148
|
+
};
|
|
149
|
+
export type ApexFinalCtaSection = {
|
|
150
|
+
readonly kind: "final-cta";
|
|
151
|
+
readonly image?: ApexImage;
|
|
152
|
+
readonly heading: string;
|
|
153
|
+
readonly sub?: string;
|
|
154
|
+
readonly cta: ApexCta;
|
|
155
|
+
};
|
|
156
|
+
/** Escape hatch for an app-specific section: raw, app-authored HTML. */
|
|
157
|
+
export type ApexHtmlSection = {
|
|
158
|
+
readonly kind: "html";
|
|
159
|
+
readonly html: string;
|
|
160
|
+
};
|
|
161
|
+
export type ApexSection = ApexHeroSection | ApexFeatureGridSection | ApexPricingGridSection | ApexInfoGridSection | ApexFinalCtaSection | ApexHtmlSection;
|
|
162
|
+
export type ApexHead = {
|
|
163
|
+
readonly lang: string;
|
|
164
|
+
readonly title: string;
|
|
165
|
+
readonly description: string;
|
|
166
|
+
readonly canonicalUrl?: string;
|
|
167
|
+
readonly faviconHref?: string;
|
|
168
|
+
readonly ogImage?: string;
|
|
169
|
+
/** hreflang alternates for multilingual SEO (e.g. the other language's URL). */
|
|
170
|
+
readonly alternates?: readonly {
|
|
171
|
+
readonly hreflang: string;
|
|
172
|
+
readonly href: string;
|
|
173
|
+
}[];
|
|
174
|
+
/** Robots meta content (e.g. "index, follow", "noindex, nofollow"). Omit = no tag. */
|
|
175
|
+
readonly robots?: string;
|
|
176
|
+
/** og:site_name — brand name for social shares. */
|
|
177
|
+
readonly siteName?: string;
|
|
178
|
+
/** og:locale — e.g. "de_DE", "en_US". */
|
|
179
|
+
readonly locale?: string;
|
|
180
|
+
/** twitter:site — @handle for X/Twitter card. */
|
|
181
|
+
readonly twitterSite?: string;
|
|
182
|
+
/** URLs for <link rel="preconnect"> hints (Core Web Vitals). */
|
|
183
|
+
readonly preconnects?: readonly string[];
|
|
184
|
+
/** Arbitrary JSON-LD structured data (Schema.org). Rendered as-is into <script type="application/ld+json">. */
|
|
185
|
+
readonly schemaJson?: Record<string, unknown>;
|
|
186
|
+
};
|
|
187
|
+
export type ApexPage = {
|
|
188
|
+
readonly theme?: ApexTheme;
|
|
189
|
+
readonly brand: ApexBrand;
|
|
190
|
+
readonly head: ApexHead;
|
|
191
|
+
readonly header: ApexHeader;
|
|
192
|
+
readonly sections: readonly ApexSection[];
|
|
193
|
+
readonly footer: ApexFooter;
|
|
194
|
+
};
|
|
195
|
+
/** Render just the apex header chrome (brand + nav + actions). Exported so a
|
|
196
|
+
* consumer that composes its own page shell (not a full apex page) can reuse
|
|
197
|
+
* the identical header — markup stays single-source. */
|
|
198
|
+
export declare function renderApexHeader(h: ApexHeader): string;
|
|
199
|
+
export declare function renderApexHeadTags(head: ApexHead): string;
|
|
200
|
+
export declare function renderApexPage(page: ApexPage): string;
|
|
201
|
+
/** Per-request head metadata (Open-Graph/title/description) for a
|
|
202
|
+
* server-rendered HTML shell. Only `title` is required; everything else
|
|
203
|
+
* falls back to no tag rather than a placeholder. */
|
|
204
|
+
export type PageHeadMeta = {
|
|
205
|
+
readonly title: string;
|
|
206
|
+
readonly description?: string;
|
|
207
|
+
readonly ogImage?: string;
|
|
208
|
+
readonly canonicalUrl?: string;
|
|
209
|
+
readonly siteName?: string;
|
|
210
|
+
readonly locale?: string;
|
|
211
|
+
};
|
|
212
|
+
export type PageHeadSystemQuery = (type: string, payload: unknown, tenantId: TenantId, options?: {
|
|
213
|
+
readonly signal?: AbortSignal;
|
|
214
|
+
}) => Promise<unknown>;
|
|
215
|
+
export type PageHeadResolver = (input: {
|
|
216
|
+
readonly path: string;
|
|
217
|
+
readonly host: string;
|
|
218
|
+
readonly preferredLocales: readonly string[];
|
|
219
|
+
readonly systemQuery: PageHeadSystemQuery;
|
|
220
|
+
readonly signal: AbortSignal;
|
|
221
|
+
}) => Promise<PageHeadMeta | null>;
|
|
222
|
+
export type PageHeadResolveInput = {
|
|
223
|
+
readonly path: string;
|
|
224
|
+
readonly host: string;
|
|
225
|
+
readonly preferredLocales: readonly string[];
|
|
226
|
+
readonly systemQuery: PageHeadSystemQuery;
|
|
227
|
+
readonly requestSignal?: AbortSignal | undefined;
|
|
228
|
+
};
|
|
229
|
+
export declare function injectPageHead(html: string, tagsHtml: string): string;
|
|
230
|
+
/** Resolves per-request head metadata and splices it into `html`, capped at
|
|
231
|
+
* the shared timeout. Never throws and never changes `html` on a resolver
|
|
232
|
+
* error, a `null` resolve, or a timeout — the caller's shell always ships
|
|
233
|
+
* unchanged. runProdApp and runDevApp both call this single function, so a
|
|
234
|
+
* future change to timeout or fallback semantics has one place to land
|
|
235
|
+
* (kumiko-framework#3026). */
|
|
236
|
+
export declare function resolveAndInjectPageHead(html: string, resolvePageHead: PageHeadResolver, input: PageHeadResolveInput): Promise<string>;
|