@steez-ui/ui 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +52 -0
  3. package/dist/components/Button.d.ts +11 -0
  4. package/dist/components/Button.d.ts.map +1 -0
  5. package/dist/components/Button.js +8 -0
  6. package/dist/components/Button.js.map +1 -0
  7. package/dist/components/CopyButton.d.ts +10 -0
  8. package/dist/components/CopyButton.d.ts.map +1 -0
  9. package/dist/components/CopyButton.js +25 -0
  10. package/dist/components/CopyButton.js.map +1 -0
  11. package/dist/components/CopyButton.module.css +30 -0
  12. package/dist/components/CornerBracketCard.d.ts +7 -0
  13. package/dist/components/CornerBracketCard.d.ts.map +1 -0
  14. package/dist/components/CornerBracketCard.js +6 -0
  15. package/dist/components/CornerBracketCard.js.map +1 -0
  16. package/dist/components/CornerBracketCard.module.css +109 -0
  17. package/dist/components/CyberpunkCheckbox.d.ts +7 -0
  18. package/dist/components/CyberpunkCheckbox.d.ts.map +1 -0
  19. package/dist/components/CyberpunkCheckbox.js +8 -0
  20. package/dist/components/CyberpunkCheckbox.js.map +1 -0
  21. package/dist/components/CyberpunkCheckbox.module.css +57 -0
  22. package/dist/components/CyberpunkInput.d.ts +9 -0
  23. package/dist/components/CyberpunkInput.d.ts.map +1 -0
  24. package/dist/components/CyberpunkInput.js +9 -0
  25. package/dist/components/CyberpunkInput.js.map +1 -0
  26. package/dist/components/CyberpunkInput.module.css +115 -0
  27. package/dist/components/CyberpunkRadio.d.ts +17 -0
  28. package/dist/components/CyberpunkRadio.d.ts.map +1 -0
  29. package/dist/components/CyberpunkRadio.js +11 -0
  30. package/dist/components/CyberpunkRadio.js.map +1 -0
  31. package/dist/components/CyberpunkRadio.module.css +64 -0
  32. package/dist/components/CyberpunkSelect.d.ts +12 -0
  33. package/dist/components/CyberpunkSelect.d.ts.map +1 -0
  34. package/dist/components/CyberpunkSelect.js +8 -0
  35. package/dist/components/CyberpunkSelect.js.map +1 -0
  36. package/dist/components/CyberpunkSelect.module.css +108 -0
  37. package/dist/components/CyberpunkSlider.d.ts +10 -0
  38. package/dist/components/CyberpunkSlider.d.ts.map +1 -0
  39. package/dist/components/CyberpunkSlider.js +9 -0
  40. package/dist/components/CyberpunkSlider.js.map +1 -0
  41. package/dist/components/CyberpunkSlider.module.css +98 -0
  42. package/dist/components/CyberpunkTextarea.d.ts +7 -0
  43. package/dist/components/CyberpunkTextarea.d.ts.map +1 -0
  44. package/dist/components/CyberpunkTextarea.js +8 -0
  45. package/dist/components/CyberpunkTextarea.js.map +1 -0
  46. package/dist/components/CyberpunkTextarea.module.css +73 -0
  47. package/dist/components/CyberpunkTile.d.ts +10 -0
  48. package/dist/components/CyberpunkTile.d.ts.map +1 -0
  49. package/dist/components/CyberpunkTile.js +6 -0
  50. package/dist/components/CyberpunkTile.js.map +1 -0
  51. package/dist/components/CyberpunkTile.module.css +133 -0
  52. package/dist/components/ErrorMessage.d.ts +11 -0
  53. package/dist/components/ErrorMessage.d.ts.map +1 -0
  54. package/dist/components/ErrorMessage.js +16 -0
  55. package/dist/components/ErrorMessage.js.map +1 -0
  56. package/dist/components/ErrorMessage.module.css +75 -0
  57. package/dist/components/LoadingProgressBar.d.ts +8 -0
  58. package/dist/components/LoadingProgressBar.d.ts.map +1 -0
  59. package/dist/components/LoadingProgressBar.js +13 -0
  60. package/dist/components/LoadingProgressBar.js.map +1 -0
  61. package/dist/components/LoadingProgressBar.module.css +42 -0
  62. package/dist/components/PageHeader.d.ts +17 -0
  63. package/dist/components/PageHeader.d.ts.map +1 -0
  64. package/dist/components/PageHeader.js +7 -0
  65. package/dist/components/PageHeader.js.map +1 -0
  66. package/dist/components/PageHeader.module.css +118 -0
  67. package/dist/components/PageTemplate.d.ts +20 -0
  68. package/dist/components/PageTemplate.d.ts.map +1 -0
  69. package/dist/components/PageTemplate.js +8 -0
  70. package/dist/components/PageTemplate.js.map +1 -0
  71. package/dist/components/PageTemplate.module.css +55 -0
  72. package/dist/components/SegmentedControl.d.ts +16 -0
  73. package/dist/components/SegmentedControl.d.ts.map +1 -0
  74. package/dist/components/SegmentedControl.js +9 -0
  75. package/dist/components/SegmentedControl.js.map +1 -0
  76. package/dist/components/SegmentedControl.module.css +51 -0
  77. package/dist/components/StatusMessage.d.ts +6 -0
  78. package/dist/components/StatusMessage.d.ts.map +1 -0
  79. package/dist/components/StatusMessage.js +7 -0
  80. package/dist/components/StatusMessage.js.map +1 -0
  81. package/dist/components/StatusMessage.module.css +60 -0
  82. package/dist/components/TabbedPanel.d.ts +23 -0
  83. package/dist/components/TabbedPanel.d.ts.map +1 -0
  84. package/dist/components/TabbedPanel.js +36 -0
  85. package/dist/components/TabbedPanel.js.map +1 -0
  86. package/dist/components/TabbedPanel.module.css +61 -0
  87. package/dist/components/ThemeToggle.d.ts +8 -0
  88. package/dist/components/ThemeToggle.d.ts.map +1 -0
  89. package/dist/components/ThemeToggle.js +22 -0
  90. package/dist/components/ThemeToggle.js.map +1 -0
  91. package/dist/components/ThemeToggle.module.css +23 -0
  92. package/dist/components/ThemedCard.d.ts +7 -0
  93. package/dist/components/ThemedCard.d.ts.map +1 -0
  94. package/dist/components/ThemedCard.js +6 -0
  95. package/dist/components/ThemedCard.js.map +1 -0
  96. package/dist/components/ThemedCard.module.css +22 -0
  97. package/dist/hooks/useStableId.d.ts +2 -0
  98. package/dist/hooks/useStableId.d.ts.map +1 -0
  99. package/dist/hooks/useStableId.js +6 -0
  100. package/dist/hooks/useStableId.js.map +1 -0
  101. package/dist/index.d.ts +20 -0
  102. package/dist/index.d.ts.map +1 -0
  103. package/dist/index.js +20 -0
  104. package/dist/index.js.map +1 -0
  105. package/dist/styles/Buttons.module.css +96 -0
  106. package/package.json +35 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Thomas Vu
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,52 @@
1
+ # Steez UI
2
+
3
+ Shared Phantasy UI primitives and shadcn-compatible registry output.
4
+
5
+ Registry frontend: `https://steez-ui.pages.dev`
6
+
7
+ ## Packages
8
+
9
+ - `@steez-ui/theme`
10
+ - `@steez-ui/icons`
11
+ - `@steez-ui/ui`
12
+
13
+ ## App
14
+
15
+ - `@steez-ui/registry`
16
+
17
+ ## Scripts
18
+
19
+ - `bun run build`
20
+ - `bun run check:release`
21
+ - `bun run publish:packages:dry-run`
22
+ - `bun run publish:packages`
23
+ - `bun run deploy:registry`
24
+ - `bun run generate:registry`
25
+ - `bun run test`
26
+ - `bun run test:install-smoke`
27
+
28
+ ## Install
29
+
30
+ ```bash
31
+ bunx shadcn@latest add https://steez-ui.pages.dev/r/foundation.json
32
+ ```
33
+
34
+ ```bash
35
+ bun add @steez-ui/theme @steez-ui/icons @steez-ui/ui
36
+ ```
37
+
38
+ ## Release Flow
39
+
40
+ 1. `bun install`
41
+ 2. `bun run check:release`
42
+ 3. `bun run publish:packages`
43
+ 4. `bun run deploy:registry`
44
+
45
+ GitHub Actions mirror the same path for CI, npm publish, and Cloudflare Pages deployment.
46
+
47
+ ## One-Time External Setup
48
+
49
+ - Create or claim the npm scope `@steez-ui`, then grant the publishing account access.
50
+ - Add `NPM_TOKEN` to the GitHub repository secrets before using the package publish workflow.
51
+ - Add `CLOUDFLARE_API_TOKEN` and `CLOUDFLARE_ACCOUNT_ID` to the GitHub repository secrets before relying on the Pages deploy workflow.
52
+ - Until those secrets exist, the GitHub publish and deploy workflows will skip with a notice instead of failing.
@@ -0,0 +1,11 @@
1
+ import React from "react";
2
+ type ButtonVariant = "primary" | "secondary" | "danger";
3
+ type ButtonSize = "small" | "medium" | "large";
4
+ export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
5
+ variant?: ButtonVariant;
6
+ size?: ButtonSize;
7
+ children: React.ReactNode;
8
+ }
9
+ export declare function Button({ variant, size, className, children, ...props }: ButtonProps): import("react/jsx-runtime").JSX.Element;
10
+ export default Button;
11
+ //# sourceMappingURL=Button.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Button.d.ts","sourceRoot":"","sources":["../../src/components/Button.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,KAAK,aAAa,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,CAAC;AACxD,KAAK,UAAU,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE/C,MAAM,WAAW,WACf,SAAQ,KAAK,CAAC,oBAAoB,CAAC,iBAAiB,CAAC;IACrD,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED,wBAAgB,MAAM,CAAC,EACrB,OAAmB,EACnB,IAAe,EACf,SAAc,EACd,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,WAAW,2CAQb;AAED,eAAe,MAAM,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import styles from "../styles/Buttons.module.css";
3
+ export function Button({ variant = "primary", size = "medium", className = "", children, ...props }) {
4
+ const sizeClass = size === "small" ? styles.small : size === "large" ? styles.large : "";
5
+ return (_jsx("button", { className: `${styles[variant]} ${sizeClass} ${className}`.trim(), ...props, children: children }));
6
+ }
7
+ export default Button;
8
+ //# sourceMappingURL=Button.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Button.js","sourceRoot":"","sources":["../../src/components/Button.tsx"],"names":[],"mappings":";AAEA,OAAO,MAAM,MAAM,8BAA8B,CAAC;AAYlD,MAAM,UAAU,MAAM,CAAC,EACrB,OAAO,GAAG,SAAS,EACnB,IAAI,GAAG,QAAQ,EACf,SAAS,GAAG,EAAE,EACd,QAAQ,EACR,GAAG,KAAK,EACI;IACZ,MAAM,SAAS,GAAG,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;IAEzF,OAAO,CACL,iBAAQ,SAAS,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,SAAS,IAAI,SAAS,EAAE,CAAC,IAAI,EAAE,KAAM,KAAK,YAChF,QAAQ,GACF,CACV,CAAC;AACJ,CAAC;AAED,eAAe,MAAM,CAAC"}
@@ -0,0 +1,10 @@
1
+ export interface CopyButtonProps {
2
+ value: string;
3
+ size?: number;
4
+ className?: string;
5
+ title?: string;
6
+ feedbackDuration?: number;
7
+ onCopyError?: (error: unknown) => void;
8
+ }
9
+ export declare function CopyButton({ value, size, className, title, feedbackDuration, onCopyError, }: CopyButtonProps): import("react/jsx-runtime").JSX.Element;
10
+ //# sourceMappingURL=CopyButton.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CopyButton.d.ts","sourceRoot":"","sources":["../../src/components/CopyButton.tsx"],"names":[],"mappings":"AAMA,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CACxC;AAED,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,IAAS,EACT,SAAc,EACd,KAA2B,EAC3B,gBAAuB,EACvB,WAAW,GACZ,EAAE,eAAe,2CAgCjB"}
@@ -0,0 +1,25 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useEffect, useState } from "react";
3
+ import { CheckIcon, CopyIcon } from "@steez-ui/icons";
4
+ import styles from "./CopyButton.module.css";
5
+ export function CopyButton({ value, size = 16, className = "", title = "Copy to clipboard", feedbackDuration = 2000, onCopyError, }) {
6
+ const [copied, setCopied] = useState(false);
7
+ useEffect(() => {
8
+ if (!copied) {
9
+ return undefined;
10
+ }
11
+ const timer = window.setTimeout(() => setCopied(false), feedbackDuration);
12
+ return () => window.clearTimeout(timer);
13
+ }, [copied, feedbackDuration]);
14
+ const handleCopy = async () => {
15
+ try {
16
+ await navigator.clipboard.writeText(value);
17
+ setCopied(true);
18
+ }
19
+ catch (error) {
20
+ onCopyError?.(error);
21
+ }
22
+ };
23
+ return (_jsx("button", { type: "button", className: `${styles.copyButton} ${copied ? styles.copied : ""} ${className}`.trim(), onClick: handleCopy, title: copied ? "Copied!" : title, "aria-label": copied ? "Copied to clipboard" : title, children: copied ? _jsx(CheckIcon, { width: size, height: size }) : _jsx(CopyIcon, { width: size, height: size }) }));
24
+ }
25
+ //# sourceMappingURL=CopyButton.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CopyButton.js","sourceRoot":"","sources":["../../src/components/CopyButton.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEnD,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEtD,OAAO,MAAM,MAAM,yBAAyB,CAAC;AAW7C,MAAM,UAAU,UAAU,CAAC,EACzB,KAAK,EACL,IAAI,GAAG,EAAE,EACT,SAAS,GAAG,EAAE,EACd,KAAK,GAAG,mBAAmB,EAC3B,gBAAgB,GAAG,IAAI,EACvB,WAAW,GACK;IAChB,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAE5C,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,gBAAgB,CAAC,CAAC;QAC1E,OAAO,GAAG,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IAC1C,CAAC,EAAE,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC;IAE/B,MAAM,UAAU,GAAG,KAAK,IAAI,EAAE;QAC5B,IAAI,CAAC;YACH,MAAM,SAAS,CAAC,SAAS,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YAC3C,SAAS,CAAC,IAAI,CAAC,CAAC;QAClB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC;QACvB,CAAC;IACH,CAAC,CAAC;IAEF,OAAO,CACL,iBACE,IAAI,EAAC,QAAQ,EACb,SAAS,EAAE,GAAG,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,SAAS,EAAE,CAAC,IAAI,EAAE,EACpF,OAAO,EAAE,UAAU,EACnB,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,gBACrB,MAAM,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,KAAK,YAEjD,MAAM,CAAC,CAAC,CAAC,KAAC,SAAS,IAAC,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,GAAI,CAAC,CAAC,CAAC,KAAC,QAAQ,IAAC,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,GAAI,GACrF,CACV,CAAC;AACJ,CAAC"}
@@ -0,0 +1,30 @@
1
+ .copyButton {
2
+ display: inline-flex;
3
+ align-items: center;
4
+ justify-content: center;
5
+ background: transparent;
6
+ color: var(--text-primary);
7
+ border: 1px solid var(--border-color);
8
+ border-radius: 6px;
9
+ padding: 4px 8px;
10
+ cursor: pointer;
11
+ font-size: 0.75rem;
12
+ transition: all var(--transition-fast);
13
+ min-width: 32px;
14
+ min-height: 24px;
15
+ }
16
+
17
+ .copyButton:hover:not(:disabled) {
18
+ border-color: var(--progress);
19
+ color: var(--progress);
20
+ }
21
+
22
+ .copyButton:active {
23
+ transform: scale(0.95);
24
+ }
25
+
26
+ .copied {
27
+ border-color: var(--success);
28
+ color: var(--success);
29
+ }
30
+
@@ -0,0 +1,7 @@
1
+ import React from "react";
2
+ export interface CornerBracketCardProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "title"> {
3
+ title?: React.ReactNode;
4
+ variant?: "default" | "featured";
5
+ }
6
+ export declare function CornerBracketCard({ title, variant, className, children, ...props }: CornerBracketCardProps): import("react/jsx-runtime").JSX.Element;
7
+ //# sourceMappingURL=CornerBracketCard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CornerBracketCard.d.ts","sourceRoot":"","sources":["../../src/components/CornerBracketCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,MAAM,WAAW,sBACf,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAC3D,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,OAAO,CAAC,EAAE,SAAS,GAAG,UAAU,CAAC;CAClC;AAED,wBAAgB,iBAAiB,CAAC,EAChC,KAAK,EACL,OAAmB,EACnB,SAAc,EACd,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,sBAAsB,2CAWxB"}
@@ -0,0 +1,6 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import styles from "./CornerBracketCard.module.css";
3
+ export function CornerBracketCard({ title, variant = "default", className = "", children, ...props }) {
4
+ return (_jsxs("div", { className: `${styles.card} ${variant === "featured" ? styles.featured : ""} ${className}`.trim(), ...props, children: [_jsx("span", { className: `${styles.corner} ${styles.cornerTopLeft}`, "aria-hidden": "true" }), _jsx("span", { className: `${styles.corner} ${styles.cornerTopRight}`, "aria-hidden": "true" }), _jsx("span", { className: `${styles.corner} ${styles.cornerBottomLeft}`, "aria-hidden": "true" }), _jsx("span", { className: `${styles.corner} ${styles.cornerBottomRight}`, "aria-hidden": "true" }), title ? _jsx("div", { className: styles.title, children: title }) : null, children] }));
5
+ }
6
+ //# sourceMappingURL=CornerBracketCard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CornerBracketCard.js","sourceRoot":"","sources":["../../src/components/CornerBracketCard.tsx"],"names":[],"mappings":";AAEA,OAAO,MAAM,MAAM,gCAAgC,CAAC;AAQpD,MAAM,UAAU,iBAAiB,CAAC,EAChC,KAAK,EACL,OAAO,GAAG,SAAS,EACnB,SAAS,GAAG,EAAE,EACd,QAAQ,EACR,GAAG,KAAK,EACe;IACvB,OAAO,CACL,eAAK,SAAS,EAAE,GAAG,MAAM,CAAC,IAAI,IAAI,OAAO,KAAK,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,SAAS,EAAE,CAAC,IAAI,EAAE,KAAM,KAAK,aAC9G,eAAM,SAAS,EAAE,GAAG,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,aAAa,EAAE,iBAAc,MAAM,GAAG,EAClF,eAAM,SAAS,EAAE,GAAG,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,cAAc,EAAE,iBAAc,MAAM,GAAG,EACnF,eAAM,SAAS,EAAE,GAAG,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,gBAAgB,EAAE,iBAAc,MAAM,GAAG,EACrF,eAAM,SAAS,EAAE,GAAG,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,iBAAiB,EAAE,iBAAc,MAAM,GAAG,EACrF,KAAK,CAAC,CAAC,CAAC,cAAK,SAAS,EAAE,MAAM,CAAC,KAAK,YAAG,KAAK,GAAO,CAAC,CAAC,CAAC,IAAI,EAC1D,QAAQ,IACL,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,109 @@
1
+ .card {
2
+ position: relative;
3
+ border: 1px solid var(--border-color);
4
+ background: color-mix(in srgb, var(--bg-secondary) 88%, transparent);
5
+ padding: 1rem;
6
+ }
7
+
8
+ .featured {
9
+ border-color: var(--accent-primary);
10
+ }
11
+
12
+ .title {
13
+ margin-bottom: 0.75rem;
14
+ color: var(--text-primary);
15
+ font-family: var(--font-primary);
16
+ font-size: 1rem;
17
+ font-weight: 600;
18
+ }
19
+
20
+ .corner {
21
+ position: absolute;
22
+ width: 18px;
23
+ height: 18px;
24
+ pointer-events: none;
25
+ }
26
+
27
+ .corner::before,
28
+ .corner::after {
29
+ content: "";
30
+ position: absolute;
31
+ background: var(--accent-primary);
32
+ }
33
+
34
+ .cornerTopLeft {
35
+ top: -1px;
36
+ left: -1px;
37
+ }
38
+
39
+ .cornerTopLeft::before,
40
+ .cornerBottomLeft::before,
41
+ .cornerTopRight::before,
42
+ .cornerBottomRight::before {
43
+ width: 12px;
44
+ height: 1px;
45
+ }
46
+
47
+ .cornerTopLeft::after,
48
+ .cornerBottomLeft::after,
49
+ .cornerTopRight::after,
50
+ .cornerBottomRight::after {
51
+ width: 1px;
52
+ height: 12px;
53
+ }
54
+
55
+ .cornerTopLeft::before {
56
+ top: 0;
57
+ left: 0;
58
+ }
59
+
60
+ .cornerTopLeft::after {
61
+ top: 0;
62
+ left: 0;
63
+ }
64
+
65
+ .cornerTopRight {
66
+ top: -1px;
67
+ right: -1px;
68
+ }
69
+
70
+ .cornerTopRight::before {
71
+ top: 0;
72
+ right: 0;
73
+ }
74
+
75
+ .cornerTopRight::after {
76
+ top: 0;
77
+ right: 0;
78
+ }
79
+
80
+ .cornerBottomLeft {
81
+ bottom: -1px;
82
+ left: -1px;
83
+ }
84
+
85
+ .cornerBottomLeft::before {
86
+ bottom: 0;
87
+ left: 0;
88
+ }
89
+
90
+ .cornerBottomLeft::after {
91
+ bottom: 0;
92
+ left: 0;
93
+ }
94
+
95
+ .cornerBottomRight {
96
+ bottom: -1px;
97
+ right: -1px;
98
+ }
99
+
100
+ .cornerBottomRight::before {
101
+ bottom: 0;
102
+ right: 0;
103
+ }
104
+
105
+ .cornerBottomRight::after {
106
+ bottom: 0;
107
+ right: 0;
108
+ }
109
+
@@ -0,0 +1,7 @@
1
+ import { InputHTMLAttributes } from "react";
2
+ export interface CyberpunkCheckboxProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "onChange" | "type"> {
3
+ label?: string;
4
+ onChange?: (checked: boolean) => void;
5
+ }
6
+ export declare function CyberpunkCheckbox({ label, className, id, onChange, ...props }: CyberpunkCheckboxProps): import("react/jsx-runtime").JSX.Element;
7
+ //# sourceMappingURL=CyberpunkCheckbox.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CyberpunkCheckbox.d.ts","sourceRoot":"","sources":["../../src/components/CyberpunkCheckbox.tsx"],"names":[],"mappings":"AAAA,OAAc,EAAE,mBAAmB,EAAE,MAAM,OAAO,CAAC;AAKnD,MAAM,WAAW,sBACf,SAAQ,IAAI,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EAAE,UAAU,GAAG,MAAM,CAAC;IACxE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;CACvC;AAED,wBAAgB,iBAAiB,CAAC,EAChC,KAAK,EACL,SAAc,EACd,EAAE,EACF,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,sBAAsB,2CAexB"}
@@ -0,0 +1,8 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useStableId } from "../hooks/useStableId";
3
+ import styles from "./CyberpunkCheckbox.module.css";
4
+ export function CyberpunkCheckbox({ label, className = "", id, onChange, ...props }) {
5
+ const inputId = useStableId("checkbox", id);
6
+ return (_jsxs("label", { htmlFor: inputId, className: `${styles.wrapper} ${className}`.trim(), children: [_jsx("input", { id: inputId, type: "checkbox", className: styles.checkbox, onChange: (event) => onChange?.(event.target.checked), ...props }), label ? _jsx("span", { className: styles.label, children: label }) : null] }));
7
+ }
8
+ //# sourceMappingURL=CyberpunkCheckbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CyberpunkCheckbox.js","sourceRoot":"","sources":["../../src/components/CyberpunkCheckbox.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,MAAM,MAAM,gCAAgC,CAAC;AAQpD,MAAM,UAAU,iBAAiB,CAAC,EAChC,KAAK,EACL,SAAS,GAAG,EAAE,EACd,EAAE,EACF,QAAQ,EACR,GAAG,KAAK,EACe;IACvB,MAAM,OAAO,GAAG,WAAW,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAE5C,OAAO,CACL,iBAAO,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,MAAM,CAAC,OAAO,IAAI,SAAS,EAAE,CAAC,IAAI,EAAE,aACzE,gBACE,EAAE,EAAE,OAAO,EACX,IAAI,EAAC,UAAU,EACf,SAAS,EAAE,MAAM,CAAC,QAAQ,EAC1B,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,KACjD,KAAK,GACT,EACD,KAAK,CAAC,CAAC,CAAC,eAAM,SAAS,EAAE,MAAM,CAAC,KAAK,YAAG,KAAK,GAAQ,CAAC,CAAC,CAAC,IAAI,IACvD,CACT,CAAC;AACJ,CAAC"}
@@ -0,0 +1,57 @@
1
+ .wrapper {
2
+ display: flex;
3
+ align-items: center;
4
+ gap: 0.75rem;
5
+ cursor: pointer;
6
+ user-select: none;
7
+ }
8
+
9
+ .checkbox {
10
+ width: 28px;
11
+ height: 28px;
12
+ border: 2px solid var(--border);
13
+ border-radius: 3px;
14
+ appearance: none;
15
+ outline: none;
16
+ margin: 0;
17
+ cursor: pointer;
18
+ position: relative;
19
+ background-color: var(--bg-primary);
20
+ transition: all var(--transition-fast);
21
+ }
22
+
23
+ .checkbox::before {
24
+ content: "";
25
+ width: 16px;
26
+ height: 16px;
27
+ background-color: var(--success);
28
+ position: absolute;
29
+ top: 4px;
30
+ left: 4px;
31
+ display: block;
32
+ transform: scale(0);
33
+ transition: 120ms transform ease-in-out;
34
+ }
35
+
36
+ .checkbox:checked::before {
37
+ transform: scale(1);
38
+ }
39
+
40
+ .checkbox:hover {
41
+ border-color: var(--success);
42
+ }
43
+
44
+ .checkbox:focus-visible {
45
+ box-shadow: 0 0 0 2px rgba(0, 255, 136, 0.2);
46
+ }
47
+
48
+ .checkbox:disabled {
49
+ opacity: 0.5;
50
+ cursor: not-allowed;
51
+ }
52
+
53
+ .label {
54
+ font-size: 0.875rem;
55
+ color: var(--text-primary);
56
+ }
57
+
@@ -0,0 +1,9 @@
1
+ import { InputHTMLAttributes, ReactNode } from "react";
2
+ export interface CyberpunkInputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "helperText"> {
3
+ label?: string;
4
+ variant?: "default" | "long" | "full";
5
+ helperText?: string;
6
+ icon?: ReactNode;
7
+ }
8
+ export declare function CyberpunkInput({ label, variant, className, id, disabled, readOnly, helperText, icon, ...props }: CyberpunkInputProps): import("react/jsx-runtime").JSX.Element;
9
+ //# sourceMappingURL=CyberpunkInput.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CyberpunkInput.d.ts","sourceRoot":"","sources":["../../src/components/CyberpunkInput.tsx"],"names":[],"mappings":"AAAA,OAAc,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAK9D,MAAM,WAAW,mBACf,SAAQ,IAAI,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EAAE,YAAY,CAAC;IACjE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,SAAS,GAAG,MAAM,GAAG,MAAM,CAAC;IACtC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB;AAED,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,OAAmB,EACnB,SAAc,EACd,EAAE,EACF,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,IAAI,EACJ,GAAG,KAAK,EACT,EAAE,mBAAmB,2CAoBrB"}
@@ -0,0 +1,9 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useStableId } from "../hooks/useStableId";
3
+ import styles from "./CyberpunkInput.module.css";
4
+ export function CyberpunkInput({ label, variant = "default", className = "", id, disabled, readOnly, helperText, icon, ...props }) {
5
+ const inputId = useStableId("input", id);
6
+ const isDisabledOrReadOnly = disabled || readOnly;
7
+ return (_jsxs("div", { className: `${styles.cyberInput} ${styles[variant]} ${className}`.trim(), children: [label ? (_jsx("label", { htmlFor: inputId, className: styles.label, children: label })) : null, _jsxs("div", { className: `${styles.inputContainer} ${isDisabledOrReadOnly ? styles.disabledContainer : ""} ${icon ? styles.withIcon : ""}`.trim(), children: [icon ? _jsx("div", { className: styles.icon, children: icon }) : null, _jsx("input", { id: inputId, className: styles.input, disabled: disabled, readOnly: readOnly, ...props })] }), helperText ? _jsx("div", { className: styles.helperText, children: helperText }) : null] }));
8
+ }
9
+ //# sourceMappingURL=CyberpunkInput.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CyberpunkInput.js","sourceRoot":"","sources":["../../src/components/CyberpunkInput.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,MAAM,MAAM,6BAA6B,CAAC;AAUjD,MAAM,UAAU,cAAc,CAAC,EAC7B,KAAK,EACL,OAAO,GAAG,SAAS,EACnB,SAAS,GAAG,EAAE,EACd,EAAE,EACF,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,IAAI,EACJ,GAAG,KAAK,EACY;IACpB,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IACzC,MAAM,oBAAoB,GAAG,QAAQ,IAAI,QAAQ,CAAC;IAElD,OAAO,CACL,eAAK,SAAS,EAAE,GAAG,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,SAAS,EAAE,CAAC,IAAI,EAAE,aAC1E,KAAK,CAAC,CAAC,CAAC,CACP,gBAAO,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,KAAK,YAC7C,KAAK,GACA,CACT,CAAC,CAAC,CAAC,IAAI,EACR,eACE,SAAS,EAAE,GAAG,MAAM,CAAC,cAAc,IAAI,oBAAoB,CAAC,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,aAElI,IAAI,CAAC,CAAC,CAAC,cAAK,SAAS,EAAE,MAAM,CAAC,IAAI,YAAG,IAAI,GAAO,CAAC,CAAC,CAAC,IAAI,EACxD,gBAAO,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,KAAM,KAAK,GAAI,IAC9F,EACL,UAAU,CAAC,CAAC,CAAC,cAAK,SAAS,EAAE,MAAM,CAAC,UAAU,YAAG,UAAU,GAAO,CAAC,CAAC,CAAC,IAAI,IACtE,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,115 @@
1
+ .cyberInput {
2
+ --input-width: 240px;
3
+ --input-font-size: 1rem;
4
+ --input-padding-top: 12px;
5
+ --input-padding-right: 12px;
6
+ --input-padding-bot: 12px;
7
+ --input-padding-left: 12px;
8
+ --focus-border-color: var(--color-accent-primary, var(--text-primary));
9
+ --label-offset-top: -2px;
10
+ --label-offset-left: 12px;
11
+ --label-padding: 1px 8px;
12
+ --label-font-size: 0.85rem;
13
+
14
+ position: relative;
15
+ margin-top: 10px;
16
+ margin-bottom: 1rem;
17
+ font-size: var(--input-font-size);
18
+ }
19
+
20
+ .inputContainer {
21
+ position: relative;
22
+ width: var(--input-width);
23
+ border: 1px solid var(--color-border-default);
24
+ background: var(--color-bg-tile);
25
+ margin-top: 6px;
26
+ }
27
+
28
+ .input {
29
+ width: 100%;
30
+ color: var(--text-primary);
31
+ font-family: var(--font-mono);
32
+ font-size: inherit;
33
+ background: transparent;
34
+ padding: var(--input-padding-top) var(--input-padding-right) var(--input-padding-bot) var(--input-padding-left);
35
+ border: none;
36
+ outline: none;
37
+ box-sizing: border-box;
38
+ }
39
+
40
+ .cyberInput:focus-within .label {
41
+ color: var(--focus-border-color);
42
+ }
43
+
44
+ .cyberInput:focus-within .inputContainer {
45
+ border-color: var(--focus-border-color);
46
+ }
47
+
48
+ .label {
49
+ position: absolute;
50
+ top: var(--label-offset-top);
51
+ left: var(--label-offset-left);
52
+ background: var(--color-bg-tile);
53
+ padding: var(--label-padding);
54
+ font-family: var(--font-mono);
55
+ font-size: var(--label-font-size);
56
+ font-weight: 500;
57
+ color: var(--text-secondary);
58
+ z-index: 1;
59
+ line-height: 1.2;
60
+ transition: background-color var(--transition-normal), color var(--transition-normal);
61
+ }
62
+
63
+ .inputContainer:hover {
64
+ border-color: var(--color-border-hover);
65
+ }
66
+
67
+ .cyberInput:focus-within .inputContainer:hover {
68
+ border-color: var(--focus-border-color);
69
+ }
70
+
71
+ .long {
72
+ --input-width: 360px;
73
+ }
74
+
75
+ .full {
76
+ --input-width: 100%;
77
+ width: 100%;
78
+ display: block;
79
+ }
80
+
81
+ .input:disabled,
82
+ .input[readonly] {
83
+ opacity: 0.7;
84
+ cursor: not-allowed;
85
+ }
86
+
87
+ .disabledContainer {
88
+ background: var(--color-bg-secondary) !important;
89
+ cursor: not-allowed;
90
+ }
91
+
92
+ .helperText {
93
+ margin-top: 0.5rem;
94
+ font-size: 0.75rem;
95
+ color: var(--text-secondary);
96
+ font-family: var(--font-mono);
97
+ }
98
+
99
+ .icon {
100
+ position: absolute;
101
+ right: 12px;
102
+ top: 50%;
103
+ transform: translateY(-50%);
104
+ display: flex;
105
+ align-items: center;
106
+ justify-content: center;
107
+ color: var(--text-secondary);
108
+ pointer-events: none;
109
+ z-index: 1;
110
+ }
111
+
112
+ .withIcon .input {
113
+ padding-right: 44px;
114
+ }
115
+
@@ -0,0 +1,17 @@
1
+ import { InputHTMLAttributes } from "react";
2
+ export interface CyberpunkRadioProps extends InputHTMLAttributes<HTMLInputElement> {
3
+ label?: string;
4
+ }
5
+ export declare function CyberpunkRadio({ label, className, id, ...props }: CyberpunkRadioProps): import("react/jsx-runtime").JSX.Element;
6
+ export interface CyberpunkRadioGroupProps {
7
+ name: string;
8
+ options: {
9
+ value: string;
10
+ label: string;
11
+ }[];
12
+ value?: string;
13
+ onChange?: (value: string) => void;
14
+ className?: string;
15
+ }
16
+ export declare function CyberpunkRadioGroup({ name, options, value, onChange, className, }: CyberpunkRadioGroupProps): import("react/jsx-runtime").JSX.Element;
17
+ //# sourceMappingURL=CyberpunkRadio.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CyberpunkRadio.d.ts","sourceRoot":"","sources":["../../src/components/CyberpunkRadio.tsx"],"names":[],"mappings":"AAAA,OAAc,EAAE,mBAAmB,EAAE,MAAM,OAAO,CAAC;AAKnD,MAAM,WAAW,mBAAoB,SAAQ,mBAAmB,CAAC,gBAAgB,CAAC;IAChF,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,cAAc,CAAC,EAAE,KAAK,EAAE,SAAc,EAAE,EAAE,EAAE,GAAG,KAAK,EAAE,EAAE,mBAAmB,2CAS1F;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,mBAAmB,CAAC,EAClC,IAAI,EACJ,OAAO,EACP,KAAK,EACL,QAAQ,EACR,SAAc,GACf,EAAE,wBAAwB,2CAe1B"}
@@ -0,0 +1,11 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useStableId } from "../hooks/useStableId";
3
+ import styles from "./CyberpunkRadio.module.css";
4
+ export function CyberpunkRadio({ label, className = "", id, ...props }) {
5
+ const inputId = useStableId("radio", id);
6
+ return (_jsxs("label", { htmlFor: inputId, className: `${styles.wrapper} ${className}`.trim(), children: [_jsx("input", { id: inputId, type: "radio", className: styles.radio, ...props }), label ? _jsx("span", { className: styles.label, children: label }) : null] }));
7
+ }
8
+ export function CyberpunkRadioGroup({ name, options, value, onChange, className = "", }) {
9
+ return (_jsx("div", { className: `${styles.radioGroup} ${className}`.trim(), children: options.map((option) => (_jsx(CyberpunkRadio, { name: name, value: option.value, label: option.label, checked: value === option.value, onChange: (event) => onChange?.(event.target.value) }, option.value))) }));
10
+ }
11
+ //# sourceMappingURL=CyberpunkRadio.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CyberpunkRadio.js","sourceRoot":"","sources":["../../src/components/CyberpunkRadio.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,MAAM,MAAM,6BAA6B,CAAC;AAMjD,MAAM,UAAU,cAAc,CAAC,EAAE,KAAK,EAAE,SAAS,GAAG,EAAE,EAAE,EAAE,EAAE,GAAG,KAAK,EAAuB;IACzF,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAEzC,OAAO,CACL,iBAAO,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,MAAM,CAAC,OAAO,IAAI,SAAS,EAAE,CAAC,IAAI,EAAE,aACzE,gBAAO,EAAE,EAAE,OAAO,EAAE,IAAI,EAAC,OAAO,EAAC,SAAS,EAAE,MAAM,CAAC,KAAK,KAAM,KAAK,GAAI,EACtE,KAAK,CAAC,CAAC,CAAC,eAAM,SAAS,EAAE,MAAM,CAAC,KAAK,YAAG,KAAK,GAAQ,CAAC,CAAC,CAAC,IAAI,IACvD,CACT,CAAC;AACJ,CAAC;AAUD,MAAM,UAAU,mBAAmB,CAAC,EAClC,IAAI,EACJ,OAAO,EACP,KAAK,EACL,QAAQ,EACR,SAAS,GAAG,EAAE,GACW;IACzB,OAAO,CACL,cAAK,SAAS,EAAE,GAAG,MAAM,CAAC,UAAU,IAAI,SAAS,EAAE,CAAC,IAAI,EAAE,YACvD,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CACvB,KAAC,cAAc,IAEb,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,MAAM,CAAC,KAAK,EACnB,KAAK,EAAE,MAAM,CAAC,KAAK,EACnB,OAAO,EAAE,KAAK,KAAK,MAAM,CAAC,KAAK,EAC/B,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,IAL9C,MAAM,CAAC,KAAK,CAMjB,CACH,CAAC,GACE,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,64 @@
1
+ .wrapper {
2
+ display: flex;
3
+ align-items: center;
4
+ gap: 0.75rem;
5
+ cursor: pointer;
6
+ user-select: none;
7
+ }
8
+
9
+ .radio {
10
+ width: 28px;
11
+ height: 28px;
12
+ border: 2px solid var(--border);
13
+ border-radius: 50%;
14
+ appearance: none;
15
+ outline: none;
16
+ margin: 0;
17
+ cursor: pointer;
18
+ position: relative;
19
+ background-color: var(--bg-primary);
20
+ transition: all var(--transition-fast);
21
+ }
22
+
23
+ .radio::before {
24
+ content: "";
25
+ width: 16px;
26
+ height: 16px;
27
+ background-color: var(--success);
28
+ border-radius: 50%;
29
+ position: absolute;
30
+ top: 4px;
31
+ left: 4px;
32
+ display: block;
33
+ transform: scale(0);
34
+ transition: 120ms transform ease-in-out;
35
+ }
36
+
37
+ .radio:checked::before {
38
+ transform: scale(1);
39
+ }
40
+
41
+ .radio:hover {
42
+ border-color: var(--success);
43
+ }
44
+
45
+ .radio:focus-visible {
46
+ box-shadow: 0 0 0 2px rgba(0, 255, 136, 0.2);
47
+ }
48
+
49
+ .radio:disabled {
50
+ opacity: 0.5;
51
+ cursor: not-allowed;
52
+ }
53
+
54
+ .label {
55
+ font-size: 0.875rem;
56
+ color: var(--text-primary);
57
+ }
58
+
59
+ .radioGroup {
60
+ display: flex;
61
+ flex-direction: column;
62
+ gap: 0.5rem;
63
+ }
64
+