@krizaka/ui 2.1.0 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -9
- package/dist/{button-Cgfkg_3y.d.ts → button-BMAO7dKF.d.ts} +29 -2
- package/dist/button.d.ts +32 -5
- package/dist/button.js +62 -9
- package/dist/button.js.map +1 -1
- package/dist/chip-link.d.ts +53 -0
- package/dist/chip-link.js +32 -0
- package/dist/chip-link.js.map +1 -0
- package/dist/chunk-43PTCDTL.js +31 -0
- package/dist/chunk-43PTCDTL.js.map +1 -0
- package/dist/chunk-6ISW63JI.js +11 -0
- package/dist/chunk-6ISW63JI.js.map +1 -0
- package/dist/chunk-HAQWKORZ.js +117 -0
- package/dist/chunk-HAQWKORZ.js.map +1 -0
- package/dist/{chunk-FHYZSO2S.js → chunk-R6SDS7JM.js} +5 -3
- package/dist/chunk-R6SDS7JM.js.map +1 -0
- package/dist/chunk-RUPNPMP3.js +103 -0
- package/dist/chunk-RUPNPMP3.js.map +1 -0
- package/dist/chunk-VDR2EP6K.js +49 -0
- package/dist/chunk-VDR2EP6K.js.map +1 -0
- package/dist/chunk-WEVYKZIF.js +33 -0
- package/dist/chunk-WEVYKZIF.js.map +1 -0
- package/dist/command.d.ts +7 -7
- package/dist/command.js +3 -2
- package/dist/command.js.map +1 -1
- package/dist/confirm-button.d.ts +1 -1
- package/dist/confirm-button.js +2 -1
- package/dist/confirm-button.js.map +1 -1
- package/dist/{dialog-GQ4Nvuyf.d.ts → dialog-D42QwYb_.d.ts} +11 -1
- package/dist/dialog.d.ts +1 -1
- package/dist/dialog.js +3 -2
- package/dist/dialog.js.map +1 -1
- package/dist/glow-card.d.ts +20 -0
- package/dist/glow-card.js +30 -0
- package/dist/glow-card.js.map +1 -0
- package/dist/index.d.ts +2 -20
- package/dist/index.js +7 -64
- package/dist/index.js.map +1 -1
- package/dist/iso.d.ts +400 -0
- package/dist/iso.js +363 -0
- package/dist/iso.js.map +1 -0
- package/dist/loader.d.ts +206 -0
- package/dist/loader.js +138 -0
- package/dist/loader.js.map +1 -0
- package/dist/marquee.d.ts +33 -0
- package/dist/marquee.js +52 -0
- package/dist/marquee.js.map +1 -0
- package/dist/mascots.d.ts +40 -0
- package/dist/mascots.js +253 -0
- package/dist/mascots.js.map +1 -0
- package/dist/meter.d.ts +146 -0
- package/dist/meter.js +107 -0
- package/dist/meter.js.map +1 -0
- package/dist/motion.css +394 -3
- package/dist/motion.d.ts +46 -0
- package/dist/motion.js +10 -0
- package/dist/motion.js.map +1 -0
- package/dist/native.d.ts +40 -1
- package/dist/native.js +326 -128
- package/dist/native.js.map +1 -1
- package/dist/nav-bar.d.ts +178 -0
- package/dist/nav-bar.js +157 -0
- package/dist/nav-bar.js.map +1 -0
- package/dist/number-ticker.d.ts +32 -0
- package/dist/number-ticker.js +61 -0
- package/dist/number-ticker.js.map +1 -0
- package/dist/progress.d.ts +56 -1
- package/dist/progress.js +72 -25
- package/dist/progress.js.map +1 -1
- package/dist/skeleton.d.ts +18 -3
- package/dist/skeleton.js +9 -1
- package/dist/skeleton.js.map +1 -1
- package/dist/spinner.d.ts +21 -5
- package/dist/spinner.js +13 -12
- package/dist/spinner.js.map +1 -1
- package/dist/stepper.d.ts +112 -0
- package/dist/stepper.js +67 -0
- package/dist/stepper.js.map +1 -0
- package/dist/tabs.d.ts +1 -1
- package/dist/tabs.js +14 -8
- package/dist/tabs.js.map +1 -1
- package/dist/theme.d.ts +1 -1
- package/dist/theme.js +2 -1
- package/dist/theme.js.map +1 -1
- package/dist/toast.d.ts +39 -4
- package/dist/toast.js +81 -7
- package/dist/toast.js.map +1 -1
- package/package.json +159 -9
- package/registry/alert.json +1 -1
- package/registry/avatar.json +1 -1
- package/registry/badge.json +1 -1
- package/registry/button.json +232 -26
- package/registry/card.json +1 -1
- package/registry/checkbox.json +1 -1
- package/registry/chip-link.json +158 -0
- package/registry/chip.json +1 -1
- package/registry/command.json +1 -1
- package/registry/confirm-button.json +91 -7
- package/registry/countdown.json +1 -1
- package/registry/dialog.json +15 -7
- package/registry/dropdown-menu.json +1 -1
- package/registry/empty-state.json +1 -1
- package/registry/examples/button/error.js +11 -0
- package/registry/examples/button/error.tsx +10 -0
- package/registry/examples/button/loading.tsx +1 -1
- package/registry/examples/button/save-flow.d.ts +4 -0
- package/registry/examples/button/save-flow.js +28 -0
- package/registry/examples/button/save-flow.tsx +24 -0
- package/registry/examples/button/signature.d.ts +4 -0
- package/registry/examples/button/signature.js +17 -0
- package/registry/examples/button/signature.tsx +19 -0
- package/registry/examples/button/upload-progress.d.ts +4 -0
- package/registry/examples/button/upload-progress.js +23 -0
- package/registry/examples/button/upload-progress.tsx +26 -0
- package/registry/examples/chip-link/filters.d.ts +4 -0
- package/registry/examples/chip-link/filters.js +12 -0
- package/registry/examples/chip-link/filters.tsx +17 -0
- package/registry/examples/dialog/left.d.ts +4 -0
- package/registry/examples/dialog/left.js +22 -0
- package/registry/examples/dialog/left.tsx +32 -0
- package/registry/examples/glow-card/link-card.d.ts +4 -0
- package/registry/examples/glow-card/link-card.js +14 -0
- package/registry/examples/glow-card/link-card.tsx +13 -0
- package/registry/examples/glow-card/plans.d.ts +4 -0
- package/registry/examples/glow-card/plans.js +25 -0
- package/registry/examples/glow-card/plans.tsx +26 -0
- package/registry/examples/glow-card/spotlight.d.ts +4 -0
- package/registry/examples/glow-card/spotlight.js +14 -0
- package/registry/examples/glow-card/spotlight.tsx +15 -0
- package/registry/examples/iso/compose.d.ts +4 -0
- package/registry/examples/iso/compose.js +22 -0
- package/registry/examples/iso/compose.tsx +19 -0
- package/registry/examples/iso/orazaka-hero.d.ts +4 -0
- package/registry/examples/iso/orazaka-hero.js +26 -0
- package/registry/examples/iso/orazaka-hero.tsx +21 -0
- package/registry/examples/iso/orochia-hero.d.ts +4 -0
- package/registry/examples/iso/orochia-hero.js +29 -0
- package/registry/examples/iso/orochia-hero.tsx +23 -0
- package/registry/examples/iso/still.d.ts +4 -0
- package/registry/examples/iso/still.js +21 -0
- package/registry/examples/iso/still.tsx +15 -0
- package/registry/examples/loader/endings.d.ts +4 -0
- package/registry/examples/loader/endings.js +14 -0
- package/registry/examples/loader/endings.tsx +11 -0
- package/registry/examples/loader/fetch-flow.d.ts +4 -0
- package/registry/examples/loader/fetch-flow.js +24 -0
- package/registry/examples/loader/fetch-flow.tsx +24 -0
- package/registry/examples/loader/minimal.d.ts +4 -0
- package/registry/examples/loader/minimal.js +11 -0
- package/registry/examples/loader/minimal.tsx +6 -0
- package/registry/examples/loader/overlay.d.ts +4 -0
- package/registry/examples/loader/overlay.js +16 -0
- package/registry/examples/loader/overlay.tsx +13 -0
- package/registry/examples/loader/region-handover.d.ts +4 -0
- package/registry/examples/loader/region-handover.js +42 -0
- package/registry/examples/loader/region-handover.tsx +29 -0
- package/registry/examples/loader/upload-eta.d.ts +4 -0
- package/registry/examples/loader/upload-eta.js +11 -0
- package/registry/examples/loader/upload-eta.tsx +10 -0
- package/registry/examples/marquee/cards.d.ts +4 -0
- package/registry/examples/marquee/cards.js +23 -0
- package/registry/examples/marquee/cards.tsx +21 -0
- package/registry/examples/marquee/logos.d.ts +4 -0
- package/registry/examples/marquee/logos.js +12 -0
- package/registry/examples/marquee/logos.tsx +17 -0
- package/registry/examples/mascots/empty-state.d.ts +4 -0
- package/registry/examples/mascots/empty-state.js +24 -0
- package/registry/examples/mascots/empty-state.tsx +18 -0
- package/registry/examples/mascots/flock.d.ts +4 -0
- package/registry/examples/mascots/flock.js +14 -0
- package/registry/examples/mascots/flock.tsx +15 -0
- package/registry/examples/mascots/long-task.d.ts +4 -0
- package/registry/examples/mascots/long-task.js +18 -0
- package/registry/examples/mascots/long-task.tsx +15 -0
- package/registry/examples/mascots/moods.d.ts +4 -0
- package/registry/examples/mascots/moods.js +14 -0
- package/registry/examples/mascots/moods.tsx +15 -0
- package/registry/examples/mascots/native/default.d.ts +4 -0
- package/registry/examples/mascots/native/default.dark.png +0 -0
- package/registry/examples/mascots/native/default.js +25 -0
- package/registry/examples/mascots/native/default.light.png +0 -0
- package/registry/examples/mascots/native/default.tsx +22 -0
- package/registry/examples/mascots/own-tone.d.ts +4 -0
- package/registry/examples/mascots/own-tone.js +11 -0
- package/registry/examples/mascots/own-tone.tsx +12 -0
- package/registry/examples/meter/balance.d.ts +4 -0
- package/registry/examples/meter/balance.js +14 -0
- package/registry/examples/meter/balance.tsx +15 -0
- package/registry/examples/meter/quota.d.ts +4 -0
- package/registry/examples/meter/quota.js +15 -0
- package/registry/examples/meter/quota.tsx +12 -0
- package/registry/examples/meter/split.d.ts +4 -0
- package/registry/examples/meter/split.js +18 -0
- package/registry/examples/meter/split.tsx +18 -0
- package/registry/examples/nav-bar/app-bar.d.ts +4 -0
- package/registry/examples/nav-bar/app-bar.js +22 -0
- package/registry/examples/nav-bar/app-bar.tsx +21 -0
- package/registry/examples/nav-bar/menu-open.d.ts +4 -0
- package/registry/examples/nav-bar/menu-open.js +26 -0
- package/registry/examples/nav-bar/menu-open.tsx +26 -0
- package/registry/examples/nav-bar/site.d.ts +4 -0
- package/registry/examples/nav-bar/site.js +31 -0
- package/registry/examples/nav-bar/site.tsx +36 -0
- package/registry/examples/number-ticker/gradient.d.ts +4 -0
- package/registry/examples/number-ticker/gradient.js +11 -0
- package/registry/examples/number-ticker/gradient.tsx +10 -0
- package/registry/examples/number-ticker/live-total.d.ts +4 -0
- package/registry/examples/number-ticker/live-total.js +17 -0
- package/registry/examples/number-ticker/live-total.tsx +21 -0
- package/registry/examples/number-ticker/stats.d.ts +4 -0
- package/registry/examples/number-ticker/stats.js +19 -0
- package/registry/examples/number-ticker/stats.tsx +23 -0
- package/registry/examples/progress/buffer.d.ts +4 -0
- package/registry/examples/progress/buffer.js +11 -0
- package/registry/examples/progress/buffer.tsx +10 -0
- package/registry/examples/progress/statuses.d.ts +4 -0
- package/registry/examples/progress/statuses.js +14 -0
- package/registry/examples/progress/statuses.tsx +11 -0
- package/registry/examples/progress/steps.d.ts +4 -0
- package/registry/examples/progress/steps.js +14 -0
- package/registry/examples/progress/steps.tsx +13 -0
- package/registry/examples/progress/upload.d.ts +4 -0
- package/registry/examples/progress/upload.js +11 -0
- package/registry/examples/progress/upload.tsx +10 -0
- package/registry/examples/skeleton/paragraph.d.ts +4 -0
- package/registry/examples/skeleton/paragraph.js +14 -0
- package/registry/examples/skeleton/paragraph.tsx +12 -0
- package/registry/examples/skeleton/shape-of-content.d.ts +4 -0
- package/registry/examples/skeleton/shape-of-content.js +23 -0
- package/registry/examples/skeleton/shape-of-content.tsx +26 -0
- package/registry/examples/spinner/default.js +5 -2
- package/registry/examples/spinner/default.tsx +7 -1
- package/registry/examples/spinner/sizes.js +2 -1
- package/registry/examples/spinner/sizes.tsx +2 -0
- package/registry/examples/spinner/value.d.ts +4 -0
- package/registry/examples/spinner/value.js +11 -0
- package/registry/examples/spinner/value.tsx +12 -0
- package/registry/examples/stepper/checkout.d.ts +4 -0
- package/registry/examples/stepper/checkout.js +22 -0
- package/registry/examples/stepper/checkout.tsx +17 -0
- package/registry/examples/stepper/failed.d.ts +4 -0
- package/registry/examples/stepper/failed.js +26 -0
- package/registry/examples/stepper/failed.tsx +21 -0
- package/registry/examples/stepper/job.d.ts +4 -0
- package/registry/examples/stepper/job.js +32 -0
- package/registry/examples/stepper/job.tsx +28 -0
- package/registry/examples/toast/grouped.d.ts +4 -0
- package/registry/examples/toast/grouped.js +21 -0
- package/registry/examples/toast/grouped.tsx +23 -0
- package/registry/examples/toast/undo.d.ts +4 -0
- package/registry/examples/toast/undo.js +29 -0
- package/registry/examples/toast/undo.tsx +30 -0
- package/registry/examples/toast/upload-progress.d.ts +4 -0
- package/registry/examples/toast/upload-progress.js +29 -0
- package/registry/examples/toast/upload-progress.tsx +31 -0
- package/registry/field.json +1 -1
- package/registry/glow-card.json +162 -0
- package/registry/index.json +207 -20
- package/registry/iso.json +1355 -0
- package/registry/kbd.json +1 -1
- package/registry/loader.json +399 -0
- package/registry/marquee.json +225 -0
- package/registry/mascots.json +314 -0
- package/registry/meter.json +324 -0
- package/registry/nav-bar.json +480 -0
- package/registry/number-ticker.json +219 -0
- package/registry/page-header.json +1 -1
- package/registry/popover.json +1 -1
- package/registry/progress.json +116 -11
- package/registry/radio-group.json +1 -1
- package/registry/section-backdrop.json +1 -1
- package/registry/separator.json +1 -1
- package/registry/skeleton.json +69 -13
- package/registry/slider.json +1 -1
- package/registry/slot.json +1 -1
- package/registry/spinner.json +91 -27
- package/registry/stat.json +1 -1
- package/registry/stepper.json +174 -0
- package/registry/switch.json +1 -1
- package/registry/tabs.json +11 -7
- package/registry/theme.json +3 -3
- package/registry/toast.json +41 -13
- package/registry/tooltip.json +1 -1
- package/dist/chunk-FHYZSO2S.js.map +0 -1
- package/dist/chunk-PESA2R4U.js +0 -51
- package/dist/chunk-PESA2R4U.js.map +0 -1
- package/registry/examples/spinner/muted.js +0 -11
- package/registry/examples/spinner/muted.tsx +0 -6
- /package/registry/examples/{spinner/muted.d.ts → button/error.d.ts} +0 -0
package/dist/iso.js
ADDED
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
// src/iso/geometry.ts
|
|
2
|
+
var COS = Math.cos(Math.PI / 6);
|
|
3
|
+
var SIN = 0.5;
|
|
4
|
+
var f = (n) => (Math.round(n * 10) / 10).toString();
|
|
5
|
+
function project([x, y, z]) {
|
|
6
|
+
return [(x - y) * COS, (x + y) * SIN - z];
|
|
7
|
+
}
|
|
8
|
+
var pts = (points) => points.map(([x, y]) => `${f(x)},${f(y)}`).join(" ");
|
|
9
|
+
var pathOf = (points, close = false) => points.map(([x, y], i) => `${i ? "L" : "M"}${f(x)} ${f(y)}`).join("") + (close ? "Z" : "");
|
|
10
|
+
function hexagon(cx2, cy, r) {
|
|
11
|
+
return Array.from({ length: 6 }, (_, k) => {
|
|
12
|
+
const a = Math.PI / 3 * k;
|
|
13
|
+
return [cx2 + r * Math.cos(a), cy + r * Math.sin(a)];
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
function cutRect(cx2, cy, w, d, c) {
|
|
17
|
+
const x0 = cx2 - w / 2;
|
|
18
|
+
const x1 = cx2 + w / 2;
|
|
19
|
+
const y0 = cy - d / 2;
|
|
20
|
+
const y1 = cy + d / 2;
|
|
21
|
+
if (c <= 0) return [[x0, y0], [x1, y0], [x1, y1], [x0, y1]];
|
|
22
|
+
return [[x0 + c, y0], [x1 - c, y0], [x1, y0 + c], [x1, y1 - c], [x1 - c, y1], [x0 + c, y1], [x0, y1 - c], [x0, y0 + c]];
|
|
23
|
+
}
|
|
24
|
+
function prism(footprint2, z0, h) {
|
|
25
|
+
const n = footprint2.length;
|
|
26
|
+
const area = footprint2.reduce((s, [x, y], i) => {
|
|
27
|
+
const [x2, y2] = footprint2[(i + 1) % n];
|
|
28
|
+
return s + (x * y2 - x2 * y);
|
|
29
|
+
}, 0);
|
|
30
|
+
const sign = area > 0 ? 1 : -1;
|
|
31
|
+
const sides = [];
|
|
32
|
+
for (let i = 0; i < n; i++) {
|
|
33
|
+
const [ax, ay] = footprint2[i];
|
|
34
|
+
const [bx, by] = footprint2[(i + 1) % n];
|
|
35
|
+
const nx = sign * (by - ay);
|
|
36
|
+
const ny = sign * -(bx - ax);
|
|
37
|
+
if (nx + ny <= 1e-6) continue;
|
|
38
|
+
const quad = [project([ax, ay, z0]), project([bx, by, z0]), project([bx, by, z0 + h]), project([ax, ay, z0 + h])];
|
|
39
|
+
sides.push({ depth: ax + ay + bx + by, face: { points: pts(quad), kind: nx >= ny ? "right" : "left" } });
|
|
40
|
+
}
|
|
41
|
+
sides.sort((a, b) => a.depth - b.depth);
|
|
42
|
+
const top = { points: pts(footprint2.map(([x, y]) => project([x, y, z0 + h]))), kind: "top" };
|
|
43
|
+
return [...sides.map((s) => s.face), top];
|
|
44
|
+
}
|
|
45
|
+
function isoCircle(cx2, cy, z, r) {
|
|
46
|
+
const [x, y] = project([cx2, cy, z]);
|
|
47
|
+
return { cx: x, cy: y, rx: r * COS * Math.SQRT2, ry: r * SIN * Math.SQRT2 };
|
|
48
|
+
}
|
|
49
|
+
function onCircle(r, deg, [cx2, cy] = [0, 0]) {
|
|
50
|
+
const a = deg * Math.PI / 180;
|
|
51
|
+
return [cx2 + r * Math.cos(a), cy + r * Math.sin(a)];
|
|
52
|
+
}
|
|
53
|
+
var depthOf = ([x, y]) => x + y;
|
|
54
|
+
function viewBoxOf(extent, top, margin = 24) {
|
|
55
|
+
const w = 2 * extent * COS + margin * 2;
|
|
56
|
+
return [-w / 2, -extent * SIN * 1.2 - top, w, extent * SIN * 2.4 + top].map(f).join(" ");
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// src/iso/iso.tsx
|
|
60
|
+
import * as React from "react";
|
|
61
|
+
|
|
62
|
+
// src/cx.ts
|
|
63
|
+
function cx(...parts) {
|
|
64
|
+
return parts.filter(Boolean).join(" ");
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// src/iso/iso.tsx
|
|
68
|
+
import { Fragment as Fragment2, jsx, jsxs } from "react/jsx-runtime";
|
|
69
|
+
var uid = (raw) => raw.replace(/[^a-zA-Z0-9_-]/g, "");
|
|
70
|
+
var footprint = (shape, [x, y], size, cut) => {
|
|
71
|
+
const [w, d] = typeof size === "number" ? [size, size] : size;
|
|
72
|
+
if (shape === "hex") return hexagon(x, y, w / 2);
|
|
73
|
+
return cutRect(x, y, w, d, shape === "rect" ? 0 : cut ?? Math.min(w, d) / 6);
|
|
74
|
+
};
|
|
75
|
+
function IsoScene({ label, description, extent = 240, top = 260, grid = true, step = 40, animated = true, viewBox, className, children, ...props }) {
|
|
76
|
+
const id = uid(React.useId());
|
|
77
|
+
const lines = [];
|
|
78
|
+
for (let v = -extent; v <= extent; v += step) {
|
|
79
|
+
lines.push(pathOf([project([v, -extent, 0]), project([v, extent, 0])]), pathOf([project([-extent, v, 0]), project([extent, v, 0])]));
|
|
80
|
+
}
|
|
81
|
+
const fade = isoCircle(0, 0, 0, extent * 0.9);
|
|
82
|
+
const named = label ? { role: "group", "aria-label": label } : { "aria-hidden": true };
|
|
83
|
+
return /* @__PURE__ */ jsxs(
|
|
84
|
+
"svg",
|
|
85
|
+
{
|
|
86
|
+
viewBox: viewBox ?? viewBoxOf(extent, top),
|
|
87
|
+
focusable: "false",
|
|
88
|
+
"data-motion-scope": "",
|
|
89
|
+
"data-animated": animated,
|
|
90
|
+
className: cx("kz-iso", className),
|
|
91
|
+
...named,
|
|
92
|
+
...props,
|
|
93
|
+
children: [
|
|
94
|
+
description && /* @__PURE__ */ jsx("desc", { children: description }),
|
|
95
|
+
grid && /* @__PURE__ */ jsxs(Fragment2, { children: [
|
|
96
|
+
/* @__PURE__ */ jsxs("defs", { children: [
|
|
97
|
+
/* @__PURE__ */ jsxs("radialGradient", { id: `${id}-fade`, children: [
|
|
98
|
+
/* @__PURE__ */ jsx("stop", { offset: "0%", stopColor: "white", stopOpacity: "1" }),
|
|
99
|
+
/* @__PURE__ */ jsx("stop", { offset: "100%", stopColor: "white", stopOpacity: "0" })
|
|
100
|
+
] }),
|
|
101
|
+
/* @__PURE__ */ jsx("mask", { id: `${id}-floor`, children: /* @__PURE__ */ jsx("ellipse", { cx: fade.cx, cy: fade.cy, rx: fade.rx, ry: fade.ry, fill: `url(#${id}-fade)` }) })
|
|
102
|
+
] }),
|
|
103
|
+
/* @__PURE__ */ jsx("path", { d: lines.join(""), className: "kz-iso-floor", mask: `url(#${id}-floor)` })
|
|
104
|
+
] }),
|
|
105
|
+
children
|
|
106
|
+
]
|
|
107
|
+
}
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
var loop = (animated) => animated === false ? void 0 : "kz-loop";
|
|
111
|
+
function Item({ label, index = 0, animated, anchor, align = "center", className, children }) {
|
|
112
|
+
const named = label ? { role: "img", "aria-label": label, tabIndex: 0 } : {};
|
|
113
|
+
return /* @__PURE__ */ jsxs("g", { className: cx("kz-iso-item", className), style: { "--kz-iso-i": index }, ...named, children: [
|
|
114
|
+
/* @__PURE__ */ jsx("g", { className: cx("kz-iso-lift", animated !== false && "kz-iso-rise"), children }),
|
|
115
|
+
label && /* @__PURE__ */ jsx(Tip, { at: anchor, text: label, align })
|
|
116
|
+
] });
|
|
117
|
+
}
|
|
118
|
+
function Tip({ at: [x, y], text, align }) {
|
|
119
|
+
const w = Math.max(40, text.length * 6.6 + 20);
|
|
120
|
+
if (align === "start") {
|
|
121
|
+
return /* @__PURE__ */ jsxs("g", { className: "kz-iso-tip", "aria-hidden": true, children: [
|
|
122
|
+
/* @__PURE__ */ jsx("path", { d: `M${Math.round(x + 3)} ${Math.round(y)}h18`, className: "kz-iso-leader" }),
|
|
123
|
+
/* @__PURE__ */ jsx("rect", { x: x + 21, y: y - 11, width: w, height: 22, rx: 7, strokeWidth: 1 }),
|
|
124
|
+
/* @__PURE__ */ jsx("text", { x: x + 21 + w / 2, y: y + 4, textAnchor: "middle", children: text })
|
|
125
|
+
] });
|
|
126
|
+
}
|
|
127
|
+
return /* @__PURE__ */ jsxs("g", { className: "kz-iso-tip", "aria-hidden": true, children: [
|
|
128
|
+
/* @__PURE__ */ jsx("rect", { x: x - w / 2, y: y - 34, width: w, height: 22, rx: 7, strokeWidth: 1 }),
|
|
129
|
+
/* @__PURE__ */ jsx("text", { x, y: y - 19, textAnchor: "middle", children: text })
|
|
130
|
+
] });
|
|
131
|
+
}
|
|
132
|
+
function Solid({ faces, material }) {
|
|
133
|
+
return /* @__PURE__ */ jsx("g", { className: "kz-iso-" + material, children: faces.map((face, i) => /* @__PURE__ */ jsx("polygon", { points: face.points, className: "kz-iso-face kz-iso-" + face.kind }, i)) });
|
|
134
|
+
}
|
|
135
|
+
function IsoPrism({ at = [0, 0], z = 0, height, shape = "cut", size = 120, cut, material = "base", strip, animated, ...item }) {
|
|
136
|
+
const foot = footprint(shape, at, size, cut);
|
|
137
|
+
const [w, d] = typeof size === "number" ? [size, size] : size;
|
|
138
|
+
return /* @__PURE__ */ jsxs(Item, { ...item, animated, anchor: project(shape === "hex" ? [at[0] + w / 4, at[1] - w * 0.433, z + height / 2] : [at[0] + w / 2, at[1] - d / 2, z + height / 2]), align: "start", children: [
|
|
139
|
+
/* @__PURE__ */ jsx(Solid, { faces: prism(foot, z, height), material }),
|
|
140
|
+
strip && /* @__PURE__ */ jsx(Strip, { at, w, d, c: shape === "rect" ? 0 : cut ?? Math.min(w, d) / 6, z: z + height / 2 + 1, animated, hex: shape === "hex" })
|
|
141
|
+
] });
|
|
142
|
+
}
|
|
143
|
+
function Strip({ at: [cx2, cy], w, d, c, z, hex, animated }) {
|
|
144
|
+
const front = hex ? [0, 1, 2].map((k) => onCircle(w / 2, k * 60 - 60, [cx2, cy])) : [[cx2 + w / 2, cy - d / 2 + c], [cx2 + w / 2, cy + d / 2 - c], [cx2 + w / 2 - c, cy + d / 2], [cx2 - w / 2 + c, cy + d / 2]];
|
|
145
|
+
return /* @__PURE__ */ jsx("polyline", { points: pts(front.map(([x, y]) => project([x, y, z]))), className: cx("kz-iso-strip", loop(animated)) });
|
|
146
|
+
}
|
|
147
|
+
function IsoStack({ layers, at = [0, 0], shape = "cut", size = 120, gap = 4, plinth = true, core = true, index = 0, animated }) {
|
|
148
|
+
const base = plinth ? 12 + gap : 0;
|
|
149
|
+
const heights = layers.map((layer) => layer.height ?? 22);
|
|
150
|
+
const stages = layers.map((layer, k) => ({ ...layer, k, height: heights[k], z: base + heights.slice(0, k).reduce((sum, h) => sum + h + gap, 0) }));
|
|
151
|
+
const top = base + heights.reduce((sum, h) => sum + h + gap, 0);
|
|
152
|
+
return /* @__PURE__ */ jsxs("g", { children: [
|
|
153
|
+
plinth && /* @__PURE__ */ jsx(IsoPrism, { at, height: 12, shape: "hex", size: size * 1.86, index, animated }),
|
|
154
|
+
stages.map((s) => /* @__PURE__ */ jsx(
|
|
155
|
+
IsoPrism,
|
|
156
|
+
{
|
|
157
|
+
at,
|
|
158
|
+
z: s.z,
|
|
159
|
+
height: s.height,
|
|
160
|
+
shape,
|
|
161
|
+
size,
|
|
162
|
+
material: s.material ?? "base",
|
|
163
|
+
strip: (s.material ?? "base") === "base",
|
|
164
|
+
label: s.label,
|
|
165
|
+
index: index + 1 + s.k,
|
|
166
|
+
animated
|
|
167
|
+
},
|
|
168
|
+
s.k
|
|
169
|
+
)),
|
|
170
|
+
core && /* @__PURE__ */ jsxs(Fragment2, { children: [
|
|
171
|
+
/* @__PURE__ */ jsx(IsoPrism, { at, z: top, height: 16, shape: "hex", size: size / 2, material: "accent", index: index + 1 + stages.length, animated, label: typeof core === "string" ? core : void 0 }),
|
|
172
|
+
/* @__PURE__ */ jsx(IsoNode, { at, z: top + 22, index: index + 2 + stages.length, animated })
|
|
173
|
+
] })
|
|
174
|
+
] });
|
|
175
|
+
}
|
|
176
|
+
function IsoNode({ at = [0, 0], z = 0, r = 7, glow = 70, index = 0, animated }) {
|
|
177
|
+
const id = uid(React.useId());
|
|
178
|
+
const [x, y] = project([at[0], at[1], z]);
|
|
179
|
+
return /* @__PURE__ */ jsxs("g", { className: cx(animated !== false && "kz-iso-rise"), style: { "--kz-iso-i": index }, children: [
|
|
180
|
+
glow > 0 && /* @__PURE__ */ jsxs(Fragment2, { children: [
|
|
181
|
+
/* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs("radialGradient", { id: `${id}-glow`, children: [
|
|
182
|
+
/* @__PURE__ */ jsx("stop", { offset: "0%", className: "kz-iso-glow-stop", stopOpacity: "0.55" }),
|
|
183
|
+
/* @__PURE__ */ jsx("stop", { offset: "100%", className: "kz-iso-glow-stop", stopOpacity: "0" })
|
|
184
|
+
] }) }),
|
|
185
|
+
/* @__PURE__ */ jsx("circle", { cx: x, cy: y, r: glow, fill: `url(#${id}-glow)`, className: cx("kz-iso-breathe", loop(animated)) })
|
|
186
|
+
] }),
|
|
187
|
+
/* @__PURE__ */ jsx("circle", { cx: x, cy: y, r, className: cx("kz-iso-node kz-iso-breathe", loop(animated)) })
|
|
188
|
+
] });
|
|
189
|
+
}
|
|
190
|
+
function IsoDome({ at = [0, 0], radius = 158, height = 250, label, animated, part = "both" }) {
|
|
191
|
+
const e = isoCircle(at[0], at[1], 0, radius);
|
|
192
|
+
const arc = `M${e.cx - e.rx} ${e.cy} A ${e.rx} ${height} 0 0 1 ${e.cx + e.rx} ${e.cy}`;
|
|
193
|
+
return /* @__PURE__ */ jsxs(Fragment2, { children: [
|
|
194
|
+
part !== "arc" && /* @__PURE__ */ jsx("ellipse", { cx: e.cx, cy: e.cy, rx: e.rx, ry: e.ry, className: "kz-iso-rim" }),
|
|
195
|
+
part !== "rim" && /* @__PURE__ */ jsxs("g", { children: [
|
|
196
|
+
/* @__PURE__ */ jsx("path", { d: arc, className: "kz-iso-dome" }),
|
|
197
|
+
/* @__PURE__ */ jsx("path", { d: arc, className: cx("kz-iso-dome-sheen", loop(animated)), pathLength: 440 }),
|
|
198
|
+
label && /* @__PURE__ */ jsx(IsoLabel, { at, z: height + 10, text: label })
|
|
199
|
+
] })
|
|
200
|
+
] });
|
|
201
|
+
}
|
|
202
|
+
function IsoTile({ at, z = 90, size = [76, 52], glyph = "none", material = "accent", float = true, animated, ...item }) {
|
|
203
|
+
const [w, d] = size;
|
|
204
|
+
const top = z + 9;
|
|
205
|
+
const shadow = isoCircle(at[0], at[1], 0, Math.min(w, d) * 0.55);
|
|
206
|
+
const foot = project([at[0], at[1], 0]);
|
|
207
|
+
return /* @__PURE__ */ jsxs(Item, { ...item, animated, anchor: project([at[0], at[1], top]), children: [
|
|
208
|
+
z > 0 && /* @__PURE__ */ jsxs(Fragment2, { children: [
|
|
209
|
+
/* @__PURE__ */ jsx("ellipse", { cx: shadow.cx, cy: shadow.cy, rx: shadow.rx, ry: shadow.ry, className: "kz-iso-shadow" }),
|
|
210
|
+
/* @__PURE__ */ jsx("path", { d: pathOf([foot, project([at[0], at[1], z])]), className: "kz-iso-tether" })
|
|
211
|
+
] }),
|
|
212
|
+
/* @__PURE__ */ jsxs("g", { className: cx(float && "kz-iso-float", float && loop(animated)), children: [
|
|
213
|
+
/* @__PURE__ */ jsx(Solid, { faces: prism(cutRect(at[0], at[1], w, d, Math.min(w, d) / 4), z, 9), material }),
|
|
214
|
+
/* @__PURE__ */ jsx(Glyph, { glyph, at, z: top, s: Math.min(w, d) * 0.3 })
|
|
215
|
+
] })
|
|
216
|
+
] });
|
|
217
|
+
}
|
|
218
|
+
function Glyph({ glyph, at: [cx2, cy], z, s }) {
|
|
219
|
+
const p = (u, v) => project([cx2 + u * s, cy + v * s, z]);
|
|
220
|
+
const line = (points, close = false) => /* @__PURE__ */ jsx("path", { d: pathOf(points.map(([u, v]) => p(u, v)), close), className: "kz-iso-glyph" });
|
|
221
|
+
switch (glyph) {
|
|
222
|
+
case "dots":
|
|
223
|
+
return /* @__PURE__ */ jsx(Fragment2, { children: [-0.8, 0, 0.8].map((u) => /* @__PURE__ */ jsx("circle", { cx: p(u, 0)[0], cy: p(u, 0)[1], r: s * 0.16, className: "kz-iso-glyph-fill" }, u)) });
|
|
224
|
+
case "lines":
|
|
225
|
+
return /* @__PURE__ */ jsx(Fragment2, { children: [-0.6, 0, 0.6].map((v) => /* @__PURE__ */ jsx(React.Fragment, { children: line([[-0.9, v], [0.7, v]]) }, v)) });
|
|
226
|
+
case "play":
|
|
227
|
+
return line([[-0.5, -0.7], [0.8, 0], [-0.5, 0.7]], true);
|
|
228
|
+
case "coin":
|
|
229
|
+
return /* @__PURE__ */ jsxs(Fragment2, { children: [
|
|
230
|
+
/* @__PURE__ */ jsx("path", { d: pathOf(hexagon(0, 0, 0.9).map(([u, v]) => p(u, v)), true), className: "kz-iso-glyph" }),
|
|
231
|
+
/* @__PURE__ */ jsx("circle", { cx: p(0, 0)[0], cy: p(0, 0)[1], r: s * 0.18, className: "kz-iso-glyph-fill" })
|
|
232
|
+
] });
|
|
233
|
+
case "lock":
|
|
234
|
+
return /* @__PURE__ */ jsxs(Fragment2, { children: [
|
|
235
|
+
line([[-0.6, -0.1], [0.6, -0.1], [0.6, 0.8], [-0.6, 0.8]], true),
|
|
236
|
+
line([[-0.35, -0.1], [-0.35, -0.5], [-0.15, -0.75], [0.15, -0.75], [0.35, -0.5], [0.35, -0.1]])
|
|
237
|
+
] });
|
|
238
|
+
case "arrow":
|
|
239
|
+
return /* @__PURE__ */ jsxs(Fragment2, { children: [
|
|
240
|
+
line([[0.8, 0.8], [-0.6, -0.6]]),
|
|
241
|
+
line([[-0.6, 0.1], [-0.6, -0.6], [0.1, -0.6]])
|
|
242
|
+
] });
|
|
243
|
+
case "flag":
|
|
244
|
+
return /* @__PURE__ */ jsxs(Fragment2, { children: [
|
|
245
|
+
line([[-0.7, 0.9], [-0.7, -0.9]]),
|
|
246
|
+
line([[-0.7, -0.9], [0.8, -0.55], [-0.7, -0.1]], true)
|
|
247
|
+
] });
|
|
248
|
+
case "heart":
|
|
249
|
+
return line([[0, 0.85], [-0.85, 0], [-0.85, -0.45], [-0.45, -0.8], [0, -0.45], [0.45, -0.8], [0.85, -0.45], [0.85, 0]], true);
|
|
250
|
+
case "node":
|
|
251
|
+
return /* @__PURE__ */ jsx("circle", { cx: p(0, 0)[0], cy: p(0, 0)[1], r: s * 0.3, className: "kz-iso-glyph-fill" });
|
|
252
|
+
default:
|
|
253
|
+
return null;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
function IsoLink({ from, to, z = 0, route = "elbow", direction = "out", particles = 2, duration = 3.6, label, animated }) {
|
|
257
|
+
const corner = [to[0], from[1]];
|
|
258
|
+
const plan = route === "elbow" && from[0] !== to[0] && from[1] !== to[1] ? [from, corner, to] : [from, to];
|
|
259
|
+
const ordered = direction === "in" ? [...plan].reverse() : plan;
|
|
260
|
+
const d = pathOf(ordered.map(([x, y]) => project([x, y, z])));
|
|
261
|
+
const mid = plan.length === 3 ? corner : [(from[0] + to[0]) / 2, (from[1] + to[1]) / 2];
|
|
262
|
+
return /* @__PURE__ */ jsxs("g", { children: [
|
|
263
|
+
/* @__PURE__ */ jsx("path", { d, className: cx("kz-iso-link", loop(animated)) }),
|
|
264
|
+
Array.from({ length: particles }, (_, k) => /* @__PURE__ */ jsx(
|
|
265
|
+
"circle",
|
|
266
|
+
{
|
|
267
|
+
r: 3.2,
|
|
268
|
+
className: cx("kz-iso-particle", loop(animated)),
|
|
269
|
+
style: {
|
|
270
|
+
offsetPath: `path("${d}")`,
|
|
271
|
+
"--kz-iso-at": `${Math.round((k + 0.5) / particles * 100)}%`,
|
|
272
|
+
"--kz-iso-dur": `${duration}s`,
|
|
273
|
+
"--kz-iso-delay": `${-duration * k / particles}s`
|
|
274
|
+
}
|
|
275
|
+
},
|
|
276
|
+
k
|
|
277
|
+
)),
|
|
278
|
+
label && /* @__PURE__ */ jsx(IsoLabel, { at: mid, z, text: label })
|
|
279
|
+
] });
|
|
280
|
+
}
|
|
281
|
+
function IsoLabel({ at, z = 0, text, strong }) {
|
|
282
|
+
const [x, y] = project([at[0], at[1], z]);
|
|
283
|
+
const chars = text.length + (strong ? strong.length + 1 : 0);
|
|
284
|
+
const w = chars * 6.8 + 22;
|
|
285
|
+
return /* @__PURE__ */ jsxs("g", { className: "kz-iso-link-label", "aria-hidden": true, children: [
|
|
286
|
+
/* @__PURE__ */ jsx("rect", { x: x - w / 2, y: y - 12, width: w, height: 24, rx: 8, strokeWidth: 1 }),
|
|
287
|
+
/* @__PURE__ */ jsxs("text", { x, y: y + 4, textAnchor: "middle", children: [
|
|
288
|
+
strong && /* @__PURE__ */ jsxs("tspan", { className: "kz-iso-strong", children: [
|
|
289
|
+
strong,
|
|
290
|
+
" "
|
|
291
|
+
] }),
|
|
292
|
+
text
|
|
293
|
+
] })
|
|
294
|
+
] });
|
|
295
|
+
}
|
|
296
|
+
function sideAngles(n) {
|
|
297
|
+
const left = Math.ceil(n / 2);
|
|
298
|
+
const right = n - left;
|
|
299
|
+
const spread = (m, centre, sign) => Array.from({ length: m }, (_, i) => centre + sign * ((m - 1) / 2 - i) * 64);
|
|
300
|
+
return [...spread(left, 135, 1), ...spread(right, -45, -1)];
|
|
301
|
+
}
|
|
302
|
+
function IsoHub({ layers, shape, size = 120, core, dome, satellites = [], radius = 210, angles, highlight, animated, viewBox, extent, ...scene }) {
|
|
303
|
+
const auto = sideAngles(satellites.length);
|
|
304
|
+
const placed = satellites.map((s, k) => {
|
|
305
|
+
const angle = angles?.[k] ?? auto[k] ?? 0;
|
|
306
|
+
const at = onCircle(radius, angle);
|
|
307
|
+
return { ...s, angle, at, z: Math.round(78 - depthOf(at) / radius * 26), k };
|
|
308
|
+
});
|
|
309
|
+
const back = placed.filter((s) => depthOf(s.at) < 0);
|
|
310
|
+
const front = placed.filter((s) => depthOf(s.at) >= 0);
|
|
311
|
+
const stackHeight = layers.reduce((h, l) => h + (l.height ?? 22) + 4, 16) + (core === false ? 0 : 38);
|
|
312
|
+
const domeR = size * 1.32;
|
|
313
|
+
const domeH = Math.max(stackHeight + 80, 200);
|
|
314
|
+
const crown = dome ? domeH + 24 : stackHeight + (highlight ? 62 : 12);
|
|
315
|
+
const points = [
|
|
316
|
+
...placed.flatMap(({ at: [x, y], z }) => [project([x - 46, y - 46, z + 52]), project([x + 46, y + 46, z]), project([x + 46, y - 46, z]), project([x - 46, y + 46, z])]),
|
|
317
|
+
...hexagon(0, 0, size * (dome ? 1.4 : 0.95)).map(([x, y]) => project([x, y, 0])),
|
|
318
|
+
project([0, 0, crown + 20])
|
|
319
|
+
];
|
|
320
|
+
const xs = points.map(([x]) => x);
|
|
321
|
+
const ys = points.map(([, y]) => y);
|
|
322
|
+
const half = Math.max(...xs.map(Math.abs)) + 20;
|
|
323
|
+
const box = [-half, Math.min(...ys) - 12, half * 2, Math.max(...ys) - Math.min(...ys) + 40].map((n) => Math.round(n)).join(" ");
|
|
324
|
+
const tile = (s) => /* @__PURE__ */ jsx(IsoTile, { at: s.at, z: s.z, glyph: s.glyph, material: s.material, label: s.label, index: layers.length + 3 + s.k, animated }, s.k);
|
|
325
|
+
const link = (s) => s.flow === "none" ? null : /* @__PURE__ */ jsx(
|
|
326
|
+
IsoLink,
|
|
327
|
+
{
|
|
328
|
+
from: s.at,
|
|
329
|
+
to: onCircle(size * (dome ? 1.32 : 0.8), s.angle),
|
|
330
|
+
route: "straight",
|
|
331
|
+
direction: s.flow === "out" ? "in" : "out",
|
|
332
|
+
label: s.value,
|
|
333
|
+
animated
|
|
334
|
+
},
|
|
335
|
+
`l${s.k}`
|
|
336
|
+
);
|
|
337
|
+
return /* @__PURE__ */ jsxs(IsoScene, { animated, extent: extent ?? Math.round(radius * 1.45 + 60), viewBox: viewBox ?? box, ...scene, children: [
|
|
338
|
+
placed.map(link),
|
|
339
|
+
dome && /* @__PURE__ */ jsx(IsoDome, { radius: domeR, part: "rim", animated }),
|
|
340
|
+
back.map(tile),
|
|
341
|
+
/* @__PURE__ */ jsx(IsoStack, { layers, shape, size, core, animated }),
|
|
342
|
+
dome && /* @__PURE__ */ jsx(IsoDome, { radius: domeR, height: domeH, part: "arc", animated, label: typeof dome === "string" ? dome : void 0 }),
|
|
343
|
+
highlight && /* @__PURE__ */ jsx(IsoLabel, { at: [0, 0], z: stackHeight + (dome ? 24 : 46), strong: highlight.strong, text: highlight.text }),
|
|
344
|
+
front.map(tile)
|
|
345
|
+
] });
|
|
346
|
+
}
|
|
347
|
+
export {
|
|
348
|
+
IsoDome,
|
|
349
|
+
IsoHub,
|
|
350
|
+
IsoLabel,
|
|
351
|
+
IsoLink,
|
|
352
|
+
IsoNode,
|
|
353
|
+
IsoPrism,
|
|
354
|
+
IsoScene,
|
|
355
|
+
IsoStack,
|
|
356
|
+
IsoTile,
|
|
357
|
+
cutRect,
|
|
358
|
+
hexagon,
|
|
359
|
+
isoCircle,
|
|
360
|
+
onCircle,
|
|
361
|
+
project
|
|
362
|
+
};
|
|
363
|
+
//# sourceMappingURL=iso.js.map
|
package/dist/iso.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/iso/geometry.ts","../src/iso/iso.tsx","../src/cx.ts"],"sourcesContent":["// Isometric projection, pure geometry (no React): the iso components compute their faces at render time — on the\n// server, as static markup. World: x to the lower right, y to the lower left, z up.\n// Screen: X = (x − y)·cos 30°, Y = (x + y)·sin 30° − z.\n\n/** A point in plan (x, y) or on screen (X, Y). */\nexport type Vec2 = readonly [number, number];\n/** A point in the world: x, y on the floor, z up. */\nexport type Vec3 = readonly [number, number, number];\n\nconst COS = Math.cos(Math.PI / 6);\nconst SIN = 0.5;\nconst f = (n: number) => (Math.round(n * 10) / 10).toString();\n\n/** The screen point of a world point. */\nexport function project([x, y, z]: Vec3): Vec2 {\n return [(x - y) * COS, (x + y) * SIN - z];\n}\n\n/** SVG `points` of screen points. */\nexport const pts = (points: readonly Vec2[]) => points.map(([x, y]) => `${f(x)},${f(y)}`).join(\" \");\n\n/** An SVG path through screen points. */\nexport const pathOf = (points: readonly Vec2[], close = false) =>\n points.map(([x, y], i) => `${i ? \"L\" : \"M\"}${f(x)} ${f(y)}`).join(\"\") + (close ? \"Z\" : \"\");\n\n/** A regular hexagon footprint (flat top in plan), centre (cx, cy), radius r. */\nexport function hexagon(cx: number, cy: number, r: number): Vec2[] {\n return Array.from({ length: 6 }, (_, k) => {\n const a = (Math.PI / 3) * k;\n return [cx + r * Math.cos(a), cy + r * Math.sin(a)] as const;\n });\n}\n\n/** A rectangle with 45° cut corners (the Krizaka chamfer), centre (cx, cy), size w × d, cut c (0: a plain rectangle). */\nexport function cutRect(cx: number, cy: number, w: number, d: number, c: number): Vec2[] {\n const x0 = cx - w / 2;\n const x1 = cx + w / 2;\n const y0 = cy - d / 2;\n const y1 = cy + d / 2;\n if (c <= 0) return [[x0, y0], [x1, y0], [x1, y1], [x0, y1]];\n return [[x0 + c, y0], [x1 - c, y0], [x1, y0 + c], [x1, y1 - c], [x1 - c, y1], [x0 + c, y1], [x0, y1 - c], [x0, y0 + c]];\n}\n\nexport interface Face {\n /** SVG `points`. */\n readonly points: string;\n /** The top, or a side facing the left or the right light. */\n readonly kind: \"top\" | \"left\" | \"right\";\n}\n\n/** The visible faces of a vertical prism over a footprint, painted back to front. */\nexport function prism(footprint: readonly Vec2[], z0: number, h: number): Face[] {\n const n = footprint.length;\n // The winding (shoelace) gives the outward normals whatever the order of the points.\n const area = footprint.reduce((s, [x, y], i) => {\n const [x2, y2] = footprint[(i + 1) % n]!;\n return s + (x * y2 - x2 * y);\n }, 0);\n const sign = area > 0 ? 1 : -1;\n const sides: { depth: number; face: Face }[] = [];\n for (let i = 0; i < n; i++) {\n const [ax, ay] = footprint[i]!;\n const [bx, by] = footprint[(i + 1) % n]!;\n const nx = sign * (by - ay);\n const ny = sign * -(bx - ax);\n if (nx + ny <= 1e-6) continue; // faces away from the viewer\n const quad: Vec2[] = [project([ax, ay, z0]), project([bx, by, z0]), project([bx, by, z0 + h]), project([ax, ay, z0 + h])];\n sides.push({ depth: ax + ay + bx + by, face: { points: pts(quad), kind: nx >= ny ? \"right\" : \"left\" } });\n }\n sides.sort((a, b) => a.depth - b.depth);\n const top: Face = { points: pts(footprint.map(([x, y]) => project([x, y, z0 + h]))), kind: \"top\" };\n return [...sides.map((s) => s.face), top];\n}\n\n/** The screen ellipse of a horizontal circle of radius r at height z: centre and radii. */\nexport function isoCircle(cx: number, cy: number, z: number, r: number) {\n const [x, y] = project([cx, cy, z]);\n return { cx: x, cy: y, rx: r * COS * Math.SQRT2, ry: r * SIN * Math.SQRT2 };\n}\n\n/** A point on a circle of the floor plan: angle in degrees, 0 toward the lower right (+x), clockwise on screen. */\nexport function onCircle(r: number, deg: number, [cx, cy]: Vec2 = [0, 0]): Vec2 {\n const a = (deg * Math.PI) / 180;\n return [cx + r * Math.cos(a), cy + r * Math.sin(a)];\n}\n\n/** Depth for the painter: larger is nearer the viewer. */\nexport const depthOf = ([x, y]: Vec2) => x + y;\n\n/** The view box that frames a floor of half-size `extent` and `top` units of height above it. */\nexport function viewBoxOf(extent: number, top: number, margin = 24): string {\n const w = 2 * extent * COS + margin * 2;\n return [-w / 2, -extent * SIN * 1.2 - top, w, extent * SIN * 2.4 + top].map(f).join(\" \");\n}\n","// Server-safe: no state, no effect, no context — static SVG computed at render time, animated by motion.css (`kz-iso-*`,\n// shipped by the preset), so a hero costs no client JavaScript. `useId` only (allowed in Server Components): every scene\n// owns its gradient and mask ids. Classes are joined with `cx`: no tailwind-variants in this entry.\nimport * as React from \"react\";\n\nimport { cx as cn } from \"../cx\";\nimport { cutRect, depthOf, type Face, hexagon, isoCircle, onCircle, pathOf, prism, project, pts, type Vec2, viewBoxOf } from \"./geometry\";\n\n/** How a solid is lit: the page's surfaces (`base`), the brand accent, accent → accent-2, or frosted glass. */\nexport type IsoMaterial = \"base\" | \"accent\" | \"accent2\" | \"glass\";\n/** The footprint of a prism: a hexagon (the marks), a rectangle with 45° cut corners (the icons) or a plain one. */\nexport type IsoShape = \"hex\" | \"cut\" | \"rect\";\n/** A pictogram drawn on the top of a tile. */\nexport type IsoGlyph = \"dots\" | \"lines\" | \"play\" | \"coin\" | \"lock\" | \"arrow\" | \"flag\" | \"heart\" | \"node\" | \"none\";\n\ntype Style = React.CSSProperties & Record<`--${string}`, string | number>;\n\nconst uid = (raw: string) => raw.replace(/[^a-zA-Z0-9_-]/g, \"\");\nconst footprint = (shape: IsoShape, [x, y]: Vec2, size: number | Vec2, cut?: number): Vec2[] => {\n const [w, d] = typeof size === \"number\" ? [size, size] : size;\n if (shape === \"hex\") return hexagon(x, y, w / 2);\n return cutRect(x, y, w, d, shape === \"rect\" ? 0 : (cut ?? Math.min(w, d) / 6));\n};\n\nexport interface IsoSceneProps extends Omit<React.ComponentProps<\"svg\">, \"children\"> {\n /** The accessible name of the scene (\"A server stack under a dome\") — passed translated. Without it the scene is decorative. */\n label?: string;\n /** A longer text version of what the scene shows, read by assistive technology. */\n description?: string;\n /**\n * Half the size of the floor, in world units: what the camera frames.\n * @default 240\n */\n extent?: number;\n /**\n * Height above the floor the camera keeps in view, in world units.\n * @default 260\n */\n top?: number;\n /**\n * The perspective grid on the floor, fading into the page.\n * @default true\n */\n grid?: boolean;\n /**\n * The spacing of the grid's lines.\n * @default 40\n */\n step?: number;\n /**\n * Motion (entrance, breathing, flow, float). `false` draws the still frame — the one prefers-reduced-motion shows.\n * @default true\n */\n animated?: boolean;\n /** The objects, painted in order: put the farthest first (or use `IsoHub`, which sorts them). */\n children?: React.ReactNode;\n}\n\n/**\n * The stage: an isometric camera over a perspective grid that fades into the page. Its animations pause off screen and\n * wait for the page to settle (MotionObserver); everything stops under prefers-reduced-motion.\n */\nexport function IsoScene({ label, description, extent = 240, top = 260, grid = true, step = 40, animated = true, viewBox, className, children, ...props }: IsoSceneProps) {\n const id = uid(React.useId());\n const lines: string[] = [];\n for (let v = -extent; v <= extent; v += step) {\n lines.push(pathOf([project([v, -extent, 0]), project([v, extent, 0])]), pathOf([project([-extent, v, 0]), project([extent, v, 0])]));\n }\n const fade = isoCircle(0, 0, 0, extent * 0.9);\n const named = label ? { role: \"group\" as const, \"aria-label\": label } : { \"aria-hidden\": true as const };\n return (\n <svg\n viewBox={viewBox ?? viewBoxOf(extent, top)}\n focusable=\"false\"\n data-motion-scope=\"\"\n data-animated={animated}\n className={cn(\"kz-iso\", className)}\n {...named}\n {...props}\n >\n {description && <desc>{description}</desc>}\n {grid && (\n <>\n <defs>\n <radialGradient id={`${id}-fade`}>\n <stop offset=\"0%\" stopColor=\"white\" stopOpacity=\"1\" />\n <stop offset=\"100%\" stopColor=\"white\" stopOpacity=\"0\" />\n </radialGradient>\n <mask id={`${id}-floor`}>\n <ellipse cx={fade.cx} cy={fade.cy} rx={fade.rx} ry={fade.ry} fill={`url(#${id}-fade)`} />\n </mask>\n </defs>\n <path d={lines.join(\"\")} className=\"kz-iso-floor\" mask={`url(#${id}-floor)`} />\n </>\n )}\n {children}\n </svg>\n );\n}\n\n/** A loop only when the scene moves: `animated={false}` on the item keeps it still. */\nconst loop = (animated: boolean | undefined) => (animated === false ? undefined : \"kz-loop\");\n\ninterface ItemProps {\n /** The name shown when the pointer (or the focus) lifts the object — passed translated. It also makes it focusable. */\n label?: string;\n /**\n * Its rank in the entrance: objects rise into place one after the other.\n * @default 0\n */\n index?: number;\n /**\n * Motion: entrance and loops. `false` keeps this object still.\n * @default true\n */\n animated?: boolean;\n /** Extra classes on the object's group. */\n className?: string;\n}\n\n/** An object of the scene: rises at the entrance, lifts under the pointer or the focus and shows its label. */\nfunction Item({ label, index = 0, animated, anchor, align = \"center\", className, children }: ItemProps & { anchor: Vec2; align?: \"center\" | \"start\"; children: React.ReactNode }) {\n const named = label ? { role: \"img\" as const, \"aria-label\": label, tabIndex: 0 } : {};\n return (\n <g className={cn(\"kz-iso-item\", className)} style={{ \"--kz-iso-i\": index } as Style} {...named}>\n <g className={cn(\"kz-iso-lift\", animated !== false && \"kz-iso-rise\")}>{children}</g>\n {label && <Tip at={anchor} text={label} align={align} />}\n </g>\n );\n}\n\n/**\n * A label in a pill (decorative: the object carries the name). `center`: above the point (a floating tile). `start`:\n * beside it, to the right, with a leader — for a stage of a stack, whose upper stages would cover a label above it.\n */\nfunction Tip({ at: [x, y], text, align }: { at: Vec2; text: string; align: \"center\" | \"start\" }) {\n const w = Math.max(40, text.length * 6.6 + 20);\n if (align === \"start\") {\n return (\n <g className=\"kz-iso-tip\" aria-hidden>\n <path d={`M${Math.round(x + 3)} ${Math.round(y)}h18`} className=\"kz-iso-leader\" />\n <rect x={x + 21} y={y - 11} width={w} height={22} rx={7} strokeWidth={1} />\n <text x={x + 21 + w / 2} y={y + 4} textAnchor=\"middle\">\n {text}\n </text>\n </g>\n );\n }\n return (\n <g className=\"kz-iso-tip\" aria-hidden>\n <rect x={x - w / 2} y={y - 34} width={w} height={22} rx={7} strokeWidth={1} />\n <text x={x} y={y - 19} textAnchor=\"middle\">\n {text}\n </text>\n </g>\n );\n}\n\nfunction Solid({ faces, material }: { faces: Face[]; material: IsoMaterial }) {\n return (\n <g className={\"kz-iso-\" + material}>\n {faces.map((face, i) => (\n <polygon key={i} points={face.points} className={\"kz-iso-face kz-iso-\" + face.kind} />\n ))}\n </g>\n );\n}\n\nexport interface IsoPrismProps extends ItemProps {\n /**\n * The centre of its footprint on the floor plan (x, y).\n * @default [0, 0]\n */\n at?: Vec2;\n /**\n * The height of its base above the floor.\n * @default 0\n */\n z?: number;\n /** Its height. */\n height: number;\n /**\n * hex · cut (45° cut corners) · rect.\n * @default \"cut\"\n */\n shape?: IsoShape;\n /**\n * Its width (a number: square or hexagon's diameter) or width × depth.\n * @default 120\n */\n size?: number | Vec2;\n /** The size of the 45° cut (`shape=\"cut\"`); a sixth of the smaller side by default. */\n cut?: number;\n /**\n * How it is lit.\n * @default \"base\"\n */\n material?: IsoMaterial;\n /** A dotted light strip around its front (the LEDs of a server), blinking slowly. */\n strip?: boolean;\n}\n\n/** A vertical prism — hexagonal, cut-corner or rectangular — that stacks with others on `z`. */\nexport function IsoPrism({ at = [0, 0], z = 0, height, shape = \"cut\", size = 120, cut, material = \"base\", strip, animated, ...item }: IsoPrismProps) {\n const foot = footprint(shape, at, size, cut);\n const [w, d] = typeof size === \"number\" ? [size, size] : size;\n return (\n <Item {...item} animated={animated} anchor={project(shape === \"hex\" ? [at[0] + w / 4, at[1] - w * 0.433, z + height / 2] : [at[0] + w / 2, at[1] - d / 2, z + height / 2])} align=\"start\">\n <Solid faces={prism(foot, z, height)} material={material} />\n {strip && <Strip at={at} w={w} d={d} c={shape === \"rect\" ? 0 : (cut ?? Math.min(w, d) / 6)} z={z + height / 2 + 1} animated={animated} hex={shape === \"hex\"} />}\n </Item>\n );\n}\n\nfunction Strip({ at: [cx, cy], w, d, c, z, hex, animated }: { at: Vec2; w: number; d: number; c: number; z: number; hex: boolean; animated?: boolean }) {\n const front: Vec2[] = hex\n ? [0, 1, 2].map((k) => onCircle(w / 2, k * 60 - 60, [cx, cy]))\n : [[cx + w / 2, cy - d / 2 + c], [cx + w / 2, cy + d / 2 - c], [cx + w / 2 - c, cy + d / 2], [cx - w / 2 + c, cy + d / 2]];\n return <polyline points={pts(front.map(([x, y]) => project([x, y, z])))} className={cn(\"kz-iso-strip\", loop(animated))} />;\n}\n\n/** One stage of an `IsoStack`. */\nexport interface IsoLayer {\n /** The stage's name, shown when it is lifted — passed translated. */\n label?: string;\n /**\n * Its height.\n * @default 22\n */\n height?: number;\n /**\n * How it is lit.\n * @default \"base\"\n */\n material?: IsoMaterial;\n}\n\nexport interface IsoStackProps {\n /** The stages, bottom first; they stack one after the other at the entrance. */\n layers: readonly IsoLayer[];\n /**\n * The centre of the stack on the floor plan.\n * @default [0, 0]\n */\n at?: Vec2;\n /**\n * The footprint of the stages.\n * @default \"cut\"\n */\n shape?: IsoShape;\n /**\n * The width of the stages.\n * @default 120\n */\n size?: number;\n /**\n * The space between two stages.\n * @default 4\n */\n gap?: number;\n /**\n * A hexagonal plinth under the stack.\n * @default true\n */\n plinth?: boolean;\n /**\n * A lit hexagonal core on top, its node glowing; a string names it.\n * @default true\n */\n core?: boolean | string;\n /**\n * The rank of the first stage in the scene's entrance.\n * @default 0\n */\n index?: number;\n /**\n * Motion: entrance and loops. `false` keeps the stack still.\n * @default true\n */\n animated?: boolean;\n}\n\n/** A stack of stages on a plinth with a lit core on top — a server, a model, a pile of layers — driven by data. */\nexport function IsoStack({ layers, at = [0, 0], shape = \"cut\", size = 120, gap = 4, plinth = true, core = true, index = 0, animated }: IsoStackProps) {\n const base = plinth ? 12 + gap : 0;\n const heights = layers.map((layer) => layer.height ?? 22);\n const stages = layers.map((layer, k) => ({ ...layer, k, height: heights[k]!, z: base + heights.slice(0, k).reduce((sum, h) => sum + h + gap, 0) }));\n const top = base + heights.reduce((sum, h) => sum + h + gap, 0);\n return (\n <g>\n {plinth && <IsoPrism at={at} height={12} shape=\"hex\" size={size * 1.86} index={index} animated={animated} />}\n {stages.map((s) => (\n <IsoPrism\n key={s.k}\n at={at}\n z={s.z}\n height={s.height}\n shape={shape}\n size={size}\n material={s.material ?? \"base\"}\n strip={(s.material ?? \"base\") === \"base\"}\n label={s.label}\n index={index + 1 + s.k}\n animated={animated}\n />\n ))}\n {core && (\n <>\n <IsoPrism at={at} z={top} height={16} shape=\"hex\" size={size / 2} material=\"accent\" index={index + 1 + stages.length} animated={animated} label={typeof core === \"string\" ? core : undefined} />\n <IsoNode at={at} z={top + 22} index={index + 2 + stages.length} animated={animated} />\n </>\n )}\n </g>\n );\n}\n\nexport interface IsoNodeProps {\n /**\n * Where, on the floor plan.\n * @default [0, 0]\n */\n at?: Vec2;\n /**\n * Its height.\n * @default 0\n */\n z?: number;\n /**\n * The radius of the node.\n * @default 7\n */\n r?: number;\n /**\n * The radius of its glow (0: none).\n * @default 70\n */\n glow?: number;\n /**\n * Its rank in the entrance.\n * @default 0\n */\n index?: number;\n /**\n * Motion: the glow breathes. `false` keeps it still.\n * @default true\n */\n animated?: boolean;\n}\n\n/** The Krizaka node: a point of light in the accent, breathing in its glow. */\nexport function IsoNode({ at = [0, 0], z = 0, r = 7, glow = 70, index = 0, animated }: IsoNodeProps) {\n const id = uid(React.useId());\n const [x, y] = project([at[0], at[1], z]);\n return (\n <g className={cn(animated !== false && \"kz-iso-rise\")} style={{ \"--kz-iso-i\": index } as Style}>\n {glow > 0 && (\n <>\n <defs>\n <radialGradient id={`${id}-glow`}>\n <stop offset=\"0%\" className=\"kz-iso-glow-stop\" stopOpacity=\"0.55\" />\n <stop offset=\"100%\" className=\"kz-iso-glow-stop\" stopOpacity=\"0\" />\n </radialGradient>\n </defs>\n <circle cx={x} cy={y} r={glow} fill={`url(#${id}-glow)`} className={cn(\"kz-iso-breathe\", loop(animated))} />\n </>\n )}\n <circle cx={x} cy={y} r={r} className={cn(\"kz-iso-node kz-iso-breathe\", loop(animated))} />\n </g>\n );\n}\n\nexport interface IsoDomeProps {\n /**\n * Its centre on the floor plan.\n * @default [0, 0]\n */\n at?: Vec2;\n /**\n * The radius of its rim on the floor.\n * @default 158\n */\n radius?: number;\n /**\n * Its height.\n * @default 250\n */\n height?: number;\n /** Its name (\"Your infrastructure\") — passed translated; shown at the top of the dome, always. */\n label?: string;\n /**\n * Motion: a sheen travels along the dome. `false` keeps it still.\n * @default true\n */\n animated?: boolean;\n}\n\n/**\n * A dome of light over what it protects: a rim on the floor, a glass arc, a sheen that travels along it. Draw its rim\n * before the objects it covers and the dome after them (`part=\"rim\"`, `part=\"arc\"`), or let `IsoHub` do it.\n */\nexport function IsoDome({ at = [0, 0], radius = 158, height = 250, label, animated, part = \"both\" }: IsoDomeProps & {\n /**\n * `rim` (the floor ellipse, drawn first), `arc` (the glass, drawn last) or `both`.\n * @default \"both\"\n */\n part?: \"rim\" | \"arc\" | \"both\";\n}) {\n const e = isoCircle(at[0], at[1], 0, radius);\n const arc = `M${e.cx - e.rx} ${e.cy} A ${e.rx} ${height} 0 0 1 ${e.cx + e.rx} ${e.cy}`;\n return (\n <>\n {part !== \"arc\" && <ellipse cx={e.cx} cy={e.cy} rx={e.rx} ry={e.ry} className=\"kz-iso-rim\" />}\n {part !== \"rim\" && (\n <g>\n <path d={arc} className=\"kz-iso-dome\" />\n <path d={arc} className={cn(\"kz-iso-dome-sheen\", loop(animated))} pathLength={440} />\n {label && <IsoLabel at={at} z={height + 10} text={label} />}\n </g>\n )}\n </>\n );\n}\n\nexport interface IsoTileProps extends ItemProps {\n /** Its centre on the floor plan. */\n at: Vec2;\n /**\n * The height it floats at.\n * @default 90\n */\n z?: number;\n /**\n * Width × depth.\n * @default [76, 52]\n */\n size?: Vec2;\n /**\n * The pictogram on its top.\n * @default \"none\"\n */\n glyph?: IsoGlyph;\n /**\n * How it is lit.\n * @default \"accent\"\n */\n material?: IsoMaterial;\n /**\n * It floats gently.\n * @default true\n */\n float?: boolean;\n}\n\n/** A satellite: a thin cut-corner tile that floats beside the hero object, a pictogram on its top. */\nexport function IsoTile({ at, z = 90, size = [76, 52], glyph = \"none\", material = \"accent\", float = true, animated, ...item }: IsoTileProps) {\n const [w, d] = size;\n const top = z + 9;\n const shadow = isoCircle(at[0], at[1], 0, Math.min(w, d) * 0.55);\n const foot = project([at[0], at[1], 0]);\n return (\n <Item {...item} animated={animated} anchor={project([at[0], at[1], top])}>\n {z > 0 && (\n <>\n <ellipse cx={shadow.cx} cy={shadow.cy} rx={shadow.rx} ry={shadow.ry} className=\"kz-iso-shadow\" />\n <path d={pathOf([foot, project([at[0], at[1], z])])} className=\"kz-iso-tether\" />\n </>\n )}\n <g className={cn(float && \"kz-iso-float\", float && loop(animated))}>\n <Solid faces={prism(cutRect(at[0], at[1], w, d, Math.min(w, d) / 4), z, 9)} material={material} />\n <Glyph glyph={glyph} at={at} z={top} s={Math.min(w, d) * 0.3} />\n </g>\n </Item>\n );\n}\n\nfunction Glyph({ glyph, at: [cx, cy], z, s }: { glyph: IsoGlyph; at: Vec2; z: number; s: number }) {\n const p = (u: number, v: number) => project([cx + u * s, cy + v * s, z]);\n const line = (points: [number, number][], close = false) => <path d={pathOf(points.map(([u, v]) => p(u, v)), close)} className=\"kz-iso-glyph\" />;\n switch (glyph) {\n case \"dots\":\n return <>{[-0.8, 0, 0.8].map((u) => <circle key={u} cx={p(u, 0)[0]} cy={p(u, 0)[1]} r={s * 0.16} className=\"kz-iso-glyph-fill\" />)}</>;\n case \"lines\":\n return <>{[-0.6, 0, 0.6].map((v) => <React.Fragment key={v}>{line([[-0.9, v], [0.7, v]])}</React.Fragment>)}</>;\n case \"play\":\n return line([[-0.5, -0.7], [0.8, 0], [-0.5, 0.7]], true);\n case \"coin\":\n return (\n <>\n <path d={pathOf(hexagon(0, 0, 0.9).map(([u, v]) => p(u, v)), true)} className=\"kz-iso-glyph\" />\n <circle cx={p(0, 0)[0]} cy={p(0, 0)[1]} r={s * 0.18} className=\"kz-iso-glyph-fill\" />\n </>\n );\n case \"lock\":\n return (\n <>\n {line([[-0.6, -0.1], [0.6, -0.1], [0.6, 0.8], [-0.6, 0.8]], true)}\n {line([[-0.35, -0.1], [-0.35, -0.5], [-0.15, -0.75], [0.15, -0.75], [0.35, -0.5], [0.35, -0.1]])}\n </>\n );\n case \"arrow\":\n return (\n <>\n {line([[0.8, 0.8], [-0.6, -0.6]])}\n {line([[-0.6, 0.1], [-0.6, -0.6], [0.1, -0.6]])}\n </>\n );\n case \"flag\":\n return (\n <>\n {line([[-0.7, 0.9], [-0.7, -0.9]])}\n {line([[-0.7, -0.9], [0.8, -0.55], [-0.7, -0.1]], true)}\n </>\n );\n case \"heart\":\n return line([[0, 0.85], [-0.85, 0], [-0.85, -0.45], [-0.45, -0.8], [0, -0.45], [0.45, -0.8], [0.85, -0.45], [0.85, 0]], true);\n case \"node\":\n return <circle cx={p(0, 0)[0]} cy={p(0, 0)[1]} r={s * 0.3} className=\"kz-iso-glyph-fill\" />;\n default:\n return null;\n }\n}\n\nexport interface IsoLinkProps {\n /** Where it starts, on the floor plan. */\n from: Vec2;\n /** Where it ends, on the floor plan. */\n to: Vec2;\n /**\n * The height it runs at.\n * @default 0\n */\n z?: number;\n /**\n * `elbow` follows the floor's axes, like a circuit; `straight` goes directly.\n * @default \"elbow\"\n */\n route?: \"elbow\" | \"straight\";\n /**\n * Which way the light flows: `out` from `from` to `to`, `in` back.\n * @default \"out\"\n */\n direction?: \"out\" | \"in\";\n /**\n * Particles of light travelling along it (0: only the dashes flow).\n * @default 2\n */\n particles?: number;\n /**\n * Seconds a particle takes to cross it.\n * @default 3.6\n */\n duration?: number;\n /** A value written on it (\"90 %\", \"Tips\") — passed translated. */\n label?: string;\n /**\n * Motion: the flow and the particles. `false` draws them still, resting along the link.\n * @default true\n */\n animated?: boolean;\n}\n\n/** A dotted link on the floor, light flowing along it and particles crossing it — a flow between two objects. */\nexport function IsoLink({ from, to, z = 0, route = \"elbow\", direction = \"out\", particles = 2, duration = 3.6, label, animated }: IsoLinkProps) {\n const corner: Vec2 = [to[0], from[1]];\n const plan = route === \"elbow\" && from[0] !== to[0] && from[1] !== to[1] ? [from, corner, to] : [from, to];\n const ordered = direction === \"in\" ? [...plan].reverse() : plan;\n const d = pathOf(ordered.map(([x, y]) => project([x, y, z])));\n const mid = plan.length === 3 ? corner : ([(from[0] + to[0]) / 2, (from[1] + to[1]) / 2] as Vec2);\n return (\n <g>\n <path d={d} className={cn(\"kz-iso-link\", loop(animated))} />\n {Array.from({ length: particles }, (_, k) => (\n <circle\n key={k}\n r={3.2}\n className={cn(\"kz-iso-particle\", loop(animated))}\n style={\n {\n offsetPath: `path(\"${d}\")`,\n \"--kz-iso-at\": `${Math.round(((k + 0.5) / particles) * 100)}%`,\n \"--kz-iso-dur\": `${duration}s`,\n \"--kz-iso-delay\": `${(-duration * k) / particles}s`,\n } as Style\n }\n />\n ))}\n {label && <IsoLabel at={mid} z={z} text={label} />}\n </g>\n );\n}\n\nexport interface IsoLabelProps {\n /** Where, on the floor plan. */\n at: Vec2;\n /**\n * Its height.\n * @default 0\n */\n z?: number;\n /** The text — passed translated. */\n text: string;\n /** A first part in the accent, bolder (\"90 %\" before \" to the creator\"). */\n strong?: string;\n}\n\n/** A label in a pill, always visible, pinned to a point of the scene (a share, a name). */\nexport function IsoLabel({ at, z = 0, text, strong }: IsoLabelProps) {\n const [x, y] = project([at[0], at[1], z]);\n const chars = text.length + (strong ? strong.length + 1 : 0);\n const w = chars * 6.8 + 22;\n return (\n <g className=\"kz-iso-link-label\" aria-hidden>\n <rect x={x - w / 2} y={y - 12} width={w} height={24} rx={8} strokeWidth={1} />\n <text x={x} y={y + 4} textAnchor=\"middle\">\n {strong && <tspan className=\"kz-iso-strong\">{strong} </tspan>}\n {text}\n </text>\n </g>\n );\n}\n\n/** A satellite of an `IsoHub`. */\nexport interface IsoSatellite {\n /** Its name, shown when lifted — passed translated. */\n label: string;\n /**\n * Its pictogram.\n * @default \"none\"\n */\n glyph?: IsoGlyph;\n /**\n * The flow on its link: `in` toward the centre, `out` from it, `none` without a link.\n * @default \"in\"\n */\n flow?: \"in\" | \"out\" | \"none\";\n /** A value written on its link (\"+ €5\") — passed translated. */\n value?: string;\n /**\n * How it is lit.\n * @default \"accent\"\n */\n material?: IsoMaterial;\n}\n\nexport interface IsoHubProps extends Omit<IsoSceneProps, \"children\"> {\n /** The hero object in the centre: its stages, bottom first. */\n layers: readonly IsoLayer[];\n /**\n * The footprint of the stages.\n * @default \"cut\"\n */\n shape?: IsoShape;\n /**\n * The width of the stages.\n * @default 120\n */\n size?: number;\n /**\n * A lit core on top of the stack; a string names it.\n * @default true\n */\n core?: boolean | string;\n /** A dome over the centre: `true`, or its name (\"Your servers\"). */\n dome?: boolean | string;\n /**\n * The objects around the centre, joined to it by flows of light. The first half stands on the left, the rest on the\n * right, top to bottom: never in front of the hero, never hidden behind it.\n */\n satellites?: readonly IsoSatellite[];\n /**\n * The distance of the satellites from the centre.\n * @default 210\n */\n radius?: number;\n /** The angle of each satellite, in degrees (0: lower right, 90: lower left, 180: upper left, 270: upper right), to place them by hand. */\n angles?: readonly number[];\n /** A label pinned above the centre, its first part in the accent: `{ strong: \"90 %\", text: \"to the creator\" }`. */\n highlight?: { readonly strong?: string; readonly text: string };\n}\n\n/** Left side (centred on 135°) then right side (centred on −45°), top to bottom, 64° apart. */\nfunction sideAngles(n: number): number[] {\n const left = Math.ceil(n / 2);\n const right = n - left;\n const spread = (m: number, centre: number, sign: 1 | -1) => Array.from({ length: m }, (_, i) => centre + sign * ((m - 1) / 2 - i) * 64);\n return [...spread(left, 135, 1), ...spread(right, -45, -1)];\n}\n\n/**\n * The hero, driven by data: a stack under an optional dome, satellites on both sides, a flow of light between each\n * satellite and the centre. Objects are painted back to front and the camera frames exactly what is drawn.\n */\nexport function IsoHub({ layers, shape, size = 120, core, dome, satellites = [], radius = 210, angles, highlight, animated, viewBox, extent, ...scene }: IsoHubProps) {\n const auto = sideAngles(satellites.length);\n const placed = satellites.map((s, k) => {\n const angle = angles?.[k] ?? auto[k] ?? 0;\n const at = onCircle(radius, angle);\n // The farther back, the higher it floats: two tiles of a side never cover each other.\n return { ...s, angle, at, z: Math.round(78 - (depthOf(at) / radius) * 26), k };\n });\n const back = placed.filter((s) => depthOf(s.at) < 0);\n const front = placed.filter((s) => depthOf(s.at) >= 0);\n const stackHeight = layers.reduce((h, l) => h + (l.height ?? 22) + 4, 16) + (core === false ? 0 : 38);\n const domeR = size * 1.32;\n const domeH = Math.max(stackHeight + 80, 200);\n const crown = dome ? domeH + 24 : stackHeight + (highlight ? 62 : 12);\n // The frame: every object's screen extent (tiles with room for their label, the plinth, the dome or the crown).\n const points: Vec2[] = [\n ...placed.flatMap(({ at: [x, y], z }) => [project([x - 46, y - 46, z + 52]), project([x + 46, y + 46, z]), project([x + 46, y - 46, z]), project([x - 46, y + 46, z])]),\n ...hexagon(0, 0, size * (dome ? 1.4 : 0.95)).map(([x, y]) => project([x, y, 0])),\n project([0, 0, crown + 20]),\n ];\n const xs = points.map(([x]) => x);\n const ys = points.map(([, y]) => y);\n const half = Math.max(...xs.map(Math.abs)) + 20;\n const box = [-half, Math.min(...ys) - 12, half * 2, Math.max(...ys) - Math.min(...ys) + 40].map((n) => Math.round(n)).join(\" \");\n const tile = (s: (typeof placed)[number]) => (\n <IsoTile key={s.k} at={s.at} z={s.z} glyph={s.glyph} material={s.material} label={s.label} index={layers.length + 3 + s.k} animated={animated} />\n );\n const link = (s: (typeof placed)[number]) =>\n s.flow === \"none\" ? null : (\n <IsoLink\n key={`l${s.k}`}\n from={s.at}\n to={onCircle(size * (dome ? 1.32 : 0.8), s.angle)}\n route=\"straight\"\n direction={s.flow === \"out\" ? \"in\" : \"out\"}\n label={s.value}\n animated={animated}\n />\n );\n return (\n <IsoScene animated={animated} extent={extent ?? Math.round(radius * 1.45 + 60)} viewBox={viewBox ?? box} {...scene}>\n {placed.map(link)}\n {dome && <IsoDome radius={domeR} part=\"rim\" animated={animated} />}\n {back.map(tile)}\n <IsoStack layers={layers} shape={shape} size={size} core={core} animated={animated} />\n {dome && <IsoDome radius={domeR} height={domeH} part=\"arc\" animated={animated} label={typeof dome === \"string\" ? dome : undefined} />}\n {highlight && <IsoLabel at={[0, 0]} z={stackHeight + (dome ? 24 : 46)} strong={highlight.strong} text={highlight.text} />}\n {front.map(tile)}\n </IsoScene>\n );\n}\n","/** Joins class names, skipping the falsy ones. */\nexport function cx(...parts: Array<string | false | null | undefined>): string {\n return parts.filter(Boolean).join(\" \");\n}\n"],"mappings":"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","names":["cx","footprint","Fragment","cx"]}
|