@oalacea/chaosui 0.4.0 → 0.5.1

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 (178) hide show
  1. package/buttons/cta-brutal/css/cta-brutal.module.css +175 -0
  2. package/buttons/cta-brutal/css/index.tsx +78 -0
  3. package/buttons/cta-brutal/tailwind/index.tsx +85 -0
  4. package/buttons/dead-button/css/dead-button.module.css +216 -0
  5. package/buttons/dead-button/css/index.tsx +47 -0
  6. package/buttons/dead-button/tailwind/index.tsx +90 -0
  7. package/buttons/deeper-button/css/deeper-button.module.css +141 -0
  8. package/buttons/deeper-button/css/index.tsx +62 -0
  9. package/buttons/deeper-button/tailwind/index.tsx +78 -0
  10. package/buttons/dual-choice/css/dual-choice.module.css +176 -0
  11. package/buttons/dual-choice/css/index.tsx +56 -0
  12. package/buttons/dual-choice/tailwind/index.tsx +89 -0
  13. package/buttons/tension-bar/css/index.tsx +96 -0
  14. package/buttons/tension-bar/css/tension-bar.module.css +204 -0
  15. package/buttons/tension-bar/tailwind/index.tsx +122 -0
  16. package/decorative/inscription/css/index.tsx +66 -0
  17. package/decorative/inscription/css/inscription.module.css +160 -0
  18. package/decorative/inscription/tailwind/index.tsx +91 -0
  19. package/decorative/ornaments/css/index.tsx +136 -0
  20. package/decorative/ornaments/css/ornaments.module.css +144 -0
  21. package/decorative/ornaments/tailwind/index.tsx +122 -0
  22. package/decorative/rune-symbols/css/index.tsx +116 -0
  23. package/decorative/rune-symbols/css/rune-symbols.module.css +116 -0
  24. package/decorative/rune-symbols/tailwind/index.tsx +108 -0
  25. package/decorative/sheet-music/css/index.tsx +144 -0
  26. package/decorative/sheet-music/css/sheet-music.module.css +152 -0
  27. package/decorative/sheet-music/tailwind/index.tsx +111 -0
  28. package/layout/horizontal-scroll/css/horizontal-scroll.module.css +93 -0
  29. package/layout/horizontal-scroll/css/index.tsx +114 -0
  30. package/layout/horizontal-scroll/tailwind/index.tsx +108 -0
  31. package/layout/spec-grid/css/index.tsx +103 -0
  32. package/layout/spec-grid/css/spec-grid.module.css +125 -0
  33. package/layout/spec-grid/tailwind/index.tsx +91 -0
  34. package/layout/tower-pricing/css/index.tsx +91 -0
  35. package/layout/tower-pricing/css/tower-pricing.module.css +177 -0
  36. package/layout/tower-pricing/tailwind/index.tsx +106 -0
  37. package/layout/tracklist/css/index.tsx +96 -0
  38. package/layout/tracklist/css/tracklist.module.css +141 -0
  39. package/layout/tracklist/tailwind/index.tsx +92 -0
  40. package/layout/void-frame/css/index.tsx +60 -0
  41. package/layout/void-frame/css/void-frame.module.css +141 -0
  42. package/layout/void-frame/tailwind/index.tsx +64 -0
  43. package/navigation/brutal-nav/css/brutal-nav.module.css +178 -0
  44. package/navigation/brutal-nav/css/index.tsx +80 -0
  45. package/navigation/brutal-nav/tailwind/index.tsx +95 -0
  46. package/navigation/progress-dots/css/index.tsx +60 -0
  47. package/navigation/progress-dots/css/progress-dots.module.css +152 -0
  48. package/navigation/progress-dots/tailwind/index.tsx +105 -0
  49. package/navigation/scattered-nav/css/index.tsx +59 -0
  50. package/navigation/scattered-nav/css/scattered-nav.module.css +121 -0
  51. package/navigation/scattered-nav/tailwind/index.tsx +77 -0
  52. package/navigation/scroll-indicator/css/index.tsx +72 -0
  53. package/navigation/scroll-indicator/css/scroll-indicator.module.css +129 -0
  54. package/navigation/scroll-indicator/tailwind/index.tsx +107 -0
  55. package/navigation/vertical-nav/css/index.tsx +69 -0
  56. package/navigation/vertical-nav/css/vertical-nav.module.css +117 -0
  57. package/navigation/vertical-nav/tailwind/index.tsx +91 -0
  58. package/package.json +8 -33
  59. package/text/ascii-art/css/ascii-art.module.css +173 -0
  60. package/text/ascii-art/css/index.tsx +116 -0
  61. package/text/ascii-art/tailwind/index.tsx +124 -0
  62. package/text/blood-drip/css/blood-drip.module.css +142 -0
  63. package/text/blood-drip/css/index.tsx +113 -0
  64. package/text/blood-drip/tailwind/index.tsx +133 -0
  65. package/text/char-glitch/css/char-glitch.module.css +124 -0
  66. package/text/char-glitch/css/index.tsx +153 -0
  67. package/text/char-glitch/tailwind/index.tsx +126 -0
  68. package/text/countdown-display/css/countdown-display.module.css +179 -0
  69. package/text/countdown-display/css/index.tsx +190 -0
  70. package/text/countdown-display/tailwind/index.tsx +155 -0
  71. package/text/giant-layers/css/giant-layers.module.css +156 -0
  72. package/text/giant-layers/css/index.tsx +97 -0
  73. package/text/giant-layers/tailwind/index.tsx +111 -0
  74. package/text/reveal-text/css/index.tsx +180 -0
  75. package/text/reveal-text/css/reveal-text.module.css +129 -0
  76. package/text/reveal-text/tailwind/index.tsx +135 -0
  77. package/text/rotate-text/css/index.tsx +139 -0
  78. package/text/rotate-text/css/rotate-text.module.css +162 -0
  79. package/text/rotate-text/tailwind/index.tsx +127 -0
  80. package/text/strike-reveal/css/index.tsx +124 -0
  81. package/text/strike-reveal/css/strike-reveal.module.css +139 -0
  82. package/text/strike-reveal/tailwind/index.tsx +138 -0
  83. package/text/terminal-output/css/index.tsx +179 -0
  84. package/text/terminal-output/css/terminal-output.module.css +203 -0
  85. package/text/terminal-output/tailwind/index.tsx +174 -0
  86. package/text/typing-text/css/index.tsx +115 -0
  87. package/text/typing-text/css/typing-text.module.css +84 -0
  88. package/text/typing-text/tailwind/index.tsx +126 -0
  89. package/bin/cli.js +0 -278
  90. package/components/backgrounds/light-beams/index.tsx +0 -80
  91. package/components/backgrounds/light-beams/light-beams.module.css +0 -27
  92. package/components/navigation/hexagon-menu/css/hexagon-menu.module.css +0 -55
  93. package/components/navigation/hexagon-menu/css/index.tsx +0 -35
  94. package/components/navigation/hexagon-menu/tailwind/index.tsx +0 -53
  95. /package/{components/backgrounds → backgrounds}/glow-orbs/glow-orbs.module.css +0 -0
  96. /package/{components/backgrounds → backgrounds}/glow-orbs/index.tsx +0 -0
  97. /package/{components/backgrounds → backgrounds}/noise-canvas/index.tsx +0 -0
  98. /package/{components/backgrounds → backgrounds}/noise-canvas/noise-canvas.module.css +0 -0
  99. /package/{components/backgrounds → backgrounds}/particle-field/index.tsx +0 -0
  100. /package/{components/backgrounds → backgrounds}/particle-field/particle-field.module.css +0 -0
  101. /package/{components/buttons → buttons}/chaos-button/chaos-button.module.css +0 -0
  102. /package/{components/buttons → buttons}/chaos-button/index.tsx +0 -0
  103. /package/{components/buttons → buttons}/glitch-button/glitch-button.module.css +0 -0
  104. /package/{components/buttons → buttons}/glitch-button/index.tsx +0 -0
  105. /package/{components/chaos-vars.css → chaos-vars.css} +0 -0
  106. /package/{components/cyber → cyber}/cyber-avatar/css/cyber-avatar.module.css +0 -0
  107. /package/{components/cyber → cyber}/cyber-avatar/css/index.tsx +0 -0
  108. /package/{components/cyber → cyber}/cyber-avatar/tailwind/index.tsx +0 -0
  109. /package/{components/cyber → cyber}/cyber-input/css/cyber-input.module.css +0 -0
  110. /package/{components/cyber → cyber}/cyber-input/css/index.tsx +0 -0
  111. /package/{components/cyber → cyber}/cyber-input/tailwind/index.tsx +0 -0
  112. /package/{components/cyber → cyber}/cyber-loader/css/cyber-loader.module.css +0 -0
  113. /package/{components/cyber → cyber}/cyber-loader/css/index.tsx +0 -0
  114. /package/{components/cyber → cyber}/cyber-loader/tailwind/index.tsx +0 -0
  115. /package/{components/cyber → cyber}/cyber-modal/css/cyber-modal.module.css +0 -0
  116. /package/{components/cyber → cyber}/cyber-modal/css/index.tsx +0 -0
  117. /package/{components/cyber → cyber}/cyber-modal/tailwind/index.tsx +0 -0
  118. /package/{components/cyber → cyber}/cyber-slider/css/cyber-slider.module.css +0 -0
  119. /package/{components/cyber → cyber}/cyber-slider/css/index.tsx +0 -0
  120. /package/{components/cyber → cyber}/cyber-slider/tailwind/index.tsx +0 -0
  121. /package/{components/cyber → cyber}/cyber-tooltip/css/cyber-tooltip.module.css +0 -0
  122. /package/{components/cyber → cyber}/cyber-tooltip/css/index.tsx +0 -0
  123. /package/{components/cyber → cyber}/cyber-tooltip/tailwind/index.tsx +0 -0
  124. /package/{components/effects → effects}/cursor-follower/cursor-follower.module.css +0 -0
  125. /package/{components/effects → effects}/cursor-follower/index.tsx +0 -0
  126. /package/{components/effects → effects}/glitch-image/css/glitch-image.module.css +0 -0
  127. /package/{components/effects → effects}/glitch-image/css/index.tsx +0 -0
  128. /package/{components/effects → effects}/glitch-image/tailwind/index.tsx +0 -0
  129. /package/{components/effects → effects}/glowing-border/css/glowing-border.module.css +0 -0
  130. /package/{components/effects → effects}/glowing-border/css/index.tsx +0 -0
  131. /package/{components/effects → effects}/glowing-border/tailwind/index.tsx +0 -0
  132. /package/{components/effects → effects}/screen-distortion/index.tsx +0 -0
  133. /package/{components/effects → effects}/screen-distortion/screen-distortion.module.css +0 -0
  134. /package/{components/effects → effects}/warning-tape/index.tsx +0 -0
  135. /package/{components/effects → effects}/warning-tape/warning-tape.module.css +0 -0
  136. /package/{components/layout → layout}/data-grid/css/data-grid.module.css +0 -0
  137. /package/{components/layout → layout}/data-grid/css/index.tsx +0 -0
  138. /package/{components/layout → layout}/data-grid/tailwind/index.tsx +0 -0
  139. /package/{components/layout → layout}/hologram-card/css/hologram-card.module.css +0 -0
  140. /package/{components/layout → layout}/hologram-card/css/index.tsx +0 -0
  141. /package/{components/layout → layout}/hologram-card/tailwind/index.tsx +0 -0
  142. /package/{components/neon → neon}/neon-alert/css/index.tsx +0 -0
  143. /package/{components/neon → neon}/neon-alert/css/neon-alert.module.css +0 -0
  144. /package/{components/neon → neon}/neon-alert/tailwind/index.tsx +0 -0
  145. /package/{components/neon → neon}/neon-badge/css/index.tsx +0 -0
  146. /package/{components/neon → neon}/neon-badge/css/neon-badge.module.css +0 -0
  147. /package/{components/neon → neon}/neon-badge/tailwind/index.tsx +0 -0
  148. /package/{components/neon → neon}/neon-button/css/index.tsx +0 -0
  149. /package/{components/neon → neon}/neon-button/css/neon-button.module.css +0 -0
  150. /package/{components/neon → neon}/neon-button/tailwind/index.tsx +0 -0
  151. /package/{components/neon → neon}/neon-divider/css/index.tsx +0 -0
  152. /package/{components/neon → neon}/neon-divider/css/neon-divider.module.css +0 -0
  153. /package/{components/neon → neon}/neon-divider/tailwind/index.tsx +0 -0
  154. /package/{components/neon → neon}/neon-progress/css/index.tsx +0 -0
  155. /package/{components/neon → neon}/neon-progress/css/neon-progress.module.css +0 -0
  156. /package/{components/neon → neon}/neon-progress/tailwind/index.tsx +0 -0
  157. /package/{components/neon → neon}/neon-tabs/css/index.tsx +0 -0
  158. /package/{components/neon → neon}/neon-tabs/css/neon-tabs.module.css +0 -0
  159. /package/{components/neon → neon}/neon-tabs/tailwind/index.tsx +0 -0
  160. /package/{components/neon → neon}/neon-toggle/css/index.tsx +0 -0
  161. /package/{components/neon → neon}/neon-toggle/css/neon-toggle.module.css +0 -0
  162. /package/{components/neon → neon}/neon-toggle/tailwind/index.tsx +0 -0
  163. /package/{components/overlays → overlays}/noise-overlay/index.tsx +0 -0
  164. /package/{components/overlays → overlays}/noise-overlay/noise-overlay.module.css +0 -0
  165. /package/{components/overlays → overlays}/scanlines/index.tsx +0 -0
  166. /package/{components/overlays → overlays}/scanlines/scanlines.module.css +0 -0
  167. /package/{components/overlays → overlays}/static-flicker/index.tsx +0 -0
  168. /package/{components/overlays → overlays}/static-flicker/static-flicker.module.css +0 -0
  169. /package/{components/overlays → overlays}/vignette/index.tsx +0 -0
  170. /package/{components/overlays → overlays}/vignette/vignette.module.css +0 -0
  171. /package/{components/text → text}/distortion-text/distortion-text.module.css +0 -0
  172. /package/{components/text → text}/distortion-text/index.tsx +0 -0
  173. /package/{components/text → text}/falling-text/falling-text.module.css +0 -0
  174. /package/{components/text → text}/falling-text/index.tsx +0 -0
  175. /package/{components/text → text}/flicker-text/flicker-text.module.css +0 -0
  176. /package/{components/text → text}/flicker-text/index.tsx +0 -0
  177. /package/{components/text → text}/glitch-text/glitch-text.module.css +0 -0
  178. /package/{components/text → text}/glitch-text/index.tsx +0 -0
