@krizaka/ui 3.37.0 → 3.39.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/blocks.css +36 -36
- package/dist/chip-link.js +1 -1
- package/dist/chip-row.js +1 -1
- package/dist/{chunk-IANSFIVC.js → chunk-7JFHTPI3.js} +13 -3
- package/dist/chunk-7JFHTPI3.js.map +1 -0
- package/dist/{chunk-RE5WJ4QP.js → chunk-ADRUEPYC.js} +4 -4
- package/dist/chunk-ADRUEPYC.js.map +1 -0
- package/dist/{chunk-BTTDIVVJ.js → chunk-F2UZ2WWL.js} +2 -2
- package/dist/chunk-F2UZ2WWL.js.map +1 -0
- package/dist/image-cropper.js +1 -1
- package/dist/kanban.js +1 -1
- package/dist/kanban.js.map +1 -1
- package/dist/landing-page.js +1 -6
- package/dist/landing-page.js.map +1 -1
- package/dist/map.js +2 -2
- package/dist/map.js.map +1 -1
- package/dist/motion.css +3 -3
- package/dist/native/vertical-video.js +1 -1
- package/dist/native/vertical-video.js.map +1 -1
- package/dist/native.d.ts +1 -1
- package/dist/native.js +11 -11
- package/dist/native.js.map +1 -1
- package/dist/nav-bar.d.ts +1 -1
- package/dist/nav-bar.js +1 -1
- package/dist/photo-grid.js +1 -1
- package/dist/photo-grid.js.map +1 -1
- package/dist/product-page.js +1 -6
- package/dist/product-page.js.map +1 -1
- package/dist/site-footer.d.ts +5 -17
- package/dist/site-footer.js +33 -29
- package/dist/site-footer.js.map +1 -1
- package/dist/{sites-B4sYlfPQ.d.ts → sites-inztN_Bv.d.ts} +8 -0
- package/dist/sites.d.ts +11 -1
- package/dist/sites.js +12 -2
- package/dist/sites.js.map +1 -1
- package/dist/slider.js +3 -3
- package/dist/slider.js.map +1 -1
- package/dist/step-showcase.js +1 -1
- package/dist/step-showcase.js.map +1 -1
- package/dist/story.css +3 -3
- package/dist/video-player.js +1 -1
- package/dist/video-trimmer.js +1 -1
- package/dist/video-trimmer.js.map +1 -1
- package/package.json +3 -3
- package/registry/chip-link.json +1 -1
- package/registry/examples/site-footer/company.js +0 -4
- package/registry/examples/site-footer/company.tsx +3 -7
- package/registry/index.json +7 -7
- package/registry/kanban.json +1 -1
- package/registry/landing-page.json +1 -1
- package/registry/map.json +2 -2
- package/registry/nav-bar.json +1 -1
- package/registry/photo-grid.json +1 -1
- package/registry/product-page.json +1 -1
- package/registry/rail-nav.json +1 -1
- package/registry/site-footer.json +10 -10
- package/registry/sites.json +2 -2
- package/registry/slider.json +1 -1
- package/registry/step-showcase.json +1 -1
- package/registry/video-trimmer.json +1 -1
- package/dist/chunk-BTTDIVVJ.js.map +0 -1
- package/dist/chunk-IANSFIVC.js.map +0 -1
- package/dist/chunk-RE5WJ4QP.js.map +0 -1
package/dist/blocks.css
CHANGED
|
@@ -228,12 +228,12 @@ a.kz-fact:focus-visible { outline: 2px solid var(--kz-ring, var(--kz-accent)); o
|
|
|
228
228
|
.kz-foundation { --kz-rail: color-mix(in srgb, var(--kz-hue, var(--kz-accent)) 50%, var(--kz-border-default)); display: grid; }
|
|
229
229
|
.kz-foundation-base { position: relative; display: grid; min-width: 0; }
|
|
230
230
|
.kz-foundation-base::after { content: ""; position: absolute; left: 50%; top: 100%; width: 1px; height: 28px; background: var(--kz-rail); }
|
|
231
|
-
.kz-foundation-group { position: relative; margin-top: 28px; padding: 22px 14px 14px; border: 1px solid var(--kz-rail); border-radius:
|
|
231
|
+
.kz-foundation-group { position: relative; margin-top: 28px; padding: 22px 14px 14px; border: 1px solid var(--kz-rail); border-radius: 0; }
|
|
232
232
|
.kz-foundation-label { position: absolute; top: -9px; left: 22px; padding: 0 8px; font: 500 11px/18px var(--kz-font-mono, ui-monospace, monospace); letter-spacing: 0; text-transform: none; color: var(--kz-hue-text, var(--kz-accent-text)); background: var(--kz-surface-0); }
|
|
233
233
|
.kz-foundation[data-position="end"] .kz-foundation-base { order: 2; }
|
|
234
234
|
.kz-foundation[data-position="end"] .kz-foundation-group { order: 1; margin-top: 0; margin-bottom: 28px; }
|
|
235
235
|
.kz-foundation[data-position="end"] .kz-foundation-base::after { top: auto; bottom: 100%; }
|
|
236
|
-
@media (max-width: 640px) { .kz-foundation-group { padding: 20px 8px 8px; border-radius:
|
|
236
|
+
@media (max-width: 640px) { .kz-foundation-group { padding: 20px 8px 8px; border-radius: 0; } }
|
|
237
237
|
|
|
238
238
|
/* The shared surface of the cards: a rail of the hue along the top, and one quiet hover (krizaka-ui#393) — the surface
|
|
239
239
|
goes one step up and the hairline strengthens, in a short colour transition. Nothing moves, nothing follows the
|
|
@@ -242,7 +242,7 @@ a.kz-fact:focus-visible { outline: 2px solid var(--kz-ring, var(--kz-accent)); o
|
|
|
242
242
|
position: relative;
|
|
243
243
|
isolation: isolate;
|
|
244
244
|
overflow: hidden;
|
|
245
|
-
border-radius:
|
|
245
|
+
border-radius: 0;
|
|
246
246
|
background: var(--kz-surface-1);
|
|
247
247
|
border: 1px solid var(--kz-border-default);
|
|
248
248
|
transition: background-color 150ms var(--kz-ease, ease), border-color 150ms var(--kz-ease, ease);
|
|
@@ -275,7 +275,7 @@ a.kz-fact:focus-visible { outline: 2px solid var(--kz-ring, var(--kz-accent)); o
|
|
|
275
275
|
flex-shrink: 0;
|
|
276
276
|
width: 42px;
|
|
277
277
|
height: 42px;
|
|
278
|
-
border-radius:
|
|
278
|
+
border-radius: 0;
|
|
279
279
|
color: var(--kz-text-primary);
|
|
280
280
|
background: color-mix(in srgb, var(--kz-hue, var(--kz-accent)) 14%, var(--kz-surface-1));
|
|
281
281
|
border: 1px solid color-mix(in srgb, var(--kz-hue, var(--kz-accent)) 30%, transparent);
|
|
@@ -388,7 +388,7 @@ a.kz-fact:focus-visible { outline: 2px solid var(--kz-ring, var(--kz-accent)); o
|
|
|
388
388
|
position: relative;
|
|
389
389
|
margin: 0;
|
|
390
390
|
padding: 14px 16px 14px 44px;
|
|
391
|
-
border-radius:
|
|
391
|
+
border-radius: 0 16px 16px 6px;
|
|
392
392
|
background: color-mix(in srgb, var(--kz-hue, var(--kz-accent)) 9%, var(--kz-surface-0));
|
|
393
393
|
border: 1px solid color-mix(in srgb, var(--kz-hue, var(--kz-accent)) 30%, transparent);
|
|
394
394
|
}
|
|
@@ -428,7 +428,7 @@ a.kz-fact:focus-visible { outline: 2px solid var(--kz-ring, var(--kz-accent)); o
|
|
|
428
428
|
color: var(--kz-hue-text, var(--kz-accent-text));
|
|
429
429
|
}
|
|
430
430
|
.kz-quote-bird { flex-shrink: 0; --kz-accent: var(--kz-hue, var(--kz-accent)); }
|
|
431
|
-
.kz-quote[data-variant="callout"] blockquote { padding: 24px 26px 24px 68px; border-radius:
|
|
431
|
+
.kz-quote[data-variant="callout"] blockquote { padding: 24px 26px 24px 68px; border-radius: 0 22px 22px 8px; }
|
|
432
432
|
.kz-quote[data-variant="callout"] blockquote::before { left: 18px; top: 12px; font-size: 72px; }
|
|
433
433
|
.kz-quote[data-variant="callout"] blockquote::after { left: 36px; bottom: -8px; width: 14px; height: 14px; }
|
|
434
434
|
.kz-quote[data-variant="callout"] blockquote p { font-family: var(--kz-font-display); font-size: clamp(16px, 2vw, 19px); font-weight: 400; line-height: 1.55; letter-spacing: -0.01em; }
|
|
@@ -445,14 +445,14 @@ a.kz-fact:focus-visible { outline: 2px solid var(--kz-ring, var(--kz-accent)); o
|
|
|
445
445
|
|
|
446
446
|
/* ─── DecisionList: one card per decision — what was chosen, large; refused · because · what it costs, side by side ─── */
|
|
447
447
|
.kz-decisions { margin: 0; padding: 0; list-style: none; display: grid; gap: 14px; }
|
|
448
|
-
.kz-decision { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 18px; padding: 20px 22px; border-radius:
|
|
449
|
-
.kz-decision-n { font-family: var(--kz-font-display); font-size: 28px; font-weight: 400; line-height: 1; letter-spacing: -0.01em; font-variant-numeric: tabular-nums; color: var(--kz-hue-text, var(--kz-accent-text)); }
|
|
448
|
+
.kz-decision { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 18px; padding: 20px 22px; border-radius: 0; background: var(--kz-surface-1); border: 1px solid var(--kz-border-default); }
|
|
449
|
+
.kz-decision-n { font-family: var(--kz-font-display); font-size: 28px; font-weight: 400; line-height: 1; letter-spacing: -0.01em; font-variant-numeric: var(--kz-figures, lining-nums tabular-nums); color: var(--kz-hue-text, var(--kz-accent-text)); }
|
|
450
450
|
.kz-decision-body { display: grid; gap: 14px; min-width: 0; }
|
|
451
451
|
.kz-decision-part p:not(.kz-label) { margin: 6px 0 0; font-size: 14px; line-height: 1.6; color: var(--kz-text-secondary); }
|
|
452
452
|
.kz-decision-part[data-part="chose"] .kz-label { color: var(--kz-success-text); }
|
|
453
453
|
.kz-decision-part[data-part="chose"] p:not(.kz-label) { font-size: 16px; font-weight: 600; line-height: 1.5; color: var(--kz-text-primary); }
|
|
454
454
|
.kz-decision-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
|
|
455
|
-
.kz-decision-grid > .kz-decision-part { min-width: 0; padding: 12px 14px; border-radius:
|
|
455
|
+
.kz-decision-grid > .kz-decision-part { min-width: 0; padding: 12px 14px; border-radius: 0; background: var(--kz-surface-0); border: 1px solid var(--kz-border-subtle); border-top: 2px solid var(--kz-border-strong); }
|
|
456
456
|
.kz-decision-part[data-part="refused"] { border-top-color: var(--kz-danger); }
|
|
457
457
|
.kz-decision-part[data-part="refused"] .kz-label { color: var(--kz-danger-text); }
|
|
458
458
|
.kz-decision-part[data-part="because"] { border-top-color: var(--kz-hue, var(--kz-accent)); }
|
|
@@ -463,7 +463,7 @@ a.kz-fact:focus-visible { outline: 2px solid var(--kz-ring, var(--kz-accent)); o
|
|
|
463
463
|
@media (max-width: 560px) { .kz-decision { grid-template-columns: minmax(0, 1fr); gap: 10px; padding: 18px; } .kz-decision-n { font-size: 22px; } }
|
|
464
464
|
|
|
465
465
|
/* ─── CodeBlock · CodeTabs: a file name, code that scrolls sideways (never shrinks), a copy button ─── */
|
|
466
|
-
.kz-code { margin: 0; min-width: 0; overflow: hidden; border-radius:
|
|
466
|
+
.kz-code { margin: 0; min-width: 0; overflow: hidden; border-radius: 0; background: var(--kz-surface-1); border: 1px solid var(--kz-border-default); box-shadow: inset 3px 0 0 var(--kz-hue, var(--kz-accent)); }
|
|
467
467
|
.kz-code-bar {
|
|
468
468
|
display: flex;
|
|
469
469
|
align-items: center;
|
|
@@ -523,7 +523,7 @@ a.kz-fact:focus-visible { outline: 2px solid var(--kz-ring, var(--kz-accent)); o
|
|
|
523
523
|
.kz-md blockquote { padding-inline-start: 1em; color: var(--kz-text-secondary); border-inline-start: 3px solid var(--kz-hue, var(--kz-accent)); }
|
|
524
524
|
.kz-md :not(pre) > code { padding: 0.12em 0.4em; border-radius: 6px; font-family: var(--kz-font-mono); font-size: 0.88em; background: var(--kz-surface-3); }
|
|
525
525
|
.kz-md hr { border: 0; border-top: 1px solid var(--kz-border-default); }
|
|
526
|
-
.kz-md img { max-width: 100%; height: auto; border-radius:
|
|
526
|
+
.kz-md img { max-width: 100%; height: auto; border-radius: 0; }
|
|
527
527
|
.kz-md-table { overflow-x: auto; }
|
|
528
528
|
.kz-md-table table { width: 100%; border-collapse: collapse; font-size: 0.93em; }
|
|
529
529
|
.kz-md-table :is(th, td) { padding: 0.55em 0.8em; text-align: start; border-bottom: 1px solid var(--kz-border-subtle); }
|
|
@@ -594,7 +594,7 @@ a.kz-fact:focus-visible { outline: 2px solid var(--kz-ring, var(--kz-accent)); o
|
|
|
594
594
|
justify-content: space-between;
|
|
595
595
|
gap: 20px;
|
|
596
596
|
padding: 24px 26px;
|
|
597
|
-
border-radius:
|
|
597
|
+
border-radius: 0;
|
|
598
598
|
background: color-mix(in srgb, var(--kz-hue, var(--kz-accent)) 8%, var(--kz-surface-1));
|
|
599
599
|
border: 1px solid color-mix(in srgb, var(--kz-hue, var(--kz-accent)) 30%, var(--kz-border-default));
|
|
600
600
|
}
|
|
@@ -636,26 +636,26 @@ a.kz-fact:focus-visible { outline: 2px solid var(--kz-ring, var(--kz-accent)); o
|
|
|
636
636
|
.kz-tpl-split[data-reverse] > :first-child { order: 2; }
|
|
637
637
|
@media (max-width: 900px) { .kz-tpl-split { grid-template-columns: minmax(0, 1fr); } .kz-tpl-split[data-reverse] > :first-child { order: 0; } }
|
|
638
638
|
.kz-tpl-stage {
|
|
639
|
-
position: relative; min-width: 0; overflow: hidden; border-radius:
|
|
640
|
-
box-shadow:
|
|
639
|
+
position: relative; min-width: 0; overflow: hidden; border-radius: 0; border: 1px solid var(--kz-border-default); background: var(--kz-surface-1);
|
|
640
|
+
box-shadow: var(--kz-shadow-md);
|
|
641
641
|
}
|
|
642
642
|
.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);
|
|
643
643
|
font-family: var(--kz-font-mono); font-size: 11px; color: var(--kz-text-secondary); }
|
|
644
|
-
.kz-tpl-stage-bar i {
|
|
645
|
-
.kz-tpl-stage-bar span { margin-left:
|
|
644
|
+
.kz-tpl-stage-bar i { display: none; } /* Cahier: no fake window controls — the bar is the plate's caption */
|
|
645
|
+
.kz-tpl-stage-bar span { margin-left: 0; }
|
|
646
646
|
.kz-tpl-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 4px; }
|
|
647
647
|
|
|
648
648
|
/* A band of proofs: figures or facts across the frame, divided by hairlines. */
|
|
649
649
|
.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); }
|
|
650
650
|
.kz-tpl-band > div { padding: 20px 18px; border-left: 1px solid var(--kz-border-subtle); }
|
|
651
651
|
.kz-tpl-band > div:first-child { border-left: 0; }
|
|
652
|
-
.kz-tpl-band dt { font-family: var(--kz-font-display); font-size: clamp(1.6rem, 3vw, 2.2rem); font-weight: 400; letter-spacing: -0.01em; color: var(--kz-text-primary); }
|
|
652
|
+
.kz-tpl-band dt { font-variant-numeric: var(--kz-figures, lining-nums tabular-nums); font-family: var(--kz-font-display); font-size: clamp(1.6rem, 3vw, 2.2rem); font-weight: 400; letter-spacing: -0.01em; color: var(--kz-text-primary); }
|
|
653
653
|
.kz-tpl-band dd { margin: 4px 0 0; font-size: 13px; color: var(--kz-text-secondary); }
|
|
654
654
|
@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; } }
|
|
655
655
|
|
|
656
656
|
/* A bento: features of different weights on a six-column grid (one column on a phone). */
|
|
657
657
|
.kz-tpl-bento { margin: 0; padding: 0; list-style: none; display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 14px; }
|
|
658
|
-
.kz-tpl-bento > li { grid-column: span 2; display: flex; flex-direction: column; gap: 10px; min-width: 0; padding: 22px; border-radius:
|
|
658
|
+
.kz-tpl-bento > li { grid-column: span 2; display: flex; flex-direction: column; gap: 10px; min-width: 0; padding: 22px; border-radius: 0;
|
|
659
659
|
background: var(--kz-surface-1); border: 1px solid var(--kz-border-default); }
|
|
660
660
|
.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)); }
|
|
661
661
|
.kz-tpl-bento > li[data-size="md"] { grid-column: span 3; }
|
|
@@ -670,7 +670,7 @@ a.kz-fact:focus-visible { outline: 2px solid var(--kz-ring, var(--kz-accent)); o
|
|
|
670
670
|
.kz-tpl-timeline::before { content: ""; position: absolute; left: 21px; top: 8px; bottom: 8px; width: 2px;
|
|
671
671
|
background: linear-gradient(var(--kz-hue, var(--kz-accent)), color-mix(in srgb, var(--kz-hue, var(--kz-accent)) 10%, transparent)); }
|
|
672
672
|
.kz-tpl-step { position: relative; display: grid; grid-template-columns: 44px minmax(0, 1fr) minmax(0, 1fr); gap: 20px 28px; align-items: start; }
|
|
673
|
-
.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:
|
|
673
|
+
.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: 0;
|
|
674
674
|
font-family: var(--kz-font-display); font-size: 16px; font-weight: 400; color: var(--kz-text-primary); background: var(--kz-surface-1);
|
|
675
675
|
border: 2px solid var(--kz-hue, var(--kz-accent)); box-shadow: 0 0 0 6px var(--kz-surface-0); }
|
|
676
676
|
.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: 400; color: var(--kz-text-primary); }
|
|
@@ -687,7 +687,7 @@ a.kz-fact:focus-visible { outline: 2px solid var(--kz-ring, var(--kz-accent)); o
|
|
|
687
687
|
/* A gallery: media in columns of different heights, the featured one wide. */
|
|
688
688
|
.kz-tpl-gallery { margin: 0; padding: 0; list-style: none; columns: 3 280px; column-gap: 14px; }
|
|
689
689
|
.kz-tpl-gallery > li { break-inside: avoid; margin-bottom: 14px; }
|
|
690
|
-
.kz-tpl-figure { margin: 0; overflow: hidden; border-radius:
|
|
690
|
+
.kz-tpl-figure { margin: 0; overflow: hidden; border-radius: 0; border: 1px solid var(--kz-border-default); background: var(--kz-surface-1); }
|
|
691
691
|
.kz-tpl-figure-media { overflow: hidden; background: var(--kz-media); }
|
|
692
692
|
.kz-tpl-figure-media > :is(img, video) { display: block; width: 100%; height: auto; }
|
|
693
693
|
.kz-tpl-figure figcaption { display: grid; gap: 4px; padding: 12px 14px; }
|
|
@@ -700,7 +700,7 @@ a.kz-fact:focus-visible { outline: 2px solid var(--kz-ring, var(--kz-accent)); o
|
|
|
700
700
|
.kz-tpl-hub-search > * { width: 100%; }
|
|
701
701
|
.kz-tpl-hub-hints { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; font-size: 13px; color: var(--kz-text-secondary); }
|
|
702
702
|
.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; }
|
|
703
|
-
.kz-tpl-collection { position: relative; isolation: isolate; overflow: hidden; display: flex; flex-direction: column; gap: 12px; height: 100%; padding: 20px; border-radius:
|
|
703
|
+
.kz-tpl-collection { position: relative; isolation: isolate; overflow: hidden; display: flex; flex-direction: column; gap: 12px; height: 100%; padding: 20px; border-radius: 0;
|
|
704
704
|
background: linear-gradient(160deg, color-mix(in srgb, var(--kz-accent) 14%, var(--kz-surface-1)), var(--kz-surface-1) 55%);
|
|
705
705
|
border: 1px solid color-mix(in srgb, var(--kz-accent) 28%, var(--kz-border-default)); }
|
|
706
706
|
.kz-tpl-collection-head { display: flex; align-items: center; gap: 10px; }
|
|
@@ -743,7 +743,7 @@ a.kz-fact:focus-visible { outline: 2px solid var(--kz-ring, var(--kz-accent)); o
|
|
|
743
743
|
.kz-tpl-prose { max-width: 46rem; font-size: 16px; line-height: 1.75; color: var(--kz-text-secondary); }
|
|
744
744
|
.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); }
|
|
745
745
|
.kz-tpl-pager { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; margin-top: 40px; }
|
|
746
|
-
.kz-tpl-pager a { display: grid; gap: 4px; padding: 14px 16px; border-radius:
|
|
746
|
+
.kz-tpl-pager a { display: grid; gap: 4px; padding: 14px 16px; border-radius: 0; border: 1px solid var(--kz-border-default); background: var(--kz-surface-1);
|
|
747
747
|
text-decoration: none; color: var(--kz-text-primary); }
|
|
748
748
|
.kz-tpl-pager a:hover { border-color: var(--kz-accent); }
|
|
749
749
|
.kz-tpl-pager a:focus-visible { outline: 2px solid var(--kz-ring, var(--kz-accent)); outline-offset: 2px; }
|
|
@@ -758,7 +758,7 @@ a.kz-fact:focus-visible { outline: 2px solid var(--kz-ring, var(--kz-accent)); o
|
|
|
758
758
|
.kz-tpl-count { margin: 0; font-family: var(--kz-font-mono); font-size: 12px; color: var(--kz-text-secondary); }
|
|
759
759
|
@media (max-width: 900px) {
|
|
760
760
|
.kz-tpl-catalogue { grid-template-columns: minmax(0, 1fr); gap: 16px; }
|
|
761
|
-
.kz-tpl-catalogue-filters { position: static; border-radius:
|
|
761
|
+
.kz-tpl-catalogue-filters { position: static; border-radius: 0; border: 1px solid var(--kz-border-default); background: var(--kz-surface-1); }
|
|
762
762
|
.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;
|
|
763
763
|
font-size: 14px; font-weight: 650; color: var(--kz-text-primary); }
|
|
764
764
|
.kz-tpl-catalogue-filters > summary::-webkit-details-marker { display: none; }
|
|
@@ -766,7 +766,7 @@ a.kz-fact:focus-visible { outline: 2px solid var(--kz-ring, var(--kz-accent)); o
|
|
|
766
766
|
}
|
|
767
767
|
@media (max-width: 1279px) {
|
|
768
768
|
.kz-tpl-catalogue[data-rail="wide"] { grid-template-columns: minmax(0, 1fr); gap: 16px; }
|
|
769
|
-
.kz-tpl-catalogue[data-rail="wide"] .kz-tpl-catalogue-filters { position: static; border-radius:
|
|
769
|
+
.kz-tpl-catalogue[data-rail="wide"] .kz-tpl-catalogue-filters { position: static; border-radius: 0; border: 1px solid var(--kz-border-default); background: var(--kz-surface-1); }
|
|
770
770
|
.kz-tpl-catalogue[data-rail="wide"] .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;
|
|
771
771
|
font-size: 14px; font-weight: 650; color: var(--kz-text-primary); }
|
|
772
772
|
.kz-tpl-catalogue[data-rail="wide"] .kz-tpl-catalogue-filters > summary::-webkit-details-marker { display: none; }
|
|
@@ -776,7 +776,7 @@ a.kz-fact:focus-visible { outline: 2px solid var(--kz-ring, var(--kz-accent)); o
|
|
|
776
776
|
/* A long read: chapters with their big numbers, pull quotes in the margin, figures that break out. */
|
|
777
777
|
.kz-tpl-chapters { display: grid; gap: clamp(40px, 7vw, 88px); }
|
|
778
778
|
.kz-tpl-chapter { display: grid; grid-template-columns: minmax(0, 9rem) minmax(0, 42rem) minmax(0, 1fr); gap: 24px 32px; }
|
|
779
|
-
.kz-tpl-chapter-n { font-family: var(--kz-font-display); font-size: clamp(2.4rem, 6vw, 4.2rem); font-weight: 400; line-height: 0.9; letter-spacing: -0.01em;
|
|
779
|
+
.kz-tpl-chapter-n { font-variant-numeric: var(--kz-figures, lining-nums tabular-nums); font-family: var(--kz-font-display); font-size: clamp(2.4rem, 6vw, 4.2rem); font-weight: 400; line-height: 0.9; letter-spacing: -0.01em;
|
|
780
780
|
color: transparent; -webkit-text-stroke: 1.5px var(--kz-hue, var(--kz-accent)); }
|
|
781
781
|
.kz-tpl-chapter h2 { margin: 0 0 14px; font-family: var(--kz-font-display); font-size: clamp(1.5rem, 3vw, 2.1rem); font-weight: 400; letter-spacing: -0.01em; line-height: 1.15;
|
|
782
782
|
color: var(--kz-text-primary); scroll-margin-top: var(--kz-anchor-offset, 96px); }
|
|
@@ -816,7 +816,7 @@ a.kz-fact:focus-visible { outline: 2px solid var(--kz-ring, var(--kz-accent)); o
|
|
|
816
816
|
/* Contact: the ways to reach us beside the form; what happens next under it. */
|
|
817
817
|
.kz-tpl-contact { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.25fr); gap: clamp(24px, 4vw, 48px); align-items: start; }
|
|
818
818
|
@media (max-width: 900px) { .kz-tpl-contact { grid-template-columns: minmax(0, 1fr); } }
|
|
819
|
-
.kz-tpl-form { padding: clamp(18px, 3vw, 28px); border-radius:
|
|
819
|
+
.kz-tpl-form { padding: clamp(18px, 3vw, 28px); border-radius: 0; background: var(--kz-surface-1); border: 1px solid var(--kz-border-default); }
|
|
820
820
|
.kz-tpl-next { margin: 0; padding: 0; list-style: none; counter-reset: next; display: grid; gap: 12px; }
|
|
821
821
|
.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); }
|
|
822
822
|
.kz-tpl-next li::before { content: counter(next); display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 30px; border-radius: 50%;
|
|
@@ -824,7 +824,7 @@ a.kz-fact:focus-visible { outline: 2px solid var(--kz-ring, var(--kz-accent)); o
|
|
|
824
824
|
.kz-tpl-next strong { display: block; color: var(--kz-text-primary); }
|
|
825
825
|
|
|
826
826
|
/* Status: one line per service, its state in words and a dot; an incident log under it. */
|
|
827
|
-
.kz-tpl-state { display: flex; flex-wrap: wrap; align-items: center; gap: 14px 20px; padding: 18px 20px; border-radius:
|
|
827
|
+
.kz-tpl-state { display: flex; flex-wrap: wrap; align-items: center; gap: 14px 20px; padding: 18px 20px; border-radius: 0; border: 1px solid var(--kz-border-default);
|
|
828
828
|
background: var(--kz-surface-1); }
|
|
829
829
|
.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)); }
|
|
830
830
|
.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)); }
|
|
@@ -835,7 +835,7 @@ a.kz-fact:focus-visible { outline: 2px solid var(--kz-ring, var(--kz-accent)); o
|
|
|
835
835
|
[data-state="degraded"] > .kz-tpl-dot, .kz-tpl-dot[data-state="degraded"] { background: var(--kz-warning); }
|
|
836
836
|
[data-state="outage"] > .kz-tpl-dot, .kz-tpl-dot[data-state="outage"] { background: var(--kz-danger); }
|
|
837
837
|
[data-state="building"] > .kz-tpl-dot, .kz-tpl-dot[data-state="building"] { background: var(--kz-info); }
|
|
838
|
-
.kz-tpl-services { margin: 16px 0 0; padding: 0; list-style: none; border-radius:
|
|
838
|
+
.kz-tpl-services { margin: 16px 0 0; padding: 0; list-style: none; border-radius: 0; border: 1px solid var(--kz-border-default); overflow: hidden; }
|
|
839
839
|
.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);
|
|
840
840
|
font-size: 14.5px; color: var(--kz-text-primary); background: var(--kz-surface-1); }
|
|
841
841
|
.kz-tpl-services li:first-child { border-top: 0; }
|
|
@@ -843,7 +843,7 @@ a.kz-fact:focus-visible { outline: 2px solid var(--kz-ring, var(--kz-accent)); o
|
|
|
843
843
|
|
|
844
844
|
/* An error: the code, huge and drawn in outline, the bird beside it, the ways out under it. */
|
|
845
845
|
.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; }
|
|
846
|
-
.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: 400;
|
|
846
|
+
.kz-tpl-error .kz-tpl-error-code { font-variant-numeric: var(--kz-figures, lining-nums tabular-nums); 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: 400;
|
|
847
847
|
line-height: 0.9; letter-spacing: -0.01em; color: transparent; -webkit-text-stroke: 2px var(--kz-hue, var(--kz-accent)); }
|
|
848
848
|
.kz-tpl-error h1 { margin: 0; font-family: var(--kz-font-display); font-size: clamp(1.6rem, 4vw, 2.3rem); font-weight: 400; letter-spacing: -0.01em; color: var(--kz-text-primary); }
|
|
849
849
|
.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); }
|
|
@@ -851,12 +851,12 @@ a.kz-fact:focus-visible { outline: 2px solid var(--kz-ring, var(--kz-accent)); o
|
|
|
851
851
|
|
|
852
852
|
/* Pricing: plans side by side, the featured one lifted; a comparison under them. */
|
|
853
853
|
.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; }
|
|
854
|
-
.kz-tpl-plan { position: relative; display: flex; flex-direction: column; gap: 14px; height: 100%; padding: 24px; border-radius:
|
|
854
|
+
.kz-tpl-plan { position: relative; display: flex; flex-direction: column; gap: 14px; height: 100%; padding: 24px; border-radius: 0; background: var(--kz-surface-1);
|
|
855
855
|
border: 1px solid var(--kz-border-default); }
|
|
856
856
|
.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%);
|
|
857
|
-
box-shadow:
|
|
857
|
+
box-shadow: var(--kz-shadow-md); }
|
|
858
858
|
.kz-tpl-plan :is(h2, h3) { margin: 0; font-family: var(--kz-font-display); font-size: 18px; font-weight: 400; color: var(--kz-text-primary); }
|
|
859
|
-
.kz-tpl-price { margin: 0; font-family: var(--kz-font-display); font-size: 2.6rem; font-weight: 400; letter-spacing: -0.01em; line-height: 1; color: var(--kz-text-primary); }
|
|
859
|
+
.kz-tpl-price { font-variant-numeric: var(--kz-figures, lining-nums tabular-nums); margin: 0; font-family: var(--kz-font-display); font-size: 2.6rem; font-weight: 400; letter-spacing: -0.01em; line-height: 1; color: var(--kz-text-primary); }
|
|
860
860
|
.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); }
|
|
861
861
|
.kz-tpl-plan ul { margin: 0; padding: 0; list-style: none; display: grid; gap: 8px; font-size: 14px; color: var(--kz-text-secondary); }
|
|
862
862
|
.kz-tpl-plan ul li { display: grid; grid-template-columns: 18px minmax(0, 1fr); gap: 8px; }
|
|
@@ -866,12 +866,12 @@ a.kz-fact:focus-visible { outline: 2px solid var(--kz-ring, var(--kz-accent)); o
|
|
|
866
866
|
.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); }
|
|
867
867
|
.kz-tpl-compare thead th { font-family: var(--kz-font-mono); font-size: 11px; letter-spacing: 0; text-transform: none; }
|
|
868
868
|
.kz-tpl-compare tbody th { color: var(--kz-text-primary); font-weight: 600; }
|
|
869
|
-
.kz-tpl-scroll { overflow-x: auto; border-radius:
|
|
869
|
+
.kz-tpl-scroll { overflow-x: auto; border-radius: 0; border: 1px solid var(--kz-border-default); background: var(--kz-surface-1); }
|
|
870
870
|
.kz-tpl-faq { display: grid; gap: 8px; }
|
|
871
|
-
.kz-tpl-faq details { border-radius:
|
|
871
|
+
.kz-tpl-faq details { border-radius: 0; border: 1px solid var(--kz-border-default); background: var(--kz-surface-1); }
|
|
872
872
|
.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); }
|
|
873
873
|
.kz-tpl-faq summary::-webkit-details-marker { display: none; }
|
|
874
|
-
.kz-tpl-faq summary:focus-visible { outline: 2px solid var(--kz-ring, var(--kz-accent)); outline-offset: 2px; border-radius:
|
|
874
|
+
.kz-tpl-faq summary:focus-visible { outline: 2px solid var(--kz-ring, var(--kz-accent)); outline-offset: 2px; border-radius: 0; }
|
|
875
875
|
.kz-tpl-faq details > div { padding: 0 16px 16px; font-size: 14.5px; line-height: 1.65; color: var(--kz-text-secondary); }
|
|
876
876
|
|
|
877
877
|
@media (prefers-reduced-motion: reduce) { .kz-tpl-collection { transition: none !important; transform: none !important; } }
|
|
@@ -1024,7 +1024,7 @@ a.kz-fact:focus-visible { outline: 2px solid var(--kz-ring, var(--kz-accent)); o
|
|
|
1024
1024
|
.kz-index-entry:focus-visible { outline: var(--kz-ring-width, 2px) solid var(--kz-ring); outline-offset: 2px; }
|
|
1025
1025
|
.kz-index-label { min-width: 0; }
|
|
1026
1026
|
.kz-index-leader { flex: 1; min-width: 12px; border-bottom: 1.5px dotted var(--kz-text-muted); transform: translateY(-4px); }
|
|
1027
|
-
.kz-index-page { font-family: var(--kz-font-mono); font-size: 12.5px; color: var(--kz-text-secondary); font-variant-numeric: tabular-nums; }
|
|
1027
|
+
.kz-index-page { font-family: var(--kz-font-mono); font-size: 12.5px; color: var(--kz-text-secondary); font-variant-numeric: var(--kz-figures, lining-nums tabular-nums); }
|
|
1028
1028
|
.kz-index-entry[aria-current="page"] { color: var(--kz-text-primary); font-weight: 700; }
|
|
1029
1029
|
.kz-index-entry[aria-current="page"]::before { content: "→"; position: absolute; left: -20px; color: var(--kz-paper-rule-margin); font-weight: 400; }
|
|
1030
1030
|
|
package/dist/chip-link.js
CHANGED
package/dist/chip-row.js
CHANGED
|
@@ -39,6 +39,11 @@ function siteById(id) {
|
|
|
39
39
|
function sitesByGroup() {
|
|
40
40
|
return siteGroups.map((group) => ({ group, sites: sites.filter((s) => s.group === group) })).filter((g) => g.sites.length > 0);
|
|
41
41
|
}
|
|
42
|
+
var companyLinks = [
|
|
43
|
+
{ id: "story", url: { en: "https://www.krizaka.com/story", fr: "https://www.krizaka.com/fr/story" } },
|
|
44
|
+
{ id: "blog", url: { en: "https://blog.krizaka.com", fr: "https://blog.krizaka.com" } },
|
|
45
|
+
{ id: "contact", url: { en: "https://www.krizaka.com/contact", fr: "https://www.krizaka.com/fr/contact" } }
|
|
46
|
+
];
|
|
42
47
|
var familyLabels = {
|
|
43
48
|
en: {
|
|
44
49
|
family: "Krizaka family",
|
|
@@ -61,7 +66,9 @@ var familyLabels = {
|
|
|
61
66
|
},
|
|
62
67
|
signature: { company: "A Krizaka company", product: "A Krizaka product", "open-source": "A Krizaka open-source project" },
|
|
63
68
|
place: "Made in Montr\xE9al",
|
|
64
|
-
version: "Version"
|
|
69
|
+
version: "Version",
|
|
70
|
+
lang: "en",
|
|
71
|
+
company: { story: "Our story", blog: "Blog", contact: "Contact us" }
|
|
65
72
|
},
|
|
66
73
|
fr: {
|
|
67
74
|
family: "Famille Krizaka",
|
|
@@ -84,7 +91,9 @@ var familyLabels = {
|
|
|
84
91
|
},
|
|
85
92
|
signature: { company: "Une compagnie Krizaka", product: "Un produit Krizaka", "open-source": "Un projet open source de Krizaka" },
|
|
86
93
|
place: "Fait \xE0 Montr\xE9al",
|
|
87
|
-
version: "Version"
|
|
94
|
+
version: "Version",
|
|
95
|
+
lang: "fr",
|
|
96
|
+
company: { story: "Notre histoire", blog: "Blogue", contact: "Nous \xE9crire" }
|
|
88
97
|
}
|
|
89
98
|
};
|
|
90
99
|
|
|
@@ -93,6 +102,7 @@ export {
|
|
|
93
102
|
FamilyMark,
|
|
94
103
|
siteById,
|
|
95
104
|
sitesByGroup,
|
|
105
|
+
companyLinks,
|
|
96
106
|
familyLabels
|
|
97
107
|
};
|
|
98
|
-
//# sourceMappingURL=chunk-
|
|
108
|
+
//# sourceMappingURL=chunk-7JFHTPI3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/family-mark.tsx","../src/sites/sites.ts"],"sourcesContent":["// The mark of a site of the family (`@krizaka/ui/sites`): its brand's `ProductLogo`, still (a list of marks never\n// moves), or GitHub's, in the text colour. Shared by `NavBar.Family` and `SiteFooter` — not an entry of its own.\nimport type * as React from \"react\";\n\nimport { ProductLogo } from \"./marks/ProductLogo\";\nimport type { SiteMark } from \"./sites/sites\";\n\n/** GitHub's mark, in the text colour (both themes). */\nexport function GitHubGlyph({ size = 16, className }: { size?: number; className?: string }) {\n return (\n <svg viewBox=\"0 0 16 16\" width={size} height={size} fill=\"currentColor\" aria-hidden className={className}>\n <path d=\"M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8Z\" />\n </svg>\n );\n}\n\n/** A site's mark, decorative (its name is always written beside it). */\nexport function FamilyMark({ mark, size }: { mark: SiteMark; size: number }): React.ReactElement {\n if (mark === \"github\") return <GitHubGlyph size={Math.round(size * 0.8)} />;\n return <ProductLogo id={mark} size={size} animated={false} />;\n}\n","// Server-safe: plain data. The Krizaka family — every site Krizaka runs, once. The family switcher of the bar\n// (`NavBar.Family`) and the common footer (`SiteFooter`) both read it, so adding a site is one release of this package:\n// every bar and every footer of the family follow.\n//\n// The words of the family (a site's one line, the groups, the statuses, the footer's signature) are brand data, written\n// here in English and French (`familyLabels`) — a site passes the set of its locale, or its own translation.\n\n/** A site of the family. */\nexport type SiteId = \"krizaka\" | \"orazaka\" | \"orochia\" | \"yasakia\" | \"yororis\" | \"yomizaka\" | \"kachizaka\" | \"akinaza\" | \"ui\" | \"java\" | \"motion\" | \"github\";\n\n/** What a site is: the company, a product, or an open-source project. It chooses the footer's signature line. */\nexport type SiteKind = \"company\" | \"product\" | \"open-source\";\n\n/**\n * `released`: open to visit. `upcoming`: announced, not released yet (said \"Coming soon\"). `construction`: under\n * construction — nothing offered (a QA-only app may run; the public page says so). `development`: being built in the\n * open, with a dev site (said \"In development\"). A site with none yet would use its repository as its address.\n */\nexport type SiteStatus = \"released\" | \"upcoming\" | \"construction\" | \"development\";\n\n/** The groups of the family, in reading order: Krizaka · Products · Open source · GitHub. */\nexport type SiteGroup = \"krizaka\" | \"products\" | \"open-source\" | \"github\";\n\n/** The mark a site wears: a brand of `ProductLogo` (Krizaka UI and Krizaka Java wear Krizaka's), or GitHub's. */\nexport type SiteMark = \"krizaka\" | \"orazaka\" | \"orochia\" | \"yasakia\" | \"yororis\" | \"yomizaka\" | \"kachizaka\" | \"akinaza\" | \"github\";\n\nexport interface Site {\n readonly id: SiteId;\n /** The name, never translated. */\n readonly name: string;\n /** The address of the site (its home). */\n readonly url: string;\n /** The address without the scheme, as people say it (`ui.krizaka.com`). */\n readonly host: string;\n readonly kind: SiteKind;\n readonly group: SiteGroup;\n readonly status: SiteStatus;\n readonly mark: SiteMark;\n /** The repository the site is built from. */\n readonly repo: string;\n}\n\nconst site = (s: Omit<Site, \"host\">): Site => ({ ...s, host: s.url.replace(/^https?:\\/\\//, \"\").replace(/\\/$/, \"\") });\n\n/** Every site of the family, in reading order (the group order, then the order inside each group). */\nexport const sites: readonly Site[] = [\n site({ id: \"krizaka\", name: \"Krizaka\", url: \"https://www.krizaka.com\", kind: \"company\", group: \"krizaka\", status: \"released\", mark: \"krizaka\", repo: \"https://github.com/krizaka/krizaka-com\" }),\n site({ id: \"orazaka\", name: \"Orazaka\", url: \"https://dev.orazaka.com\", kind: \"product\", group: \"products\", status: \"released\", mark: \"orazaka\", repo: \"https://github.com/krizaka/orazaka\" }),\n site({ id: \"orochia\", name: \"Orochia\", url: \"https://dev.orochia.com\", kind: \"product\", group: \"products\", status: \"released\", mark: \"orochia\", repo: \"https://github.com/krizaka/orochia\" }),\n site({ id: \"yasakia\", name: \"Yasakia\", url: \"https://dev.yasakia.com\", kind: \"product\", group: \"products\", status: \"development\", mark: \"yasakia\", repo: \"https://github.com/krizaka/yasakia\" }),\n site({ id: \"yororis\", name: \"Yororis\", url: \"https://dev.yororis.com\", kind: \"product\", group: \"products\", status: \"construction\", mark: \"yororis\", repo: \"https://github.com/krizaka/yororis\" }),\n site({ id: \"yomizaka\", name: \"Yomizaka\", url: \"https://dev.yomizaka.com\", kind: \"product\", group: \"products\", status: \"development\", mark: \"yomizaka\", repo: \"https://github.com/krizaka/yomizaka\" }),\n site({ id: \"kachizaka\", name: \"Kachizaka\", url: \"https://dev.kachizaka.com\", kind: \"product\", group: \"products\", status: \"development\", mark: \"kachizaka\", repo: \"https://github.com/krizaka/kachizaka\" }),\n site({ id: \"akinaza\", name: \"Akinaza\", url: \"https://dev.akinaza.com\", kind: \"product\", group: \"products\", status: \"development\", mark: \"akinaza\", repo: \"https://github.com/krizaka/akinaza\" }),\n site({ id: \"ui\", name: \"Krizaka UI\", url: \"https://ui.krizaka.com\", kind: \"open-source\", group: \"open-source\", status: \"released\", mark: \"krizaka\", repo: \"https://github.com/krizaka/krizaka-ui\" }),\n site({ id: \"java\", name: \"Krizaka Java\", url: \"https://java.krizaka.com\", kind: \"open-source\", group: \"open-source\", status: \"released\", mark: \"krizaka\", repo: \"https://github.com/krizaka/krizaka-build\" }),\n // The motion lab: built in the open on GitHub Pages; what proves itself there moves into Krizaka UI.\n site({ id: \"motion\", name: \"Krizaka Motion\", url: \"https://krizaka.github.io/krizaka-motion\", kind: \"open-source\", group: \"open-source\", status: \"development\", mark: \"krizaka\", repo: \"https://github.com/krizaka/krizaka-motion\" }),\n site({ id: \"github\", name: \"GitHub\", url: \"https://github.com/krizaka\", kind: \"open-source\", group: \"github\", status: \"released\", mark: \"github\", repo: \"https://github.com/krizaka\" }),\n];\n\n/** The groups, in reading order. */\nexport const siteGroups: readonly SiteGroup[] = [\"krizaka\", \"products\", \"open-source\", \"github\"];\n\n/** A site by id. */\nexport function siteById(id: SiteId): Site {\n const found = sites.find((s) => s.id === id);\n if (!found) throw new Error(`Unknown Krizaka site \"${id}\".`);\n return found;\n}\n\n/** The family grouped, in reading order: `[{ group, sites }]`, empty groups left out. */\nexport function sitesByGroup(): { group: SiteGroup; sites: Site[] }[] {\n return siteGroups.map((group) => ({ group, sites: sites.filter((s) => s.group === group) })).filter((g) => g.sites.length > 0);\n}\n\n/** The languages the family's words are written in. */\nexport type SiteLocale = \"en\" | \"fr\";\n\n/** The company's own pages, the footer's « Krizaka » column (the brand's home is the signature line's link). */\nexport type CompanyLinkId = \"story\" | \"blog\" | \"contact\";\nexport const companyLinks: readonly { id: CompanyLinkId; url: Record<SiteLocale, string> }[] = [\n { id: \"story\", url: { en: \"https://www.krizaka.com/story\", fr: \"https://www.krizaka.com/fr/story\" } },\n { id: \"blog\", url: { en: \"https://blog.krizaka.com\", fr: \"https://blog.krizaka.com\" } },\n { id: \"contact\", url: { en: \"https://www.krizaka.com/contact\", fr: \"https://www.krizaka.com/fr/contact\" } },\n];\n\n/** The words of the family: the switcher, the footer, each site's one line. */\nexport interface FamilyLabels {\n /** The family's name: the switcher's navigation and its button, the footer's navigation (“Krizaka family”). */\n family: string;\n /** The heading of each group. */\n groups: Record<SiteGroup, string>;\n /** The badge of a site that is not released. */\n status: Record<Exclude<SiteStatus, \"released\">, string>;\n /** Says which site is the current one (“You are here”). */\n current: string;\n /** One line per site: what it is. */\n descriptions: Record<SiteId, string>;\n /** The footer's signature, by the kind of the current site (“A Krizaka product”). */\n signature: Record<SiteKind, string>;\n /** The footer's place line (“Made in Montréal”). */\n place: string;\n /** The accessible name of the version (“Version”). */\n version: string;\n /** The language of these words: the company links open in it. @default \"en\" */\n lang?: SiteLocale;\n /** The company's pages in the footer's « Krizaka » column. @default the English words */\n company?: Record<CompanyLinkId, string>;\n}\n\n/** The family's words in English and French. Pass `familyLabels[locale]`, or your own translation of the same shape. */\nexport const familyLabels: Record<SiteLocale, FamilyLabels> = {\n en: {\n family: \"Krizaka family\",\n groups: { krizaka: \"Krizaka\", products: \"Products\", \"open-source\": \"Open source\", github: \"GitHub\" },\n status: { upcoming: \"Coming soon\", construction: \"Under construction\", development: \"In development\" },\n current: \"You are here\",\n descriptions: {\n krizaka: \"The company: our products, our open source, our story.\",\n orazaka: \"Sovereign AI on your own servers: chat, documents, images and video — and the engine under the other products.\",\n orochia: \"A video platform for creators.\",\n yasakia: \"Meet real people: introductions, and photos checked before you see them.\",\n yororis: \"A listening space with a face and a voice.\",\n yomizaka: \"Yomizaka reads your leases, contracts and invoices.\",\n kachizaka: \"Predictions among friends — live data, in real time.\",\n akinaza: \"Running a shop in Québec, for less — Loi 25 by design.\",\n ui: \"Components, tokens, icons and charts — web and React Native.\",\n java: \"Spring Boot building blocks on Maven Central.\",\n motion: \"The motion lab: the kit's motion, played live with its knobs.\",\n github: \"Every repository, in the open.\",\n },\n signature: { company: \"A Krizaka company\", product: \"A Krizaka product\", \"open-source\": \"A Krizaka open-source project\" },\n place: \"Made in Montréal\",\n version: \"Version\",\n lang: \"en\",\n company: { story: \"Our story\", blog: \"Blog\", contact: \"Contact us\" },\n },\n fr: {\n family: \"Famille Krizaka\",\n groups: { krizaka: \"Krizaka\", products: \"Produits\", \"open-source\": \"Open source\", github: \"GitHub\" },\n status: { upcoming: \"Bientôt\", construction: \"En construction\", development: \"En développement\" },\n current: \"Vous êtes ici\",\n descriptions: {\n krizaka: \"La compagnie : nos produits, notre open source, notre histoire.\",\n orazaka: \"L’IA souveraine sur vos propres serveurs : conversation, documents, images et vidéo — et le moteur des autres produits.\",\n orochia: \"Une plateforme vidéo pour les créateurs.\",\n yasakia: \"Rencontrez de vraies personnes : des présentations, et des photos vérifiées avant que vous les voyiez.\",\n yororis: \"Un espace d’écoute avec un visage et une voix.\",\n yomizaka: \"Yomizaka lit vos baux, contrats et factures.\",\n kachizaka: \"Les pronostics entre amis — des données en direct.\",\n akinaza: \"Tenir une boutique au Québec, pour moins cher — Loi 25 dès la conception.\",\n ui: \"Composants, jetons, icônes et graphiques — web et React Native.\",\n java: \"Des briques Spring Boot sur Maven Central.\",\n motion: \"Le labo du mouvement : le mouvement du kit, joué en direct, avec ses réglages.\",\n github: \"Tous les dépôts, au grand jour.\",\n },\n signature: { company: \"Une compagnie Krizaka\", product: \"Un produit Krizaka\", \"open-source\": \"Un projet open source de Krizaka\" },\n place: \"Fait à Montréal\",\n version: \"Version\",\n lang: \"fr\",\n company: { story: \"Notre histoire\", blog: \"Blogue\", contact: \"Nous écrire\" },\n },\n};\n"],"mappings":"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","names":[]}
|
|
@@ -13,14 +13,14 @@ var slider = tv({
|
|
|
13
13
|
header: "flex items-baseline justify-between gap-3 text-xs font-semibold text-fg-secondary",
|
|
14
14
|
value: "font-mono text-[11px] tabular-nums text-fg-secondary",
|
|
15
15
|
control: "relative flex touch-none select-none items-center data-disabled:cursor-not-allowed data-disabled:opacity-40 data-[orientation=horizontal]:h-6 data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:min-h-40 data-[orientation=vertical]:w-6 data-[orientation=vertical]:flex-col",
|
|
16
|
-
track: "relative grow overflow-hidden rounded-
|
|
17
|
-
range: "absolute rounded-
|
|
16
|
+
track: "relative grow overflow-hidden rounded-sm bg-surface-3 inset-shadow-well data-[orientation=horizontal]:h-1.5 data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-1.5",
|
|
17
|
+
range: "absolute rounded-sm data-[orientation=horizontal]:h-full data-[orientation=vertical]:w-full",
|
|
18
18
|
thumb: "group/thumb relative block h-5 w-5 cursor-grab rounded-full border-2 border-accent bg-fg-on-media shadow-raised transition-[box-shadow,scale] duration-150 hover:ring-4 hover:ring-accent/15 focus-visible:outline-hidden focus-visible:focus-ring active:scale-110 active:cursor-grabbing motion-reduce:transition-none motion-reduce:active:scale-100",
|
|
19
19
|
// The value over the thumb: shown while the thumb is hovered, focused or held.
|
|
20
20
|
bubble: "pointer-events-none absolute bottom-full left-1/2 mb-2.5 -translate-x-1/2 whitespace-nowrap rounded-lg bg-fg px-2 py-1 font-mono text-[11px] font-semibold tabular-nums text-surface-0 opacity-0 shadow-floating transition-opacity duration-150 after:absolute after:left-1/2 after:top-full after:-translate-x-1/2 after:border-4 after:border-transparent after:border-t-fg group-hover/thumb:opacity-100 group-focus-visible/thumb:opacity-100 group-active/thumb:opacity-100 data-[always]:opacity-100 motion-reduce:transition-none",
|
|
21
21
|
bubbleVertical: "bottom-auto left-full top-1/2 mb-0 ml-3 -translate-x-0 -translate-y-1/2 after:hidden",
|
|
22
22
|
ticks: "pointer-events-none absolute inset-0",
|
|
23
|
-
tick: "absolute rounded-
|
|
23
|
+
tick: "absolute rounded-sm bg-border-strong data-[on]:bg-on-accent/70 data-[orientation=horizontal]:top-1/2 data-[orientation=horizontal]:h-1 data-[orientation=horizontal]:w-px data-[orientation=horizontal]:-translate-x-1/2 data-[orientation=horizontal]:-translate-y-1/2 data-[orientation=vertical]:left-1/2 data-[orientation=vertical]:h-px data-[orientation=vertical]:w-1 data-[orientation=vertical]:-translate-x-1/2 data-[orientation=vertical]:translate-y-1/2",
|
|
24
24
|
marks: "relative h-4 w-full text-[11px] font-medium tabular-nums text-fg-secondary",
|
|
25
25
|
mark: "absolute top-0 -translate-x-1/2 whitespace-nowrap first:translate-x-0 last:-translate-x-full"
|
|
26
26
|
},
|
|
@@ -132,4 +132,4 @@ function Slider({
|
|
|
132
132
|
export {
|
|
133
133
|
Slider
|
|
134
134
|
};
|
|
135
|
-
//# sourceMappingURL=chunk-
|
|
135
|
+
//# sourceMappingURL=chunk-ADRUEPYC.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/slider/slider.tsx"],"sourcesContent":["// Client. Radix Slider: role=\"slider\" on each thumb, arrows / Page Up / Page Down / Home / End, a range with two\n// thumbs, horizontal or vertical. The words arrive as props: `label` names the thumb(s), `formatValue` gives the\n// aria-valuetext and the value shown (above the track, or floating over the thumb while it is touched). `ticks` draws the\n// graduations of the steps (and `marks` their words under the track); `tone` fills with the brand's gradient or its\n// accent alone.\nimport { Slider as SliderPrimitive } from \"radix-ui\";\nimport * as React from \"react\";\n\nimport { tv } from \"../tv\";\n\nexport const slider = tv({\n slots: {\n root: \"flex flex-col gap-2 data-[orientation=vertical]:h-full data-[orientation=vertical]:items-center\",\n header: \"flex items-baseline justify-between gap-3 text-xs font-semibold text-fg-secondary\",\n value: \"font-mono text-[11px] tabular-nums text-fg-secondary\",\n control:\n \"relative flex touch-none select-none items-center data-disabled:cursor-not-allowed data-disabled:opacity-40 \" +\n \"data-[orientation=horizontal]:h-6 data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:min-h-40 data-[orientation=vertical]:w-6 data-[orientation=vertical]:flex-col\",\n track:\n \"relative grow overflow-hidden rounded-sm bg-surface-3 inset-shadow-well \" +\n \"data-[orientation=horizontal]:h-1.5 data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-1.5\",\n range: \"absolute rounded-sm data-[orientation=horizontal]:h-full data-[orientation=vertical]:w-full\",\n thumb:\n \"group/thumb relative block h-5 w-5 cursor-grab rounded-full border-2 border-accent bg-fg-on-media shadow-raised transition-[box-shadow,scale] duration-150 \" +\n \"hover:ring-4 hover:ring-accent/15 focus-visible:outline-hidden focus-visible:focus-ring active:scale-110 active:cursor-grabbing motion-reduce:transition-none motion-reduce:active:scale-100\",\n // The value over the thumb: shown while the thumb is hovered, focused or held.\n bubble:\n \"pointer-events-none absolute bottom-full left-1/2 mb-2.5 -translate-x-1/2 whitespace-nowrap rounded-lg bg-fg px-2 py-1 font-mono text-[11px] font-semibold tabular-nums text-surface-0 opacity-0 shadow-floating \" +\n \"transition-opacity duration-150 after:absolute after:left-1/2 after:top-full after:-translate-x-1/2 after:border-4 after:border-transparent after:border-t-fg \" +\n \"group-hover/thumb:opacity-100 group-focus-visible/thumb:opacity-100 group-active/thumb:opacity-100 data-[always]:opacity-100 motion-reduce:transition-none\",\n bubbleVertical: \"bottom-auto left-full top-1/2 mb-0 ml-3 -translate-x-0 -translate-y-1/2 after:hidden\",\n ticks: \"pointer-events-none absolute inset-0\",\n tick: \"absolute rounded-sm bg-border-strong data-[on]:bg-on-accent/70 data-[orientation=horizontal]:top-1/2 data-[orientation=horizontal]:h-1 data-[orientation=horizontal]:w-px data-[orientation=horizontal]:-translate-x-1/2 data-[orientation=horizontal]:-translate-y-1/2 data-[orientation=vertical]:left-1/2 data-[orientation=vertical]:h-px data-[orientation=vertical]:w-1 data-[orientation=vertical]:-translate-x-1/2 data-[orientation=vertical]:translate-y-1/2\",\n marks: \"relative h-4 w-full text-[11px] font-medium tabular-nums text-fg-secondary\",\n mark: \"absolute top-0 -translate-x-1/2 whitespace-nowrap first:translate-x-0 last:-translate-x-full\",\n },\n variants: {\n tone: {\n /** The brand's signature: accent → accent-2, a glow under it. */\n gradient: { range: \"bg-linear-to-r from-accent to-accent-2 shadow-glow data-[orientation=vertical]:bg-linear-to-t\" },\n /** The accent alone. */\n solid: { range: \"bg-accent\" },\n },\n size: {\n md: {},\n lg: {\n track: \"data-[orientation=horizontal]:h-2.5 data-[orientation=vertical]:w-2.5\",\n thumb: \"h-6 w-6\",\n control: \"data-[orientation=horizontal]:h-8 data-[orientation=vertical]:w-8\",\n },\n },\n },\n defaultVariants: { tone: \"gradient\", size: \"md\" },\n});\n\nexport type SliderValue = number | [number, number];\n\nexport type SliderMark = {\n /** Where the mark stands. */\n value: number;\n /** Its words under the track (\"0\", \"50 %\", \"Max\"), passed translated. */\n label: string;\n};\n\nexport type SliderProps<V extends SliderValue = number> = Omit<\n React.ComponentProps<typeof SliderPrimitive.Root>,\n \"value\" | \"defaultValue\" | \"onValueChange\" | \"onValueCommit\" | \"children\"\n> & {\n /** One number (a thumb) or two (a range). Controlled with `onValueChange`. */\n value?: V;\n /** The value at first, uncontrolled: one number, or two for a range. */\n defaultValue?: V;\n /** Called on every move, with one number or two. */\n onValueChange?: (value: V) => void;\n /** Called once the drag or the key press ends. */\n onValueCommit?: (value: V) => void;\n /** The accessible name — of the thumb, or of both thumbs of a range — passed translated. */\n label: string;\n /** For a range: each thumb's own name ([\"Minimum\", \"Maximum\"]), passed translated. */\n thumbLabels?: [string, string];\n /** The value as words (aria-valuetext) and as shown: \"1.5×\", \"−12 %\", \"3 min\". */\n formatValue?: (value: number) => string;\n /** Shows the label and the value above the track. Without it, `label` only names the thumb. */\n showLabel?: boolean;\n /** Shows the value floating over the thumb while it is hovered, focused or held (`\"always\"`: at all times). */\n floatingValue?: boolean | \"always\";\n /** Fills from this value instead of the minimum (a ±range from 0: brightness, balance). One horizontal thumb only. */\n origin?: number;\n /** Draws a graduation at every step (`true`, up to 40 of them) or at the values given. */\n ticks?: boolean | readonly number[];\n /** Words under the track at some values (`[{ value: 0, label: \"0\" }, { value: 100, label: \"100\" }]`). Horizontal only. */\n marks?: readonly SliderMark[];\n /**\n * `gradient` (the brand's accent → accent-2, a glow) or `solid` (the accent alone).\n * @default \"gradient\"\n */\n tone?: \"gradient\" | \"solid\";\n /**\n * md · lg (a thicker track and thumb: a hero control, a touch screen).\n * @default \"md\"\n */\n size?: \"md\" | \"lg\";\n};\n\nconst toArray = (v: SliderValue | undefined) => (v === undefined ? undefined : typeof v === \"number\" ? [v] : v);\n\n/** A slider on one value or a range: `value`/`defaultValue` + `onValueChange`, `min`, `max`, `step`, `orientation`. */\nexport function Slider<V extends SliderValue = number>({\n value,\n defaultValue,\n onValueChange,\n onValueCommit,\n label,\n thumbLabels,\n formatValue = String,\n showLabel,\n floatingValue,\n origin,\n ticks,\n marks,\n tone,\n size,\n min = 0,\n max = 100,\n step = 1,\n orientation = \"horizontal\",\n className,\n ...props\n}: SliderProps<V>) {\n const s = slider({ tone, size });\n const range = Array.isArray(value ?? defaultValue);\n const vertical = orientation === \"vertical\";\n const [inner, setInner] = React.useState(() => toArray(defaultValue) ?? [min]);\n const current = toArray(value) ?? inner;\n const out = (next: number[]) => (range ? next : next[0]) as V;\n const pct = (v: number) => ((v - min) / (max - min || 1)) * 100;\n const fill =\n origin !== undefined && !range && !vertical\n ? { left: `${Math.min(pct(origin), pct(current[0]!))}%`, right: `${100 - Math.max(pct(origin), pct(current[0]!))}%` }\n : undefined;\n const lo = range ? Math.min(...current) : (origin ?? min);\n const hi = range ? Math.max(...current) : current[0]!;\n const tickValues = ticks === true ? (max - min) / step <= 40 ? Array.from({ length: Math.round((max - min) / step) + 1 }, (_, i) => min + i * step) : [] : ticks ? [...ticks] : [];\n const id = React.useId();\n return (\n <div className={s.root({ className })} data-range={range ? \"\" : undefined} data-orientation={orientation}>\n {showLabel && (\n <div className={s.header()}>\n <span id={`${id}-label`}>{label}</span>\n <span className={s.value()} aria-hidden>\n {current.map(formatValue).join(\" – \")}\n </span>\n </div>\n )}\n <SliderPrimitive.Root\n min={min}\n max={max}\n step={step}\n orientation={orientation}\n value={current}\n onValueChange={(next) => {\n if (value === undefined) setInner(next);\n onValueChange?.(out(next));\n }}\n onValueCommit={onValueCommit && ((next) => onValueCommit(out(next)))}\n className={s.control()}\n {...props}\n >\n <SliderPrimitive.Track className={s.track()}>\n {fill ? <span data-origin=\"\" data-orientation={orientation} className={s.range()} style={fill} /> : <SliderPrimitive.Range className={s.range()} />}\n {tickValues.length ? (\n <span aria-hidden className={s.ticks()}>\n {tickValues.map((t) => (\n <span\n key={t}\n data-orientation={orientation}\n data-on={t > lo && t < hi ? \"\" : undefined}\n className={s.tick()}\n style={vertical ? { bottom: `${pct(t)}%` } : { left: `${pct(t)}%` }}\n />\n ))}\n </span>\n ) : null}\n </SliderPrimitive.Track>\n {current.map((v, i) => (\n <SliderPrimitive.Thumb\n key={i}\n aria-label={range ? (thumbLabels?.[i] ?? label) : showLabel ? undefined : label}\n aria-labelledby={!range && showLabel ? `${id}-label` : undefined}\n aria-valuetext={formatValue(v)}\n className={s.thumb()}\n >\n {floatingValue ? (\n <span aria-hidden data-always={floatingValue === \"always\" ? \"\" : undefined} className={s.bubble({ className: vertical ? s.bubbleVertical() : undefined })}>\n {formatValue(v)}\n </span>\n ) : null}\n </SliderPrimitive.Thumb>\n ))}\n </SliderPrimitive.Root>\n {marks?.length && !vertical ? (\n <div aria-hidden className={s.marks()}>\n {marks.map((m) => (\n <span key={m.value} className={s.mark()} style={{ left: `${pct(m.value)}%` }}>\n {m.label}\n </span>\n ))}\n </div>\n ) : null}\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -3,7 +3,7 @@ import { Slot } from "radix-ui";
|
|
|
3
3
|
import { tv } from "tailwind-variants";
|
|
4
4
|
import { jsx } from "react/jsx-runtime";
|
|
5
5
|
var chipVariants = tv({
|
|
6
|
-
base: "inline-flex shrink-0 select-none items-center justify-center gap-1.5 whitespace-nowrap rounded-
|
|
6
|
+
base: "inline-flex shrink-0 select-none items-center justify-center gap-1.5 whitespace-nowrap rounded-sm border font-semibold no-underline transition-colors focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring",
|
|
7
7
|
variants: {
|
|
8
8
|
size: { sm: "h-7 px-3 text-xs", md: "h-9 px-3.5 text-xs" },
|
|
9
9
|
selected: {
|
|
@@ -30,4 +30,4 @@ export {
|
|
|
30
30
|
chipVariants,
|
|
31
31
|
ChipLink
|
|
32
32
|
};
|
|
33
|
-
//# sourceMappingURL=chunk-
|
|
33
|
+
//# sourceMappingURL=chunk-F2UZ2WWL.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/chip-link/chip-link.tsx"],"sourcesContent":["// Server-safe: no hook, no context. A chip that is a link — a filter that is an address (`/explore?tag=night`): the look\n// of `Chip`, the current filter marked by `selected` (`aria-current`, the accent), usable in a Server Component.\n// `chipVariants` styles anything else (a router link you render yourself).\nimport { Slot } from \"radix-ui\";\nimport type * as React from \"react\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nexport const chipVariants = tv({\n base:\n \"inline-flex shrink-0 select-none items-center justify-center gap-1.5 whitespace-nowrap rounded-sm border font-semibold no-underline transition-colors \" +\n \"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring\",\n variants: {\n size: { sm: \"h-7 px-3 text-xs\", md: \"h-9 px-3.5 text-xs\" },\n selected: {\n false: \"border-border-default bg-surface-1 text-fg-secondary hover:border-border-strong hover:text-fg\",\n true: \"border-accent bg-accent-soft text-fg\",\n },\n },\n defaultVariants: { size: \"md\", selected: false },\n});\n\nexport type ChipVariantsProps = VariantProps<typeof chipVariants>;\n\nexport type ChipLinkProps = React.ComponentProps<\"a\"> & {\n /**\n * sm · md.\n * @default \"md\"\n */\n size?: ChipVariantsProps[\"size\"];\n /** The current filter: the accent, `aria-current` (`page` by default) and `data-state=\"on\"`. */\n selected?: boolean;\n /**\n * What `aria-current` says when selected: `page` (a filter that is a page) or `true`.\n * @default \"page\"\n */\n current?: \"page\" | \"true\";\n /** Renders your router's `<Link>` with the chip's look. */\n asChild?: boolean;\n};\n\n/** A filter that is a link, with the look of `Chip`. */\nexport function ChipLink({ size, selected = false, current = \"page\", asChild, className, ...props }: ChipLinkProps) {\n const Comp = asChild ? Slot.Root : \"a\";\n return (\n <Comp\n data-state={selected ? \"on\" : \"off\"}\n aria-current={selected ? current : undefined}\n className={chipVariants({ size, selected, className })}\n {...props}\n />\n );\n}\n"],"mappings":";AAGA,SAAS,YAAY;AAErB,SAAS,UAA6B;AAuClC;AArCG,IAAM,eAAe,GAAG;AAAA,EAC7B,MACE;AAAA,EAEF,UAAU;AAAA,IACR,MAAM,EAAE,IAAI,oBAAoB,IAAI,qBAAqB;AAAA,IACzD,UAAU;AAAA,MACR,OAAO;AAAA,MACP,MAAM;AAAA,IACR;AAAA,EACF;AAAA,EACA,iBAAiB,EAAE,MAAM,MAAM,UAAU,MAAM;AACjD,CAAC;AAsBM,SAAS,SAAS,EAAE,MAAM,WAAW,OAAO,UAAU,QAAQ,SAAS,WAAW,GAAG,MAAM,GAAkB;AAClH,QAAM,OAAO,UAAU,KAAK,OAAO;AACnC,SACE;AAAA,IAAC;AAAA;AAAA,MACC,cAAY,WAAW,OAAO;AAAA,MAC9B,gBAAc,WAAW,UAAU;AAAA,MACnC,WAAW,aAAa,EAAE,MAAM,UAAU,UAAU,CAAC;AAAA,MACpD,GAAG;AAAA;AAAA,EACN;AAEJ;","names":[]}
|
package/dist/image-cropper.js
CHANGED
package/dist/kanban.js
CHANGED
|
@@ -10,7 +10,7 @@ var kanban = tv({
|
|
|
10
10
|
column: "flex w-72 shrink-0 flex-col rounded-xl border border-border-default bg-surface-1 data-[over]:border-accent data-[over]:bg-accent-soft/40",
|
|
11
11
|
header: "flex items-center gap-2 px-3 pb-2 pt-3",
|
|
12
12
|
title: "min-w-0 flex-1 truncate text-sm font-semibold text-fg",
|
|
13
|
-
count: "rounded-
|
|
13
|
+
count: "rounded-sm bg-surface-3 px-2 text-xs font-semibold tabular-nums text-fg-secondary data-[over-limit]:bg-danger data-[over-limit]:text-on-accent",
|
|
14
14
|
list: "m-0 flex min-h-16 list-none flex-col gap-2 p-2 pt-0",
|
|
15
15
|
card: "cursor-grab rounded-lg border border-border-default bg-surface-0 p-3 text-sm text-fg shadow-xs outline-hidden transition-shadow focus-visible:ring-2 focus-visible:ring-ring active:cursor-grabbing data-[grabbed]:ring-2 data-[grabbed]:ring-accent data-[grabbed]:shadow-lg data-[dragging]:opacity-40",
|
|
16
16
|
empty: "rounded-lg border border-dashed border-border-default px-3 py-4 text-center text-xs text-fg-secondary"
|
package/dist/kanban.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/kanban/kanban.tsx"],"sourcesContent":["// Client (the drag, the keyboard move, the announcements). Cards in columns that move by drag and drop — and by the\n// keyboard: Space picks a card up, the arrows carry it (← → between columns, ↑ ↓ within one), Space drops it, Esc puts it\n// back. Every move is announced in words. The app owns the data: `onMove` says where a card went.\nimport * as React from \"react\";\nimport { tv } from \"tailwind-variants\";\n\nexport const kanban = tv({\n slots: {\n root: \"flex w-full gap-3 overflow-x-auto pb-2\",\n column: \"flex w-72 shrink-0 flex-col rounded-xl border border-border-default bg-surface-1 data-[over]:border-accent data-[over]:bg-accent-soft/40\",\n header: \"flex items-center gap-2 px-3 pb-2 pt-3\",\n title: \"min-w-0 flex-1 truncate text-sm font-semibold text-fg\",\n count: \"rounded-full bg-surface-3 px-2 text-xs font-semibold tabular-nums text-fg-secondary data-[over-limit]:bg-danger data-[over-limit]:text-on-accent\",\n list: \"m-0 flex min-h-16 list-none flex-col gap-2 p-2 pt-0\",\n card:\n \"cursor-grab rounded-lg border border-border-default bg-surface-0 p-3 text-sm text-fg shadow-xs outline-hidden transition-shadow \" +\n \"focus-visible:ring-2 focus-visible:ring-ring active:cursor-grabbing data-[grabbed]:ring-2 data-[grabbed]:ring-accent data-[grabbed]:shadow-lg data-[dragging]:opacity-40\",\n empty: \"rounded-lg border border-dashed border-border-default px-3 py-4 text-center text-xs text-fg-secondary\",\n },\n});\n\nexport type KanbanColumn = {\n /** A stable id. */\n id: string;\n /** Its name — passed translated (“To review”). */\n title: string;\n /** The most cards it should hold: the count turns to danger past it. */\n limit?: number;\n};\n\nexport type KanbanMove = {\n /** The card moved. */\n cardId: string;\n /** Where it came from. */\n from: string;\n /** The column it went to. */\n to: string;\n /** Its position in that column (0 = top). */\n index: number;\n};\n\nexport type KanbanLabels = {\n /** The hint read on a card: how to move it with the keyboard. */\n instructions: string;\n /** Announced when a card is picked up: `(card, column) => …`. */\n grabbed: (card: string, column: string) => string;\n /** Announced as it moves: `(card, column, position, total) => …`. */\n moved: (card: string, column: string, position: number, total: number) => string;\n /** Announced when it is dropped. */\n dropped: (card: string, column: string, position: number) => string;\n /** Announced when the move is cancelled. */\n cancelled: (card: string) => string;\n /** A column without card (“No card”). */\n empty: string;\n};\n\nexport const kanbanLabels: KanbanLabels = {\n instructions: \"Press Space to pick it up, the arrow keys to move it, Space to drop it, Escape to cancel.\",\n grabbed: (card, column) => `${card} picked up, in ${column}.`,\n moved: (card, column, position, total) => `${card}: ${column}, position ${position} of ${total}.`,\n dropped: (card, column, position) => `${card} dropped in ${column}, position ${position}.`,\n cancelled: (card) => `Move of ${card} cancelled.`,\n empty: \"No card\",\n};\n\nexport type KanbanProps<T> = {\n /** The columns, in order. */\n columns: readonly KanbanColumn[];\n /** The cards, in their order within each column. */\n cards: readonly T[];\n /** A card's id. */\n getId: (card: T) => string;\n /** A card's column. */\n getColumn: (card: T) => string;\n /** A card's name, for the announcements. */\n getTitle: (card: T) => string;\n /** What a card shows. */\n renderCard: (card: T) => React.ReactNode;\n /** Called when a card is dropped somewhere new: update the data here. */\n onMove: (move: KanbanMove) => void;\n /** The board's accessible name (“Moderation queue”). */\n \"aria-label\": string;\n /** The words, passed translated; English by default. */\n labels?: Partial<KanbanLabels>;\n /** Classes merged on the root. */\n className?: string;\n};\n\ntype Placement = { column: string; index: number };\n\n/**\n * A board of cards in columns — a moderation queue, a release plan: drag and drop with the pointer, or Space and the\n * arrow keys, every step announced. Column limits show in the counts.\n */\nexport function Kanban<T>({ columns, cards, getId, getColumn, getTitle, renderCard, onMove, \"aria-label\": label, labels: words, className }: KanbanProps<T>) {\n const labels = { ...kanbanLabels, ...words };\n const s = kanban();\n const instructionsId = React.useId();\n const [grab, setGrab] = React.useState<{ id: string; origin: Placement; at: Placement } | null>(null);\n const [dragging, setDragging] = React.useState<string | null>(null);\n const [over, setOver] = React.useState<Placement | null>(null);\n const [message, setMessage] = React.useState(\"\");\n const refs = React.useRef(new Map<string, HTMLLIElement>());\n const byColumn = (column: string, without?: string) => cards.filter((c) => getColumn(c) === column && getId(c) !== without);\n const titleOf = (id: string) => {\n const card = cards.find((c) => getId(c) === id);\n return card ? getTitle(card) : id;\n };\n const columnTitle = (id: string) => columns.find((c) => c.id === id)?.title ?? id;\n const placementOf = (id: string): Placement => {\n const card = cards.find((c) => getId(c) === id)!;\n const column = getColumn(card);\n return { column, index: byColumn(column).findIndex((c) => getId(c) === id) };\n };\n const commit = (id: string, from: Placement, to: Placement) => {\n if (from.column !== to.column || from.index !== to.index) onMove({ cardId: id, from: from.column, to: to.column, index: to.index });\n };\n // The cards of a column as shown, with the grabbed card at its keyboard position.\n const shown = (column: string) => {\n const list = byColumn(column, grab?.id);\n if (grab && grab.at.column === column) {\n const card = cards.find((c) => getId(c) === grab.id);\n if (card) list.splice(grab.at.index, 0, card);\n }\n return list;\n };\n React.useEffect(() => {\n if (grab) refs.current.get(grab.id)?.focus();\n }, [grab]);\n\n const onKeyDown = (event: React.KeyboardEvent, id: string) => {\n const title = titleOf(id);\n if (!grab) {\n if (event.key === \" \" || event.key === \"Enter\") {\n event.preventDefault();\n const origin = placementOf(id);\n setGrab({ id, origin, at: origin });\n setMessage(labels.grabbed(title, columnTitle(origin.column)));\n }\n return;\n }\n const { at, origin } = grab;\n const columnIndex = columns.findIndex((c) => c.id === at.column);\n let next: Placement | null = null;\n if (event.key === \"ArrowLeft\" && columnIndex > 0) next = { column: columns[columnIndex - 1]!.id, index: Math.min(at.index, byColumn(columns[columnIndex - 1]!.id, id).length) };\n if (event.key === \"ArrowRight\" && columnIndex < columns.length - 1) next = { column: columns[columnIndex + 1]!.id, index: Math.min(at.index, byColumn(columns[columnIndex + 1]!.id, id).length) };\n if (event.key === \"ArrowUp\" && at.index > 0) next = { ...at, index: at.index - 1 };\n if (event.key === \"ArrowDown\" && at.index < byColumn(at.column, id).length) next = { ...at, index: at.index + 1 };\n if (next) {\n event.preventDefault();\n setGrab({ ...grab, at: next });\n setMessage(labels.moved(title, columnTitle(next.column), next.index + 1, byColumn(next.column, id).length + 1));\n return;\n }\n if (event.key === \" \" || event.key === \"Enter\") {\n event.preventDefault();\n setGrab(null);\n commit(id, origin, at);\n setMessage(labels.dropped(title, columnTitle(at.column), at.index + 1));\n } else if (event.key === \"Escape\") {\n event.preventDefault();\n setGrab(null);\n setMessage(labels.cancelled(title));\n }\n };\n\n const indexAt = (column: string, y: number) => {\n const list = byColumn(column, dragging ?? undefined);\n const i = list.findIndex((c) => {\n const box = refs.current.get(getId(c))?.getBoundingClientRect();\n return box ? y < box.top + box.height / 2 : false;\n });\n return i === -1 ? list.length : i;\n };\n\n return (\n <div role=\"group\" aria-label={label} className={s.root({ className })}>\n <p id={instructionsId} className=\"sr-only\">\n {labels.instructions}\n </p>\n <p className=\"sr-only\" aria-live=\"assertive\">\n {message}\n </p>\n {columns.map((column) => {\n const list = shown(column.id);\n const overLimit = column.limit !== undefined && list.length > column.limit;\n return (\n <section\n key={column.id}\n aria-label={column.title}\n data-over={over?.column === column.id || undefined}\n className={s.column()}\n onDragOver={(e) => {\n if (!dragging) return;\n e.preventDefault();\n setOver({ column: column.id, index: indexAt(column.id, e.clientY) });\n }}\n onDragLeave={(e) => {\n if (!e.currentTarget.contains(e.relatedTarget as Node | null)) setOver(null);\n }}\n onDrop={(e) => {\n e.preventDefault();\n if (dragging) commit(dragging, placementOf(dragging), { column: column.id, index: indexAt(column.id, e.clientY) });\n setDragging(null);\n setOver(null);\n }}\n >\n <header className={s.header()}>\n <h3 className={s.title()}>{column.title}</h3>\n <span className={s.count()} data-over-limit={overLimit || undefined}>\n {column.limit !== undefined ? `${list.length}/${column.limit}` : list.length}\n </span>\n </header>\n <ul className={s.list()}>\n {list.length === 0 ? <li className={s.empty()}>{labels.empty}</li> : null}\n {list.map((card) => {\n const id = getId(card);\n return (\n <li\n key={id}\n ref={(el) => {\n if (el) refs.current.set(id, el);\n else refs.current.delete(id);\n }}\n tabIndex={0}\n draggable\n aria-describedby={instructionsId}\n aria-roledescription=\"card\"\n data-grabbed={grab?.id === id || undefined}\n data-dragging={dragging === id || undefined}\n className={s.card()}\n onKeyDown={(e) => onKeyDown(e, id)}\n onFocus={() => {\n // Tab to another card while one is carried: the carried one goes back.\n if (grab && grab.id !== id) {\n setMessage(labels.cancelled(titleOf(grab.id)));\n setGrab(null);\n }\n }}\n onDragStart={(e) => {\n e.dataTransfer.effectAllowed = \"move\";\n e.dataTransfer.setData(\"text/plain\", id);\n setDragging(id);\n }}\n onDragEnd={() => {\n setDragging(null);\n setOver(null);\n }}\n >\n {renderCard(card)}\n </li>\n );\n })}\n </ul>\n </section>\n );\n })}\n </div>\n );\n}\n"],"mappings":"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","names":["origin"]}
|
|
1
|
+
{"version":3,"sources":["../src/kanban/kanban.tsx"],"sourcesContent":["// Client (the drag, the keyboard move, the announcements). Cards in columns that move by drag and drop — and by the\n// keyboard: Space picks a card up, the arrows carry it (← → between columns, ↑ ↓ within one), Space drops it, Esc puts it\n// back. Every move is announced in words. The app owns the data: `onMove` says where a card went.\nimport * as React from \"react\";\nimport { tv } from \"tailwind-variants\";\n\nexport const kanban = tv({\n slots: {\n root: \"flex w-full gap-3 overflow-x-auto pb-2\",\n column: \"flex w-72 shrink-0 flex-col rounded-xl border border-border-default bg-surface-1 data-[over]:border-accent data-[over]:bg-accent-soft/40\",\n header: \"flex items-center gap-2 px-3 pb-2 pt-3\",\n title: \"min-w-0 flex-1 truncate text-sm font-semibold text-fg\",\n count: \"rounded-sm bg-surface-3 px-2 text-xs font-semibold tabular-nums text-fg-secondary data-[over-limit]:bg-danger data-[over-limit]:text-on-accent\",\n list: \"m-0 flex min-h-16 list-none flex-col gap-2 p-2 pt-0\",\n card:\n \"cursor-grab rounded-lg border border-border-default bg-surface-0 p-3 text-sm text-fg shadow-xs outline-hidden transition-shadow \" +\n \"focus-visible:ring-2 focus-visible:ring-ring active:cursor-grabbing data-[grabbed]:ring-2 data-[grabbed]:ring-accent data-[grabbed]:shadow-lg data-[dragging]:opacity-40\",\n empty: \"rounded-lg border border-dashed border-border-default px-3 py-4 text-center text-xs text-fg-secondary\",\n },\n});\n\nexport type KanbanColumn = {\n /** A stable id. */\n id: string;\n /** Its name — passed translated (“To review”). */\n title: string;\n /** The most cards it should hold: the count turns to danger past it. */\n limit?: number;\n};\n\nexport type KanbanMove = {\n /** The card moved. */\n cardId: string;\n /** Where it came from. */\n from: string;\n /** The column it went to. */\n to: string;\n /** Its position in that column (0 = top). */\n index: number;\n};\n\nexport type KanbanLabels = {\n /** The hint read on a card: how to move it with the keyboard. */\n instructions: string;\n /** Announced when a card is picked up: `(card, column) => …`. */\n grabbed: (card: string, column: string) => string;\n /** Announced as it moves: `(card, column, position, total) => …`. */\n moved: (card: string, column: string, position: number, total: number) => string;\n /** Announced when it is dropped. */\n dropped: (card: string, column: string, position: number) => string;\n /** Announced when the move is cancelled. */\n cancelled: (card: string) => string;\n /** A column without card (“No card”). */\n empty: string;\n};\n\nexport const kanbanLabels: KanbanLabels = {\n instructions: \"Press Space to pick it up, the arrow keys to move it, Space to drop it, Escape to cancel.\",\n grabbed: (card, column) => `${card} picked up, in ${column}.`,\n moved: (card, column, position, total) => `${card}: ${column}, position ${position} of ${total}.`,\n dropped: (card, column, position) => `${card} dropped in ${column}, position ${position}.`,\n cancelled: (card) => `Move of ${card} cancelled.`,\n empty: \"No card\",\n};\n\nexport type KanbanProps<T> = {\n /** The columns, in order. */\n columns: readonly KanbanColumn[];\n /** The cards, in their order within each column. */\n cards: readonly T[];\n /** A card's id. */\n getId: (card: T) => string;\n /** A card's column. */\n getColumn: (card: T) => string;\n /** A card's name, for the announcements. */\n getTitle: (card: T) => string;\n /** What a card shows. */\n renderCard: (card: T) => React.ReactNode;\n /** Called when a card is dropped somewhere new: update the data here. */\n onMove: (move: KanbanMove) => void;\n /** The board's accessible name (“Moderation queue”). */\n \"aria-label\": string;\n /** The words, passed translated; English by default. */\n labels?: Partial<KanbanLabels>;\n /** Classes merged on the root. */\n className?: string;\n};\n\ntype Placement = { column: string; index: number };\n\n/**\n * A board of cards in columns — a moderation queue, a release plan: drag and drop with the pointer, or Space and the\n * arrow keys, every step announced. Column limits show in the counts.\n */\nexport function Kanban<T>({ columns, cards, getId, getColumn, getTitle, renderCard, onMove, \"aria-label\": label, labels: words, className }: KanbanProps<T>) {\n const labels = { ...kanbanLabels, ...words };\n const s = kanban();\n const instructionsId = React.useId();\n const [grab, setGrab] = React.useState<{ id: string; origin: Placement; at: Placement } | null>(null);\n const [dragging, setDragging] = React.useState<string | null>(null);\n const [over, setOver] = React.useState<Placement | null>(null);\n const [message, setMessage] = React.useState(\"\");\n const refs = React.useRef(new Map<string, HTMLLIElement>());\n const byColumn = (column: string, without?: string) => cards.filter((c) => getColumn(c) === column && getId(c) !== without);\n const titleOf = (id: string) => {\n const card = cards.find((c) => getId(c) === id);\n return card ? getTitle(card) : id;\n };\n const columnTitle = (id: string) => columns.find((c) => c.id === id)?.title ?? id;\n const placementOf = (id: string): Placement => {\n const card = cards.find((c) => getId(c) === id)!;\n const column = getColumn(card);\n return { column, index: byColumn(column).findIndex((c) => getId(c) === id) };\n };\n const commit = (id: string, from: Placement, to: Placement) => {\n if (from.column !== to.column || from.index !== to.index) onMove({ cardId: id, from: from.column, to: to.column, index: to.index });\n };\n // The cards of a column as shown, with the grabbed card at its keyboard position.\n const shown = (column: string) => {\n const list = byColumn(column, grab?.id);\n if (grab && grab.at.column === column) {\n const card = cards.find((c) => getId(c) === grab.id);\n if (card) list.splice(grab.at.index, 0, card);\n }\n return list;\n };\n React.useEffect(() => {\n if (grab) refs.current.get(grab.id)?.focus();\n }, [grab]);\n\n const onKeyDown = (event: React.KeyboardEvent, id: string) => {\n const title = titleOf(id);\n if (!grab) {\n if (event.key === \" \" || event.key === \"Enter\") {\n event.preventDefault();\n const origin = placementOf(id);\n setGrab({ id, origin, at: origin });\n setMessage(labels.grabbed(title, columnTitle(origin.column)));\n }\n return;\n }\n const { at, origin } = grab;\n const columnIndex = columns.findIndex((c) => c.id === at.column);\n let next: Placement | null = null;\n if (event.key === \"ArrowLeft\" && columnIndex > 0) next = { column: columns[columnIndex - 1]!.id, index: Math.min(at.index, byColumn(columns[columnIndex - 1]!.id, id).length) };\n if (event.key === \"ArrowRight\" && columnIndex < columns.length - 1) next = { column: columns[columnIndex + 1]!.id, index: Math.min(at.index, byColumn(columns[columnIndex + 1]!.id, id).length) };\n if (event.key === \"ArrowUp\" && at.index > 0) next = { ...at, index: at.index - 1 };\n if (event.key === \"ArrowDown\" && at.index < byColumn(at.column, id).length) next = { ...at, index: at.index + 1 };\n if (next) {\n event.preventDefault();\n setGrab({ ...grab, at: next });\n setMessage(labels.moved(title, columnTitle(next.column), next.index + 1, byColumn(next.column, id).length + 1));\n return;\n }\n if (event.key === \" \" || event.key === \"Enter\") {\n event.preventDefault();\n setGrab(null);\n commit(id, origin, at);\n setMessage(labels.dropped(title, columnTitle(at.column), at.index + 1));\n } else if (event.key === \"Escape\") {\n event.preventDefault();\n setGrab(null);\n setMessage(labels.cancelled(title));\n }\n };\n\n const indexAt = (column: string, y: number) => {\n const list = byColumn(column, dragging ?? undefined);\n const i = list.findIndex((c) => {\n const box = refs.current.get(getId(c))?.getBoundingClientRect();\n return box ? y < box.top + box.height / 2 : false;\n });\n return i === -1 ? list.length : i;\n };\n\n return (\n <div role=\"group\" aria-label={label} className={s.root({ className })}>\n <p id={instructionsId} className=\"sr-only\">\n {labels.instructions}\n </p>\n <p className=\"sr-only\" aria-live=\"assertive\">\n {message}\n </p>\n {columns.map((column) => {\n const list = shown(column.id);\n const overLimit = column.limit !== undefined && list.length > column.limit;\n return (\n <section\n key={column.id}\n aria-label={column.title}\n data-over={over?.column === column.id || undefined}\n className={s.column()}\n onDragOver={(e) => {\n if (!dragging) return;\n e.preventDefault();\n setOver({ column: column.id, index: indexAt(column.id, e.clientY) });\n }}\n onDragLeave={(e) => {\n if (!e.currentTarget.contains(e.relatedTarget as Node | null)) setOver(null);\n }}\n onDrop={(e) => {\n e.preventDefault();\n if (dragging) commit(dragging, placementOf(dragging), { column: column.id, index: indexAt(column.id, e.clientY) });\n setDragging(null);\n setOver(null);\n }}\n >\n <header className={s.header()}>\n <h3 className={s.title()}>{column.title}</h3>\n <span className={s.count()} data-over-limit={overLimit || undefined}>\n {column.limit !== undefined ? `${list.length}/${column.limit}` : list.length}\n </span>\n </header>\n <ul className={s.list()}>\n {list.length === 0 ? <li className={s.empty()}>{labels.empty}</li> : null}\n {list.map((card) => {\n const id = getId(card);\n return (\n <li\n key={id}\n ref={(el) => {\n if (el) refs.current.set(id, el);\n else refs.current.delete(id);\n }}\n tabIndex={0}\n draggable\n aria-describedby={instructionsId}\n aria-roledescription=\"card\"\n data-grabbed={grab?.id === id || undefined}\n data-dragging={dragging === id || undefined}\n className={s.card()}\n onKeyDown={(e) => onKeyDown(e, id)}\n onFocus={() => {\n // Tab to another card while one is carried: the carried one goes back.\n if (grab && grab.id !== id) {\n setMessage(labels.cancelled(titleOf(grab.id)));\n setGrab(null);\n }\n }}\n onDragStart={(e) => {\n e.dataTransfer.effectAllowed = \"move\";\n e.dataTransfer.setData(\"text/plain\", id);\n setDragging(id);\n }}\n onDragEnd={() => {\n setDragging(null);\n setOver(null);\n }}\n >\n {renderCard(card)}\n </li>\n );\n })}\n </ul>\n </section>\n );\n })}\n </div>\n );\n}\n"],"mappings":"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","names":["origin"]}
|
package/dist/landing-page.js
CHANGED
|
@@ -13,12 +13,7 @@ function LandingPage({ eyebrow, title, lead, actions, visual, visualLabel, proof
|
|
|
13
13
|
actions && /* @__PURE__ */ jsx("div", { className: "kz-tpl-actions kz-hero-extra", children: actions })
|
|
14
14
|
] }),
|
|
15
15
|
/* @__PURE__ */ jsxs("figure", { className: "kz-tpl-stage", children: [
|
|
16
|
-
/* @__PURE__ */
|
|
17
|
-
/* @__PURE__ */ jsx("i", {}),
|
|
18
|
-
/* @__PURE__ */ jsx("i", {}),
|
|
19
|
-
/* @__PURE__ */ jsx("i", {}),
|
|
20
|
-
visualLabel && /* @__PURE__ */ jsx("span", { children: visualLabel })
|
|
21
|
-
] }),
|
|
16
|
+
/* @__PURE__ */ jsx("div", { className: "kz-tpl-stage-bar", "aria-hidden": true, children: visualLabel && /* @__PURE__ */ jsx("span", { children: visualLabel }) }),
|
|
22
17
|
visual
|
|
23
18
|
] })
|
|
24
19
|
] }) }) }),
|