@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,177 @@
1
+ .tower {
2
+ --tower-accent: #c9a227;
3
+ --tower-bg: rgba(0, 0, 0, 0.6);
4
+ --tower-border: rgba(255, 255, 255, 0.1);
5
+
6
+ display: flex;
7
+ flex-direction: column;
8
+ gap: 0;
9
+ max-width: 400px;
10
+ }
11
+
12
+ .tier {
13
+ position: relative;
14
+ padding: 2rem;
15
+ background: var(--tower-bg);
16
+ border: 1px solid var(--tower-border);
17
+ border-top: none;
18
+ transition: all 0.3s ease;
19
+ }
20
+
21
+ .tier:first-child {
22
+ border-top: 1px solid var(--tower-border);
23
+ border-radius: 4px 4px 0 0;
24
+ }
25
+
26
+ .tier:last-child {
27
+ border-radius: 0 0 4px 4px;
28
+ }
29
+
30
+ .tier:hover {
31
+ background: rgba(201, 162, 39, 0.05);
32
+ border-color: var(--tower-accent);
33
+ z-index: 1;
34
+ }
35
+
36
+ /* Featured tier */
37
+ .featured {
38
+ border-color: var(--tower-accent);
39
+ background: rgba(201, 162, 39, 0.1);
40
+ transform: scale(1.02);
41
+ z-index: 2;
42
+ }
43
+
44
+ .featured::before {
45
+ content: '';
46
+ position: absolute;
47
+ left: -1px;
48
+ right: -1px;
49
+ top: -1px;
50
+ height: 3px;
51
+ background: var(--tower-accent);
52
+ }
53
+
54
+ .featuredBadge {
55
+ position: absolute;
56
+ top: -12px;
57
+ left: 50%;
58
+ transform: translateX(-50%);
59
+ padding: 0.25rem 1rem;
60
+ background: var(--tower-accent);
61
+ color: #000;
62
+ font-size: 0.65rem;
63
+ font-weight: 700;
64
+ text-transform: uppercase;
65
+ letter-spacing: 0.1em;
66
+ }
67
+
68
+ .tierHeader {
69
+ display: flex;
70
+ justify-content: space-between;
71
+ align-items: baseline;
72
+ margin-bottom: 1rem;
73
+ padding-bottom: 1rem;
74
+ border-bottom: 1px solid var(--tower-border);
75
+ }
76
+
77
+ .tierName {
78
+ font-family: 'Cinzel', serif;
79
+ font-size: 1.25rem;
80
+ font-weight: 700;
81
+ color: var(--tower-accent);
82
+ letter-spacing: 0.1em;
83
+ }
84
+
85
+ .tierPrice {
86
+ display: flex;
87
+ align-items: baseline;
88
+ gap: 0.25rem;
89
+ }
90
+
91
+ .currency {
92
+ font-size: 1rem;
93
+ color: rgba(255, 255, 255, 0.5);
94
+ }
95
+
96
+ .amount {
97
+ font-size: 2rem;
98
+ font-weight: 700;
99
+ color: #fff;
100
+ }
101
+
102
+ .period {
103
+ font-size: 0.75rem;
104
+ color: rgba(255, 255, 255, 0.4);
105
+ }
106
+
107
+ .tierFeatures {
108
+ list-style: none;
109
+ margin: 1rem 0;
110
+ padding: 0;
111
+ }
112
+
113
+ .feature {
114
+ display: flex;
115
+ align-items: center;
116
+ gap: 0.75rem;
117
+ padding: 0.5rem 0;
118
+ font-size: 0.875rem;
119
+ color: rgba(255, 255, 255, 0.8);
120
+ }
121
+
122
+ .featureIcon {
123
+ color: var(--tower-accent);
124
+ font-size: 0.75rem;
125
+ }
126
+
127
+ .tierAction {
128
+ margin-top: 1.5rem;
129
+ }
130
+
131
+ .actionButton {
132
+ width: 100%;
133
+ padding: 0.875rem 1.5rem;
134
+ background: transparent;
135
+ border: 1px solid var(--tower-accent);
136
+ color: var(--tower-accent);
137
+ font-family: inherit;
138
+ font-size: 0.8rem;
139
+ font-weight: 600;
140
+ text-transform: uppercase;
141
+ letter-spacing: 0.15em;
142
+ cursor: pointer;
143
+ transition: all 0.3s ease;
144
+ }
145
+
146
+ .actionButton:hover {
147
+ background: var(--tower-accent);
148
+ color: #000;
149
+ }
150
+
151
+ .featured .actionButton {
152
+ background: var(--tower-accent);
153
+ color: #000;
154
+ }
155
+
156
+ .featured .actionButton:hover {
157
+ background: transparent;
158
+ color: var(--tower-accent);
159
+ }
160
+
161
+ /* Variants */
162
+ .gold { --tower-accent: #c9a227; }
163
+ .blood { --tower-accent: #8b1a1a; }
164
+ .cyan { --tower-accent: #00f0ff; }
165
+ .bone { --tower-accent: #d4c5a9; }
166
+
167
+ /* Connector lines between tiers */
168
+ .connector {
169
+ position: absolute;
170
+ left: 50%;
171
+ bottom: -1px;
172
+ transform: translateX(-50%);
173
+ width: 1px;
174
+ height: 20px;
175
+ background: var(--tower-accent);
176
+ opacity: 0.3;
177
+ }
@@ -0,0 +1,106 @@
1
+ 'use client';
2
+
3
+ import { forwardRef, HTMLAttributes } from 'react';
4
+
5
+ export interface PricingTier {
6
+ name: string;
7
+ price: number | string;
8
+ currency?: string;
9
+ period?: string;
10
+ features: string[];
11
+ featured?: boolean;
12
+ featuredLabel?: string;
13
+ buttonText?: string;
14
+ onSelect?: () => void;
15
+ }
16
+
17
+ export interface TowerPricingProps extends HTMLAttributes<HTMLDivElement> {
18
+ tiers: PricingTier[];
19
+ variant?: 'gold' | 'blood' | 'cyan' | 'bone';
20
+ showConnectors?: boolean;
21
+ }
22
+
23
+ const variantStyles = {
24
+ gold: { accent: 'text-amber-600', border: 'border-amber-600', bg: 'bg-amber-600', hoverBg: 'hover:bg-amber-600/5' },
25
+ blood: { accent: 'text-red-800', border: 'border-red-800', bg: 'bg-red-800', hoverBg: 'hover:bg-red-800/5' },
26
+ cyan: { accent: 'text-cyan-400', border: 'border-cyan-400', bg: 'bg-cyan-400', hoverBg: 'hover:bg-cyan-400/5' },
27
+ bone: { accent: 'text-stone-400', border: 'border-stone-400', bg: 'bg-stone-400', hoverBg: 'hover:bg-stone-400/5' },
28
+ };
29
+
30
+ export const TowerPricing = forwardRef<HTMLDivElement, TowerPricingProps>(
31
+ ({ tiers, variant = 'gold', showConnectors = false, className = '', ...props }, ref) => {
32
+ const colors = variantStyles[variant];
33
+
34
+ return (
35
+ <div ref={ref} className={`flex flex-col max-w-[400px] ${className}`} {...props}>
36
+ {tiers.map((tier, index) => (
37
+ <div
38
+ key={tier.name}
39
+ className={`
40
+ relative p-8 bg-black/60 border border-white/10 transition-all duration-300
41
+ ${index === 0 ? 'rounded-t border-t' : 'border-t-0'}
42
+ ${index === tiers.length - 1 ? 'rounded-b' : ''}
43
+ ${tier.featured
44
+ ? `${colors.border} bg-amber-600/10 scale-[1.02] z-10`
45
+ : `${colors.hoverBg} hover:${colors.border} hover:z-[1]`
46
+ }
47
+ `}
48
+ >
49
+ {tier.featured && (
50
+ <>
51
+ <div className={`absolute -top-px left-[-1px] right-[-1px] h-[3px] ${colors.bg}`} />
52
+ {tier.featuredLabel && (
53
+ <span className={`absolute -top-3 left-1/2 -translate-x-1/2 px-4 py-1 ${colors.bg} text-black text-[0.65rem] font-bold uppercase tracking-wider`}>
54
+ {tier.featuredLabel}
55
+ </span>
56
+ )}
57
+ </>
58
+ )}
59
+
60
+ <div className="flex justify-between items-baseline mb-4 pb-4 border-b border-white/10">
61
+ <span className={`font-['Cinzel',serif] text-xl font-bold ${colors.accent} tracking-wider`}>
62
+ {tier.name}
63
+ </span>
64
+ <div className="flex items-baseline gap-1">
65
+ <span className="text-white/50">{tier.currency || '$'}</span>
66
+ <span className="text-3xl font-bold text-white">{tier.price}</span>
67
+ {tier.period && <span className="text-xs text-white/40">/{tier.period}</span>}
68
+ </div>
69
+ </div>
70
+
71
+ <ul className="my-4 space-y-2">
72
+ {tier.features.map((feature, i) => (
73
+ <li key={i} className="flex items-center gap-3 text-sm text-white/80">
74
+ <span className={`text-xs ${colors.accent}`}>✦</span>
75
+ {feature}
76
+ </li>
77
+ ))}
78
+ </ul>
79
+
80
+ <div className="mt-6">
81
+ <button
82
+ onClick={tier.onSelect}
83
+ className={`
84
+ w-full py-3.5 px-6 border font-semibold text-xs uppercase tracking-[0.15em] transition-all duration-300
85
+ ${tier.featured
86
+ ? `${colors.bg} ${colors.border} text-black hover:bg-transparent hover:${colors.accent}`
87
+ : `bg-transparent ${colors.border} ${colors.accent} hover:${colors.bg} hover:text-black`
88
+ }
89
+ `}
90
+ >
91
+ {tier.buttonText || 'Select'}
92
+ </button>
93
+ </div>
94
+
95
+ {showConnectors && index < tiers.length - 1 && (
96
+ <span className={`absolute left-1/2 -bottom-px -translate-x-1/2 w-px h-5 ${colors.bg} opacity-30`} />
97
+ )}
98
+ </div>
99
+ ))}
100
+ </div>
101
+ );
102
+ }
103
+ );
104
+
105
+ TowerPricing.displayName = 'TowerPricing';
106
+ export default TowerPricing;
@@ -0,0 +1,96 @@
1
+ 'use client';
2
+
3
+ import { forwardRef, HTMLAttributes } from 'react';
4
+ import styles from './tracklist.module.css';
5
+
6
+ export interface Track {
7
+ number: number | string;
8
+ name: string;
9
+ artist?: string;
10
+ duration: string;
11
+ active?: boolean;
12
+ }
13
+
14
+ export interface TracklistProps extends HTMLAttributes<HTMLDivElement> {
15
+ /** List of tracks */
16
+ tracks: Track[];
17
+ /** Color variant */
18
+ variant?: 'silver' | 'blood' | 'gold' | 'bone';
19
+ /** Show header row */
20
+ showHeader?: boolean;
21
+ /** Compact mode */
22
+ compact?: boolean;
23
+ /** Large track numbers */
24
+ numbered?: boolean;
25
+ /** Track click handler */
26
+ onTrackClick?: (track: Track, index: number) => void;
27
+ }
28
+
29
+ export const Tracklist = forwardRef<HTMLDivElement, TracklistProps>(
30
+ (
31
+ {
32
+ tracks,
33
+ variant = 'silver',
34
+ showHeader = false,
35
+ compact = false,
36
+ numbered = false,
37
+ onTrackClick,
38
+ className,
39
+ ...props
40
+ },
41
+ ref
42
+ ) => {
43
+ return (
44
+ <div
45
+ ref={ref}
46
+ className={`
47
+ ${styles.tracklist}
48
+ ${styles[variant]}
49
+ ${compact ? styles.compact : ''}
50
+ ${numbered ? styles.numbered : ''}
51
+ ${className || ''}
52
+ `}
53
+ {...props}
54
+ >
55
+ {showHeader && (
56
+ <div className={styles.header}>
57
+ <span>#</span>
58
+ <span>Title</span>
59
+ <span></span>
60
+ <span>Duration</span>
61
+ </div>
62
+ )}
63
+
64
+ {tracks.map((track, index) => (
65
+ <div
66
+ key={index}
67
+ className={`${styles.track} ${track.active ? styles.active : ''}`}
68
+ onClick={() => onTrackClick?.(track, index)}
69
+ >
70
+ <span className={styles.trackNum}>
71
+ {String(track.number).padStart(2, '0')}
72
+ </span>
73
+
74
+ <div className={styles.trackInfo}>
75
+ <span className={styles.trackName}>{track.name}</span>
76
+ {track.artist && (
77
+ <span className={styles.trackArtist}>{track.artist}</span>
78
+ )}
79
+ </div>
80
+
81
+ {!compact && (
82
+ <div className={styles.trackBarContainer}>
83
+ <div className={styles.trackBar} />
84
+ </div>
85
+ )}
86
+
87
+ <span className={styles.trackDuration}>{track.duration}</span>
88
+ </div>
89
+ ))}
90
+ </div>
91
+ );
92
+ }
93
+ );
94
+
95
+ Tracklist.displayName = 'Tracklist';
96
+ export default Tracklist;
@@ -0,0 +1,141 @@
1
+ .tracklist {
2
+ --track-accent: #888;
3
+ --track-hover: rgba(255, 255, 255, 0.05);
4
+ --track-active: rgba(139, 26, 26, 0.2);
5
+
6
+ display: flex;
7
+ flex-direction: column;
8
+ font-family: 'Cormorant Garamond', serif;
9
+ }
10
+
11
+ .track {
12
+ display: grid;
13
+ grid-template-columns: auto 1fr auto auto;
14
+ align-items: center;
15
+ gap: 1.5rem;
16
+ padding: 1rem 1.5rem;
17
+ border-bottom: 1px solid rgba(255, 255, 255, 0.05);
18
+ cursor: pointer;
19
+ transition: all 0.3s ease;
20
+ }
21
+
22
+ .track:hover {
23
+ background: var(--track-hover);
24
+ }
25
+
26
+ .track:hover .trackBar {
27
+ width: 100%;
28
+ }
29
+
30
+ .trackNum {
31
+ font-family: 'Share Tech Mono', monospace;
32
+ font-size: 0.75rem;
33
+ color: var(--track-accent);
34
+ min-width: 2rem;
35
+ }
36
+
37
+ .trackInfo {
38
+ display: flex;
39
+ flex-direction: column;
40
+ gap: 0.25rem;
41
+ overflow: hidden;
42
+ }
43
+
44
+ .trackName {
45
+ font-size: 1rem;
46
+ color: #fff;
47
+ white-space: nowrap;
48
+ overflow: hidden;
49
+ text-overflow: ellipsis;
50
+ }
51
+
52
+ .trackArtist {
53
+ font-size: 0.75rem;
54
+ color: rgba(255, 255, 255, 0.4);
55
+ font-style: italic;
56
+ }
57
+
58
+ .trackBarContainer {
59
+ position: relative;
60
+ width: 80px;
61
+ height: 2px;
62
+ background: rgba(255, 255, 255, 0.1);
63
+ overflow: hidden;
64
+ }
65
+
66
+ .trackBar {
67
+ position: absolute;
68
+ left: 0;
69
+ top: 0;
70
+ height: 100%;
71
+ width: 0;
72
+ background: var(--track-accent);
73
+ transition: width 0.6s ease;
74
+ }
75
+
76
+ .trackDuration {
77
+ font-family: 'Share Tech Mono', monospace;
78
+ font-size: 0.75rem;
79
+ color: rgba(255, 255, 255, 0.5);
80
+ min-width: 3rem;
81
+ text-align: right;
82
+ }
83
+
84
+ /* Active/playing state */
85
+ .active {
86
+ background: var(--track-active);
87
+ }
88
+
89
+ .active .trackNum {
90
+ color: #8b1a1a;
91
+ }
92
+
93
+ .active .trackNum::before {
94
+ content: '▶';
95
+ margin-right: 0.5rem;
96
+ }
97
+
98
+ .active .trackBar {
99
+ animation: progress 180s linear forwards;
100
+ }
101
+
102
+ @keyframes progress {
103
+ from { width: 0; }
104
+ to { width: 100%; }
105
+ }
106
+
107
+ /* Variants */
108
+ .silver { --track-accent: #888; }
109
+ .blood { --track-accent: #8b1a1a; --track-active: rgba(139, 26, 26, 0.2); }
110
+ .gold { --track-accent: #c9a227; --track-active: rgba(201, 162, 39, 0.2); }
111
+ .bone { --track-accent: #d4c5a9; --track-active: rgba(212, 197, 169, 0.2); }
112
+
113
+ /* Header */
114
+ .header {
115
+ display: grid;
116
+ grid-template-columns: auto 1fr auto auto;
117
+ gap: 1.5rem;
118
+ padding: 0.75rem 1.5rem;
119
+ border-bottom: 1px solid rgba(255, 255, 255, 0.1);
120
+ font-size: 0.65rem;
121
+ text-transform: uppercase;
122
+ letter-spacing: 0.2em;
123
+ color: var(--track-accent);
124
+ }
125
+
126
+ /* Compact mode */
127
+ .compact .track {
128
+ padding: 0.75rem 1rem;
129
+ gap: 1rem;
130
+ }
131
+
132
+ .compact .trackBarContainer {
133
+ display: none;
134
+ }
135
+
136
+ /* Numbered style */
137
+ .numbered .trackNum {
138
+ font-size: 1.25rem;
139
+ font-family: 'Playfair Display', serif;
140
+ font-weight: 700;
141
+ }
@@ -0,0 +1,92 @@
1
+ 'use client';
2
+
3
+ import { forwardRef, HTMLAttributes } from 'react';
4
+
5
+ export interface Track {
6
+ number: number | string;
7
+ name: string;
8
+ artist?: string;
9
+ duration: string;
10
+ active?: boolean;
11
+ }
12
+
13
+ export interface TracklistProps extends HTMLAttributes<HTMLDivElement> {
14
+ tracks: Track[];
15
+ variant?: 'silver' | 'blood' | 'gold' | 'bone';
16
+ showHeader?: boolean;
17
+ compact?: boolean;
18
+ numbered?: boolean;
19
+ onTrackClick?: (track: Track, index: number) => void;
20
+ }
21
+
22
+ const variantStyles = {
23
+ silver: { accent: 'text-gray-400', bar: 'bg-gray-400', activeBg: 'bg-gray-400/10' },
24
+ blood: { accent: 'text-red-800', bar: 'bg-red-800', activeBg: 'bg-red-800/20' },
25
+ gold: { accent: 'text-amber-600', bar: 'bg-amber-600', activeBg: 'bg-amber-600/20' },
26
+ bone: { accent: 'text-stone-400', bar: 'bg-stone-400', activeBg: 'bg-stone-400/20' },
27
+ };
28
+
29
+ export const Tracklist = forwardRef<HTMLDivElement, TracklistProps>(
30
+ ({ tracks, variant = 'silver', showHeader = false, compact = false, numbered = false, onTrackClick, className = '', ...props }, ref) => {
31
+ const colors = variantStyles[variant];
32
+
33
+ return (
34
+ <div ref={ref} className={`flex flex-col font-['Cormorant_Garamond',serif] ${className}`} {...props}>
35
+ {showHeader && (
36
+ <div className={`grid grid-cols-[auto_1fr_auto_auto] gap-6 py-3 px-6 border-b border-white/10 text-[0.65rem] uppercase tracking-[0.2em] ${colors.accent}`}>
37
+ <span>#</span>
38
+ <span>Title</span>
39
+ <span></span>
40
+ <span>Duration</span>
41
+ </div>
42
+ )}
43
+
44
+ {tracks.map((track, index) => (
45
+ <div
46
+ key={index}
47
+ onClick={() => onTrackClick?.(track, index)}
48
+ className={`
49
+ grid gap-6 items-center border-b border-white/5 cursor-pointer transition-all duration-300
50
+ hover:bg-white/5 group
51
+ ${compact ? 'grid-cols-[auto_1fr_auto] py-3 px-4 gap-4' : 'grid-cols-[auto_1fr_auto_auto] py-4 px-6'}
52
+ ${track.active ? colors.activeBg : ''}
53
+ `}
54
+ >
55
+ <span className={`
56
+ font-['Share_Tech_Mono',monospace] min-w-[2rem]
57
+ ${numbered ? "text-xl font-['Playfair_Display',serif] font-bold" : 'text-xs'}
58
+ ${track.active ? colors.accent : colors.accent}
59
+ `}>
60
+ {track.active && <span className="mr-2">▶</span>}
61
+ {String(track.number).padStart(2, '0')}
62
+ </span>
63
+
64
+ <div className="flex flex-col gap-1 overflow-hidden">
65
+ <span className="text-white truncate">{track.name}</span>
66
+ {track.artist && (
67
+ <span className="text-xs text-white/40 italic">{track.artist}</span>
68
+ )}
69
+ </div>
70
+
71
+ {!compact && (
72
+ <div className="relative w-20 h-0.5 bg-white/10 overflow-hidden">
73
+ <div className={`
74
+ absolute left-0 top-0 h-full w-0 ${colors.bar} transition-[width] duration-500
75
+ group-hover:w-full
76
+ ${track.active ? 'animate-[progress_180s_linear_forwards]' : ''}
77
+ `} />
78
+ </div>
79
+ )}
80
+
81
+ <span className="font-['Share_Tech_Mono',monospace] text-xs text-white/50 min-w-[3rem] text-right">
82
+ {track.duration}
83
+ </span>
84
+ </div>
85
+ ))}
86
+ </div>
87
+ );
88
+ }
89
+ );
90
+
91
+ Tracklist.displayName = 'Tracklist';
92
+ export default Tracklist;
@@ -0,0 +1,60 @@
1
+ 'use client';
2
+
3
+ import { forwardRef, HTMLAttributes, ReactNode } from 'react';
4
+ import styles from './void-frame.module.css';
5
+
6
+ export interface VoidFrameProps extends HTMLAttributes<HTMLDivElement> {
7
+ /** Frame content */
8
+ children: ReactNode;
9
+ /** Color variant */
10
+ variant?: 'gold' | 'bone' | 'blood' | 'iron' | 'cyan';
11
+ /** Corner style */
12
+ cornerStyle?: 'simple' | 'extended' | 'ornate';
13
+ /** Add glow effect */
14
+ glow?: boolean;
15
+ /** Padding size */
16
+ padding?: 'sm' | 'md' | 'lg' | 'xl';
17
+ }
18
+
19
+ export const VoidFrame = forwardRef<HTMLDivElement, VoidFrameProps>(
20
+ (
21
+ {
22
+ children,
23
+ variant = 'gold',
24
+ cornerStyle = 'simple',
25
+ glow = false,
26
+ padding = 'md',
27
+ className,
28
+ style,
29
+ ...props
30
+ },
31
+ ref
32
+ ) => {
33
+ const paddingSizes = {
34
+ sm: '1rem',
35
+ md: '2rem',
36
+ lg: '3rem',
37
+ xl: '4rem',
38
+ };
39
+
40
+ const cornerStyleClass = cornerStyle === 'extended' ? styles.extended : cornerStyle === 'ornate' ? styles.ornate : '';
41
+
42
+ return (
43
+ <div
44
+ ref={ref}
45
+ className={`${styles.frame} ${styles[variant]} ${cornerStyleClass} ${glow ? styles.glow : ''} ${className || ''}`}
46
+ style={{ padding: paddingSizes[padding], ...style }}
47
+ {...props}
48
+ >
49
+ <span className={`${styles.corner} ${styles.cornerTopLeft}`} />
50
+ <span className={`${styles.corner} ${styles.cornerTopRight}`} />
51
+ <span className={`${styles.corner} ${styles.cornerBottomLeft}`} />
52
+ <span className={`${styles.corner} ${styles.cornerBottomRight}`} />
53
+ {children}
54
+ </div>
55
+ );
56
+ }
57
+ );
58
+
59
+ VoidFrame.displayName = 'VoidFrame';
60
+ export default VoidFrame;