@krizaka/ui 2.9.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 +41 -5
- 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/{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/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/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/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/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 +11 -2
- package/dist/index.js +93 -5
- 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/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/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 +4 -4
- package/dist/mascots.js +1 -1
- package/dist/native.d.ts +16 -9
- package/dist/native.js +183 -74
- 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/status-page.d.ts +42 -0
- package/dist/status-page.js +28 -0
- package/dist/status-page.js.map +1 -0
- package/package.json +233 -7
- package/registry/achievement.json +1 -1
- package/registry/action-bar.json +1 -1
- package/registry/alert.json +1 -1
- package/registry/app-shell.json +1 -1
- package/registry/argument-card.json +1 -1
- package/registry/audio-player.json +1 -1
- package/registry/auth-layout.json +1 -1
- package/registry/avatar.json +1 -1
- package/registry/badge.json +1 -1
- package/registry/button.json +1 -1
- package/registry/card-grid.json +1 -1
- package/registry/card.json +1 -1
- 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 +1 -1
- 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 +1 -1
- package/registry/contact-page.json +212 -0
- package/registry/continue-prompt.json +1 -1
- package/registry/countdown.json +1 -1
- package/registry/cta-panel.json +1 -1
- package/registry/dashboard-layout.json +1 -1
- 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 +1 -1
- 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 +1 -1
- package/registry/dropdown-menu.json +1 -1
- package/registry/empty-state.json +1 -1
- package/registry/error-page.json +183 -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/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/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/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/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/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/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/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/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 +1 -1
- package/registry/how-it-works-page.json +242 -0
- package/registry/image-cropper.json +1 -1
- package/registry/index.json +309 -5
- package/registry/iso.json +1 -1
- package/registry/kbd.json +1 -1
- package/registry/landing-page.json +242 -0
- package/registry/landscape.json +1 -1
- 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 +1 -1
- package/registry/marquee.json +1 -1
- package/registry/mascot-quote.json +6 -6
- package/registry/mascot-state.json +34 -34
- package/registry/mascots.json +41 -21
- 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 +1 -1
- package/registry/page.json +1 -1
- 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 +1 -1
- package/registry/progress.json +1 -1
- package/registry/promise-card.json +1 -1
- package/registry/radio-group.json +1 -1
- package/registry/scroll-stage.json +1 -1
- 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 +1 -1
- 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 +1 -1
- package/registry/stage-banner.json +1 -1
- 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
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
**The Krizaka front-end platform's components, shared by every product.**
|
|
11
11
|
The primitives (button, badge, avatar, field, theme, countdown…) on the semantic `--kz-*` tokens, the animated marks
|
|
12
|
-
of Krizaka, Orazaka, Orochia and
|
|
12
|
+
of Krizaka, Orazaka, Orochia, Yazakia and Yororis, and the Krizaka motion signature — one easing, one way to enter, reveal, roll, shine
|
|
13
13
|
and open.
|
|
14
14
|
|
|
15
15
|
[](https://www.npmjs.com/package/@krizaka/ui)
|
|
@@ -172,7 +172,7 @@ light or a product's — is a set of tokens.
|
|
|
172
172
|
| `@krizaka/ui/glow-card` | `GlowCard` (`glow` border·spotlight·both, `alive`, `asChild`) | client |
|
|
173
173
|
| `@krizaka/ui/marquee` | `Marquee` (`label`, `pauseLabel`, `playLabel`, `speed` px/s, `direction`, `fade`, `defaultPaused`) | client |
|
|
174
174
|
| `@krizaka/ui/section-backdrop` | `SectionBackdrop` (`as`, `direction` down·up, `dome`, `grid`, `media` blurred for depth of field, `animated`): a page section on the brand's section gradient — see `@krizaka/tokens` BRAND.md, "Visual language" | server |
|
|
175
|
-
| `@krizaka/ui/mascots` | `Mascot` (`bird` falcon·owl·duck·flamingo·pigeon·lovebird, `mood` welcome·thinking·success·empty·error, `tone` brand·own, `size`, `animated`, `title`), `MASCOT_BIRDS`, `MASCOT_MOODS`: the Krizaka flock, in the host brand's accent — one bird at a moment that matters (onboarding, a long wait, a success, an empty list, an error); native `Mascot` in `/native` | client |
|
|
175
|
+
| `@krizaka/ui/mascots` | `Mascot` (`bird` falcon·owl·duck·flamingo·pigeon·lovebird·crane, `mood` welcome·thinking·success·empty·error, `tone` brand·own, `size`, `animated`, `title`), `MASCOT_BIRDS`, `MASCOT_MOODS`: the Krizaka flock, in the host brand's accent — one bird at a moment that matters (onboarding, a long wait, a success, an empty list, an error); native `Mascot` in `/native` | client |
|
|
176
176
|
| `@krizaka/ui/iso` | the isometric kit: `IsoHub` (a hero driven by data: `layers`, `dome`, `satellites`, `highlight`), `IsoScene`, `IsoPrism`, `IsoStack`, `IsoDome`, `IsoTile`, `IsoLink`, `IsoNode`, `IsoLabel`, the projection helpers — static SVG animated by motion.css | server |
|
|
177
177
|
| `@krizaka/ui/motion` | `MotionObserver` (reveal, off-screen pause, settle, spotlight, magnetism) and `RotatingWord` (no layout shift) | client |
|
|
178
178
|
| `@krizaka/ui/pagination` | `Pagination` (pages: `page`, `pageCount`, `onPageChange` or `getHref` for links; cursor: `hasPrevious`/`hasNext`, `onPrevious`/`onNext`; `status`, `pageSize` + `pageSizeOptions`, `siblings`, `boundaries`, `labels`; folds into "Page 3 of 12" in a narrow container), `pageRange` | server |
|
|
@@ -208,6 +208,21 @@ light or a product's — is a set of tokens.
|
|
|
208
208
|
| `@krizaka/ui/split-view` | `SplitView` (`listTitle`, `listActions`, `list`, `detailHead`, `detail`, `empty`, `showDetail`, `back`) | server |
|
|
209
209
|
| `@krizaka/ui/marketing-layout` | `MarketingLayout` (`header`, `footer`, `skipLabel`) | server |
|
|
210
210
|
| `@krizaka/ui/docs-layout` | `DocsLayout` (`sidebar`, `sidebarLabel`, `toc`) | server |
|
|
211
|
+
| `@krizaka/ui/landing-page` | `LandingPage` — a page template, see [Page templates](#page-templates) | server |
|
|
212
|
+
| `@krizaka/ui/product-page` | `ProductPage` — a page template, see [Page templates](#page-templates) | server |
|
|
213
|
+
| `@krizaka/ui/how-it-works-page` | `HowItWorksPage` — a page template, see [Page templates](#page-templates) | server |
|
|
214
|
+
| `@krizaka/ui/gallery-page` | `GalleryPage` — a page template, see [Page templates](#page-templates) | server |
|
|
215
|
+
| `@krizaka/ui/docs-hub-page` | `DocsHubPage` — a page template, see [Page templates](#page-templates) | server |
|
|
216
|
+
| `@krizaka/ui/docs-article-page` | `DocsArticlePage` — a page template, see [Page templates](#page-templates) | server |
|
|
217
|
+
| `@krizaka/ui/component-page` | `ComponentPage` — a page template, see [Page templates](#page-templates) | server |
|
|
218
|
+
| `@krizaka/ui/catalogue-page` | `CataloguePage` — a page template, see [Page templates](#page-templates) | server |
|
|
219
|
+
| `@krizaka/ui/longform-page` | `LongformPage` — a page template, see [Page templates](#page-templates) | server |
|
|
220
|
+
| `@krizaka/ui/changelog-page` | `ChangelogPage` — a page template, see [Page templates](#page-templates) | server |
|
|
221
|
+
| `@krizaka/ui/contact-page` | `ContactPage` — a page template, see [Page templates](#page-templates) | server |
|
|
222
|
+
| `@krizaka/ui/legal-page` | `LegalPage` — a page template, see [Page templates](#page-templates) | server |
|
|
223
|
+
| `@krizaka/ui/status-page` | `StatusPage` — a page template, see [Page templates](#page-templates) | server |
|
|
224
|
+
| `@krizaka/ui/error-page` | `ErrorPage` — a page template, see [Page templates](#page-templates) | server |
|
|
225
|
+
| `@krizaka/ui/pricing-page` | `PricingPage` — a page template, see [Page templates](#page-templates) | server |
|
|
211
226
|
| `@krizaka/ui/native/video-player` | React Native `VideoPlayer` on expo-video (optional peer) | native |
|
|
212
227
|
| `@krizaka/ui/native/media-capture` | React Native `MediaCapture` on expo-camera (optional peer) | native |
|
|
213
228
|
| `@krizaka/ui` | the marks, `MotionObserver`, `RotatingWord`, `cx` (unchanged) | client |
|
|
@@ -260,7 +275,27 @@ import { LinkCard } from "@krizaka/ui/link-card";
|
|
|
260
275
|
- **Motion.** `reveal` uses `[data-reveal]` (MotionObserver): never on the first screen. The pointer's light, the lifts
|
|
261
276
|
and the hops stop under `prefers-reduced-motion`; nothing loops.
|
|
262
277
|
|
|
263
|
-
##
|
|
278
|
+
## Page templates
|
|
279
|
+
|
|
280
|
+
> Category **templates** of krizaka.com/docs/ui: every page of a Krizaka site has its template.
|
|
281
|
+
|
|
282
|
+
Fifteen templates, each a **distinct composition** of the blocks — not the same card grid everywhere: `LandingPage`
|
|
283
|
+
(split hero with the product alive, a band of proofs, a bento), `ProductPage` (split hero in the product's brand,
|
|
284
|
+
compact argument cards, decisions, the bird's promise), `HowItWorksPage` (a numbered timeline, the visuals
|
|
285
|
+
alternating), `GalleryPage` (filters, staggered columns of media), `DocsHubPage` (search first, the collections in
|
|
286
|
+
their brand with quick links, quick starts, most read, what is new), `DocsArticlePage` (pages · article · contents,
|
|
287
|
+
pager), `ComponentPage` (preview, install, sections, related), `CataloguePage` (sticky filters beside the results),
|
|
288
|
+
`LongformPage` (chapters with outlined numbers, pull quotes in the margin), `ChangelogPage` (a sticky date beside each
|
|
289
|
+
entry, changes by kind), `ContactPage` (channels beside the form, what happens next), `LegalPage` (summary, sections,
|
|
290
|
+
contents), `StatusPage` (the state in words, each service — or « under construction »), `ErrorPage` (the code drawn,
|
|
291
|
+
the bird, a search, the ways back) and `PricingPage` (plans, comparison, credits, questions).
|
|
292
|
+
|
|
293
|
+
Words and content are props or slots; `brand` puts a page under `.brand-<id>`; calls to action use the cut button;
|
|
294
|
+
what rises does so with `[data-reveal]` (still under reduced motion); every one reads in one column on a phone, and
|
|
295
|
+
each example has a phone story. The templates import the blocks through the package's own entries, so a block's client
|
|
296
|
+
boundary stays where it is: a template is a Server Component.
|
|
297
|
+
|
|
298
|
+
## Layouts and screens
|
|
264
299
|
|
|
265
300
|
> Category **layouts** of krizaka.com/docs/ui, and **templates**: whole screens composed from the platform.
|
|
266
301
|
|
|
@@ -367,7 +402,7 @@ const { theme, scheme, mode, setMode, radius } = useTheme(); // theme.surface1,
|
|
|
367
402
|
| `Segmented` | `options` (`value`, `label`, `disabled`), `value`, `onValueChange`, `size` | The web `Tabs variant="segmented"` (a tab list). To filter, `Chip.Group`. |
|
|
368
403
|
| `Progress` | `variant` bar·ring, `size`, `value`/`max`, `label`, `valueText`, a ring's centre as children | The fill is the `accent` → `accent2` gradient (react-native-svg); it animates to each new value. |
|
|
369
404
|
| `Toaster`, `toast` | `toast(title, { description, tone, icon, action, onPress, id, duration, onDismiss })`, `toast.success/warning/error/info`, `toast.dismiss(id?)`; `Toaster closeLabel position offset duration max` | No sonner: a light queue of its own. `offset` takes the safe-area inset (no safe-area dependency). |
|
|
370
|
-
| `KrizakaMark`, `OrazakaMark`, `OrochiaMark`, `YazakiaMark`, `ProductMark` (`id`) | `size`, `animated`, `title`, `neutral` (default `theme.textMuted`) | The brand marks, drawn with react-native-svg from the web marks' geometry. |
|
|
405
|
+
| `KrizakaMark`, `OrazakaMark`, `OrochiaMark`, `YazakiaMark`, `YororisMark`, `ProductMark` (`id`) | `size`, `animated`, `title`, `neutral` (default `theme.textMuted`) | The brand marks, drawn with react-native-svg from the web marks' geometry. |
|
|
371
406
|
|
|
372
407
|
Every animation (skeleton, badge dot, urgent countdown, progress, toast entrance, the marks) stops when the system
|
|
373
408
|
asks to reduce motion (`useReducedMotion()`). Accessibility goes through `role` and `aria-*` (RN ≥ 0.71): headings,
|
|
@@ -397,12 +432,13 @@ Testing Library (`src/native/*.test.tsx`); `scripts/native-dist.mjs` checks that
|
|
|
397
432
|
## The marks
|
|
398
433
|
|
|
399
434
|
```tsx
|
|
400
|
-
import { KrizakaLogo, OrazakaLogo, OrochiaLogo, ProductLogo, YazakiaLogo } from "@krizaka/ui";
|
|
435
|
+
import { KrizakaLogo, OrazakaLogo, OrochiaLogo, ProductLogo, YazakiaLogo, YororisLogo } from "@krizaka/ui";
|
|
401
436
|
|
|
402
437
|
<OrochiaLogo size={36} /> // decorative (aria-hidden)
|
|
403
438
|
<KrizakaLogo size={48} title="Krizaka" /> // an image with an accessible name
|
|
404
439
|
<ProductLogo id="orazaka" animated={false} /> // by id, still
|
|
405
440
|
<YazakiaLogo size={32} /> // Yazakia: emerald → turquoise, two voices that meet
|
|
441
|
+
<YororisLogo size={32} /> // Yororis: sand → sage, the hold
|
|
406
442
|
```
|
|
407
443
|
|
|
408
444
|
Neutral strokes follow the host's `--kz-*` tokens when they exist (`--kz-border-strong`, `--kz-text-muted`…) and the
|
package/dist/blocks.css
CHANGED
|
@@ -527,3 +527,250 @@ a.kz-fact:focus-visible { outline: 2px solid var(--kz-ring, var(--kz-accent)); o
|
|
|
527
527
|
.kz-block-card:hover, .kz-block-card:hover .kz-block-icon, .kz-link-card:hover .kz-link-card-cta svg, .kz-arg-more:hover svg { transform: none !important; }
|
|
528
528
|
.kz-quote-bird { animation: none !important; }
|
|
529
529
|
}
|
|
530
|
+
|
|
531
|
+
/* ═══ Page templates (@krizaka/ui/*-page): each one a distinct composition of the blocks ═══ */
|
|
532
|
+
|
|
533
|
+
/* A split hero: the words on one side, the product live on the other (a demo, a recording, a schema). */
|
|
534
|
+
.kz-tpl-split { display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr); gap: clamp(24px, 4vw, 56px); align-items: center; }
|
|
535
|
+
.kz-tpl-split[data-reverse] > :first-child { order: 2; }
|
|
536
|
+
@media (max-width: 900px) { .kz-tpl-split { grid-template-columns: minmax(0, 1fr); } .kz-tpl-split[data-reverse] > :first-child { order: 0; } }
|
|
537
|
+
.kz-tpl-stage {
|
|
538
|
+
position: relative; min-width: 0; overflow: hidden; border-radius: 20px; border: 1px solid var(--kz-border-default); background: var(--kz-surface-1);
|
|
539
|
+
box-shadow: 0 40px 80px -48px color-mix(in srgb, var(--kz-hue, var(--kz-accent)) 70%, transparent);
|
|
540
|
+
}
|
|
541
|
+
.kz-tpl-stage-bar { display: flex; align-items: center; gap: 6px; padding: 9px 12px; border-bottom: 1px solid var(--kz-border-subtle); background: var(--kz-surface-2);
|
|
542
|
+
font-family: var(--kz-font-mono); font-size: 11px; color: var(--kz-text-secondary); }
|
|
543
|
+
.kz-tpl-stage-bar i { width: 9px; height: 9px; border-radius: 50%; background: var(--kz-border-strong); }
|
|
544
|
+
.kz-tpl-stage-bar span { margin-left: 8px; }
|
|
545
|
+
.kz-tpl-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 4px; }
|
|
546
|
+
|
|
547
|
+
/* A band of proofs: figures or facts across the frame, divided by hairlines. */
|
|
548
|
+
.kz-tpl-band { margin: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 180px), 1fr)); border-block: 1px solid var(--kz-border-subtle); }
|
|
549
|
+
.kz-tpl-band > div { padding: 20px 18px; border-left: 1px solid var(--kz-border-subtle); }
|
|
550
|
+
.kz-tpl-band > div:first-child { border-left: 0; }
|
|
551
|
+
.kz-tpl-band dt { font-family: var(--kz-font-display); font-size: clamp(1.6rem, 3vw, 2.2rem); font-weight: 800; letter-spacing: -0.03em; color: var(--kz-text-primary); }
|
|
552
|
+
.kz-tpl-band dd { margin: 4px 0 0; font-size: 13px; color: var(--kz-text-secondary); }
|
|
553
|
+
@media (max-width: 560px) { .kz-tpl-band > div { border-left: 0; border-top: 1px solid var(--kz-border-subtle); } .kz-tpl-band > div:first-child { border-top: 0; } }
|
|
554
|
+
|
|
555
|
+
/* A bento: features of different weights on a six-column grid (one column on a phone). */
|
|
556
|
+
.kz-tpl-bento { margin: 0; padding: 0; list-style: none; display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 14px; }
|
|
557
|
+
.kz-tpl-bento > li { grid-column: span 2; display: flex; flex-direction: column; gap: 10px; min-width: 0; padding: 22px; border-radius: 18px;
|
|
558
|
+
background: var(--kz-surface-1); border: 1px solid var(--kz-border-default); }
|
|
559
|
+
.kz-tpl-bento > li[data-size="lg"] { grid-column: span 4; grid-row: span 2; background: color-mix(in srgb, var(--kz-hue, var(--kz-accent)) 7%, var(--kz-surface-1)); }
|
|
560
|
+
.kz-tpl-bento > li[data-size="md"] { grid-column: span 3; }
|
|
561
|
+
.kz-tpl-bento h3 { margin: 0; font-family: var(--kz-font-display); font-size: 17px; font-weight: 800; letter-spacing: -0.012em; color: var(--kz-text-primary); }
|
|
562
|
+
.kz-tpl-bento > li[data-size="lg"] h3 { font-size: clamp(1.3rem, 2.4vw, 1.75rem); }
|
|
563
|
+
.kz-tpl-bento p { margin: 0; font-size: 14px; line-height: 1.6; color: var(--kz-text-secondary); }
|
|
564
|
+
.kz-tpl-bento-visual { margin-top: auto; min-width: 0; }
|
|
565
|
+
@media (max-width: 900px) { .kz-tpl-bento > li, .kz-tpl-bento > li[data-size] { grid-column: span 6; grid-row: auto; } }
|
|
566
|
+
|
|
567
|
+
/* A timeline: numbered steps along a line, the visual alternating sides on a wide screen. */
|
|
568
|
+
.kz-tpl-timeline { margin: 0; padding: 0; list-style: none; position: relative; display: grid; gap: clamp(28px, 5vw, 56px); }
|
|
569
|
+
.kz-tpl-timeline::before { content: ""; position: absolute; left: 21px; top: 8px; bottom: 8px; width: 2px;
|
|
570
|
+
background: linear-gradient(var(--kz-hue, var(--kz-accent)), color-mix(in srgb, var(--kz-hue, var(--kz-accent)) 10%, transparent)); }
|
|
571
|
+
.kz-tpl-step { position: relative; display: grid; grid-template-columns: 44px minmax(0, 1fr) minmax(0, 1fr); gap: 20px 28px; align-items: start; }
|
|
572
|
+
.kz-tpl-step-n { grid-column: 1; grid-row: 1; position: relative; z-index: 1; display: inline-flex; align-items: center; justify-content: center; width: 44px; height: 44px; border-radius: 14px;
|
|
573
|
+
font-family: var(--kz-font-display); font-size: 16px; font-weight: 800; color: var(--kz-text-primary); background: var(--kz-surface-1);
|
|
574
|
+
border: 2px solid var(--kz-hue, var(--kz-accent)); box-shadow: 0 0 0 6px var(--kz-surface-0); }
|
|
575
|
+
.kz-tpl-step :is(h2, h3) { margin: 6px 0 8px; font-family: var(--kz-font-display); font-size: clamp(1.15rem, 2.2vw, 1.4rem); font-weight: 800; color: var(--kz-text-primary); }
|
|
576
|
+
.kz-tpl-step p { margin: 0; font-size: 15px; line-height: 1.7; color: var(--kz-text-secondary); }
|
|
577
|
+
.kz-tpl-step-visual { min-width: 0; }
|
|
578
|
+
.kz-tpl-step:nth-child(even) .kz-tpl-step-visual { order: -1; grid-column: 2; }
|
|
579
|
+
.kz-tpl-step:nth-child(even) .kz-tpl-step-text { grid-column: 3; grid-row: 1; }
|
|
580
|
+
@media (max-width: 900px) {
|
|
581
|
+
.kz-tpl-step, .kz-tpl-step:nth-child(even) { grid-template-columns: 44px minmax(0, 1fr); }
|
|
582
|
+
.kz-tpl-step .kz-tpl-step-visual, .kz-tpl-step:nth-child(even) .kz-tpl-step-visual { order: 0; grid-column: 2; }
|
|
583
|
+
.kz-tpl-step:nth-child(even) .kz-tpl-step-text { grid-column: 2; grid-row: auto; }
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
/* A gallery: media in columns of different heights, the featured one wide. */
|
|
587
|
+
.kz-tpl-gallery { margin: 0; padding: 0; list-style: none; columns: 3 280px; column-gap: 14px; }
|
|
588
|
+
.kz-tpl-gallery > li { break-inside: avoid; margin-bottom: 14px; }
|
|
589
|
+
.kz-tpl-figure { margin: 0; overflow: hidden; border-radius: 16px; border: 1px solid var(--kz-border-default); background: var(--kz-surface-1); }
|
|
590
|
+
.kz-tpl-figure-media { overflow: hidden; background: var(--kz-media); }
|
|
591
|
+
.kz-tpl-figure-media > :is(img, video) { display: block; width: 100%; height: auto; }
|
|
592
|
+
.kz-tpl-figure figcaption { display: grid; gap: 4px; padding: 12px 14px; }
|
|
593
|
+
.kz-tpl-figure strong { font-size: 14px; color: var(--kz-text-primary); }
|
|
594
|
+
.kz-tpl-figure span { font-size: 13px; line-height: 1.5; color: var(--kz-text-secondary); }
|
|
595
|
+
.kz-tpl-filters { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 20px; }
|
|
596
|
+
|
|
597
|
+
/* The documentation hub: the search in the middle, the collections as brand panels with their quick links. */
|
|
598
|
+
.kz-tpl-hub-search { display: grid; justify-items: center; gap: 12px; margin: 24px auto 0; width: min(100%, 40rem); }
|
|
599
|
+
.kz-tpl-hub-search > * { width: 100%; }
|
|
600
|
+
.kz-tpl-hub-hints { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; font-size: 13px; color: var(--kz-text-secondary); }
|
|
601
|
+
.kz-tpl-collections { margin: 0; padding: 0; list-style: none; display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr)); gap: 14px; }
|
|
602
|
+
.kz-tpl-collection { position: relative; isolation: isolate; overflow: hidden; display: flex; flex-direction: column; gap: 12px; height: 100%; padding: 20px; border-radius: 18px;
|
|
603
|
+
background: linear-gradient(160deg, color-mix(in srgb, var(--kz-accent) 14%, var(--kz-surface-1)), var(--kz-surface-1) 55%);
|
|
604
|
+
border: 1px solid color-mix(in srgb, var(--kz-accent) 28%, var(--kz-border-default)); }
|
|
605
|
+
.kz-tpl-collection-head { display: flex; align-items: center; gap: 10px; }
|
|
606
|
+
.kz-tpl-collection-head a { font-family: var(--kz-font-display); font-size: 18px; font-weight: 800; color: var(--kz-text-primary); text-decoration: none; }
|
|
607
|
+
.kz-tpl-collection-head a::after { content: ""; position: absolute; inset: 0; z-index: -1; }
|
|
608
|
+
.kz-tpl-collection-head a:focus-visible { outline: none; }
|
|
609
|
+
.kz-tpl-collection:has(.kz-tpl-collection-head a:focus-visible) { outline: 2px solid var(--kz-ring, var(--kz-accent)); outline-offset: 2px; }
|
|
610
|
+
.kz-tpl-collection p { margin: 0; font-size: 14px; line-height: 1.55; color: var(--kz-text-secondary); }
|
|
611
|
+
.kz-tpl-collection ul { position: relative; z-index: 1; margin: auto 0 0; padding: 10px 0 0; list-style: none; display: flex; flex-wrap: wrap; gap: 6px;
|
|
612
|
+
border-top: 1px solid var(--kz-border-subtle); }
|
|
613
|
+
.kz-tpl-collection ul a { display: inline-flex; min-height: 28px; align-items: center; padding: 0 10px; border-radius: 999px; font-size: 12.5px; font-weight: 600;
|
|
614
|
+
text-decoration: none; color: var(--kz-text-primary); background: var(--kz-surface-2); border: 1px solid var(--kz-border-subtle); }
|
|
615
|
+
.kz-tpl-collection ul a:hover { border-color: var(--kz-accent); }
|
|
616
|
+
.kz-tpl-collection ul a:focus-visible { outline: 2px solid var(--kz-ring, var(--kz-accent)); outline-offset: 2px; }
|
|
617
|
+
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
|
|
618
|
+
.kz-tpl-collection { transition: transform 0.3s var(--kz-ease, ease), box-shadow 0.3s var(--kz-ease, ease); }
|
|
619
|
+
.kz-tpl-collection:hover { transform: translateY(-3px); box-shadow: 0 24px 48px -30px var(--kz-accent); }
|
|
620
|
+
}
|
|
621
|
+
.kz-tpl-two { display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr); gap: 28px; }
|
|
622
|
+
@media (max-width: 900px) { .kz-tpl-two { grid-template-columns: minmax(0, 1fr); } }
|
|
623
|
+
.kz-tpl-links { margin: 0; padding: 0; list-style: none; display: grid; }
|
|
624
|
+
.kz-tpl-links li { border-top: 1px solid var(--kz-border-subtle); }
|
|
625
|
+
.kz-tpl-links li:first-child { border-top: 0; }
|
|
626
|
+
.kz-tpl-links a { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; padding: 12px 2px; text-decoration: none; color: var(--kz-text-primary); }
|
|
627
|
+
.kz-tpl-links a:hover { color: var(--kz-accent-text); }
|
|
628
|
+
.kz-tpl-links a:focus-visible { outline: 2px solid var(--kz-ring, var(--kz-accent)); outline-offset: 2px; border-radius: 6px; }
|
|
629
|
+
.kz-tpl-links strong { font-size: 14.5px; font-weight: 650; }
|
|
630
|
+
.kz-tpl-links small { flex-shrink: 0; font-family: var(--kz-font-mono); font-size: 11.5px; color: var(--kz-text-secondary); }
|
|
631
|
+
|
|
632
|
+
/* An article: breadcrumb, title, meta, then the reading column; previous / next at the foot. */
|
|
633
|
+
.kz-tpl-crumbs { margin: 0 0 12px; padding: 0; list-style: none; display: flex; flex-wrap: wrap; gap: 6px; font-size: 13px; color: var(--kz-text-secondary); }
|
|
634
|
+
.kz-tpl-crumbs li + li::before { content: "/"; margin-right: 6px; color: var(--kz-border-strong); }
|
|
635
|
+
.kz-tpl-crumbs a { color: inherit; text-decoration: none; }
|
|
636
|
+
.kz-tpl-crumbs a:hover { color: var(--kz-text-primary); }
|
|
637
|
+
.kz-tpl-article-title { margin: 0; font-family: var(--kz-font-display); font-size: clamp(1.9rem, 4vw, 2.6rem); font-weight: 800; letter-spacing: -0.03em; line-height: 1.1; color: var(--kz-text-primary); }
|
|
638
|
+
.kz-tpl-article-lead { margin: 12px 0 0; max-width: 46rem; font-size: 17px; line-height: 1.65; color: var(--kz-text-secondary); }
|
|
639
|
+
.kz-tpl-article-meta { margin-top: 14px; }
|
|
640
|
+
.kz-tpl-prose { max-width: 46rem; font-size: 16px; line-height: 1.75; color: var(--kz-text-secondary); }
|
|
641
|
+
.kz-tpl-prose :is(h2, h3) { color: var(--kz-text-primary); font-family: var(--kz-font-display); scroll-margin-top: var(--kz-anchor-offset, 96px); }
|
|
642
|
+
.kz-tpl-pager { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; margin-top: 40px; }
|
|
643
|
+
.kz-tpl-pager a { display: grid; gap: 4px; padding: 14px 16px; border-radius: 14px; border: 1px solid var(--kz-border-default); background: var(--kz-surface-1);
|
|
644
|
+
text-decoration: none; color: var(--kz-text-primary); }
|
|
645
|
+
.kz-tpl-pager a:hover { border-color: var(--kz-accent); }
|
|
646
|
+
.kz-tpl-pager a:focus-visible { outline: 2px solid var(--kz-ring, var(--kz-accent)); outline-offset: 2px; }
|
|
647
|
+
.kz-tpl-pager a[rel="next"] { grid-column: 2; text-align: right; }
|
|
648
|
+
.kz-tpl-pager small { font-family: var(--kz-font-mono); font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--kz-text-secondary); }
|
|
649
|
+
|
|
650
|
+
/* A catalogue: the filters in a sticky column (folded above the results on a phone). */
|
|
651
|
+
.kz-tpl-catalogue { display: grid; grid-template-columns: 15rem minmax(0, 1fr); gap: 32px; align-items: start; }
|
|
652
|
+
.kz-tpl-catalogue-filters { position: sticky; top: var(--kz-anchor-offset, 96px); }
|
|
653
|
+
.kz-tpl-catalogue-filters > summary { display: none; }
|
|
654
|
+
.kz-tpl-catalogue-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 16px; }
|
|
655
|
+
.kz-tpl-count { margin: 0; font-family: var(--kz-font-mono); font-size: 12px; color: var(--kz-text-secondary); }
|
|
656
|
+
@media (max-width: 900px) {
|
|
657
|
+
.kz-tpl-catalogue { grid-template-columns: minmax(0, 1fr); gap: 16px; }
|
|
658
|
+
.kz-tpl-catalogue-filters { position: static; border-radius: 14px; border: 1px solid var(--kz-border-default); background: var(--kz-surface-1); }
|
|
659
|
+
.kz-tpl-catalogue-filters > summary { display: flex; align-items: center; justify-content: space-between; min-height: 44px; padding: 0 14px; cursor: pointer; list-style: none;
|
|
660
|
+
font-size: 14px; font-weight: 650; color: var(--kz-text-primary); }
|
|
661
|
+
.kz-tpl-catalogue-filters > summary::-webkit-details-marker { display: none; }
|
|
662
|
+
.kz-tpl-catalogue-filters > div { padding: 0 14px 14px; }
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
/* A long read: chapters with their big numbers, pull quotes in the margin, figures that break out. */
|
|
666
|
+
.kz-tpl-chapters { display: grid; gap: clamp(40px, 7vw, 88px); }
|
|
667
|
+
.kz-tpl-chapter { display: grid; grid-template-columns: minmax(0, 9rem) minmax(0, 42rem) minmax(0, 1fr); gap: 24px 32px; }
|
|
668
|
+
.kz-tpl-chapter-n { font-family: var(--kz-font-display); font-size: clamp(2.4rem, 6vw, 4.2rem); font-weight: 800; line-height: 0.9; letter-spacing: -0.04em;
|
|
669
|
+
color: transparent; -webkit-text-stroke: 1.5px var(--kz-hue, var(--kz-accent)); }
|
|
670
|
+
.kz-tpl-chapter h2 { margin: 0 0 14px; font-family: var(--kz-font-display); font-size: clamp(1.5rem, 3vw, 2.1rem); font-weight: 800; letter-spacing: -0.025em; line-height: 1.15;
|
|
671
|
+
color: var(--kz-text-primary); scroll-margin-top: var(--kz-anchor-offset, 96px); }
|
|
672
|
+
.kz-tpl-chapter-body { font-size: 17px; line-height: 1.8; color: var(--kz-text-secondary); }
|
|
673
|
+
.kz-tpl-chapter-body p { margin: 0 0 1em; }
|
|
674
|
+
.kz-tpl-chapter-aside { align-self: start; padding-top: 8px; }
|
|
675
|
+
.kz-tpl-pull { margin: 0; padding-left: 16px; border-left: 3px solid var(--kz-hue, var(--kz-accent)); font-family: var(--kz-font-display); font-size: 19px; font-weight: 700;
|
|
676
|
+
line-height: 1.4; color: var(--kz-text-primary); }
|
|
677
|
+
.kz-tpl-chapter-figure { grid-column: 2 / -1; margin: 8px 0 0; }
|
|
678
|
+
@media (max-width: 1023px) {
|
|
679
|
+
.kz-tpl-chapter { grid-template-columns: minmax(0, 1fr); gap: 12px; }
|
|
680
|
+
.kz-tpl-chapter-figure { grid-column: auto; }
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
/* A changelog: the date sticks beside its entries; each entry a version, a title, its kinds of change. */
|
|
684
|
+
.kz-tpl-log { margin: 0; padding: 0; list-style: none; display: grid; gap: 8px; }
|
|
685
|
+
.kz-tpl-log-entry { display: grid; grid-template-columns: 10rem minmax(0, 1fr); gap: 24px; padding: 24px 0; border-top: 1px solid var(--kz-border-subtle); }
|
|
686
|
+
.kz-tpl-log-entry:first-child { border-top: 0; }
|
|
687
|
+
.kz-tpl-log-when { position: sticky; top: var(--kz-anchor-offset, 96px); align-self: start; display: grid; gap: 6px; }
|
|
688
|
+
.kz-tpl-log-when time { font-family: var(--kz-font-mono); font-size: 12.5px; color: var(--kz-text-secondary); }
|
|
689
|
+
.kz-tpl-log-entry :is(h2, h3) { margin: 0 0 10px; font-family: var(--kz-font-display); font-size: 19px; font-weight: 800; color: var(--kz-text-primary); }
|
|
690
|
+
.kz-tpl-log-items { margin: 0; padding: 0; list-style: none; display: grid; gap: 8px; }
|
|
691
|
+
.kz-tpl-log-items li { display: grid; grid-template-columns: 6.5rem minmax(0, 1fr); gap: 10px; font-size: 14.5px; line-height: 1.6; color: var(--kz-text-secondary); }
|
|
692
|
+
.kz-tpl-log-kind { font-family: var(--kz-font-mono); font-size: 11px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; padding-top: 3px; }
|
|
693
|
+
.kz-tpl-log-kind[data-kind="added"] { color: var(--kz-success-text); }
|
|
694
|
+
.kz-tpl-log-kind[data-kind="changed"] { color: var(--kz-accent-text); }
|
|
695
|
+
.kz-tpl-log-kind[data-kind="fixed"] { color: var(--kz-warning-text); }
|
|
696
|
+
.kz-tpl-log-kind[data-kind="removed"] { color: var(--kz-danger-text); }
|
|
697
|
+
@media (max-width: 720px) {
|
|
698
|
+
.kz-tpl-log-entry { grid-template-columns: minmax(0, 1fr); gap: 10px; }
|
|
699
|
+
.kz-tpl-log-when { position: static; grid-auto-flow: column; justify-content: start; align-items: center; gap: 10px; }
|
|
700
|
+
.kz-tpl-log-items li { grid-template-columns: minmax(0, 1fr); gap: 2px; }
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
/* Contact: the ways to reach us beside the form; what happens next under it. */
|
|
704
|
+
.kz-tpl-contact { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.25fr); gap: clamp(24px, 4vw, 48px); align-items: start; }
|
|
705
|
+
@media (max-width: 900px) { .kz-tpl-contact { grid-template-columns: minmax(0, 1fr); } }
|
|
706
|
+
.kz-tpl-form { padding: clamp(18px, 3vw, 28px); border-radius: 20px; background: var(--kz-surface-1); border: 1px solid var(--kz-border-default); }
|
|
707
|
+
.kz-tpl-next { margin: 0; padding: 0; list-style: none; counter-reset: next; display: grid; gap: 12px; }
|
|
708
|
+
.kz-tpl-next li { counter-increment: next; display: grid; grid-template-columns: 30px minmax(0, 1fr); gap: 12px; font-size: 14px; line-height: 1.6; color: var(--kz-text-secondary); }
|
|
709
|
+
.kz-tpl-next li::before { content: counter(next); display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 30px; border-radius: 50%;
|
|
710
|
+
font-family: var(--kz-font-mono); font-size: 12px; font-weight: 700; color: var(--kz-accent-text); background: var(--kz-accent-soft); }
|
|
711
|
+
.kz-tpl-next strong { display: block; color: var(--kz-text-primary); }
|
|
712
|
+
|
|
713
|
+
/* Status: one line per service, its state in words and a dot; an incident log under it. */
|
|
714
|
+
.kz-tpl-state { display: flex; flex-wrap: wrap; align-items: center; gap: 14px 20px; padding: 18px 20px; border-radius: 18px; border: 1px solid var(--kz-border-default);
|
|
715
|
+
background: var(--kz-surface-1); }
|
|
716
|
+
.kz-tpl-state[data-state="operational"] { border-color: color-mix(in srgb, var(--kz-success) 40%, var(--kz-border-default)); background: color-mix(in srgb, var(--kz-success) 7%, var(--kz-surface-1)); }
|
|
717
|
+
.kz-tpl-state[data-state="degraded"] { border-color: color-mix(in srgb, var(--kz-warning) 40%, var(--kz-border-default)); background: color-mix(in srgb, var(--kz-warning) 7%, var(--kz-surface-1)); }
|
|
718
|
+
.kz-tpl-state[data-state="outage"] { border-color: color-mix(in srgb, var(--kz-danger) 40%, var(--kz-border-default)); background: color-mix(in srgb, var(--kz-danger) 7%, var(--kz-surface-1)); }
|
|
719
|
+
.kz-tpl-state strong { font-family: var(--kz-font-display); font-size: 19px; font-weight: 800; color: var(--kz-text-primary); }
|
|
720
|
+
.kz-tpl-dot { width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0; background: var(--kz-text-secondary); }
|
|
721
|
+
[data-state="operational"] > .kz-tpl-dot, .kz-tpl-dot[data-state="operational"] { background: var(--kz-success); box-shadow: 0 0 0 4px color-mix(in srgb, var(--kz-success) 22%, transparent); }
|
|
722
|
+
[data-state="degraded"] > .kz-tpl-dot, .kz-tpl-dot[data-state="degraded"] { background: var(--kz-warning); }
|
|
723
|
+
[data-state="outage"] > .kz-tpl-dot, .kz-tpl-dot[data-state="outage"] { background: var(--kz-danger); }
|
|
724
|
+
[data-state="building"] > .kz-tpl-dot, .kz-tpl-dot[data-state="building"] { background: var(--kz-info); }
|
|
725
|
+
.kz-tpl-services { margin: 16px 0 0; padding: 0; list-style: none; border-radius: 16px; border: 1px solid var(--kz-border-default); overflow: hidden; }
|
|
726
|
+
.kz-tpl-services li { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 14px 16px; border-top: 1px solid var(--kz-border-subtle);
|
|
727
|
+
font-size: 14.5px; color: var(--kz-text-primary); background: var(--kz-surface-1); }
|
|
728
|
+
.kz-tpl-services li:first-child { border-top: 0; }
|
|
729
|
+
.kz-tpl-services small { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; color: var(--kz-text-secondary); }
|
|
730
|
+
|
|
731
|
+
/* An error: the code, huge and drawn in outline, the bird beside it, the ways out under it. */
|
|
732
|
+
.kz-tpl-error { display: grid; justify-items: center; gap: 16px; padding-block: calc(var(--kz-hero-top, 120px) - 16px) clamp(48px, 8vw, 96px); text-align: center; }
|
|
733
|
+
.kz-tpl-error .kz-tpl-error-code { margin: 0; max-width: none; display: flex; align-items: center; gap: 8px; font-family: var(--kz-font-display); font-size: clamp(5rem, 18vw, 10rem); font-weight: 800;
|
|
734
|
+
line-height: 0.9; letter-spacing: -0.06em; color: transparent; -webkit-text-stroke: 2px var(--kz-hue, var(--kz-accent)); }
|
|
735
|
+
.kz-tpl-error h1 { margin: 0; font-family: var(--kz-font-display); font-size: clamp(1.6rem, 4vw, 2.3rem); font-weight: 800; letter-spacing: -0.025em; color: var(--kz-text-primary); }
|
|
736
|
+
.kz-tpl-error p:not(.kz-tpl-error-code) { margin: 0; max-width: 34rem; font-size: 16px; line-height: 1.65; color: var(--kz-text-secondary); }
|
|
737
|
+
.kz-tpl-error-search { width: min(100%, 28rem); }
|
|
738
|
+
|
|
739
|
+
/* Pricing: plans side by side, the featured one lifted; a comparison under them. */
|
|
740
|
+
.kz-tpl-plans { margin: 0; padding: 0; list-style: none; display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 250px), 1fr)); gap: 14px; align-items: stretch; }
|
|
741
|
+
.kz-tpl-plan { position: relative; display: flex; flex-direction: column; gap: 14px; height: 100%; padding: 24px; border-radius: 20px; background: var(--kz-surface-1);
|
|
742
|
+
border: 1px solid var(--kz-border-default); }
|
|
743
|
+
.kz-tpl-plan[data-featured] { border-color: var(--kz-accent); background: linear-gradient(170deg, color-mix(in srgb, var(--kz-accent) 12%, var(--kz-surface-1)), var(--kz-surface-1) 60%);
|
|
744
|
+
box-shadow: 0 30px 60px -36px var(--kz-accent); }
|
|
745
|
+
.kz-tpl-plan :is(h2, h3) { margin: 0; font-family: var(--kz-font-display); font-size: 18px; font-weight: 800; color: var(--kz-text-primary); }
|
|
746
|
+
.kz-tpl-price { margin: 0; font-family: var(--kz-font-display); font-size: 2.6rem; font-weight: 800; letter-spacing: -0.03em; line-height: 1; color: var(--kz-text-primary); }
|
|
747
|
+
.kz-tpl-price small { display: block; margin-top: 6px; font-family: var(--kz-font-text, inherit); font-size: 13px; font-weight: 500; letter-spacing: 0; color: var(--kz-text-secondary); }
|
|
748
|
+
.kz-tpl-plan ul { margin: 0; padding: 0; list-style: none; display: grid; gap: 8px; font-size: 14px; color: var(--kz-text-secondary); }
|
|
749
|
+
.kz-tpl-plan ul li { display: grid; grid-template-columns: 18px minmax(0, 1fr); gap: 8px; }
|
|
750
|
+
.kz-tpl-plan ul svg { margin-top: 3px; color: var(--kz-success-text); }
|
|
751
|
+
.kz-tpl-plan > :last-child { margin-top: auto; }
|
|
752
|
+
.kz-tpl-compare { width: 100%; border-collapse: collapse; font-size: 14px; }
|
|
753
|
+
.kz-tpl-compare th, .kz-tpl-compare td { padding: 12px 14px; text-align: left; border-bottom: 1px solid var(--kz-border-subtle); color: var(--kz-text-secondary); }
|
|
754
|
+
.kz-tpl-compare thead th { font-family: var(--kz-font-mono); font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase; }
|
|
755
|
+
.kz-tpl-compare tbody th { color: var(--kz-text-primary); font-weight: 600; }
|
|
756
|
+
.kz-tpl-scroll { overflow-x: auto; border-radius: 16px; border: 1px solid var(--kz-border-default); background: var(--kz-surface-1); }
|
|
757
|
+
.kz-tpl-faq { display: grid; gap: 8px; }
|
|
758
|
+
.kz-tpl-faq details { border-radius: 14px; border: 1px solid var(--kz-border-default); background: var(--kz-surface-1); }
|
|
759
|
+
.kz-tpl-faq summary { display: flex; align-items: center; min-height: 48px; padding: 0 16px; cursor: pointer; list-style: none; font-size: 15px; font-weight: 650; color: var(--kz-text-primary); }
|
|
760
|
+
.kz-tpl-faq summary::-webkit-details-marker { display: none; }
|
|
761
|
+
.kz-tpl-faq summary:focus-visible { outline: 2px solid var(--kz-ring, var(--kz-accent)); outline-offset: 2px; border-radius: 14px; }
|
|
762
|
+
.kz-tpl-faq details > div { padding: 0 16px 16px; font-size: 14.5px; line-height: 1.65; color: var(--kz-text-secondary); }
|
|
763
|
+
|
|
764
|
+
@media (prefers-reduced-motion: reduce) { .kz-tpl-collection { transition: none !important; transform: none !important; } }
|
|
765
|
+
.kz-tpl-promise { margin-top: 32px; }
|
|
766
|
+
.kz-hero[data-align="center"] .kz-hero-extra { justify-content: center; }
|
|
767
|
+
.kz-tpl-stack { display: grid; gap: 14px; min-width: 0; align-content: start; }
|
|
768
|
+
.kz-tpl-h2 { font-size: clamp(1.15rem, 2.2vw, 1.4rem); max-width: none; }
|
|
769
|
+
.kz-tpl-flush .kz-frame { --kz-gutter: 0px; }
|
|
770
|
+
.kz-tpl-catalogue-frame { padding-block: 24px clamp(48px, 7vw, 88px); }
|
|
771
|
+
.kz-tpl-longform { padding-block: clamp(32px, 5vw, 64px) clamp(56px, 8vw, 96px); }
|
|
772
|
+
.kz-tpl-summary { display: block; font-size: 15px; line-height: 1.65; color: var(--kz-text-primary); }
|
|
773
|
+
.kz-tpl-caption { padding: 12px 14px 4px; text-align: left; caption-side: top; }
|
|
774
|
+
.kz-tpl-plan .kz-tpl-collection-head { justify-content: space-between; }
|
|
775
|
+
.kz-tpl-scroll:focus-visible { outline: 2px solid var(--kz-ring, var(--kz-accent)); outline-offset: 2px; }
|
|
776
|
+
.kz-tpl-prose > p, .kz-tpl-prose > ul, .kz-tpl-prose > ol { margin: 0 0 1em; }
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { LinkComponent } from '@krizaka/ui/page-hero';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
|
|
4
|
+
type CataloguePageProps = Omit<React.HTMLAttributes<HTMLElement>, "title"> & {
|
|
5
|
+
/** The way back. */
|
|
6
|
+
back?: {
|
|
7
|
+
href: string;
|
|
8
|
+
label: string;
|
|
9
|
+
};
|
|
10
|
+
/** A mono line above the title. */
|
|
11
|
+
eyebrow?: React.ReactNode;
|
|
12
|
+
/** The page's `h1`. */
|
|
13
|
+
title: React.ReactNode;
|
|
14
|
+
/** One sentence under it. */
|
|
15
|
+
lead?: React.ReactNode;
|
|
16
|
+
/** In the hero: a search field. */
|
|
17
|
+
search?: React.ReactNode;
|
|
18
|
+
/** The filters (groups of ChipLinks, a FilterBar): sticky on a desktop. */
|
|
19
|
+
filters: React.ReactNode;
|
|
20
|
+
/** On a phone, the words that open the filters (`Filters`). */
|
|
21
|
+
filtersLabel: string;
|
|
22
|
+
/** What matches, in words (`24 components`). */
|
|
23
|
+
count?: React.ReactNode;
|
|
24
|
+
/** On the right of the count: the sort, a view switch. */
|
|
25
|
+
toolbar?: React.ReactNode;
|
|
26
|
+
/** The results: a CardGrid, a list, an empty state. */
|
|
27
|
+
children: React.ReactNode;
|
|
28
|
+
/** The app's link component (Next's `Link`). */
|
|
29
|
+
linkAs?: LinkComponent;
|
|
30
|
+
};
|
|
31
|
+
/** A catalogue: hero, sticky filters beside the results (folded on a phone), the count, the results. */
|
|
32
|
+
declare function CataloguePage({ back, eyebrow, title, lead, search, filters, filtersLabel, count, toolbar, linkAs, children, ...props }: CataloguePageProps): React.JSX.Element;
|
|
33
|
+
|
|
34
|
+
export { CataloguePage, type CataloguePageProps };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// src/catalogue-page/catalogue-page.tsx
|
|
2
|
+
import { Page } from "@krizaka/ui/page";
|
|
3
|
+
import { PageHero } from "@krizaka/ui/page-hero";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
function CataloguePage({ back, eyebrow, title, lead, search, filters, filtersLabel, count, toolbar, linkAs, children, ...props }) {
|
|
6
|
+
return /* @__PURE__ */ jsxs("div", { ...props, children: [
|
|
7
|
+
/* @__PURE__ */ jsx(PageHero, { back, linkAs, eyebrow, title, lead, backdrop: "plain", children: search }),
|
|
8
|
+
/* @__PURE__ */ jsx(Page, { className: "kz-tpl-catalogue-frame", children: /* @__PURE__ */ jsxs("div", { className: "kz-tpl-catalogue", children: [
|
|
9
|
+
/* @__PURE__ */ jsxs("details", { className: "kz-tpl-catalogue-filters", open: true, children: [
|
|
10
|
+
/* @__PURE__ */ jsx("summary", { children: filtersLabel }),
|
|
11
|
+
/* @__PURE__ */ jsx("div", { children: filters })
|
|
12
|
+
] }),
|
|
13
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
14
|
+
(count || toolbar) && /* @__PURE__ */ jsxs("div", { className: "kz-tpl-catalogue-head", children: [
|
|
15
|
+
count && /* @__PURE__ */ jsx("p", { className: "kz-tpl-count", "aria-live": "polite", children: count }),
|
|
16
|
+
toolbar
|
|
17
|
+
] }),
|
|
18
|
+
children
|
|
19
|
+
] })
|
|
20
|
+
] }) })
|
|
21
|
+
] });
|
|
22
|
+
}
|
|
23
|
+
export {
|
|
24
|
+
CataloguePage
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=catalogue-page.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/catalogue-page/catalogue-page.tsx"],"sourcesContent":["// Server-safe. A catalogue or an index (blocks.css `.kz-tpl-catalogue`): the hero, then the filters in a sticky column\n// beside the results — folded into a disclosure above them on a phone — the count of what matches and the sort, and\n// the results (a CardGrid of LinkCards, a list). The filters live in the address: a link per choice, no client state.\nimport { Page } from \"@krizaka/ui/page\";\nimport type { LinkComponent } from \"@krizaka/ui/page-hero\";\nimport { PageHero } from \"@krizaka/ui/page-hero\";\nimport type * as React from \"react\";\n\nexport type CataloguePageProps = Omit<React.HTMLAttributes<HTMLElement>, \"title\"> & {\n /** The way back. */\n back?: { href: string; label: string };\n /** A mono line above the title. */\n eyebrow?: React.ReactNode;\n /** The page's `h1`. */\n title: React.ReactNode;\n /** One sentence under it. */\n lead?: React.ReactNode;\n /** In the hero: a search field. */\n search?: React.ReactNode;\n /** The filters (groups of ChipLinks, a FilterBar): sticky on a desktop. */\n filters: React.ReactNode;\n /** On a phone, the words that open the filters (`Filters`). */\n filtersLabel: string;\n /** What matches, in words (`24 components`). */\n count?: React.ReactNode;\n /** On the right of the count: the sort, a view switch. */\n toolbar?: React.ReactNode;\n /** The results: a CardGrid, a list, an empty state. */\n children: React.ReactNode;\n /** The app's link component (Next's `Link`). */\n linkAs?: LinkComponent;\n};\n\n/** A catalogue: hero, sticky filters beside the results (folded on a phone), the count, the results. */\nexport function CataloguePage({ back, eyebrow, title, lead, search, filters, filtersLabel, count, toolbar, linkAs, children, ...props }: CataloguePageProps) {\n return (\n <div {...props}>\n <PageHero back={back} linkAs={linkAs} eyebrow={eyebrow} title={title} lead={lead} backdrop=\"plain\">\n {search}\n </PageHero>\n <Page className=\"kz-tpl-catalogue-frame\">\n <div className=\"kz-tpl-catalogue\">\n <details className=\"kz-tpl-catalogue-filters\" open>\n <summary>{filtersLabel}</summary>\n <div>{filters}</div>\n </details>\n <div className=\"min-w-0\">\n {(count || toolbar) && (\n <div className=\"kz-tpl-catalogue-head\">\n {count && (\n <p className=\"kz-tpl-count\" aria-live=\"polite\">\n {count}\n </p>\n )}\n {toolbar}\n </div>\n )}\n {children}\n </div>\n </div>\n </Page>\n </div>\n );\n}\n"],"mappings":";AAGA,SAAS,YAAY;AAErB,SAAS,gBAAgB;AAgCnB,cAKI,YALJ;AAHC,SAAS,cAAc,EAAE,MAAM,SAAS,OAAO,MAAM,QAAQ,SAAS,cAAc,OAAO,SAAS,QAAQ,UAAU,GAAG,MAAM,GAAuB;AAC3J,SACE,qBAAC,SAAK,GAAG,OACP;AAAA,wBAAC,YAAS,MAAY,QAAgB,SAAkB,OAAc,MAAY,UAAS,SACxF,kBACH;AAAA,IACA,oBAAC,QAAK,WAAU,0BACd,+BAAC,SAAI,WAAU,oBACb;AAAA,2BAAC,aAAQ,WAAU,4BAA2B,MAAI,MAChD;AAAA,4BAAC,aAAS,wBAAa;AAAA,QACvB,oBAAC,SAAK,mBAAQ;AAAA,SAChB;AAAA,MACA,qBAAC,SAAI,WAAU,WACX;AAAA,kBAAS,YACT,qBAAC,SAAI,WAAU,yBACZ;AAAA,mBACC,oBAAC,OAAE,WAAU,gBAAe,aAAU,UACnC,iBACH;AAAA,UAED;AAAA,WACH;AAAA,QAED;AAAA,SACH;AAAA,OACF,GACF;AAAA,KACF;AAEJ;","names":[]}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { LinkComponent } from '@krizaka/ui/page-hero';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
|
|
4
|
+
type ChangeKind = "added" | "changed" | "fixed" | "removed";
|
|
5
|
+
interface ChangelogEntry {
|
|
6
|
+
/** A stable key (the entry's anchor). */
|
|
7
|
+
id: string;
|
|
8
|
+
/** Its date, ISO (`2026-10-11`): shown as `dateLabel`. */
|
|
9
|
+
date: string;
|
|
10
|
+
/** The date as the reader reads it (`11 October 2026`). */
|
|
11
|
+
dateLabel: React.ReactNode;
|
|
12
|
+
/** The version or the release (`@krizaka/ui 2.6.0`): a fact beside the date. */
|
|
13
|
+
version?: React.ReactNode;
|
|
14
|
+
/** The entry's title. */
|
|
15
|
+
title: React.ReactNode;
|
|
16
|
+
/** The changes, each with its kind. */
|
|
17
|
+
changes: readonly {
|
|
18
|
+
kind: ChangeKind;
|
|
19
|
+
text: React.ReactNode;
|
|
20
|
+
}[];
|
|
21
|
+
/** Under the changes: why (a DecisionList, a quote), a link to the pull request. */
|
|
22
|
+
children?: React.ReactNode;
|
|
23
|
+
}
|
|
24
|
+
type ChangelogPageProps = Omit<React.HTMLAttributes<HTMLElement>, "title"> & {
|
|
25
|
+
/** The way back. */
|
|
26
|
+
back?: {
|
|
27
|
+
href: string;
|
|
28
|
+
label: string;
|
|
29
|
+
};
|
|
30
|
+
/** A mono line above the title. */
|
|
31
|
+
eyebrow?: React.ReactNode;
|
|
32
|
+
/** The page's `h1`. */
|
|
33
|
+
title: React.ReactNode;
|
|
34
|
+
/** One sentence under it. */
|
|
35
|
+
lead?: React.ReactNode;
|
|
36
|
+
/** In the hero: a subscribe action, the feed. */
|
|
37
|
+
actions?: React.ReactNode;
|
|
38
|
+
/** The words of the kinds: `{ added: "Added", … }`. */
|
|
39
|
+
kindLabels: Record<ChangeKind, string>;
|
|
40
|
+
/** The log's accessible name (`Changes`). */
|
|
41
|
+
logLabel: string;
|
|
42
|
+
/** The entries, newest first. */
|
|
43
|
+
entries: readonly ChangelogEntry[];
|
|
44
|
+
/** The app's link component (Next's `Link`). */
|
|
45
|
+
linkAs?: LinkComponent;
|
|
46
|
+
};
|
|
47
|
+
/** A changelog: entries with a sticky date and version, changes by kind, the reasons under them. */
|
|
48
|
+
declare function ChangelogPage({ back, eyebrow, title, lead, actions, kindLabels, logLabel, entries, linkAs, ...props }: ChangelogPageProps): React.JSX.Element;
|
|
49
|
+
|
|
50
|
+
export { type ChangeKind, type ChangelogEntry, ChangelogPage, type ChangelogPageProps };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// src/changelog-page/changelog-page.tsx
|
|
2
|
+
import { Page } from "@krizaka/ui/page";
|
|
3
|
+
import { PageHero } from "@krizaka/ui/page-hero";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
function ChangelogPage({ back, eyebrow, title, lead, actions, kindLabels, logLabel, entries, linkAs, ...props }) {
|
|
6
|
+
return /* @__PURE__ */ jsxs("div", { ...props, children: [
|
|
7
|
+
/* @__PURE__ */ jsx(PageHero, { back, linkAs, eyebrow, title, lead, backdrop: "plain", children: actions }),
|
|
8
|
+
/* @__PURE__ */ jsx(Page, { className: "kz-tpl-longform", children: /* @__PURE__ */ jsx("ol", { className: "kz-tpl-log", "aria-label": logLabel, children: entries.map((e) => /* @__PURE__ */ jsxs("li", { id: e.id, className: "kz-tpl-log-entry", children: [
|
|
9
|
+
/* @__PURE__ */ jsxs("div", { className: "kz-tpl-log-when", children: [
|
|
10
|
+
/* @__PURE__ */ jsx("time", { dateTime: e.date, children: e.dateLabel }),
|
|
11
|
+
e.version && /* @__PURE__ */ jsx("span", { className: "kz-fact", children: e.version })
|
|
12
|
+
] }),
|
|
13
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
14
|
+
/* @__PURE__ */ jsx("h2", { children: e.title }),
|
|
15
|
+
/* @__PURE__ */ jsx("ul", { className: "kz-tpl-log-items", children: e.changes.map((c, i) => /* @__PURE__ */ jsxs("li", { children: [
|
|
16
|
+
/* @__PURE__ */ jsx("span", { className: "kz-tpl-log-kind", "data-kind": c.kind, children: kindLabels[c.kind] }),
|
|
17
|
+
/* @__PURE__ */ jsx("span", { children: c.text })
|
|
18
|
+
] }, i)) }),
|
|
19
|
+
e.children
|
|
20
|
+
] })
|
|
21
|
+
] }, e.id)) }) })
|
|
22
|
+
] });
|
|
23
|
+
}
|
|
24
|
+
export {
|
|
25
|
+
ChangelogPage
|
|
26
|
+
};
|
|
27
|
+
//# sourceMappingURL=changelog-page.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/changelog-page/changelog-page.tsx"],"sourcesContent":["// Server-safe. What changed and why (blocks.css `.kz-tpl-log`): the hero, then the entries — the date and version\n// sticking beside them while they scroll, a title, the changes by kind (added · changed · fixed · removed, in words and\n// colour) — and, when a change was a decision, its reasons (a DecisionList) under it.\nimport { Page } from \"@krizaka/ui/page\";\nimport type { LinkComponent } from \"@krizaka/ui/page-hero\";\nimport { PageHero } from \"@krizaka/ui/page-hero\";\nimport type * as React from \"react\";\n\nexport type ChangeKind = \"added\" | \"changed\" | \"fixed\" | \"removed\";\n\nexport interface ChangelogEntry {\n /** A stable key (the entry's anchor). */\n id: string;\n /** Its date, ISO (`2026-10-11`): shown as `dateLabel`. */\n date: string;\n /** The date as the reader reads it (`11 October 2026`). */\n dateLabel: React.ReactNode;\n /** The version or the release (`@krizaka/ui 2.6.0`): a fact beside the date. */\n version?: React.ReactNode;\n /** The entry's title. */\n title: React.ReactNode;\n /** The changes, each with its kind. */\n changes: readonly { kind: ChangeKind; text: React.ReactNode }[];\n /** Under the changes: why (a DecisionList, a quote), a link to the pull request. */\n children?: React.ReactNode;\n}\n\nexport type ChangelogPageProps = Omit<React.HTMLAttributes<HTMLElement>, \"title\"> & {\n /** The way back. */\n back?: { href: string; label: string };\n /** A mono line above the title. */\n eyebrow?: React.ReactNode;\n /** The page's `h1`. */\n title: React.ReactNode;\n /** One sentence under it. */\n lead?: React.ReactNode;\n /** In the hero: a subscribe action, the feed. */\n actions?: React.ReactNode;\n /** The words of the kinds: `{ added: \"Added\", … }`. */\n kindLabels: Record<ChangeKind, string>;\n /** The log's accessible name (`Changes`). */\n logLabel: string;\n /** The entries, newest first. */\n entries: readonly ChangelogEntry[];\n /** The app's link component (Next's `Link`). */\n linkAs?: LinkComponent;\n};\n\n/** A changelog: entries with a sticky date and version, changes by kind, the reasons under them. */\nexport function ChangelogPage({ back, eyebrow, title, lead, actions, kindLabels, logLabel, entries, linkAs, ...props }: ChangelogPageProps) {\n return (\n <div {...props}>\n <PageHero back={back} linkAs={linkAs} eyebrow={eyebrow} title={title} lead={lead} backdrop=\"plain\">\n {actions}\n </PageHero>\n <Page className=\"kz-tpl-longform\">\n <ol className=\"kz-tpl-log\" aria-label={logLabel}>\n {entries.map((e) => (\n <li key={e.id} id={e.id} className=\"kz-tpl-log-entry\">\n <div className=\"kz-tpl-log-when\">\n <time dateTime={e.date}>{e.dateLabel}</time>\n {e.version && <span className=\"kz-fact\">{e.version}</span>}\n </div>\n <div>\n <h2>{e.title}</h2>\n <ul className=\"kz-tpl-log-items\">\n {e.changes.map((c, i) => (\n <li key={i}>\n <span className=\"kz-tpl-log-kind\" data-kind={c.kind}>\n {kindLabels[c.kind]}\n </span>\n <span>{c.text}</span>\n </li>\n ))}\n </ul>\n {e.children}\n </div>\n </li>\n ))}\n </ol>\n </Page>\n </div>\n );\n}\n"],"mappings":";AAGA,SAAS,YAAY;AAErB,SAAS,gBAAgB;AA+CnB,cAOQ,YAPR;AAHC,SAAS,cAAc,EAAE,MAAM,SAAS,OAAO,MAAM,SAAS,YAAY,UAAU,SAAS,QAAQ,GAAG,MAAM,GAAuB;AAC1I,SACE,qBAAC,SAAK,GAAG,OACP;AAAA,wBAAC,YAAS,MAAY,QAAgB,SAAkB,OAAc,MAAY,UAAS,SACxF,mBACH;AAAA,IACA,oBAAC,QAAK,WAAU,mBACd,8BAAC,QAAG,WAAU,cAAa,cAAY,UACpC,kBAAQ,IAAI,CAAC,MACZ,qBAAC,QAAc,IAAI,EAAE,IAAI,WAAU,oBACjC;AAAA,2BAAC,SAAI,WAAU,mBACb;AAAA,4BAAC,UAAK,UAAU,EAAE,MAAO,YAAE,WAAU;AAAA,QACpC,EAAE,WAAW,oBAAC,UAAK,WAAU,WAAW,YAAE,SAAQ;AAAA,SACrD;AAAA,MACA,qBAAC,SACC;AAAA,4BAAC,QAAI,YAAE,OAAM;AAAA,QACb,oBAAC,QAAG,WAAU,oBACX,YAAE,QAAQ,IAAI,CAAC,GAAG,MACjB,qBAAC,QACC;AAAA,8BAAC,UAAK,WAAU,mBAAkB,aAAW,EAAE,MAC5C,qBAAW,EAAE,IAAI,GACpB;AAAA,UACA,oBAAC,UAAM,YAAE,MAAK;AAAA,aAJP,CAKT,CACD,GACH;AAAA,QACC,EAAE;AAAA,SACL;AAAA,SAlBO,EAAE,EAmBX,CACD,GACH,GACF;AAAA,KACF;AAEJ;","names":[]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
// src/mascots/geometry.ts
|
|
4
|
-
var MASCOT_BIRDS = ["falcon", "owl", "duck", "flamingo", "pigeon", "lovebird"];
|
|
4
|
+
var MASCOT_BIRDS = ["falcon", "owl", "duck", "flamingo", "pigeon", "lovebird", "crane"];
|
|
5
5
|
var MASCOT_MOODS = ["welcome", "thinking", "success", "empty", "error"];
|
|
6
6
|
var mirror = (d) => d.replace(/(-?\d+(?:\.\d+)?) (-?\d+(?:\.\d+)?)/g, (_, x, y) => `${120 - Number(x)} ${y}`);
|
|
7
7
|
var falconWing = "M29 58 C17 68 19 88 37 86 C31 76 31 66 29 58 Z";
|
|
@@ -101,6 +101,26 @@ var BIRDS = {
|
|
|
101
101
|
details: ["M43 40 C42 28 51 22 60 22 C69 22 78 28 77 40 C76 50 68 55 60 55 C52 55 44 50 43 40 Z"],
|
|
102
102
|
beak: "M55 44 C55 40 65 40 65 44 C65 50 62 54 60 55 C58 54 55 50 55 44 Z",
|
|
103
103
|
eyes: { at: [[51, 36], [69, 36]], white: 4.6, pupil: 2.4 }
|
|
104
|
+
},
|
|
105
|
+
/**
|
|
106
|
+
* The crane — the one that listens: posed, unhurried, drawn in one line. A tall wader seen in profile, standing still
|
|
107
|
+
* on two straight legs, the neck a single stroke up to a small head with its crown (the detail colour) and a long,
|
|
108
|
+
* straight beak; the folded wings low on its back. The flamingo bends and answers; the crane stands and listens.
|
|
109
|
+
*/
|
|
110
|
+
crane: {
|
|
111
|
+
shadow: [62, 110, 20, 3],
|
|
112
|
+
legs: ["M56 87 L55 108 M51 108 L59 108", "M67 87 L68 108 M64 108 L73 108"],
|
|
113
|
+
body: "M40 66 C38 54 84 54 86 68 C88 82 76 88 62 88 C48 88 40 80 40 66 Z",
|
|
114
|
+
belly: "M48 70 C48 62 78 62 79 70 C80 79 72 84 63 84 C54 84 48 79 48 70 Z",
|
|
115
|
+
wings: [
|
|
116
|
+
{ d: "M44 62 C33 68 35 82 49 83 C45 76 45 69 44 62 Z", pivot: [44, 62] },
|
|
117
|
+
{ d: "M82 62 C93 67 96 82 80 84 C83 76 83 69 82 62 Z", pivot: [82, 62] }
|
|
118
|
+
],
|
|
119
|
+
neck: { d: "M52 62 C48 47 52 37 48 26", width: 6 },
|
|
120
|
+
head: { cx: 47, cy: 21, r: 8.5 },
|
|
121
|
+
details: ["M41 16.5 C42 11 52 11 53 16.5 C50 14.6 44 14.6 41 16.5 Z"],
|
|
122
|
+
beak: "M40.5 18.5 L19 22.5 L40.5 25.5 Z",
|
|
123
|
+
eyes: { at: [[45.5, 19.5]], white: 2.8, pupil: 1.6 }
|
|
104
124
|
}
|
|
105
125
|
};
|
|
106
126
|
var MOOD_PARTS = {
|
|
@@ -129,7 +149,9 @@ var OWN_PALETTES = {
|
|
|
129
149
|
duck: { from: "#f43f5e", to: "#be123c", wing: "#db2777", detail: "#9f1239", beak: "#fbbf24", eye: "#1f2937" },
|
|
130
150
|
flamingo: { from: "#f9a8d4", to: "#db2777", wing: "#ec4899", detail: "#be185d", beak: "#fbbf24", eye: "#1f2937" },
|
|
131
151
|
pigeon: { from: "#22d3ee", to: "#6366f1", wing: "#a855f7", detail: "#4338ca", beak: "#f59e0b", eye: "#1f2937" },
|
|
132
|
-
lovebird: { from: "#6ee7b7", to: "#059669", wing: "#047857", detail: "#fb7185", beak: "#f97316", eye: "#1f2937" }
|
|
152
|
+
lovebird: { from: "#6ee7b7", to: "#059669", wing: "#047857", detail: "#fb7185", beak: "#f97316", eye: "#1f2937" },
|
|
153
|
+
// The sandhill crane (grue du Canada): sand-grey plumage, its red crown, dark legs and beak.
|
|
154
|
+
crane: { from: "#ebe3d6", to: "#9c8f80", wing: "#7d7266", detail: "#dc2626", beak: "#44403c", eye: "#1f2937" }
|
|
133
155
|
};
|
|
134
156
|
var LIGHT = "#ffffff";
|
|
135
157
|
var SHADE = "#000000";
|
|
@@ -271,4 +293,4 @@ export {
|
|
|
271
293
|
MASCOT_MOODS,
|
|
272
294
|
Mascot
|
|
273
295
|
};
|
|
274
|
-
//# sourceMappingURL=chunk-
|
|
296
|
+
//# sourceMappingURL=chunk-JZPVUJIX.js.map
|