acidui-core 1.0.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 (194) hide show
  1. package/README.md +127 -0
  2. package/eslint.config.js +23 -0
  3. package/git +0 -0
  4. package/index.html +13 -0
  5. package/package.json +38 -0
  6. package/public/vite.svg +1 -0
  7. package/src/App.css +8 -0
  8. package/src/App.tsx +26 -0
  9. package/src/assets/react.svg +1 -0
  10. package/src/cli/main.mjs +209 -0
  11. package/src/components/AcidAccordion.css +52 -0
  12. package/src/components/AcidAccordion.tsx +72 -0
  13. package/src/components/AcidAlert.css +86 -0
  14. package/src/components/AcidAlert.tsx +52 -0
  15. package/src/components/AcidAnimatedNotification.css +103 -0
  16. package/src/components/AcidAnimatedNotification.tsx +62 -0
  17. package/src/components/AcidAspectRatio.css +16 -0
  18. package/src/components/AcidAspectRatio.tsx +21 -0
  19. package/src/components/AcidAuroraText.css +49 -0
  20. package/src/components/AcidAuroraText.tsx +19 -0
  21. package/src/components/AcidAvatar.css +70 -0
  22. package/src/components/AcidAvatar.tsx +32 -0
  23. package/src/components/AcidBadge.css +54 -0
  24. package/src/components/AcidBadge.tsx +27 -0
  25. package/src/components/AcidBentoGrid.css +98 -0
  26. package/src/components/AcidBentoGrid.tsx +68 -0
  27. package/src/components/AcidBorderBeam.css +27 -0
  28. package/src/components/AcidBorderBeam.tsx +37 -0
  29. package/src/components/AcidBreadcrumb.css +36 -0
  30. package/src/components/AcidBreadcrumb.tsx +35 -0
  31. package/src/components/AcidButton.css +97 -0
  32. package/src/components/AcidButton.tsx +29 -0
  33. package/src/components/AcidCalendar.css +136 -0
  34. package/src/components/AcidCalendar.tsx +144 -0
  35. package/src/components/AcidCard.css +42 -0
  36. package/src/components/AcidCard.tsx +26 -0
  37. package/src/components/AcidCarousel.css +166 -0
  38. package/src/components/AcidCarousel.tsx +168 -0
  39. package/src/components/AcidChart.css +132 -0
  40. package/src/components/AcidChart.tsx +198 -0
  41. package/src/components/AcidCheckbox.css +64 -0
  42. package/src/components/AcidCheckbox.tsx +58 -0
  43. package/src/components/AcidCodeBlock.css +51 -0
  44. package/src/components/AcidCodeBlock.tsx +25 -0
  45. package/src/components/AcidCodeDisplay.css +79 -0
  46. package/src/components/AcidCodeDisplay.tsx +42 -0
  47. package/src/components/AcidCollapsible.css +54 -0
  48. package/src/components/AcidCollapsible.tsx +56 -0
  49. package/src/components/AcidCommand.css +207 -0
  50. package/src/components/AcidCommand.tsx +149 -0
  51. package/src/components/AcidConfettiButton.tsx +37 -0
  52. package/src/components/AcidContextMenu.css +84 -0
  53. package/src/components/AcidContextMenu.tsx +111 -0
  54. package/src/components/AcidCountUp.css +54 -0
  55. package/src/components/AcidCountUp.tsx +66 -0
  56. package/src/components/AcidDialog.css +124 -0
  57. package/src/components/AcidDialog.tsx +89 -0
  58. package/src/components/AcidDivider.css +44 -0
  59. package/src/components/AcidDivider.tsx +28 -0
  60. package/src/components/AcidDock.css +74 -0
  61. package/src/components/AcidDock.tsx +65 -0
  62. package/src/components/AcidDragOrderList.css +45 -0
  63. package/src/components/AcidDragOrderList.tsx +58 -0
  64. package/src/components/AcidDrawer.css +64 -0
  65. package/src/components/AcidDrawer.tsx +55 -0
  66. package/src/components/AcidDropdown.css +103 -0
  67. package/src/components/AcidDropdown.tsx +87 -0
  68. package/src/components/AcidDynamicNavbar.css +273 -0
  69. package/src/components/AcidDynamicNavbar.tsx +157 -0
  70. package/src/components/AcidElectroBorder.css +141 -0
  71. package/src/components/AcidElectroBorder.tsx +53 -0
  72. package/src/components/AcidFloatingNavbar.css +152 -0
  73. package/src/components/AcidFloatingNavbar.tsx +111 -0
  74. package/src/components/AcidForm.css +78 -0
  75. package/src/components/AcidForm.tsx +45 -0
  76. package/src/components/AcidGlassFolder.css +111 -0
  77. package/src/components/AcidGlassFolder.tsx +34 -0
  78. package/src/components/AcidGradientButton.css +99 -0
  79. package/src/components/AcidGradientButton.tsx +37 -0
  80. package/src/components/AcidGridBox.css +61 -0
  81. package/src/components/AcidGridBox.tsx +26 -0
  82. package/src/components/AcidIconBox.css +42 -0
  83. package/src/components/AcidIconBox.tsx +18 -0
  84. package/src/components/AcidInput.css +99 -0
  85. package/src/components/AcidInput.tsx +27 -0
  86. package/src/components/AcidInputOtp.css +57 -0
  87. package/src/components/AcidInputOtp.tsx +102 -0
  88. package/src/components/AcidLabel.css +26 -0
  89. package/src/components/AcidLabel.tsx +18 -0
  90. package/src/components/AcidLayout.css +42 -0
  91. package/src/components/AcidLayout.tsx +35 -0
  92. package/src/components/AcidLink.css +26 -0
  93. package/src/components/AcidLink.tsx +19 -0
  94. package/src/components/AcidMagicCard.css +27 -0
  95. package/src/components/AcidMagicCard.tsx +49 -0
  96. package/src/components/AcidMagicLoader.css +47 -0
  97. package/src/components/AcidMagicLoader.tsx +43 -0
  98. package/src/components/AcidMarquee.css +59 -0
  99. package/src/components/AcidMarquee.tsx +28 -0
  100. package/src/components/AcidMeter.css +118 -0
  101. package/src/components/AcidMeter.tsx +37 -0
  102. package/src/components/AcidNavbar.css +142 -0
  103. package/src/components/AcidNavbar.tsx +111 -0
  104. package/src/components/AcidNavigationMenu.css +47 -0
  105. package/src/components/AcidNavigationMenu.tsx +38 -0
  106. package/src/components/AcidPagination.css +57 -0
  107. package/src/components/AcidPagination.tsx +51 -0
  108. package/src/components/AcidProgress.css +57 -0
  109. package/src/components/AcidProgress.tsx +40 -0
  110. package/src/components/AcidRadioGroup.css +98 -0
  111. package/src/components/AcidRadioGroup.tsx +70 -0
  112. package/src/components/AcidResizable.css +34 -0
  113. package/src/components/AcidResizable.tsx +46 -0
  114. package/src/components/AcidRippleButton.css +34 -0
  115. package/src/components/AcidRippleButton.tsx +61 -0
  116. package/src/components/AcidRippleLoader.css +23 -0
  117. package/src/components/AcidRippleLoader.tsx +40 -0
  118. package/src/components/AcidScrollArea.css +28 -0
  119. package/src/components/AcidScrollArea.tsx +21 -0
  120. package/src/components/AcidScrollList.css +107 -0
  121. package/src/components/AcidScrollList.tsx +58 -0
  122. package/src/components/AcidScrollReveal.tsx +29 -0
  123. package/src/components/AcidScrollStack.css +46 -0
  124. package/src/components/AcidScrollStack.tsx +54 -0
  125. package/src/components/AcidSelect.css +144 -0
  126. package/src/components/AcidSelect.tsx +108 -0
  127. package/src/components/AcidSeparator.css +15 -0
  128. package/src/components/AcidSeparator.tsx +24 -0
  129. package/src/components/AcidSheet.css +99 -0
  130. package/src/components/AcidSheet.tsx +68 -0
  131. package/src/components/AcidShineButton.css +36 -0
  132. package/src/components/AcidShineButton.tsx +24 -0
  133. package/src/components/AcidShinyText.css +22 -0
  134. package/src/components/AcidShinyText.tsx +20 -0
  135. package/src/components/AcidSidebar.css +152 -0
  136. package/src/components/AcidSidebar.tsx +44 -0
  137. package/src/components/AcidSkeleton.css +61 -0
  138. package/src/components/AcidSkeleton.tsx +29 -0
  139. package/src/components/AcidSlider.css +89 -0
  140. package/src/components/AcidSlider.tsx +87 -0
  141. package/src/components/AcidSolidCard.css +55 -0
  142. package/src/components/AcidSolidCard.tsx +35 -0
  143. package/src/components/AcidStackList.css +59 -0
  144. package/src/components/AcidStackList.tsx +38 -0
  145. package/src/components/AcidStepList.css +35 -0
  146. package/src/components/AcidStepList.tsx +31 -0
  147. package/src/components/AcidSwitch.css +48 -0
  148. package/src/components/AcidSwitch.tsx +48 -0
  149. package/src/components/AcidTable.css +60 -0
  150. package/src/components/AcidTable.tsx +44 -0
  151. package/src/components/AcidTabs.css +102 -0
  152. package/src/components/AcidTabs.tsx +47 -0
  153. package/src/components/AcidTerminalCard.css +63 -0
  154. package/src/components/AcidTerminalCard.tsx +35 -0
  155. package/src/components/AcidTextMarquee.css +30 -0
  156. package/src/components/AcidTextMarquee.tsx +37 -0
  157. package/src/components/AcidTextarea.tsx +32 -0
  158. package/src/components/AcidTimeline.css +129 -0
  159. package/src/components/AcidTimeline.tsx +59 -0
  160. package/src/components/AcidToast.css +77 -0
  161. package/src/components/AcidToast.tsx +72 -0
  162. package/src/components/AcidToggle.css +73 -0
  163. package/src/components/AcidToggle.tsx +56 -0
  164. package/src/components/AcidToggleGroup.css +61 -0
  165. package/src/components/AcidToggleGroup.tsx +76 -0
  166. package/src/components/AcidTooltip.css +81 -0
  167. package/src/components/AcidTooltip.tsx +44 -0
  168. package/src/components/AcidTopLoader.css +24 -0
  169. package/src/components/AcidTopLoader.tsx +61 -0
  170. package/src/components/AcidTopStickyBar.css +99 -0
  171. package/src/components/AcidTopStickyBar.tsx +51 -0
  172. package/src/components/AcidTrialButton.css +55 -0
  173. package/src/components/AcidTrialButton.tsx +26 -0
  174. package/src/components/AcidTrustedUsers.css +59 -0
  175. package/src/components/AcidTrustedUsers.tsx +46 -0
  176. package/src/components/AcidTypewriterInput.css +37 -0
  177. package/src/components/AcidTypewriterInput.tsx +31 -0
  178. package/src/components/AcidTypingText.tsx +32 -0
  179. package/src/components/AcidVideoText.css +35 -0
  180. package/src/components/AcidVideoText.tsx +25 -0
  181. package/src/data/sidebar.ts +135 -0
  182. package/src/data/snippets.ts +13 -0
  183. package/src/index.css +136 -0
  184. package/src/main.tsx +13 -0
  185. package/src/pages/Docs.css +604 -0
  186. package/src/pages/Docs.tsx +2347 -0
  187. package/src/pages/Landing.css +342 -0
  188. package/src/pages/Landing.tsx +216 -0
  189. package/src/pages/Library.css +426 -0
  190. package/src/pages/Library.tsx +254 -0
  191. package/tsconfig.app.json +28 -0
  192. package/tsconfig.json +7 -0
  193. package/tsconfig.node.json +26 -0
  194. package/vite.config.ts +7 -0
