@krizaka/ui 2.8.0 → 2.10.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 +73 -5
- package/dist/achievement.d.ts +54 -0
- package/dist/achievement.js +73 -0
- package/dist/achievement.js.map +1 -0
- package/dist/app-shell.d.ts +203 -0
- package/dist/app-shell.js +137 -0
- package/dist/app-shell.js.map +1 -0
- package/dist/auth-layout.d.ts +136 -0
- package/dist/auth-layout.js +75 -0
- package/dist/auth-layout.js.map +1 -0
- package/dist/blocks.css +247 -0
- package/dist/catalogue-page.d.ts +34 -0
- package/dist/catalogue-page.js +26 -0
- package/dist/catalogue-page.js.map +1 -0
- package/dist/changelog-page.d.ts +50 -0
- package/dist/changelog-page.js +27 -0
- package/dist/changelog-page.js.map +1 -0
- package/dist/choice-grid.d.ts +84 -0
- package/dist/choice-grid.js +141 -0
- package/dist/choice-grid.js.map +1 -0
- package/dist/chunk-555LWYIN.js +11 -0
- package/dist/chunk-555LWYIN.js.map +1 -0
- package/dist/chunk-AZPKXP3O.js +36 -0
- package/dist/chunk-AZPKXP3O.js.map +1 -0
- package/dist/{chunk-NOVUREEC.js → chunk-JZPVUJIX.js} +25 -3
- package/dist/chunk-JZPVUJIX.js.map +1 -0
- package/dist/chunk-KNBYZGSQ.js +11 -0
- package/dist/chunk-KNBYZGSQ.js.map +1 -0
- package/dist/chunk-VCAAHCHL.js +17 -0
- package/dist/chunk-VCAAHCHL.js.map +1 -0
- package/dist/code-block.js +23 -44
- package/dist/code-block.js.map +1 -1
- package/dist/component-page.d.ts +41 -0
- package/dist/component-page.js +17 -0
- package/dist/component-page.js.map +1 -0
- package/dist/contact-page.d.ts +31 -0
- package/dist/contact-page.js +26 -0
- package/dist/contact-page.js.map +1 -0
- package/dist/continue-prompt.d.ts +48 -0
- package/dist/continue-prompt.js +200 -0
- package/dist/continue-prompt.js.map +1 -0
- package/dist/dashboard-layout.d.ts +139 -0
- package/dist/dashboard-layout.js +68 -0
- package/dist/dashboard-layout.js.map +1 -0
- package/dist/detail-layout.d.ts +126 -0
- package/dist/detail-layout.js +48 -0
- package/dist/detail-layout.js.map +1 -0
- package/dist/docs-article-page.d.ts +54 -0
- package/dist/docs-article-page.js +29 -0
- package/dist/docs-article-page.js.map +1 -0
- package/dist/docs-hub-page.d.ts +72 -0
- package/dist/docs-hub-page.js +45 -0
- package/dist/docs-hub-page.js.map +1 -0
- package/dist/docs-layout.d.ts +78 -0
- package/dist/docs-layout.js +60 -0
- package/dist/docs-layout.js.map +1 -0
- package/dist/error-page.d.ts +22 -0
- package/dist/error-page.js +23 -0
- package/dist/error-page.js.map +1 -0
- package/dist/gallery-page.d.ts +50 -0
- package/dist/gallery-page.js +30 -0
- package/dist/gallery-page.js.map +1 -0
- package/dist/{geometry-CXrAW34x.d.ts → geometry-CbOU4rtL.d.ts} +4 -4
- package/dist/goal-gauge.d.ts +38 -0
- package/dist/goal-gauge.js +53 -0
- package/dist/goal-gauge.js.map +1 -0
- package/dist/how-it-works-page.d.ts +48 -0
- package/dist/how-it-works-page.js +28 -0
- package/dist/how-it-works-page.js.map +1 -0
- package/dist/index.d.ts +16 -6
- package/dist/index.js +115 -24
- package/dist/index.js.map +1 -1
- package/dist/landing-page.d.ts +58 -0
- package/dist/landing-page.js +42 -0
- package/dist/landing-page.js.map +1 -0
- package/dist/landscape.d.ts +41 -0
- package/dist/landscape.js +836 -0
- package/dist/landscape.js.map +1 -0
- package/dist/legal-page.d.ts +34 -0
- package/dist/legal-page.js +18 -0
- package/dist/legal-page.js.map +1 -0
- package/dist/longform-page.d.ts +42 -0
- package/dist/longform-page.js +29 -0
- package/dist/longform-page.js.map +1 -0
- package/dist/marketing-layout.d.ts +60 -0
- package/dist/marketing-layout.js +25 -0
- package/dist/marketing-layout.js.map +1 -0
- package/dist/mascot-quote.d.ts +4 -4
- package/dist/mascot-quote.js +23 -1
- package/dist/mascot-quote.js.map +1 -1
- package/dist/mascot-state.d.ts +2 -2
- package/dist/mascot-state.js +1 -1
- package/dist/mascot-state.js.map +1 -1
- package/dist/mascots.d.ts +18 -5
- package/dist/mascots.js +87 -2
- package/dist/mascots.js.map +1 -1
- package/dist/native.d.ts +88 -11
- package/dist/native.js +640 -297
- package/dist/native.js.map +1 -1
- package/dist/pricing-page.d.ts +62 -0
- package/dist/pricing-page.js +71 -0
- package/dist/pricing-page.js.map +1 -0
- package/dist/product-page.d.ts +83 -0
- package/dist/product-page.js +60 -0
- package/dist/product-page.js.map +1 -0
- package/dist/profile-card.d.ts +85 -0
- package/dist/profile-card.js +87 -0
- package/dist/profile-card.js.map +1 -0
- package/dist/promise-card.d.ts +28 -0
- package/dist/promise-card.js +29 -0
- package/dist/promise-card.js.map +1 -0
- package/dist/scroll-stage.d.ts +603 -0
- package/dist/scroll-stage.js +59 -0
- package/dist/scroll-stage.js.map +1 -0
- package/dist/settings-layout.d.ts +154 -0
- package/dist/settings-layout.js +57 -0
- package/dist/settings-layout.js.map +1 -0
- package/dist/split-view.d.ts +106 -0
- package/dist/split-view.js +41 -0
- package/dist/split-view.js.map +1 -0
- package/dist/stage-banner.d.ts +34 -0
- package/dist/stage-banner.js +26 -0
- package/dist/stage-banner.js.map +1 -0
- package/dist/status-page.d.ts +42 -0
- package/dist/status-page.js +28 -0
- package/dist/status-page.js.map +1 -0
- package/dist/story-variant-CLn4H5Nt.d.ts +4 -0
- package/dist/story.css +432 -0
- package/package.json +478 -10
- package/registry/achievement.json +322 -0
- package/registry/action-bar.json +1 -1
- package/registry/alert.json +1 -1
- package/registry/app-shell.json +451 -0
- package/registry/argument-card.json +1 -1
- package/registry/audio-player.json +1 -1
- package/registry/auth-layout.json +230 -0
- package/registry/avatar.json +1 -1
- package/registry/badge.json +1 -1
- package/registry/button.json +5 -5
- package/registry/card-grid.json +5 -5
- package/registry/card.json +3 -3
- package/registry/catalogue-page.json +240 -0
- package/registry/changelog-page.json +226 -0
- package/registry/checkbox.json +1 -1
- package/registry/chip-link.json +1 -1
- package/registry/chip.json +1 -1
- package/registry/choice-grid.json +318 -0
- package/registry/code-block.json +1 -1
- package/registry/combobox.json +1 -1
- package/registry/command.json +1 -1
- package/registry/component-page.json +227 -0
- package/registry/confirm-button.json +3 -3
- package/registry/contact-page.json +212 -0
- package/registry/continue-prompt.json +312 -0
- package/registry/countdown.json +1 -1
- package/registry/cta-panel.json +1 -1
- package/registry/dashboard-layout.json +273 -0
- package/registry/data-table.json +1 -1
- package/registry/date-picker.json +1 -1
- package/registry/decision-list.json +1 -1
- package/registry/detail-layout.json +233 -0
- package/registry/dialog.json +1 -1
- package/registry/docs-article-page.json +242 -0
- package/registry/docs-hub-page.json +270 -0
- package/registry/docs-layout.json +148 -0
- package/registry/dropdown-menu.json +3 -3
- package/registry/empty-state.json +1 -1
- package/registry/error-page.json +183 -0
- package/registry/examples/achievement/arcade.d.ts +4 -0
- package/registry/examples/achievement/arcade.js +15 -0
- package/registry/examples/achievement/arcade.tsx +12 -0
- package/registry/examples/achievement/milestones.d.ts +4 -0
- package/registry/examples/achievement/milestones.js +15 -0
- package/registry/examples/achievement/milestones.tsx +12 -0
- package/registry/examples/app-shell/admin-console.d.ts +4 -0
- package/registry/examples/app-shell/admin-console.js +52 -0
- package/registry/examples/app-shell/admin-console.tsx +64 -0
- package/registry/examples/app-shell/basic.d.ts +4 -0
- package/registry/examples/app-shell/basic.js +37 -0
- package/registry/examples/app-shell/basic.tsx +31 -0
- package/registry/examples/app-shell/orochia-studio.d.ts +4 -0
- package/registry/examples/app-shell/orochia-studio.js +89 -0
- package/registry/examples/app-shell/orochia-studio.tsx +101 -0
- package/registry/examples/auth-layout/onboarding.d.ts +4 -0
- package/registry/examples/auth-layout/onboarding.js +56 -0
- package/registry/examples/auth-layout/onboarding.tsx +47 -0
- package/registry/examples/auth-layout/sign-in.d.ts +4 -0
- package/registry/examples/auth-layout/sign-in.js +55 -0
- package/registry/examples/auth-layout/sign-in.tsx +47 -0
- package/registry/examples/auth-layout/verify.d.ts +4 -0
- package/registry/examples/auth-layout/verify.js +23 -0
- package/registry/examples/auth-layout/verify.tsx +19 -0
- package/registry/examples/catalogue-page/components.d.ts +4 -0
- package/registry/examples/catalogue-page/components.js +33 -0
- package/registry/examples/catalogue-page/components.tsx +36 -0
- package/registry/examples/changelog-page/releases.d.ts +4 -0
- package/registry/examples/changelog-page/releases.js +44 -0
- package/registry/examples/changelog-page/releases.tsx +39 -0
- package/registry/examples/choice-grid/line-up.d.ts +4 -0
- package/registry/examples/choice-grid/line-up.js +37 -0
- package/registry/examples/choice-grid/line-up.tsx +32 -0
- package/registry/examples/choice-grid/plans.d.ts +4 -0
- package/registry/examples/choice-grid/plans.js +28 -0
- package/registry/examples/choice-grid/plans.tsx +24 -0
- package/registry/examples/component-page/button.d.ts +4 -0
- package/registry/examples/component-page/button.js +33 -0
- package/registry/examples/component-page/button.tsx +30 -0
- package/registry/examples/contact-page/team.d.ts +4 -0
- package/registry/examples/contact-page/team.js +39 -0
- package/registry/examples/contact-page/team.tsx +38 -0
- package/registry/examples/continue-prompt/arcade.d.ts +4 -0
- package/registry/examples/continue-prompt/arcade.js +28 -0
- package/registry/examples/continue-prompt/arcade.tsx +25 -0
- package/registry/examples/continue-prompt/offer.d.ts +4 -0
- package/registry/examples/continue-prompt/offer.js +24 -0
- package/registry/examples/continue-prompt/offer.tsx +19 -0
- package/registry/examples/dashboard-layout/orazaka-eric.d.ts +4 -0
- package/registry/examples/dashboard-layout/orazaka-eric.js +58 -0
- package/registry/examples/dashboard-layout/orazaka-eric.tsx +80 -0
- package/registry/examples/dashboard-layout/widgets.d.ts +4 -0
- package/registry/examples/dashboard-layout/widgets.js +17 -0
- package/registry/examples/dashboard-layout/widgets.tsx +22 -0
- package/registry/examples/detail-layout/job.d.ts +4 -0
- package/registry/examples/detail-layout/job.js +25 -0
- package/registry/examples/detail-layout/job.tsx +20 -0
- package/registry/examples/detail-layout/video.d.ts +4 -0
- package/registry/examples/detail-layout/video.js +44 -0
- package/registry/examples/detail-layout/video.tsx +53 -0
- package/registry/examples/docs-article-page/cli.d.ts +4 -0
- package/registry/examples/docs-article-page/cli.js +33 -0
- package/registry/examples/docs-article-page/cli.tsx +38 -0
- package/registry/examples/docs-hub-page/krizaka.d.ts +4 -0
- package/registry/examples/docs-hub-page/krizaka.js +46 -0
- package/registry/examples/docs-hub-page/krizaka.tsx +37 -0
- package/registry/examples/docs-layout/page.d.ts +4 -0
- package/registry/examples/docs-layout/page.js +26 -0
- package/registry/examples/docs-layout/page.tsx +30 -0
- package/registry/examples/error-page/not-found.d.ts +4 -0
- package/registry/examples/error-page/not-found.js +24 -0
- package/registry/examples/error-page/not-found.tsx +19 -0
- package/registry/examples/gallery-page/made-here.d.ts +4 -0
- package/registry/examples/gallery-page/made-here.js +34 -0
- package/registry/examples/gallery-page/made-here.tsx +32 -0
- package/registry/examples/goal-gauge/arcade.d.ts +4 -0
- package/registry/examples/goal-gauge/arcade.js +11 -0
- package/registry/examples/goal-gauge/arcade.tsx +10 -0
- package/registry/examples/goal-gauge/challenge.d.ts +4 -0
- package/registry/examples/goal-gauge/challenge.js +11 -0
- package/registry/examples/goal-gauge/challenge.tsx +10 -0
- package/registry/examples/goal-gauge/drain.d.ts +4 -0
- package/registry/examples/goal-gauge/drain.js +11 -0
- package/registry/examples/goal-gauge/drain.tsx +10 -0
- package/registry/examples/goal-gauge/native/default.d.ts +4 -0
- package/registry/examples/goal-gauge/native/default.dark.png +0 -0
- package/registry/examples/goal-gauge/native/default.js +15 -0
- package/registry/examples/goal-gauge/native/default.light.png +0 -0
- package/registry/examples/goal-gauge/native/default.tsx +12 -0
- package/registry/examples/how-it-works-page/orazaka.d.ts +4 -0
- package/registry/examples/how-it-works-page/orazaka.js +30 -0
- package/registry/examples/how-it-works-page/orazaka.tsx +26 -0
- package/registry/examples/landing-page/krizaka.d.ts +4 -0
- package/registry/examples/landing-page/krizaka.js +44 -0
- package/registry/examples/landing-page/krizaka.tsx +44 -0
- package/registry/examples/landscape/backdrop.d.ts +4 -0
- package/registry/examples/landscape/backdrop.js +14 -0
- package/registry/examples/landscape/backdrop.tsx +11 -0
- package/registry/examples/landscape/brand.d.ts +4 -0
- package/registry/examples/landscape/brand.js +11 -0
- package/registry/examples/landscape/brand.tsx +10 -0
- package/registry/examples/legal-page/privacy.d.ts +4 -0
- package/registry/examples/legal-page/privacy.js +24 -0
- package/registry/examples/legal-page/privacy.tsx +19 -0
- package/registry/examples/longform-page/story.d.ts +4 -0
- package/registry/examples/longform-page/story.js +38 -0
- package/registry/examples/longform-page/story.tsx +35 -0
- package/registry/examples/marketing-layout/basic.d.ts +4 -0
- package/registry/examples/marketing-layout/basic.js +31 -0
- package/registry/examples/marketing-layout/basic.tsx +28 -0
- package/registry/examples/marketing-layout/docs-hub.d.ts +4 -0
- package/registry/examples/marketing-layout/docs-hub.js +37 -0
- package/registry/examples/marketing-layout/docs-hub.tsx +44 -0
- package/registry/examples/marketing-layout/pricing.d.ts +4 -0
- package/registry/examples/marketing-layout/pricing.js +45 -0
- package/registry/examples/marketing-layout/pricing.tsx +55 -0
- package/registry/examples/marketing-layout/product-page.d.ts +4 -0
- package/registry/examples/marketing-layout/product-page.js +79 -0
- package/registry/examples/marketing-layout/product-page.tsx +83 -0
- package/registry/examples/mascots/crane.d.ts +4 -0
- package/registry/examples/mascots/crane.js +19 -0
- package/registry/examples/mascots/crane.tsx +18 -0
- package/registry/examples/mascots/flock.tsx +2 -1
- package/registry/examples/mascots/native/crane.d.ts +4 -0
- package/registry/examples/mascots/native/crane.dark.png +0 -0
- package/registry/examples/mascots/native/crane.js +21 -0
- package/registry/examples/mascots/native/crane.light.png +0 -0
- package/registry/examples/mascots/native/crane.tsx +18 -0
- package/registry/examples/mascots/native/phoenix.d.ts +4 -0
- package/registry/examples/mascots/native/phoenix.dark.png +0 -0
- package/registry/examples/mascots/native/phoenix.js +21 -0
- package/registry/examples/mascots/native/phoenix.light.png +0 -0
- package/registry/examples/mascots/native/phoenix.tsx +18 -0
- package/registry/examples/mascots/phoenix.d.ts +4 -0
- package/registry/examples/mascots/phoenix.js +14 -0
- package/registry/examples/mascots/phoenix.tsx +11 -0
- package/registry/examples/pricing-page/credits.d.ts +4 -0
- package/registry/examples/pricing-page/credits.js +41 -0
- package/registry/examples/pricing-page/credits.tsx +33 -0
- package/registry/examples/product-page/orazaka.d.ts +4 -0
- package/registry/examples/product-page/orazaka.js +44 -0
- package/registry/examples/product-page/orazaka.tsx +36 -0
- package/registry/examples/profile-card/arcade.d.ts +4 -0
- package/registry/examples/profile-card/arcade.js +25 -0
- package/registry/examples/profile-card/arcade.tsx +19 -0
- package/registry/examples/profile-card/creator.d.ts +4 -0
- package/registry/examples/profile-card/creator.js +31 -0
- package/registry/examples/profile-card/creator.tsx +26 -0
- package/registry/examples/profile-card/match.d.ts +4 -0
- package/registry/examples/profile-card/match.js +25 -0
- package/registry/examples/profile-card/match.tsx +19 -0
- package/registry/examples/profile-card/native/default.d.ts +4 -0
- package/registry/examples/profile-card/native/default.dark.png +0 -0
- package/registry/examples/profile-card/native/default.js +27 -0
- package/registry/examples/profile-card/native/default.light.png +0 -0
- package/registry/examples/profile-card/native/default.tsx +22 -0
- package/registry/examples/promise-card/arcade.d.ts +4 -0
- package/registry/examples/promise-card/arcade.js +25 -0
- package/registry/examples/promise-card/arcade.tsx +19 -0
- package/registry/examples/promise-card/guarantee.d.ts +4 -0
- package/registry/examples/promise-card/guarantee.js +23 -0
- package/registry/examples/promise-card/guarantee.tsx +17 -0
- package/registry/examples/scroll-stage/arcade.d.ts +4 -0
- package/registry/examples/scroll-stage/arcade.js +16 -0
- package/registry/examples/scroll-stage/arcade.tsx +15 -0
- package/registry/examples/scroll-stage/chapters.d.ts +4 -0
- package/registry/examples/scroll-stage/chapters.js +25 -0
- package/registry/examples/scroll-stage/chapters.tsx +22 -0
- package/registry/examples/settings-layout/account.d.ts +4 -0
- package/registry/examples/settings-layout/account.js +51 -0
- package/registry/examples/settings-layout/account.tsx +50 -0
- package/registry/examples/settings-layout/sections.d.ts +4 -0
- package/registry/examples/settings-layout/sections.js +27 -0
- package/registry/examples/settings-layout/sections.tsx +24 -0
- package/registry/examples/split-view/empty.d.ts +4 -0
- package/registry/examples/split-view/empty.js +19 -0
- package/registry/examples/split-view/empty.tsx +13 -0
- package/registry/examples/split-view/messages.d.ts +4 -0
- package/registry/examples/split-view/messages.js +49 -0
- package/registry/examples/split-view/messages.tsx +52 -0
- package/registry/examples/stage-banner/round.d.ts +4 -0
- package/registry/examples/stage-banner/round.js +14 -0
- package/registry/examples/stage-banner/round.tsx +11 -0
- package/registry/examples/stage-banner/steps.d.ts +4 -0
- package/registry/examples/stage-banner/steps.js +14 -0
- package/registry/examples/stage-banner/steps.tsx +11 -0
- package/registry/examples/status-page/building.d.ts +4 -0
- package/registry/examples/status-page/building.js +29 -0
- package/registry/examples/status-page/building.tsx +25 -0
- package/registry/examples/status-page/operational.d.ts +4 -0
- package/registry/examples/status-page/operational.js +26 -0
- package/registry/examples/status-page/operational.tsx +20 -0
- package/registry/field.json +1 -1
- package/registry/file-upload.json +1 -1
- package/registry/filter-bar.json +1 -1
- package/registry/gallery-page.json +256 -0
- package/registry/glow-card.json +1 -1
- package/registry/goal-gauge.json +322 -0
- package/registry/how-it-works-page.json +242 -0
- package/registry/image-cropper.json +1 -1
- package/registry/index.json +621 -5
- package/registry/iso.json +1 -1
- package/registry/kbd.json +1 -1
- package/registry/landing-page.json +242 -0
- package/registry/landscape.json +189 -0
- package/registry/legal-page.json +199 -0
- package/registry/link-card.json +1 -1
- package/registry/loader.json +1 -1
- package/registry/longform-page.json +213 -0
- package/registry/marketing-layout.json +172 -0
- package/registry/marquee.json +1 -1
- package/registry/mascot-quote.json +6 -6
- package/registry/mascot-state.json +34 -34
- package/registry/mascots.json +140 -23
- package/registry/media-capture.json +1 -1
- package/registry/meter.json +1 -1
- package/registry/nav-bar.json +1 -1
- package/registry/number-ticker.json +1 -1
- package/registry/page-header.json +1 -1
- package/registry/page-hero.json +3 -3
- package/registry/page.json +5 -5
- package/registry/pagination.json +1 -1
- package/registry/pointer-light.json +1 -1
- package/registry/popover.json +1 -1
- package/registry/pricing-page.json +245 -0
- package/registry/product-page.json +319 -0
- package/registry/profile-card.json +501 -0
- package/registry/progress.json +1 -1
- package/registry/promise-card.json +228 -0
- package/registry/radio-group.json +1 -1
- package/registry/scroll-stage.json +197 -0
- package/registry/search-field.json +1 -1
- package/registry/section-backdrop.json +1 -1
- package/registry/separator.json +1 -1
- package/registry/settings-layout.json +231 -0
- package/registry/skeleton.json +1 -1
- package/registry/slider.json +1 -1
- package/registry/slot.json +1 -1
- package/registry/spinner.json +1 -1
- package/registry/split-view.json +233 -0
- package/registry/stage-banner.json +221 -0
- package/registry/stat.json +1 -1
- package/registry/status-page.json +263 -0
- package/registry/stepper.json +1 -1
- package/registry/switch.json +1 -1
- package/registry/tabs.json +1 -1
- package/registry/tag-input.json +1 -1
- package/registry/terminal-replay.json +1 -1
- package/registry/theme.json +1 -1
- package/registry/toast.json +1 -1
- package/registry/toc.json +1 -1
- package/registry/tooltip.json +1 -1
- package/registry/video-player.json +1 -1
- package/registry/video-trimmer.json +1 -1
- package/dist/chunk-NOVUREEC.js.map +0 -1
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "landscape",
|
|
3
|
+
"type": "primitive",
|
|
4
|
+
"title": "Landscape",
|
|
5
|
+
"summary": "The Krizaka valley at dusk — peaks, a phoenix over a river of two flames, trees of light and the flock at work: a decorative backdrop in its own colours or in the host brand's.",
|
|
6
|
+
"description": "The Krizaka valley at dusk — peaks, a phoenix over a river of two flames, trees of light and the flock at work: a decorative backdrop in its own colours or in the host brand's.",
|
|
7
|
+
"status": "beta",
|
|
8
|
+
"category": "blocks",
|
|
9
|
+
"platforms": "web",
|
|
10
|
+
"whenToUse": [
|
|
11
|
+
"Behind the end of a told page or a home's first screen, under the last words.",
|
|
12
|
+
"A product's about page, in its own accents (`tone=\"brand\"`, `flock={false}` for a calmer one)."
|
|
13
|
+
],
|
|
14
|
+
"whenNotToUse": [
|
|
15
|
+
{
|
|
16
|
+
"when": "Behind a section's content: the brand's gradient and grid are the section backdrop.",
|
|
17
|
+
"use": "section-backdrop"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"when": "In a working screen, or behind text that must be read."
|
|
21
|
+
}
|
|
22
|
+
],
|
|
23
|
+
"bestPractices": [
|
|
24
|
+
"Place it at the bottom of a positioned parent with room under the words; it fades into the surface.",
|
|
25
|
+
"Hold it still (`animated={false}`) on a page that already moves; it pauses off screen with `MotionObserver`.",
|
|
26
|
+
"The birds are hidden under 1024 px: on a phone the valley stays calm."
|
|
27
|
+
],
|
|
28
|
+
"accessibility": {
|
|
29
|
+
"keyboard": [],
|
|
30
|
+
"notes": [
|
|
31
|
+
"Decorative (`aria-hidden`): it never carries information.",
|
|
32
|
+
"Every loop holds its first frame under `prefers-reduced-motion`, with `animated={false}`, and while off screen."
|
|
33
|
+
]
|
|
34
|
+
},
|
|
35
|
+
"related": [
|
|
36
|
+
"section-backdrop",
|
|
37
|
+
"mascots",
|
|
38
|
+
"page-hero"
|
|
39
|
+
],
|
|
40
|
+
"web": {
|
|
41
|
+
"entry": "@krizaka/ui/landscape",
|
|
42
|
+
"import": "import { Landscape } from \"@krizaka/ui/landscape\";",
|
|
43
|
+
"props": [
|
|
44
|
+
{
|
|
45
|
+
"component": "Landscape",
|
|
46
|
+
"description": "The Krizaka landscape: a decorative backdrop for a hero or a page's end (`aria-hidden`).",
|
|
47
|
+
"props": [
|
|
48
|
+
{
|
|
49
|
+
"name": "animated",
|
|
50
|
+
"type": "boolean",
|
|
51
|
+
"default": "true",
|
|
52
|
+
"description": "The slow loops (the sun, the stars, the flames, the birds). `false` holds the first frame; always held under\n`prefers-reduced-motion` and while off screen (with `MotionObserver`).",
|
|
53
|
+
"required": false
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"name": "fade",
|
|
57
|
+
"type": "boolean",
|
|
58
|
+
"default": "true",
|
|
59
|
+
"description": "Fades the bottom into the page's surface.",
|
|
60
|
+
"required": false
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"name": "flock",
|
|
64
|
+
"type": "boolean",
|
|
65
|
+
"default": "true",
|
|
66
|
+
"description": "The flock at work in the valley (hidden under 1024 px wide either way).",
|
|
67
|
+
"required": false
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"name": "phoenix",
|
|
71
|
+
"type": "boolean",
|
|
72
|
+
"default": "true",
|
|
73
|
+
"description": "The phoenix and its river of two flames.",
|
|
74
|
+
"required": false
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"name": "position",
|
|
78
|
+
"type": "\"absolute\" | \"relative\"",
|
|
79
|
+
"default": "absolute",
|
|
80
|
+
"description": "`absolute`: fills its positioned parent, anchored at the bottom (a backdrop). `relative`: a block in the flow — give\nit a height.",
|
|
81
|
+
"required": false
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"name": "tone",
|
|
85
|
+
"type": "\"brand\" | \"own\"",
|
|
86
|
+
"default": "own",
|
|
87
|
+
"description": "`own`: the Krizaka dusk (indigo, cyan and magenta peaks). `brand`: the sky and the peaks in the host brand's\naccents (`.brand-<id>`). The birds and the phoenix keep their own colours.",
|
|
88
|
+
"required": false
|
|
89
|
+
}
|
|
90
|
+
]
|
|
91
|
+
}
|
|
92
|
+
],
|
|
93
|
+
"examples": [
|
|
94
|
+
{
|
|
95
|
+
"name": "backdrop",
|
|
96
|
+
"title": "A page's end",
|
|
97
|
+
"description": "The valley behind the last words, faded into the surface.",
|
|
98
|
+
"path": "examples/landscape/backdrop.tsx",
|
|
99
|
+
"module": "@krizaka/ui/registry/examples/landscape/backdrop",
|
|
100
|
+
"code": "import { Landscape } from \"@krizaka/ui/landscape\";\n\n// A page's end: the Krizaka valley at dusk behind the last words, faded into the surface.\nexport default function LandscapeBackdrop() {\n return (\n <div className=\"relative h-80 w-full max-w-3xl overflow-hidden rounded-2xl border border-border-subtle\">\n <Landscape animated={false} />\n <p className=\"relative z-10 p-6 text-lg font-semibold text-fg\">Built in the open, in Montréal.</p>\n </div>\n );\n}\n"
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
"name": "brand",
|
|
104
|
+
"title": "In the brand's colours",
|
|
105
|
+
"description": "`tone=\"brand\"` without the flock: the sky and the peaks in the host's accents.",
|
|
106
|
+
"path": "examples/landscape/brand.tsx",
|
|
107
|
+
"module": "@krizaka/ui/registry/examples/landscape/brand",
|
|
108
|
+
"code": "import { Landscape } from \"@krizaka/ui/landscape\";\n\n// `tone=\"brand\"`: the sky and the peaks in the host brand's accents; without the flock, a calmer backdrop.\nexport default function LandscapeBrand() {\n return (\n <div className=\"brand-orazaka relative h-64 w-full max-w-3xl overflow-hidden rounded-2xl border border-border-subtle\">\n <Landscape tone=\"brand\" flock={false} animated={false} />\n </div>\n );\n}\n"
|
|
109
|
+
}
|
|
110
|
+
]
|
|
111
|
+
},
|
|
112
|
+
"native": null,
|
|
113
|
+
"files": [
|
|
114
|
+
{
|
|
115
|
+
"path": "landscape/index.ts",
|
|
116
|
+
"content": "/** @krizaka/ui/landscape — `Landscape`, the Krizaka valley at dusk (brand layer, decorative). Client: ids per instance. */\nexport { Landscape, type LandscapeProps } from \"./landscape\";\n"
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
"path": "landscape/landscape.tsx",
|
|
120
|
+
"content": "// The Krizaka landscape — a valley at dusk under a constellation: three ranges of peaks, a phoenix over a river of\n// two flames, trees of light, a treehouse, and the flock at work (the falcon on watch, the owl, the duck at its\n// laptop, the flamingo). The brand layer's illustration, like the marks: drawn in code, ids unique per instance, its\n// own colours by default (`tone=\"own\"`) or the host brand's sky and peaks (`tone=\"brand\"`). Decorative.\nimport type * as React from \"react\";\nimport { useId } from \"react\";\n\nimport { cn } from \"../cn\";\n\n/** The sky and the peaks: the Krizaka dusk (`own`), or the host brand's accents (`brand`). Birds keep their colours. */\nconst TONES = {\n own: {\n \"--kzl-sun\": \"#f59e0b\",\n \"--kzl-sun-2\": \"#ec4899\",\n \"--kzl-sun-3\": \"#6366f1\",\n \"--kzl-far\": \"#6366f1\",\n \"--kzl-far-2\": \"#4f46e5\",\n \"--kzl-far-line\": \"#818cf8\",\n \"--kzl-mid\": \"#06b6d4\",\n \"--kzl-mid-2\": \"#0891b2\",\n \"--kzl-mid-line\": \"#22d3ee\",\n \"--kzl-near\": \"#d946ef\",\n \"--kzl-near-2\": \"#a855f7\",\n \"--kzl-near-line\": \"#e879f9\",\n \"--kzl-aurora-l\": \"#00f2fe\",\n \"--kzl-aurora-r\": \"#ec4899\",\n },\n brand: {\n \"--kzl-sun\": \"var(--kz-accent-2, var(--kz-accent))\",\n \"--kzl-sun-2\": \"var(--kz-accent)\",\n \"--kzl-sun-3\": \"var(--kz-accent)\",\n \"--kzl-far\": \"var(--kz-accent-2, var(--kz-accent))\",\n \"--kzl-far-2\": \"var(--kz-accent-2, var(--kz-accent))\",\n \"--kzl-far-line\": \"var(--kz-accent-2, var(--kz-accent))\",\n \"--kzl-mid\": \"color-mix(in srgb, var(--kz-accent) 55%, var(--kz-accent-2, var(--kz-accent)))\",\n \"--kzl-mid-2\": \"color-mix(in srgb, var(--kz-accent) 55%, var(--kz-accent-2, var(--kz-accent)))\",\n \"--kzl-mid-line\": \"color-mix(in srgb, var(--kz-accent) 55%, var(--kz-accent-2, var(--kz-accent)))\",\n \"--kzl-near\": \"var(--kz-accent)\",\n \"--kzl-near-2\": \"var(--kz-accent)\",\n \"--kzl-near-line\": \"var(--kz-accent)\",\n \"--kzl-aurora-l\": \"var(--kz-accent-2, var(--kz-accent))\",\n \"--kzl-aurora-r\": \"var(--kz-accent)\",\n },\n} as const;\n\nconst CSS = `\n.kzl { pointer-events: none; overflow: hidden; }\n.kzl-fade { position: absolute; bottom: 0; left: 0; right: 0; height: 120px; pointer-events: none; z-index: 3;\n background: linear-gradient(to top, var(--kz-surface-0) 0%, transparent 100%); }\n /* --- Cyber Phoenix & Flame Flow animations --- */\n @keyframes kzl-phoenix-flow-purple {\n from { stroke-dashoffset: 350; }\n to { stroke-dashoffset: 0; }\n }\n @keyframes kzl-phoenix-flow-gold {\n from { stroke-dashoffset: 0; }\n to { stroke-dashoffset: 350; }\n }\n @keyframes kzl-phoenix-bob {\n 0%, 100% { transform: translateY(0) scale(1); }\n 50% { transform: translateY(-8px) scale(1.02); }\n }\n @keyframes kzl-wing-flap-l-phoenix {\n 0%, 100% { transform: rotate(0deg); }\n 50% { transform: rotate(-10deg) translateY(-2px); }\n }\n @keyframes kzl-wing-flap-r-phoenix {\n 0%, 100% { transform: rotate(0deg); }\n 50% { transform: rotate(10deg) translateY(-2px); }\n }\n @keyframes kzl-core-glow {\n 0%, 100% { fill: #ffef5c; filter: drop-shadow(0 0 1px #ffef5c); }\n 50% { fill: #ffffff; filter: drop-shadow(0 0 5px #ff3c00); }\n }\n\n .kzl-cyber-phoenix {\n animation: kzl-phoenix-bob 4s ease-in-out infinite;\n transform-origin: 600px 325px;\n transition: transform 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);\n }\n .kzl-cyber-phoenix:hover {\n transform: translateY(-4px) scale(1.08);\n }\n .kzl-phoenix-wing-l {\n animation: kzl-wing-flap-l-phoenix 2.5s ease-in-out infinite;\n }\n .kzl-phoenix-wing-r {\n animation: kzl-wing-flap-r-phoenix 2.5s ease-in-out infinite;\n }\n .kzl-cyber-phoenix:hover .kzl-phoenix-wing-l {\n animation: kzl-wing-flap-l-phoenix 0.6s linear infinite;\n }\n .kzl-cyber-phoenix:hover .kzl-phoenix-wing-r {\n animation: kzl-wing-flap-r-phoenix 0.6s linear infinite;\n }\n .kzl-phoenix-core {\n animation: kzl-core-glow 1.5s ease-in-out infinite;\n }\n\n /* --- Pulse Animations --- */\n @keyframes kzl-opacity-pulse {\n 0%, 100% { opacity: 0.35; }\n 50% { opacity: 0.95; }\n }\n .kzl-pulse-slow {\n animation: kzl-opacity-pulse 4s ease-in-out infinite;\n }\n @keyframes kzl-sun-pulse {\n 0%, 100% { opacity: 0.16; transform: scale(0.96); }\n 50% { opacity: 0.32; transform: scale(1.04); }\n }\n .kzl-sun-pulsing {\n animation: kzl-sun-pulse 6s ease-in-out infinite;\n transform-origin: 600px 200px;\n }\n\n /* --- Rising local data pulses --- */\n @keyframes kzl-rise-fade-1 {\n 0% { transform: translateY(80px) scale(0.5); opacity: 0; }\n 40% { opacity: 0.8; }\n 100% { transform: translateY(-30px) scale(1.3); opacity: 0; }\n }\n @keyframes kzl-rise-fade-2 {\n 0% { transform: translateY(60px) scale(0.4); opacity: 0; }\n 50% { opacity: 0.9; }\n 100% { transform: translateY(-50px) scale(1.2); opacity: 0; }\n }\n .kzl-rising-pulse-1 {\n animation: kzl-rise-fade-1 4s cubic-bezier(0.1, 0.8, 0.3, 1) infinite;\n transform-origin: center;\n }\n .kzl-rising-pulse-2 {\n animation: kzl-rise-fade-2 5s cubic-bezier(0.1, 0.8, 0.3, 1) infinite 1.5s;\n transform-origin: center;\n }\n\n /* --- Mascot Hover Animations (Stable Hitboxes) --- */\n .kzl-bird-graphics {\n transform-box: fill-box;\n transform-origin: center;\n transition: transform 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);\n }\n .kzl-bird-hitbox:hover .kzl-bird-graphics {\n transform: scale(1.08) translateY(-4px);\n }\n\n /* --- Bird Eye Blinking/Glowing Animations --- */\n .kzl-falcon-eye {\n animation: kzl-falcon-eye-pulse 2.5s ease-in-out infinite;\n }\n .kzl-duck-eye {\n transform-box: fill-box;\n transform-origin: center;\n animation: kzl-eye-blink 5s ease-in-out infinite 1s;\n }\n .kzl-flamingo-eye {\n transform-box: fill-box;\n transform-origin: center;\n animation: kzl-eye-blink 6s ease-in-out infinite 2.5s;\n }\n .kzl-owl-eye {\n transform-box: fill-box;\n transform-origin: center;\n animation: kzl-eye-blink 4s ease-in-out infinite 0.5s;\n }\n\n @keyframes kzl-eye-blink {\n 0%, 90%, 100% {\n transform: scaleY(1);\n }\n 95% {\n transform: scaleY(0.15);\n }\n }\n\n @keyframes kzl-falcon-eye-pulse {\n 0%, 100% { fill: #00f2fe; filter: drop-shadow(0 0 2px #00f2fe); }\n 50% { fill: #00ff66; filter: drop-shadow(0 0 5px #00ff66); }\n }\n\n /* FalconBot constant loop animations */\n .kzl-falcon-bot .kzl-head-group {\n animation: kzl-head-bob 4s ease-in-out infinite;\n }\n .kzl-falcon-bot .kzl-wing-left {\n animation: kzl-wing-flap-left 3s ease-in-out infinite;\n }\n .kzl-falcon-bot .kzl-wing-right {\n animation: kzl-wing-flap-right 3s ease-in-out infinite;\n }\n .kzl-falcon-bot .kzl-sentry-laser {\n animation: kzl-scan-flicker 5s ease-in-out infinite;\n }\n\n @keyframes kzl-scan-flicker {\n 0%, 100% { opacity: 0; }\n 10%, 90% { opacity: 0.15; }\n 50% { opacity: 0.5; }\n }\n @keyframes kzl-head-bob {\n 0%, 100% { transform: translateY(0) rotate(0deg); }\n 50% { transform: translateY(-2px) rotate(2deg); }\n }\n @keyframes kzl-wing-flap-left {\n 0%, 100% { transform: rotate(0deg); }\n 50% { transform: rotate(-8deg) scaleX(1.05); }\n }\n @keyframes kzl-wing-flap-right {\n 0%, 100% { transform: rotate(0deg); }\n 50% { transform: rotate(8deg) scaleX(1.05); }\n }\n\n /* Developer Duck constant loop animations */\n .kzl-developer-duck .kzl-head-group {\n animation: kzl-duck-look 6s ease-in-out infinite;\n }\n .kzl-developer-duck .kzl-wing-left-type {\n animation: kzl-wing-type-l 0.5s ease-in-out infinite;\n }\n .kzl-developer-duck .kzl-wing-right-type {\n animation: kzl-wing-type-r 0.5s ease-in-out infinite 0.25s;\n }\n .kzl-developer-duck .kzl-laptop-screen {\n animation: kzl-screen-flicker-idle 3s ease-in-out infinite;\n }\n .kzl-developer-duck .kzl-holo-projection {\n animation: kzl-holo-flicker 6s ease-in-out infinite;\n }\n .kzl-developer-duck .kzl-holo-elements {\n animation: kzl-holo-elements-rise 6s ease-in-out infinite;\n }\n\n @keyframes kzl-screen-flicker-idle {\n 0%, 100% { opacity: 0.7; }\n 50% { opacity: 0.95; filter: drop-shadow(0 0 3px var(--kz-accent)); }\n }\n @keyframes kzl-holo-flicker {\n 0%, 100% { opacity: 0; }\n 20%, 80% { opacity: 0.35; }\n 50% { opacity: 0.65; }\n }\n @keyframes kzl-holo-elements-rise {\n 0% { transform: translateY(10px); opacity: 0; }\n 50% { opacity: 0.8; }\n 100% { transform: translateY(-15px); opacity: 0; }\n }\n @keyframes kzl-duck-look {\n 0%, 100% { transform: rotate(0deg); }\n 30% { transform: rotate(-5deg); }\n 70% { transform: rotate(5deg); }\n }\n @keyframes kzl-wing-type-l {\n 0%, 100% { transform: translateY(0) rotate(0deg); }\n 50% { transform: translateY(-3px) rotate(-4deg); }\n }\n @keyframes kzl-wing-type-r {\n 0%, 100% { transform: translateY(0) rotate(0deg); }\n 50% { transform: translateY(-3px) rotate(4deg); }\n }\n\n /* Flamingo Bot constant loop animations */\n .kzl-flamingo-bot .kzl-head-group {\n animation: kzl-flamingo-head-bob 5s ease-in-out infinite;\n }\n .kzl-flamingo-bot .kzl-flamingo-neck {\n animation: kzl-flamingo-neck-sway 7s ease-in-out infinite;\n transform-origin: 20px 74px;\n }\n .kzl-flamingo-bot .kzl-flamingo-wing {\n animation: kzl-flamingo-wing-flap 4s ease-in-out infinite;\n }\n\n @keyframes kzl-flamingo-neck-sway {\n 0%, 100% { transform: rotate(0deg); }\n 50% { transform: rotate(-3deg) scaleY(1.02); }\n }\n @keyframes kzl-flamingo-head-bob {\n 0%, 100% { transform: translate(8px, 12px) translateY(0) rotate(0deg); }\n 50% { transform: translate(8px, 12px) translateY(-5px) rotate(-3deg); }\n }\n @keyframes kzl-flamingo-wing-flap {\n 0%, 100% { transform: translateY(0) rotate(0deg); }\n 50% { transform: translateY(-2px) rotate(-6deg); }\n }\n\n /* Owl Bot constant loop animations */\n .kzl-owl-bot {\n animation: kzl-owl-sway 5s ease-in-out infinite;\n transform-origin: center;\n }\n @keyframes kzl-owl-sway {\n 0%, 100% { transform: rotate(0deg) translateY(0); }\n 50% { transform: rotate(-3deg) translateY(-2px); }\n }\n\n /* Treehouse hover glow */\n .kzl-cyber-treehouse:hover .kzl-window-glow {\n fill: #f59e0b;\n filter: drop-shadow(0 0 10px #f59e0b);\n }\n\n /* Floating tech particles */\n @keyframes kzl-float-up-down {\n 0%, 100% { transform: translateY(0); opacity: 0.4; }\n 50% { transform: translateY(-24px); opacity: 0.95; }\n }\n .kzl-float-particle-1 { animation: kzl-float-up-down 4.2s ease-in-out infinite; }\n .kzl-float-particle-2 { animation: kzl-float-up-down 5.2s ease-in-out infinite 1.2s; }\n .kzl-float-particle-3 { animation: kzl-float-up-down 4.7s ease-in-out infinite 0.6s; }\n .kzl-float-particle-4 { animation: kzl-float-up-down 6.2s ease-in-out infinite 2.2s; }\n\n @media (max-width: 1024px) {\n .kzl-mobile-hide {\n display: none !important;\n }\n }\n/* Still: with animated={false}, off screen, and under reduced motion — every loop holds its first frame. */\n.kzl[data-still] *, .kzl[data-offscreen] * { animation-play-state: paused !important; }\n@media (prefers-reduced-motion: reduce) {\n .kzl * { animation-play-state: paused !important; transition: none !important; }\n}\n`;\n\nexport type LandscapeProps = Omit<React.HTMLAttributes<HTMLDivElement>, \"children\"> & {\n /**\n * `own`: the Krizaka dusk (indigo, cyan and magenta peaks). `brand`: the sky and the peaks in the host brand's\n * accents (`.brand-<id>`). The birds and the phoenix keep their own colours.\n * @default \"own\"\n */\n tone?: \"own\" | \"brand\";\n /**\n * The flock at work in the valley (hidden under 1024 px wide either way).\n * @default true\n */\n flock?: boolean;\n /**\n * The phoenix and its river of two flames.\n * @default true\n */\n phoenix?: boolean;\n /**\n * The slow loops (the sun, the stars, the flames, the birds). `false` holds the first frame; always held under\n * `prefers-reduced-motion` and while off screen (with `MotionObserver`).\n * @default true\n */\n animated?: boolean;\n /**\n * `absolute`: fills its positioned parent, anchored at the bottom (a backdrop). `relative`: a block in the flow — give\n * it a height.\n * @default \"absolute\"\n */\n position?: \"absolute\" | \"relative\";\n /**\n * Fades the bottom into the page's surface.\n * @default true\n */\n fade?: boolean;\n};\n\n/** The Krizaka landscape: a decorative backdrop for a hero or a page's end (`aria-hidden`). */\nexport function Landscape({ tone = \"own\", flock = true, phoenix = true, animated = true, position = \"absolute\", fade = true, className, style, ...props }: LandscapeProps) {\n const u = \"kzl\" + useId().replace(/[^a-zA-Z0-9_-]/g, \"\");\n const box: React.CSSProperties =\n position === \"absolute\" ? { position: \"absolute\", inset: \"auto 0 0 0\", height: \"100%\", width: \"100%\" } : { position: \"relative\", width: \"100%\", height: 440 };\n return (\n <div\n aria-hidden\n data-motion-scope=\"\"\n data-still={animated ? undefined : \"\"}\n className={cn(\"kzl\", className)}\n style={{ ...box, ...(TONES[tone] as React.CSSProperties), ...style }}\n {...props}\n >\n <style>{CSS}</style>\n <svg width=\"100%\" height=\"100%\" viewBox=\"0 50 1200 520\" preserveAspectRatio=\"xMidYMax slice\" fill=\"none\" style={{ display: \"block\", pointerEvents: \"none\" }}>\n <defs>\n {/* Vibrant Cyber Sun Glow */}\n <radialGradient id={`${u}-sun-glow`} cx=\"50%\" cy=\"50%\" r=\"50%\">\n <stop offset=\"0%\" stopColor=\"var(--kzl-sun)\" stopOpacity=\"0.45\" />\n <stop offset=\"30%\" stopColor=\"var(--kzl-sun-2)\" stopOpacity=\"0.28\" />\n <stop offset=\"70%\" stopColor=\"var(--kzl-sun-3)\" stopOpacity=\"0.16\" />\n <stop offset=\"100%\" stopColor=\"transparent\" stopOpacity=\"0\" />\n </radialGradient>\n\n {/* Mountains Vibrant Gradients */}\n <linearGradient id={`${u}-mtn-back`} x1=\"0%\" y1=\"0%\" x2=\"0%\" y2=\"100%\">\n <stop offset=\"0%\" stopColor=\"var(--kzl-far)\" stopOpacity=\"0.75\" /> {/* indigo */}\n <stop offset=\"50%\" stopColor=\"var(--kzl-far-2)\" stopOpacity=\"0.45\" />\n <stop offset=\"100%\" stopColor=\"var(--kz-surface-0)\" />\n </linearGradient>\n <linearGradient id={`${u}-mtn-mid`} x1=\"0%\" y1=\"0%\" x2=\"0%\" y2=\"100%\">\n <stop offset=\"0%\" stopColor=\"var(--kzl-mid)\" stopOpacity=\"0.7\" /> {/* cyan */}\n <stop offset=\"50%\" stopColor=\"var(--kzl-mid-2)\" stopOpacity=\"0.4\" />\n <stop offset=\"100%\" stopColor=\"var(--kz-surface-0)\" />\n </linearGradient>\n <linearGradient id={`${u}-mtn-front`} x1=\"0%\" y1=\"0%\" x2=\"0%\" y2=\"100%\">\n <stop offset=\"0%\" stopColor=\"var(--kzl-near)\" stopOpacity=\"0.8\" /> {/* pink */}\n <stop offset=\"50%\" stopColor=\"var(--kzl-near-2)\" stopOpacity=\"0.5\" />\n <stop offset=\"100%\" stopColor=\"var(--kz-surface-0)\" />\n </linearGradient>\n\n {/* Vibrant Mascot Gradients */}\n <linearGradient id={`${u}-falcon-grad`} x1=\"0%\" y1=\"0%\" x2=\"0%\" y2=\"100%\">\n <stop offset=\"0%\" stopColor=\"#ff9f00\" />\n <stop offset=\"100%\" stopColor=\"#ff2a00\" />\n </linearGradient>\n <linearGradient id={`${u}-duck-grad`} x1=\"0%\" y1=\"0%\" x2=\"0%\" y2=\"100%\">\n <stop offset=\"0%\" stopColor=\"#f43f5e\" />\n <stop offset=\"100%\" stopColor=\"#be123c\" />\n </linearGradient>\n <linearGradient id={`${u}-flamingo-grad`} x1=\"0%\" y1=\"0%\" x2=\"0%\" y2=\"100%\">\n <stop offset=\"0%\" stopColor=\"#3b82f6\" />\n <stop offset=\"100%\" stopColor=\"#1d4ed8\" />\n </linearGradient>\n <linearGradient id={`${u}-owl-grad`} x1=\"0%\" y1=\"0%\" x2=\"0%\" y2=\"100%\">\n <stop offset=\"0%\" stopColor=\"#a78bfa\" />\n <stop offset=\"100%\" stopColor=\"#6d28d9\" />\n </linearGradient>\n\n {/* Hologram Projections */}\n <linearGradient id={`${u}-holo-grad`} x1=\"0%\" y1=\"100%\" x2=\"0%\" y2=\"0%\">\n <stop offset=\"0%\" stopColor=\"#10b981\" stopOpacity=\"0.5\" />\n <stop offset=\"100%\" stopColor=\"#10b981\" stopOpacity=\"0\" />\n </linearGradient>\n\n {/* Rival flame gradients for the Cyber-Phoenix */}\n <linearGradient id={`${u}-phoenix-gold-grad`} x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"100%\">\n <stop offset=\"0%\" stopColor=\"#ffb000\" />\n <stop offset=\"100%\" stopColor=\"#ff3c00\" />\n </linearGradient>\n <linearGradient id={`${u}-phoenix-purple-grad`} x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"100%\">\n <stop offset=\"0%\" stopColor=\"#c084fc\" />\n <stop offset=\"100%\" stopColor=\"#db2777\" />\n </linearGradient>\n <linearGradient id={`${u}-phoenix-body-grad`} x1=\"0%\" y1=\"0%\" x2=\"0%\" y2=\"100%\">\n <stop offset=\"0%\" stopColor=\"var(--kz-surface-3)\" />\n <stop offset=\"100%\" stopColor=\"var(--kz-surface-2)\" />\n </linearGradient>\n\n {/* Glowing stream gradients */}\n <linearGradient id={`${u}-gold-glow`} x1=\"0%\" y1=\"0%\" x2=\"0%\" y2=\"100%\">\n <stop offset=\"0%\" stopColor=\"#ff3c00\" stopOpacity=\"0.95\" />\n <stop offset=\"50%\" stopColor=\"#ffb000\" stopOpacity=\"0.75\" />\n <stop offset=\"100%\" stopColor=\"var(--kz-surface-0)\" />\n </linearGradient>\n <linearGradient id={`${u}-purple-glow`} x1=\"0%\" y1=\"0%\" x2=\"0%\" y2=\"100%\">\n <stop offset=\"0%\" stopColor=\"#db2777\" stopOpacity=\"0.95\" />\n <stop offset=\"50%\" stopColor=\"#a78bfa\" stopOpacity=\"0.75\" />\n <stop offset=\"100%\" stopColor=\"var(--kz-surface-0)\" />\n </linearGradient>\n\n {/* River mask to fade out at the bottom */}\n <linearGradient id={`${u}-river-mask-grad`} x1=\"0%\" y1=\"0%\" x2=\"0%\" y2=\"100%\">\n <stop offset=\"85%\" stopColor=\"white\" />\n <stop offset=\"100%\" stopColor=\"black\" />\n </linearGradient>\n <mask id={`${u}-river-fade-mask`}>\n <rect x=\"0\" y=\"0\" width=\"1200\" height=\"1000\" fill={`url(#${u}-river-mask-grad)`} />\n </mask>\n\n {/* Cyber trees gradient */}\n <linearGradient id={`${u}-tree-grad`} x1=\"0%\" y1=\"0%\" x2=\"0%\" y2=\"100%\">\n <stop offset=\"0%\" stopColor=\"var(--kz-accent)\" stopOpacity=\"0.35\" />\n <stop offset=\"100%\" stopColor=\"transparent\" />\n </linearGradient>\n\n {/* Cyber Bench Gradient */}\n <linearGradient id={`${u}-bench-grad`} x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"0%\">\n <stop offset=\"0%\" stopColor=\"var(--kz-surface-3)\" />\n <stop offset=\"100%\" stopColor=\"var(--kz-surface-2)\" />\n </linearGradient>\n\n {/* Cyber Aurora Glows */}\n <radialGradient id={`${u}-aurora-left`} cx=\"20%\" cy=\"30%\" r=\"50%\">\n <stop offset=\"0%\" stopColor=\"var(--kzl-aurora-l)\" stopOpacity=\"0.22\" />\n <stop offset=\"100%\" stopColor=\"transparent\" stopOpacity=\"0\" />\n </radialGradient>\n <radialGradient id={`${u}-aurora-right`} cx=\"80%\" cy=\"25%\" r=\"50%\">\n <stop offset=\"0%\" stopColor=\"var(--kzl-aurora-r)\" stopOpacity=\"0.22\" />\n <stop offset=\"100%\" stopColor=\"transparent\" stopOpacity=\"0\" />\n </radialGradient>\n </defs>\n\n <g transform=\"translate(0, 60)\">\n {/* ─── Cyber Aurora Backdrop ─── */}\n <circle cx=\"200\" cy=\"180\" r=\"600\" fill={`url(#${u}-aurora-left)`} />\n <circle cx=\"1000\" cy=\"150\" r=\"600\" fill={`url(#${u}-aurora-right)`} />\n\n {/* ─── Ethereal Sun and Sky Network Nodes (Constellations) ─── */}\n <circle cx=\"600\" cy=\"200\" r=\"380\" fill={`url(#${u}-sun-glow)`} />\n <circle cx=\"600\" cy=\"200\" r=\"64\" fill=\"var(--kzl-sun)\" opacity=\"0.16\" className=\"kzl-sun-pulsing\" />\n\n {/* Constellation grid lines in the sky */}\n <g opacity=\"0.3\" stroke=\"var(--kz-accent)\" strokeWidth=\"1\">\n <line x1=\"300\" y1=\"120\" x2=\"380\" y2=\"80\" />\n <line x1=\"380\" y1=\"80\" x2=\"450\" y2=\"110\" />\n <line x1=\"450\" y1=\"110\" x2=\"300\" y2=\"120\" />\n <line x1=\"450\" y1=\"110\" x2=\"520\" y2=\"60\" />\n <line x1=\"750\" y1=\"80\" x2=\"840\" y2=\"130\" />\n <line x1=\"840\" y1=\"130\" x2=\"900\" y2=\"70\" />\n <line x1=\"900\" y1=\"70\" x2=\"750\" y2=\"80\" />\n </g>\n {/* Constellation node points */}\n <g fill=\"var(--kz-accent)\" opacity=\"0.65\">\n <circle cx=\"300\" cy=\"120\" r=\"3.5\" />\n <circle cx=\"380\" cy=\"80\" r=\"5\" className=\"kzl-pulse-slow\" />\n <circle cx=\"450\" cy=\"110\" r=\"3\" />\n <circle cx=\"520\" cy=\"60\" r=\"4.5\" />\n <circle cx=\"750\" cy=\"80\" r=\"4.5\" />\n <circle cx=\"840\" cy=\"130\" r=\"3.5\" />\n <circle cx=\"900\" cy=\"70\" r=\"6\" className=\"kzl-pulse-slow\" />\n </g>\n\n {/* ─── Layered Mountains (with Digital Contours) ─── */}\n {/* Far Peaks */}\n <path d=\"M 150 480 L 420 280 L 680 480 Z\" fill={`url(#${u}-mtn-back)`} stroke=\"var(--kzl-far-line)\" strokeWidth=\"1.5\" />\n <path d=\"M 520 480 L 780 230 L 1050 480 Z\" fill={`url(#${u}-mtn-back)`} stroke=\"var(--kzl-far-line)\" strokeWidth=\"1.5\" />\n\n {/* Mid Peaks */}\n <path d=\"M -50 500 L 220 320 L 500 500 Z\" fill={`url(#${u}-mtn-mid)`} stroke=\"var(--kzl-mid-line)\" strokeWidth=\"1.5\" />\n <path d=\"M 700 500 L 980 300 L 1250 500 Z\" fill={`url(#${u}-mtn-mid)`} stroke=\"var(--kzl-mid-line)\" strokeWidth=\"1.5\" />\n\n {/* Wireframe grids on mountains (Contour lines) */}\n <g stroke=\"var(--kz-accent)\" strokeWidth=\"1.2\" opacity=\"0.18\">\n {/* Mid peak left contours */}\n <line x1=\"30\" y1=\"440\" x2=\"410\" y2=\"440\" />\n <line x1=\"85\" y1=\"400\" x2=\"355\" y2=\"400\" />\n <line x1=\"140\" y1=\"360\" x2=\"300\" y2=\"360\" />\n {/* Mid peak right contours */}\n <line x1=\"770\" y1=\"450\" x2=\"1180\" y2=\"450\" />\n <line x1=\"825\" y1=\"410\" x2=\"1125\" y2=\"410\" />\n <line x1=\"880\" y1=\"370\" x2=\"1070\" y2=\"370\" />\n </g>\n\n {/* Front Peaks */}\n <path d=\"M 100 520 L 360 380 L 620 520 Z\" fill={`url(#${u}-mtn-front)`} stroke=\"var(--kzl-near-line)\" strokeWidth=\"1.8\" />\n <path d=\"M 580 520 L 850 350 L 1100 520 Z\" fill={`url(#${u}-mtn-front)`} stroke=\"var(--kzl-near-line)\" strokeWidth=\"1.8\" />\n\n {phoenix && (\n <>\n {/* ─── Cyber-Phoenix & Dual Glowing Flame Trails ─── */}\n {/* Dual Cascading Flame Trails */}\n {/* Left Purple Flame Trail */}\n <path\n d=\"M 590 340 C 570 370, 610 390, 590 410 C 570 430, 490 440, 510 480 C 530 520, 670 530, 700 560 C 720 580, 750 600, 730 630 C 710 660, 630 670, 650 710 C 660 730, 690 740, 700 760 C 710 780, 670 800, 650 830 C 630 860, 680 890, 690 920 C 695 935, 705 945, 710 1000\"\n fill=\"none\"\n stroke={`url(#${u}-purple-glow)`}\n strokeWidth=\"6\"\n strokeLinecap=\"round\"\n opacity=\"0.6\"\n mask={`url(#${u}-river-fade-mask)`}\n style={{\n filter: \"drop-shadow(0 0 6px rgba(219, 39, 119, 0.4))\",\n }}\n />\n <path\n d=\"M 590 340 C 570 370, 610 390, 590 410 C 570 430, 490 440, 510 480 C 530 520, 670 530, 700 560 C 720 580, 750 600, 730 630 C 710 660, 630 670, 650 710 C 660 730, 690 740, 700 760 C 710 780, 670 800, 650 830 C 630 860, 680 890, 690 920 C 695 935, 705 945, 710 1000\"\n fill=\"none\"\n stroke=\"#db2777\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n opacity=\"0.9\"\n mask={`url(#${u}-river-fade-mask)`}\n style={{\n strokeDasharray: \"25, 20\",\n animation: \"kzl-phoenix-flow-purple 8s linear infinite\",\n pointerEvents: \"none\",\n filter: \"drop-shadow(0 0 3px #db2777)\",\n }}\n />\n\n {/* Right Gold Flame Trail */}\n <path\n d=\"M 610 340 C 590 370, 630 390, 610 410 C 590 430, 510 440, 530 480 C 550 520, 690 530, 720 560 C 740 580, 770 600, 750 630 C 730 660, 650 670, 670 710 C 680 730, 710 740, 720 760 C 730 780, 690 800, 670 830 C 650 860, 700 890, 710 920 C 715 935, 725 945, 730 1000\"\n fill=\"none\"\n stroke={`url(#${u}-gold-glow)`}\n strokeWidth=\"6\"\n strokeLinecap=\"round\"\n opacity=\"0.6\"\n mask={`url(#${u}-river-fade-mask)`}\n style={{\n filter: \"drop-shadow(0 0 6px rgba(251, 191, 36, 0.4))\",\n }}\n />\n <path\n d=\"M 610 340 C 590 370, 630 390, 610 410 C 590 430, 510 440, 530 480 C 550 520, 690 530, 720 560 C 740 580, 770 600, 750 630 C 730 660, 650 670, 670 710 C 680 730, 710 740, 720 760 C 730 780, 690 800, 670 830 C 650 860, 700 890, 710 920 C 715 935, 725 945, 730 1000\"\n fill=\"none\"\n stroke=\"#fbbf24\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n opacity=\"0.9\"\n mask={`url(#${u}-river-fade-mask)`}\n style={{\n strokeDasharray: \"35, 15\",\n animation: \"kzl-phoenix-flow-gold 6s linear infinite\",\n pointerEvents: \"none\",\n filter: \"drop-shadow(0 0 3px #fbbf24)\",\n }}\n />\n\n {/* Hoverable Cyber-Phoenix Soaring in the Valley Center */}\n <g className=\"kzl-cyber-phoenix\" style={{ cursor: \"pointer\", pointerEvents: \"auto\" }}>\n {/* Main Body diamond capsule */}\n <polygon\n points=\"600,310 608,325 600,345 592,325\"\n fill={`url(#${u}-phoenix-body-grad)`}\n stroke=\"var(--kz-border-strong)\"\n strokeWidth=\"1.2\"\n />\n {/* Glowing Phoenix Core */}\n <circle cx=\"600\" cy=\"325\" r=\"3\" fill=\"#ffef5c\" className=\"kzl-phoenix-core\" />\n\n {/* Head */}\n <circle cx=\"600\" cy=\"302\" r=\"6\" fill={`url(#${u}-phoenix-body-grad)`} stroke=\"var(--kz-border-strong)\" strokeWidth=\"1.2\" />\n {/* Visor */}\n <rect x=\"598\" y=\"300\" width=\"4\" height=\"2\" rx=\"0.5\" fill=\"#00f2fe\" />\n {/* Head Crest */}\n <polygon points=\"600,296 603,290 600,293 597,290\" fill=\"#ff3c00\" />\n\n {/* Left Wing (Purple mechanical fire) */}\n <path\n d=\"M 592 322 C 555 310, 520 325, 498 348 C 525 348, 545 338, 568 340 C 582 341, 588 333, 592 322 Z\"\n fill={`url(#${u}-phoenix-purple-grad)`}\n stroke=\"var(--kz-border-strong)\"\n strokeWidth=\"1\"\n className=\"kzl-phoenix-wing-l\"\n style={{ transformOrigin: \"592px 322px\" }}\n />\n\n {/* Right Wing (Gold mechanical fire) */}\n <path\n d=\"M 608 322 C 645 310, 680 325, 702 348 C 675 348, 655 338, 632 340 C 618 341, 612 333, 608 322 Z\"\n fill={`url(#${u}-phoenix-gold-grad)`}\n stroke=\"var(--kz-border-strong)\"\n strokeWidth=\"1\"\n className=\"kzl-phoenix-wing-r\"\n style={{ transformOrigin: \"608px 322px\" }}\n />\n </g>\n\n </>\n )}\n {/* ─── Cyber Trees & Hexagonal Foliage (Nature + Tech) ─── */}\n {/* Left Tree */}\n <g transform=\"translate(180, 360)\">\n {/* Server trunk */}\n <line x1=\"0\" y1=\"120\" x2=\"0\" y2=\"40\" stroke=\"var(--kz-border-strong)\" strokeWidth=\"4\" />\n <rect x=\"-8\" y=\"50\" width=\"16\" height=\"28\" rx=\"2\" fill=\"var(--kz-surface-2)\" stroke=\"var(--kz-border-subtle)\" />\n {/* LED dots on trunk */}\n <circle cx=\"0\" cy=\"58\" r=\"1.5\" fill=\"var(--kz-accent)\" />\n <circle cx=\"0\" cy=\"66\" r=\"1.5\" fill=\"var(--kz-accent)\" opacity=\"0.6\" />\n {/* Hexagonal foliage */}\n <polygon points=\"0,-10 35,10 35,50 0,70 -35,50 -35,10\" fill={`url(#${u}-tree-grad)`} stroke=\"var(--kz-accent)\" strokeWidth=\"1.2\" opacity=\"0.4\" />\n <polygon points=\"0,-5 25,10 25,40 0,55 -25,40 -25,10\" fill={`url(#${u}-tree-grad)`} stroke=\"var(--kz-accent)\" strokeWidth=\"1.2\" opacity=\"0.6\" />\n </g>\n\n {/* Treehouse Tree (Center-Left) */}\n <g transform=\"translate(420, 320)\">\n {/* Trunk */}\n <line x1=\"0\" y1=\"180\" x2=\"0\" y2=\"60\" stroke=\"var(--kz-border-strong)\" strokeWidth=\"5\" />\n <line x1=\"0\" y1=\"110\" x2=\"35\" y2=\"90\" stroke=\"var(--kz-border-strong)\" strokeWidth=\"3.5\" />\n {/* Foliage */}\n <polygon points=\"0,-20 52,10 52,70 0,100 -52,70 -52,10\" fill={`url(#${u}-tree-grad)`} stroke=\"var(--kz-accent)\" strokeWidth=\"1.2\" opacity=\"0.35\" />\n <polygon points=\"0,-10 38,10 38,55 0,75 -38,55 -38,10\" fill={`url(#${u}-tree-grad)`} stroke=\"var(--kz-accent)\" strokeWidth=\"1.2\" opacity=\"0.5\" />\n\n {/* Hexagonal Treehouse */}\n <g transform=\"translate(0, 50)\" style={{ pointerEvents: \"auto\", cursor: \"pointer\" }} className=\"kzl-cyber-treehouse\">\n <polygon points=\"0,-30 26,-15 26,15 0,30 -26,15 -26,-15\" fill=\"var(--kz-surface-3)\" stroke=\"var(--kz-accent)\" strokeWidth=\"1.5\" />\n {/* Window */}\n <circle cx=\"0\" cy=\"0\" r=\"8\" fill=\"var(--kz-surface-1)\" stroke=\"var(--kz-border-strong)\" />\n <circle cx=\"0\" cy=\"0\" r=\"4\" fill=\"var(--kz-accent)\" className=\"kzl-window-glow\" />\n {/* Ladder */}\n <path d=\"M -6 30 L -6 95 M 6 30 L 6 95 M -6 42 L 6 42 M -6 54 L 6 54 M -6 66 L 6 66 M -6 78 L 6 78 M -6 90 L 6 90\" stroke=\"var(--kz-border-strong)\" strokeWidth=\"1.5\" />\n {/* Animated green local data pulses rising from treehouse */}\n <circle cx=\"0\" cy=\"-45\" r=\"3\" fill=\"#10b981\" className=\"kzl-rising-pulse-1\" />\n <circle cx=\"15\" cy=\"-35\" r=\"2\" fill=\"#10b981\" className=\"kzl-rising-pulse-2\" />\n </g>\n </g>\n\n {/* Right Tree */}\n <g transform=\"translate(1000, 340)\">\n <line x1=\"0\" y1=\"160\" x2=\"0\" y2=\"60\" stroke=\"var(--kz-border-strong)\" strokeWidth=\"4\" />\n <polygon points=\"0,-15 42,10 42,60 0,85 -42,60 -42,10\" fill={`url(#${u}-tree-grad)`} stroke=\"var(--kz-accent)\" strokeWidth=\"1.2\" opacity=\"0.4\" />\n <polygon points=\"0,-5 28,10 28,42 0,60 -28,42 -28,10\" fill={`url(#${u}-tree-grad)`} stroke=\"var(--kz-accent)\" strokeWidth=\"1.2\" opacity=\"0.6\" />\n </g>\n\n {/* ─── Cyber Tech Bench (Center-Right) ─── */}\n <g transform=\"translate(740, 480)\">\n {/* Bench support legs */}\n <line x1=\"20\" y1=\"35\" x2=\"20\" y2=\"60\" stroke=\"var(--kz-border-strong)\" strokeWidth=\"4\" />\n <line x1=\"140\" y1=\"35\" x2=\"140\" y2=\"60\" stroke=\"var(--kz-border-strong)\" strokeWidth=\"4\" />\n {/* Bench seat */}\n <rect x=\"0\" y=\"22\" width=\"160\" height=\"12\" rx=\"4\" fill={`url(#${u}-bench-grad)`} stroke=\"var(--kz-border-default)\" strokeWidth=\"1.2\" />\n {/* Bench backrest */}\n <rect x=\"0\" y=\"0\" width=\"160\" height=\"10\" rx=\"3\" fill={`url(#${u}-bench-grad)`} stroke=\"var(--kz-border-default)\" strokeWidth=\"1.2\" transform=\"rotate(-5, 80, 5)\" />\n {/* Backrest brackets */}\n <line x1=\"15\" y1=\"10\" x2=\"15\" y2=\"24\" stroke=\"var(--kz-border-strong)\" strokeWidth=\"3\" />\n <line x1=\"145\" y1=\"10\" x2=\"145\" y2=\"24\" stroke=\"var(--kz-border-strong)\" strokeWidth=\"3\" />\n </g>\n\n {flock && (\n <>\n {/* ─── MASCOT BIRD 4: Cyber Owl (Teal/Indigo - Left Tree) ─── */}\n <g transform=\"translate(180, 275) scale(1.4)\" className=\"kzl-bird-hitbox kzl-mobile-hide\">\n <rect x=\"-20\" y=\"-15\" width=\"40\" height=\"70\" fill=\"transparent\" style={{ cursor: \"pointer\", pointerEvents: \"all\" }} />\n <g className=\"kzl-bird-graphics kzl-owl-bot\">\n {/* Shadow */}\n <ellipse cx=\"0\" cy=\"50\" rx=\"16\" ry=\"4\" fill=\"rgba(0,0,0,0.15)\" />\n {/* Body */}\n <path\n d=\"M -15,10 C -15,-10, 15,-10, 15,10 C 15,30, 10,45, 0,45 C -10,45, -15,30, -15,10 Z\"\n fill={`url(#${u}-owl-grad)`}\n stroke=\"var(--kz-border-strong)\"\n strokeWidth=\"1.2\"\n />\n {/* Belly plate */}\n <path\n d=\"M -8,15 C -8,5, 8,5, 8,15 C 8,28, 5,35, 0,35 C -5,35, -8,28, -8,15 Z\"\n fill=\"#00f2fe\"\n opacity=\"0.35\"\n />\n {/* Eyes */}\n <circle cx=\"-6\" cy=\"2\" r=\"5\" fill=\"var(--kz-surface-0)\" stroke=\"var(--kz-border-strong)\" strokeWidth=\"1\" />\n <circle cx=\"6\" cy=\"2\" r=\"5\" fill=\"var(--kz-surface-0)\" stroke=\"var(--kz-border-strong)\" strokeWidth=\"1\" />\n <circle cx=\"-6\" cy=\"2\" r=\"2\" fill=\"#00ff66\" className=\"kzl-owl-eye\" />\n <circle cx=\"6\" cy=\"2\" r=\"2\" fill=\"#00ff66\" className=\"kzl-owl-eye\" />\n {/* Beak */}\n <polygon points=\"-2,4 2,4 0,10\" fill=\"#fbbf24\" stroke=\"var(--kz-border-strong)\" strokeWidth=\"1\" />\n {/* Horns / Ears */}\n <polygon points=\"-12,-8 -6,-4 -14,2\" fill=\"#7c3aed\" stroke=\"var(--kz-border-strong)\" strokeWidth=\"1\" />\n <polygon points=\"12,-8 6,-4 14,2\" fill=\"#7c3aed\" stroke=\"var(--kz-border-strong)\" strokeWidth=\"1\" />\n </g>\n </g>\n\n {/* ─── MASCOT BIRD 1: Cyber-Sentry Falcon (Orange - Left) ─── */}\n <g transform=\"translate(120, 360) scale(1.65)\" className=\"kzl-bird-hitbox kzl-mobile-hide\">\n <rect x=\"-10\" y=\"0\" width=\"70\" height=\"90\" fill=\"transparent\" style={{ cursor: \"pointer\", pointerEvents: \"all\" }} />\n <g className=\"kzl-bird-graphics kzl-falcon-bot\">\n {/* Shadow */}\n <ellipse cx=\"25\" cy=\"85\" rx=\"30\" ry=\"6\" fill=\"rgba(0,0,0,0.15)\" />\n \n {/* Legs */}\n <line x1=\"16\" y1=\"65\" x2=\"12\" y2=\"85\" stroke=\"#f97316\" strokeWidth=\"3\" strokeLinecap=\"round\" />\n <line x1=\"34\" y1=\"65\" x2=\"38\" y2=\"85\" stroke=\"#f97316\" strokeWidth=\"3\" strokeLinecap=\"round\" />\n {/* Feet claws */}\n <path d=\"M 6 85 L 14 85 M 34 85 L 44 85\" stroke=\"#f97316\" strokeWidth=\"3\" strokeLinecap=\"round\" />\n\n {/* Body */}\n <path\n d=\"M 5 35 C 5 20, 45 20, 45 35 C 45 58, 38 68, 25 68 C 12 68, 5 58, 5 35 Z\"\n fill={`url(#${u}-falcon-grad)`}\n stroke=\"var(--kz-border-strong)\"\n strokeWidth=\"1.5\"\n />\n {/* Belly plate */}\n <path\n d=\"M 12 38 C 12 28, 38 28, 38 38 C 38 52, 32 58, 25 58 C 18 58, 12 52, 12 38 Z\"\n fill=\"#ff9800\"\n opacity=\"0.85\"\n />\n\n {/* Wings */}\n <path\n d=\"M 2 30 C -8 40, -4 60, 10 58 C 5 50, 4 38, 2 30 Z\"\n fill=\"#d84315\"\n stroke=\"var(--kz-border-strong)\"\n strokeWidth=\"1.2\"\n className=\"kzl-wing-left\"\n style={{ transformOrigin: \"2px 30px\" }}\n />\n <path\n d=\"M 48 30 C 58 40, 54 60, 40 58 C 45 50, 46 38, 48 30 Z\"\n fill=\"#d84315\"\n stroke=\"var(--kz-border-strong)\"\n strokeWidth=\"1.2\"\n className=\"kzl-wing-right\"\n style={{ transformOrigin: \"48px 30px\" }}\n />\n\n {/* Tail feathers */}\n <path d=\"M 20 66 L 15 80 L 25 76 L 35 80 L 30 66\" fill=\"#bf360c\" stroke=\"var(--kz-border-strong)\" strokeWidth=\"1\" />\n\n {/* Head */}\n <g className=\"kzl-head-group\" style={{ transformOrigin: \"25px 28px\" }}>\n <circle cx=\"25\" cy=\"22\" r=\"18\" fill={`url(#${u}-falcon-grad)`} stroke=\"var(--kz-border-strong)\" strokeWidth=\"1.5\" />\n \n {/* Beak */}\n <polygon points=\"21,24 29,24 25,36\" fill=\"#ffb300\" stroke=\"var(--kz-border-strong)\" strokeWidth=\"1.2\" />\n\n {/* Visor */}\n <rect x=\"9\" y=\"10\" width=\"32\" height=\"10\" rx=\"3\" fill=\"var(--kz-surface-0)\" stroke=\"var(--kz-border-strong)\" strokeWidth=\"1.2\" />\n {/* Lenses */}\n <circle cx=\"17\" cy=\"15\" r=\"2.5\" fill=\"#00f2fe\" className=\"kzl-falcon-eye\" />\n <circle cx=\"33\" cy=\"15\" r=\"2.5\" fill=\"#00f2fe\" className=\"kzl-falcon-eye\" />\n {/* Wire */}\n <path d=\"M 41 15 C 44 15, 43 25, 41 28\" stroke=\"var(--kz-border-strong)\" strokeWidth=\"1\" fill=\"none\" />\n </g>\n\n {/* Sentry Scan Laser Overlay */}\n <polygon points=\"25,28 -60,180 110,180\" fill={`url(#${u}-holo-grad)`} className=\"kzl-sentry-laser\" opacity=\"0\" style={{ transformOrigin: \"25px 28px\", pointerEvents: \"none\" }} />\n </g>\n </g>\n\n {/* ─── MASCOT BIRD 2: Developer Duck (Pink - Center Bench) ─── */}\n <g transform=\"translate(750, 355) scale(1.75)\" className=\"kzl-bird-hitbox kzl-mobile-hide\">\n <rect x=\"-10\" y=\"5\" width=\"70\" height=\"75\" fill=\"transparent\" style={{ cursor: \"pointer\", pointerEvents: \"all\" }} />\n <g className=\"kzl-bird-graphics kzl-developer-duck\">\n {/* Sitting body */}\n <path\n d=\"M 5 45 C 5 30, 45 30, 45 45 C 45 62, 38 72, 25 72 C 12 72, 5 62, 5 45 Z\"\n fill={`url(#${u}-duck-grad)`}\n stroke=\"var(--kz-border-strong)\"\n strokeWidth=\"1.5\"\n />\n {/* Belly light */}\n <path\n d=\"M 12 48 C 12 40, 38 40, 38 48 C 38 60, 32 64, 25 64 C 18 64, 12 60, 12 48 Z\"\n fill=\"#f472b6\"\n opacity=\"0.85\"\n />\n\n {/* Wings typing */}\n <path\n d=\"M -2 40 C -8 46, -4 55, 10 52\"\n fill=\"none\"\n stroke=\"#db2777\"\n strokeWidth=\"8\"\n strokeLinecap=\"round\"\n className=\"kzl-wing-left-type\"\n />\n <path\n d=\"M 52 40 C 58 46, 54 55, 40 52\"\n fill=\"none\"\n stroke=\"#db2777\"\n strokeWidth=\"8\"\n strokeLinecap=\"round\"\n className=\"kzl-wing-right-type\"\n />\n\n {/* Head */}\n <g className=\"kzl-head-group\" style={{ transformOrigin: \"25px 32px\" }}>\n <circle cx=\"25\" cy=\"24\" r=\"16\" fill={`url(#${u}-duck-grad)`} stroke=\"var(--kz-border-strong)\" strokeWidth=\"1.5\" />\n {/* Duck Beak */}\n <path\n d=\"M 12 24 C 12 20, 22 18, 25 18 C 28 18, 38 20, 38 24 C 38 28, 28 32, 25 32 C 22 32, 12 28, 12 24 Z\"\n fill=\"#fbbf24\"\n stroke=\"var(--kz-border-strong)\"\n strokeWidth=\"1.2\"\n />\n {/* Eyes */}\n <circle cx=\"19\" cy=\"16\" r=\"2\" fill=\"var(--kz-text-primary)\" className=\"kzl-duck-eye\" />\n <circle cx=\"31\" cy=\"16\" r=\"2\" fill=\"var(--kz-text-primary)\" className=\"kzl-duck-eye\" />\n {/* Glasses */}\n <circle cx=\"19\" cy=\"16\" r=\"4.5\" fill=\"none\" stroke=\"var(--kz-border-strong)\" strokeWidth=\"1.2\" />\n <circle cx=\"31\" cy=\"16\" r=\"4.5\" fill=\"none\" stroke=\"var(--kz-border-strong)\" strokeWidth=\"1.2\" />\n <line x1=\"23.5\" y1=\"16\" x2=\"26.5\" y2=\"16\" stroke=\"var(--kz-border-strong)\" strokeWidth=\"1.2\" />\n </g>\n\n {/* Holographic Laptop */}\n <g transform=\"translate(10, 52)\">\n {/* Base */}\n <polygon points=\"-8,16 38,16 30,22 -14,22\" fill=\"var(--kz-surface-3)\" stroke=\"var(--kz-border-strong)\" strokeWidth=\"1\" />\n {/* Hologram screen */}\n <polygon\n points=\"-4,14 34,14 30,-2 -8,-2\"\n fill=\"var(--kz-accent-soft)\"\n stroke=\"var(--kz-accent)\"\n strokeWidth=\"1\"\n opacity=\"0.8\"\n className=\"kzl-laptop-screen\"\n />\n {/* Glowing prompt line */}\n <line x1=\"-2\" y1=\"4\" x2=\"24\" y2=\"4\" stroke=\"var(--kz-accent)\" strokeWidth=\"1.5\" opacity=\"0.9\" />\n <line x1=\"-2\" y1=\"8\" x2=\"16\" y2=\"8\" stroke=\"var(--kz-accent)\" strokeWidth=\"1.5\" opacity=\"0.6\" />\n \n {/* Holographic Projection */}\n <polygon points=\"12,-2 -40,-80 70,-80\" fill={`url(#${u}-holo-grad)`} opacity=\"0\" className=\"kzl-holo-projection\" style={{ pointerEvents: \"none\" }} />\n {/* Tiny code elements inside hologram */}\n <g className=\"kzl-holo-elements\" opacity=\"0\">\n <rect x=\"-10\" y=\"-45\" width=\"22\" height=\"6\" rx=\"2\" fill=\"var(--kz-surface-3)\" stroke=\"#10b981\" strokeWidth=\"0.5\" />\n <rect x=\"18\" y=\"-35\" width=\"18\" height=\"6\" rx=\"2\" fill=\"var(--kz-surface-3)\" stroke=\"#10b981\" strokeWidth=\"0.5\" />\n </g>\n </g>\n </g>\n </g>\n\n {/* ─── MASCOT BIRD 3: High-Neck Flamingo-Bot (Blue - Right) ─── */}\n <g transform=\"translate(1000, 270) scale(1.75)\" className=\"kzl-bird-hitbox kzl-mobile-hide\">\n <rect x=\"-15\" y=\"0\" width=\"65\" height=\"165\" fill=\"transparent\" style={{ cursor: \"pointer\", pointerEvents: \"all\" }} />\n <g className=\"kzl-bird-graphics kzl-flamingo-bot\">\n {/* Shadow */}\n <ellipse cx=\"20\" cy=\"160\" rx=\"22\" ry=\"5\" fill=\"rgba(0,0,0,0.15)\" />\n\n {/* Long legs */}\n <line x1=\"12\" y1=\"105\" x2=\"12\" y2=\"160\" stroke=\"var(--kz-border-strong)\" strokeWidth=\"2.5\" />\n <line x1=\"26\" y1=\"105\" x2=\"28\" y2=\"160\" stroke=\"var(--kz-border-strong)\" strokeWidth=\"2.5\" />\n {/* Joints */}\n <circle cx=\"12\" cy=\"130\" r=\"2.5\" fill=\"#3b82f6\" />\n <circle cx=\"27\" cy=\"130\" r=\"2.5\" fill=\"#3b82f6\" />\n\n {/* Body */}\n <path\n d=\"M 2 80 C 2 68, 38 68, 38 80 C 38 108, 28 112, 20 112 C 12 112, 2 108, 2 80 Z\"\n fill={`url(#${u}-flamingo-grad)`}\n stroke=\"var(--kz-border-strong)\"\n strokeWidth=\"1.5\"\n />\n\n {/* Wing (Vibrant contrast) */}\n <path\n d=\"M 8 82 L 20 74 L 32 82 L 32 94 L 20 102 L 8 94 Z\"\n fill=\"#ec4899\"\n stroke=\"var(--kz-border-strong)\"\n strokeWidth=\"1\"\n opacity=\"0.95\"\n className=\"kzl-flamingo-wing\"\n />\n\n {/* Curved neck */}\n <path\n d=\"M 20 74 C 20 60, -2 40, 8 18\"\n fill=\"none\"\n stroke={`url(#${u}-flamingo-grad)`}\n strokeWidth=\"6\"\n strokeLinecap=\"round\"\n className=\"kzl-flamingo-neck\"\n />\n\n {/* Head */}\n <g className=\"kzl-head-group\" transform=\"translate(8, 12)\" style={{ transformOrigin: \"0px 0px\" }}>\n <circle cx=\"0\" cy=\"0\" r=\"10\" fill={`url(#${u}-flamingo-grad)`} stroke=\"var(--kz-border-strong)\" strokeWidth=\"1.2\" />\n \n {/* Eye */}\n <circle cx=\"-3\" cy=\"-2\" r=\"1.5\" fill=\"var(--kz-surface-0)\" />\n <circle cx=\"-3\" cy=\"-2\" r=\"0.6\" fill=\"#f43f5e\" className=\"kzl-flamingo-eye\" />\n\n {/* Beak */}\n <path d=\"M -8 -2 C -18 2, -16 14, -22 18 C -14 10, -8 4, -8 -2 Z\" fill=\"#fbbf24\" stroke=\"var(--kz-border-strong)\" strokeWidth=\"1\" />\n\n {/* Hat */}\n <path d=\"M -8 -8 L 8 -8 L 6 -14 L -6 -14 Z\" fill=\"var(--kz-surface-3)\" stroke=\"var(--kz-border-strong)\" strokeWidth=\"1.2\" />\n <ellipse cx=\"0\" cy=\"-8\" rx=\"10\" ry=\"1.5\" fill=\"var(--kz-surface-3)\" stroke=\"var(--kz-border-strong)\" strokeWidth=\"1\" />\n </g>\n </g>\n </g>\n\n </>\n )}\n {/* ─── Floating Glowing Tech Particles ─── */}\n <circle cx=\"340\" cy=\"300\" r=\"6\" fill=\"#00f2fe\" opacity=\"0.75\" className=\"kzl-float-particle-1\" />\n <circle cx=\"520\" cy=\"220\" r=\"5\" fill=\"#a855f7\" opacity=\"0.65\" className=\"kzl-float-particle-2\" />\n <circle cx=\"710\" cy=\"310\" r=\"6.5\" fill=\"#3b82f6\" opacity=\"0.7\" className=\"kzl-float-particle-3\" />\n <circle cx=\"920\" cy=\"250\" r=\"5\" fill=\"#00f2fe\" opacity=\"0.8\" className=\"kzl-float-particle-4\" />\n </g>\n </svg>\n {fade && <div className=\"kzl-fade\" />}\n </div>\n );\n}\n"
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
"path": "landscape/meta.ts",
|
|
124
|
+
"content": "import type { ComponentMeta } from \"../meta\";\n\nexport const meta = {\n title: \"Landscape\",\n summary:\n \"The Krizaka valley at dusk — peaks, a phoenix over a river of two flames, trees of light and the flock at work: a decorative backdrop in its own colours or in the host brand's.\",\n status: \"beta\",\n category: \"blocks\",\n platforms: \"web\",\n whenToUse: [\n \"Behind the end of a told page or a home's first screen, under the last words.\",\n \"A product's about page, in its own accents (`tone=\\\"brand\\\"`, `flock={false}` for a calmer one).\",\n ],\n whenNotToUse: [\n { when: \"Behind a section's content: the brand's gradient and grid are the section backdrop.\", use: \"section-backdrop\" },\n { when: \"In a working screen, or behind text that must be read.\" },\n ],\n bestPractices: [\n \"Place it at the bottom of a positioned parent with room under the words; it fades into the surface.\",\n \"Hold it still (`animated={false}`) on a page that already moves; it pauses off screen with `MotionObserver`.\",\n \"The birds are hidden under 1024 px: on a phone the valley stays calm.\",\n ],\n accessibility: {\n keyboard: [],\n notes: [\n \"Decorative (`aria-hidden`): it never carries information.\",\n \"Every loop holds its first frame under `prefers-reduced-motion`, with `animated={false}`, and while off screen.\",\n ],\n },\n related: [\"section-backdrop\", \"mascots\", \"page-hero\"],\n web: {\n imports: [\"Landscape\"],\n examples: [\n { name: \"backdrop\", title: \"A page's end\", description: \"The valley behind the last words, faded into the surface.\" },\n { name: \"brand\", title: \"In the brand's colours\", description: \"`tone=\\\"brand\\\"` without the flock: the sky and the peaks in the host's accents.\" },\n ],\n },\n} satisfies ComponentMeta;\n"
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
"path": "meta.ts",
|
|
128
|
+
"content": "// The documentation of a component, carried by its code: each primitive has a `meta.ts` beside its source\n// (`src/<name>/meta.ts`; a component that exists only in React Native: `src/native/meta/<name>.ts`). Never built into\n// the package: `scripts/build-registry.mjs` reads them into `registry/<name>.json`, which krizaka.com renders as\n// /docs/ui/<name>, and `scripts/registry.test.mjs` fails when one is missing or incomplete.\n//\n// Why a typed module and not JSDoc tags: the fields are lists and links (`related`, `whenNotToUse[].use`, examples),\n// which a type checks and a comment does not; the file is plain data (erasable TypeScript), so Node reads it without a\n// compiler, and an editor completes it.\n\n/** Every documented component: the web primitives (one entry of the package each) and the native-only ones. */\nexport type ComponentName =\n | \"achievement\"\n | \"action-bar\"\n | \"alert\"\n | \"app-shell\"\n | \"argument-card\"\n | \"audio-player\"\n | \"auth-layout\"\n | \"avatar\"\n | \"badge\"\n | \"button\"\n | \"card\"\n | \"card-grid\"\n | \"catalogue-page\"\n | \"changelog-page\"\n | \"checkbox\"\n | \"chip\"\n | \"chip-link\"\n | \"choice-grid\"\n | \"cn\"\n | \"code-block\"\n | \"combobox\"\n | \"command\"\n | \"component-page\"\n | \"confirm-button\"\n | \"contact-page\"\n | \"continue-prompt\"\n | \"countdown\"\n | \"cta-panel\"\n | \"dashboard-layout\"\n | \"data-table\"\n | \"date-picker\"\n | \"decision-list\"\n | \"detail-layout\"\n | \"dialog\"\n | \"docs-article-page\"\n | \"docs-hub-page\"\n | \"docs-layout\"\n | \"dropdown-menu\"\n | \"empty-state\"\n | \"error-page\"\n | \"field\"\n | \"file-upload\"\n | \"filter-bar\"\n | \"gallery-page\"\n | \"glow-card\"\n | \"goal-gauge\"\n | \"how-it-works-page\"\n | \"image-cropper\"\n | \"iso\"\n | \"kbd\"\n | \"landing-page\"\n | \"landscape\"\n | \"legal-page\"\n | \"link-card\"\n | \"loader\"\n | \"longform-page\"\n | \"marketing-layout\"\n | \"marquee\"\n | \"mascot-quote\"\n | \"mascot-state\"\n | \"mascots\"\n | \"media-capture\"\n | \"meter\"\n | \"nav-bar\"\n | \"number-ticker\"\n | \"page\"\n | \"page-header\"\n | \"page-hero\"\n | \"pagination\"\n | \"pointer-light\"\n | \"popover\"\n | \"pricing-page\"\n | \"product-page\"\n | \"profile-card\"\n | \"progress\"\n | \"promise-card\"\n | \"radio-group\"\n | \"scroll-stage\"\n | \"search-field\"\n | \"section-backdrop\"\n | \"segmented\"\n | \"separator\"\n | \"settings-layout\"\n | \"skeleton\"\n | \"slider\"\n | \"slot\"\n | \"spinner\"\n | \"split-view\"\n | \"stage-banner\"\n | \"stat\"\n | \"status-page\"\n | \"stepper\"\n | \"switch\"\n | \"tabs\"\n | \"tag-input\"\n | \"terminal-replay\"\n | \"theme\"\n | \"toast\"\n | \"toc\"\n | \"tooltip\"\n | \"txt\"\n | \"video-player\"\n | \"video-trimmer\";\n\n/** Where a component exists: `@krizaka/ui/<name>` (web), `@krizaka/ui/native` (React Native), or both. */\nexport type Platform = \"web\" | \"native\" | \"both\";\n\n/** `stable`: its API only changes in a major. `beta`: it may still change in a minor. */\nexport type Status = \"stable\" | \"beta\";\n\n/**\n * The group of the catalogue. `media`: video, sound, camera, files, cropping. `blocks`: the page blocks — the frame,\n * the hero, sections, cards that lead or argue, decisions, code, calls to act — that every page of a site is made of.\n * `layouts`: the shells of whole screens — an application, a dashboard, settings, sign-in, an object, a list and its\n * item, a site's page, a documentation page — each with its screens. `templates`: the page templates — whole pages of a\n * site (a landing, a product, a docs hub, a long read, a changelog, pricing, status, an error…), each a distinct\n * composition of the blocks, words and content as props.\n */\nexport type Category = \"actions\" | \"forms\" | \"navigation\" | \"overlays\" | \"feedback\" | \"data-display\" | \"media\" | \"blocks\" | \"layouts\" | \"templates\" | \"layout\" | \"foundations\";\n\n/**\n * A named example: the file `registry/examples/<component>/<name>.tsx` (web) or\n * `registry/examples/<component>/native/<name>.tsx` (React Native) — at most 40 lines, imported by the stories and\n * shown (live, with its code) by the documentation.\n */\nexport interface Example {\n /** The file name, kebab-case (`primary`, `icon-button`). */\n readonly name: string;\n /** A short title (`Primary`, `Icon button`). */\n readonly title: string;\n /** One or two sentences: when this variant is the right one. */\n readonly description: string;\n /**\n * A template: a whole screen of a product composed from the platform (a layout and its blocks, real words, its phone\n * version thought out), copied as a starting point — at most 160 lines, listed on krizaka.com/docs/ui/templates.\n */\n readonly template?: boolean;\n}\n\n/** One platform's side of a component. */\nexport interface PlatformDocs {\n /** The names to import (`[\"Button\", \"IconButton\"]`): from `@krizaka/ui/<name>` on the web, `@krizaka/ui/native` in React Native. */\n readonly imports: readonly string[];\n /** The examples, in reading order; the first one is the component's preview. */\n readonly examples: readonly Example[];\n}\n\n/** The React Native side: the same concept, and what differs from the web API. */\nexport interface NativeDocs extends PlatformDocs {\n /**\n * The entry to import from when it is not `@krizaka/ui/native`: a component that needs an Expo module (an optional\n * peer) has its own, `@krizaka/ui/native/<name>`, so an app that does not use it never installs the module.\n */\n readonly entry?: string;\n /** What differs from the web API (`label` instead of children…); empty for a native-only component. */\n readonly differences: readonly string[];\n}\n\nexport interface KeyboardInteraction {\n /** The keys, as written on a keyboard: `Space`, `Enter`, `Arrow keys`, `Esc`, `Tab`. */\n readonly keys: string;\n /** What they do. */\n readonly action: string;\n}\n\nexport interface ComponentMeta {\n /** The display name: `Button`, `Dropdown menu`. */\n readonly title: string;\n /** One sentence: what it is. */\n readonly summary: string;\n readonly status: Status;\n readonly category: Category;\n /** Must match the sides below: `both` ⇔ `web` and `native`. */\n readonly platforms: Platform;\n /** When to reach for it: concrete situations, one per item. */\n readonly whenToUse: readonly string[];\n /** When not to — and what to use instead (`use`), when another component is the answer. */\n readonly whenNotToUse: readonly { readonly when: string; readonly use?: ComponentName }[];\n /** How to use it well: wording, placement, composition. */\n readonly bestPractices: readonly string[];\n readonly accessibility: {\n /** The keyboard, when it does more than Tab and Enter. */\n readonly keyboard: readonly KeyboardInteraction[];\n /** Roles, names and announcements: what the component does, what the app must provide. */\n readonly notes: readonly string[];\n };\n /** The components a reader of this page should know about. */\n readonly related: readonly ComponentName[];\n readonly web?: PlatformDocs;\n readonly native?: NativeDocs;\n}\n"
|
|
129
|
+
}
|
|
130
|
+
],
|
|
131
|
+
"dependencies": [],
|
|
132
|
+
"registryDependencies": [
|
|
133
|
+
"cn"
|
|
134
|
+
],
|
|
135
|
+
"demo": {
|
|
136
|
+
"path": "examples/landscape/backdrop.tsx",
|
|
137
|
+
"content": "import { Landscape } from \"@krizaka/ui/landscape\";\n\n// A page's end: the Krizaka valley at dusk behind the last words, faded into the surface.\nexport default function LandscapeBackdrop() {\n return (\n <div className=\"relative h-80 w-full max-w-3xl overflow-hidden rounded-2xl border border-border-subtle\">\n <Landscape animated={false} />\n <p className=\"relative z-10 p-6 text-lg font-semibold text-fg\">Built in the open, in Montréal.</p>\n </div>\n );\n}\n"
|
|
138
|
+
},
|
|
139
|
+
"props": [
|
|
140
|
+
{
|
|
141
|
+
"component": "Landscape",
|
|
142
|
+
"description": "The Krizaka landscape: a decorative backdrop for a hero or a page's end (`aria-hidden`).",
|
|
143
|
+
"props": [
|
|
144
|
+
{
|
|
145
|
+
"name": "animated",
|
|
146
|
+
"type": "boolean",
|
|
147
|
+
"default": "true",
|
|
148
|
+
"description": "The slow loops (the sun, the stars, the flames, the birds). `false` holds the first frame; always held under\n`prefers-reduced-motion` and while off screen (with `MotionObserver`).",
|
|
149
|
+
"required": false
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
"name": "fade",
|
|
153
|
+
"type": "boolean",
|
|
154
|
+
"default": "true",
|
|
155
|
+
"description": "Fades the bottom into the page's surface.",
|
|
156
|
+
"required": false
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
"name": "flock",
|
|
160
|
+
"type": "boolean",
|
|
161
|
+
"default": "true",
|
|
162
|
+
"description": "The flock at work in the valley (hidden under 1024 px wide either way).",
|
|
163
|
+
"required": false
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
"name": "phoenix",
|
|
167
|
+
"type": "boolean",
|
|
168
|
+
"default": "true",
|
|
169
|
+
"description": "The phoenix and its river of two flames.",
|
|
170
|
+
"required": false
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
"name": "position",
|
|
174
|
+
"type": "\"absolute\" | \"relative\"",
|
|
175
|
+
"default": "absolute",
|
|
176
|
+
"description": "`absolute`: fills its positioned parent, anchored at the bottom (a backdrop). `relative`: a block in the flow — give\nit a height.",
|
|
177
|
+
"required": false
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
"name": "tone",
|
|
181
|
+
"type": "\"brand\" | \"own\"",
|
|
182
|
+
"default": "own",
|
|
183
|
+
"description": "`own`: the Krizaka dusk (indigo, cyan and magenta peaks). `brand`: the sky and the peaks in the host brand's\naccents (`.brand-<id>`). The birds and the phoenix keep their own colours.",
|
|
184
|
+
"required": false
|
|
185
|
+
}
|
|
186
|
+
]
|
|
187
|
+
}
|
|
188
|
+
]
|
|
189
|
+
}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "legal-page",
|
|
3
|
+
"type": "primitive",
|
|
4
|
+
"title": "Legal page",
|
|
5
|
+
"summary": "A policy or terms: the date in force, the short version in plain words, the sections in a narrow column with their contents beside them.",
|
|
6
|
+
"description": "A policy or terms: the date in force, the short version in plain words, the sections in a narrow column with their contents beside them.",
|
|
7
|
+
"status": "beta",
|
|
8
|
+
"category": "templates",
|
|
9
|
+
"platforms": "web",
|
|
10
|
+
"whenToUse": [
|
|
11
|
+
"Privacy, terms, cookies, a licence.",
|
|
12
|
+
"Any document read section by section."
|
|
13
|
+
],
|
|
14
|
+
"whenNotToUse": [
|
|
15
|
+
{
|
|
16
|
+
"when": "For a long read with chapters.",
|
|
17
|
+
"use": "longform-page"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"when": "For a documentation article.",
|
|
21
|
+
"use": "docs-article-page"
|
|
22
|
+
}
|
|
23
|
+
],
|
|
24
|
+
"bestPractices": [
|
|
25
|
+
"Open with the short version in plain words.",
|
|
26
|
+
"Date the document; keep each section to one subject.",
|
|
27
|
+
"Words and content arrive as props; the motion is the platform's (`[data-reveal]`, still under reduced motion)."
|
|
28
|
+
],
|
|
29
|
+
"accessibility": {
|
|
30
|
+
"keyboard": [],
|
|
31
|
+
"notes": [
|
|
32
|
+
"Sections are named by their `h2`; the contents a named `nav`.",
|
|
33
|
+
"The summary is plain text, read first."
|
|
34
|
+
]
|
|
35
|
+
},
|
|
36
|
+
"related": [
|
|
37
|
+
"toc",
|
|
38
|
+
"longform-page",
|
|
39
|
+
"page"
|
|
40
|
+
],
|
|
41
|
+
"web": {
|
|
42
|
+
"entry": "@krizaka/ui/legal-page",
|
|
43
|
+
"import": "import { LegalPage } from \"@krizaka/ui/legal-page\";",
|
|
44
|
+
"props": [
|
|
45
|
+
{
|
|
46
|
+
"component": "LegalPage",
|
|
47
|
+
"description": "A legal page: hero with the date, a plain-words summary, the sections with their contents.",
|
|
48
|
+
"props": [
|
|
49
|
+
{
|
|
50
|
+
"name": "sections",
|
|
51
|
+
"type": "readonly LegalSection[]",
|
|
52
|
+
"default": null,
|
|
53
|
+
"description": "The sections.",
|
|
54
|
+
"required": true
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"name": "title",
|
|
58
|
+
"type": "ReactNode",
|
|
59
|
+
"default": null,
|
|
60
|
+
"description": "The page's `h1` (`Privacy policy`).",
|
|
61
|
+
"required": true
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"name": "tocLabel",
|
|
65
|
+
"type": "string",
|
|
66
|
+
"default": null,
|
|
67
|
+
"description": "The contents' label (`On this page`).",
|
|
68
|
+
"required": true
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"name": "back",
|
|
72
|
+
"type": "{ href: string; label: string; }",
|
|
73
|
+
"default": null,
|
|
74
|
+
"description": "The way back.",
|
|
75
|
+
"required": false
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"name": "linkAs",
|
|
79
|
+
"type": "LinkComponent",
|
|
80
|
+
"default": null,
|
|
81
|
+
"description": "The app's link component (Next's `Link`).",
|
|
82
|
+
"required": false
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"name": "summary",
|
|
86
|
+
"type": "ReactNode",
|
|
87
|
+
"default": null,
|
|
88
|
+
"description": "The short version, in plain words, before the sections.",
|
|
89
|
+
"required": false
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"name": "updated",
|
|
93
|
+
"type": "ReactNode",
|
|
94
|
+
"default": null,
|
|
95
|
+
"description": "In force since (`Last updated: October 2026`).",
|
|
96
|
+
"required": false
|
|
97
|
+
}
|
|
98
|
+
]
|
|
99
|
+
}
|
|
100
|
+
],
|
|
101
|
+
"examples": [
|
|
102
|
+
{
|
|
103
|
+
"name": "privacy",
|
|
104
|
+
"title": "Privacy policy",
|
|
105
|
+
"description": "A summary and three sections with their contents.",
|
|
106
|
+
"template": true,
|
|
107
|
+
"path": "examples/legal-page/privacy.tsx",
|
|
108
|
+
"module": "@krizaka/ui/registry/examples/legal-page/privacy",
|
|
109
|
+
"code": "import { LegalPage } from \"@krizaka/ui/legal-page\";\n\n// TEMPLATE — a policy: the date in force, the short version in plain words, then the sections with their contents\n// beside them (chips on a phone).\nexport default function LegalPagePrivacy() {\n return (\n <LegalPage\n title=\"Privacy policy\"\n updated=\"Last updated: October 2026\"\n summary=\"In short: we collect what you send us, keep it in Québec, never sell it, and delete it when you ask.\"\n tocLabel=\"On this page\"\n sections={[\n { id: \"collect\", title: \"What we collect\", children: <p>Your email and your message, when you write to us.</p> },\n { id: \"keep\", title: \"Where it is kept\", children: <p>On servers in Québec, encrypted at rest.</p> },\n { id: \"rights\", title: \"Your rights\", children: <p>Ask for a copy or for deletion at any time; we answer within 30 days.</p> },\n ]}\n />\n );\n}\n"
|
|
110
|
+
}
|
|
111
|
+
]
|
|
112
|
+
},
|
|
113
|
+
"native": null,
|
|
114
|
+
"files": [
|
|
115
|
+
{
|
|
116
|
+
"path": "legal-page/index.ts",
|
|
117
|
+
"content": "/** @krizaka/ui/legal-page — `LegalPage`: A legal page: the date in force, a plain-words summary, sections with their contents. Server-safe; a page template. */\nexport { LegalPage, type LegalPageProps, type LegalSection } from \"./legal-page\";\n"
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
"path": "legal-page/legal-page.tsx",
|
|
121
|
+
"content": "// Server-safe. A policy or terms (TocLayout): the hero with the date in force, then the sections in a narrow reading\n// column with their contents beside — chips on a phone — and a summary in plain words first when there is one.\nimport { Page, Section } from \"@krizaka/ui/page\";\nimport type { LinkComponent } from \"@krizaka/ui/page-hero\";\nimport { PageHero } from \"@krizaka/ui/page-hero\";\nimport { Toc, TocLayout } from \"@krizaka/ui/toc\";\nimport type * as React from \"react\";\n\nexport interface LegalSection {\n /** The section's anchor. */\n id: string;\n /** Its title. */\n title: string;\n /** Its paragraphs. */\n children: React.ReactNode;\n}\n\nexport type LegalPageProps = Omit<React.HTMLAttributes<HTMLElement>, \"title\"> & {\n /** The way back. */\n back?: { href: string; label: string };\n /** The page's `h1` (`Privacy policy`). */\n title: React.ReactNode;\n /** In force since (`Last updated: October 2026`). */\n updated?: React.ReactNode;\n /** The short version, in plain words, before the sections. */\n summary?: React.ReactNode;\n /** The contents' label (`On this page`). */\n tocLabel: string;\n /** The sections. */\n sections: readonly LegalSection[];\n /** The app's link component (Next's `Link`). */\n linkAs?: LinkComponent;\n};\n\n/** A legal page: hero with the date, a plain-words summary, the sections with their contents. */\nexport function LegalPage({ back, title, updated, summary, tocLabel, sections, linkAs, ...props }: LegalPageProps) {\n return (\n <div {...props}>\n <PageHero back={back} linkAs={linkAs} title={title} lead={updated} backdrop=\"plain\" />\n <Page className=\"kz-tpl-longform\">\n <TocLayout toc={<Toc label={tocLabel} items={sections.map((s) => ({ id: s.id, label: s.title }))} />}>\n {summary && <div className=\"kz-cta kz-tpl-summary\">{summary}</div>}\n {sections.map((s, i) => (\n <Section key={s.id} id={s.id} title={s.title} headingSize=\"sm\" spacing=\"sm\" size=\"narrow\" divider={i > 0 || Boolean(summary)}>\n <div className=\"kz-tpl-prose\">{s.children}</div>\n </Section>\n ))}\n </TocLayout>\n </Page>\n </div>\n );\n}\n"
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
"path": "legal-page/meta.ts",
|
|
125
|
+
"content": "import type { ComponentMeta } from \"../meta\";\n\nexport const meta = {\n title: \"Legal page\",\n summary: \"A policy or terms: the date in force, the short version in plain words, the sections in a narrow column with their contents beside them.\",\n status: \"beta\",\n category: \"templates\",\n platforms: \"web\",\n whenToUse: [\"Privacy, terms, cookies, a licence.\", \"Any document read section by section.\"],\n whenNotToUse: [\n { when: \"For a long read with chapters.\", use: \"longform-page\" },\n { when: \"For a documentation article.\", use: \"docs-article-page\" },\n ],\n bestPractices: [\"Open with the short version in plain words.\", \"Date the document; keep each section to one subject.\", \"Words and content arrive as props; the motion is the platform's (`[data-reveal]`, still under reduced motion).\"],\n accessibility: {\n keyboard: [],\n notes: [\"Sections are named by their `h2`; the contents a named `nav`.\", \"The summary is plain text, read first.\"],\n },\n related: [\"toc\", \"longform-page\", \"page\"],\n web: {\n imports: [\"LegalPage\"],\n examples: [\n { name: \"privacy\", title: \"Privacy policy\", description: \"A summary and three sections with their contents.\", template: true },\n ],\n },\n} satisfies ComponentMeta;\n"
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
"path": "meta.ts",
|
|
129
|
+
"content": "// The documentation of a component, carried by its code: each primitive has a `meta.ts` beside its source\n// (`src/<name>/meta.ts`; a component that exists only in React Native: `src/native/meta/<name>.ts`). Never built into\n// the package: `scripts/build-registry.mjs` reads them into `registry/<name>.json`, which krizaka.com renders as\n// /docs/ui/<name>, and `scripts/registry.test.mjs` fails when one is missing or incomplete.\n//\n// Why a typed module and not JSDoc tags: the fields are lists and links (`related`, `whenNotToUse[].use`, examples),\n// which a type checks and a comment does not; the file is plain data (erasable TypeScript), so Node reads it without a\n// compiler, and an editor completes it.\n\n/** Every documented component: the web primitives (one entry of the package each) and the native-only ones. */\nexport type ComponentName =\n | \"achievement\"\n | \"action-bar\"\n | \"alert\"\n | \"app-shell\"\n | \"argument-card\"\n | \"audio-player\"\n | \"auth-layout\"\n | \"avatar\"\n | \"badge\"\n | \"button\"\n | \"card\"\n | \"card-grid\"\n | \"catalogue-page\"\n | \"changelog-page\"\n | \"checkbox\"\n | \"chip\"\n | \"chip-link\"\n | \"choice-grid\"\n | \"cn\"\n | \"code-block\"\n | \"combobox\"\n | \"command\"\n | \"component-page\"\n | \"confirm-button\"\n | \"contact-page\"\n | \"continue-prompt\"\n | \"countdown\"\n | \"cta-panel\"\n | \"dashboard-layout\"\n | \"data-table\"\n | \"date-picker\"\n | \"decision-list\"\n | \"detail-layout\"\n | \"dialog\"\n | \"docs-article-page\"\n | \"docs-hub-page\"\n | \"docs-layout\"\n | \"dropdown-menu\"\n | \"empty-state\"\n | \"error-page\"\n | \"field\"\n | \"file-upload\"\n | \"filter-bar\"\n | \"gallery-page\"\n | \"glow-card\"\n | \"goal-gauge\"\n | \"how-it-works-page\"\n | \"image-cropper\"\n | \"iso\"\n | \"kbd\"\n | \"landing-page\"\n | \"landscape\"\n | \"legal-page\"\n | \"link-card\"\n | \"loader\"\n | \"longform-page\"\n | \"marketing-layout\"\n | \"marquee\"\n | \"mascot-quote\"\n | \"mascot-state\"\n | \"mascots\"\n | \"media-capture\"\n | \"meter\"\n | \"nav-bar\"\n | \"number-ticker\"\n | \"page\"\n | \"page-header\"\n | \"page-hero\"\n | \"pagination\"\n | \"pointer-light\"\n | \"popover\"\n | \"pricing-page\"\n | \"product-page\"\n | \"profile-card\"\n | \"progress\"\n | \"promise-card\"\n | \"radio-group\"\n | \"scroll-stage\"\n | \"search-field\"\n | \"section-backdrop\"\n | \"segmented\"\n | \"separator\"\n | \"settings-layout\"\n | \"skeleton\"\n | \"slider\"\n | \"slot\"\n | \"spinner\"\n | \"split-view\"\n | \"stage-banner\"\n | \"stat\"\n | \"status-page\"\n | \"stepper\"\n | \"switch\"\n | \"tabs\"\n | \"tag-input\"\n | \"terminal-replay\"\n | \"theme\"\n | \"toast\"\n | \"toc\"\n | \"tooltip\"\n | \"txt\"\n | \"video-player\"\n | \"video-trimmer\";\n\n/** Where a component exists: `@krizaka/ui/<name>` (web), `@krizaka/ui/native` (React Native), or both. */\nexport type Platform = \"web\" | \"native\" | \"both\";\n\n/** `stable`: its API only changes in a major. `beta`: it may still change in a minor. */\nexport type Status = \"stable\" | \"beta\";\n\n/**\n * The group of the catalogue. `media`: video, sound, camera, files, cropping. `blocks`: the page blocks — the frame,\n * the hero, sections, cards that lead or argue, decisions, code, calls to act — that every page of a site is made of.\n * `layouts`: the shells of whole screens — an application, a dashboard, settings, sign-in, an object, a list and its\n * item, a site's page, a documentation page — each with its screens. `templates`: the page templates — whole pages of a\n * site (a landing, a product, a docs hub, a long read, a changelog, pricing, status, an error…), each a distinct\n * composition of the blocks, words and content as props.\n */\nexport type Category = \"actions\" | \"forms\" | \"navigation\" | \"overlays\" | \"feedback\" | \"data-display\" | \"media\" | \"blocks\" | \"layouts\" | \"templates\" | \"layout\" | \"foundations\";\n\n/**\n * A named example: the file `registry/examples/<component>/<name>.tsx` (web) or\n * `registry/examples/<component>/native/<name>.tsx` (React Native) — at most 40 lines, imported by the stories and\n * shown (live, with its code) by the documentation.\n */\nexport interface Example {\n /** The file name, kebab-case (`primary`, `icon-button`). */\n readonly name: string;\n /** A short title (`Primary`, `Icon button`). */\n readonly title: string;\n /** One or two sentences: when this variant is the right one. */\n readonly description: string;\n /**\n * A template: a whole screen of a product composed from the platform (a layout and its blocks, real words, its phone\n * version thought out), copied as a starting point — at most 160 lines, listed on krizaka.com/docs/ui/templates.\n */\n readonly template?: boolean;\n}\n\n/** One platform's side of a component. */\nexport interface PlatformDocs {\n /** The names to import (`[\"Button\", \"IconButton\"]`): from `@krizaka/ui/<name>` on the web, `@krizaka/ui/native` in React Native. */\n readonly imports: readonly string[];\n /** The examples, in reading order; the first one is the component's preview. */\n readonly examples: readonly Example[];\n}\n\n/** The React Native side: the same concept, and what differs from the web API. */\nexport interface NativeDocs extends PlatformDocs {\n /**\n * The entry to import from when it is not `@krizaka/ui/native`: a component that needs an Expo module (an optional\n * peer) has its own, `@krizaka/ui/native/<name>`, so an app that does not use it never installs the module.\n */\n readonly entry?: string;\n /** What differs from the web API (`label` instead of children…); empty for a native-only component. */\n readonly differences: readonly string[];\n}\n\nexport interface KeyboardInteraction {\n /** The keys, as written on a keyboard: `Space`, `Enter`, `Arrow keys`, `Esc`, `Tab`. */\n readonly keys: string;\n /** What they do. */\n readonly action: string;\n}\n\nexport interface ComponentMeta {\n /** The display name: `Button`, `Dropdown menu`. */\n readonly title: string;\n /** One sentence: what it is. */\n readonly summary: string;\n readonly status: Status;\n readonly category: Category;\n /** Must match the sides below: `both` ⇔ `web` and `native`. */\n readonly platforms: Platform;\n /** When to reach for it: concrete situations, one per item. */\n readonly whenToUse: readonly string[];\n /** When not to — and what to use instead (`use`), when another component is the answer. */\n readonly whenNotToUse: readonly { readonly when: string; readonly use?: ComponentName }[];\n /** How to use it well: wording, placement, composition. */\n readonly bestPractices: readonly string[];\n readonly accessibility: {\n /** The keyboard, when it does more than Tab and Enter. */\n readonly keyboard: readonly KeyboardInteraction[];\n /** Roles, names and announcements: what the component does, what the app must provide. */\n readonly notes: readonly string[];\n };\n /** The components a reader of this page should know about. */\n readonly related: readonly ComponentName[];\n readonly web?: PlatformDocs;\n readonly native?: NativeDocs;\n}\n"
|
|
130
|
+
}
|
|
131
|
+
],
|
|
132
|
+
"dependencies": [],
|
|
133
|
+
"registryDependencies": [
|
|
134
|
+
"page",
|
|
135
|
+
"page-hero",
|
|
136
|
+
"toc"
|
|
137
|
+
],
|
|
138
|
+
"demo": {
|
|
139
|
+
"path": "examples/legal-page/privacy.tsx",
|
|
140
|
+
"content": "import { LegalPage } from \"@krizaka/ui/legal-page\";\n\n// TEMPLATE — a policy: the date in force, the short version in plain words, then the sections with their contents\n// beside them (chips on a phone).\nexport default function LegalPagePrivacy() {\n return (\n <LegalPage\n title=\"Privacy policy\"\n updated=\"Last updated: October 2026\"\n summary=\"In short: we collect what you send us, keep it in Québec, never sell it, and delete it when you ask.\"\n tocLabel=\"On this page\"\n sections={[\n { id: \"collect\", title: \"What we collect\", children: <p>Your email and your message, when you write to us.</p> },\n { id: \"keep\", title: \"Where it is kept\", children: <p>On servers in Québec, encrypted at rest.</p> },\n { id: \"rights\", title: \"Your rights\", children: <p>Ask for a copy or for deletion at any time; we answer within 30 days.</p> },\n ]}\n />\n );\n}\n"
|
|
141
|
+
},
|
|
142
|
+
"props": [
|
|
143
|
+
{
|
|
144
|
+
"component": "LegalPage",
|
|
145
|
+
"description": "A legal page: hero with the date, a plain-words summary, the sections with their contents.",
|
|
146
|
+
"props": [
|
|
147
|
+
{
|
|
148
|
+
"name": "sections",
|
|
149
|
+
"type": "readonly LegalSection[]",
|
|
150
|
+
"default": null,
|
|
151
|
+
"description": "The sections.",
|
|
152
|
+
"required": true
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
"name": "title",
|
|
156
|
+
"type": "ReactNode",
|
|
157
|
+
"default": null,
|
|
158
|
+
"description": "The page's `h1` (`Privacy policy`).",
|
|
159
|
+
"required": true
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
"name": "tocLabel",
|
|
163
|
+
"type": "string",
|
|
164
|
+
"default": null,
|
|
165
|
+
"description": "The contents' label (`On this page`).",
|
|
166
|
+
"required": true
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
"name": "back",
|
|
170
|
+
"type": "{ href: string; label: string; }",
|
|
171
|
+
"default": null,
|
|
172
|
+
"description": "The way back.",
|
|
173
|
+
"required": false
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
"name": "linkAs",
|
|
177
|
+
"type": "LinkComponent",
|
|
178
|
+
"default": null,
|
|
179
|
+
"description": "The app's link component (Next's `Link`).",
|
|
180
|
+
"required": false
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
"name": "summary",
|
|
184
|
+
"type": "ReactNode",
|
|
185
|
+
"default": null,
|
|
186
|
+
"description": "The short version, in plain words, before the sections.",
|
|
187
|
+
"required": false
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
"name": "updated",
|
|
191
|
+
"type": "ReactNode",
|
|
192
|
+
"default": null,
|
|
193
|
+
"description": "In force since (`Last updated: October 2026`).",
|
|
194
|
+
"required": false
|
|
195
|
+
}
|
|
196
|
+
]
|
|
197
|
+
}
|
|
198
|
+
]
|
|
199
|
+
}
|
package/registry/link-card.json
CHANGED
|
@@ -182,7 +182,7 @@
|
|
|
182
182
|
},
|
|
183
183
|
{
|
|
184
184
|
"path": "meta.ts",
|
|
185
|
-
"content": "// The documentation of a component, carried by its code: each primitive has a `meta.ts` beside its source\n// (`src/<name>/meta.ts`; a component that exists only in React Native: `src/native/meta/<name>.ts`). Never built into\n// the package: `scripts/build-registry.mjs` reads them into `registry/<name>.json`, which krizaka.com renders as\n// /docs/ui/<name>, and `scripts/registry.test.mjs` fails when one is missing or incomplete.\n//\n// Why a typed module and not JSDoc tags: the fields are lists and links (`related`, `whenNotToUse[].use`, examples),\n// which a type checks and a comment does not; the file is plain data (erasable TypeScript), so Node reads it without a\n// compiler, and an editor completes it.\n\n/** Every documented component: the web primitives (one entry of the package each) and the native-only ones. */\nexport type ComponentName =\n | \"action-bar\"\n | \"alert\"\n | \"argument-card\"\n | \"audio-player\"\n | \"avatar\"\n | \"badge\"\n | \"button\"\n | \"card\"\n | \"card-grid\"\n | \"checkbox\"\n | \"chip\"\n | \"chip-link\"\n | \"cn\"\n | \"code-block\"\n | \"combobox\"\n | \"command\"\n | \"confirm-button\"\n | \"countdown\"\n | \"cta-panel\"\n | \"data-table\"\n | \"date-picker\"\n | \"decision-list\"\n | \"dialog\"\n | \"dropdown-menu\"\n | \"empty-state\"\n | \"field\"\n | \"file-upload\"\n | \"filter-bar\"\n | \"glow-card\"\n | \"image-cropper\"\n | \"iso\"\n | \"kbd\"\n | \"link-card\"\n | \"loader\"\n | \"marquee\"\n | \"mascot-quote\"\n | \"mascot-state\"\n | \"mascots\"\n | \"media-capture\"\n | \"meter\"\n | \"nav-bar\"\n | \"number-ticker\"\n | \"page\"\n | \"page-header\"\n | \"page-hero\"\n | \"pagination\"\n | \"pointer-light\"\n | \"popover\"\n | \"progress\"\n | \"radio-group\"\n | \"search-field\"\n | \"section-backdrop\"\n | \"segmented\"\n | \"separator\"\n | \"skeleton\"\n | \"slider\"\n | \"slot\"\n | \"spinner\"\n | \"stat\"\n | \"stepper\"\n | \"switch\"\n | \"tabs\"\n | \"tag-input\"\n | \"terminal-replay\"\n | \"theme\"\n | \"toast\"\n | \"toc\"\n | \"tooltip\"\n | \"txt\"\n | \"video-player\"\n | \"video-trimmer\";\n\n/** Where a component exists: `@krizaka/ui/<name>` (web), `@krizaka/ui/native` (React Native), or both. */\nexport type Platform = \"web\" | \"native\" | \"both\";\n\n/** `stable`: its API only changes in a major. `beta`: it may still change in a minor. */\nexport type Status = \"stable\" | \"beta\";\n\n/**\n * The group of the catalogue. `media`: video, sound, camera, files, cropping. `blocks`: the page blocks — the frame,\n * the hero, sections, cards that lead or argue, decisions, code, calls to act — that every page of a site is made of.\n */\nexport type Category = \"actions\" | \"forms\" | \"navigation\" | \"overlays\" | \"feedback\" | \"data-display\" | \"media\" | \"blocks\" | \"layout\" | \"foundations\";\n\n/**\n * A named example: the file `registry/examples/<component>/<name>.tsx` (web) or\n * `registry/examples/<component>/native/<name>.tsx` (React Native) — at most 40 lines, imported by the stories and\n * shown (live, with its code) by the documentation.\n */\nexport interface Example {\n /** The file name, kebab-case (`primary`, `icon-button`). */\n readonly name: string;\n /** A short title (`Primary`, `Icon button`). */\n readonly title: string;\n /** One or two sentences: when this variant is the right one. */\n readonly description: string;\n}\n\n/** One platform's side of a component. */\nexport interface PlatformDocs {\n /** The names to import (`[\"Button\", \"IconButton\"]`): from `@krizaka/ui/<name>` on the web, `@krizaka/ui/native` in React Native. */\n readonly imports: readonly string[];\n /** The examples, in reading order; the first one is the component's preview. */\n readonly examples: readonly Example[];\n}\n\n/** The React Native side: the same concept, and what differs from the web API. */\nexport interface NativeDocs extends PlatformDocs {\n /**\n * The entry to import from when it is not `@krizaka/ui/native`: a component that needs an Expo module (an optional\n * peer) has its own, `@krizaka/ui/native/<name>`, so an app that does not use it never installs the module.\n */\n readonly entry?: string;\n /** What differs from the web API (`label` instead of children…); empty for a native-only component. */\n readonly differences: readonly string[];\n}\n\nexport interface KeyboardInteraction {\n /** The keys, as written on a keyboard: `Space`, `Enter`, `Arrow keys`, `Esc`, `Tab`. */\n readonly keys: string;\n /** What they do. */\n readonly action: string;\n}\n\nexport interface ComponentMeta {\n /** The display name: `Button`, `Dropdown menu`. */\n readonly title: string;\n /** One sentence: what it is. */\n readonly summary: string;\n readonly status: Status;\n readonly category: Category;\n /** Must match the sides below: `both` ⇔ `web` and `native`. */\n readonly platforms: Platform;\n /** When to reach for it: concrete situations, one per item. */\n readonly whenToUse: readonly string[];\n /** When not to — and what to use instead (`use`), when another component is the answer. */\n readonly whenNotToUse: readonly { readonly when: string; readonly use?: ComponentName }[];\n /** How to use it well: wording, placement, composition. */\n readonly bestPractices: readonly string[];\n readonly accessibility: {\n /** The keyboard, when it does more than Tab and Enter. */\n readonly keyboard: readonly KeyboardInteraction[];\n /** Roles, names and announcements: what the component does, what the app must provide. */\n readonly notes: readonly string[];\n };\n /** The components a reader of this page should know about. */\n readonly related: readonly ComponentName[];\n readonly web?: PlatformDocs;\n readonly native?: NativeDocs;\n}\n"
|
|
185
|
+
"content": "// The documentation of a component, carried by its code: each primitive has a `meta.ts` beside its source\n// (`src/<name>/meta.ts`; a component that exists only in React Native: `src/native/meta/<name>.ts`). Never built into\n// the package: `scripts/build-registry.mjs` reads them into `registry/<name>.json`, which krizaka.com renders as\n// /docs/ui/<name>, and `scripts/registry.test.mjs` fails when one is missing or incomplete.\n//\n// Why a typed module and not JSDoc tags: the fields are lists and links (`related`, `whenNotToUse[].use`, examples),\n// which a type checks and a comment does not; the file is plain data (erasable TypeScript), so Node reads it without a\n// compiler, and an editor completes it.\n\n/** Every documented component: the web primitives (one entry of the package each) and the native-only ones. */\nexport type ComponentName =\n | \"achievement\"\n | \"action-bar\"\n | \"alert\"\n | \"app-shell\"\n | \"argument-card\"\n | \"audio-player\"\n | \"auth-layout\"\n | \"avatar\"\n | \"badge\"\n | \"button\"\n | \"card\"\n | \"card-grid\"\n | \"catalogue-page\"\n | \"changelog-page\"\n | \"checkbox\"\n | \"chip\"\n | \"chip-link\"\n | \"choice-grid\"\n | \"cn\"\n | \"code-block\"\n | \"combobox\"\n | \"command\"\n | \"component-page\"\n | \"confirm-button\"\n | \"contact-page\"\n | \"continue-prompt\"\n | \"countdown\"\n | \"cta-panel\"\n | \"dashboard-layout\"\n | \"data-table\"\n | \"date-picker\"\n | \"decision-list\"\n | \"detail-layout\"\n | \"dialog\"\n | \"docs-article-page\"\n | \"docs-hub-page\"\n | \"docs-layout\"\n | \"dropdown-menu\"\n | \"empty-state\"\n | \"error-page\"\n | \"field\"\n | \"file-upload\"\n | \"filter-bar\"\n | \"gallery-page\"\n | \"glow-card\"\n | \"goal-gauge\"\n | \"how-it-works-page\"\n | \"image-cropper\"\n | \"iso\"\n | \"kbd\"\n | \"landing-page\"\n | \"landscape\"\n | \"legal-page\"\n | \"link-card\"\n | \"loader\"\n | \"longform-page\"\n | \"marketing-layout\"\n | \"marquee\"\n | \"mascot-quote\"\n | \"mascot-state\"\n | \"mascots\"\n | \"media-capture\"\n | \"meter\"\n | \"nav-bar\"\n | \"number-ticker\"\n | \"page\"\n | \"page-header\"\n | \"page-hero\"\n | \"pagination\"\n | \"pointer-light\"\n | \"popover\"\n | \"pricing-page\"\n | \"product-page\"\n | \"profile-card\"\n | \"progress\"\n | \"promise-card\"\n | \"radio-group\"\n | \"scroll-stage\"\n | \"search-field\"\n | \"section-backdrop\"\n | \"segmented\"\n | \"separator\"\n | \"settings-layout\"\n | \"skeleton\"\n | \"slider\"\n | \"slot\"\n | \"spinner\"\n | \"split-view\"\n | \"stage-banner\"\n | \"stat\"\n | \"status-page\"\n | \"stepper\"\n | \"switch\"\n | \"tabs\"\n | \"tag-input\"\n | \"terminal-replay\"\n | \"theme\"\n | \"toast\"\n | \"toc\"\n | \"tooltip\"\n | \"txt\"\n | \"video-player\"\n | \"video-trimmer\";\n\n/** Where a component exists: `@krizaka/ui/<name>` (web), `@krizaka/ui/native` (React Native), or both. */\nexport type Platform = \"web\" | \"native\" | \"both\";\n\n/** `stable`: its API only changes in a major. `beta`: it may still change in a minor. */\nexport type Status = \"stable\" | \"beta\";\n\n/**\n * The group of the catalogue. `media`: video, sound, camera, files, cropping. `blocks`: the page blocks — the frame,\n * the hero, sections, cards that lead or argue, decisions, code, calls to act — that every page of a site is made of.\n * `layouts`: the shells of whole screens — an application, a dashboard, settings, sign-in, an object, a list and its\n * item, a site's page, a documentation page — each with its screens. `templates`: the page templates — whole pages of a\n * site (a landing, a product, a docs hub, a long read, a changelog, pricing, status, an error…), each a distinct\n * composition of the blocks, words and content as props.\n */\nexport type Category = \"actions\" | \"forms\" | \"navigation\" | \"overlays\" | \"feedback\" | \"data-display\" | \"media\" | \"blocks\" | \"layouts\" | \"templates\" | \"layout\" | \"foundations\";\n\n/**\n * A named example: the file `registry/examples/<component>/<name>.tsx` (web) or\n * `registry/examples/<component>/native/<name>.tsx` (React Native) — at most 40 lines, imported by the stories and\n * shown (live, with its code) by the documentation.\n */\nexport interface Example {\n /** The file name, kebab-case (`primary`, `icon-button`). */\n readonly name: string;\n /** A short title (`Primary`, `Icon button`). */\n readonly title: string;\n /** One or two sentences: when this variant is the right one. */\n readonly description: string;\n /**\n * A template: a whole screen of a product composed from the platform (a layout and its blocks, real words, its phone\n * version thought out), copied as a starting point — at most 160 lines, listed on krizaka.com/docs/ui/templates.\n */\n readonly template?: boolean;\n}\n\n/** One platform's side of a component. */\nexport interface PlatformDocs {\n /** The names to import (`[\"Button\", \"IconButton\"]`): from `@krizaka/ui/<name>` on the web, `@krizaka/ui/native` in React Native. */\n readonly imports: readonly string[];\n /** The examples, in reading order; the first one is the component's preview. */\n readonly examples: readonly Example[];\n}\n\n/** The React Native side: the same concept, and what differs from the web API. */\nexport interface NativeDocs extends PlatformDocs {\n /**\n * The entry to import from when it is not `@krizaka/ui/native`: a component that needs an Expo module (an optional\n * peer) has its own, `@krizaka/ui/native/<name>`, so an app that does not use it never installs the module.\n */\n readonly entry?: string;\n /** What differs from the web API (`label` instead of children…); empty for a native-only component. */\n readonly differences: readonly string[];\n}\n\nexport interface KeyboardInteraction {\n /** The keys, as written on a keyboard: `Space`, `Enter`, `Arrow keys`, `Esc`, `Tab`. */\n readonly keys: string;\n /** What they do. */\n readonly action: string;\n}\n\nexport interface ComponentMeta {\n /** The display name: `Button`, `Dropdown menu`. */\n readonly title: string;\n /** One sentence: what it is. */\n readonly summary: string;\n readonly status: Status;\n readonly category: Category;\n /** Must match the sides below: `both` ⇔ `web` and `native`. */\n readonly platforms: Platform;\n /** When to reach for it: concrete situations, one per item. */\n readonly whenToUse: readonly string[];\n /** When not to — and what to use instead (`use`), when another component is the answer. */\n readonly whenNotToUse: readonly { readonly when: string; readonly use?: ComponentName }[];\n /** How to use it well: wording, placement, composition. */\n readonly bestPractices: readonly string[];\n readonly accessibility: {\n /** The keyboard, when it does more than Tab and Enter. */\n readonly keyboard: readonly KeyboardInteraction[];\n /** Roles, names and announcements: what the component does, what the app must provide. */\n readonly notes: readonly string[];\n };\n /** The components a reader of this page should know about. */\n readonly related: readonly ComponentName[];\n readonly web?: PlatformDocs;\n readonly native?: NativeDocs;\n}\n"
|
|
186
186
|
}
|
|
187
187
|
],
|
|
188
188
|
"dependencies": [],
|