@krizaka/ui 2.0.0-beta.4 → 2.0.0-beta.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/README.md +3 -1
  2. package/dist/{button-8La7l0V4.d.ts → button-D5aSsmxX.d.ts} +3 -3
  3. package/dist/button.d.ts +3 -3
  4. package/dist/button.js +1 -1
  5. package/dist/button.js.map +1 -1
  6. package/dist/card.js +1 -1
  7. package/dist/card.js.map +1 -1
  8. package/dist/{chunk-ZUD4U22H.js → chunk-6DJ6SQY3.js} +2 -2
  9. package/dist/chunk-6DJ6SQY3.js.map +1 -0
  10. package/dist/{chunk-3X5MVH54.js → chunk-IUGBKMJC.js} +2 -2
  11. package/dist/command.js +2 -2
  12. package/dist/confirm-button.d.ts +1 -1
  13. package/dist/confirm-button.js +1 -1
  14. package/dist/dialog.js +2 -2
  15. package/dist/dropdown-menu.js +1 -1
  16. package/dist/dropdown-menu.js.map +1 -1
  17. package/dist/index.d.ts +9 -2
  18. package/dist/index.js +90 -65
  19. package/dist/index.js.map +1 -1
  20. package/dist/motion.css +52 -2
  21. package/dist/native.d.ts +29 -4
  22. package/dist/native.js +359 -92
  23. package/dist/native.js.map +1 -1
  24. package/dist/section-backdrop.d.ts +75 -0
  25. package/dist/section-backdrop.js +27 -0
  26. package/dist/section-backdrop.js.map +1 -0
  27. package/dist/theme.d.ts +1 -1
  28. package/dist/theme.js +1 -1
  29. package/package.json +18 -4
  30. package/registry/button.json +1 -1
  31. package/registry/card.json +1 -1
  32. package/registry/demos/section-backdrop.d.ts +5 -0
  33. package/registry/demos/section-backdrop.js +14 -0
  34. package/registry/demos/section-backdrop.tsx +10 -0
  35. package/registry/dropdown-menu.json +1 -1
  36. package/registry/index.json +10 -1
  37. package/registry/section-backdrop.json +73 -0
  38. package/dist/chunk-ZUD4U22H.js.map +0 -1
  39. /package/dist/{chunk-3X5MVH54.js.map → chunk-IUGBKMJC.js.map} +0 -0
@@ -0,0 +1,75 @@
1
+ import * as tailwind_variants from 'tailwind-variants';
2
+ import * as React from 'react';
3
+
4
+ declare const sectionBackdropVariants: tailwind_variants.TVReturnType<{
5
+ [key: string]: {
6
+ [key: string]: tailwind_variants.ClassValue | {
7
+ root?: tailwind_variants.ClassValue;
8
+ drift?: tailwind_variants.ClassValue;
9
+ dome?: tailwind_variants.ClassValue;
10
+ grid?: tailwind_variants.ClassValue;
11
+ media?: tailwind_variants.ClassValue;
12
+ };
13
+ };
14
+ } | {
15
+ [x: string]: {
16
+ [x: string]: tailwind_variants.ClassValue | {
17
+ root?: tailwind_variants.ClassValue;
18
+ drift?: tailwind_variants.ClassValue;
19
+ dome?: tailwind_variants.ClassValue;
20
+ grid?: tailwind_variants.ClassValue;
21
+ media?: tailwind_variants.ClassValue;
22
+ };
23
+ };
24
+ } | {}, {
25
+ root: string;
26
+ drift: string;
27
+ dome: string;
28
+ grid: string;
29
+ media: string;
30
+ }, undefined, {
31
+ [key: string]: {
32
+ [key: string]: tailwind_variants.ClassValue | {
33
+ root?: tailwind_variants.ClassValue;
34
+ drift?: tailwind_variants.ClassValue;
35
+ dome?: tailwind_variants.ClassValue;
36
+ grid?: tailwind_variants.ClassValue;
37
+ media?: tailwind_variants.ClassValue;
38
+ };
39
+ };
40
+ } | {}, {
41
+ root: string;
42
+ drift: string;
43
+ dome: string;
44
+ grid: string;
45
+ media: string;
46
+ }, tailwind_variants.TVReturnTypeLike<unknown, {
47
+ root: string;
48
+ drift: string;
49
+ dome: string;
50
+ grid: string;
51
+ media: string;
52
+ }>>;
53
+ interface SectionBackdropProps extends React.HTMLAttributes<HTMLElement> {
54
+ /** The element: `section` (default), `header`, `footer` or `div`. */
55
+ as?: "section" | "header" | "footer" | "div";
56
+ /** Where the brand tint sits: `down` (default) starts tinted and ends on the page surface; `up` ends tinted (a closing call to action). */
57
+ direction?: "down" | "up";
58
+ /** The light dome above the content (the halo of a hero). Default true. */
59
+ dome?: boolean;
60
+ /** A floor of perspective lines under the content. Default false. */
61
+ grid?: boolean;
62
+ /** A foreground illustration or image, blurred for depth of field, behind the content (decorative: hidden from assistive technology). */
63
+ media?: React.ReactNode;
64
+ /** The very slow drift of the light (40 s); always still under prefers-reduced-motion. Default true. */
65
+ animated?: boolean;
66
+ }
67
+ /**
68
+ * A section of a page in the Krizaka visual language: the brand's section gradient (`--kz-brand-gradient-*`, so it
69
+ * follows the brand theme and dark/light), a light dome, an optional perspective grid and a blurred foreground. Every
70
+ * section ends on the page surface, so consecutive sections glide from one tint to the next. Text on it reads at AA
71
+ * (tested in @krizaka/tokens).
72
+ */
73
+ declare function SectionBackdrop({ as: Tag, direction, dome, grid, media, animated, className, children, ...props }: SectionBackdropProps): React.JSX.Element;
74
+
75
+ export { SectionBackdrop, type SectionBackdropProps, sectionBackdropVariants };
@@ -0,0 +1,27 @@
1
+ // src/section-backdrop/section-backdrop.tsx
2
+ import { tv } from "tailwind-variants";
3
+ import { jsx, jsxs } from "react/jsx-runtime";
4
+ var sectionBackdropVariants = tv({
5
+ slots: {
6
+ root: "kz-backdrop",
7
+ drift: "kz-backdrop-drift",
8
+ dome: "kz-backdrop-dome",
9
+ grid: "kz-backdrop-grid",
10
+ media: "kz-backdrop-media"
11
+ }
12
+ });
13
+ function SectionBackdrop({ as: Tag = "section", direction = "down", dome = true, grid = false, media, animated = true, className, children, ...props }) {
14
+ const s = sectionBackdropVariants();
15
+ return /* @__PURE__ */ jsxs(Tag, { className: s.root({ className }), "data-direction": direction, ...props, children: [
16
+ animated ? /* @__PURE__ */ jsx("div", { "data-backdrop-layer": true, "aria-hidden": true, className: s.drift() }) : null,
17
+ dome ? /* @__PURE__ */ jsx("div", { "data-backdrop-layer": true, "aria-hidden": true, className: s.dome() }) : null,
18
+ grid ? /* @__PURE__ */ jsx("div", { "data-backdrop-layer": true, "aria-hidden": true, className: s.grid() }) : null,
19
+ media ? /* @__PURE__ */ jsx("div", { "data-backdrop-layer": true, "aria-hidden": true, className: s.media(), children: media }) : null,
20
+ children
21
+ ] });
22
+ }
23
+ export {
24
+ SectionBackdrop,
25
+ sectionBackdropVariants
26
+ };
27
+ //# sourceMappingURL=section-backdrop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/section-backdrop/section-backdrop.tsx"],"sourcesContent":["// Server-safe. The backdrop of a page section in the brand's visual language (packages/tokens/BRAND.md).\nimport type * as React from \"react\";\nimport { tv } from \"tailwind-variants\";\n\nexport const sectionBackdropVariants = tv({\n slots: {\n root: \"kz-backdrop\",\n drift: \"kz-backdrop-drift\",\n dome: \"kz-backdrop-dome\",\n grid: \"kz-backdrop-grid\",\n media: \"kz-backdrop-media\",\n },\n});\n\nexport interface SectionBackdropProps extends React.HTMLAttributes<HTMLElement> {\n /** The element: `section` (default), `header`, `footer` or `div`. */\n as?: \"section\" | \"header\" | \"footer\" | \"div\";\n /** Where the brand tint sits: `down` (default) starts tinted and ends on the page surface; `up` ends tinted (a closing call to action). */\n direction?: \"down\" | \"up\";\n /** The light dome above the content (the halo of a hero). Default true. */\n dome?: boolean;\n /** A floor of perspective lines under the content. Default false. */\n grid?: boolean;\n /** A foreground illustration or image, blurred for depth of field, behind the content (decorative: hidden from assistive technology). */\n media?: React.ReactNode;\n /** The very slow drift of the light (40 s); always still under prefers-reduced-motion. Default true. */\n animated?: boolean;\n}\n\n/**\n * A section of a page in the Krizaka visual language: the brand's section gradient (`--kz-brand-gradient-*`, so it\n * follows the brand theme and dark/light), a light dome, an optional perspective grid and a blurred foreground. Every\n * section ends on the page surface, so consecutive sections glide from one tint to the next. Text on it reads at AA\n * (tested in @krizaka/tokens).\n */\nexport function SectionBackdrop({ as: Tag = \"section\", direction = \"down\", dome = true, grid = false, media, animated = true, className, children, ...props }: SectionBackdropProps) {\n const s = sectionBackdropVariants();\n return (\n <Tag className={s.root({ className })} data-direction={direction} {...props}>\n {animated ? <div data-backdrop-layer aria-hidden className={s.drift()} /> : null}\n {dome ? <div data-backdrop-layer aria-hidden className={s.dome()} /> : null}\n {grid ? <div data-backdrop-layer aria-hidden className={s.grid()} /> : null}\n {media ? (\n <div data-backdrop-layer aria-hidden className={s.media()}>\n {media}\n </div>\n ) : null}\n {children}\n </Tag>\n );\n}\n"],"mappings":";AAEA,SAAS,UAAU;AAoCf,SACc,KADd;AAlCG,IAAM,0BAA0B,GAAG;AAAA,EACxC,OAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAO;AAAA,IACP,MAAM;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,EACT;AACF,CAAC;AAuBM,SAAS,gBAAgB,EAAE,IAAI,MAAM,WAAW,YAAY,QAAQ,OAAO,MAAM,OAAO,OAAO,OAAO,WAAW,MAAM,WAAW,UAAU,GAAG,MAAM,GAAyB;AACnL,QAAM,IAAI,wBAAwB;AAClC,SACE,qBAAC,OAAI,WAAW,EAAE,KAAK,EAAE,UAAU,CAAC,GAAG,kBAAgB,WAAY,GAAG,OACnE;AAAA,eAAW,oBAAC,SAAI,uBAAmB,MAAC,eAAW,MAAC,WAAW,EAAE,MAAM,GAAG,IAAK;AAAA,IAC3E,OAAO,oBAAC,SAAI,uBAAmB,MAAC,eAAW,MAAC,WAAW,EAAE,KAAK,GAAG,IAAK;AAAA,IACtE,OAAO,oBAAC,SAAI,uBAAmB,MAAC,eAAW,MAAC,WAAW,EAAE,KAAK,GAAG,IAAK;AAAA,IACtE,QACC,oBAAC,SAAI,uBAAmB,MAAC,eAAW,MAAC,WAAW,EAAE,MAAM,GACrD,iBACH,IACE;AAAA,IACH;AAAA,KACH;AAEJ;","names":[]}
package/dist/theme.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import { a as ButtonVariants } from './button-8La7l0V4.js';
2
+ import { a as ButtonVariants } from './button-D5aSsmxX.js';
3
3
  import 'tailwind-variants';