@@ -0,0 +1,61 @@
1
+ .ac-grid-box {
2
+ position: relative;
3
+ border: 1px solid var(--ac-border-muted);
4
+ background: var(--ac-bg);
5
+ padding: 1.5rem;
6
+ }
7
+
8
+ .ac-grid-inner {
9
+ position: relative;
10
+ z-index: 2;
11
+ }
12
+
13
+ .ac-ch {
14
+ position: absolute;
15
+ width: 9px;
16
+ height: 9px;
17
+ pointer-events: none;
18
+ z-index: 1;
19
+ }
20
+
21
+ .ac-ch::before,
22
+ .ac-ch::after {
23
+ content: '';
24
+ position: absolute;
25
+ background: var(--ac-text-muted);
26
+ }
27
+
28
+ .ac-ch::before {
29
+ top: 4px;
30
+ left: 0;
31
+ width: 9px;
32
+ height: 1px;
33
+ }
34
+
35
+ .ac-ch::after {
36
+ top: 0;
37
+ left: 4px;
38
+ width: 1px;
39
+ height: 9px;
40
+ }
41
+
42
+ /* Positioning */
43
+ .ac-ch-tl {
44
+ top: -5px;
45
+ left: -5px;
46
+ }
47
+
48
+ .ac-ch-tr {
49
+ top: -5px;
50
+ right: -5px;
51
+ }
52
+
53
+ .ac-ch-bl {
54
+ bottom: -5px;
55
+ left: -5px;
56
+ }
57
+
58
+ .ac-ch-br {
59
+ bottom: -5px;
60
+ right: -5px;
61
+ }
@@ -0,0 +1,26 @@
1
+ import React from 'react';
2
+ import clsx from 'clsx';
3
+ import './AcidGridBox.css';
4
+
5
+ export interface AcidGridBoxProps extends React.HTMLAttributes<HTMLDivElement> {
6
+ children?: React.ReactNode;
7
+ showCrosshairs?: boolean;
8
+ }
9
+
10
+ export const AcidGridBox = React.forwardRef<HTMLDivElement, AcidGridBoxProps>(
11
+ ({ className, showCrosshairs = true, children, ...props }, ref) => {
12
+ return (
13
+ <div className={clsx('ac-grid-box', className)} ref={ref} {...props}>
14
+ {showCrosshairs && (
15
+ <>
16
+ <div className="ac-ch ac-ch-tl" />
17
+ <div className="ac-ch ac-ch-tr" />
18
+ <div className="ac-ch ac-ch-bl" />
19
+ <div className="ac-ch ac-ch-br" />
20
+ </>
21
+ )}
22
+ <div className="ac-grid-inner">{children}</div>
23
+ </div>
24
+ );
25
+ }
26
+ );
@@ -0,0 +1,42 @@
1
+ .ac-icon-box-wrapper {
2
+ display: flex;
3
+ align-items: flex-start;
4
+ gap: 1.5rem;
5
+ }
6
+
7
+ .ac-icon-box {
8
+ flex-shrink: 0;
9
+ width: 48px;
10
+ height: 48px;
11
+ display: flex;
12
+ align-items: center;
13
+ justify-content: center;
14
+ background: var(--ac-surface);
15
+ border: 1px solid var(--ac-border-bright);
16
+ border-radius: 4px;
17
+ color: var(--ac-text-primary);
18
+ transition: all 0.2s;
19
+ }
20
+
21
+ .ac-icon-box-wrapper:hover .ac-icon-box {
22
+ border-color: var(--ac-text-secondary);
23
+ }
24
+
25
+ .ac-icon-box-content {
26
+ display: flex;
27
+ flex-direction: column;
28
+ }
29
+
30
+ .ac-icon-box-content strong {
31
+ font-family: var(--font-inter);
32
+ font-weight: 500;
33
+ font-size: 1.1rem;
34
+ margin-bottom: 0.25rem;
35
+ color: var(--ac-text-primary);
36
+ }
37
+
38
+ .ac-icon-box-content p {
39
+ color: var(--ac-text-secondary);
40
+ font-size: 0.9rem;
41
+ line-height: 1.4;
42
+ }
@@ -0,0 +1,18 @@
1
+ import React from 'react';
2
+ import clsx from 'clsx';
3
+ import './AcidIconBox.css';
4
+
5
+ export interface AcidIconBoxProps extends React.HTMLAttributes<HTMLDivElement> {
6
+ icon?: React.ReactNode;
7
+ }
8
+
9
+ export const AcidIconBox = React.forwardRef<HTMLDivElement, AcidIconBoxProps>(
10
+ ({ className, icon, children, ...props }, ref) => {
11
+ return (
12
+ <div className={clsx('ac-icon-box-wrapper', className)} ref={ref} {...props}>
13
+ <div className="ac-icon-box">{icon}</div>
14
+ <div className="ac-icon-box-content">{children}</div>
15
+ </div>
16
+ );
17
+ }
18
+ );
@@ -0,0 +1,99 @@
1
+ .ac-input-container {
2
+ display: flex;
3
+ flex-direction: column;
4
+ gap: 0.5rem;
5
+ width: 100%;
6
+ }
7
+
8
+ .ac-input-label {
9
+ font-size: 0.85rem;
10
+ font-weight: 500;
11
+ text-transform: none;
12
+ color: var(--ac-text-secondary);
13
+ transition: color 0.2s;
14
+ }
15
+
16
+ .ac-input-wrapper {
17
+ position: relative;
18
+ display: flex;
19
+ align-items: center;
20
+ }
21
+
22
+ .ac-input-prefix {
23
+ position: absolute;
24
+ left: 0.75rem;
25
+ color: var(--ac-text-secondary);
26
+ font-family: var(--font-mono);
27
+ pointer-events: none;
28
+ }
29
+
30
+ .ac-input-field {
31
+ width: 100%;
32
+ padding: 0.75rem 1rem;
33
+ background-color: var(--ac-surface);
34
+ border: 1px solid var(--ac-border-muted);
35
+ border-radius: 0;
36
+ color: var(--ac-text-primary);
37
+ font-family: var(--font-mono);
38
+ font-size: 0.875rem;
39
+ outline: none;
40
+ transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
41
+ clip-path: polygon(0 0,
42
+ calc(100% - 8px) 0,
43
+ 100% 8px,
44
+ 100% 100%,
45
+ 8px 100%,
46
+ 0 calc(100% - 8px));
47
+ }
48
+
49
+ .ac-input-field:focus {
50
+ border-color: var(--ac-brand);
51
+ background-color: var(--ac-surface-hover);
52
+ }
53
+
54
+ .ac-input-field::placeholder {
55
+ color: var(--ac-text-muted);
56
+ }
57
+
58
+ /* Variants */
59
+ .ac-input-outline {
60
+ background-color: transparent;
61
+ }
62
+
63
+ .ac-input-filled {
64
+ background-color: var(--ac-surface);
65
+ border-color: transparent;
66
+ }
67
+
68
+ .ac-input-filled:focus {
69
+ background-color: var(--ac-surface-hover);
70
+ border-color: var(--ac-text-primary);
71
+ }
72
+
73
+ .ac-input-terminal {
74
+ padding-left: 2rem;
75
+ background-color: var(--ac-bg);
76
+ border-color: var(--ac-border-muted);
77
+ }
78
+
79
+ .ac-textarea-field {
80
+ min-height: 120px;
81
+ resize: vertical;
82
+ line-height: 1.6;
83
+ }
84
+
85
+ .ac-input-helper {
86
+ font-size: 0.75rem;
87
+ font-family: var(--font-mono);
88
+ color: var(--ac-text-muted);
89
+ margin-top: 0.25rem;
90
+ display: block;
91
+ }
92
+
93
+ .ac-input-helper.error {
94
+ color: var(--ac-brand);
95
+ }
96
+
97
+ .ac-input-error {
98
+ border-color: var(--ac-brand) !important;
99
+ }
@@ -0,0 +1,27 @@
1
+ import React from 'react';
2
+ import clsx from 'clsx';
3
+ import './AcidInput.css';
4
+
5
+ export interface AcidInputProps extends React.InputHTMLAttributes<HTMLInputElement> {
6
+ label?: string;
7
+ variant?: 'outline' | 'filled' | 'terminal';
8
+ }
9
+
10
+ export const AcidInput = React.forwardRef<HTMLInputElement, AcidInputProps>(
11
+ ({ className, label, variant = 'outline', placeholder, ...props }, ref) => {
12
+ return (
13
+ <div className={clsx('ac-input-container', className)}>
14
+ {label && <label className="ac-input-label">{label}</label>}
15
+ <div className="ac-input-wrapper">
16
+ {variant === 'terminal' && <span className="ac-input-prefix">{'>'}</span>}
17
+ <input
18
+ ref={ref}
19
+ className={clsx('ac-input-field', `ac-input-${variant}`)}
20
+ placeholder={placeholder || " "}
21
+ {...props}
22
+ />
23
+ </div>
24
+ </div>
25
+ );
26
+ }
27
+ );
@@ -0,0 +1,57 @@
1
+ .ac-otp-wrapper {
2
+ display: flex;
3
+ flex-direction: column;
4
+ gap: 0.75rem;
5
+ }
6
+
7
+ .ac-otp-label {
8
+ font-family: var(--font-mono);
9
+ font-size: 0.75rem;
10
+ letter-spacing: 0.1em;
11
+ color: var(--ac-text-muted);
12
+ text-transform: uppercase;
13
+ }
14
+
15
+ .ac-otp-inputs {
16
+ display: flex;
17
+ gap: 0.5rem;
18
+ align-items: center;
19
+ }
20
+
21
+ .ac-otp-cell {
22
+ width: 48px;
23
+ height: 56px;
24
+ border: 1px solid var(--ac-border-muted);
25
+ background: var(--ac-surface);
26
+ color: var(--ac-text-primary);
27
+ font-family: var(--font-mono);
28
+ font-size: 1.5rem;
29
+ font-weight: 700;
30
+ text-align: center;
31
+ outline: none;
32
+ transition: all 0.2s ease;
33
+ letter-spacing: 0;
34
+ /* remove browser defaults */
35
+ -moz-appearance: textfield;
36
+ }
37
+
38
+ .ac-otp-cell::-webkit-outer-spin-button,
39
+ .ac-otp-cell::-webkit-inner-spin-button {
40
+ -webkit-appearance: none;
41
+ }
42
+
43
+ .ac-otp-cell:focus {
44
+ border-color: var(--ac-text-primary);
45
+ background: var(--ac-surface-hover);
46
+ box-shadow: 0 0 0 2px color-mix(in srgb, var(--ac-text-primary) 10%, transparent);
47
+ }
48
+
49
+ .ac-otp-cell-filled {
50
+ border-color: var(--ac-brand);
51
+ color: var(--ac-brand);
52
+ }
53
+
54
+ .ac-otp-cell:disabled {
55
+ opacity: 0.4;
56
+ cursor: not-allowed;
57
+ }
@@ -0,0 +1,102 @@
1
+ import { useState, useRef } from 'react';
2
+ import clsx from 'clsx';
3
+ import './AcidInputOtp.css';
4
+
5
+ export interface AcidInputOtpProps {
6
+ length?: number;
7
+ value?: string;
8
+ onChange?: (value: string) => void;
9
+ onComplete?: (value: string) => void;
10
+ disabled?: boolean;
11
+ mask?: boolean;
12
+ className?: string;
13
+ label?: string;
14
+ }
15
+
16
+ export const AcidInputOtp = ({
17
+ length = 6,
18
+ value,
19
+ onChange,
20
+ onComplete,
21
+ disabled = false,
22
+ mask = false,
23
+ className,
24
+ label
25
+ }: AcidInputOtpProps) => {
26
+ const [internalValue, setInternalValue] = useState(value || '');
27
+ const inputRefs = useRef<Array<HTMLInputElement | null>>([]);
28
+ const digits = value !== undefined ? value : internalValue;
29
+
30
+ const getDigit = (index: number) => digits[index] || '';
31
+
32
+ const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>, index: number) => {
33
+ if (e.key === 'Backspace') {
34
+ if (digits[index]) {
35
+ const next = digits.substring(0, index) + digits.substring(index + 1);
36
+ setInternalValue(next);
37
+ onChange?.(next);
38
+ } else if (index > 0) {
39
+ inputRefs.current[index - 1]?.focus();
40
+ const next = digits.substring(0, index - 1) + digits.substring(index);
41
+ setInternalValue(next);
42
+ onChange?.(next);
43
+ }
44
+ } else if (e.key === 'ArrowLeft' && index > 0) {
45
+ inputRefs.current[index - 1]?.focus();
46
+ } else if (e.key === 'ArrowRight' && index < length - 1) {
47
+ inputRefs.current[index + 1]?.focus();
48
+ }
49
+ };
50
+
51
+ const handleInput = (e: React.ChangeEvent<HTMLInputElement>, index: number) => {
52
+ const raw = e.target.value;
53
+ const char = raw.replace(/\D/g, '').slice(-1);
54
+ if (!char) return;
55
+
56
+ const arr = digits.split('');
57
+ arr[index] = char;
58
+ const next = arr.join('').substring(0, length);
59
+ setInternalValue(next);
60
+ onChange?.(next);
61
+
62
+ if (next.length === length) {
63
+ onComplete?.(next);
64
+ } else if (index < length - 1) {
65
+ inputRefs.current[index + 1]?.focus();
66
+ }
67
+ };
68
+
69
+ const handlePaste = (e: React.ClipboardEvent) => {
70
+ e.preventDefault();
71
+ const pasted = e.clipboardData.getData('text').replace(/\D/g, '').substring(0, length);
72
+ setInternalValue(pasted);
73
+ onChange?.(pasted);
74
+ if (pasted.length === length) onComplete?.(pasted);
75
+ const focusIndex = Math.min(pasted.length, length - 1);
76
+ inputRefs.current[focusIndex]?.focus();
77
+ };
78
+
79
+ return (
80
+ <div className={clsx('ac-otp-wrapper', className)}>
81
+ {label && <span className="ac-otp-label">{label}</span>}
82
+ <div className="ac-otp-inputs">
83
+ {Array.from({ length }).map((_, i) => (
84
+ <input
85
+ key={i}
86
+ ref={el => { inputRefs.current[i] = el; }}
87
+ className={clsx('ac-otp-cell', getDigit(i) && 'ac-otp-cell-filled')}
88
+ type={mask ? 'password' : 'text'}
89
+ inputMode="numeric"
90
+ maxLength={1}
91
+ value={mask && getDigit(i) ? '•' : getDigit(i)}
92
+ onChange={(e) => handleInput(e, i)}
93
+ onKeyDown={(e) => handleKeyDown(e, i)}
94
+ onPaste={handlePaste}
95
+ disabled={disabled}
96
+ autoComplete="off"
97
+ />
98
+ ))}
99
+ </div>
100
+ </div>
101
+ );
102
+ };
@@ -0,0 +1,26 @@
1
+ .ac-label {
2
+ display: inline-flex;
3
+ align-items: center;
4
+ gap: 0.5rem;
5
+ font-family: var(--font-mono);
6
+ font-size: 0.7rem;
7
+ font-weight: 700;
8
+ letter-spacing: 0.05em;
9
+ text-transform: uppercase;
10
+ color: var(--ac-text-secondary);
11
+ }
12
+
13
+ .ac-label-dot {
14
+ width: 6px;
15
+ height: 6px;
16
+ border-radius: 50%;
17
+ flex-shrink: 0;
18
+ }
19
+
20
+ .ac-dot-brand {
21
+ background-color: var(--ac-brand);
22
+ }
23
+
24
+ .ac-dot-muted {
25
+ background-color: var(--ac-border-bright);
26
+ }
@@ -0,0 +1,18 @@
1
+ import React from 'react';
2
+ import clsx from 'clsx';
3
+ import './AcidLabel.css';
4
+
5
+ export interface AcidLabelProps extends React.HTMLAttributes<HTMLSpanElement> {
6
+ color?: 'brand' | 'muted';
7
+ }
8
+
9
+ export const AcidLabel = React.forwardRef<HTMLSpanElement, AcidLabelProps>(
10
+ ({ className, color = 'brand', children, ...props }, ref) => {
11
+ return (
12
+ <span className={clsx('ac-label', className)} ref={ref} {...props}>
13
+ <span className={clsx('ac-label-dot', `ac-dot-${color}`)} />
14
+ {children}
15
+ </span>
16
+ );
17
+ }
18
+ );
@@ -0,0 +1,42 @@
1
+ .ac-layout {
2
+ display: flex;
3
+ flex-direction: column;
4
+ min-height: 100vh;
5
+ background: var(--ac-bg);
6
+ }
7
+
8
+ .ac-panel {
9
+ border: 1px solid var(--ac-border-muted);
10
+ background: rgba(0, 0, 0, 0.2);
11
+ display: flex;
12
+ flex-direction: column;
13
+ }
14
+
15
+ .ac-panel-header {
16
+ padding: 0.5rem 1rem;
17
+ border-bottom: 1px solid var(--ac-border-muted);
18
+ display: flex;
19
+ align-items: center;
20
+ gap: 0.75rem;
21
+ background: var(--ac-surface);
22
+ }
23
+
24
+ .ac-panel-dot {
25
+ width: 6px;
26
+ height: 6px;
27
+ background: var(--ac-brand);
28
+ border-radius: 50%;
29
+ }
30
+
31
+ .ac-panel-title {
32
+ font-family: var(--font-mono);
33
+ font-size: 0.75rem;
34
+ letter-spacing: 0.05em;
35
+ color: var(--ac-text-primary);
36
+ text-transform: uppercase;
37
+ }
38
+
39
+ .ac-panel-content {
40
+ flex: 1;
41
+ padding: 1.5rem;
42
+ }
@@ -0,0 +1,35 @@
1
+ import React from 'react';
2
+ import clsx from 'clsx';
3
+ import './AcidLayout.css';
4
+
5
+ export interface AcidLayoutProps extends React.HTMLAttributes<HTMLDivElement> {
6
+ variant?: 'default' | 'industrial';
7
+ }
8
+
9
+ export const AcidLayout = ({ variant = 'default', className, children, ...props }: AcidLayoutProps) => {
10
+ return (
11
+ <div className={clsx('ac-layout', `ac-layout-${variant}`, className)} {...props}>
12
+ {children}
13
+ </div>
14
+ );
15
+ };
16
+
17
+ export interface AcidPanelProps extends React.HTMLAttributes<HTMLDivElement> {
18
+ title?: string;
19
+ }
20
+
21
+ export const AcidPanel = ({ className, children, title, ...props }: AcidPanelProps) => {
22
+ return (
23
+ <div className={clsx('ac-panel', className)} {...props}>
24
+ {title && (
25
+ <div className="ac-panel-header">
26
+ <span className="ac-panel-dot" />
27
+ <span className="ac-panel-title">{title}</span>
28
+ </div>
29
+ )}
30
+ <div className="ac-panel-content">
31
+ {children}
32
+ </div>
33
+ </div>
34
+ );
35
+ };
@@ -0,0 +1,26 @@
1
+ .ac-link {
2
+ display: inline-flex;
3
+ align-items: center;
4
+ gap: 0.5rem;
5
+ font-family: var(--font-mono);
6
+ font-size: 0.8rem;
7
+ font-weight: 700;
8
+ color: var(--ac-text-primary);
9
+ text-decoration: none;
10
+ text-transform: uppercase;
11
+ letter-spacing: 0.05em;
12
+ transition: color 0.2s ease;
13
+ cursor: pointer;
14
+ }
15
+
16
+ .ac-link:hover {
17
+ color: var(--ac-brand);
18
+ }
19
+
20
+ .ac-link-arrow {
21
+ transition: transform 0.2s ease;
22
+ }
23
+
24
+ .ac-link:hover .ac-link-arrow {
25
+ transform: translateX(4px);
26
+ }
@@ -0,0 +1,19 @@
1
+ import React from 'react';
2
+ import clsx from 'clsx';
3
+ import { ArrowRight } from 'lucide-react';
4
+ import './AcidLink.css';
5
+
6
+ export interface AcidLinkProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> {
7
+ children: React.ReactNode;
8
+ }
9
+
10
+ export const AcidLink = React.forwardRef<HTMLAnchorElement, AcidLinkProps>(
11
+ ({ className, children, ...props }, ref) => {
12
+ return (
13
+ <a className={clsx('ac-link', className)} ref={ref} {...props}>
14
+ <span className="ac-link-text">{children}</span>
15
+ <ArrowRight size={14} className="ac-link-arrow" />
16
+ </a>
17
+ );
18
+ }
19
+ );
@@ -0,0 +1,27 @@
1
+ .ac-magic-card {
2
+ position: relative;
3
+ background: var(--ac-surface);
4
+ border: 1px solid var(--ac-border-muted);
5
+ border-radius: 12px;
6
+ overflow: hidden;
7
+ transition: border-color 0.3s;
8
+ }
9
+
10
+ .ac-magic-card:hover {
11
+ border-color: var(--ac-border-bright);
12
+ }
13
+
14
+ .ac-magic-glow {
15
+ position: absolute;
16
+ inset: 0;
17
+ pointer-events: none;
18
+ z-index: 0;
19
+ transition: opacity 0.5s;
20
+ }
21
+
22
+ .ac-magic-content {
23
+ position: relative;
24
+ z-index: 1;
25
+ height: 100%;
26
+ width: 100%;
27
+ }
@@ -0,0 +1,49 @@
1
+ import React, { useRef, useState } from 'react';
2
+ import clsx from 'clsx';
3
+ import './AcidMagicCard.css';
4
+
5
+ export interface AcidMagicCardProps {
6
+ children: React.ReactNode;
7
+ className?: string;
8
+ glowColor?: string;
9
+ style?: React.CSSProperties;
10
+ }
11
+
12
+ export const AcidMagicCard = ({
13
+ children,
14
+ className,
15
+ glowColor = 'rgba(244, 67, 54, 0.15)',
16
+ style
17
+ }: AcidMagicCardProps) => {
18
+ const cardRef = useRef<HTMLDivElement>(null);
19
+ const [mousePos, setMousePos] = useState({ x: -1000, y: -1000 });
20
+
21
+ const handleMouseMove = (e: React.MouseEvent) => {
22
+ if (!cardRef.current) return;
23
+ const rect = cardRef.current.getBoundingClientRect();
24
+ setMousePos({
25
+ x: e.clientX - rect.left,
26
+ y: e.clientY - rect.top
27
+ });
28
+ };
29
+
30
+ return (
31
+ <div
32
+ ref={cardRef}
33
+ className={clsx('ac-magic-card', className)}
34
+ onMouseMove={handleMouseMove}
35
+ onMouseLeave={() => setMousePos({ x: -1000, y: -1000 })}
36
+ style={style}
37
+ >
38
+ <div
39
+ className="ac-magic-glow"
40
+ style={{
41
+ background: `radial-gradient(400px circle at ${mousePos.x}px ${mousePos.y}px, ${glowColor}, transparent 40%)`
42
+ }}
43
+ />
44
+ <div className="ac-magic-content">
45
+ {children}
46
+ </div>
47
+ </div>
48
+ );
49
+ };