@@ -0,0 +1,129 @@
1
+ /* scroll-indicator - Indicateur de scroll vertical avec texte */
2
+ .container {
3
+ position: fixed;
4
+ right: 0;
5
+ top: 0;
6
+ bottom: 0;
7
+ width: 60px;
8
+ display: flex;
9
+ align-items: center;
10
+ justify-content: center;
11
+ z-index: 100;
12
+ }
13
+
14
+ .inner {
15
+ display: flex;
16
+ flex-direction: column;
17
+ align-items: center;
18
+ gap: 1rem;
19
+ }
20
+
21
+ .track {
22
+ width: 2px;
23
+ height: 100px;
24
+ background: var(--chaos-iron, #2a2820);
25
+ position: relative;
26
+ border-radius: 1px;
27
+ }
28
+
29
+ .thumb {
30
+ width: 6px;
31
+ height: 20px;
32
+ background: var(--chaos-gold, #c9a227);
33
+ position: absolute;
34
+ left: -2px;
35
+ top: 0;
36
+ border-radius: 3px;
37
+ transition: top 0.3s ease-out;
38
+ box-shadow: 0 0 10px rgba(201, 162, 39, 0.3);
39
+ }
40
+
41
+ .text {
42
+ writing-mode: vertical-rl;
43
+ text-orientation: mixed;
44
+ font-family: var(--chaos-font-serif, 'Cinzel', serif);
45
+ font-size: 0.5rem;
46
+ letter-spacing: 0.4em;
47
+ color: var(--chaos-bone-dark, #9a8b6f);
48
+ transform: rotate(180deg);
49
+ text-transform: uppercase;
50
+ }
51
+
52
+ /* Animated arrow */
53
+ .arrow {
54
+ animation: bounce 2s ease-in-out infinite;
55
+ color: var(--chaos-gold, #c9a227);
56
+ font-size: 0.8rem;
57
+ }
58
+
59
+ @keyframes bounce {
60
+ 0%, 100% { transform: translateY(0); opacity: 1; }
61
+ 50% { transform: translateY(5px); opacity: 0.5; }
62
+ }
63
+
64
+ /* Variant: blood/red */
65
+ .variantBlood .track {
66
+ background: rgba(255, 0, 64, 0.2);
67
+ }
68
+
69
+ .variantBlood .thumb {
70
+ background: var(--chaos-blood, #ff0040);
71
+ box-shadow: 0 0 10px rgba(255, 0, 64, 0.5);
72
+ }
73
+
74
+ .variantBlood .text {
75
+ color: var(--chaos-bone-dark, #666);
76
+ }
77
+
78
+ .variantBlood .arrow {
79
+ color: var(--chaos-blood, #ff0040);
80
+ }
81
+
82
+ /* Variant: minimal */
83
+ .variantMinimal .track {
84
+ width: 1px;
85
+ height: 60px;
86
+ }
87
+
88
+ .variantMinimal .thumb {
89
+ width: 3px;
90
+ height: 10px;
91
+ left: -1px;
92
+ }
93
+
94
+ .variantMinimal .text {
95
+ display: none;
96
+ }
97
+
98
+ /* Left position */
99
+ .positionLeft {
100
+ left: 0;
101
+ right: auto;
102
+ }
103
+
104
+ .positionLeft .text {
105
+ transform: rotate(0deg);
106
+ }
107
+
108
+ /* Percentage display */
109
+ .percentage {
110
+ font-family: var(--chaos-font-mono, monospace);
111
+ font-size: 0.6rem;
112
+ color: var(--chaos-gold, #c9a227);
113
+ margin-top: 0.5rem;
114
+ }
115
+
116
+ .variantBlood .percentage {
117
+ color: var(--chaos-blood, #ff0040);
118
+ }
119
+
120
+ /* Pulse effect on scroll */
121
+ .thumbPulsing {
122
+ animation: thumbPulse 0.5s ease-out;
123
+ }
124
+
125
+ @keyframes thumbPulse {
126
+ 0% { box-shadow: 0 0 10px currentColor; }
127
+ 50% { box-shadow: 0 0 20px currentColor, 0 0 30px currentColor; }
128
+ 100% { box-shadow: 0 0 10px currentColor; }
129
+ }
@@ -0,0 +1,107 @@
1
+ 'use client';
2
+
3
+ import { forwardRef, HTMLAttributes, useEffect, useState } from 'react';
4
+
5
+ export interface ScrollIndicatorProps extends HTMLAttributes<HTMLDivElement> {
6
+ text?: string;
7
+ showArrow?: boolean;
8
+ showPercentage?: boolean;
9
+ variant?: 'default' | 'blood' | 'minimal';
10
+ position?: 'right' | 'left';
11
+ trackHeight?: number;
12
+ }
13
+
14
+ const variantStyles: Record<string, { track: string; thumb: string; text: string }> = {
15
+ default: {
16
+ track: 'bg-stone-700',
17
+ thumb: 'bg-amber-500 shadow-[0_0_10px_rgba(201,162,39,0.3)]',
18
+ text: 'text-stone-500',
19
+ },
20
+ blood: {
21
+ track: 'bg-red-500/20',
22
+ thumb: 'bg-red-500 shadow-[0_0_10px_rgba(255,0,64,0.5)]',
23
+ text: 'text-gray-500',
24
+ },
25
+ minimal: {
26
+ track: 'bg-stone-700',
27
+ thumb: 'bg-amber-500',
28
+ text: 'text-stone-500',
29
+ },
30
+ };
31
+
32
+ export const ScrollIndicator = forwardRef<HTMLDivElement, ScrollIndicatorProps>(
33
+ ({ text = 'SCROLL', showArrow = false, showPercentage = false, variant = 'default', position = 'right', trackHeight = 100, className, ...props }, ref) => {
34
+ const [scrollProgress, setScrollProgress] = useState(0);
35
+
36
+ useEffect(() => {
37
+ const handleScroll = () => {
38
+ const scrollTop = window.scrollY;
39
+ const docHeight = document.documentElement.scrollHeight - window.innerHeight;
40
+ const progress = docHeight > 0 ? (scrollTop / docHeight) * 100 : 0;
41
+ setScrollProgress(Math.min(100, Math.max(0, progress)));
42
+ };
43
+
44
+ window.addEventListener('scroll', handleScroll, { passive: true });
45
+ handleScroll();
46
+
47
+ return () => window.removeEventListener('scroll', handleScroll);
48
+ }, []);
49
+
50
+ const colors = variantStyles[variant];
51
+ const thumbTop = (scrollProgress / 100) * (trackHeight - 20);
52
+ const isMinimal = variant === 'minimal';
53
+
54
+ return (
55
+ <div
56
+ ref={ref}
57
+ className={`
58
+ fixed top-0 bottom-0 w-[60px] flex items-center justify-center z-50
59
+ ${position === 'left' ? 'left-0' : 'right-0'}
60
+ ${className || ''}
61
+ `}
62
+ {...props}
63
+ >
64
+ <div className="flex flex-col items-center gap-4">
65
+ {showArrow && (
66
+ <span className={`animate-bounce ${variant === 'blood' ? 'text-red-500' : 'text-amber-500'}`}>
67
+
68
+ </span>
69
+ )}
70
+
71
+ <div
72
+ className={`relative rounded-sm ${isMinimal ? 'w-px' : 'w-0.5'} ${colors.track}`}
73
+ style={{ height: trackHeight }}
74
+ >
75
+ <div
76
+ className={`
77
+ absolute rounded transition-all duration-300
78
+ ${isMinimal ? 'w-[3px] h-[10px] -left-px' : 'w-1.5 h-5 -left-0.5'}
79
+ ${colors.thumb}
80
+ `}
81
+ style={{ top: thumbTop }}
82
+ />
83
+ </div>
84
+
85
+ {text && !isMinimal && (
86
+ <span className={`
87
+ [writing-mode:vertical-rl] text-[0.5rem] tracking-[0.4em] uppercase font-serif
88
+ ${position === 'left' ? '' : 'rotate-180'}
89
+ ${colors.text}
90
+ `}>
91
+ {text}
92
+ </span>
93
+ )}
94
+
95
+ {showPercentage && (
96
+ <span className={`font-mono text-[0.6rem] ${variant === 'blood' ? 'text-red-500' : 'text-amber-500'}`}>
97
+ {Math.round(scrollProgress)}%
98
+ </span>
99
+ )}
100
+ </div>
101
+ </div>
102
+ );
103
+ }
104
+ );
105
+
106
+ ScrollIndicator.displayName = 'ScrollIndicator';
107
+ export default ScrollIndicator;
@@ -0,0 +1,69 @@
1
+ 'use client';
2
+
3
+ import { forwardRef, HTMLAttributes, ReactNode } from 'react';
4
+ import styles from './vertical-nav.module.css';
5
+
6
+ export interface VerticalNavItemProps {
7
+ href?: string;
8
+ glyph: string;
9
+ label?: string;
10
+ active?: boolean;
11
+ onClick?: () => void;
12
+ }
13
+
14
+ export interface VerticalNavProps extends HTMLAttributes<HTMLElement> {
15
+ items?: VerticalNavItemProps[];
16
+ runeTop?: string;
17
+ runeBottom?: string;
18
+ variant?: 'default' | 'dark';
19
+ size?: 'default' | 'compact';
20
+ children?: ReactNode;
21
+ }
22
+
23
+ export const VerticalNavItem = forwardRef<HTMLAnchorElement, VerticalNavItemProps>(
24
+ ({ href, glyph, label, active, onClick, ...props }, ref) => {
25
+ const classes = [styles.glyph, active && styles.glyphActive].filter(Boolean).join(' ');
26
+
27
+ if (href) {
28
+ return (
29
+ <a ref={ref} href={href} className={classes} data-label={label} onClick={onClick} {...props}>
30
+ {glyph}
31
+ </a>
32
+ );
33
+ }
34
+ return (
35
+ <button className={classes} data-label={label} onClick={onClick} {...props}>
36
+ {glyph}
37
+ </button>
38
+ );
39
+ }
40
+ );
41
+
42
+ VerticalNavItem.displayName = 'VerticalNavItem';
43
+
44
+ export const VerticalNav = forwardRef<HTMLElement, VerticalNavProps>(
45
+ ({ items, runeTop = 'ᛟ', runeBottom = 'ᛞ', variant = 'default', size = 'default', children, className, ...props }, ref) => {
46
+ const classes = [
47
+ styles.nav,
48
+ variant === 'dark' && styles.variantDark,
49
+ size === 'compact' && styles.sizeCompact,
50
+ className,
51
+ ].filter(Boolean).join(' ');
52
+
53
+ return (
54
+ <nav ref={ref} className={classes} {...props}>
55
+ <div className={styles.rune}>{runeTop}</div>
56
+ <div className={styles.items}>
57
+ {items?.map((item, i) => (
58
+ <VerticalNavItem key={i} {...item} />
59
+ ))}
60
+ {children}
61
+ </div>
62
+ <div className={styles.rune}>{runeBottom}</div>
63
+ </nav>
64
+ );
65
+ }
66
+ );
67
+
68
+ VerticalNav.displayName = 'VerticalNav';
69
+ export default VerticalNav;
@@ -0,0 +1,117 @@
1
+ /* vertical-nav - Nav latérale avec glyphes/runes */
2
+ .nav {
3
+ position: fixed;
4
+ left: 0;
5
+ top: 0;
6
+ bottom: 0;
7
+ width: 80px;
8
+ background: linear-gradient(to right, var(--chaos-obsidian, #121210) 0%, transparent 100%);
9
+ border-right: 1px solid var(--chaos-iron, #2a2820);
10
+ display: flex;
11
+ flex-direction: column;
12
+ align-items: center;
13
+ justify-content: space-between;
14
+ padding: 2rem 0;
15
+ z-index: 100;
16
+ }
17
+
18
+ .rune {
19
+ font-size: 1.5rem;
20
+ color: var(--chaos-gold-dark, #8b7017);
21
+ opacity: 0.5;
22
+ animation: runeGlow 4s ease-in-out infinite;
23
+ }
24
+
25
+ @keyframes runeGlow {
26
+ 0%, 100% { opacity: 0.3; text-shadow: none; }
27
+ 50% { opacity: 0.8; text-shadow: 0 0 10px var(--chaos-gold, #c9a227); }
28
+ }
29
+
30
+ .items {
31
+ display: flex;
32
+ flex-direction: column;
33
+ gap: 3rem;
34
+ }
35
+
36
+ .glyph {
37
+ width: 40px;
38
+ height: 40px;
39
+ display: flex;
40
+ align-items: center;
41
+ justify-content: center;
42
+ font-family: var(--chaos-font-display, 'Cinzel Decorative', serif);
43
+ font-size: 1rem;
44
+ color: var(--chaos-bone-dark, #9a8b6f);
45
+ text-decoration: none;
46
+ border: 1px solid var(--chaos-iron, #2a2820);
47
+ position: relative;
48
+ transition: all 0.4s;
49
+ }
50
+
51
+ .glyph::before {
52
+ content: attr(data-label);
53
+ position: absolute;
54
+ left: 60px;
55
+ font-family: var(--chaos-font-serif, 'Cinzel', serif);
56
+ font-size: 0.6rem;
57
+ letter-spacing: 0.3em;
58
+ color: var(--chaos-bone-dark, #9a8b6f);
59
+ opacity: 0;
60
+ transform: translateX(-10px);
61
+ transition: all 0.3s;
62
+ white-space: nowrap;
63
+ text-transform: uppercase;
64
+ }
65
+
66
+ .glyph:hover {
67
+ color: var(--chaos-gold, #c9a227);
68
+ border-color: var(--chaos-gold, #c9a227);
69
+ background: rgba(201, 162, 39, 0.1);
70
+ }
71
+
72
+ .glyph:hover::before {
73
+ opacity: 1;
74
+ transform: translateX(0);
75
+ }
76
+
77
+ .glyphActive {
78
+ color: var(--chaos-gold, #c9a227);
79
+ border-color: var(--chaos-gold, #c9a227);
80
+ box-shadow: 0 0 15px rgba(201, 162, 39, 0.3);
81
+ }
82
+
83
+ /* Variants */
84
+ .variantDark {
85
+ background: linear-gradient(to right, var(--chaos-void, #0a0a0a) 0%, transparent 100%);
86
+ border-right-color: var(--chaos-blood, #ff0040);
87
+ }
88
+
89
+ .variantDark .rune {
90
+ color: var(--chaos-blood, #ff0040);
91
+ }
92
+
93
+ .variantDark .glyph {
94
+ border-color: rgba(255, 0, 64, 0.3);
95
+ }
96
+
97
+ .variantDark .glyph:hover {
98
+ color: var(--chaos-blood, #ff0040);
99
+ border-color: var(--chaos-blood, #ff0040);
100
+ background: rgba(255, 0, 64, 0.1);
101
+ }
102
+
103
+ /* Size variants */
104
+ .sizeCompact {
105
+ width: 50px;
106
+ padding: 1rem 0;
107
+ }
108
+
109
+ .sizeCompact .glyph {
110
+ width: 30px;
111
+ height: 30px;
112
+ font-size: 0.8rem;
113
+ }
114
+
115
+ .sizeCompact .rune {
116
+ font-size: 1rem;
117
+ }
@@ -0,0 +1,91 @@
1
+ 'use client';
2
+
3
+ import { forwardRef, HTMLAttributes, ReactNode } from 'react';
4
+
5
+ export interface VerticalNavItemProps {
6
+ href?: string;
7
+ glyph: string;
8
+ label?: string;
9
+ active?: boolean;
10
+ onClick?: () => void;
11
+ }
12
+
13
+ export interface VerticalNavProps extends HTMLAttributes<HTMLElement> {
14
+ items?: VerticalNavItemProps[];
15
+ runeTop?: string;
16
+ runeBottom?: string;
17
+ variant?: 'default' | 'dark';
18
+ size?: 'default' | 'compact';
19
+ children?: ReactNode;
20
+ }
21
+
22
+ export const VerticalNavItem = forwardRef<HTMLAnchorElement, VerticalNavItemProps>(
23
+ ({ href, glyph, label, active, onClick, ...props }, ref) => {
24
+ const baseClasses = `
25
+ w-10 h-10 flex items-center justify-center font-display text-base
26
+ border transition-all duration-300 relative group
27
+ ${active
28
+ ? 'text-amber-500 border-amber-500 shadow-[0_0_15px_rgba(201,162,39,0.3)]'
29
+ : 'text-stone-500 border-stone-700 hover:text-amber-500 hover:border-amber-500 hover:bg-amber-500/10'
30
+ }
31
+ `;
32
+
33
+ const labelEl = label && (
34
+ <span className="absolute left-[60px] text-[0.6rem] tracking-[0.3em] text-stone-500 uppercase whitespace-nowrap opacity-0 -translate-x-2 transition-all group-hover:opacity-100 group-hover:translate-x-0">
35
+ {label}
36
+ </span>
37
+ );
38
+
39
+ if (href) {
40
+ return (
41
+ <a ref={ref} href={href} className={baseClasses} onClick={onClick} {...props}>
42
+ {glyph}
43
+ {labelEl}
44
+ </a>
45
+ );
46
+ }
47
+ return (
48
+ <button className={baseClasses} onClick={onClick} {...props}>
49
+ {glyph}
50
+ {labelEl}
51
+ </button>
52
+ );
53
+ }
54
+ );
55
+
56
+ VerticalNavItem.displayName = 'VerticalNavItem';
57
+
58
+ export const VerticalNav = forwardRef<HTMLElement, VerticalNavProps>(
59
+ ({ items, runeTop = 'ᛟ', runeBottom = 'ᛞ', variant = 'default', size = 'default', children, className, ...props }, ref) => {
60
+ const navClasses = `
61
+ fixed left-0 top-0 bottom-0 z-50 flex flex-col items-center justify-between
62
+ ${size === 'compact' ? 'w-[50px] py-4' : 'w-20 py-8'}
63
+ ${variant === 'dark'
64
+ ? 'bg-gradient-to-r from-black to-transparent border-r border-red-500'
65
+ : 'bg-gradient-to-r from-stone-900 to-transparent border-r border-stone-700'
66
+ }
67
+ ${className || ''}
68
+ `;
69
+
70
+ const runeClasses = `
71
+ text-2xl animate-pulse
72
+ ${variant === 'dark' ? 'text-red-500' : 'text-amber-700'}
73
+ `;
74
+
75
+ return (
76
+ <nav ref={ref} className={navClasses} {...props}>
77
+ <div className={runeClasses}>{runeTop}</div>
78
+ <div className="flex flex-col gap-12">
79
+ {items?.map((item, i) => (
80
+ <VerticalNavItem key={i} {...item} />
81
+ ))}
82
+ {children}
83
+ </div>
84
+ <div className={runeClasses}>{runeBottom}</div>
85
+ </nav>
86
+ );
87
+ }
88
+ );
89
+
90
+ VerticalNav.displayName = 'VerticalNav';
91
+ export default VerticalNav;
package/package.json CHANGED
@@ -1,38 +1,13 @@
1
1
  {
2
2
  "name": "@oalacea/chaosui",
3
- "version": "0.4.0",
4
- "description": "Glitch, noise, and distortion components for React. Copy-paste like shadcn.",
3
+ "version": "0.5.1",
4
+ "description": "Glitch, noise, and distortion UI components",
5
5
  "type": "module",
6
- "bin": {
7
- "chaos-ui": "./bin/cli.js",
8
- "chaosui": "./bin/cli.js"
9
- },
10
- "files": [
11
- "bin",
12
- "components"
13
- ],
14
- "keywords": [
15
- "react",
16
- "components",
17
- "glitch",
18
- "noise",
19
- "distortion",
20
- "ui",
21
- "effects",
22
- "css",
23
- "animation"
24
- ],
25
- "author": "Oalacea",
26
- "license": "MIT",
27
- "repository": {
28
- "type": "git",
29
- "url": "https://github.com/Pamacea/chaos.git"
30
- },
31
- "homepage": "https://github.com/Pamacea/chaos",
32
- "dependencies": {
33
- "commander": "^12.0.0",
34
- "picocolors": "^1.0.0",
35
- "prompts": "^2.4.2",
36
- "fs-extra": "^11.2.0"
6
+ "exports": {
7
+ "./text/*": "./text/*/index.tsx",
8
+ "./overlays/*": "./overlays/*/index.tsx",
9
+ "./buttons/*": "./buttons/*/index.tsx",
10
+ "./effects/*": "./effects/*/index.tsx",
11
+ "./backgrounds/*": "./backgrounds/*/index.tsx"
37
12
  }
38
13
  }