4
4
 
5
5
  type Mode = "dark" | "light" | "system";
package/dist/theme.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import {
3
3
  buttonVariants
4
- } from "./chunk-ZUD4U22H.js";
4
+ } from "./chunk-6DJ6SQY3.js";
5
5
 
6
6
  // src/theme/theme.tsx
7
7
  import * as React from "react";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@krizaka/ui",
3
- "version": "2.0.0-beta.4",
3
+ "version": "2.0.0-beta.5",
4
4
  "description": "The Krizaka front-end platform's components: the primitives (button, card, dialog, toast, menu, field, tabs, chip, switch, slider, command palette, theme, countdown…) on the semantic --kz-* tokens, the animated marks (Krizaka, Orazaka, Orochia) and the motion signature — web and /native.",
5
5
  "keywords": [
6
6
  "krizaka",
@@ -162,6 +162,10 @@
162
162
  "types": "./dist/progress.d.ts",
163
163
  "import": "./dist/progress.js"
164
164
  },
165
+ "./section-backdrop": {
166
+ "types": "./dist/section-backdrop.d.ts",
167
+ "import": "./dist/section-backdrop.js"
168
+ },
165
169
  "./motion.css": "./dist/motion.css",
166
170
  "./tailwind.css": "./tailwind.css",
167
171
  "./native": {
@@ -190,7 +194,7 @@
190
194
  "*.css"
191
195
  ],
192
196
  "peerDependencies": {
193
- "@krizaka/tailwind": ">=2.0.0-beta.4",
197
+ "@krizaka/tailwind": ">=2.0.0-beta.5",
194
198
  "react": ">=18",
195
199
  "react-dom": ">=18",
196
200
  "react-native": ">=0.76",
@@ -234,7 +238,7 @@
234
238
  "typescript": "^5.9.0",
235
239
  "vitest": "^4.1.11",
236
240
  "@krizaka/config": "0.1.0",
237
- "@krizaka/tokens": "2.0.0-beta.4"
241
+ "@krizaka/tokens": "2.0.0-beta.5"
238
242
  },
239
243
  "engines": {
240
244
  "node": ">=20"
@@ -269,7 +273,7 @@
269
273
  {
270
274
  "name": "./native (bundled into the app by Metro, never downloaded: a regression guard, not a budget)",
271
275
  "path": "dist/native.js",
272
- "limit": "10.5 kB",
276
+ "limit": "11.5 kB",
273
277
  "gzip": true
274
278
  },
275
279
  {
@@ -488,6 +492,16 @@
488
492
  "clsx"
489
493
  ]
490
494
  },
