@krizaka/ui 1.0.0 → 1.2.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 CHANGED
@@ -22,6 +22,20 @@ npm install @krizaka/ui
22
22
 
23
23
  React 18 or 19. No framework, no CSS library required: the marks carry their own styles, the motion is one CSS file.
24
24
 
25
+
26
+ ## React Native
27
+
28
+ The marks have one geometry; `@krizaka/ui/native` draws it with `react-native-svg` for the apps
29
+ ([orochia-mobile](https://github.com/krizaka/orochia-mobile)). The orbit turns and the flame breathes on the native
30
+ driver, and stay still when the system asks to reduce motion. `react-dom`, `react-native` and `react-native-svg` are
31
+ optional peers: a web app never installs the native ones, a native app never installs `react-dom`.
32
+
33
+ ```tsx
34
+ import { OrochiaMark } from "@krizaka/ui/native";
35
+
36
+ <OrochiaMark size={72} title="Orochia" neutral={theme.border} />
37
+ ```
38
+
25
39
  ## The marks
26
40
 
27
41
  ```tsx
@@ -72,12 +86,17 @@ With Tailwind CSS v4, give every transition the same easing:
72
86
 
73
87
  ## Develop
74
88
 
89
+ This package lives in the [`krizaka-ui`](https://github.com/krizaka/krizaka-ui) monorepo (pnpm + Turborepo), in
90
+ `packages/ui`. From the repository root:
91
+
75
92
  ```bash
76
- npm install
77
- npm run check # type-check, tests, build
93
+ pnpm install
94
+ pnpm turbo run check --filter=@krizaka/ui # lint, type-check, tests, build, size, publint
78
95
  ```
79
96
 
80
- Releases: a `v*` tag publishes to npm from CI with provenance.
97
+ Releases go through [Changesets](https://github.com/changesets/changesets): a pull request adds a
98
+ `.changeset/*.md`; merging the "Version Packages" pull request publishes to npm with provenance and tags
99
+ `@krizaka/ui@x.y.z`.
81
100
 
82
101
  ## Used by
83
102
 
package/dist/index.js CHANGED
@@ -106,6 +106,30 @@ function OrazakaLogo({ size = 28, animated = true, title, className }) {
106
106
  ] });
107
107
  }
108
108
 
109
+ // src/marks/orochia-geometry.ts
110
+ var OROCHIA = {
111
+ viewBox: "0 0 400 400",
112
+ croppedViewBox: "86 82 228 228",
113
+ offset: 20,
114
+ body: { x1: 70, y1: 290, x2: 290, y2: 70, stops: [["0%", "#7c3aed"], ["55%", "#d946ef"], ["100%", "#f472b6"]] },
115
+ flameGradient: { stops: [["0%", "#a855f7"], ["100%", "#f9a8d4"]] },
116
+ glow: { color: "#d946ef", opacity: 0.18 },
117
+ orbit: { r: 160, dash: "8 8", width: 1.5 },
118
+ ring: { r: 134, width: 1 },
119
+ arc: "M259.8,142.8 A88,88 0 1 1 142.8,100.2",
120
+ neck: "M142.8,100.2 A88,88 0 0 1 187.7,92.3",
121
+ tail: "M187.7,92.3 A88,88 0 0 1 221.3,102.3",
122
+ scales: { color: "#fdf4ff", opacity: 0.45, width: 3, dash: "2 14" },
123
+ head: { cx: 253.9, cy: 130.1, rx: 13, ry: 20, rotate: -25 },
124
+ tongue: { d: "M245.4,112.0 L242.0,104.8 L235.0,101.5 M242.0,104.8 L244.0,97.3", color: "#f472b6" },
125
+ eye: { cx: 256.3, cy: 123.5, r: 4.5, color: "#fdf4ff" },
126
+ flame: {
127
+ translate: [127, 120],
128
+ scale: 4.4,
129
+ d: "M8.5 14.5A2.5 2.5 0 0 0 11 12c0-1.38-.5-2-1-3-1.072-2.143-.224-4.054 2-6 .5 2.5 2 4.9 4 6.5 2 1.6 3 3.5 3 5.5a7 7 0 1 1-14 0c0-1.153.433-2.294 1-3a2.5 2.5 0 0 0 2.5 2.5z"
130
+ }
131
+ };
132
+
109
133
  // src/marks/OrochiaLogo.tsx
110
134
  import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
111
135
  var CSS3 = `
@@ -123,44 +147,28 @@ var CSS3 = `
123
147
  function OrochiaLogo({ size = 36, animated = true, title, className }) {
124
148
  const id = useIds("orom", ["body", "flame", "glow"]);
125
149
  const m = (cls) => animated ? cls : void 0;
126
- const arc = "M259.8,142.8 A88,88 0 1 1 142.8,100.2";
127
- return /* @__PURE__ */ jsxs3("svg", { width: size, height: size, viewBox: size < 48 ? "86 82 228 228" : "0 0 400 400", fill: "none", xmlns: "http://www.w3.org/2000/svg", className, ...a11y(title), children: [
150
+ return /* @__PURE__ */ jsxs3("svg", { width: size, height: size, viewBox: size < 48 ? OROCHIA.croppedViewBox : OROCHIA.viewBox, fill: "none", xmlns: "http://www.w3.org/2000/svg", className, ...a11y(title), children: [
128
151
  /* @__PURE__ */ jsx3("style", { children: CSS3 }),
129
152
  /* @__PURE__ */ jsxs3("defs", { children: [
130
- /* @__PURE__ */ jsxs3("linearGradient", { id: id.body, gradientUnits: "userSpaceOnUse", x1: "70", y1: "290", x2: "290", y2: "70", children: [
131
- /* @__PURE__ */ jsx3("stop", { offset: "0%", stopColor: "#7c3aed" }),
132
- /* @__PURE__ */ jsx3("stop", { offset: "55%", stopColor: "#d946ef" }),
133
- /* @__PURE__ */ jsx3("stop", { offset: "100%", stopColor: "#f472b6" })
134
- ] }),
135
- /* @__PURE__ */ jsxs3("linearGradient", { id: id.flame, x1: "50%", y1: "100%", x2: "50%", y2: "0%", children: [
136
- /* @__PURE__ */ jsx3("stop", { offset: "0%", stopColor: "#a855f7" }),
137
- /* @__PURE__ */ jsx3("stop", { offset: "100%", stopColor: "#f9a8d4" })
138
- ] }),
153
+ /* @__PURE__ */ jsx3("linearGradient", { id: id.body, gradientUnits: "userSpaceOnUse", x1: OROCHIA.body.x1, y1: OROCHIA.body.y1, x2: OROCHIA.body.x2, y2: OROCHIA.body.y2, children: OROCHIA.body.stops.map(([offset, color]) => /* @__PURE__ */ jsx3("stop", { offset, stopColor: color }, offset)) }),
154
+ /* @__PURE__ */ jsx3("linearGradient", { id: id.flame, x1: "50%", y1: "100%", x2: "50%", y2: "0%", children: OROCHIA.flameGradient.stops.map(([offset, color]) => /* @__PURE__ */ jsx3("stop", { offset, stopColor: color }, offset)) }),
139
155
  /* @__PURE__ */ jsxs3("radialGradient", { id: id.glow, cx: "50%", cy: "50%", r: "50%", children: [
140
- /* @__PURE__ */ jsx3("stop", { offset: "0%", stopColor: "#d946ef", stopOpacity: "0.18" }),
141
- /* @__PURE__ */ jsx3("stop", { offset: "100%", stopColor: "#d946ef", stopOpacity: "0" })
156
+ /* @__PURE__ */ jsx3("stop", { offset: "0%", stopColor: OROCHIA.glow.color, stopOpacity: OROCHIA.glow.opacity }),
157
+ /* @__PURE__ */ jsx3("stop", { offset: "100%", stopColor: OROCHIA.glow.color, stopOpacity: "0" })
142
158
  ] })
143
159
  ] }),
144
- /* @__PURE__ */ jsxs3("g", { transform: "translate(20 20)", children: [
160
+ /* @__PURE__ */ jsxs3("g", { transform: `translate(${OROCHIA.offset} ${OROCHIA.offset})`, children: [
145
161
  /* @__PURE__ */ jsx3("circle", { cx: "180", cy: "180", r: "170", fill: `url(#${id.glow})` }),
146
- /* @__PURE__ */ jsx3("circle", { className: m("orom-spin"), cx: "180", cy: "180", r: "160", stroke: neutral("--kz-border-strong", 40), strokeWidth: "1.5", strokeDasharray: "8 8", opacity: ".6" }),
147
- /* @__PURE__ */ jsx3("circle", { cx: "180", cy: "180", r: "134", stroke: neutral("--kz-border-default", 30), strokeWidth: "1", opacity: ".35" }),
148
- /* @__PURE__ */ jsx3("path", { d: arc, stroke: `url(#${id.body})`, strokeWidth: "22", strokeLinecap: "round" }),
149
- /* @__PURE__ */ jsx3("path", { className: m("orom-slither"), d: arc, stroke: "#fdf4ff", strokeOpacity: ".45", strokeWidth: "3", strokeLinecap: "round", strokeDasharray: "2 14" }),
150
- /* @__PURE__ */ jsx3("path", { d: "M142.8,100.2 A88,88 0 0 1 187.7,92.3", stroke: `url(#${id.body})`, strokeWidth: "14", strokeLinecap: "round" }),
151
- /* @__PURE__ */ jsx3("path", { d: "M187.7,92.3 A88,88 0 0 1 221.3,102.3", stroke: `url(#${id.body})`, strokeWidth: "6", strokeLinecap: "round" }),
152
- /* @__PURE__ */ jsx3("ellipse", { cx: "253.9", cy: "130.1", rx: "13", ry: "20", transform: "rotate(-25 253.9 130.1)", fill: `url(#${id.body})` }),
153
- /* @__PURE__ */ jsx3("path", { d: "M245.4,112.0 L242.0,104.8 L235.0,101.5 M242.0,104.8 L244.0,97.3", stroke: "#f472b6", strokeWidth: "3", strokeLinecap: "round" }),
154
- /* @__PURE__ */ jsx3("circle", { className: m("orom-pulse"), cx: "256.3", cy: "123.5", r: "4.5", fill: "#fdf4ff" }),
155
- /* @__PURE__ */ jsx3(
156
- "path",
157
- {
158
- className: m("orom-pulse"),
159
- transform: "translate(127 120) scale(4.4)",
160
- d: "M8.5 14.5A2.5 2.5 0 0 0 11 12c0-1.38-.5-2-1-3-1.072-2.143-.224-4.054 2-6 .5 2.5 2 4.9 4 6.5 2 1.6 3 3.5 3 5.5a7 7 0 1 1-14 0c0-1.153.433-2.294 1-3a2.5 2.5 0 0 0 2.5 2.5z",
161
- fill: `url(#${id.flame})`
162
- }
163
- )
162
+ /* @__PURE__ */ jsx3("circle", { className: m("orom-spin"), cx: "180", cy: "180", r: OROCHIA.orbit.r, stroke: neutral("--kz-border-strong", 40), strokeWidth: OROCHIA.orbit.width, strokeDasharray: OROCHIA.orbit.dash, opacity: ".6" }),
163
+ /* @__PURE__ */ jsx3("circle", { cx: "180", cy: "180", r: OROCHIA.ring.r, stroke: neutral("--kz-border-default", 30), strokeWidth: OROCHIA.ring.width, opacity: ".35" }),
164
+ /* @__PURE__ */ jsx3("path", { d: OROCHIA.arc, stroke: `url(#${id.body})`, strokeWidth: "22", strokeLinecap: "round" }),
165
+ /* @__PURE__ */ jsx3("path", { className: m("orom-slither"), d: OROCHIA.arc, stroke: OROCHIA.scales.color, strokeOpacity: OROCHIA.scales.opacity, strokeWidth: OROCHIA.scales.width, strokeLinecap: "round", strokeDasharray: OROCHIA.scales.dash }),
166
+ /* @__PURE__ */ jsx3("path", { d: OROCHIA.neck, stroke: `url(#${id.body})`, strokeWidth: "14", strokeLinecap: "round" }),
167
+ /* @__PURE__ */ jsx3("path", { d: OROCHIA.tail, stroke: `url(#${id.body})`, strokeWidth: "6", strokeLinecap: "round" }),
168
+ /* @__PURE__ */ jsx3("ellipse", { cx: OROCHIA.head.cx, cy: OROCHIA.head.cy, rx: OROCHIA.head.rx, ry: OROCHIA.head.ry, transform: `rotate(${OROCHIA.head.rotate} ${OROCHIA.head.cx} ${OROCHIA.head.cy})`, fill: `url(#${id.body})` }),
169
+ /* @__PURE__ */ jsx3("path", { d: OROCHIA.tongue.d, stroke: OROCHIA.tongue.color, strokeWidth: "3", strokeLinecap: "round" }),
170
+ /* @__PURE__ */ jsx3("circle", { className: m("orom-pulse"), cx: OROCHIA.eye.cx, cy: OROCHIA.eye.cy, r: OROCHIA.eye.r, fill: OROCHIA.eye.color }),
171
+ /* @__PURE__ */ jsx3("path", { className: m("orom-pulse"), transform: `translate(${OROCHIA.flame.translate[0]} ${OROCHIA.flame.translate[1]}) scale(${OROCHIA.flame.scale})`, d: OROCHIA.flame.d, fill: `url(#${id.flame})` })
164
172
  ] })
165
173
  ] });
166
174
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/marks/shared.ts","../src/marks/KrizakaLogo.tsx","../src/marks/OrazakaLogo.tsx","../src/marks/OrochiaLogo.tsx","../src/marks/ProductLogo.tsx","../src/motion/MotionObserver.tsx","../src/motion/RotatingWord.tsx","../src/cx.ts"],"sourcesContent":["import { useId } from \"react\";\n\nexport interface MarkProps {\n /** Width and height in pixels. */\n size?: number;\n /** Orbit, pulse and shimmer. Off with `false`; always off under prefers-reduced-motion. */\n animated?: boolean;\n /** An accessible name (the mark becomes an image); without it the mark is decorative. */\n title?: string;\n className?: string;\n}\n\n/** A neutral stroke: the host's `--kz-*` token when it has one, else the text colour at a low opacity. */\nexport const neutral = (token: string, percent: number) => `var(${token}, color-mix(in srgb, currentColor ${percent}%, transparent))`;\n\n/** Ids unique per instance, so several marks on a page never share a gradient. */\nexport function useIds<K extends string>(prefix: string, keys: readonly K[]): Record<K, string> {\n const uid = useId().replace(/[^a-zA-Z0-9_-]/g, \"\");\n return Object.fromEntries(keys.map((k) => [k, `${prefix}-${k}-${uid}`])) as Record<K, string>;\n}\n\nexport const a11y = (title?: string) => (title ? { role: \"img\" as const, \"aria-label\": title } : { \"aria-hidden\": true as const });\n","import { a11y, neutral, useIds, type MarkProps } from \"./shared\";\n\nconst CSS = `\n.kzm-spin { transform-origin: 180px 180px; animation: kzm-spin 30s linear infinite; }\n.kzm-pulse { animation: kzm-pulse 4s ease-in-out infinite; }\n@keyframes kzm-spin { to { transform: rotate(360deg); } }\n@keyframes kzm-pulse {\n 0%, 100% { filter: drop-shadow(0 0 8px hsla(217, 92%, 60%, .2)) drop-shadow(0 0 24px hsla(217, 92%, 60%, .06)); }\n 50% { filter: drop-shadow(0 0 12px hsla(217, 92%, 60%, .35)) drop-shadow(0 0 36px hsla(217, 92%, 60%, .12)); }\n}\n@media (prefers-reduced-motion: reduce) { .kzm-spin, .kzm-pulse { animation: none; } }\n`;\n\n/** The Krizaka mark: a hexagonal shield with a neural core, inside slow orbits. Blue accent: `--kz-accent`. */\nexport function KrizakaLogo({ size = 32, animated = true, title, className }: MarkProps) {\n const id = useIds(\"kzm\", [\"blue\", \"steel\", \"core\", \"ambient\"] as const);\n const accent = \"var(--kz-accent, hsl(217, 92%, 60%))\";\n const m = (cls: string) => (animated ? cls : undefined);\n const pulse = (x: number, y: number) => ({ className: m(\"kzm-pulse\"), style: { transformOrigin: `${x}px ${y}px` } });\n return (\n <svg width={size} height={size} viewBox=\"0 0 400 400\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" className={className} {...a11y(title)}>\n <style>{CSS}</style>\n <defs>\n <linearGradient id={id.blue} x1=\"0%\" y1=\"100%\" x2=\"100%\" y2=\"0%\">\n <stop offset=\"0%\" stopColor={accent} />\n <stop offset=\"100%\" stopColor=\"#60A5FA\" />\n </linearGradient>\n <linearGradient id={id.steel} x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"100%\">\n <stop offset=\"0%\" stopColor={neutral(\"--kz-text-secondary\", 64)} />\n <stop offset=\"100%\" stopColor={neutral(\"--kz-text-muted\", 38)} />\n </linearGradient>\n <radialGradient id={id.core} cx=\"50%\" cy=\"50%\" r=\"50%\">\n <stop offset=\"0%\" stopColor=\"#60A5FA\" stopOpacity=\"1\" />\n <stop offset=\"35%\" stopColor={accent} stopOpacity=\"0.7\" />\n <stop offset=\"65%\" stopColor={accent} stopOpacity=\"0.02\" />\n <stop offset=\"100%\" stopColor={accent} stopOpacity=\"0\" />\n </radialGradient>\n <radialGradient id={id.ambient} cx=\"50%\" cy=\"50%\" r=\"50%\">\n <stop offset=\"0%\" stopColor={accent} stopOpacity=\"0.08\" />\n <stop offset=\"100%\" stopColor={accent} stopOpacity=\"0\" />\n </radialGradient>\n </defs>\n <g transform=\"translate(20, 20)\">\n <circle cx=\"180\" cy=\"180\" r=\"170\" fill={`url(#${id.ambient})`} />\n <circle cx=\"180\" cy=\"180\" r=\"160\" stroke={neutral(\"--kz-border-strong\", 16)} strokeWidth=\"1.5\" strokeDasharray=\"8 8\" opacity=\"0.6\" className={m(\"kzm-spin\")} />\n <circle cx=\"180\" cy=\"180\" r=\"130\" stroke={neutral(\"--kz-border-default\", 10)} strokeWidth=\"1\" opacity=\"0.35\" />\n <circle cx=\"180\" cy=\"180\" r=\"100\" stroke={neutral(\"--kz-border-subtle\", 6)} strokeWidth=\"1\" strokeDasharray=\"3 6\" opacity=\"0.3\" />\n <line x1=\"180\" y1=\"20\" x2=\"180\" y2=\"80\" stroke={neutral(\"--kz-border-strong\", 16)} strokeWidth=\"0.5\" opacity=\"0.2\" />\n <line x1=\"320\" y1=\"100\" x2=\"260\" y2=\"140\" stroke={neutral(\"--kz-border-strong\", 16)} strokeWidth=\"0.5\" opacity=\"0.2\" />\n <line x1=\"40\" y1=\"100\" x2=\"100\" y2=\"140\" stroke={neutral(\"--kz-border-strong\", 16)} strokeWidth=\"0.5\" opacity=\"0.2\" />\n <circle cx=\"180\" cy=\"180\" r=\"55\" fill={`url(#${id.core})`} {...pulse(180, 180)} />\n <path d=\"M180,80 L255,120 L255,200 L180,240 L105,200 L105,120 Z\" stroke={`url(#${id.blue})`} strokeWidth=\"3\" strokeLinejoin=\"round\" opacity=\"0.9\" />\n <path d=\"M180,105 L235,133 L235,187 L180,215 L125,187 L125,133 Z\" stroke={`url(#${id.steel})`} strokeWidth=\"2\" strokeLinejoin=\"round\" opacity=\"0.5\" />\n <path d=\"M255,120 L290,85 L310,100\" stroke={`url(#${id.blue})`} strokeWidth=\"5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n <path d=\"M105,120 L70,85 L50,100\" stroke={`url(#${id.steel})`} strokeWidth=\"5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n <path d=\"M180,240 L180,280 L200,295\" stroke={`url(#${id.steel})`} strokeWidth=\"3\" strokeLinecap=\"round\" strokeLinejoin=\"round\" opacity=\"0.5\" />\n <path d=\"M180,280 L160,295\" stroke={`url(#${id.steel})`} strokeWidth=\"3\" strokeLinecap=\"round\" opacity=\"0.5\" />\n <line x1=\"180\" y1=\"130\" x2=\"180\" y2=\"195\" stroke=\"#60A5FA\" strokeWidth=\"1.5\" opacity=\"0.3\" />\n <line x1=\"145\" y1=\"160\" x2=\"215\" y2=\"160\" stroke=\"#60A5FA\" strokeWidth=\"1.5\" opacity=\"0.3\" />\n {[[180, 130], [180, 195], [145, 160], [215, 160]].map(([x, y]) => (\n <circle key={`${x}-${y}`} cx={x} cy={y} r=\"3\" fill=\"#60A5FA\" opacity=\"0.5\" {...pulse(x, y)} />\n ))}\n <circle cx=\"180\" cy=\"160\" r=\"18\" fill=\"#1E40AF\" {...pulse(180, 160)} />\n <circle cx=\"180\" cy=\"160\" r=\"12\" fill=\"#3B82F6\" {...pulse(180, 160)} />\n <circle cx=\"180\" cy=\"160\" r=\"5\" fill=\"#BFDBFE\" {...pulse(180, 160)} />\n <circle cx=\"310\" cy=\"50\" r=\"2.5\" fill=\"#60A5FA\" opacity=\"0.6\" />\n <circle cx=\"50\" cy=\"260\" r=\"2\" fill={neutral(\"--kz-border-strong\", 16)} opacity=\"0.4\" />\n </g>\n </svg>\n );\n}\n","import { a11y, neutral, useIds, type MarkProps } from \"./shared\";\n\nconst CSS = `\n.ozm-orbit { transform-box: view-box; transform-origin: 0 0; animation: ozm-orbit 35s linear infinite; }\n.ozm-core { transform-box: fill-box; transform-origin: center; animation: ozm-core 2.5s ease-in-out infinite; }\n@keyframes ozm-orbit { to { transform: rotate(360deg); } }\n@keyframes ozm-core {\n 0%, 100% { transform: scale(1); opacity: .9; filter: drop-shadow(0 0 3px #f59e0b); }\n 50% { transform: scale(1.15); opacity: 1; filter: drop-shadow(0 0 10px #f59e0b); }\n}\n@media (prefers-reduced-motion: reduce) { .ozm-orbit, .ozm-core { animation: none; } }\n`;\n\n/** The Orazaka mark: three shards orbiting slowly around an amber core that breathes. */\nexport function OrazakaLogo({ size = 28, animated = true, title, className }: MarkProps) {\n const id = useIds(\"ozm\", [\"amber\"] as const);\n return (\n <svg width={size} height={size} viewBox=\"-66 -66 132 132\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" className={className} {...a11y(title)}>\n <style>{CSS}</style>\n <defs>\n <linearGradient id={id.amber} x1=\"0\" y1=\"0\" x2=\"1\" y2=\"1\">\n <stop offset=\"0%\" stopColor=\"#f59e0b\" />\n <stop offset=\"100%\" stopColor=\"#b45309\" />\n </linearGradient>\n </defs>\n <circle r=\"62\" stroke={neutral(\"--kz-border-strong\", 16)} strokeWidth=\"1.5\" strokeDasharray=\"6 6\" opacity=\"0.5\" />\n <circle r=\"48\" stroke={neutral(\"--kz-border-default\", 10)} strokeWidth=\"1\" opacity=\"0.3\" />\n <g className={animated ? \"ozm-orbit\" : undefined}>\n <path d=\"M -24 -41.5 L 0 -55.4 L 24 -41.5 L 24 -24 L 14 -18.2 L 14 -35.7 L 0 -43.8 L -14 -35.7 L -14 -18.2\" stroke={neutral(\"--kz-text-muted\", 45)} strokeWidth=\"3.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n <path d=\"M -48 0 L -38 17.3 L -14 31.2 L 0 23.1 L -10 17.3 L -24 9.2 L -24 -9.2\" stroke={neutral(\"--kz-text-secondary\", 70)} strokeWidth=\"3.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n <path d=\"M 48 0 L 38 17.3 L 14 31.2 L 0 23.1 L 10 17.3 L 24 9.2 L 24 -9.2\" stroke={`url(#${id.amber})`} strokeWidth=\"3.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </g>\n <circle r=\"10\" fill={`url(#${id.amber})`} className={animated ? \"ozm-core\" : undefined} />\n </svg>\n );\n}\n","import { a11y, neutral, useIds, type MarkProps } from \"./shared\";\n\nconst CSS = `\n.orom-spin { transform-origin: 180px 180px; animation: orom-spin 30s linear infinite; }\n.orom-slither { animation: orom-slither 2.4s linear infinite; }\n.orom-pulse { transform-box: view-box; animation: orom-pulse 3.2s ease-in-out infinite; }\n@keyframes orom-spin { to { transform: rotate(360deg); } }\n@keyframes orom-slither { to { stroke-dashoffset: -64; } }\n@keyframes orom-pulse {\n 0%, 100% { filter: drop-shadow(0 0 6px hsla(292, 84%, 61%, .25)); opacity: .9; }\n 50% { filter: drop-shadow(0 0 14px hsla(292, 84%, 61%, .55)); opacity: 1; }\n}\n@media (prefers-reduced-motion: reduce) { .orom-spin, .orom-slither, .orom-pulse { animation: none; } }\n`;\n\n/**\n * The Orochia mark: the serpent (Orochi) coiled into an \"O\" around the flame it guards. The orbit turns, scales slide\n * along the body, the eye and the flame breathe. Below 48 px it crops to the serpent: the orbits would be hairlines.\n */\nexport function OrochiaLogo({ size = 36, animated = true, title, className }: MarkProps) {\n const id = useIds(\"orom\", [\"body\", \"flame\", \"glow\"] as const);\n const m = (cls: string) => (animated ? cls : undefined);\n const arc = \"M259.8,142.8 A88,88 0 1 1 142.8,100.2\";\n return (\n <svg width={size} height={size} viewBox={size < 48 ? \"86 82 228 228\" : \"0 0 400 400\"} fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" className={className} {...a11y(title)}>\n <style>{CSS}</style>\n <defs>\n <linearGradient id={id.body} gradientUnits=\"userSpaceOnUse\" x1=\"70\" y1=\"290\" x2=\"290\" y2=\"70\">\n <stop offset=\"0%\" stopColor=\"#7c3aed\" />\n <stop offset=\"55%\" stopColor=\"#d946ef\" />\n <stop offset=\"100%\" stopColor=\"#f472b6\" />\n </linearGradient>\n <linearGradient id={id.flame} x1=\"50%\" y1=\"100%\" x2=\"50%\" y2=\"0%\">\n <stop offset=\"0%\" stopColor=\"#a855f7\" />\n <stop offset=\"100%\" stopColor=\"#f9a8d4\" />\n </linearGradient>\n <radialGradient id={id.glow} cx=\"50%\" cy=\"50%\" r=\"50%\">\n <stop offset=\"0%\" stopColor=\"#d946ef\" stopOpacity=\"0.18\" />\n <stop offset=\"100%\" stopColor=\"#d946ef\" stopOpacity=\"0\" />\n </radialGradient>\n </defs>\n <g transform=\"translate(20 20)\">\n <circle cx=\"180\" cy=\"180\" r=\"170\" fill={`url(#${id.glow})`} />\n <circle className={m(\"orom-spin\")} cx=\"180\" cy=\"180\" r=\"160\" stroke={neutral(\"--kz-border-strong\", 40)} strokeWidth=\"1.5\" strokeDasharray=\"8 8\" opacity=\".6\" />\n <circle cx=\"180\" cy=\"180\" r=\"134\" stroke={neutral(\"--kz-border-default\", 30)} strokeWidth=\"1\" opacity=\".35\" />\n <path d={arc} stroke={`url(#${id.body})`} strokeWidth=\"22\" strokeLinecap=\"round\" />\n <path className={m(\"orom-slither\")} d={arc} stroke=\"#fdf4ff\" strokeOpacity=\".45\" strokeWidth=\"3\" strokeLinecap=\"round\" strokeDasharray=\"2 14\" />\n <path d=\"M142.8,100.2 A88,88 0 0 1 187.7,92.3\" stroke={`url(#${id.body})`} strokeWidth=\"14\" strokeLinecap=\"round\" />\n <path d=\"M187.7,92.3 A88,88 0 0 1 221.3,102.3\" stroke={`url(#${id.body})`} strokeWidth=\"6\" strokeLinecap=\"round\" />\n <ellipse cx=\"253.9\" cy=\"130.1\" rx=\"13\" ry=\"20\" transform=\"rotate(-25 253.9 130.1)\" fill={`url(#${id.body})`} />\n <path d=\"M245.4,112.0 L242.0,104.8 L235.0,101.5 M242.0,104.8 L244.0,97.3\" stroke=\"#f472b6\" strokeWidth=\"3\" strokeLinecap=\"round\" />\n <circle className={m(\"orom-pulse\")} cx=\"256.3\" cy=\"123.5\" r=\"4.5\" fill=\"#fdf4ff\" />\n <path\n className={m(\"orom-pulse\")}\n transform=\"translate(127 120) scale(4.4)\"\n d=\"M8.5 14.5A2.5 2.5 0 0 0 11 12c0-1.38-.5-2-1-3-1.072-2.143-.224-4.054 2-6 .5 2.5 2 4.9 4 6.5 2 1.6 3 3.5 3 5.5a7 7 0 1 1-14 0c0-1.153.433-2.294 1-3a2.5 2.5 0 0 0 2.5 2.5z\"\n fill={`url(#${id.flame})`}\n />\n </g>\n </svg>\n );\n}\n","import { KrizakaLogo } from \"./KrizakaLogo\";\nimport { OrazakaLogo } from \"./OrazakaLogo\";\nimport { OrochiaLogo } from \"./OrochiaLogo\";\nimport type { MarkProps } from \"./shared\";\n\nexport type BrandId = \"krizaka\" | \"orazaka\" | \"orochia\";\n\n/** The mark of a Krizaka brand by id — for navigation, cards and lists driven by data. */\nexport function ProductLogo({ id, ...props }: MarkProps & { id: BrandId }) {\n if (id === \"krizaka\") return <KrizakaLogo {...props} />;\n if (id === \"orazaka\") return <OrazakaLogo {...props} />;\n return <OrochiaLogo {...props} />;\n}\n","import { useEffect } from \"react\";\n\n/**\n * Mount once at the root of the app. It reveals every `[data-reveal]` element as it enters the viewport — including\n * elements added later, so client-side navigation needs nothing more — and feeds the pointer position to\n * `.kz-spotlight` cards (`--spot-x`, `--spot-y`). One IntersectionObserver, one MutationObserver, one listener.\n * Under prefers-reduced-motion everything is revealed at once.\n */\nexport function MotionObserver(): null {\n useEffect(() => {\n if (window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches) {\n const revealAll = (root: ParentNode) => root.querySelectorAll(\"[data-reveal]\").forEach((el) => el.classList.add(\"kz-in\"));\n revealAll(document);\n const mo = new MutationObserver(() => revealAll(document));\n mo.observe(document.body, { childList: true, subtree: true });\n return () => mo.disconnect();\n }\n const io = new IntersectionObserver(\n (entries) => {\n for (const entry of entries) {\n if (!entry.isIntersecting) continue;\n entry.target.classList.add(\"kz-in\");\n io.unobserve(entry.target);\n }\n },\n { rootMargin: \"0px 0px -8% 0px\", threshold: 0.12 },\n );\n const watch = (root: ParentNode) => root.querySelectorAll(\"[data-reveal]:not(.kz-in)\").forEach((el) => io.observe(el));\n watch(document);\n const mo = new MutationObserver((records) => {\n for (const r of records) r.addedNodes.forEach((n) => n instanceof Element && (n.matches(\"[data-reveal]\") ? io.observe(n) : watch(n)));\n });\n mo.observe(document.body, { childList: true, subtree: true });\n return () => {\n io.disconnect();\n mo.disconnect();\n };\n }, []);\n\n useEffect(() => {\n const move = (e: PointerEvent) => {\n const card = (e.target as Element | null)?.closest?.(\".kz-spotlight\") as HTMLElement | null;\n if (!card) return;\n const box = card.getBoundingClientRect();\n card.style.setProperty(\"--spot-x\", `${e.clientX - box.left}px`);\n card.style.setProperty(\"--spot-y\", `${e.clientY - box.top}px`);\n };\n document.addEventListener(\"pointermove\", move, { passive: true });\n return () => document.removeEventListener(\"pointermove\", move);\n }, []);\n\n return null;\n}\n","import { useEffect, useState } from \"react\";\nimport { cx } from \"../cx\";\n\n/**\n * A word that rolls through alternatives — the Krizaka headline signature. The server render and the first client\n * render show the first word; under prefers-reduced-motion it stays put. Decorative (`aria-hidden`): give the\n * heading a stable accessible label.\n */\nexport function RotatingWord({ words, interval = 2600, className }: { words: readonly string[]; interval?: number; className?: string }) {\n const [i, setI] = useState(0);\n useEffect(() => {\n if (words.length < 2 || window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches) return;\n const timer = setInterval(() => setI((k) => (k + 1) % words.length), interval);\n return () => clearInterval(timer);\n }, [words.length, interval]);\n return (\n <span aria-hidden className=\"kz-rotating\">\n <span key={i} className={cx(\"kz-word\", className)}>\n {words[i]}\n </span>\n </span>\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":["jsx","jsxs","CSS","jsx","jsxs","CSS","jsx","mo","useEffect","jsx","useEffect"]}
1
+ {"version":3,"sources":["../src/marks/shared.ts","../src/marks/KrizakaLogo.tsx","../src/marks/OrazakaLogo.tsx","../src/marks/orochia-geometry.ts","../src/marks/OrochiaLogo.tsx","../src/marks/ProductLogo.tsx","../src/motion/MotionObserver.tsx","../src/motion/RotatingWord.tsx","../src/cx.ts"],"sourcesContent":["import { useId } from \"react\";\n\nexport interface MarkProps {\n /** Width and height in pixels. */\n size?: number;\n /** Orbit, pulse and shimmer. Off with `false`; always off under prefers-reduced-motion. */\n animated?: boolean;\n /** An accessible name (the mark becomes an image); without it the mark is decorative. */\n title?: string;\n className?: string;\n}\n\n/** A neutral stroke: the host's `--kz-*` token when it has one, else the text colour at a low opacity. */\nexport const neutral = (token: string, percent: number) => `var(${token}, color-mix(in srgb, currentColor ${percent}%, transparent))`;\n\n/** Ids unique per instance, so several marks on a page never share a gradient. */\nexport function useIds<K extends string>(prefix: string, keys: readonly K[]): Record<K, string> {\n const uid = useId().replace(/[^a-zA-Z0-9_-]/g, \"\");\n return Object.fromEntries(keys.map((k) => [k, `${prefix}-${k}-${uid}`])) as Record<K, string>;\n}\n\nexport const a11y = (title?: string) => (title ? { role: \"img\" as const, \"aria-label\": title } : { \"aria-hidden\": true as const });\n","import { a11y, neutral, useIds, type MarkProps } from \"./shared\";\n\nconst CSS = `\n.kzm-spin { transform-origin: 180px 180px; animation: kzm-spin 30s linear infinite; }\n.kzm-pulse { animation: kzm-pulse 4s ease-in-out infinite; }\n@keyframes kzm-spin { to { transform: rotate(360deg); } }\n@keyframes kzm-pulse {\n 0%, 100% { filter: drop-shadow(0 0 8px hsla(217, 92%, 60%, .2)) drop-shadow(0 0 24px hsla(217, 92%, 60%, .06)); }\n 50% { filter: drop-shadow(0 0 12px hsla(217, 92%, 60%, .35)) drop-shadow(0 0 36px hsla(217, 92%, 60%, .12)); }\n}\n@media (prefers-reduced-motion: reduce) { .kzm-spin, .kzm-pulse { animation: none; } }\n`;\n\n/** The Krizaka mark: a hexagonal shield with a neural core, inside slow orbits. Blue accent: `--kz-accent`. */\nexport function KrizakaLogo({ size = 32, animated = true, title, className }: MarkProps) {\n const id = useIds(\"kzm\", [\"blue\", \"steel\", \"core\", \"ambient\"] as const);\n const accent = \"var(--kz-accent, hsl(217, 92%, 60%))\";\n const m = (cls: string) => (animated ? cls : undefined);\n const pulse = (x: number, y: number) => ({ className: m(\"kzm-pulse\"), style: { transformOrigin: `${x}px ${y}px` } });\n return (\n <svg width={size} height={size} viewBox=\"0 0 400 400\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" className={className} {...a11y(title)}>\n <style>{CSS}</style>\n <defs>\n <linearGradient id={id.blue} x1=\"0%\" y1=\"100%\" x2=\"100%\" y2=\"0%\">\n <stop offset=\"0%\" stopColor={accent} />\n <stop offset=\"100%\" stopColor=\"#60A5FA\" />\n </linearGradient>\n <linearGradient id={id.steel} x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"100%\">\n <stop offset=\"0%\" stopColor={neutral(\"--kz-text-secondary\", 64)} />\n <stop offset=\"100%\" stopColor={neutral(\"--kz-text-muted\", 38)} />\n </linearGradient>\n <radialGradient id={id.core} cx=\"50%\" cy=\"50%\" r=\"50%\">\n <stop offset=\"0%\" stopColor=\"#60A5FA\" stopOpacity=\"1\" />\n <stop offset=\"35%\" stopColor={accent} stopOpacity=\"0.7\" />\n <stop offset=\"65%\" stopColor={accent} stopOpacity=\"0.02\" />\n <stop offset=\"100%\" stopColor={accent} stopOpacity=\"0\" />\n </radialGradient>\n <radialGradient id={id.ambient} cx=\"50%\" cy=\"50%\" r=\"50%\">\n <stop offset=\"0%\" stopColor={accent} stopOpacity=\"0.08\" />\n <stop offset=\"100%\" stopColor={accent} stopOpacity=\"0\" />\n </radialGradient>\n </defs>\n <g transform=\"translate(20, 20)\">\n <circle cx=\"180\" cy=\"180\" r=\"170\" fill={`url(#${id.ambient})`} />\n <circle cx=\"180\" cy=\"180\" r=\"160\" stroke={neutral(\"--kz-border-strong\", 16)} strokeWidth=\"1.5\" strokeDasharray=\"8 8\" opacity=\"0.6\" className={m(\"kzm-spin\")} />\n <circle cx=\"180\" cy=\"180\" r=\"130\" stroke={neutral(\"--kz-border-default\", 10)} strokeWidth=\"1\" opacity=\"0.35\" />\n <circle cx=\"180\" cy=\"180\" r=\"100\" stroke={neutral(\"--kz-border-subtle\", 6)} strokeWidth=\"1\" strokeDasharray=\"3 6\" opacity=\"0.3\" />\n <line x1=\"180\" y1=\"20\" x2=\"180\" y2=\"80\" stroke={neutral(\"--kz-border-strong\", 16)} strokeWidth=\"0.5\" opacity=\"0.2\" />\n <line x1=\"320\" y1=\"100\" x2=\"260\" y2=\"140\" stroke={neutral(\"--kz-border-strong\", 16)} strokeWidth=\"0.5\" opacity=\"0.2\" />\n <line x1=\"40\" y1=\"100\" x2=\"100\" y2=\"140\" stroke={neutral(\"--kz-border-strong\", 16)} strokeWidth=\"0.5\" opacity=\"0.2\" />\n <circle cx=\"180\" cy=\"180\" r=\"55\" fill={`url(#${id.core})`} {...pulse(180, 180)} />\n <path d=\"M180,80 L255,120 L255,200 L180,240 L105,200 L105,120 Z\" stroke={`url(#${id.blue})`} strokeWidth=\"3\" strokeLinejoin=\"round\" opacity=\"0.9\" />\n <path d=\"M180,105 L235,133 L235,187 L180,215 L125,187 L125,133 Z\" stroke={`url(#${id.steel})`} strokeWidth=\"2\" strokeLinejoin=\"round\" opacity=\"0.5\" />\n <path d=\"M255,120 L290,85 L310,100\" stroke={`url(#${id.blue})`} strokeWidth=\"5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n <path d=\"M105,120 L70,85 L50,100\" stroke={`url(#${id.steel})`} strokeWidth=\"5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n <path d=\"M180,240 L180,280 L200,295\" stroke={`url(#${id.steel})`} strokeWidth=\"3\" strokeLinecap=\"round\" strokeLinejoin=\"round\" opacity=\"0.5\" />\n <path d=\"M180,280 L160,295\" stroke={`url(#${id.steel})`} strokeWidth=\"3\" strokeLinecap=\"round\" opacity=\"0.5\" />\n <line x1=\"180\" y1=\"130\" x2=\"180\" y2=\"195\" stroke=\"#60A5FA\" strokeWidth=\"1.5\" opacity=\"0.3\" />\n <line x1=\"145\" y1=\"160\" x2=\"215\" y2=\"160\" stroke=\"#60A5FA\" strokeWidth=\"1.5\" opacity=\"0.3\" />\n {[[180, 130], [180, 195], [145, 160], [215, 160]].map(([x, y]) => (\n <circle key={`${x}-${y}`} cx={x} cy={y} r=\"3\" fill=\"#60A5FA\" opacity=\"0.5\" {...pulse(x, y)} />\n ))}\n <circle cx=\"180\" cy=\"160\" r=\"18\" fill=\"#1E40AF\" {...pulse(180, 160)} />\n <circle cx=\"180\" cy=\"160\" r=\"12\" fill=\"#3B82F6\" {...pulse(180, 160)} />\n <circle cx=\"180\" cy=\"160\" r=\"5\" fill=\"#BFDBFE\" {...pulse(180, 160)} />\n <circle cx=\"310\" cy=\"50\" r=\"2.5\" fill=\"#60A5FA\" opacity=\"0.6\" />\n <circle cx=\"50\" cy=\"260\" r=\"2\" fill={neutral(\"--kz-border-strong\", 16)} opacity=\"0.4\" />\n </g>\n </svg>\n );\n}\n","import { a11y, neutral, useIds, type MarkProps } from \"./shared\";\n\nconst CSS = `\n.ozm-orbit { transform-box: view-box; transform-origin: 0 0; animation: ozm-orbit 35s linear infinite; }\n.ozm-core { transform-box: fill-box; transform-origin: center; animation: ozm-core 2.5s ease-in-out infinite; }\n@keyframes ozm-orbit { to { transform: rotate(360deg); } }\n@keyframes ozm-core {\n 0%, 100% { transform: scale(1); opacity: .9; filter: drop-shadow(0 0 3px #f59e0b); }\n 50% { transform: scale(1.15); opacity: 1; filter: drop-shadow(0 0 10px #f59e0b); }\n}\n@media (prefers-reduced-motion: reduce) { .ozm-orbit, .ozm-core { animation: none; } }\n`;\n\n/** The Orazaka mark: three shards orbiting slowly around an amber core that breathes. */\nexport function OrazakaLogo({ size = 28, animated = true, title, className }: MarkProps) {\n const id = useIds(\"ozm\", [\"amber\"] as const);\n return (\n <svg width={size} height={size} viewBox=\"-66 -66 132 132\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" className={className} {...a11y(title)}>\n <style>{CSS}</style>\n <defs>\n <linearGradient id={id.amber} x1=\"0\" y1=\"0\" x2=\"1\" y2=\"1\">\n <stop offset=\"0%\" stopColor=\"#f59e0b\" />\n <stop offset=\"100%\" stopColor=\"#b45309\" />\n </linearGradient>\n </defs>\n <circle r=\"62\" stroke={neutral(\"--kz-border-strong\", 16)} strokeWidth=\"1.5\" strokeDasharray=\"6 6\" opacity=\"0.5\" />\n <circle r=\"48\" stroke={neutral(\"--kz-border-default\", 10)} strokeWidth=\"1\" opacity=\"0.3\" />\n <g className={animated ? \"ozm-orbit\" : undefined}>\n <path d=\"M -24 -41.5 L 0 -55.4 L 24 -41.5 L 24 -24 L 14 -18.2 L 14 -35.7 L 0 -43.8 L -14 -35.7 L -14 -18.2\" stroke={neutral(\"--kz-text-muted\", 45)} strokeWidth=\"3.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n <path d=\"M -48 0 L -38 17.3 L -14 31.2 L 0 23.1 L -10 17.3 L -24 9.2 L -24 -9.2\" stroke={neutral(\"--kz-text-secondary\", 70)} strokeWidth=\"3.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n <path d=\"M 48 0 L 38 17.3 L 14 31.2 L 0 23.1 L 10 17.3 L 24 9.2 L 24 -9.2\" stroke={`url(#${id.amber})`} strokeWidth=\"3.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </g>\n <circle r=\"10\" fill={`url(#${id.amber})`} className={animated ? \"ozm-core\" : undefined} />\n </svg>\n );\n}\n","/**\n * The Orochia mark's geometry — the one description of the serpent and its flame, drawn by the web mark (SVG in the\n * DOM, OrochiaLogo) and the native one (react-native-svg, @krizaka/ui/native). Coordinates are in the 360×360 artwork,\n * placed at (20, 20) in a 400×400 view box; below 48 px the view box crops to the serpent.\n */\nexport const OROCHIA = {\n viewBox: \"0 0 400 400\",\n croppedViewBox: \"86 82 228 228\",\n offset: 20,\n body: { x1: 70, y1: 290, x2: 290, y2: 70, stops: [[\"0%\", \"#7c3aed\"], [\"55%\", \"#d946ef\"], [\"100%\", \"#f472b6\"]] },\n flameGradient: { stops: [[\"0%\", \"#a855f7\"], [\"100%\", \"#f9a8d4\"]] },\n glow: { color: \"#d946ef\", opacity: 0.18 },\n orbit: { r: 160, dash: \"8 8\", width: 1.5 },\n ring: { r: 134, width: 1 },\n arc: \"M259.8,142.8 A88,88 0 1 1 142.8,100.2\",\n neck: \"M142.8,100.2 A88,88 0 0 1 187.7,92.3\",\n tail: \"M187.7,92.3 A88,88 0 0 1 221.3,102.3\",\n scales: { color: \"#fdf4ff\", opacity: 0.45, width: 3, dash: \"2 14\" },\n head: { cx: 253.9, cy: 130.1, rx: 13, ry: 20, rotate: -25 },\n tongue: { d: \"M245.4,112.0 L242.0,104.8 L235.0,101.5 M242.0,104.8 L244.0,97.3\", color: \"#f472b6\" },\n eye: { cx: 256.3, cy: 123.5, r: 4.5, color: \"#fdf4ff\" },\n flame: {\n translate: [127, 120] as const,\n scale: 4.4,\n d: \"M8.5 14.5A2.5 2.5 0 0 0 11 12c0-1.38-.5-2-1-3-1.072-2.143-.224-4.054 2-6 .5 2.5 2 4.9 4 6.5 2 1.6 3 3.5 3 5.5a7 7 0 1 1-14 0c0-1.153.433-2.294 1-3a2.5 2.5 0 0 0 2.5 2.5z\",\n },\n} as const;\n","import { a11y, neutral, useIds, type MarkProps } from \"./shared\";\nimport { OROCHIA as G } from \"./orochia-geometry\";\n\nconst CSS = `\n.orom-spin { transform-origin: 180px 180px; animation: orom-spin 30s linear infinite; }\n.orom-slither { animation: orom-slither 2.4s linear infinite; }\n.orom-pulse { transform-box: view-box; animation: orom-pulse 3.2s ease-in-out infinite; }\n@keyframes orom-spin { to { transform: rotate(360deg); } }\n@keyframes orom-slither { to { stroke-dashoffset: -64; } }\n@keyframes orom-pulse {\n 0%, 100% { filter: drop-shadow(0 0 6px hsla(292, 84%, 61%, .25)); opacity: .9; }\n 50% { filter: drop-shadow(0 0 14px hsla(292, 84%, 61%, .55)); opacity: 1; }\n}\n@media (prefers-reduced-motion: reduce) { .orom-spin, .orom-slither, .orom-pulse { animation: none; } }\n`;\n\n/**\n * The Orochia mark: the serpent (Orochi) coiled into an \"O\" around the flame it guards. The orbit turns, scales slide\n * along the body, the eye and the flame breathe. Below 48 px it crops to the serpent: the orbits would be hairlines.\n */\nexport function OrochiaLogo({ size = 36, animated = true, title, className }: MarkProps) {\n const id = useIds(\"orom\", [\"body\", \"flame\", \"glow\"] as const);\n const m = (cls: string) => (animated ? cls : undefined);\n return (\n <svg width={size} height={size} viewBox={size < 48 ? G.croppedViewBox : G.viewBox} fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" className={className} {...a11y(title)}>\n <style>{CSS}</style>\n <defs>\n <linearGradient id={id.body} gradientUnits=\"userSpaceOnUse\" x1={G.body.x1} y1={G.body.y1} x2={G.body.x2} y2={G.body.y2}>\n {G.body.stops.map(([offset, color]) => (\n <stop key={offset} offset={offset} stopColor={color} />\n ))}\n </linearGradient>\n <linearGradient id={id.flame} x1=\"50%\" y1=\"100%\" x2=\"50%\" y2=\"0%\">\n {G.flameGradient.stops.map(([offset, color]) => (\n <stop key={offset} offset={offset} stopColor={color} />\n ))}\n </linearGradient>\n <radialGradient id={id.glow} cx=\"50%\" cy=\"50%\" r=\"50%\">\n <stop offset=\"0%\" stopColor={G.glow.color} stopOpacity={G.glow.opacity} />\n <stop offset=\"100%\" stopColor={G.glow.color} stopOpacity=\"0\" />\n </radialGradient>\n </defs>\n <g transform={`translate(${G.offset} ${G.offset})`}>\n <circle cx=\"180\" cy=\"180\" r=\"170\" fill={`url(#${id.glow})`} />\n <circle className={m(\"orom-spin\")} cx=\"180\" cy=\"180\" r={G.orbit.r} stroke={neutral(\"--kz-border-strong\", 40)} strokeWidth={G.orbit.width} strokeDasharray={G.orbit.dash} opacity=\".6\" />\n <circle cx=\"180\" cy=\"180\" r={G.ring.r} stroke={neutral(\"--kz-border-default\", 30)} strokeWidth={G.ring.width} opacity=\".35\" />\n <path d={G.arc} stroke={`url(#${id.body})`} strokeWidth=\"22\" strokeLinecap=\"round\" />\n <path className={m(\"orom-slither\")} d={G.arc} stroke={G.scales.color} strokeOpacity={G.scales.opacity} strokeWidth={G.scales.width} strokeLinecap=\"round\" strokeDasharray={G.scales.dash} />\n <path d={G.neck} stroke={`url(#${id.body})`} strokeWidth=\"14\" strokeLinecap=\"round\" />\n <path d={G.tail} stroke={`url(#${id.body})`} strokeWidth=\"6\" strokeLinecap=\"round\" />\n <ellipse cx={G.head.cx} cy={G.head.cy} rx={G.head.rx} ry={G.head.ry} transform={`rotate(${G.head.rotate} ${G.head.cx} ${G.head.cy})`} fill={`url(#${id.body})`} />\n <path d={G.tongue.d} stroke={G.tongue.color} strokeWidth=\"3\" strokeLinecap=\"round\" />\n <circle className={m(\"orom-pulse\")} cx={G.eye.cx} cy={G.eye.cy} r={G.eye.r} fill={G.eye.color} />\n <path className={m(\"orom-pulse\")} transform={`translate(${G.flame.translate[0]} ${G.flame.translate[1]}) scale(${G.flame.scale})`} d={G.flame.d} fill={`url(#${id.flame})`} />\n </g>\n </svg>\n );\n}\n","import { KrizakaLogo } from \"./KrizakaLogo\";\nimport { OrazakaLogo } from \"./OrazakaLogo\";\nimport { OrochiaLogo } from \"./OrochiaLogo\";\nimport type { MarkProps } from \"./shared\";\n\nexport type BrandId = \"krizaka\" | \"orazaka\" | \"orochia\";\n\n/** The mark of a Krizaka brand by id — for navigation, cards and lists driven by data. */\nexport function ProductLogo({ id, ...props }: MarkProps & { id: BrandId }) {\n if (id === \"krizaka\") return <KrizakaLogo {...props} />;\n if (id === \"orazaka\") return <OrazakaLogo {...props} />;\n return <OrochiaLogo {...props} />;\n}\n","import { useEffect } from \"react\";\n\n/**\n * Mount once at the root of the app. It reveals every `[data-reveal]` element as it enters the viewport — including\n * elements added later, so client-side navigation needs nothing more — and feeds the pointer position to\n * `.kz-spotlight` cards (`--spot-x`, `--spot-y`). One IntersectionObserver, one MutationObserver, one listener.\n * Under prefers-reduced-motion everything is revealed at once.\n */\nexport function MotionObserver(): null {\n useEffect(() => {\n if (window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches) {\n const revealAll = (root: ParentNode) => root.querySelectorAll(\"[data-reveal]\").forEach((el) => el.classList.add(\"kz-in\"));\n revealAll(document);\n const mo = new MutationObserver(() => revealAll(document));\n mo.observe(document.body, { childList: true, subtree: true });\n return () => mo.disconnect();\n }\n const io = new IntersectionObserver(\n (entries) => {\n for (const entry of entries) {\n if (!entry.isIntersecting) continue;\n entry.target.classList.add(\"kz-in\");\n io.unobserve(entry.target);\n }\n },\n { rootMargin: \"0px 0px -8% 0px\", threshold: 0.12 },\n );\n const watch = (root: ParentNode) => root.querySelectorAll(\"[data-reveal]:not(.kz-in)\").forEach((el) => io.observe(el));\n watch(document);\n const mo = new MutationObserver((records) => {\n for (const r of records) r.addedNodes.forEach((n) => n instanceof Element && (n.matches(\"[data-reveal]\") ? io.observe(n) : watch(n)));\n });\n mo.observe(document.body, { childList: true, subtree: true });\n return () => {\n io.disconnect();\n mo.disconnect();\n };\n }, []);\n\n useEffect(() => {\n const move = (e: PointerEvent) => {\n const card = (e.target as Element | null)?.closest?.(\".kz-spotlight\") as HTMLElement | null;\n if (!card) return;\n const box = card.getBoundingClientRect();\n card.style.setProperty(\"--spot-x\", `${e.clientX - box.left}px`);\n card.style.setProperty(\"--spot-y\", `${e.clientY - box.top}px`);\n };\n document.addEventListener(\"pointermove\", move, { passive: true });\n return () => document.removeEventListener(\"pointermove\", move);\n }, []);\n\n return null;\n}\n","import { useEffect, useState } from \"react\";\nimport { cx } from \"../cx\";\n\n/**\n * A word that rolls through alternatives — the Krizaka headline signature. The server render and the first client\n * render show the first word; under prefers-reduced-motion it stays put. Decorative (`aria-hidden`): give the\n * heading a stable accessible label.\n */\nexport function RotatingWord({ words, interval = 2600, className }: { words: readonly string[]; interval?: number; className?: string }) {\n const [i, setI] = useState(0);\n useEffect(() => {\n if (words.length < 2 || window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches) return;\n const timer = setInterval(() => setI((k) => (k + 1) % words.length), interval);\n return () => clearInterval(timer);\n }, [words.length, interval]);\n return (\n <span aria-hidden className=\"kz-rotating\">\n <span key={i} className={cx(\"kz-word\", className)}>\n {words[i]}\n </span>\n </span>\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":["jsx","jsxs","CSS","jsx","jsxs","CSS","jsx","mo","useEffect","jsx","useEffect"]}
package/dist/motion.css CHANGED
@@ -88,7 +88,7 @@
88
88
  position: absolute;
89
89
  inset: 0;
90
90
  border-radius: inherit;
91
- background: radial-gradient(420px circle at var(--spot-x, 50%) var(--spot-y, 50%), rgba(168, 85, 247, 0.16), transparent 45%);
91
+ background: radial-gradient(420px circle at var(--spot-x, 50%) var(--spot-y, 50%), color-mix(in oklab, var(--kz-accent, #a855f7) 16%, transparent), transparent 45%);
92
92
  opacity: 0;
93
93
  transition: opacity 0.35s var(--kz-ease);
94
94
  pointer-events: none;
@@ -105,7 +105,7 @@
105
105
  @media (hover: hover) {
106
106
  .kz-lift:hover {
107
107
  transform: translateY(-4px);
108
- box-shadow: 0 18px 40px -18px rgba(124, 58, 237, 0.45);
108
+ box-shadow: 0 18px 40px -18px color-mix(in oklab, var(--kz-accent, #7c3aed) 45%, transparent);
109
109
  }
110
110
  }
111
111
 
@@ -0,0 +1,20 @@
1
+ import React from 'react';
2
+
3
+ interface NativeMarkProps {
4
+ /** Width and height in points. */
5
+ size?: number;
6
+ /** The orbit turns and the flame breathes; always still when the system asks to reduce motion. */
7
+ animated?: boolean;
8
+ /** An accessible name (the mark becomes an image); without it the mark is decorative. */
9
+ title?: string;
10
+ /** The neutral strokes (orbit, ring): the host's border colour. */
11
+ neutral?: string;
12
+ }
13
+ /**
14
+ * The Orochia mark for React Native — the same geometry as the web mark (marks/orochia-geometry.ts), drawn with
15
+ * react-native-svg. Three layers so that the motion runs on the native driver: the orbit turns, the eye and the flame
16
+ * breathe, the serpent stays still.
17
+ */
18
+ declare function OrochiaMark({ size, animated, title, neutral }: NativeMarkProps): React.JSX.Element;
19
+
20
+ export { type NativeMarkProps, OrochiaMark };
package/dist/native.js ADDED
@@ -0,0 +1,95 @@
1
+ // src/native/OrochiaMark.tsx
2
+ import { useEffect, useRef } from "react";
3
+ import { AccessibilityInfo, Animated, Easing, View } from "react-native";
4
+ import Svg, { Circle, Defs, Ellipse, G as Group, LinearGradient, Path, RadialGradient, Stop } from "react-native-svg";
5
+
6
+ // src/marks/orochia-geometry.ts
7
+ var OROCHIA = {
8
+ viewBox: "0 0 400 400",
9
+ croppedViewBox: "86 82 228 228",
10
+ offset: 20,
11
+ body: { x1: 70, y1: 290, x2: 290, y2: 70, stops: [["0%", "#7c3aed"], ["55%", "#d946ef"], ["100%", "#f472b6"]] },
12
+ flameGradient: { stops: [["0%", "#a855f7"], ["100%", "#f9a8d4"]] },
13
+ glow: { color: "#d946ef", opacity: 0.18 },
14
+ orbit: { r: 160, dash: "8 8", width: 1.5 },
15
+ ring: { r: 134, width: 1 },
16
+ arc: "M259.8,142.8 A88,88 0 1 1 142.8,100.2",
17
+ neck: "M142.8,100.2 A88,88 0 0 1 187.7,92.3",
18
+ tail: "M187.7,92.3 A88,88 0 0 1 221.3,102.3",
19
+ scales: { color: "#fdf4ff", opacity: 0.45, width: 3, dash: "2 14" },
20
+ head: { cx: 253.9, cy: 130.1, rx: 13, ry: 20, rotate: -25 },
21
+ tongue: { d: "M245.4,112.0 L242.0,104.8 L235.0,101.5 M242.0,104.8 L244.0,97.3", color: "#f472b6" },
22
+ eye: { cx: 256.3, cy: 123.5, r: 4.5, color: "#fdf4ff" },
23
+ flame: {
24
+ translate: [127, 120],
25
+ scale: 4.4,
26
+ d: "M8.5 14.5A2.5 2.5 0 0 0 11 12c0-1.38-.5-2-1-3-1.072-2.143-.224-4.054 2-6 .5 2.5 2 4.9 4 6.5 2 1.6 3 3.5 3 5.5a7 7 0 1 1-14 0c0-1.153.433-2.294 1-3a2.5 2.5 0 0 0 2.5 2.5z"
27
+ }
28
+ };
29
+
30
+ // src/native/OrochiaMark.tsx
31
+ import { jsx, jsxs } from "react/jsx-runtime";
32
+ var CENTER = OROCHIA.offset + 180;
33
+ function OrochiaMark({ size = 48, animated = true, title, neutral = "rgba(255,255,255,0.35)" }) {
34
+ const spin = useRef(new Animated.Value(0)).current;
35
+ const pulse = useRef(new Animated.Value(0)).current;
36
+ useEffect(() => {
37
+ if (!animated) return;
38
+ let loops = [];
39
+ let cancelled = false;
40
+ void AccessibilityInfo.isReduceMotionEnabled().then((reduce) => {
41
+ if (reduce || cancelled) return;
42
+ loops = [
43
+ Animated.loop(Animated.timing(spin, { toValue: 1, duration: 3e4, easing: Easing.linear, useNativeDriver: true })),
44
+ Animated.loop(
45
+ Animated.sequence([
46
+ Animated.timing(pulse, { toValue: 1, duration: 1600, easing: Easing.inOut(Easing.ease), useNativeDriver: true }),
47
+ Animated.timing(pulse, { toValue: 0, duration: 1600, easing: Easing.inOut(Easing.ease), useNativeDriver: true })
48
+ ])
49
+ )
50
+ ];
51
+ loops.forEach((l) => l.start());
52
+ });
53
+ return () => {
54
+ cancelled = true;
55
+ loops.forEach((l) => l.stop());
56
+ };
57
+ }, [animated, spin, pulse]);
58
+ const viewBox = size < 48 ? OROCHIA.croppedViewBox : OROCHIA.viewBox;
59
+ const layer = { position: "absolute", width: size, height: size };
60
+ const a11y = title ? { accessible: true, accessibilityRole: "image", accessibilityLabel: title } : { accessibilityElementsHidden: true, importantForAccessibility: "no-hide-descendants" };
61
+ const bodyGradient = /* @__PURE__ */ jsx(LinearGradient, { id: "body", gradientUnits: "userSpaceOnUse", x1: OROCHIA.body.x1 + OROCHIA.offset, y1: OROCHIA.body.y1 + OROCHIA.offset, x2: OROCHIA.body.x2 + OROCHIA.offset, y2: OROCHIA.body.y2 + OROCHIA.offset, children: OROCHIA.body.stops.map(([offset, color]) => /* @__PURE__ */ jsx(Stop, { offset, stopColor: color }, offset)) });
62
+ return /* @__PURE__ */ jsxs(View, { style: { width: size, height: size }, ...a11y, children: [
63
+ /* @__PURE__ */ jsxs(Svg, { viewBox, style: layer, children: [
64
+ /* @__PURE__ */ jsx(Defs, { children: /* @__PURE__ */ jsxs(RadialGradient, { id: "glow", cx: "50%", cy: "50%", r: "50%", children: [
65
+ /* @__PURE__ */ jsx(Stop, { offset: "0%", stopColor: OROCHIA.glow.color, stopOpacity: OROCHIA.glow.opacity }),
66
+ /* @__PURE__ */ jsx(Stop, { offset: "100%", stopColor: OROCHIA.glow.color, stopOpacity: 0 })
67
+ ] }) }),
68
+ /* @__PURE__ */ jsx(Circle, { cx: CENTER, cy: CENTER, r: 170, fill: "url(#glow)" }),
69
+ /* @__PURE__ */ jsx(Circle, { cx: CENTER, cy: CENTER, r: OROCHIA.ring.r, stroke: neutral, strokeWidth: OROCHIA.ring.width, opacity: 0.35, fill: "none" })
70
+ ] }),
71
+ /* @__PURE__ */ jsx(Animated.View, { style: [layer, { transform: [{ rotate: spin.interpolate({ inputRange: [0, 1], outputRange: ["0deg", "360deg"] }) }] }], children: /* @__PURE__ */ jsx(Svg, { viewBox, style: layer, children: /* @__PURE__ */ jsx(Circle, { cx: CENTER, cy: CENTER, r: OROCHIA.orbit.r, stroke: neutral, strokeWidth: OROCHIA.orbit.width, strokeDasharray: OROCHIA.orbit.dash, opacity: 0.6, fill: "none" }) }) }),
72
+ /* @__PURE__ */ jsxs(Svg, { viewBox, style: layer, children: [
73
+ /* @__PURE__ */ jsx(Defs, { children: bodyGradient }),
74
+ /* @__PURE__ */ jsxs(Group, { transform: `translate(${OROCHIA.offset} ${OROCHIA.offset})`, children: [
75
+ /* @__PURE__ */ jsx(Path, { d: OROCHIA.arc, stroke: "url(#body)", strokeWidth: 22, strokeLinecap: "round", fill: "none" }),
76
+ /* @__PURE__ */ jsx(Path, { d: OROCHIA.arc, stroke: OROCHIA.scales.color, strokeOpacity: OROCHIA.scales.opacity, strokeWidth: OROCHIA.scales.width, strokeLinecap: "round", strokeDasharray: OROCHIA.scales.dash, fill: "none" }),
77
+ /* @__PURE__ */ jsx(Path, { d: OROCHIA.neck, stroke: "url(#body)", strokeWidth: 14, strokeLinecap: "round", fill: "none" }),
78
+ /* @__PURE__ */ jsx(Path, { d: OROCHIA.tail, stroke: "url(#body)", strokeWidth: 6, strokeLinecap: "round", fill: "none" }),
79
+ /* @__PURE__ */ jsx(Ellipse, { cx: OROCHIA.head.cx, cy: OROCHIA.head.cy, rx: OROCHIA.head.rx, ry: OROCHIA.head.ry, rotation: OROCHIA.head.rotate, origin: `${OROCHIA.head.cx}, ${OROCHIA.head.cy}`, fill: "url(#body)" }),
80
+ /* @__PURE__ */ jsx(Path, { d: OROCHIA.tongue.d, stroke: OROCHIA.tongue.color, strokeWidth: 3, strokeLinecap: "round", fill: "none" })
81
+ ] })
82
+ ] }),
83
+ /* @__PURE__ */ jsx(Animated.View, { style: [layer, { opacity: pulse.interpolate({ inputRange: [0, 1], outputRange: [0.85, 1] }) }], children: /* @__PURE__ */ jsxs(Svg, { viewBox, style: layer, children: [
84
+ /* @__PURE__ */ jsx(Defs, { children: /* @__PURE__ */ jsx(LinearGradient, { id: "flame", x1: "50%", y1: "100%", x2: "50%", y2: "0%", children: OROCHIA.flameGradient.stops.map(([offset, color]) => /* @__PURE__ */ jsx(Stop, { offset, stopColor: color }, offset)) }) }),
85
+ /* @__PURE__ */ jsxs(Group, { transform: `translate(${OROCHIA.offset} ${OROCHIA.offset})`, children: [
86
+ /* @__PURE__ */ jsx(Circle, { cx: OROCHIA.eye.cx, cy: OROCHIA.eye.cy, r: OROCHIA.eye.r, fill: OROCHIA.eye.color }),
87
+ /* @__PURE__ */ jsx(Path, { d: OROCHIA.flame.d, transform: `translate(${OROCHIA.flame.translate[0]} ${OROCHIA.flame.translate[1]}) scale(${OROCHIA.flame.scale})`, fill: "url(#flame)" })
88
+ ] })
89
+ ] }) })
90
+ ] });
91
+ }
92
+ export {
93
+ OrochiaMark
94
+ };
95
+ //# sourceMappingURL=native.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/native/OrochiaMark.tsx","../src/marks/orochia-geometry.ts"],"sourcesContent":["import React, { useEffect, useRef } from \"react\";\nimport { AccessibilityInfo, Animated, Easing, View } from \"react-native\";\nimport Svg, { Circle, Defs, Ellipse, G as Group, LinearGradient, Path, RadialGradient, Stop } from \"react-native-svg\";\nimport { OROCHIA as G } from \"../marks/orochia-geometry\";\n\nexport interface NativeMarkProps {\n /** Width and height in points. */\n size?: number;\n /** The orbit turns and the flame breathes; always still when the system asks to reduce motion. */\n animated?: boolean;\n /** An accessible name (the mark becomes an image); without it the mark is decorative. */\n title?: string;\n /** The neutral strokes (orbit, ring): the host's border colour. */\n neutral?: string;\n}\n\nconst CENTER = G.offset + 180;\n\n/**\n * The Orochia mark for React Native — the same geometry as the web mark (marks/orochia-geometry.ts), drawn with\n * react-native-svg. Three layers so that the motion runs on the native driver: the orbit turns, the eye and the flame\n * breathe, the serpent stays still.\n */\nexport function OrochiaMark({ size = 48, animated = true, title, neutral = \"rgba(255,255,255,0.35)\" }: NativeMarkProps) {\n const spin = useRef(new Animated.Value(0)).current;\n const pulse = useRef(new Animated.Value(0)).current;\n useEffect(() => {\n if (!animated) return;\n let loops: Animated.CompositeAnimation[] = [];\n let cancelled = false;\n void AccessibilityInfo.isReduceMotionEnabled().then((reduce) => {\n if (reduce || cancelled) return;\n loops = [\n Animated.loop(Animated.timing(spin, { toValue: 1, duration: 30_000, easing: Easing.linear, useNativeDriver: true })),\n Animated.loop(\n Animated.sequence([\n Animated.timing(pulse, { toValue: 1, duration: 1600, easing: Easing.inOut(Easing.ease), useNativeDriver: true }),\n Animated.timing(pulse, { toValue: 0, duration: 1600, easing: Easing.inOut(Easing.ease), useNativeDriver: true }),\n ]),\n ),\n ];\n loops.forEach((l) => l.start());\n });\n return () => {\n cancelled = true;\n loops.forEach((l) => l.stop());\n };\n }, [animated, spin, pulse]);\n\n const viewBox = size < 48 ? G.croppedViewBox : G.viewBox;\n const layer = { position: \"absolute\" as const, width: size, height: size };\n const a11y = title ? { accessible: true, accessibilityRole: \"image\" as const, accessibilityLabel: title } : { accessibilityElementsHidden: true, importantForAccessibility: \"no-hide-descendants\" as const };\n const bodyGradient = (\n <LinearGradient id=\"body\" gradientUnits=\"userSpaceOnUse\" x1={G.body.x1 + G.offset} y1={G.body.y1 + G.offset} x2={G.body.x2 + G.offset} y2={G.body.y2 + G.offset}>\n {G.body.stops.map(([offset, color]) => (\n <Stop key={offset} offset={offset} stopColor={color} />\n ))}\n </LinearGradient>\n );\n\n return (\n <View style={{ width: size, height: size }} {...a11y}>\n <Svg viewBox={viewBox} style={layer}>\n <Defs>\n <RadialGradient id=\"glow\" cx=\"50%\" cy=\"50%\" r=\"50%\">\n <Stop offset=\"0%\" stopColor={G.glow.color} stopOpacity={G.glow.opacity} />\n <Stop offset=\"100%\" stopColor={G.glow.color} stopOpacity={0} />\n </RadialGradient>\n </Defs>\n <Circle cx={CENTER} cy={CENTER} r={170} fill=\"url(#glow)\" />\n <Circle cx={CENTER} cy={CENTER} r={G.ring.r} stroke={neutral} strokeWidth={G.ring.width} opacity={0.35} fill=\"none\" />\n </Svg>\n <Animated.View style={[layer, { transform: [{ rotate: spin.interpolate({ inputRange: [0, 1], outputRange: [\"0deg\", \"360deg\"] }) }] }]}>\n <Svg viewBox={viewBox} style={layer}>\n <Circle cx={CENTER} cy={CENTER} r={G.orbit.r} stroke={neutral} strokeWidth={G.orbit.width} strokeDasharray={G.orbit.dash} opacity={0.6} fill=\"none\" />\n </Svg>\n </Animated.View>\n <Svg viewBox={viewBox} style={layer}>\n <Defs>{bodyGradient}</Defs>\n <Group transform={`translate(${G.offset} ${G.offset})`}>\n <Path d={G.arc} stroke=\"url(#body)\" strokeWidth={22} strokeLinecap=\"round\" fill=\"none\" />\n <Path d={G.arc} stroke={G.scales.color} strokeOpacity={G.scales.opacity} strokeWidth={G.scales.width} strokeLinecap=\"round\" strokeDasharray={G.scales.dash} fill=\"none\" />\n <Path d={G.neck} stroke=\"url(#body)\" strokeWidth={14} strokeLinecap=\"round\" fill=\"none\" />\n <Path d={G.tail} stroke=\"url(#body)\" strokeWidth={6} strokeLinecap=\"round\" fill=\"none\" />\n <Ellipse cx={G.head.cx} cy={G.head.cy} rx={G.head.rx} ry={G.head.ry} rotation={G.head.rotate} origin={`${G.head.cx}, ${G.head.cy}`} fill=\"url(#body)\" />\n <Path d={G.tongue.d} stroke={G.tongue.color} strokeWidth={3} strokeLinecap=\"round\" fill=\"none\" />\n </Group>\n </Svg>\n <Animated.View style={[layer, { opacity: pulse.interpolate({ inputRange: [0, 1], outputRange: [0.85, 1] }) }]}>\n <Svg viewBox={viewBox} style={layer}>\n <Defs>\n <LinearGradient id=\"flame\" x1=\"50%\" y1=\"100%\" x2=\"50%\" y2=\"0%\">\n {G.flameGradient.stops.map(([offset, color]) => (\n <Stop key={offset} offset={offset} stopColor={color} />\n ))}\n </LinearGradient>\n </Defs>\n <Group transform={`translate(${G.offset} ${G.offset})`}>\n <Circle cx={G.eye.cx} cy={G.eye.cy} r={G.eye.r} fill={G.eye.color} />\n <Path d={G.flame.d} transform={`translate(${G.flame.translate[0]} ${G.flame.translate[1]}) scale(${G.flame.scale})`} fill=\"url(#flame)\" />\n </Group>\n </Svg>\n </Animated.View>\n </View>\n );\n}\n","/**\n * The Orochia mark's geometry — the one description of the serpent and its flame, drawn by the web mark (SVG in the\n * DOM, OrochiaLogo) and the native one (react-native-svg, @krizaka/ui/native). Coordinates are in the 360×360 artwork,\n * placed at (20, 20) in a 400×400 view box; below 48 px the view box crops to the serpent.\n */\nexport const OROCHIA = {\n viewBox: \"0 0 400 400\",\n croppedViewBox: \"86 82 228 228\",\n offset: 20,\n body: { x1: 70, y1: 290, x2: 290, y2: 70, stops: [[\"0%\", \"#7c3aed\"], [\"55%\", \"#d946ef\"], [\"100%\", \"#f472b6\"]] },\n flameGradient: { stops: [[\"0%\", \"#a855f7\"], [\"100%\", \"#f9a8d4\"]] },\n glow: { color: \"#d946ef\", opacity: 0.18 },\n orbit: { r: 160, dash: \"8 8\", width: 1.5 },\n ring: { r: 134, width: 1 },\n arc: \"M259.8,142.8 A88,88 0 1 1 142.8,100.2\",\n neck: \"M142.8,100.2 A88,88 0 0 1 187.7,92.3\",\n tail: \"M187.7,92.3 A88,88 0 0 1 221.3,102.3\",\n scales: { color: \"#fdf4ff\", opacity: 0.45, width: 3, dash: \"2 14\" },\n head: { cx: 253.9, cy: 130.1, rx: 13, ry: 20, rotate: -25 },\n tongue: { d: \"M245.4,112.0 L242.0,104.8 L235.0,101.5 M242.0,104.8 L244.0,97.3\", color: \"#f472b6\" },\n eye: { cx: 256.3, cy: 123.5, r: 4.5, color: \"#fdf4ff\" },\n flame: {\n translate: [127, 120] as const,\n scale: 4.4,\n d: \"M8.5 14.5A2.5 2.5 0 0 0 11 12c0-1.38-.5-2-1-3-1.072-2.143-.224-4.054 2-6 .5 2.5 2 4.9 4 6.5 2 1.6 3 3.5 3 5.5a7 7 0 1 1-14 0c0-1.153.433-2.294 1-3a2.5 2.5 0 0 0 2.5 2.5z\",\n },\n} as const;\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@krizaka/ui",
3
- "version": "1.0.0",
3
+ "version": "1.2.0",
4
4
  "description": "The Krizaka brand layer shared by every product: the animated marks (Krizaka, Orazaka, Orochia) and the Krizaka motion signature, in CSS and React.",
5
5
  "keywords": [
6
6
  "krizaka",
@@ -17,7 +17,8 @@
17
17
  "bugs": "https://github.com/krizaka/krizaka-ui/issues",
18
18
  "repository": {
19
19
  "type": "git",
20
- "url": "git+https://github.com/krizaka/krizaka-ui.git"
20
+ "url": "git+https://github.com/krizaka/krizaka-ui.git",
21
+ "directory": "packages/ui"
21
22
  },
22
23
  "license": "Apache-2.0",
23
24
  "author": "Krizaka (https://www.krizaka.com)",
@@ -31,7 +32,11 @@
31
32
  "import": "./dist/index.js"
32
33
  },
33
34
  "./motion.css": "./dist/motion.css",
34
- "./package.json": "./package.json"
35
+ "./package.json": "./package.json",
36
+ "./native": {
37
+ "types": "./dist/native.d.ts",
38
+ "import": "./dist/native.js"
39
+ }
35
40
  },
36
41
  "files": [
37
42
  "dist",
@@ -41,25 +46,27 @@
41
46
  "sideEffects": [
42
47
  "*.css"
43
48
  ],
44
- "scripts": {
45
- "build": "tsup && node -e \"require('node:fs').copyFileSync('src/motion.css','dist/motion.css')\"",
46
- "typecheck": "tsc --noEmit",
47
- "test": "vitest run",
48
- "check": "npm run typecheck && npm test && npm run build",
49
- "prepublishOnly": "npm run check"
50
- },
51
49
  "peerDependencies": {
52
50
  "react": ">=18",
53
- "react-dom": ">=18"
51
+ "react-dom": ">=18",
52
+ "react-native": ">=0.76",
53
+ "react-native-svg": ">=15"
54
54
  },
55
55
  "devDependencies": {
56
+ "@arethetypeswrong/cli": "^0.18.5",
57
+ "@size-limit/preset-small-lib": "^14.2.0",
56
58
  "@testing-library/dom": "^10.4.0",
57
59
  "@testing-library/react": "^16.3.0",
60
+ "@types/node": "^22.15.0",
58
61
  "@types/react": "^19.2.0",
59
62
  "@types/react-dom": "^19.2.0",
60
63
  "happy-dom": "^20.0.0",
64
+ "publint": "^0.3.25",
61
65
  "react": "^19.2.0",
62
66
  "react-dom": "^19.2.0",
67
+ "react-native": "^0.86.3",
68
+ "react-native-svg": "^15.15.4",
69
+ "size-limit": "^14.2.0",
63
70
  "tsup": "^8.5.1",
64
71
  "typescript": "^5.9.0",
65
72
  "vitest": "^4.1.11"
@@ -69,5 +76,38 @@
69
76
  },
70
77
  "publishConfig": {
71
78
  "access": "public"
79
+ },
80
+ "peerDependenciesMeta": {
81
+ "react-dom": {
82
+ "optional": true
83
+ },
84
+ "react-native": {
85
+ "optional": true
86
+ },
87
+ "react-native-svg": {
88
+ "optional": true
89
+ }
90
+ },
91
+ "size-limit": [
92
+ {
93
+ "name": ".",
94
+ "path": "dist/index.js",
95
+ "limit": "8 kB",
96
+ "gzip": true
97
+ },
98
+ {
99
+ "name": "./native",
100
+ "path": "dist/native.js",
101
+ "limit": "6 kB",
102
+ "gzip": true
103
+ }
104
+ ],
105
+ "scripts": {
106
+ "build": "tsup && node -e \"require('node:fs').copyFileSync('src/motion.css','dist/motion.css')\"",
107
+ "lint": "tsc --noEmit --noUnusedParameters --noFallthroughCasesInSwitch --noImplicitReturns",
108
+ "typecheck": "tsc --noEmit",
109
+ "test": "vitest run",
110
+ "size": "size-limit",
111
+ "publint": "publint && attw --pack . --profile esm-only --exclude-entrypoints ./motion.css"
72
112
  }
73
- }
113
+ }