@krizaka/ui 3.50.0 → 3.52.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 (224) hide show
  1. package/dist/argument-card.js +3 -3
  2. package/dist/blocks.css +209 -0
  3. package/dist/chunk-YATTFMDV.js +45 -0
  4. package/dist/chunk-YATTFMDV.js.map +1 -0
  5. package/dist/glossary-term.d.ts +12 -0
  6. package/dist/glossary-term.js +16 -0
  7. package/dist/glossary-term.js.map +1 -0
  8. package/dist/glossary.d.ts +20 -0
  9. package/dist/glossary.js +17 -0
  10. package/dist/glossary.js.map +1 -0
  11. package/dist/index.js +7 -7
  12. package/dist/kpi-explained.d.ts +66 -0
  13. package/dist/kpi-explained.js +84 -0
  14. package/dist/kpi-explained.js.map +1 -0
  15. package/dist/next-actions.d.ts +27 -0
  16. package/dist/next-actions.js +27 -0
  17. package/dist/next-actions.js.map +1 -0
  18. package/dist/taped-photo.d.ts +16 -0
  19. package/dist/taped-photo.js +26 -0
  20. package/dist/taped-photo.js.map +1 -0
  21. package/dist/text-style/server.d.ts +63 -0
  22. package/dist/text-style/server.js +109 -0
  23. package/dist/text-style/server.js.map +1 -0
  24. package/dist/text-style.d.ts +149 -0
  25. package/dist/text-style.js +399 -0
  26. package/dist/text-style.js.map +1 -0
  27. package/dist/tooltip.js +5 -37
  28. package/dist/tooltip.js.map +1 -1
  29. package/package.json +83 -5
  30. package/registry/account-menu.json +1 -1
  31. package/registry/account-settings.json +1 -1
  32. package/registry/achievement.json +1 -1
  33. package/registry/action-bar.json +1 -1
  34. package/registry/activity-feed.json +1 -1
  35. package/registry/agenda.json +1 -1
  36. package/registry/alert.json +1 -1
  37. package/registry/anatomy-plate.json +1 -1
  38. package/registry/app-header.json +1 -1
  39. package/registry/app-shell.json +1 -1
  40. package/registry/argument-card.json +1 -1
  41. package/registry/audio-player.json +1 -1
  42. package/registry/auth-layout.json +1 -1
  43. package/registry/avatar.json +1 -1
  44. package/registry/badge.json +1 -1
  45. package/registry/bird-plate.json +1 -1
  46. package/registry/button.json +1 -1
  47. package/registry/captcha.json +1 -1
  48. package/registry/card-grid.json +1 -1
  49. package/registry/card.json +1 -1
  50. package/registry/catalogue-page.json +1 -1
  51. package/registry/changelog-page.json +1 -1
  52. package/registry/chat.json +1 -1
  53. package/registry/checkbox.json +1 -1
  54. package/registry/chip-link.json +1 -1
  55. package/registry/chip-row.json +1 -1
  56. package/registry/chip.json +1 -1
  57. package/registry/choice-grid.json +1 -1
  58. package/registry/code-block.json +1 -1
  59. package/registry/combobox.json +1 -1
  60. package/registry/command.json +1 -1
  61. package/registry/comparison-table.json +1 -1
  62. package/registry/component-page.json +1 -1
  63. package/registry/confirm-button.json +1 -1
  64. package/registry/contact-page.json +1 -1
  65. package/registry/continue-prompt.json +1 -1
  66. package/registry/countdown.json +1 -1
  67. package/registry/cover-hero.json +1 -1
  68. package/registry/cta-panel.json +1 -1
  69. package/registry/dashboard-layout.json +1 -1
  70. package/registry/data-table.json +1 -1
  71. package/registry/date-picker.json +2 -2
  72. package/registry/decision-list.json +1 -1
  73. package/registry/description-list.json +1 -1
  74. package/registry/detail-layout.json +1 -1
  75. package/registry/dialog.json +1 -1
  76. package/registry/docs-article-page.json +1 -1
  77. package/registry/docs-hub-page.json +1 -1
  78. package/registry/docs-layout.json +1 -1
  79. package/registry/docs-nav.json +1 -1
  80. package/registry/document-viewer.json +1 -1
  81. package/registry/drop-overlay.json +1 -1
  82. package/registry/dropdown-menu.json +1 -1
  83. package/registry/elephant.json +2 -2
  84. package/registry/empty-state.json +1 -1
  85. package/registry/engine-flow.json +1 -1
  86. package/registry/error-page.json +1 -1
  87. package/registry/examples/glossary/shop-terms.d.ts +4 -0
  88. package/registry/examples/glossary/shop-terms.js +11 -0
  89. package/registry/examples/glossary/shop-terms.tsx +5 -0
  90. package/registry/examples/glossary-term/inline.d.ts +4 -0
  91. package/registry/examples/glossary-term/inline.js +15 -0
  92. package/registry/examples/glossary-term/inline.tsx +5 -0
  93. package/registry/examples/kpi-explained/founder-cockpit.d.ts +4 -0
  94. package/registry/examples/kpi-explained/founder-cockpit.js +11 -0
  95. package/registry/examples/kpi-explained/founder-cockpit.tsx +5 -0
  96. package/registry/examples/kpi-explained/salon-month.d.ts +4 -0
  97. package/registry/examples/kpi-explained/salon-month.js +11 -0
  98. package/registry/examples/kpi-explained/salon-month.tsx +5 -0
  99. package/registry/examples/next-actions/shop-owner.d.ts +4 -0
  100. package/registry/examples/next-actions/shop-owner.js +11 -0
  101. package/registry/examples/next-actions/shop-owner.tsx +5 -0
  102. package/registry/examples/taped-photo/scene.d.ts +4 -0
  103. package/registry/examples/taped-photo/scene.js +25 -0
  104. package/registry/examples/taped-photo/scene.tsx +23 -0
  105. package/registry/examples/taped-photo/top.d.ts +4 -0
  106. package/registry/examples/taped-photo/top.js +11 -0
  107. package/registry/examples/taped-photo/top.tsx +10 -0
  108. package/registry/examples/text-style/compact-toolbar.d.ts +4 -0
  109. package/registry/examples/text-style/compact-toolbar.js +28 -0
  110. package/registry/examples/text-style/compact-toolbar.tsx +21 -0
  111. package/registry/examples/text-style/product-price.d.ts +4 -0
  112. package/registry/examples/text-style/product-price.js +26 -0
  113. package/registry/examples/text-style/product-price.tsx +17 -0
  114. package/registry/examples/text-style/storefront-title.d.ts +4 -0
  115. package/registry/examples/text-style/storefront-title.js +36 -0
  116. package/registry/examples/text-style/storefront-title.tsx +22 -0
  117. package/registry/field.json +1 -1
  118. package/registry/file-upload.json +2 -2
  119. package/registry/filter-bar.json +1 -1
  120. package/registry/flock.json +1 -1
  121. package/registry/footnote.json +1 -1
  122. package/registry/force-update-screen.json +1 -1
  123. package/registry/form.json +2 -2
  124. package/registry/gallery-page.json +1 -1
  125. package/registry/genui.json +2 -2
  126. package/registry/glossary-term.json +144 -0
  127. package/registry/glossary.json +137 -0
  128. package/registry/glow-card.json +1 -1
  129. package/registry/goal-gauge.json +1 -1
  130. package/registry/how-it-works-page.json +1 -1
  131. package/registry/image-cropper.json +1 -1
  132. package/registry/index.json +199 -11
  133. package/registry/iso.json +1 -1
  134. package/registry/kanban.json +1 -1
  135. package/registry/kbd.json +1 -1
  136. package/registry/kpi-explained.json +364 -0
  137. package/registry/landing-page.json +1 -1
  138. package/registry/landscape.json +1 -1
  139. package/registry/language-switch.json +1 -1
  140. package/registry/legal-page.json +1 -1
  141. package/registry/link-card.json +1 -1
  142. package/registry/list.json +1 -1
  143. package/registry/loader.json +1 -1
  144. package/registry/longform-page.json +1 -1
  145. package/registry/maintenance-screen.json +1 -1
  146. package/registry/map.json +2 -2
  147. package/registry/markdown.json +1 -1
  148. package/registry/marketing-layout.json +1 -1
  149. package/registry/marquee.json +1 -1
  150. package/registry/mascot-quote.json +1 -1
  151. package/registry/mascot-state.json +1 -1
  152. package/registry/mascots.json +1 -1
  153. package/registry/match-dialog.json +1 -1
  154. package/registry/media-capture.json +1 -1
  155. package/registry/media-gallery.json +1 -1
  156. package/registry/media-grid.json +1 -1
  157. package/registry/meta-row.json +1 -1
  158. package/registry/meter.json +1 -1
  159. package/registry/nav-bar.json +2 -2
  160. package/registry/next-actions.json +142 -0
  161. package/registry/number-ticker.json +1 -1
  162. package/registry/opening-hours.json +1 -1
  163. package/registry/page-header.json +1 -1
  164. package/registry/page-hero.json +1 -1
  165. package/registry/page-index.json +1 -1
  166. package/registry/page.json +1 -1
  167. package/registry/pagination.json +1 -1
  168. package/registry/photo-grid.json +1 -1
  169. package/registry/pointer-light.json +1 -1
  170. package/registry/popover.json +1 -1
  171. package/registry/pricing-page.json +1 -1
  172. package/registry/product-page.json +1 -1
  173. package/registry/profile-card.json +1 -1
  174. package/registry/progress.json +1 -1
  175. package/registry/promise-card.json +1 -1
  176. package/registry/radio-group.json +1 -1
  177. package/registry/rail-nav.json +2 -2
  178. package/registry/recipes.json +1 -1
  179. package/registry/router.json +1 -1
  180. package/registry/scroll-stage.json +1 -1
  181. package/registry/search-field.json +1 -1
  182. package/registry/section-backdrop.json +1 -1
  183. package/registry/separator.json +1 -1
  184. package/registry/service-card.json +1 -1
  185. package/registry/settings-layout.json +1 -1
  186. package/registry/showcase.json +1 -1
  187. package/registry/site-footer.json +2 -2
  188. package/registry/sites.json +1 -1
  189. package/registry/skeleton.json +1 -1
  190. package/registry/skip-link.json +1 -1
  191. package/registry/slider.json +1 -1
  192. package/registry/slot-picker.json +1 -1
  193. package/registry/slot.json +1 -1
  194. package/registry/specimen-tag.json +1 -1
  195. package/registry/spinner.json +1 -1
  196. package/registry/split-view.json +1 -1
  197. package/registry/stage-banner.json +1 -1
  198. package/registry/stat.json +1 -1
  199. package/registry/status-page.json +1 -1
  200. package/registry/step-progress.json +1 -1
  201. package/registry/step-showcase.json +1 -1
  202. package/registry/stepper.json +1 -1
  203. package/registry/sticky-action.json +1 -1
  204. package/registry/swipe-deck.json +1 -1
  205. package/registry/switch.json +1 -1
  206. package/registry/tabs.json +1 -1
  207. package/registry/tag-input.json +1 -1
  208. package/registry/tag-selector.json +1 -1
  209. package/registry/taped-photo.json +165 -0
  210. package/registry/terminal-replay.json +1 -1
  211. package/registry/text-style.json +378 -0
  212. package/registry/theme.json +1 -1
  213. package/registry/toast.json +1 -1
  214. package/registry/toc.json +1 -1
  215. package/registry/tooltip.json +1 -1
  216. package/registry/tree-view.json +1 -1
  217. package/registry/update-prompt.json +1 -1
  218. package/registry/upload-queue.json +1 -1
  219. package/registry/verified-badge.json +1 -1
  220. package/registry/vertical-video.json +2 -2
  221. package/registry/video-player.json +1 -1
  222. package/registry/video-trimmer.json +1 -1
  223. package/registry/virtual.json +1 -1
  224. package/registry/waveform.json +1 -1