495
+ {
496
+ "name": "./section-backdrop",
497
+ "path": "dist/section-backdrop.js",
498
+ "limit": "1 kB",
499
+ "gzip": true,
500
+ "ignore": [
501
+ "tailwind-variants",
502
+ "clsx"
503
+ ]
504
+ },
491
505
  {
492
506
  "name": "./tabs",
493
507
  "path": "dist/tabs.js",
@@ -5,7 +5,7 @@
5
5
  "files": [
6
6
  {
7
7
  "path": "button/button.tsx",
8
- "content": "// Server-safe: no hook, no context. `buttonVariants` styles a <Link> or a Server Component without the component.\nimport { Slot } from \"radix-ui\";\nimport type * as React from \"react\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nexport const buttonVariants = tv({\n base:\n \"inline-flex shrink-0 select-none items-center justify-center gap-2 whitespace-nowrap font-semibold transition-all \" +\n \"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-surface-0 \" +\n \"disabled:pointer-events-none disabled:opacity-40 data-loading:cursor-progress active:scale-[0.98]\",\n variants: {\n variant: {\n primary: \"bg-accent text-on-accent shadow-sm hover:bg-accent-hover\",\n secondary: \"border border-border-default bg-surface-2 text-fg hover:border-border-strong hover:bg-surface-3\",\n outline: \"border border-border-default bg-transparent text-fg hover:border-accent hover:text-accent\",\n ghost: \"text-fg-secondary hover:bg-surface-2 hover:text-fg\",\n // The danger token is invariant and too light for small text on a light surface (3.6:1): the label stays a\n // text role, the border and the tint carry the danger.\n danger: \"border border-danger/50 bg-danger/10 text-fg hover:border-danger hover:bg-danger/20\",\n },\n size: { sm: \"h-8 px-3 text-xs\", md: \"h-10 px-4 text-sm\", lg: \"h-12 px-6 text-sm\", icon: \"h-10 w-10\" },\n shape: { rounded: \"rounded-lg\", pill: \"rounded-full\" },\n },\n defaultVariants: { variant: \"secondary\", size: \"md\", shape: \"rounded\" },\n});\n\nexport type ButtonVariants = VariantProps<typeof buttonVariants>;\n\nexport type ButtonProps = React.ComponentProps<\"button\"> &\n ButtonVariants & {\n /**\n * The look: `primary` (the accent), `secondary` (a raised surface), `outline`, `ghost`, `danger`.\n * @default \"secondary\"\n */\n variant?: ButtonVariants[\"variant\"];\n /**\n * sm · md · lg, or `icon` (a square).\n * @default \"md\"\n */\n size?: ButtonVariants[\"size\"];\n /**\n * rounded · pill.\n * @default \"rounded\"\n */\n shape?: ButtonVariants[\"shape\"];\n /** Renders the child (e.g. a <Link>) instead of the <button>, with props, classes and ref merged. */\n asChild?: boolean;\n /** Disables and signals the wait (aria-busy, data-loading) — the product adds a spinner if it wants one. */\n loading?: boolean;\n };\n\nexport function Button({ asChild, loading, variant, size, shape, className, disabled, ...props }: ButtonProps) {\n const Comp = asChild ? Slot.Root : \"button\";\n return (\n <Comp\n type={asChild ? undefined : \"button\"}\n aria-busy={loading || undefined}\n data-loading={loading ? \"\" : undefined}\n data-variant={variant ?? \"secondary\"}\n disabled={asChild ? undefined : disabled || loading}\n aria-disabled={asChild && (disabled || loading) ? true : undefined}\n className={buttonVariants({ variant, size, shape, className })}\n {...props}\n />\n );\n}\n\nexport type IconButtonProps = Omit<ButtonProps, \"size\"> & {\n /** The accessible name (and tooltip) of the button — required, passed translated. */\n label: string;\n /**\n * sm · md · lg, or `icon` (a square).\n * @default \"icon\"\n */\n size?: ButtonProps[\"size\"];\n};\n\n/** An icon-only button: `label` is required, it is its accessible name. */\nexport function IconButton({ label, size = \"icon\", ...props }: IconButtonProps) {\n return <Button aria-label={label} title={label} size={size} {...props} />;\n}\n"
8
+ "content": "// Server-safe: no hook, no context. `buttonVariants` styles a <Link> or a Server Component without the component.\nimport { Slot } from \"radix-ui\";\nimport type * as React from \"react\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nexport const buttonVariants = tv({\n base:\n \"inline-flex shrink-0 select-none items-center justify-center gap-2 whitespace-nowrap font-semibold transition-all \" +\n \"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-surface-0 \" +\n \"disabled:pointer-events-none disabled:opacity-40 data-loading:cursor-progress active:scale-[0.98]\",\n variants: {\n variant: {\n primary: \"bg-accent text-on-accent shadow-sm hover:bg-accent-hover\",\n secondary: \"border border-border-default bg-surface-2 text-fg hover:border-border-strong hover:bg-surface-3\",\n outline: \"border border-border-default bg-transparent text-fg hover:border-accent hover:text-fg-accent\",\n ghost: \"text-fg-secondary hover:bg-surface-2 hover:text-fg\",\n // The danger token is invariant and too light for small text on a light surface (3.6:1): the label stays a\n // text role, the border and the tint carry the danger.\n danger: \"border border-danger/50 bg-danger/10 text-fg hover:border-danger hover:bg-danger/20\",\n },\n size: { sm: \"h-8 px-3 text-xs\", md: \"h-10 px-4 text-sm\", lg: \"h-12 px-6 text-sm\", icon: \"h-10 w-10\" },\n shape: { rounded: \"rounded-lg\", pill: \"rounded-full\" },\n },\n defaultVariants: { variant: \"secondary\", size: \"md\", shape: \"rounded\" },\n});\n\nexport type ButtonVariants = VariantProps<typeof buttonVariants>;\n\nexport type ButtonProps = React.ComponentProps<\"button\"> &\n ButtonVariants & {\n /**\n * The look: `primary` (the accent), `secondary` (a raised surface), `outline`, `ghost`, `danger`.\n * @default \"secondary\"\n */\n variant?: ButtonVariants[\"variant\"];\n /**\n * sm · md · lg, or `icon` (a square).\n * @default \"md\"\n */\n size?: ButtonVariants[\"size\"];\n /**\n * rounded · pill.\n * @default \"rounded\"\n */\n shape?: ButtonVariants[\"shape\"];\n /** Renders the child (e.g. a <Link>) instead of the <button>, with props, classes and ref merged. */\n asChild?: boolean;\n /** Disables and signals the wait (aria-busy, data-loading) — the product adds a spinner if it wants one. */\n loading?: boolean;\n };\n\nexport function Button({ asChild, loading, variant, size, shape, className, disabled, ...props }: ButtonProps) {\n const Comp = asChild ? Slot.Root : \"button\";\n return (\n <Comp\n type={asChild ? undefined : \"button\"}\n aria-busy={loading || undefined}\n data-loading={loading ? \"\" : undefined}\n data-variant={variant ?? \"secondary\"}\n disabled={asChild ? undefined : disabled || loading}\n aria-disabled={asChild && (disabled || loading) ? true : undefined}\n className={buttonVariants({ variant, size, shape, className })}\n {...props}\n />\n );\n}\n\nexport type IconButtonProps = Omit<ButtonProps, \"size\"> & {\n /** The accessible name (and tooltip) of the button — required, passed translated. */\n label: string;\n /**\n * sm · md · lg, or `icon` (a square).\n * @default \"icon\"\n */\n size?: ButtonProps[\"size\"];\n};\n\n/** An icon-only button: `label` is required, it is its accessible name. */\nexport function IconButton({ label, size = \"icon\", ...props }: IconButtonProps) {\n return <Button aria-label={label} title={label} size={size} {...props} />;\n}\n"
9
9
  },
10
10
  {
11
11
  "path": "button/index.ts",
@@ -5,7 +5,7 @@
5
5
  "files": [
6
6
  {
7
7
  "path": "card/card.tsx",
8
- "content": "// Server-safe: no hook, no context. One `tv` definition with slots: each part takes its slot, and a product overrides\n// any part through `className` (merged last by tailwind-merge).\nimport { Slot } from \"radix-ui\";\nimport type * as React from \"react\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nimport { cn } from \"../cn\";\n\nexport const card = tv({\n slots: {\n root:\n \"group relative flex flex-col overflow-hidden border border-border-default bg-surface-1 text-fg transition-colors \" +\n \"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring\",\n media: \"relative overflow-hidden bg-media\",\n image: \"h-full w-full object-cover transition-transform duration-500 motion-safe:group-hover:scale-105\",\n fallback: \"flex h-full w-full items-center justify-center bg-linear-to-br from-accent/15 via-media to-accent-2/15 text-accent/60\",\n overlay: \"absolute z-10 flex items-center gap-1.5\",\n body: \"relative flex flex-1 flex-col gap-3\",\n title: \"line-clamp-1 text-sm font-semibold text-fg transition-colors group-hover:text-accent\",\n description: \"line-clamp-2 text-xs text-fg-secondary\",\n stat: \"min-w-0\",\n statLabel: \"text-[10px] font-semibold uppercase tracking-wider text-fg-secondary\",\n statValue: \"font-display text-xl font-black tabular-nums text-fg\",\n footer: \"relative mt-auto flex items-center gap-2 border-t border-border-subtle pt-3 text-xs text-fg-secondary\",\n },\n variants: {\n radius: { md: { root: \"rounded-md\" }, lg: { root: \"rounded-lg\" }, xl: { root: \"rounded-xl\" } },\n tone: { default: {}, elevated: { root: \"bg-surface-2 shadow-md\" }, glass: { root: \"bg-surface-1/70 backdrop-blur-md\" } },\n interactive: { true: { root: \"kz-spotlight kz-lift hover:border-accent/50\" } },\n padding: { none: { body: \"p-0\" }, sm: { body: \"p-3\" }, md: { body: \"p-4\" }, lg: { body: \"p-6\" } },\n },\n defaultVariants: { radius: \"xl\", tone: \"default\", padding: \"md\" },\n});\n\ntype CardVariants = VariantProps<typeof card>;\n/** The parts without a variant read the default slots: no context, so server-safe. */\nconst slots = card();\n\nexport type CardRootProps = React.ComponentProps<\"div\"> &\n Pick<CardVariants, \"radius\" | \"tone\" | \"interactive\"> & {\n /**\n * md · lg · xl.\n * @default \"xl\"\n */\n radius?: CardVariants[\"radius\"];\n /**\n * default (the base surface) · elevated (raised, a shadow) · glass (translucent, blurred).\n * @default \"default\"\n */\n tone?: CardVariants[\"tone\"];\n /** The spotlight that follows the pointer and the lift on hover: for a card that is a link. */\n interactive?: CardVariants[\"interactive\"];\n /** Renders the child (a link, an article) instead of the <div>, with props, classes and ref merged. */\n asChild?: boolean;\n /** Enters on scroll (MotionObserver): the index in the grid becomes the delay (50 ms a step, 8 steps at most). */\n reveal?: number;\n };\n\nexport function CardRoot({ asChild, reveal, radius, tone, interactive, className, style, ...props }: CardRootProps) {\n const Comp = asChild ? Slot.Root : \"div\";\n const revealStyle =\n reveal === undefined ? style : ({ ...style, \"--kz-delay\": `${Math.min(Math.max(reveal, 0), 8) * 50}ms` } as React.CSSProperties);\n return (\n <Comp\n data-reveal={reveal === undefined ? undefined : \"\"}\n data-interactive={interactive ? \"\" : undefined}\n style={revealStyle}\n className={card({ radius, tone, interactive }).root({ className })}\n {...props}\n />\n );\n}\n\nconst ASPECT = { video: \"aspect-video\", square: \"aspect-square\", portrait: \"aspect-[3/4]\", auto: \"\" } as const;\nexport type CardMediaProps = React.ComponentProps<\"div\"> & {\n /** The ratio of the media: video (16:9) · square · portrait (3:4) · auto (the content's). */\n aspect?: keyof typeof ASPECT;\n};\n\nexport function CardMedia({ aspect = \"video\", className, ...props }: CardMediaProps) {\n return <div data-aspect={aspect} className={slots.media({ className: cn(ASPECT[aspect], className) })} {...props} />;\n}\n\nexport type CardImageProps = Omit<React.ComponentProps<\"img\">, \"src\"> & {\n /** The image's URL; `null` or nothing shows the `fallback`. */\n src?: string | null;\n /** Shown when there is no image: an icon, an illustration (decorative). */\n fallback?: React.ReactNode;\n};\n\n/** The image of a media, or its `fallback` when there is none. `alt` is empty by default: the title names the card. */\nexport function CardImage({ src, alt = \"\", fallback, className, ...props }: CardImageProps) {\n if (!src) {\n return (\n <div data-fallback=\"\" aria-hidden className={slots.fallback({ className })}>\n {fallback}\n </div>\n );\n }\n return <img src={src} alt={alt} loading=\"lazy\" decoding=\"async\" className={slots.image({ className })} {...props} />;\n}\n\nconst CORNER = {\n \"top-left\": \"left-2.5 top-2.5\",\n \"top-right\": \"right-2.5 top-2.5\",\n \"bottom-left\": \"bottom-2.5 left-2.5\",\n \"bottom-right\": \"bottom-2.5 right-2.5\",\n} as const;\nexport type CardOverlayProps = React.ComponentProps<\"div\"> & {\n /** The corner of the media it sits in. */\n corner?: keyof typeof CORNER;\n};\n\n/** What sits on the media (badges, a caption). `scrim` and `fg-on-media` are invariant: nothing to do for light. */\nexport function CardOverlay({ corner = \"top-left\", className, ...props }: CardOverlayProps) {\n return <div data-corner={corner} className={slots.overlay({ className: cn(CORNER[corner], className) })} {...props} />;\n}\n\nexport type CardBodyProps = React.ComponentProps<\"div\"> & {\n /**\n * none · sm · md · lg.\n * @default \"md\"\n */\n padding?: CardVariants[\"padding\"];\n};\n\nexport function CardBody({ padding, className, ...props }: CardBodyProps) {\n return <div className={card({ padding }).body({ className })} {...props} />;\n}\n\nexport type CardTitleProps = React.ComponentProps<\"h3\"> & {\n /** The heading level, to fit the page's outline. */\n as?: \"h2\" | \"h3\" | \"h4\";\n};\n\nexport function CardTitle({ as: Tag = \"h3\", className, ...props }: CardTitleProps) {\n return <Tag className={slots.title({ className })} {...props} />;\n}\n\nexport function CardDescription({ className, ...props }: React.ComponentProps<\"p\">) {\n return <p className={slots.description({ className })} {...props} />;\n}\n\nexport type CardStatProps = React.ComponentProps<\"div\"> & {\n /** What the figure is, in small capitals above it (the figure is the children). */\n label: React.ReactNode;\n};\n\n/** A figure put forward: the label in capitals, the value in tabular digits. */\nexport function CardStat({ label, className, children, ...props }: CardStatProps) {\n return (\n <div className={slots.stat({ className })} {...props}>\n <p className={slots.statLabel()}>{label}</p>\n <p className={slots.statValue()}>{children}</p>\n </div>\n );\n}\n\nexport function CardFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return <div className={slots.footer({ className })} {...props} />;\n}\n\n/** `Card.Root/Media/Image/Overlay/Body/Title/Description/Stat/Footer`. */\nexport const Card = {\n Root: CardRoot,\n Media: CardMedia,\n Image: CardImage,\n Overlay: CardOverlay,\n Body: CardBody,\n Title: CardTitle,\n Description: CardDescription,\n Stat: CardStat,\n Footer: CardFooter,\n};\n"
8
+ "content": "// Server-safe: no hook, no context. One `tv` definition with slots: each part takes its slot, and a product overrides\n// any part through `className` (merged last by tailwind-merge).\nimport { Slot } from \"radix-ui\";\nimport type * as React from \"react\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nimport { cn } from \"../cn\";\n\nexport const card = tv({\n slots: {\n root:\n \"group relative flex flex-col overflow-hidden border border-border-default bg-surface-1 text-fg transition-colors \" +\n \"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring\",\n media: \"relative overflow-hidden bg-media\",\n image: \"h-full w-full object-cover transition-transform duration-500 motion-safe:group-hover:scale-105\",\n fallback: \"flex h-full w-full items-center justify-center bg-linear-to-br from-accent/15 via-media to-accent-2/15 text-accent/60\",\n overlay: \"absolute z-10 flex items-center gap-1.5\",\n body: \"relative flex flex-1 flex-col gap-3\",\n title: \"line-clamp-1 text-sm font-semibold text-fg transition-colors group-hover:text-fg-accent\",\n description: \"line-clamp-2 text-xs text-fg-secondary\",\n stat: \"min-w-0\",\n statLabel: \"text-[10px] font-semibold uppercase tracking-wider text-fg-secondary\",\n statValue: \"font-display text-xl font-black tabular-nums text-fg\",\n footer: \"relative mt-auto flex items-center gap-2 border-t border-border-subtle pt-3 text-xs text-fg-secondary\",\n },\n variants: {\n radius: { md: { root: \"rounded-md\" }, lg: { root: \"rounded-lg\" }, xl: { root: \"rounded-xl\" } },\n tone: { default: {}, elevated: { root: \"bg-surface-2 shadow-md\" }, glass: { root: \"bg-surface-1/70 backdrop-blur-md\" } },\n interactive: { true: { root: \"kz-spotlight kz-lift hover:border-accent/50\" } },\n padding: { none: { body: \"p-0\" }, sm: { body: \"p-3\" }, md: { body: \"p-4\" }, lg: { body: \"p-6\" } },\n },\n defaultVariants: { radius: \"xl\", tone: \"default\", padding: \"md\" },\n});\n\ntype CardVariants = VariantProps<typeof card>;\n/** The parts without a variant read the default slots: no context, so server-safe. */\nconst slots = card();\n\nexport type CardRootProps = React.ComponentProps<\"div\"> &\n Pick<CardVariants, \"radius\" | \"tone\" | \"interactive\"> & {\n /**\n * md · lg · xl.\n * @default \"xl\"\n */\n radius?: CardVariants[\"radius\"];\n /**\n * default (the base surface) · elevated (raised, a shadow) · glass (translucent, blurred).\n * @default \"default\"\n */\n tone?: CardVariants[\"tone\"];\n /** The spotlight that follows the pointer and the lift on hover: for a card that is a link. */\n interactive?: CardVariants[\"interactive\"];\n /** Renders the child (a link, an article) instead of the <div>, with props, classes and ref merged. */\n asChild?: boolean;\n /** Enters on scroll (MotionObserver): the index in the grid becomes the delay (50 ms a step, 8 steps at most). */\n reveal?: number;\n };\n\nexport function CardRoot({ asChild, reveal, radius, tone, interactive, className, style, ...props }: CardRootProps) {\n const Comp = asChild ? Slot.Root : \"div\";\n const revealStyle =\n reveal === undefined ? style : ({ ...style, \"--kz-delay\": `${Math.min(Math.max(reveal, 0), 8) * 50}ms` } as React.CSSProperties);\n return (\n <Comp\n data-reveal={reveal === undefined ? undefined : \"\"}\n data-interactive={interactive ? \"\" : undefined}\n style={revealStyle}\n className={card({ radius, tone, interactive }).root({ className })}\n {...props}\n />\n );\n}\n\nconst ASPECT = { video: \"aspect-video\", square: \"aspect-square\", portrait: \"aspect-[3/4]\", auto: \"\" } as const;\nexport type CardMediaProps = React.ComponentProps<\"div\"> & {\n /** The ratio of the media: video (16:9) · square · portrait (3:4) · auto (the content's). */\n aspect?: keyof typeof ASPECT;\n};\n\nexport function CardMedia({ aspect = \"video\", className, ...props }: CardMediaProps) {\n return <div data-aspect={aspect} className={slots.media({ className: cn(ASPECT[aspect], className) })} {...props} />;\n}\n\nexport type CardImageProps = Omit<React.ComponentProps<\"img\">, \"src\"> & {\n /** The image's URL; `null` or nothing shows the `fallback`. */\n src?: string | null;\n /** Shown when there is no image: an icon, an illustration (decorative). */\n fallback?: React.ReactNode;\n};\n\n/** The image of a media, or its `fallback` when there is none. `alt` is empty by default: the title names the card. */\nexport function CardImage({ src, alt = \"\", fallback, className, ...props }: CardImageProps) {\n if (!src) {\n return (\n <div data-fallback=\"\" aria-hidden className={slots.fallback({ className })}>\n {fallback}\n </div>\n );\n }\n return <img src={src} alt={alt} loading=\"lazy\" decoding=\"async\" className={slots.image({ className })} {...props} />;\n}\n\nconst CORNER = {\n \"top-left\": \"left-2.5 top-2.5\",\n \"top-right\": \"right-2.5 top-2.5\",\n \"bottom-left\": \"bottom-2.5 left-2.5\",\n \"bottom-right\": \"bottom-2.5 right-2.5\",\n} as const;\nexport type CardOverlayProps = React.ComponentProps<\"div\"> & {\n /** The corner of the media it sits in. */\n corner?: keyof typeof CORNER;\n};\n\n/** What sits on the media (badges, a caption). `scrim` and `fg-on-media` are invariant: nothing to do for light. */\nexport function CardOverlay({ corner = \"top-left\", className, ...props }: CardOverlayProps) {\n return <div data-corner={corner} className={slots.overlay({ className: cn(CORNER[corner], className) })} {...props} />;\n}\n\nexport type CardBodyProps = React.ComponentProps<\"div\"> & {\n /**\n * none · sm · md · lg.\n * @default \"md\"\n */\n padding?: CardVariants[\"padding\"];\n};\n\nexport function CardBody({ padding, className, ...props }: CardBodyProps) {\n return <div className={card({ padding }).body({ className })} {...props} />;\n}\n\nexport type CardTitleProps = React.ComponentProps<\"h3\"> & {\n /** The heading level, to fit the page's outline. */\n as?: \"h2\" | \"h3\" | \"h4\";\n};\n\nexport function CardTitle({ as: Tag = \"h3\", className, ...props }: CardTitleProps) {\n return <Tag className={slots.title({ className })} {...props} />;\n}\n\nexport function CardDescription({ className, ...props }: React.ComponentProps<\"p\">) {\n return <p className={slots.description({ className })} {...props} />;\n}\n\nexport type CardStatProps = React.ComponentProps<\"div\"> & {\n /** What the figure is, in small capitals above it (the figure is the children). */\n label: React.ReactNode;\n};\n\n/** A figure put forward: the label in capitals, the value in tabular digits. */\nexport function CardStat({ label, className, children, ...props }: CardStatProps) {\n return (\n <div className={slots.stat({ className })} {...props}>\n <p className={slots.statLabel()}>{label}</p>\n <p className={slots.statValue()}>{children}</p>\n </div>\n );\n}\n\nexport function CardFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return <div className={slots.footer({ className })} {...props} />;\n}\n\n/** `Card.Root/Media/Image/Overlay/Body/Title/Description/Stat/Footer`. */\nexport const Card = {\n Root: CardRoot,\n Media: CardMedia,\n Image: CardImage,\n Overlay: CardOverlay,\n Body: CardBody,\n Title: CardTitle,\n Description: CardDescription,\n Stat: CardStat,\n Footer: CardFooter,\n};\n"
9
9
  },
10
10
  {
11
11
  "path": "card/index.ts",
@@ -0,0 +1,5 @@
1
+ import * as react from 'react';
2
+
3
+ declare function SectionBackdropDemo(): react.JSX.Element;
4
+
5
+ export { SectionBackdropDemo as default };
@@ -0,0 +1,14 @@
1
+ "use client";
2
+
3
+ // registry/demos/section-backdrop.tsx
4
+ import { SectionBackdrop } from "@krizaka/ui/section-backdrop";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+ function SectionBackdropDemo() {
7
+ return /* @__PURE__ */ jsxs(SectionBackdrop, { grid: true, className: "rounded-xl px-8 py-16", children: [
8
+ /* @__PURE__ */ jsx("h2", { className: "font-display text-3xl font-semibold text-fg", children: "Sovereign by design" }),
9
+ /* @__PURE__ */ jsx("p", { className: "mt-2 max-w-md text-fg-secondary", children: "Your models, your data, your servers." })
10
+ ] });
11
+ }
12
+ export {
13
+ SectionBackdropDemo as default
14
+ };
@@ -0,0 +1,10 @@
1
+ import { SectionBackdrop } from "@krizaka/ui/section-backdrop";
2
+
3
+ export default function SectionBackdropDemo() {
4
+ return (
5
+ <SectionBackdrop grid className="rounded-xl px-8 py-16">
6
+ <h2 className="font-display text-3xl font-semibold text-fg">Sovereign by design</h2>
7
+ <p className="mt-2 max-w-md text-fg-secondary">Your models, your data, your servers.</p>
8
+ </SectionBackdrop>
9
+ );
10
+ }
@@ -5,7 +5,7 @@
5
5
  "files": [
6
6
  {
7
7
  "path": "dropdown-menu/dropdown-menu.tsx",
8
- "content": "// Client (a portal). Radix does the roving focus, the arrows, Home/End, typeahead, Escape and the focus return.\nimport { DropdownMenu as MenuPrimitive } from \"radix-ui\";\nimport type * as React from \"react\";\nimport { tv } from \"tailwind-variants\";\n\nimport { cn } from \"../cn\";\nimport { floating } from \"../floating\";\n\nexport const menu = tv({\n slots: {\n content: cn(floating, \"min-w-48 max-h-(--radix-dropdown-menu-content-available-height) overflow-y-auto p-1 origin-(--radix-dropdown-menu-content-transform-origin)\"),\n item:\n \"relative flex cursor-pointer select-none items-center gap-2 rounded-md px-2.5 py-2 text-sm text-fg outline-hidden transition-colors \" +\n \"data-highlighted:bg-surface-3 data-disabled:pointer-events-none data-disabled:opacity-40 [&>svg]:h-4 [&>svg]:w-4 [&>svg]:shrink-0 \" +\n \"[&>svg]:text-fg-secondary\",\n indicator: \"ml-auto flex h-4 w-4 items-center justify-center text-accent\",\n label: \"px-2.5 pb-1 pt-2 text-[11px] font-semibold uppercase tracking-wider text-fg-secondary\",\n separator: \"-mx-1 my-1 h-px bg-border-subtle\",\n },\n variants: {\n // The danger token is too light for small text on a light surface: the label stays a text role, the icon and the\n // highlight carry the danger.\n tone: { default: {}, danger: { item: \"data-highlighted:bg-danger/15 [&>svg]:text-danger\" } },\n },\n defaultVariants: { tone: \"default\" },\n});\nconst s = menu();\n\nexport type DropdownMenuContentProps = React.ComponentProps<typeof MenuPrimitive.Content> & {\n /** The element the portal renders into (default: document.body). */\n container?: HTMLElement | null;\n};\n\nexport function DropdownMenuContent({ sideOffset = 6, align = \"end\", collisionPadding = 8, container, className, ...props }: DropdownMenuContentProps) {\n return (\n <MenuPrimitive.Portal container={container}>\n <MenuPrimitive.Content sideOffset={sideOffset} align={align} collisionPadding={collisionPadding} className={s.content({ className })} {...props} />\n </MenuPrimitive.Portal>\n );\n}\n\nexport type DropdownMenuItemProps = React.ComponentProps<typeof MenuPrimitive.Item> & {\n /** `danger` for a destructive action: the icon and the highlight carry the danger, the label stays legible. */\n tone?: \"default\" | \"danger\";\n};\n\n/** An action. `tone=\"danger\"` for a destructive one; `onSelect` runs it (the menu closes). */\nexport function DropdownMenuItem({ tone, className, ...props }: DropdownMenuItemProps) {\n return <MenuPrimitive.Item data-tone={tone ?? \"default\"} className={menu({ tone }).item({ className })} {...props} />;\n}\n\n/** A toggled option: `checked` + `onCheckedChange`. */\nexport function DropdownMenuCheckboxItem({ className, children, ...props }: React.ComponentProps<typeof MenuPrimitive.CheckboxItem>) {\n return (\n <MenuPrimitive.CheckboxItem className={s.item({ className })} {...props}>\n {children}\n <MenuPrimitive.ItemIndicator className={s.indicator()}>\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden>\n <path d=\"M20 6 9 17l-5-5\" />\n </svg>\n </MenuPrimitive.ItemIndicator>\n </MenuPrimitive.CheckboxItem>\n );\n}\n\nexport function DropdownMenuLabel({ className, ...props }: React.ComponentProps<typeof MenuPrimitive.Label>) {\n return <MenuPrimitive.Label className={s.label({ className })} {...props} />;\n}\n\nexport function DropdownMenuSeparator({ className, ...props }: React.ComponentProps<typeof MenuPrimitive.Separator>) {\n return <MenuPrimitive.Separator className={s.separator({ className })} {...props} />;\n}\n\n/** `DropdownMenu.Root/Trigger/Content/Item/CheckboxItem/Label/Separator/Group`. `open`/`defaultOpen` + `onOpenChange`. */\nexport const DropdownMenu = {\n Root: MenuPrimitive.Root,\n Trigger: MenuPrimitive.Trigger,\n Content: DropdownMenuContent,\n Item: DropdownMenuItem,\n CheckboxItem: DropdownMenuCheckboxItem,\n Label: DropdownMenuLabel,\n Separator: DropdownMenuSeparator,\n Group: MenuPrimitive.Group,\n};\n"
8
+ "content": "// Client (a portal). Radix does the roving focus, the arrows, Home/End, typeahead, Escape and the focus return.\nimport { DropdownMenu as MenuPrimitive } from \"radix-ui\";\nimport type * as React from \"react\";\nimport { tv } from \"tailwind-variants\";\n\nimport { cn } from \"../cn\";\nimport { floating } from \"../floating\";\n\nexport const menu = tv({\n slots: {\n content: cn(floating, \"min-w-48 max-h-(--radix-dropdown-menu-content-available-height) overflow-y-auto p-1 origin-(--radix-dropdown-menu-content-transform-origin)\"),\n item:\n \"relative flex cursor-pointer select-none items-center gap-2 rounded-md px-2.5 py-2 text-sm text-fg outline-hidden transition-colors \" +\n \"data-highlighted:bg-surface-3 data-disabled:pointer-events-none data-disabled:opacity-40 [&>svg]:h-4 [&>svg]:w-4 [&>svg]:shrink-0 \" +\n \"[&>svg]:text-fg-secondary\",\n indicator: \"ml-auto flex h-4 w-4 items-center justify-center text-fg-accent\",\n label: \"px-2.5 pb-1 pt-2 text-[11px] font-semibold uppercase tracking-wider text-fg-secondary\",\n separator: \"-mx-1 my-1 h-px bg-border-subtle\",\n },\n variants: {\n // The danger token is too light for small text on a light surface: the label stays a text role, the icon and the\n // highlight carry the danger.\n tone: { default: {}, danger: { item: \"data-highlighted:bg-danger/15 [&>svg]:text-danger\" } },\n },\n defaultVariants: { tone: \"default\" },\n});\nconst s = menu();\n\nexport type DropdownMenuContentProps = React.ComponentProps<typeof MenuPrimitive.Content> & {\n /** The element the portal renders into (default: document.body). */\n container?: HTMLElement | null;\n};\n\nexport function DropdownMenuContent({ sideOffset = 6, align = \"end\", collisionPadding = 8, container, className, ...props }: DropdownMenuContentProps) {\n return (\n <MenuPrimitive.Portal container={container}>\n <MenuPrimitive.Content sideOffset={sideOffset} align={align} collisionPadding={collisionPadding} className={s.content({ className })} {...props} />\n </MenuPrimitive.Portal>\n );\n}\n\nexport type DropdownMenuItemProps = React.ComponentProps<typeof MenuPrimitive.Item> & {\n /** `danger` for a destructive action: the icon and the highlight carry the danger, the label stays legible. */\n tone?: \"default\" | \"danger\";\n};\n\n/** An action. `tone=\"danger\"` for a destructive one; `onSelect` runs it (the menu closes). */\nexport function DropdownMenuItem({ tone, className, ...props }: DropdownMenuItemProps) {\n return <MenuPrimitive.Item data-tone={tone ?? \"default\"} className={menu({ tone }).item({ className })} {...props} />;\n}\n\n/** A toggled option: `checked` + `onCheckedChange`. */\nexport function DropdownMenuCheckboxItem({ className, children, ...props }: React.ComponentProps<typeof MenuPrimitive.CheckboxItem>) {\n return (\n <MenuPrimitive.CheckboxItem className={s.item({ className })} {...props}>\n {children}\n <MenuPrimitive.ItemIndicator className={s.indicator()}>\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden>\n <path d=\"M20 6 9 17l-5-5\" />\n </svg>\n </MenuPrimitive.ItemIndicator>\n </MenuPrimitive.CheckboxItem>\n );\n}\n\nexport function DropdownMenuLabel({ className, ...props }: React.ComponentProps<typeof MenuPrimitive.Label>) {\n return <MenuPrimitive.Label className={s.label({ className })} {...props} />;\n}\n\nexport function DropdownMenuSeparator({ className, ...props }: React.ComponentProps<typeof MenuPrimitive.Separator>) {\n return <MenuPrimitive.Separator className={s.separator({ className })} {...props} />;\n}\n\n/** `DropdownMenu.Root/Trigger/Content/Item/CheckboxItem/Label/Separator/Group`. `open`/`defaultOpen` + `onOpenChange`. */\nexport const DropdownMenu = {\n Root: MenuPrimitive.Root,\n Trigger: MenuPrimitive.Trigger,\n Content: DropdownMenuContent,\n Item: DropdownMenuItem,\n CheckboxItem: DropdownMenuCheckboxItem,\n Label: DropdownMenuLabel,\n Separator: DropdownMenuSeparator,\n Group: MenuPrimitive.Group,\n};\n"
9
9
  },
10
10
  {
11
11
  "path": "dropdown-menu/index.ts",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@krizaka/ui",
3
- "version": "2.0.0-beta.4",
3
+ "version": "2.0.0-beta.5",
4
4
  "items": [
5
5
  {
6
6
  "name": "alert",
@@ -209,6 +209,15 @@
209
209
  ],
210
210
  "registryDependencies": []
211
211
  },
212
+ {
213
+ "name": "section-backdrop",
214
+ "type": "primitive",
215
+ "description": "`SectionBackdrop`, `sectionBackdropVariants`. Server-safe.",
216
+ "dependencies": [
217
+ "tailwind-variants@^3.3.1"
218
+ ],
219
+ "registryDependencies": []
220
+ },
212
221
  {
213
222
  "name": "separator",
214
223
  "type": "primitive",
@@ -0,0 +1,73 @@
1
+ {
2
+ "name": "section-backdrop",
3
+ "type": "primitive",
4
+ "description": "`SectionBackdrop`, `sectionBackdropVariants`. Server-safe.",
5
+ "files": [
6
+ {
7
+ "path": "section-backdrop/index.ts",
8
+ "content": "/** @krizaka/ui/section-backdrop — `SectionBackdrop`, `sectionBackdropVariants`. Server-safe. */\nexport { SectionBackdrop, type SectionBackdropProps, sectionBackdropVariants } from \"./section-backdrop\";\n"
9
+ },
10
+ {
11
+ "path": "section-backdrop/section-backdrop.tsx",
12
+ "content": "// Server-safe. The backdrop of a page section in the brand's visual language (packages/tokens/BRAND.md).\nimport type * as React from \"react\";\nimport { tv } from \"tailwind-variants\";\n\nexport const sectionBackdropVariants = tv({\n slots: {\n root: \"kz-backdrop\",\n drift: \"kz-backdrop-drift\",\n dome: \"kz-backdrop-dome\",\n grid: \"kz-backdrop-grid\",\n media: \"kz-backdrop-media\",\n },\n});\n\nexport interface SectionBackdropProps extends React.HTMLAttributes<HTMLElement> {\n /** The element: `section` (default), `header`, `footer` or `div`. */\n as?: \"section\" | \"header\" | \"footer\" | \"div\";\n /** Where the brand tint sits: `down` (default) starts tinted and ends on the page surface; `up` ends tinted (a closing call to action). */\n direction?: \"down\" | \"up\";\n /** The light dome above the content (the halo of a hero). Default true. */\n dome?: boolean;\n /** A floor of perspective lines under the content. Default false. */\n grid?: boolean;\n /** A foreground illustration or image, blurred for depth of field, behind the content (decorative: hidden from assistive technology). */\n media?: React.ReactNode;\n /** The very slow drift of the light (40 s); always still under prefers-reduced-motion. Default true. */\n animated?: boolean;\n}\n\n/**\n * A section of a page in the Krizaka visual language: the brand's section gradient (`--kz-brand-gradient-*`, so it\n * follows the brand theme and dark/light), a light dome, an optional perspective grid and a blurred foreground. Every\n * section ends on the page surface, so consecutive sections glide from one tint to the next. Text on it reads at AA\n * (tested in @krizaka/tokens).\n */\nexport function SectionBackdrop({ as: Tag = \"section\", direction = \"down\", dome = true, grid = false, media, animated = true, className, children, ...props }: SectionBackdropProps) {\n const s = sectionBackdropVariants();\n return (\n <Tag className={s.root({ className })} data-direction={direction} {...props}>\n {animated ? <div data-backdrop-layer aria-hidden className={s.drift()} /> : null}\n {dome ? <div data-backdrop-layer aria-hidden className={s.dome()} /> : null}\n {grid ? <div data-backdrop-layer aria-hidden className={s.grid()} /> : null}\n {media ? (\n <div data-backdrop-layer aria-hidden className={s.media()}>\n {media}\n </div>\n ) : null}\n {children}\n </Tag>\n );\n}\n"
13
+ }
14
+ ],
15
+ "dependencies": [
16
+ "tailwind-variants@^3.3.1"
17
+ ],
18
+ "registryDependencies": [],
19
+ "demo": {
20
+ "path": "demos/section-backdrop.tsx",
21
+ "content": "import { SectionBackdrop } from \"@krizaka/ui/section-backdrop\";\n\nexport default function SectionBackdropDemo() {\n return (\n <SectionBackdrop grid className=\"rounded-xl px-8 py-16\">\n <h2 className=\"font-display text-3xl font-semibold text-fg\">Sovereign by design</h2>\n <p className=\"mt-2 max-w-md text-fg-secondary\">Your models, your data, your servers.</p>\n </SectionBackdrop>\n );\n}\n"
22
+ },
23
+ "props": [
24
+ {
25
+ "component": "SectionBackdrop",
26
+ "description": "A section of a page in the Krizaka visual language: the brand's section gradient (`--kz-brand-gradient-*`, so it\nfollows the brand theme and dark/light), a light dome, an optional perspective grid and a blurred foreground. Every\nsection ends on the page surface, so consecutive sections glide from one tint to the next. Text on it reads at AA\n(tested in",
27
+ "props": [
28
+ {
29
+ "name": "animated",
30
+ "type": "boolean",
31
+ "default": "true",
32
+ "description": "The very slow drift of the light (40 s); always still under prefers-reduced-motion. Default true.",
33
+ "required": false
34
+ },
35
+ {
36
+ "name": "as",
37
+ "type": "\"div\" | \"footer\" | \"header\" | \"section\"",
38
+ "default": "section",
39
+ "description": "The element: `section` (default), `header`, `footer` or `div`.",
40
+ "required": false
41
+ },
42
+ {
43
+ "name": "direction",
44
+ "type": "\"down\" | \"up\"",
45
+ "default": "down",
46
+ "description": "Where the brand tint sits: `down` (default) starts tinted and ends on the page surface; `up` ends tinted (a closing call to action).",
47
+ "required": false
48
+ },
49
+ {
50
+ "name": "dome",
51
+ "type": "boolean",
52
+ "default": "true",
53
+ "description": "The light dome above the content (the halo of a hero). Default true.",
54
+ "required": false
55
+ },
56
+ {
57
+ "name": "grid",
58
+ "type": "boolean",
59
+ "default": "false",
60
+ "description": "A floor of perspective lines under the content. Default false.",
61
+ "required": false
62
+ },
63
+ {
64
+ "name": "media",
65
+ "type": "ReactNode",
66
+ "default": null,
67
+ "description": "A foreground illustration or image, blurred for depth of field, behind the content (decorative: hidden from assistive technology).",
68
+ "required": false
69
+ }
70
+ ]
71
+ }
72
+ ]
73
+ }
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/button/button.tsx"],"sourcesContent":["// Server-safe: no hook, no context. `buttonVariants` styles a <Link> or a Server Component without the component.\nimport { Slot } from \"radix-ui\";\nimport type * as React from \"react\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\n\nexport const buttonVariants = tv({\n base:\n \"inline-flex shrink-0 select-none items-center justify-center gap-2 whitespace-nowrap font-semibold transition-all \" +\n \"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-surface-0 \" +\n \"disabled:pointer-events-none disabled:opacity-40 data-loading:cursor-progress active:scale-[0.98]\",\n variants: {\n variant: {\n primary: \"bg-accent text-on-accent shadow-sm hover:bg-accent-hover\",\n secondary: \"border border-border-default bg-surface-2 text-fg hover:border-border-strong hover:bg-surface-3\",\n outline: \"border border-border-default bg-transparent text-fg hover:border-accent hover:text-accent\",\n ghost: \"text-fg-secondary hover:bg-surface-2 hover:text-fg\",\n // The danger token is invariant and too light for small text on a light surface (3.6:1): the label stays a\n // text role, the border and the tint carry the danger.\n danger: \"border border-danger/50 bg-danger/10 text-fg hover:border-danger hover:bg-danger/20\",\n },\n size: { sm: \"h-8 px-3 text-xs\", md: \"h-10 px-4 text-sm\", lg: \"h-12 px-6 text-sm\", icon: \"h-10 w-10\" },\n shape: { rounded: \"rounded-lg\", pill: \"rounded-full\" },\n },\n defaultVariants: { variant: \"secondary\", size: \"md\", shape: \"rounded\" },\n});\n\nexport type ButtonVariants = VariantProps<typeof buttonVariants>;\n\nexport type ButtonProps = React.ComponentProps<\"button\"> &\n ButtonVariants & {\n /**\n * The look: `primary` (the accent), `secondary` (a raised surface), `outline`, `ghost`, `danger`.\n * @default \"secondary\"\n */\n variant?: ButtonVariants[\"variant\"];\n /**\n * sm · md · lg, or `icon` (a square).\n * @default \"md\"\n */\n size?: ButtonVariants[\"size\"];\n /**\n * rounded · pill.\n * @default \"rounded\"\n */\n shape?: ButtonVariants[\"shape\"];\n /** Renders the child (e.g. a <Link>) instead of the <button>, with props, classes and ref merged. */\n asChild?: boolean;\n /** Disables and signals the wait (aria-busy, data-loading) — the product adds a spinner if it wants one. */\n loading?: boolean;\n };\n\nexport function Button({ asChild, loading, variant, size, shape, className, disabled, ...props }: ButtonProps) {\n const Comp = asChild ? Slot.Root : \"button\";\n return (\n <Comp\n type={asChild ? undefined : \"button\"}\n aria-busy={loading || undefined}\n data-loading={loading ? \"\" : undefined}\n data-variant={variant ?? \"secondary\"}\n disabled={asChild ? undefined : disabled || loading}\n aria-disabled={asChild && (disabled || loading) ? true : undefined}\n className={buttonVariants({ variant, size, shape, className })}\n {...props}\n />\n );\n}\n\nexport type IconButtonProps = Omit<ButtonProps, \"size\"> & {\n /** The accessible name (and tooltip) of the button — required, passed translated. */\n label: string;\n /**\n * sm · md · lg, or `icon` (a square).\n * @default \"icon\"\n */\n size?: ButtonProps[\"size\"];\n};\n\n/** An icon-only button: `label` is required, it is its accessible name. */\nexport function IconButton({ label, size = \"icon\", ...props }: IconButtonProps) {\n return <Button aria-label={label} title={label} size={size} {...props} />;\n}\n"],"mappings":";;;AACA,SAAS,YAAY;AAErB,SAAS,UAA6B;AAmDlC;AAjDG,IAAM,iBAAiB,GAAG;AAAA,EAC/B,MACE;AAAA,EAGF,UAAU;AAAA,IACR,SAAS;AAAA,MACP,SAAS;AAAA,MACT,WAAW;AAAA,MACX,SAAS;AAAA,MACT,OAAO;AAAA;AAAA;AAAA,MAGP,QAAQ;AAAA,IACV;AAAA,IACA,MAAM,EAAE,IAAI,oBAAoB,IAAI,qBAAqB,IAAI,qBAAqB,MAAM,YAAY;AAAA,IACpG,OAAO,EAAE,SAAS,cAAc,MAAM,eAAe;AAAA,EACvD;AAAA,EACA,iBAAiB,EAAE,SAAS,aAAa,MAAM,MAAM,OAAO,UAAU;AACxE,CAAC;AA2BM,SAAS,OAAO,EAAE,SAAS,SAAS,SAAS,MAAM,OAAO,WAAW,UAAU,GAAG,MAAM,GAAgB;AAC7G,QAAM,OAAO,UAAU,KAAK,OAAO;AACnC,SACE;AAAA,IAAC;AAAA;AAAA,MACC,MAAM,UAAU,SAAY;AAAA,MAC5B,aAAW,WAAW;AAAA,MACtB,gBAAc,UAAU,KAAK;AAAA,MAC7B,gBAAc,WAAW;AAAA,MACzB,UAAU,UAAU,SAAY,YAAY;AAAA,MAC5C,iBAAe,YAAY,YAAY,WAAW,OAAO;AAAA,MACzD,WAAW,eAAe,EAAE,SAAS,MAAM,OAAO,UAAU,CAAC;AAAA,MAC5D,GAAG;AAAA;AAAA,EACN;AAEJ;AAaO,SAAS,WAAW,EAAE,OAAO,OAAO,QAAQ,GAAG,MAAM,GAAoB;AAC9E,SAAO,oBAAC,UAAO,cAAY,OAAO,OAAO,OAAO,MAAa,GAAG,OAAO;AACzE;","names":[]}