@krizaka/ui 2.9.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (307) hide show
  1. package/README.md +44 -6
  2. package/dist/audio-player.js +1 -1
  3. package/dist/blocks.css +247 -0
  4. package/dist/catalogue-page.d.ts +34 -0
  5. package/dist/catalogue-page.js +26 -0
  6. package/dist/catalogue-page.js.map +1 -0
  7. package/dist/changelog-page.d.ts +50 -0
  8. package/dist/changelog-page.js +27 -0
  9. package/dist/changelog-page.js.map +1 -0
  10. package/dist/{chunk-EUPTXKH7.js → chunk-BRKMQ6JV.js} +2 -1
  11. package/dist/chunk-FDCMBWUU.js +168 -0
  12. package/dist/chunk-FDCMBWUU.js.map +1 -0
  13. package/dist/chunk-HCNOOPZE.js +210 -0
  14. package/dist/chunk-HCNOOPZE.js.map +1 -0
  15. package/dist/{chunk-NOVUREEC.js → chunk-JZPVUJIX.js} +25 -3
  16. package/dist/chunk-JZPVUJIX.js.map +1 -0
  17. package/dist/chunk-KNBYZGSQ.js +11 -0
  18. package/dist/chunk-KNBYZGSQ.js.map +1 -0
  19. package/dist/{chunk-X6TW3X6Y.js → chunk-LCZXS6AK.js} +2 -2
  20. package/dist/chunk-OGJI5X4W.js +157 -0
  21. package/dist/chunk-OGJI5X4W.js.map +1 -0
  22. package/dist/combobox.js +2 -2
  23. package/dist/component-page.d.ts +41 -0
  24. package/dist/component-page.js +17 -0
  25. package/dist/component-page.js.map +1 -0
  26. package/dist/contact-page.d.ts +31 -0
  27. package/dist/contact-page.js +26 -0
  28. package/dist/contact-page.js.map +1 -0
  29. package/dist/data-table.d.ts +284 -24
  30. package/dist/data-table.js +914 -121
  31. package/dist/data-table.js.map +1 -1
  32. package/dist/date-picker.js +1 -1
  33. package/dist/docs-article-page.d.ts +54 -0
  34. package/dist/docs-article-page.js +29 -0
  35. package/dist/docs-article-page.js.map +1 -0
  36. package/dist/docs-hub-page.d.ts +72 -0
  37. package/dist/docs-hub-page.js +45 -0
  38. package/dist/docs-hub-page.js.map +1 -0
  39. package/dist/error-page.d.ts +22 -0
  40. package/dist/error-page.js +23 -0
  41. package/dist/error-page.js.map +1 -0
  42. package/dist/filter-bar.d.ts +12 -12
  43. package/dist/filter-bar.js +9 -145
  44. package/dist/filter-bar.js.map +1 -1
  45. package/dist/gallery-page.d.ts +50 -0
  46. package/dist/gallery-page.js +30 -0
  47. package/dist/gallery-page.js.map +1 -0
  48. package/dist/{geometry-CXrAW34x.d.ts → geometry-CbOU4rtL.d.ts} +4 -4
  49. package/dist/how-it-works-page.d.ts +48 -0
  50. package/dist/how-it-works-page.js +28 -0
  51. package/dist/how-it-works-page.js.map +1 -0
  52. package/dist/image-cropper.js +1 -1
  53. package/dist/index.d.ts +11 -2
  54. package/dist/index.js +93 -5
  55. package/dist/index.js.map +1 -1
  56. package/dist/landing-page.d.ts +58 -0
  57. package/dist/landing-page.js +42 -0
  58. package/dist/landing-page.js.map +1 -0
  59. package/dist/legal-page.d.ts +34 -0
  60. package/dist/legal-page.js +18 -0
  61. package/dist/legal-page.js.map +1 -0
  62. package/dist/longform-page.d.ts +42 -0
  63. package/dist/longform-page.js +29 -0
  64. package/dist/longform-page.js.map +1 -0
  65. package/dist/mascot-quote.d.ts +4 -4
  66. package/dist/mascot-quote.js +23 -1
  67. package/dist/mascot-quote.js.map +1 -1
  68. package/dist/mascot-state.d.ts +2 -2
  69. package/dist/mascot-state.js +1 -1
  70. package/dist/mascot-state.js.map +1 -1
  71. package/dist/mascots.d.ts +4 -4
  72. package/dist/mascots.js +1 -1
  73. package/dist/media-capture.js +1 -1
  74. package/dist/native/list.d.ts +95 -0
  75. package/dist/native/list.js +135 -0
  76. package/dist/native/list.js.map +1 -0
  77. package/dist/native.d.ts +16 -9
  78. package/dist/native.js +183 -74
  79. package/dist/native.js.map +1 -1
  80. package/dist/pricing-page.d.ts +62 -0
  81. package/dist/pricing-page.js +71 -0
  82. package/dist/pricing-page.js.map +1 -0
  83. package/dist/product-page.d.ts +83 -0
  84. package/dist/product-page.js +60 -0
  85. package/dist/product-page.js.map +1 -0
  86. package/dist/search-field.js +6 -160
  87. package/dist/search-field.js.map +1 -1
  88. package/dist/status-page.d.ts +42 -0
  89. package/dist/status-page.js +28 -0
  90. package/dist/status-page.js.map +1 -0
  91. package/dist/tag-input.js +2 -2
  92. package/dist/video-player.js +1 -1
  93. package/dist/video-trimmer.js +1 -1
  94. package/dist/virtual.d.ts +140 -0
  95. package/dist/virtual.js +19 -0
  96. package/dist/virtual.js.map +1 -0
  97. package/package.json +296 -10
  98. package/registry/achievement.json +1 -1
  99. package/registry/action-bar.json +1 -1
  100. package/registry/alert.json +1 -1
  101. package/registry/app-shell.json +1 -1
  102. package/registry/argument-card.json +1 -1
  103. package/registry/audio-player.json +1 -1
  104. package/registry/auth-layout.json +1 -1
  105. package/registry/avatar.json +1 -1
  106. package/registry/badge.json +1 -1
  107. package/registry/button.json +1 -1
  108. package/registry/card-grid.json +1 -1
  109. package/registry/card.json +1 -1
  110. package/registry/catalogue-page.json +240 -0
  111. package/registry/changelog-page.json +226 -0
  112. package/registry/checkbox.json +1 -1
  113. package/registry/chip-link.json +1 -1
  114. package/registry/chip.json +1 -1
  115. package/registry/choice-grid.json +1 -1
  116. package/registry/code-block.json +1 -1
  117. package/registry/combobox.json +1 -1
  118. package/registry/command.json +1 -1
  119. package/registry/component-page.json +227 -0
  120. package/registry/confirm-button.json +1 -1
  121. package/registry/contact-page.json +212 -0
  122. package/registry/continue-prompt.json +1 -1
  123. package/registry/countdown.json +1 -1
  124. package/registry/cta-panel.json +1 -1
  125. package/registry/dashboard-layout.json +1 -1
  126. package/registry/data-table.json +643 -49
  127. package/registry/date-picker.json +1 -1
  128. package/registry/decision-list.json +1 -1
  129. package/registry/detail-layout.json +1 -1
  130. package/registry/dialog.json +1 -1
  131. package/registry/docs-article-page.json +242 -0
  132. package/registry/docs-hub-page.json +270 -0
  133. package/registry/docs-layout.json +1 -1
  134. package/registry/dropdown-menu.json +1 -1
  135. package/registry/empty-state.json +1 -1
  136. package/registry/error-page.json +183 -0
  137. package/registry/examples/catalogue-page/components.d.ts +4 -0
  138. package/registry/examples/catalogue-page/components.js +33 -0
  139. package/registry/examples/catalogue-page/components.tsx +36 -0
  140. package/registry/examples/changelog-page/releases.d.ts +4 -0
  141. package/registry/examples/changelog-page/releases.js +44 -0
  142. package/registry/examples/changelog-page/releases.tsx +39 -0
  143. package/registry/examples/component-page/button.d.ts +4 -0
  144. package/registry/examples/component-page/button.js +33 -0
  145. package/registry/examples/component-page/button.tsx +30 -0
  146. package/registry/examples/contact-page/team.d.ts +4 -0
  147. package/registry/examples/contact-page/team.js +39 -0
  148. package/registry/examples/contact-page/team.tsx +38 -0
  149. package/registry/examples/data-table/details.d.ts +4 -0
  150. package/registry/examples/data-table/details.js +33 -0
  151. package/registry/examples/data-table/details.tsx +31 -0
  152. package/registry/examples/data-table/filters.d.ts +4 -0
  153. package/registry/examples/data-table/filters.js +40 -0
  154. package/registry/examples/data-table/filters.tsx +40 -0
  155. package/registry/examples/data-table/grouped.d.ts +4 -0
  156. package/registry/examples/data-table/grouped.js +24 -0
  157. package/registry/examples/data-table/grouped.tsx +23 -0
  158. package/registry/examples/data-table/paginated.d.ts +4 -0
  159. package/registry/examples/data-table/paginated.js +23 -0
  160. package/registry/examples/data-table/paginated.tsx +22 -0
  161. package/registry/examples/data-table/pinned.d.ts +4 -0
  162. package/registry/examples/data-table/pinned.js +26 -0
  163. package/registry/examples/data-table/pinned.tsx +25 -0
  164. package/registry/examples/data-table/server.d.ts +4 -0
  165. package/registry/examples/data-table/server.js +40 -0
  166. package/registry/examples/data-table/server.tsx +40 -0
  167. package/registry/examples/data-table/virtualized.js +2 -2
  168. package/registry/examples/data-table/virtualized.tsx +3 -3
  169. package/registry/examples/docs-article-page/cli.d.ts +4 -0
  170. package/registry/examples/docs-article-page/cli.js +33 -0
  171. package/registry/examples/docs-article-page/cli.tsx +38 -0
  172. package/registry/examples/docs-hub-page/krizaka.d.ts +4 -0
  173. package/registry/examples/docs-hub-page/krizaka.js +46 -0
  174. package/registry/examples/docs-hub-page/krizaka.tsx +37 -0
  175. package/registry/examples/error-page/not-found.d.ts +4 -0
  176. package/registry/examples/error-page/not-found.js +24 -0
  177. package/registry/examples/error-page/not-found.tsx +19 -0
  178. package/registry/examples/gallery-page/made-here.d.ts +4 -0
  179. package/registry/examples/gallery-page/made-here.js +34 -0
  180. package/registry/examples/gallery-page/made-here.tsx +32 -0
  181. package/registry/examples/how-it-works-page/orazaka.d.ts +4 -0
  182. package/registry/examples/how-it-works-page/orazaka.js +30 -0
  183. package/registry/examples/how-it-works-page/orazaka.tsx +26 -0
  184. package/registry/examples/landing-page/krizaka.d.ts +4 -0
  185. package/registry/examples/landing-page/krizaka.js +44 -0
  186. package/registry/examples/landing-page/krizaka.tsx +44 -0
  187. package/registry/examples/legal-page/privacy.d.ts +4 -0
  188. package/registry/examples/legal-page/privacy.js +24 -0
  189. package/registry/examples/legal-page/privacy.tsx +19 -0
  190. package/registry/examples/list/native/default.d.ts +4 -0
  191. package/registry/examples/list/native/default.dark.png +0 -0
  192. package/registry/examples/list/native/default.js +33 -0
  193. package/registry/examples/list/native/default.light.png +0 -0
  194. package/registry/examples/list/native/default.tsx +31 -0
  195. package/registry/examples/list/native/infinite.d.ts +4 -0
  196. package/registry/examples/list/native/infinite.dark.png +0 -0
  197. package/registry/examples/list/native/infinite.js +30 -0
  198. package/registry/examples/list/native/infinite.light.png +0 -0
  199. package/registry/examples/list/native/infinite.tsx +35 -0
  200. package/registry/examples/list/native/states.d.ts +4 -0
  201. package/registry/examples/list/native/states.dark.png +0 -0
  202. package/registry/examples/list/native/states.js +26 -0
  203. package/registry/examples/list/native/states.light.png +0 -0
  204. package/registry/examples/list/native/states.tsx +21 -0
  205. package/registry/examples/longform-page/story.d.ts +4 -0
  206. package/registry/examples/longform-page/story.js +38 -0
  207. package/registry/examples/longform-page/story.tsx +35 -0
  208. package/registry/examples/mascots/crane.d.ts +4 -0
  209. package/registry/examples/mascots/crane.js +19 -0
  210. package/registry/examples/mascots/crane.tsx +18 -0
  211. package/registry/examples/mascots/flock.tsx +2 -1
  212. package/registry/examples/mascots/native/crane.d.ts +4 -0
  213. package/registry/examples/mascots/native/crane.dark.png +0 -0
  214. package/registry/examples/mascots/native/crane.js +21 -0
  215. package/registry/examples/mascots/native/crane.light.png +0 -0
  216. package/registry/examples/mascots/native/crane.tsx +18 -0
  217. package/registry/examples/pricing-page/credits.d.ts +4 -0
  218. package/registry/examples/pricing-page/credits.js +41 -0
  219. package/registry/examples/pricing-page/credits.tsx +33 -0
  220. package/registry/examples/product-page/orazaka.d.ts +4 -0
  221. package/registry/examples/product-page/orazaka.js +44 -0
  222. package/registry/examples/product-page/orazaka.tsx +36 -0
  223. package/registry/examples/status-page/building.d.ts +4 -0
  224. package/registry/examples/status-page/building.js +29 -0
  225. package/registry/examples/status-page/building.tsx +25 -0
  226. package/registry/examples/status-page/operational.d.ts +4 -0
  227. package/registry/examples/status-page/operational.js +26 -0
  228. package/registry/examples/status-page/operational.tsx +20 -0
  229. package/registry/examples/virtual/feed.d.ts +4 -0
  230. package/registry/examples/virtual/feed.js +26 -0
  231. package/registry/examples/virtual/feed.tsx +24 -0
  232. package/registry/examples/virtual/gallery.d.ts +4 -0
  233. package/registry/examples/virtual/gallery.js +31 -0
  234. package/registry/examples/virtual/gallery.tsx +28 -0
  235. package/registry/examples/virtual/messages.d.ts +4 -0
  236. package/registry/examples/virtual/messages.js +28 -0
  237. package/registry/examples/virtual/messages.tsx +28 -0
  238. package/registry/field.json +1 -1
  239. package/registry/file-upload.json +1 -1
  240. package/registry/filter-bar.json +1 -1
  241. package/registry/gallery-page.json +256 -0
  242. package/registry/glow-card.json +1 -1
  243. package/registry/goal-gauge.json +1 -1
  244. package/registry/how-it-works-page.json +242 -0
  245. package/registry/image-cropper.json +1 -1
  246. package/registry/index.json +356 -9
  247. package/registry/iso.json +1 -1
  248. package/registry/kbd.json +1 -1
  249. package/registry/landing-page.json +242 -0
  250. package/registry/landscape.json +1 -1
  251. package/registry/legal-page.json +199 -0
  252. package/registry/link-card.json +1 -1
  253. package/registry/list.json +249 -0
  254. package/registry/loader.json +1 -1
  255. package/registry/longform-page.json +213 -0
  256. package/registry/marketing-layout.json +1 -1
  257. package/registry/marquee.json +1 -1
  258. package/registry/mascot-quote.json +6 -6
  259. package/registry/mascot-state.json +34 -34
  260. package/registry/mascots.json +41 -21
  261. package/registry/media-capture.json +1 -1
  262. package/registry/meter.json +1 -1
  263. package/registry/nav-bar.json +1 -1
  264. package/registry/number-ticker.json +1 -1
  265. package/registry/page-header.json +1 -1
  266. package/registry/page-hero.json +1 -1
  267. package/registry/page.json +1 -1
  268. package/registry/pagination.json +1 -1
  269. package/registry/pointer-light.json +1 -1
  270. package/registry/popover.json +1 -1
  271. package/registry/pricing-page.json +245 -0
  272. package/registry/product-page.json +319 -0
  273. package/registry/profile-card.json +1 -1
  274. package/registry/progress.json +1 -1
  275. package/registry/promise-card.json +1 -1
  276. package/registry/radio-group.json +1 -1
  277. package/registry/scroll-stage.json +1 -1
  278. package/registry/search-field.json +1 -1
  279. package/registry/section-backdrop.json +1 -1
  280. package/registry/separator.json +1 -1
  281. package/registry/settings-layout.json +1 -1
  282. package/registry/skeleton.json +1 -1
  283. package/registry/slider.json +1 -1
  284. package/registry/slot.json +1 -1
  285. package/registry/spinner.json +1 -1
  286. package/registry/split-view.json +1 -1
  287. package/registry/stage-banner.json +1 -1
  288. package/registry/stat.json +1 -1
  289. package/registry/status-page.json +263 -0
  290. package/registry/stepper.json +1 -1
  291. package/registry/switch.json +1 -1
  292. package/registry/tabs.json +1 -1
  293. package/registry/tag-input.json +1 -1
  294. package/registry/terminal-replay.json +1 -1
  295. package/registry/theme.json +1 -1
  296. package/registry/toast.json +1 -1
  297. package/registry/toc.json +1 -1
  298. package/registry/tooltip.json +1 -1
  299. package/registry/video-player.json +1 -1
  300. package/registry/video-trimmer.json +1 -1
  301. package/registry/virtual.json +569 -0
  302. package/skills/data-table/SKILL.md +56 -0
  303. package/skills/native-list/SKILL.md +39 -0
  304. package/skills/virtual/SKILL.md +35 -0
  305. package/dist/chunk-NOVUREEC.js.map +0 -1
  306. /package/dist/{chunk-EUPTXKH7.js.map → chunk-BRKMQ6JV.js.map} +0 -0
  307. /package/dist/{chunk-X6TW3X6Y.js.map → chunk-LCZXS6AK.js.map} +0 -0
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 Yazakia, and the Krizaka motion signature — one easing, one way to enter, reveal, roll, shine
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
  [![npm](https://img.shields.io/npm/v/@krizaka/ui?color=196df5&label=npm)](https://www.npmjs.com/package/@krizaka/ui)
@@ -172,11 +172,12 @@ 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 |
179
- | `@krizaka/ui/data-table` | `DataTable` (`rows`, `columns` with `header`, `cell`, `value`, `sortable`, `align`, `card` title·label·hidden; `caption`, `sort`/`defaultSort` + `onSortChange`, `manualSort`, `selectable` + `selected`, `loading`, `empty`, `error`, `layout` auto·table·cards, `density`, `virtualize`, `footer`) | client |
179
+ | `@krizaka/ui/data-table` | **v2, on TanStack Table v9** (never imported by a product): `DataTable` (`rows`, `columns` with `header`, `cell`, `value`, `sortable`, `filter` text·facet·range + `options`, `groupable` + `aggregate`, `align`, `width`, `card`, `hideable`; `caption`, `sort`, `filters`, `selected` + `selectable`, `groupBy`, `columnVisibility`, `expanded` + `renderDetail` / `getSubRows`, `page` + `pageSize` / `pageSizeOptions`, each controlled or `default*`; `pinning`, `resizing`, `manual` sorting·filtering·pagination + `rowCount` + `onStateChange` (server mode), `virtualized`, `loading`, `empty`, `error`, `layout` auto·table·cards, `density`, `toolbar`, `footer`, `labels`), the toolbar `DataTableFilters` · `DataTableColumnsMenu` · `DataTableExport`, `useDataTable()` (the TanStack instance), `dataTableCsv` | client |
180
+ | `@krizaka/ui/virtual` | On TanStack Virtual v3: `VirtualList` (own region or `scroll="window"`, measured items, `onEndReached`, `ref.scrollToIndex`), `VirtualGrid` (columns that fit the width), `useVirtualizer` / `useWindowVirtualizer` through the facade | client |
180
181
  | `@krizaka/ui/filter-bar` | `FilterBar` (`label`, the controls as children, `active` chips, `onClearAll`, `results` announced), `FilterMenu` (checkboxes or radios with counts), `readFilterParams` / `writeFilterParams` (the filters in the address) | client |
181
182
  | `@krizaka/ui/combobox` | `Combobox` (ARIA 1.2: `options` or `onSearch(query, signal)` debounced, `multiple` chips + `maxSelected`, `creatable` + `onCreate`, `separators`, `hint`, `error`, `labels`) | client |
182
183
  | `@krizaka/ui/tag-input` | `TagInput` (free words as chips: `suggestions`, `normalize`, `validate`, `max`, `separators`, paste split) | client |
@@ -208,7 +209,23 @@ light or a product's — is a set of tokens.
208
209
  | `@krizaka/ui/split-view` | `SplitView` (`listTitle`, `listActions`, `list`, `detailHead`, `detail`, `empty`, `showDetail`, `back`) | server |
209
210
  | `@krizaka/ui/marketing-layout` | `MarketingLayout` (`header`, `footer`, `skipLabel`) | server |
210
211
  | `@krizaka/ui/docs-layout` | `DocsLayout` (`sidebar`, `sidebarLabel`, `toc`) | server |
212
+ | `@krizaka/ui/landing-page` | `LandingPage` — a page template, see [Page templates](#page-templates) | server |
213
+ | `@krizaka/ui/product-page` | `ProductPage` — a page template, see [Page templates](#page-templates) | server |
214
+ | `@krizaka/ui/how-it-works-page` | `HowItWorksPage` — a page template, see [Page templates](#page-templates) | server |
215
+ | `@krizaka/ui/gallery-page` | `GalleryPage` — a page template, see [Page templates](#page-templates) | server |
216
+ | `@krizaka/ui/docs-hub-page` | `DocsHubPage` — a page template, see [Page templates](#page-templates) | server |
217
+ | `@krizaka/ui/docs-article-page` | `DocsArticlePage` — a page template, see [Page templates](#page-templates) | server |
218
+ | `@krizaka/ui/component-page` | `ComponentPage` — a page template, see [Page templates](#page-templates) | server |
219
+ | `@krizaka/ui/catalogue-page` | `CataloguePage` — a page template, see [Page templates](#page-templates) | server |
220
+ | `@krizaka/ui/longform-page` | `LongformPage` — a page template, see [Page templates](#page-templates) | server |
221
+ | `@krizaka/ui/changelog-page` | `ChangelogPage` — a page template, see [Page templates](#page-templates) | server |
222
+ | `@krizaka/ui/contact-page` | `ContactPage` — a page template, see [Page templates](#page-templates) | server |
223
+ | `@krizaka/ui/legal-page` | `LegalPage` — a page template, see [Page templates](#page-templates) | server |
224
+ | `@krizaka/ui/status-page` | `StatusPage` — a page template, see [Page templates](#page-templates) | server |
225
+ | `@krizaka/ui/error-page` | `ErrorPage` — a page template, see [Page templates](#page-templates) | server |
226
+ | `@krizaka/ui/pricing-page` | `PricingPage` — a page template, see [Page templates](#page-templates) | server |
211
227
  | `@krizaka/ui/native/video-player` | React Native `VideoPlayer` on expo-video (optional peer) | native |
228
+ | `@krizaka/ui/native/list` | React Native `List` on FlashList v2 and `useInfiniteList` on `useInfiniteQuery` of `@krizaka/query` (optional peers): separators, skeleton rows, empty/error, pull to refresh, the next page near the end | native |
212
229
  | `@krizaka/ui/native/media-capture` | React Native `MediaCapture` on expo-camera (optional peer) | native |
213
230
  | `@krizaka/ui` | the marks, `MotionObserver`, `RotatingWord`, `cx` (unchanged) | client |
214
231
  | `@krizaka/ui/native` | React Native: `ThemeProvider`/`useTheme`, `Txt`, `Button`, `IconButton`, `Card.*`, `Badge`, `Chip` (+ `Group`), `Avatar` (+ `Group`), `Skeleton`, `EmptyState`, `Spinner`, `Countdown`, `Segmented`, `Progress`, `Toaster`/`toast`, `Pagination`, `SearchField`, the marks — see [React Native](#react-native) | native |
@@ -260,7 +277,27 @@ import { LinkCard } from "@krizaka/ui/link-card";
260
277
  - **Motion.** `reveal` uses `[data-reveal]` (MotionObserver): never on the first screen. The pointer's light, the lifts
261
278
  and the hops stop under `prefers-reduced-motion`; nothing loops.
262
279
 
263
- ## Layouts and templates
280
+ ## Page templates
281
+
282
+ > Category **templates** of krizaka.com/docs/ui: every page of a Krizaka site has its template.
283
+
284
+ Fifteen templates, each a **distinct composition** of the blocks — not the same card grid everywhere: `LandingPage`
285
+ (split hero with the product alive, a band of proofs, a bento), `ProductPage` (split hero in the product's brand,
286
+ compact argument cards, decisions, the bird's promise), `HowItWorksPage` (a numbered timeline, the visuals
287
+ alternating), `GalleryPage` (filters, staggered columns of media), `DocsHubPage` (search first, the collections in
288
+ their brand with quick links, quick starts, most read, what is new), `DocsArticlePage` (pages · article · contents,
289
+ pager), `ComponentPage` (preview, install, sections, related), `CataloguePage` (sticky filters beside the results),
290
+ `LongformPage` (chapters with outlined numbers, pull quotes in the margin), `ChangelogPage` (a sticky date beside each
291
+ entry, changes by kind), `ContactPage` (channels beside the form, what happens next), `LegalPage` (summary, sections,
292
+ contents), `StatusPage` (the state in words, each service — or « under construction »), `ErrorPage` (the code drawn,
293
+ the bird, a search, the ways back) and `PricingPage` (plans, comparison, credits, questions).
294
+
295
+ Words and content are props or slots; `brand` puts a page under `.brand-<id>`; calls to action use the cut button;
296
+ what rises does so with `[data-reveal]` (still under reduced motion); every one reads in one column on a phone, and
297
+ each example has a phone story. The templates import the blocks through the package's own entries, so a block's client
298
+ boundary stays where it is: a template is a Server Component.
299
+
300
+ ## Layouts and screens
264
301
 
265
302
  > Category **layouts** of krizaka.com/docs/ui, and **templates**: whole screens composed from the platform.
266
303
 
@@ -367,7 +404,7 @@ const { theme, scheme, mode, setMode, radius } = useTheme(); // theme.surface1,
367
404
  | `Segmented` | `options` (`value`, `label`, `disabled`), `value`, `onValueChange`, `size` | The web `Tabs variant="segmented"` (a tab list). To filter, `Chip.Group`. |
368
405
  | `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
406
  | `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. |
407
+ | `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
408
 
372
409
  Every animation (skeleton, badge dot, urgent countdown, progress, toast entrance, the marks) stops when the system
373
410
  asks to reduce motion (`useReducedMotion()`). Accessibility goes through `role` and `aria-*` (RN ≥ 0.71): headings,
@@ -397,12 +434,13 @@ Testing Library (`src/native/*.test.tsx`); `scripts/native-dist.mjs` checks that
397
434
  ## The marks
398
435
 
399
436
  ```tsx
400
- import { KrizakaLogo, OrazakaLogo, OrochiaLogo, ProductLogo, YazakiaLogo } from "@krizaka/ui";
437
+ import { KrizakaLogo, OrazakaLogo, OrochiaLogo, ProductLogo, YazakiaLogo, YororisLogo } from "@krizaka/ui";
401
438
 
402
439
  <OrochiaLogo size={36} /> // decorative (aria-hidden)
403
440
  <KrizakaLogo size={48} title="Krizaka" /> // an image with an accessible name
404
441
  <ProductLogo id="orazaka" animated={false} /> // by id, still
405
442
  <YazakiaLogo size={32} /> // Yazakia: emerald → turquoise, two voices that meet
443
+ <YororisLogo size={32} /> // Yororis: sand → sage, the hold
406
444
  ```
407
445
 
408
446
  Neutral strokes follow the host's `--kz-*` tokens when they exist (`--kz-border-strong`, `--kz-text-muted`…) and the
@@ -4,7 +4,7 @@ import {
4
4
  formatClock,
5
5
  playSafely,
6
6
  useInView
7
- } from "./chunk-EUPTXKH7.js";
7
+ } from "./chunk-BRKMQ6JV.js";
8
8
  import {
9
9
  PauseGlyph,
10
10
  PlayGlyph
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":[]}
@@ -87,9 +87,10 @@ export {
87
87
  formatClock,
88
88
  clamp,
89
89
  usePrefersReducedMotion,
90
+ useLatest,
90
91
  useInView,
91
92
  useDebouncedCallback,
92
93
  useControllable,
93
94
  playSafely
94
95
  };
95
- //# sourceMappingURL=chunk-EUPTXKH7.js.map
96
+ //# sourceMappingURL=chunk-BRKMQ6JV.js.map