@@ -1,9 +1,9 @@
1
- import {
2
- Facts
3
- } from "./chunk-YKEIOYJ5.js";
4
1
  import {
5
2
  cardHoverClass
6
3
  } from "./chunk-IBDTAMPF.js";
4
+ import {
5
+ Facts
6
+ } from "./chunk-YKEIOYJ5.js";
7
7
  import {
8
8
  BlockLink
9
9
  } from "./chunk-2AGSO3WH.js";
package/dist/blocks.css CHANGED
@@ -140,6 +140,191 @@
140
140
  .kz-heading-actions { grid-column: 1; grid-row: auto; }
141
141
  }
142
142
 
143
+ /* ─── Explained figures, next actions and the host's glossary ─── */
144
+ .kz-kpi,
145
+ .kz-next-actions,
146
+ .kz-glossary {
147
+ min-width: 0;
148
+ color: var(--kz-text-primary);
149
+ }
150
+ .kz-kpi {
151
+ display: grid;
152
+ gap: 12px;
153
+ padding: clamp(16px, 3vw, 24px);
154
+ border: 1px solid var(--kz-border-default);
155
+ border-radius: 8px;
156
+ background: var(--kz-surface-1);
157
+ }
158
+ .kz-kpi-head,
159
+ .kz-next-action-heading {
160
+ display: flex;
161
+ flex-wrap: wrap;
162
+ align-items: center;
163
+ justify-content: space-between;
164
+ gap: 8px 12px;
165
+ }
166
+ .kz-kpi-label,
167
+ .kz-next-actions-title,
168
+ .kz-glossary-title,
169
+ .kz-next-action-heading h3 {
170
+ margin: 0;
171
+ color: var(--kz-text-primary);
172
+ font-size: 1rem;
173
+ font-weight: 650;
174
+ line-height: 1.35;
175
+ }
176
+ .kz-kpi-state,
177
+ .kz-kpi-stale,
178
+ .kz-next-action-urgency {
179
+ display: inline-flex;
180
+ align-items: center;
181
+ min-height: 24px;
182
+ padding: 2px 8px;
183
+ border: 1px solid var(--kz-border-default);
184
+ border-radius: 999px;
185
+ color: var(--kz-text-primary);
186
+ background: var(--kz-surface-2);
187
+ font-size: 0.75rem;
188
+ font-weight: 650;
189
+ line-height: 1.3;
190
+ }
191
+ .kz-kpi-state[data-state="watch"],
192
+ .kz-kpi-stale,
193
+ .kz-next-action-urgency[data-urgency="medium"] {
194
+ border-color: color-mix(in srgb, var(--kz-warning) 38%, var(--kz-border-default));
195
+ background: color-mix(in srgb, var(--kz-warning) 10%, var(--kz-surface-1));
196
+ }
197
+ .kz-kpi-state[data-state="act"],
198
+ .kz-next-action-urgency[data-urgency="high"] {
199
+ border-color: color-mix(in srgb, var(--kz-danger) 38%, var(--kz-border-default));
200
+ background: color-mix(in srgb, var(--kz-danger) 10%, var(--kz-surface-1));
201
+ }
202
+ .kz-next-action-urgency[data-urgency="low"] {
203
+ border-color: color-mix(in srgb, var(--kz-success) 38%, var(--kz-border-default));
204
+ background: color-mix(in srgb, var(--kz-success) 10%, var(--kz-surface-1));
205
+ }
206
+ .kz-kpi-value {
207
+ margin: 0;
208
+ overflow-wrap: anywhere;
209
+ color: var(--kz-text-primary);
210
+ font-family: var(--kz-font-display);
211
+ font-size: clamp(1.75rem, 5vw, 2.5rem);
212
+ font-variant-numeric: var(--kz-figures, tabular-nums);
213
+ font-weight: 700;
214
+ line-height: 1.15;
215
+ }
216
+ .kz-kpi-meaning,
217
+ .kz-next-action-copy p {
218
+ margin: 0;
219
+ color: var(--kz-text-secondary);
220
+ font-size: 0.875rem;
221
+ line-height: 1.55;
222
+ }
223
+ .kz-kpi-details {
224
+ display: grid;
225
+ grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr));
226
+ gap: 12px 20px;
227
+ margin: 0;
228
+ }
229
+ .kz-kpi-details > div { min-width: 0; }
230
+ .kz-kpi-details dt {
231
+ margin-bottom: 3px;
232
+ color: var(--kz-text-secondary);
233
+ font-size: 0.75rem;
234
+ font-weight: 650;
235
+ }
236
+ .kz-kpi-details dd {
237
+ margin: 0;
238
+ overflow-wrap: anywhere;
239
+ color: var(--kz-text-primary);
240
+ font-size: 0.875rem;
241
+ line-height: 1.5;
242
+ }
243
+ .kz-kpi-verify { display: inline-flex; margin-inline-start: 10px; }
244
+ .kz-kpi-freshness {
245
+ display: flex;
246
+ flex-wrap: wrap;
247
+ align-items: center;
248
+ gap: 6px 10px;
249
+ margin: 0;
250
+ color: var(--kz-text-secondary);
251
+ font-size: 0.75rem;
252
+ }
253
+ .kz-kpi-sparkline { min-width: 0; }
254
+ .kz-next-actions,
255
+ .kz-glossary {
256
+ display: grid;
257
+ gap: 16px;
258
+ }
259
+ .kz-next-actions-list {
260
+ display: grid;
261
+ gap: 10px;
262
+ margin: 0;
263
+ padding: 0;
264
+ list-style: none;
265
+ }
266
+ .kz-next-action {
267
+ display: grid;
268
+ grid-template-columns: auto minmax(0, 1fr);
269
+ align-items: start;
270
+ gap: 12px;
271
+ min-width: 0;
272
+ padding: 14px 16px;
273
+ border: 1px solid var(--kz-border-default);
274
+ border-radius: 8px;
275
+ background: var(--kz-surface-1);
276
+ }
277
+ .kz-next-action-rank { color: var(--kz-text-secondary); font-weight: 650; font-variant-numeric: var(--kz-figures, lining-nums tabular-nums); }
278
+ .kz-next-action-content {
279
+ display: grid;
280
+ grid-template-columns: minmax(0, 1fr) auto;
281
+ align-items: center;
282
+ gap: 12px 20px;
283
+ min-width: 0;
284
+ }
285
+ .kz-next-action-copy { display: grid; min-width: 0; gap: 5px; }
286
+ .kz-next-action-control { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
287
+ .kz-glossary-list { display: grid; gap: 12px; margin: 0; }
288
+ .kz-glossary-entry {
289
+ display: grid;
290
+ grid-template-columns: minmax(8rem, 1fr) minmax(0, 3fr);
291
+ gap: 8px 20px;
292
+ padding-block: 12px;
293
+ border-bottom: 1px solid var(--kz-border-subtle);
294
+ }
295
+ .kz-glossary-entry dt { color: var(--kz-text-primary); font-weight: 650; }
296
+ .kz-glossary-entry dd { margin: 0; color: var(--kz-text-secondary); line-height: 1.55; }
297
+ .kz-glossary-term {
298
+ border-radius: 2px;
299
+ color: inherit;
300
+ font-style: inherit;
301
+ text-decoration-line: underline;
302
+ text-decoration-color: var(--kz-accent);
303
+ text-decoration-style: dotted;
304
+ text-underline-offset: 0.2em;
305
+ cursor: help;
306
+ }
307
+ .kz-glossary-term:focus-visible {
308
+ outline: 2px solid var(--kz-ring, var(--kz-accent));
309
+ outline-offset: 3px;
310
+ }
311
+ @media (max-width: 520px) {
312
+ .kz-next-action-content { grid-template-columns: minmax(0, 1fr); }
313
+ .kz-glossary-entry { grid-template-columns: minmax(0, 1fr); gap: 4px; }
314
+ }
315
+ @media (prefers-reduced-motion: reduce) {
316
+ .kz-kpi, .kz-next-action, .kz-glossary-entry, .kz-glossary-term { animation: none; scroll-behavior: auto; transition: none; }
317
+ }
318
+ @media print {
319
+ .kz-kpi, .kz-next-actions, .kz-glossary, .kz-next-action, .kz-glossary-entry {
320
+ break-inside: avoid;
321
+ box-shadow: none;
322
+ background: transparent;
323
+ }
324
+ .kz-kpi, .kz-next-action, .kz-glossary-entry { border-color: currentColor; }
325
+ .kz-kpi-stale, .kz-kpi-state, .kz-next-action-urgency { border-color: currentColor; }
326
+ }
327
+
143
328
  /* Ticks: a word between backticks in a sentence reads as code. */
144
329
  .kz-ic {
145
330
  padding: 0.08em 0.38em;
@@ -979,6 +1164,30 @@ a.kz-fact:focus-visible { outline: 2px solid var(--kz-ring, var(--kz-accent)); o
979
1164
  .kz-tag .kz-stamp[data-tone="construction"] { --kz-stamp-ink: color-mix(in oklab, var(--kz-paper-rule-margin) 72%, var(--kz-paper-tag-ink)); }
980
1165
 
981
1166
  /* BirdPlate and AnatomyPlate — a sheet of the field guide. */
1167
+ /* ─── The taped photo (ADR-004): a print stuck in the notebook — tilted (`--kz-taped-tilt`, eased on a phone), a thin warm
1168
+ print border, a layered paper shadow (hard offsets, no blur — the Cahier's rule), tape at two opposite corners or one strip at the top. The print stays
1169
+ paper in the dark too (a photo is a photo), a shade dimmer. Transform only: the picture keeps its box, nothing shifts. ─── */
1170
+ .kz-taped { position: relative; margin: 0; --kz-print: hsl(44 30% 96%); --kz-print-ink: hsl(215 35% 22%); --kz-tape: hsl(46 58% 82% / 0.72);
1171
+ --kz-tape-w: clamp(54px, 8vw, 92px); --kz-tape-h: clamp(17px, 2.4vw, 26px);
1172
+ padding: clamp(7px, 1.2vw, 14px); background: var(--kz-print); transform: rotate(var(--kz-taped-tilt, -1.6deg)); transform-origin: 50% 60%;
1173
+ box-shadow: 0 1px 0 hsl(30 20% 8% / 0.22), 2px 4px 0 hsl(30 20% 8% / 0.14), 4px 8px 0 -2px hsl(30 20% 8% / 0.08); }
1174
+ :root:not(.light) .kz-taped { --kz-print: hsl(42 22% 88%); --kz-tape: hsl(46 40% 70% / 0.62); }
1175
+ .kz-taped::before, .kz-taped::after { content: ""; position: absolute; z-index: 1; width: var(--kz-tape-w); height: var(--kz-tape-h); background: var(--kz-tape);
1176
+ box-shadow: 0 1px 0 hsl(30 20% 8% / 0.2); pointer-events: none;
1177
+ clip-path: polygon(0 8%, 4% 0, 8% 10%, 12% 0, 100% 0, 96% 25%, 100% 50%, 96% 75%, 100% 100%, 12% 100%, 8% 90%, 4% 100%, 0 92%); }
1178
+ .kz-taped::before { top: calc(-0.55 * var(--kz-tape-h)); left: calc(-0.35 * var(--kz-tape-w)); transform: rotate(-34deg); }
1179
+ .kz-taped::after { bottom: calc(-0.55 * var(--kz-tape-h)); right: calc(-0.35 * var(--kz-tape-w)); transform: rotate(-34deg); }
1180
+ .kz-taped[data-tape="top"]::before { top: calc(-0.5 * var(--kz-tape-h)); left: calc(50% - var(--kz-tape-w) / 2); transform: rotate(-3deg); }
1181
+ .kz-taped[data-tape="top"]::after, .kz-taped[data-tape="none"]::before, .kz-taped[data-tape="none"]::after { display: none; }
1182
+ .kz-taped-picture { position: relative; overflow: hidden; }
1183
+ .kz-taped-picture > img, .kz-taped-picture > video { display: block; width: 100%; height: auto; }
1184
+ .kz-taped-caption { margin: 0; padding: 10px 4px 2px; font-family: var(--kz-font-mono); font-size: 13px; line-height: 20px; color: var(--kz-print-ink); }
1185
+ @media (max-width: 640px) {
1186
+ .kz-taped { transform: rotate(calc(var(--kz-taped-tilt, -1.6deg) * 0.6)); }
1187
+ .kz-taped::before { left: -4px; } .kz-taped::after { right: -4px; }
1188
+ .kz-taped[data-tape="top"]::before { left: calc(50% - var(--kz-tape-w) / 2); }
1189
+ }
1190
+
982
1191
  .kz-plate, .kz-anatomy {
983
1192
  margin: 0;
984
1193
  padding: 20px 24px 24px;
@@ -0,0 +1,45 @@
1
+ "use client";
2
+ import {
3
+ floating
4
+ } from "./chunk-J3NC6ER4.js";
5
+ import {
6
+ cn
7
+ } from "./chunk-NSLXEDIS.js";
8
+
9
+ // src/tooltip/tooltip.tsx
10
+ import { Tooltip as TooltipPrimitive } from "radix-ui";
11
+ import { jsx, jsxs } from "react/jsx-runtime";
12
+ var TooltipProvider = TooltipPrimitive.Provider;
13
+ function Tooltip({
14
+ content,
15
+ children,
16
+ open,
17
+ defaultOpen,
18
+ onOpenChange,
19
+ delayDuration = 300,
20
+ container,
21
+ sideOffset = 6,
22
+ collisionPadding = 8,
23
+ className,
24
+ ...props
25
+ }) {
26
+ return /* @__PURE__ */ jsx(TooltipPrimitive.Provider, { delayDuration, children: /* @__PURE__ */ jsxs(TooltipPrimitive.Root, { open, defaultOpen, onOpenChange, children: [
27
+ /* @__PURE__ */ jsx(TooltipPrimitive.Trigger, { asChild: true, children }),
28
+ /* @__PURE__ */ jsx(TooltipPrimitive.Portal, { container, children: /* @__PURE__ */ jsx(
29
+ TooltipPrimitive.Content,
30
+ {
31
+ sideOffset,
32
+ collisionPadding,
33
+ className: cn(floating, "max-w-xs px-2.5 py-1.5 text-xs font-medium origin-(--radix-tooltip-content-transform-origin)", className),
34
+ ...props,
35
+ children: content
36
+ }
37
+ ) })
38
+ ] }) });
39
+ }
40
+
41
+ export {
42
+ TooltipProvider,
43
+ Tooltip
44
+ };
45
+ //# sourceMappingURL=chunk-YATTFMDV.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/tooltip/tooltip.tsx"],"sourcesContent":["// Client (a portal). A short label for a control, on hover after `delayDuration` and on keyboard focus at once;\n// Escape dismisses it. It names nothing: the control keeps its own accessible name (an IconButton's `label`).\nimport { Tooltip as TooltipPrimitive } from \"radix-ui\";\nimport type * as React from \"react\";\n\nimport { cn } from \"../cn\";\nimport { floating } from \"../floating\";\n\n/** Optional, once near the root: shares `delayDuration` and the skip delay between tooltips. */\nexport const TooltipProvider = TooltipPrimitive.Provider;\n\nexport type TooltipProps = Omit<React.ComponentProps<typeof TooltipPrimitive.Content>, \"content\" | \"children\"> & {\n /** What the tooltip says — passed translated. */\n content: React.ReactNode;\n /** The trigger, rendered as is (`asChild`): a focusable element. */\n children: React.ReactNode;\n /** Open or closed (controlled), with `onOpenChange`. */\n open?: boolean;\n /** Open at first, uncontrolled. */\n defaultOpen?: boolean;\n /** Called when it opens or closes. */\n onOpenChange?: (open: boolean) => void;\n /** Hover delay in ms before it opens (300 by default). */\n delayDuration?: number;\n /** The element the portal renders into (default: document.body). */\n container?: HTMLElement | null;\n};\n\nexport function Tooltip({\n content,\n children,\n open,\n defaultOpen,\n onOpenChange,\n delayDuration = 300,\n container,\n sideOffset = 6,\n collisionPadding = 8,\n className,\n ...props\n}: TooltipProps) {\n return (\n <TooltipPrimitive.Provider delayDuration={delayDuration}>\n <TooltipPrimitive.Root open={open} defaultOpen={defaultOpen} onOpenChange={onOpenChange}>\n <TooltipPrimitive.Trigger asChild>{children}</TooltipPrimitive.Trigger>\n <TooltipPrimitive.Portal container={container}>\n <TooltipPrimitive.Content\n sideOffset={sideOffset}\n collisionPadding={collisionPadding}\n className={cn(floating, \"max-w-xs px-2.5 py-1.5 text-xs font-medium origin-(--radix-tooltip-content-transform-origin)\", className)}\n {...props}\n >\n {content}\n </TooltipPrimitive.Content>\n </TooltipPrimitive.Portal>\n </TooltipPrimitive.Root>\n </TooltipPrimitive.Provider>\n );\n}\n"],"mappings":";;;;;;;;;AAEA,SAAS,WAAW,wBAAwB;AAyCtC,SACE,KADF;AAlCC,IAAM,kBAAkB,iBAAiB;AAmBzC,SAAS,QAAQ;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,gBAAgB;AAAA,EAChB;AAAA,EACA,aAAa;AAAA,EACb,mBAAmB;AAAA,EACnB;AAAA,EACA,GAAG;AACL,GAAiB;AACf,SACE,oBAAC,iBAAiB,UAAjB,EAA0B,eACzB,+BAAC,iBAAiB,MAAjB,EAAsB,MAAY,aAA0B,cAC3D;AAAA,wBAAC,iBAAiB,SAAjB,EAAyB,SAAO,MAAE,UAAS;AAAA,IAC5C,oBAAC,iBAAiB,QAAjB,EAAwB,WACvB;AAAA,MAAC,iBAAiB;AAAA,MAAjB;AAAA,QACC;AAAA,QACA;AAAA,QACA,WAAW,GAAG,UAAU,gGAAgG,SAAS;AAAA,QAChI,GAAG;AAAA,QAEH;AAAA;AAAA,IACH,GACF;AAAA,KACF,GACF;AAEJ;","names":[]}
@@ -0,0 +1,12 @@
1
+ import * as React from 'react';
2
+
3
+ interface GlossaryTermProps {
4
+ /** The word in the host's glossary. */
5
+ term: string;
6
+ /** The host's definition. */
7
+ definition: React.ReactNode;
8
+ }
9
+ /** An underlined glossary word with a keyboard- and screen-reader-accessible definition tooltip. */
10
+ declare function GlossaryTerm({ term, definition }: GlossaryTermProps): React.JSX.Element;
11
+
12
+ export { GlossaryTerm, type GlossaryTermProps };
@@ -0,0 +1,16 @@
1
+ "use client";
2
+ import {
3
+ Tooltip
4
+ } from "./chunk-YATTFMDV.js";
5
+ import "./chunk-J3NC6ER4.js";
6
+ import "./chunk-NSLXEDIS.js";
7
+
8
+ // src/glossary-term/glossary-term.tsx
9
+ import { jsx } from "react/jsx-runtime";
10
+ function GlossaryTerm({ term, definition }) {
11
+ return /* @__PURE__ */ jsx(Tooltip, { content: definition, children: /* @__PURE__ */ jsx("dfn", { tabIndex: 0, className: "kz-glossary-term", children: term }) });
12
+ }
13
+ export {
14
+ GlossaryTerm
15
+ };
16
+ //# sourceMappingURL=glossary-term.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/glossary-term/glossary-term.tsx"],"sourcesContent":["// Client (Radix Tooltip): an inline term whose definition is available on keyboard focus as well as hover.\nimport type * as React from \"react\";\n\nimport { Tooltip } from \"../tooltip\";\n\nexport interface GlossaryTermProps {\n /** The word in the host's glossary. */\n term: string;\n /** The host's definition. */\n definition: React.ReactNode;\n}\n\n/** An underlined glossary word with a keyboard- and screen-reader-accessible definition tooltip. */\nexport function GlossaryTerm({ term, definition }: GlossaryTermProps) {\n return (\n <Tooltip content={definition}>\n <dfn tabIndex={0} className=\"kz-glossary-term\">{term}</dfn>\n </Tooltip>\n );\n}\n"],"mappings":";;;;;;;;AAgBM;AAHC,SAAS,aAAa,EAAE,MAAM,WAAW,GAAsB;AACpE,SACE,oBAAC,WAAQ,SAAS,YAChB,8BAAC,SAAI,UAAU,GAAG,WAAU,oBAAoB,gBAAK,GACvD;AAEJ;","names":[]}
@@ -0,0 +1,20 @@
1
+ import * as React from 'react';
2
+
3
+ interface GlossaryEntry {
4
+ /** A stable key supplied by the host. */
5
+ id: string;
6
+ /** The term in the host's glossary. */
7
+ term: React.ReactNode;
8
+ /** The host's definition. */
9
+ definition: React.ReactNode;
10
+ }
11
+ interface GlossaryProps extends Omit<React.ComponentProps<"section">, "children" | "title"> {
12
+ /** The section's visible heading. */
13
+ title: React.ReactNode;
14
+ /** The terms and definitions from the host's catalogue, in the desired reading order. */
15
+ terms: readonly GlossaryEntry[];
16
+ }
17
+ /** A page or panel listing the terms and definitions from the host's glossary catalogue. */
18
+ declare function Glossary({ title, terms, className, ...props }: GlossaryProps): React.JSX.Element;
19
+
20
+ export { Glossary, type GlossaryEntry, type GlossaryProps };
@@ -0,0 +1,17 @@
1
+ // src/glossary/glossary.tsx
2
+ import * as React from "react";
3
+ import { jsx, jsxs } from "react/jsx-runtime";
4
+ function Glossary({ title, terms, className, ...props }) {
5
+ const id = React.useId();
6
+ return /* @__PURE__ */ jsxs("section", { "aria-labelledby": `${id}-title`, className: ["kz-glossary", className].filter(Boolean).join(" "), ...props, children: [
7
+ /* @__PURE__ */ jsx("h2", { id: `${id}-title`, className: "kz-glossary-title", children: title }),
8
+ /* @__PURE__ */ jsx("dl", { className: "kz-glossary-list", children: terms.map(({ id: termId, term, definition }) => /* @__PURE__ */ jsxs("div", { className: "kz-glossary-entry", children: [
9
+ /* @__PURE__ */ jsx("dt", { children: term }),
10
+ /* @__PURE__ */ jsx("dd", { children: definition })
11
+ ] }, termId)) })
12
+ ] });
13
+ }
14
+ export {
15
+ Glossary
16
+ };
17
+ //# sourceMappingURL=glossary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/glossary/glossary.tsx"],"sourcesContent":["// Server-safe. The full list from the host's glossary catalogue.\nimport * as React from \"react\";\n\nexport interface GlossaryEntry {\n /** A stable key supplied by the host. */\n id: string;\n /** The term in the host's glossary. */\n term: React.ReactNode;\n /** The host's definition. */\n definition: React.ReactNode;\n}\n\nexport interface GlossaryProps extends Omit<React.ComponentProps<\"section\">, \"children\" | \"title\"> {\n /** The section's visible heading. */\n title: React.ReactNode;\n /** The terms and definitions from the host's catalogue, in the desired reading order. */\n terms: readonly GlossaryEntry[];\n}\n\n/** A page or panel listing the terms and definitions from the host's glossary catalogue. */\nexport function Glossary({ title, terms, className, ...props }: GlossaryProps) {\n const id = React.useId();\n return (\n <section aria-labelledby={`${id}-title`} className={[\"kz-glossary\", className].filter(Boolean).join(\" \")} {...props}>\n <h2 id={`${id}-title`} className=\"kz-glossary-title\">{title}</h2>\n <dl className=\"kz-glossary-list\">\n {terms.map(({ id: termId, term, definition }) => (\n <div className=\"kz-glossary-entry\" key={termId}>\n <dt>{term}</dt>\n <dd>{definition}</dd>\n </div>\n ))}\n </dl>\n </section>\n );\n}\n"],"mappings":";AACA,YAAY,WAAW;AAuBjB,cAGI,YAHJ;AAJC,SAAS,SAAS,EAAE,OAAO,OAAO,WAAW,GAAG,MAAM,GAAkB;AAC7E,QAAM,KAAW,YAAM;AACvB,SACE,qBAAC,aAAQ,mBAAiB,GAAG,EAAE,UAAU,WAAW,CAAC,eAAe,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAI,GAAG,OAC5G;AAAA,wBAAC,QAAG,IAAI,GAAG,EAAE,UAAU,WAAU,qBAAqB,iBAAM;AAAA,IAC5D,oBAAC,QAAG,WAAU,oBACX,gBAAM,IAAI,CAAC,EAAE,IAAI,QAAQ,MAAM,WAAW,MACzC,qBAAC,SAAI,WAAU,qBACb;AAAA,0BAAC,QAAI,gBAAK;AAAA,MACV,oBAAC,QAAI,sBAAW;AAAA,SAFsB,MAGxC,CACD,GACH;AAAA,KACF;AAEJ;","names":[]}
package/dist/index.js CHANGED
@@ -1,11 +1,4 @@
1
1
  "use client";
2
- import {
3
- cx
4
- } from "./chunk-6ISW63JI.js";
5
- import {
6
- MotionObserver,
7
- RotatingWord
8
- } from "./chunk-4JO5GSSD.js";
9
2
  import {
10
3
  AkinazaLogo,
11
4
  KachizakaLogo,
@@ -21,6 +14,13 @@ import {
21
14
  neutral,
22
15
  useIds
23
16
  } from "./chunk-4E5IUZHR.js";
17
+ import {
18
+ cx
19
+ } from "./chunk-6ISW63JI.js";
20
+ import {
21
+ MotionObserver,
22
+ RotatingWord
23
+ } from "./chunk-4JO5GSSD.js";
24
24
 
25
25
  // src/marks/wu-sama-geometry.ts
26
26
  import { marks } from "@krizaka/tokens/native";
@@ -0,0 +1,66 @@
1
+ import { Locale, DateInput } from '@krizaka/intl';
2
+ import * as React from 'react';
3
+
4
+ type KpiNumberOptions = Omit<Intl.NumberFormatOptions, "style" | "currency" | "currencyDisplay">;
5
+ type KpiFormat = {
6
+ type: "money";
7
+ currency: string;
8
+ minorUnitDigits?: number;
9
+ } | {
10
+ type: "number";
11
+ options?: KpiNumberOptions;
12
+ } | {
13
+ type: "percent";
14
+ options?: KpiNumberOptions;
15
+ };
16
+ type KpiState = "ok" | "watch" | "act";
17
+ interface KpiExplainedProps extends Omit<React.ComponentProps<"article">, "children"> {
18
+ /** The figure's name. */
19
+ label: React.ReactNode;
20
+ /** The raw number: money is integer minor units; percentages are ratios such as 0.125. */
21
+ value: number;
22
+ /** How to format the value with `@krizaka/intl`. */
23
+ format: KpiFormat;
24
+ /** The app's locale, e.g. `fr-CA`. */
25
+ locale: Locale;
26
+ /** The IANA time zone for freshness dates; defaults to UTC for deterministic rendering. */
27
+ timeZone?: string;
28
+ /** One plain-language sentence about what the figure means. */
29
+ meaning: string;
30
+ /** The localized label for the formula row. */
31
+ formulaLabel: React.ReactNode;
32
+ /** The calculation in words, e.g. “dépenses TTC ÷ ventes TTC”. */
33
+ formula: string;
34
+ /** The localized label for the source row. */
35
+ sourceLabel: React.ReactNode;
36
+ /** The source link or file name, supplied by the host. */
37
+ source: React.ReactNode;
38
+ /** A host-provided action such as “Verify”, next to the source. */
39
+ verify?: React.ReactNode;
40
+ /** Host-provided thresholds in the same units as `value`. */
41
+ thresholds: {
42
+ direction: "above" | "below";
43
+ watchAt: number;
44
+ actAt: number;
45
+ };
46
+ /** Host-provided words for the derived state. */
47
+ stateLabels: Record<KpiState, React.ReactNode>;
48
+ /** Reading time and the expected next reading time (the host derives it from its cadence). */
49
+ freshness: {
50
+ lastRead: DateInput;
51
+ expectedAt: DateInput;
52
+ now: DateInput;
53
+ lastReadLabel: React.ReactNode;
54
+ staleLabel: React.ReactNode;
55
+ };
56
+ /** An optional Sparkline from `@krizaka/charts`, with its own accessible summary. */
57
+ sparkline?: React.ReactNode;
58
+ /** Replace every non-space character in the value while preserving its formatted shape. */
59
+ masked?: boolean;
60
+ /** The accessible name shown instead of the value when masked. */
61
+ maskedLabel: string;
62
+ }
63
+ /** A key figure that explains what it means, how it is calculated and where it came from. */
64
+ declare function KpiExplained({ label, value, format, locale, timeZone, meaning, formulaLabel, formula, sourceLabel, source, verify, thresholds, stateLabels, freshness, sparkline, masked, maskedLabel, className, ...props }: KpiExplainedProps): React.JSX.Element;
65
+
66
+ export { KpiExplained, type KpiExplainedProps, type KpiFormat, type KpiNumberOptions, type KpiState };
@@ -0,0 +1,84 @@
1
+ // src/kpi-explained/kpi-explained.tsx
2
+ import { formatDate, formatMoney, formatNumber, formatPercent } from "@krizaka/intl";
3
+ import * as React from "react";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
+ function formatValue(value, format, locale) {
6
+ switch (format.type) {
7
+ case "money":
8
+ return formatMoney(value, { currency: format.currency, locale, minorUnitDigits: format.minorUnitDigits });
9
+ case "percent":
10
+ return formatPercent(value, { locale, ...format.options });
11
+ case "number":
12
+ return formatNumber(value, { locale, ...format.options });
13
+ }
14
+ }
15
+ function stateFor(value, thresholds) {
16
+ if (thresholds.direction === "above") {
17
+ return value >= thresholds.actAt ? "act" : value >= thresholds.watchAt ? "watch" : "ok";
18
+ }
19
+ return value <= thresholds.actAt ? "act" : value <= thresholds.watchAt ? "watch" : "ok";
20
+ }
21
+ function maskValue(value) {
22
+ return value.replace(/[^\s]/gu, "\u2022");
23
+ }
24
+ function KpiExplained({
25
+ label,
26
+ value,
27
+ format,
28
+ locale,
29
+ timeZone = "UTC",
30
+ meaning,
31
+ formulaLabel,
32
+ formula,
33
+ sourceLabel,
34
+ source,
35
+ verify,
36
+ thresholds,
37
+ stateLabels,
38
+ freshness,
39
+ sparkline,
40
+ masked = false,
41
+ maskedLabel,
42
+ className,
43
+ ...props
44
+ }) {
45
+ const id = React.useId();
46
+ const state = stateFor(value, thresholds);
47
+ const formattedValue = formatValue(value, format, locale);
48
+ const lastRead = new Date(freshness.lastRead);
49
+ const stale = new Date(freshness.now) >= new Date(freshness.expectedAt);
50
+ return /* @__PURE__ */ jsxs("article", { "aria-labelledby": `${id}-label`, className: ["kz-kpi", className].filter(Boolean).join(" "), "data-state": state, ...props, children: [
51
+ /* @__PURE__ */ jsxs("header", { className: "kz-kpi-head", children: [
52
+ /* @__PURE__ */ jsx("h3", { id: `${id}-label`, className: "kz-kpi-label", children: label }),
53
+ /* @__PURE__ */ jsx("span", { className: "kz-kpi-state", "data-state": state, children: stateLabels[state] })
54
+ ] }),
55
+ /* @__PURE__ */ jsx("p", { className: "kz-kpi-value", children: masked ? /* @__PURE__ */ jsx("span", { role: "img", "aria-label": maskedLabel, children: maskValue(formattedValue) }) : formattedValue }),
56
+ /* @__PURE__ */ jsx("p", { className: "kz-kpi-meaning", children: meaning }),
57
+ /* @__PURE__ */ jsxs("dl", { className: "kz-kpi-details", children: [
58
+ /* @__PURE__ */ jsxs("div", { children: [
59
+ /* @__PURE__ */ jsx("dt", { children: formulaLabel }),
60
+ /* @__PURE__ */ jsx("dd", { children: formula })
61
+ ] }),
62
+ /* @__PURE__ */ jsxs("div", { children: [
63
+ /* @__PURE__ */ jsx("dt", { children: sourceLabel }),
64
+ /* @__PURE__ */ jsxs("dd", { children: [
65
+ source,
66
+ verify ? /* @__PURE__ */ jsx("span", { className: "kz-kpi-verify", children: verify }) : null
67
+ ] })
68
+ ] })
69
+ ] }),
70
+ /* @__PURE__ */ jsxs("p", { className: "kz-kpi-freshness", children: [
71
+ /* @__PURE__ */ jsxs("span", { children: [
72
+ freshness.lastReadLabel,
73
+ ": "
74
+ ] }),
75
+ /* @__PURE__ */ jsx("time", { dateTime: lastRead.toISOString(), children: formatDate(lastRead, { locale, style: "medium", timeStyle: "short", timeZone }) }),
76
+ stale ? /* @__PURE__ */ jsx("span", { className: "kz-kpi-stale", role: "status", children: freshness.staleLabel }) : null
77
+ ] }),
78
+ sparkline ? /* @__PURE__ */ jsx("div", { className: "kz-kpi-sparkline", children: sparkline }) : null
79
+ ] });
80
+ }
81
+ export {
82
+ KpiExplained
83
+ };
84
+ //# sourceMappingURL=kpi-explained.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/kpi-explained/kpi-explained.tsx"],"sourcesContent":["// Server-safe. A figure whose meaning, formula, source and freshness travel with its value.\nimport { type DateInput, formatDate, formatMoney, formatNumber, formatPercent, type Locale } from \"@krizaka/intl\";\nimport * as React from \"react\";\n\nexport type KpiNumberOptions = Omit<Intl.NumberFormatOptions, \"style\" | \"currency\" | \"currencyDisplay\">;\n\nexport type KpiFormat =\n | { type: \"money\"; currency: string; minorUnitDigits?: number }\n | { type: \"number\"; options?: KpiNumberOptions }\n | { type: \"percent\"; options?: KpiNumberOptions };\n\nexport type KpiState = \"ok\" | \"watch\" | \"act\";\n\nexport interface KpiExplainedProps extends Omit<React.ComponentProps<\"article\">, \"children\"> {\n /** The figure's name. */\n label: React.ReactNode;\n /** The raw number: money is integer minor units; percentages are ratios such as 0.125. */\n value: number;\n /** How to format the value with `@krizaka/intl`. */\n format: KpiFormat;\n /** The app's locale, e.g. `fr-CA`. */\n locale: Locale;\n /** The IANA time zone for freshness dates; defaults to UTC for deterministic rendering. */\n timeZone?: string;\n /** One plain-language sentence about what the figure means. */\n meaning: string;\n /** The localized label for the formula row. */\n formulaLabel: React.ReactNode;\n /** The calculation in words, e.g. “dépenses TTC ÷ ventes TTC”. */\n formula: string;\n /** The localized label for the source row. */\n sourceLabel: React.ReactNode;\n /** The source link or file name, supplied by the host. */\n source: React.ReactNode;\n /** A host-provided action such as “Verify”, next to the source. */\n verify?: React.ReactNode;\n /** Host-provided thresholds in the same units as `value`. */\n thresholds: {\n direction: \"above\" | \"below\";\n watchAt: number;\n actAt: number;\n };\n /** Host-provided words for the derived state. */\n stateLabels: Record<KpiState, React.ReactNode>;\n /** Reading time and the expected next reading time (the host derives it from its cadence). */\n freshness: {\n lastRead: DateInput;\n expectedAt: DateInput;\n now: DateInput;\n lastReadLabel: React.ReactNode;\n staleLabel: React.ReactNode;\n };\n /** An optional Sparkline from `@krizaka/charts`, with its own accessible summary. */\n sparkline?: React.ReactNode;\n /** Replace every non-space character in the value while preserving its formatted shape. */\n masked?: boolean;\n /** The accessible name shown instead of the value when masked. */\n maskedLabel: string;\n}\n\nfunction formatValue(value: number, format: KpiFormat, locale: Locale): string {\n switch (format.type) {\n case \"money\":\n return formatMoney(value, { currency: format.currency, locale, minorUnitDigits: format.minorUnitDigits });\n case \"percent\":\n return formatPercent(value, { locale, ...format.options });\n case \"number\":\n return formatNumber(value, { locale, ...format.options });\n }\n}\n\nfunction stateFor(value: number, thresholds: KpiExplainedProps[\"thresholds\"]): KpiState {\n if (thresholds.direction === \"above\") {\n return value >= thresholds.actAt ? \"act\" : value >= thresholds.watchAt ? \"watch\" : \"ok\";\n }\n return value <= thresholds.actAt ? \"act\" : value <= thresholds.watchAt ? \"watch\" : \"ok\";\n}\n\nfunction maskValue(value: string): string {\n return value.replace(/[^\\s]/gu, \"•\");\n}\n\n/** A key figure that explains what it means, how it is calculated and where it came from. */\nexport function KpiExplained({\n label,\n value,\n format,\n locale,\n timeZone = \"UTC\",\n meaning,\n formulaLabel,\n formula,\n sourceLabel,\n source,\n verify,\n thresholds,\n stateLabels,\n freshness,\n sparkline,\n masked = false,\n maskedLabel,\n className,\n ...props\n}: KpiExplainedProps) {\n const id = React.useId();\n const state = stateFor(value, thresholds);\n const formattedValue = formatValue(value, format, locale);\n const lastRead = new Date(freshness.lastRead);\n const stale = new Date(freshness.now) >= new Date(freshness.expectedAt);\n\n return (\n <article aria-labelledby={`${id}-label`} className={[\"kz-kpi\", className].filter(Boolean).join(\" \")} data-state={state} {...props}>\n <header className=\"kz-kpi-head\">\n <h3 id={`${id}-label`} className=\"kz-kpi-label\">{label}</h3>\n <span className=\"kz-kpi-state\" data-state={state}>{stateLabels[state]}</span>\n </header>\n <p className=\"kz-kpi-value\">\n {masked ? <span role=\"img\" aria-label={maskedLabel}>{maskValue(formattedValue)}</span> : formattedValue}\n </p>\n <p className=\"kz-kpi-meaning\">{meaning}</p>\n <dl className=\"kz-kpi-details\">\n <div><dt>{formulaLabel}</dt><dd>{formula}</dd></div>\n <div><dt>{sourceLabel}</dt><dd>{source}{verify ? <span className=\"kz-kpi-verify\">{verify}</span> : null}</dd></div>\n </dl>\n <p className=\"kz-kpi-freshness\">\n <span>{freshness.lastReadLabel}: </span>\n <time dateTime={lastRead.toISOString()}>{formatDate(lastRead, { locale, style: \"medium\", timeStyle: \"short\", timeZone })}</time>\n {stale ? <span className=\"kz-kpi-stale\" role=\"status\">{freshness.staleLabel}</span> : null}\n </p>\n {sparkline ? <div className=\"kz-kpi-sparkline\">{sparkline}</div> : null}\n </article>\n );\n}\n"],"mappings":";AACA,SAAyB,YAAY,aAAa,cAAc,qBAAkC;AAClG,YAAY,WAAW;AA8GjB,SACE,KADF;AApDN,SAAS,YAAY,OAAe,QAAmB,QAAwB;AAC7E,UAAQ,OAAO,MAAM;AAAA,IACnB,KAAK;AACH,aAAO,YAAY,OAAO,EAAE,UAAU,OAAO,UAAU,QAAQ,iBAAiB,OAAO,gBAAgB,CAAC;AAAA,IAC1G,KAAK;AACH,aAAO,cAAc,OAAO,EAAE,QAAQ,GAAG,OAAO,QAAQ,CAAC;AAAA,IAC3D,KAAK;AACH,aAAO,aAAa,OAAO,EAAE,QAAQ,GAAG,OAAO,QAAQ,CAAC;AAAA,EAC5D;AACF;AAEA,SAAS,SAAS,OAAe,YAAuD;AACtF,MAAI,WAAW,cAAc,SAAS;AACpC,WAAO,SAAS,WAAW,QAAQ,QAAQ,SAAS,WAAW,UAAU,UAAU;AAAA,EACrF;AACA,SAAO,SAAS,WAAW,QAAQ,QAAQ,SAAS,WAAW,UAAU,UAAU;AACrF;AAEA,SAAS,UAAU,OAAuB;AACxC,SAAO,MAAM,QAAQ,WAAW,QAAG;AACrC;AAGO,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,SAAS;AAAA,EACT;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAsB;AACpB,QAAM,KAAW,YAAM;AACvB,QAAM,QAAQ,SAAS,OAAO,UAAU;AACxC,QAAM,iBAAiB,YAAY,OAAO,QAAQ,MAAM;AACxD,QAAM,WAAW,IAAI,KAAK,UAAU,QAAQ;AAC5C,QAAM,QAAQ,IAAI,KAAK,UAAU,GAAG,KAAK,IAAI,KAAK,UAAU,UAAU;AAEtE,SACE,qBAAC,aAAQ,mBAAiB,GAAG,EAAE,UAAU,WAAW,CAAC,UAAU,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAG,cAAY,OAAQ,GAAG,OAC1H;AAAA,yBAAC,YAAO,WAAU,eAChB;AAAA,0BAAC,QAAG,IAAI,GAAG,EAAE,UAAU,WAAU,gBAAgB,iBAAM;AAAA,MACvD,oBAAC,UAAK,WAAU,gBAAe,cAAY,OAAQ,sBAAY,KAAK,GAAE;AAAA,OACxE;AAAA,IACA,oBAAC,OAAE,WAAU,gBACV,mBAAS,oBAAC,UAAK,MAAK,OAAM,cAAY,aAAc,oBAAU,cAAc,GAAE,IAAU,gBAC3F;AAAA,IACA,oBAAC,OAAE,WAAU,kBAAkB,mBAAQ;AAAA,IACvC,qBAAC,QAAG,WAAU,kBACZ;AAAA,2BAAC,SAAI;AAAA,4BAAC,QAAI,wBAAa;AAAA,QAAK,oBAAC,QAAI,mBAAQ;AAAA,SAAK;AAAA,MAC9C,qBAAC,SAAI;AAAA,4BAAC,QAAI,uBAAY;AAAA,QAAK,qBAAC,QAAI;AAAA;AAAA,UAAQ,SAAS,oBAAC,UAAK,WAAU,iBAAiB,kBAAO,IAAU;AAAA,WAAK;AAAA,SAAK;AAAA,OAC/G;AAAA,IACA,qBAAC,OAAE,WAAU,oBACX;AAAA,2BAAC,UAAM;AAAA,kBAAU;AAAA,QAAc;AAAA,SAAE;AAAA,MACjC,oBAAC,UAAK,UAAU,SAAS,YAAY,GAAI,qBAAW,UAAU,EAAE,QAAQ,OAAO,UAAU,WAAW,SAAS,SAAS,CAAC,GAAE;AAAA,MACxH,QAAQ,oBAAC,UAAK,WAAU,gBAAe,MAAK,UAAU,oBAAU,YAAW,IAAU;AAAA,OACxF;AAAA,IACC,YAAY,oBAAC,SAAI,WAAU,oBAAoB,qBAAU,IAAS;AAAA,KACrE;AAEJ;","names":[]}
@@ -0,0 +1,27 @@
1
+ import * as React from 'react';
2
+
3
+ type ActionUrgency = "low" | "medium" | "high";
4
+ interface NextAction {
5
+ /** A stable key supplied by the host. */
6
+ id: string;
7
+ /** The action's short name. */
8
+ title: React.ReactNode;
9
+ /** Why it matters, in one line. */
10
+ why: string;
11
+ /** How soon it matters. */
12
+ urgency: ActionUrgency;
13
+ /** The host's translated urgency word. */
14
+ urgencyLabel: React.ReactNode;
15
+ /** A host-rendered link, button or command for a developer tool. */
16
+ action: React.ReactNode;
17
+ }
18
+ interface NextActionsProps extends Omit<React.ComponentProps<"section">, "children" | "title"> {
19
+ /** A heading such as “Que faire maintenant”. */
20
+ title: React.ReactNode;
21
+ /** Two or three actions, already ordered by the host from most to least important. */
22
+ actions: readonly [NextAction, NextAction] | readonly [NextAction, NextAction, NextAction];
23
+ }
24
+ /** “What to do now”: two or three ranked actions, with their reason and urgency. */
25
+ declare function NextActions({ title, actions, className, ...props }: NextActionsProps): React.JSX.Element;
26
+
27
+ export { type ActionUrgency, type NextAction, NextActions, type NextActionsProps };
@@ -0,0 +1,27 @@
1
+ // src/next-actions/next-actions.tsx
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ function NextActions({ title, actions, className, ...props }) {
4
+ return /* @__PURE__ */ jsxs("section", { className: ["kz-next-actions", className].filter(Boolean).join(" "), ...props, children: [
5
+ /* @__PURE__ */ jsx("h2", { className: "kz-next-actions-title", children: title }),
6
+ /* @__PURE__ */ jsx("ol", { className: "kz-next-actions-list", children: actions.map((action, index) => /* @__PURE__ */ jsxs("li", { className: "kz-next-action", "data-urgency": action.urgency, children: [
7
+ /* @__PURE__ */ jsxs("span", { className: "kz-next-action-rank", "aria-hidden": "true", children: [
8
+ index + 1,
9
+ "."
10
+ ] }),
11
+ /* @__PURE__ */ jsxs("div", { className: "kz-next-action-content", children: [
12
+ /* @__PURE__ */ jsxs("div", { className: "kz-next-action-copy", children: [
13
+ /* @__PURE__ */ jsxs("div", { className: "kz-next-action-heading", children: [
14
+ /* @__PURE__ */ jsx("h3", { children: action.title }),
15
+ /* @__PURE__ */ jsx("span", { className: "kz-next-action-urgency", "data-urgency": action.urgency, children: action.urgencyLabel })
16
+ ] }),
17
+ /* @__PURE__ */ jsx("p", { children: action.why })
18
+ ] }),
19
+ /* @__PURE__ */ jsx("div", { className: "kz-next-action-control", children: action.action })
20
+ ] })
21
+ ] }, action.id)) })
22
+ ] });
23
+ }
24
+ export {
25
+ NextActions
26
+ };
27
+ //# sourceMappingURL=next-actions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/next-actions/next-actions.tsx"],"sourcesContent":["// Server-safe. A ranked list from the host: this block never creates an action of its own.\nimport type * as React from \"react\";\n\nexport type ActionUrgency = \"low\" | \"medium\" | \"high\";\n\nexport interface NextAction {\n /** A stable key supplied by the host. */\n id: string;\n /** The action's short name. */\n title: React.ReactNode;\n /** Why it matters, in one line. */\n why: string;\n /** How soon it matters. */\n urgency: ActionUrgency;\n /** The host's translated urgency word. */\n urgencyLabel: React.ReactNode;\n /** A host-rendered link, button or command for a developer tool. */\n action: React.ReactNode;\n}\n\nexport interface NextActionsProps extends Omit<React.ComponentProps<\"section\">, \"children\" | \"title\"> {\n /** A heading such as “Que faire maintenant”. */\n title: React.ReactNode;\n /** Two or three actions, already ordered by the host from most to least important. */\n actions: readonly [NextAction, NextAction] | readonly [NextAction, NextAction, NextAction];\n}\n\n/** “What to do now”: two or three ranked actions, with their reason and urgency. */\nexport function NextActions({ title, actions, className, ...props }: NextActionsProps) {\n return (\n <section className={[\"kz-next-actions\", className].filter(Boolean).join(\" \")} {...props}>\n <h2 className=\"kz-next-actions-title\">{title}</h2>\n <ol className=\"kz-next-actions-list\">\n {actions.map((action, index) => (\n <li className=\"kz-next-action\" data-urgency={action.urgency} key={action.id}>\n <span className=\"kz-next-action-rank\" aria-hidden=\"true\">{index + 1}.</span>\n <div className=\"kz-next-action-content\">\n <div className=\"kz-next-action-copy\">\n <div className=\"kz-next-action-heading\">\n <h3>{action.title}</h3>\n <span className=\"kz-next-action-urgency\" data-urgency={action.urgency}>{action.urgencyLabel}</span>\n </div>\n <p>{action.why}</p>\n </div>\n <div className=\"kz-next-action-control\">{action.action}</div>\n </div>\n </li>\n ))}\n </ol>\n </section>\n );\n}\n"],"mappings":";AA+BM,cAIM,YAJN;AAHC,SAAS,YAAY,EAAE,OAAO,SAAS,WAAW,GAAG,MAAM,GAAqB;AACrF,SACE,qBAAC,aAAQ,WAAW,CAAC,mBAAmB,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAI,GAAG,OAChF;AAAA,wBAAC,QAAG,WAAU,yBAAyB,iBAAM;AAAA,IAC7C,oBAAC,QAAG,WAAU,wBACX,kBAAQ,IAAI,CAAC,QAAQ,UACpB,qBAAC,QAAG,WAAU,kBAAiB,gBAAc,OAAO,SAClD;AAAA,2BAAC,UAAK,WAAU,uBAAsB,eAAY,QAAQ;AAAA,gBAAQ;AAAA,QAAE;AAAA,SAAC;AAAA,MACrE,qBAAC,SAAI,WAAU,0BACb;AAAA,6BAAC,SAAI,WAAU,uBACb;AAAA,+BAAC,SAAI,WAAU,0BACb;AAAA,gCAAC,QAAI,iBAAO,OAAM;AAAA,YAClB,oBAAC,UAAK,WAAU,0BAAyB,gBAAc,OAAO,SAAU,iBAAO,cAAa;AAAA,aAC9F;AAAA,UACA,oBAAC,OAAG,iBAAO,KAAI;AAAA,WACjB;AAAA,QACA,oBAAC,SAAI,WAAU,0BAA0B,iBAAO,QAAO;AAAA,SACzD;AAAA,SAXgE,OAAO,EAYzE,CACD,GACH;AAAA,KACF;AAEJ;","names":[]}
@@ -0,0 +1,16 @@
1
+ import * as React from 'react';
2
+
3
+ type TapedPhotoProps = React.HTMLAttributes<HTMLElement> & {
4
+ /** The picture: an `img`, a `video`, a scene. It fills the print. */
5
+ children: React.ReactNode;
6
+ /** A line written under the picture, on the print. */
7
+ caption?: React.ReactNode;
8
+ /** The tilt in degrees (negative leans left); eased on a phone. @default -1.6 */
9
+ tilt?: number;
10
+ /** Where the tape holds it: two opposite `corners`, one strip at the `top`, or `none`. @default "corners" */
11
+ tape?: "corners" | "top" | "none";
12
+ };
13
+ /** A print taped in the notebook: tilted, a white border, a paper shadow, tape at two corners or at the top. */
14
+ declare function TapedPhoto({ children, caption, tilt, tape, className, style, ...props }: TapedPhotoProps): React.JSX.Element;
15
+
16
+ export { TapedPhoto, type TapedPhotoProps };