@oalacea/chaosui 0.5.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 (197) hide show
  1. package/buttons/cta-brutal/css/cta-brutal.module.css +175 -0
  2. package/{components/buttons/cta-brutal → buttons/cta-brutal/css}/index.tsx +25 -3
  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/tailwind/index.tsx +90 -0
  6. package/buttons/deeper-button/css/deeper-button.module.css +141 -0
  7. package/{components/buttons/deeper-button → buttons/deeper-button/css}/index.tsx +14 -3
  8. package/buttons/deeper-button/tailwind/index.tsx +78 -0
  9. package/buttons/dual-choice/css/dual-choice.module.css +176 -0
  10. package/{components/buttons/dual-choice → buttons/dual-choice/css}/index.tsx +2 -0
  11. package/buttons/dual-choice/tailwind/index.tsx +89 -0
  12. package/{components/buttons/tension-bar → buttons/tension-bar/css}/index.tsx +22 -5
  13. package/buttons/tension-bar/css/tension-bar.module.css +204 -0
  14. package/buttons/tension-bar/tailwind/index.tsx +122 -0
  15. package/decorative/inscription/css/index.tsx +66 -0
  16. package/decorative/inscription/css/inscription.module.css +160 -0
  17. package/decorative/inscription/tailwind/index.tsx +91 -0
  18. package/decorative/ornaments/css/index.tsx +136 -0
  19. package/decorative/ornaments/css/ornaments.module.css +144 -0
  20. package/decorative/ornaments/tailwind/index.tsx +122 -0
  21. package/decorative/rune-symbols/css/index.tsx +116 -0
  22. package/decorative/rune-symbols/css/rune-symbols.module.css +116 -0
  23. package/decorative/rune-symbols/tailwind/index.tsx +108 -0
  24. package/decorative/sheet-music/css/index.tsx +144 -0
  25. package/decorative/sheet-music/css/sheet-music.module.css +152 -0
  26. package/decorative/sheet-music/tailwind/index.tsx +111 -0
  27. package/layout/horizontal-scroll/css/horizontal-scroll.module.css +93 -0
  28. package/{components/layout/horizontal-scroll → layout/horizontal-scroll/css}/index.tsx +41 -5
  29. package/layout/horizontal-scroll/tailwind/index.tsx +108 -0
  30. package/layout/spec-grid/css/index.tsx +103 -0
  31. package/layout/spec-grid/css/spec-grid.module.css +125 -0
  32. package/layout/spec-grid/tailwind/index.tsx +91 -0
  33. package/{components/layout/tower-pricing → layout/tower-pricing/css}/index.tsx +43 -8
  34. package/layout/tower-pricing/css/tower-pricing.module.css +177 -0
  35. package/layout/tower-pricing/tailwind/index.tsx +106 -0
  36. package/layout/tracklist/css/index.tsx +96 -0
  37. package/layout/tracklist/css/tracklist.module.css +141 -0
  38. package/layout/tracklist/tailwind/index.tsx +92 -0
  39. package/{components/layout/void-frame → layout/void-frame/css}/index.tsx +31 -3
  40. package/layout/void-frame/css/void-frame.module.css +141 -0
  41. package/layout/void-frame/tailwind/index.tsx +64 -0
  42. package/navigation/brutal-nav/css/brutal-nav.module.css +178 -0
  43. package/{components/navigation/brutal-nav → navigation/brutal-nav/css}/index.tsx +12 -3
  44. package/navigation/brutal-nav/tailwind/index.tsx +95 -0
  45. package/{components/navigation/progress-dots → navigation/progress-dots/css}/index.tsx +7 -2
  46. package/{components/navigation/progress-dots → navigation/progress-dots/css}/progress-dots.module.css +74 -13
  47. package/navigation/progress-dots/tailwind/index.tsx +105 -0
  48. package/{components/navigation/scattered-nav → navigation/scattered-nav/css}/scattered-nav.module.css +9 -1
  49. package/navigation/scattered-nav/tailwind/index.tsx +77 -0
  50. package/{components/navigation/scroll-indicator → navigation/scroll-indicator/css}/index.tsx +18 -4
  51. package/{components/navigation/scroll-indicator → navigation/scroll-indicator/css}/scroll-indicator.module.css +57 -10
  52. package/navigation/scroll-indicator/tailwind/index.tsx +107 -0
  53. package/{components/navigation/vertical-nav → navigation/vertical-nav/css}/index.tsx +13 -3
  54. package/{components/navigation/vertical-nav → navigation/vertical-nav/css}/vertical-nav.module.css +24 -5
  55. package/navigation/vertical-nav/tailwind/index.tsx +91 -0
  56. package/package.json +8 -33
  57. package/bin/cli.js +0 -308
  58. package/components/backgrounds/light-beams/index.tsx +0 -80
  59. package/components/backgrounds/light-beams/light-beams.module.css +0 -27
  60. package/components/buttons/cta-brutal/cta-brutal.module.css +0 -81
  61. package/components/buttons/dead-button/dead-button.module.css +0 -111
  62. package/components/buttons/deeper-button/deeper-button.module.css +0 -76
  63. package/components/buttons/dual-choice/dual-choice.module.css +0 -90
  64. package/components/buttons/tension-bar/tension-bar.module.css +0 -105
  65. package/components/decorative/coffee-stain/coffee-stain.module.css +0 -24
  66. package/components/decorative/coffee-stain/index.tsx +0 -55
  67. package/components/decorative/ornaments/index.tsx +0 -51
  68. package/components/decorative/ornaments/ornaments.module.css +0 -33
  69. package/components/decorative/rune-symbols/index.tsx +0 -55
  70. package/components/decorative/rune-symbols/rune-symbols.module.css +0 -22
  71. package/components/layout/horizontal-scroll/horizontal-scroll.module.css +0 -30
  72. package/components/layout/spec-grid/index.tsx +0 -56
  73. package/components/layout/spec-grid/spec-grid.module.css +0 -21
  74. package/components/layout/tower-pricing/tower-pricing.module.css +0 -27
  75. package/components/layout/tracklist/index.tsx +0 -45
  76. package/components/layout/tracklist/tracklist.module.css +0 -24
  77. package/components/layout/void-frame/void-frame.module.css +0 -38
  78. package/components/navigation/brutal-nav/brutal-nav.module.css +0 -85
  79. package/components/navigation/hexagon-menu/css/hexagon-menu.module.css +0 -55
  80. package/components/navigation/hexagon-menu/css/index.tsx +0 -35
  81. package/components/navigation/hexagon-menu/tailwind/index.tsx +0 -53
  82. /package/{components/backgrounds → backgrounds}/glow-orbs/glow-orbs.module.css +0 -0
  83. /package/{components/backgrounds → backgrounds}/glow-orbs/index.tsx +0 -0
  84. /package/{components/backgrounds → backgrounds}/noise-canvas/index.tsx +0 -0
  85. /package/{components/backgrounds → backgrounds}/noise-canvas/noise-canvas.module.css +0 -0
  86. /package/{components/backgrounds → backgrounds}/particle-field/index.tsx +0 -0
  87. /package/{components/backgrounds → backgrounds}/particle-field/particle-field.module.css +0 -0
  88. /package/{components/buttons → buttons}/chaos-button/chaos-button.module.css +0 -0
  89. /package/{components/buttons → buttons}/chaos-button/index.tsx +0 -0
  90. /package/{components/buttons/dead-button → buttons/dead-button/css}/index.tsx +0 -0
  91. /package/{components/buttons → buttons}/glitch-button/glitch-button.module.css +0 -0
  92. /package/{components/buttons → buttons}/glitch-button/index.tsx +0 -0
  93. /package/{components/chaos-vars.css → chaos-vars.css} +0 -0
  94. /package/{components/cyber → cyber}/cyber-avatar/css/cyber-avatar.module.css +0 -0
  95. /package/{components/cyber → cyber}/cyber-avatar/css/index.tsx +0 -0
  96. /package/{components/cyber → cyber}/cyber-avatar/tailwind/index.tsx +0 -0
  97. /package/{components/cyber → cyber}/cyber-input/css/cyber-input.module.css +0 -0
  98. /package/{components/cyber → cyber}/cyber-input/css/index.tsx +0 -0
  99. /package/{components/cyber → cyber}/cyber-input/tailwind/index.tsx +0 -0
  100. /package/{components/cyber → cyber}/cyber-loader/css/cyber-loader.module.css +0 -0
  101. /package/{components/cyber → cyber}/cyber-loader/css/index.tsx +0 -0
  102. /package/{components/cyber → cyber}/cyber-loader/tailwind/index.tsx +0 -0
  103. /package/{components/cyber → cyber}/cyber-modal/css/cyber-modal.module.css +0 -0
  104. /package/{components/cyber → cyber}/cyber-modal/css/index.tsx +0 -0
  105. /package/{components/cyber → cyber}/cyber-modal/tailwind/index.tsx +0 -0
  106. /package/{components/cyber → cyber}/cyber-slider/css/cyber-slider.module.css +0 -0
  107. /package/{components/cyber → cyber}/cyber-slider/css/index.tsx +0 -0
  108. /package/{components/cyber → cyber}/cyber-slider/tailwind/index.tsx +0 -0
  109. /package/{components/cyber → cyber}/cyber-tooltip/css/cyber-tooltip.module.css +0 -0
  110. /package/{components/cyber → cyber}/cyber-tooltip/css/index.tsx +0 -0
  111. /package/{components/cyber → cyber}/cyber-tooltip/tailwind/index.tsx +0 -0
  112. /package/{components/effects → effects}/cursor-follower/cursor-follower.module.css +0 -0
  113. /package/{components/effects → effects}/cursor-follower/index.tsx +0 -0
  114. /package/{components/effects → effects}/glitch-image/css/glitch-image.module.css +0 -0
  115. /package/{components/effects → effects}/glitch-image/css/index.tsx +0 -0
  116. /package/{components/effects → effects}/glitch-image/tailwind/index.tsx +0 -0
  117. /package/{components/effects → effects}/glowing-border/css/glowing-border.module.css +0 -0
  118. /package/{components/effects → effects}/glowing-border/css/index.tsx +0 -0
  119. /package/{components/effects → effects}/glowing-border/tailwind/index.tsx +0 -0
  120. /package/{components/effects → effects}/screen-distortion/index.tsx +0 -0
  121. /package/{components/effects → effects}/screen-distortion/screen-distortion.module.css +0 -0
  122. /package/{components/effects → effects}/warning-tape/index.tsx +0 -0
  123. /package/{components/effects → effects}/warning-tape/warning-tape.module.css +0 -0
  124. /package/{components/layout → layout}/data-grid/css/data-grid.module.css +0 -0
  125. /package/{components/layout → layout}/data-grid/css/index.tsx +0 -0
  126. /package/{components/layout → layout}/data-grid/tailwind/index.tsx +0 -0
  127. /package/{components/layout → layout}/hologram-card/css/hologram-card.module.css +0 -0
  128. /package/{components/layout → layout}/hologram-card/css/index.tsx +0 -0
  129. /package/{components/layout → layout}/hologram-card/tailwind/index.tsx +0 -0
  130. /package/{components/navigation/scattered-nav → navigation/scattered-nav/css}/index.tsx +0 -0
  131. /package/{components/neon → neon}/neon-alert/css/index.tsx +0 -0
  132. /package/{components/neon → neon}/neon-alert/css/neon-alert.module.css +0 -0
  133. /package/{components/neon → neon}/neon-alert/tailwind/index.tsx +0 -0
  134. /package/{components/neon → neon}/neon-badge/css/index.tsx +0 -0
  135. /package/{components/neon → neon}/neon-badge/css/neon-badge.module.css +0 -0
  136. /package/{components/neon → neon}/neon-badge/tailwind/index.tsx +0 -0
  137. /package/{components/neon → neon}/neon-button/css/index.tsx +0 -0
  138. /package/{components/neon → neon}/neon-button/css/neon-button.module.css +0 -0
  139. /package/{components/neon → neon}/neon-button/tailwind/index.tsx +0 -0
  140. /package/{components/neon → neon}/neon-divider/css/index.tsx +0 -0
  141. /package/{components/neon → neon}/neon-divider/css/neon-divider.module.css +0 -0
  142. /package/{components/neon → neon}/neon-divider/tailwind/index.tsx +0 -0
  143. /package/{components/neon → neon}/neon-progress/css/index.tsx +0 -0
  144. /package/{components/neon → neon}/neon-progress/css/neon-progress.module.css +0 -0
  145. /package/{components/neon → neon}/neon-progress/tailwind/index.tsx +0 -0
  146. /package/{components/neon → neon}/neon-tabs/css/index.tsx +0 -0
  147. /package/{components/neon → neon}/neon-tabs/css/neon-tabs.module.css +0 -0
  148. /package/{components/neon → neon}/neon-tabs/tailwind/index.tsx +0 -0
  149. /package/{components/neon → neon}/neon-toggle/css/index.tsx +0 -0
  150. /package/{components/neon → neon}/neon-toggle/css/neon-toggle.module.css +0 -0
  151. /package/{components/neon → neon}/neon-toggle/tailwind/index.tsx +0 -0
  152. /package/{components/overlays → overlays}/noise-overlay/index.tsx +0 -0
  153. /package/{components/overlays → overlays}/noise-overlay/noise-overlay.module.css +0 -0
  154. /package/{components/overlays → overlays}/scanlines/index.tsx +0 -0
  155. /package/{components/overlays → overlays}/scanlines/scanlines.module.css +0 -0
  156. /package/{components/overlays → overlays}/static-flicker/index.tsx +0 -0
  157. /package/{components/overlays → overlays}/static-flicker/static-flicker.module.css +0 -0
  158. /package/{components/overlays → overlays}/vignette/index.tsx +0 -0
  159. /package/{components/overlays → overlays}/vignette/vignette.module.css +0 -0
  160. /package/{components/text → text}/ascii-art/css/ascii-art.module.css +0 -0
  161. /package/{components/text → text}/ascii-art/css/index.tsx +0 -0
  162. /package/{components/text → text}/ascii-art/tailwind/index.tsx +0 -0
  163. /package/{components/text → text}/blood-drip/css/blood-drip.module.css +0 -0
  164. /package/{components/text → text}/blood-drip/css/index.tsx +0 -0
  165. /package/{components/text → text}/blood-drip/tailwind/index.tsx +0 -0
  166. /package/{components/text → text}/char-glitch/css/char-glitch.module.css +0 -0
  167. /package/{components/text → text}/char-glitch/css/index.tsx +0 -0
  168. /package/{components/text → text}/char-glitch/tailwind/index.tsx +0 -0
  169. /package/{components/text → text}/countdown-display/css/countdown-display.module.css +0 -0
  170. /package/{components/text → text}/countdown-display/css/index.tsx +0 -0
  171. /package/{components/text → text}/countdown-display/tailwind/index.tsx +0 -0
  172. /package/{components/text → text}/distortion-text/distortion-text.module.css +0 -0
  173. /package/{components/text → text}/distortion-text/index.tsx +0 -0
  174. /package/{components/text → text}/falling-text/falling-text.module.css +0 -0
  175. /package/{components/text → text}/falling-text/index.tsx +0 -0
  176. /package/{components/text → text}/flicker-text/flicker-text.module.css +0 -0
  177. /package/{components/text → text}/flicker-text/index.tsx +0 -0
  178. /package/{components/text → text}/giant-layers/css/giant-layers.module.css +0 -0
  179. /package/{components/text → text}/giant-layers/css/index.tsx +0 -0
  180. /package/{components/text → text}/giant-layers/tailwind/index.tsx +0 -0
  181. /package/{components/text → text}/glitch-text/glitch-text.module.css +0 -0
  182. /package/{components/text → text}/glitch-text/index.tsx +0 -0
  183. /package/{components/text → text}/reveal-text/css/index.tsx +0 -0
  184. /package/{components/text → text}/reveal-text/css/reveal-text.module.css +0 -0
  185. /package/{components/text → text}/reveal-text/tailwind/index.tsx +0 -0
  186. /package/{components/text → text}/rotate-text/css/index.tsx +0 -0
  187. /package/{components/text → text}/rotate-text/css/rotate-text.module.css +0 -0
  188. /package/{components/text → text}/rotate-text/tailwind/index.tsx +0 -0
  189. /package/{components/text → text}/strike-reveal/css/index.tsx +0 -0
  190. /package/{components/text → text}/strike-reveal/css/strike-reveal.module.css +0 -0
  191. /package/{components/text → text}/strike-reveal/tailwind/index.tsx +0 -0
  192. /package/{components/text → text}/terminal-output/css/index.tsx +0 -0
  193. /package/{components/text → text}/terminal-output/css/terminal-output.module.css +0 -0
  194. /package/{components/text → text}/terminal-output/tailwind/index.tsx +0 -0
  195. /package/{components/text → text}/typing-text/css/index.tsx +0 -0
  196. /package/{components/text → text}/typing-text/css/typing-text.module.css +0 -0
  197. /package/{components/text → text}/typing-text/tailwind/index.tsx +0 -0
@@ -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;
@@ -4,20 +4,48 @@ import { forwardRef, HTMLAttributes, ReactNode } from 'react';
4
4
  import styles from './void-frame.module.css';
5
5
 
6
6
  export interface VoidFrameProps extends HTMLAttributes<HTMLDivElement> {
7
+ /** Frame content */
7
8
  children: ReactNode;
9
+ /** Color variant */
8
10
  variant?: 'gold' | 'bone' | 'blood' | 'iron' | 'cyan';
11
+ /** Corner style */
9
12
  cornerStyle?: 'simple' | 'extended' | 'ornate';
13
+ /** Add glow effect */
10
14
  glow?: boolean;
15
+ /** Padding size */
11
16
  padding?: 'sm' | 'md' | 'lg' | 'xl';
12
17
  }
13
18
 
14
19
  export const VoidFrame = forwardRef<HTMLDivElement, VoidFrameProps>(
15
- ({ children, variant = 'gold', cornerStyle = 'simple', glow = false, padding = 'md', className, style, ...props }, ref) => {
16
- const paddingSizes = { sm: '1rem', md: '2rem', lg: '3rem', xl: '4rem' };
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
+
17
40
  const cornerStyleClass = cornerStyle === 'extended' ? styles.extended : cornerStyle === 'ornate' ? styles.ornate : '';
18
41
 
19
42
  return (
20
- <div ref={ref} className={`${styles.frame} ${styles[variant]} ${cornerStyleClass} ${glow ? styles.glow : ''} ${className || ''}`} style={{ padding: paddingSizes[padding], ...style }} {...props}>
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
+ >
21
49
  <span className={`${styles.corner} ${styles.cornerTopLeft}`} />
22
50
  <span className={`${styles.corner} ${styles.cornerTopRight}`} />
23
51
  <span className={`${styles.corner} ${styles.cornerBottomLeft}`} />
@@ -0,0 +1,141 @@
1
+ .frame {
2
+ --frame-color: #c9a227;
3
+ --frame-bg: rgba(0, 0, 0, 0.5);
4
+
5
+ position: relative;
6
+ padding: 2rem;
7
+ background: var(--frame-bg);
8
+ border: 1px solid var(--frame-color);
9
+ }
10
+
11
+ /* Corner ornaments */
12
+ .corner {
13
+ position: absolute;
14
+ width: 20px;
15
+ height: 20px;
16
+ border-color: var(--frame-color);
17
+ border-style: solid;
18
+ }
19
+
20
+ .cornerTopLeft {
21
+ top: -1px;
22
+ left: -1px;
23
+ border-width: 2px 0 0 2px;
24
+ }
25
+
26
+ .cornerTopRight {
27
+ top: -1px;
28
+ right: -1px;
29
+ border-width: 2px 2px 0 0;
30
+ }
31
+
32
+ .cornerBottomLeft {
33
+ bottom: -1px;
34
+ left: -1px;
35
+ border-width: 0 0 2px 2px;
36
+ }
37
+
38
+ .cornerBottomRight {
39
+ bottom: -1px;
40
+ right: -1px;
41
+ border-width: 0 2px 2px 0;
42
+ }
43
+
44
+ /* Extended corners */
45
+ .extended .corner {
46
+ width: 30px;
47
+ height: 30px;
48
+ }
49
+
50
+ .extended .corner::before,
51
+ .extended .corner::after {
52
+ content: '';
53
+ position: absolute;
54
+ background: var(--frame-color);
55
+ }
56
+
57
+ .extended .cornerTopLeft::before,
58
+ .extended .cornerBottomLeft::before {
59
+ left: 5px;
60
+ width: 1px;
61
+ height: 15px;
62
+ }
63
+
64
+ .extended .cornerTopLeft::before { top: 5px; }
65
+ .extended .cornerBottomLeft::before { bottom: 5px; }
66
+
67
+ .extended .cornerTopRight::before,
68
+ .extended .cornerBottomRight::before {
69
+ right: 5px;
70
+ width: 1px;
71
+ height: 15px;
72
+ }
73
+
74
+ .extended .cornerTopRight::before { top: 5px; }
75
+ .extended .cornerBottomRight::before { bottom: 5px; }
76
+
77
+ .extended .cornerTopLeft::after,
78
+ .extended .cornerTopRight::after {
79
+ top: 5px;
80
+ height: 1px;
81
+ width: 15px;
82
+ }
83
+
84
+ .extended .cornerTopLeft::after { left: 5px; }
85
+ .extended .cornerTopRight::after { right: 5px; }
86
+
87
+ .extended .cornerBottomLeft::after,
88
+ .extended .cornerBottomRight::after {
89
+ bottom: 5px;
90
+ height: 1px;
91
+ width: 15px;
92
+ }
93
+
94
+ .extended .cornerBottomLeft::after { left: 5px; }
95
+ .extended .cornerBottomRight::after { right: 5px; }
96
+
97
+ /* Ornate style - with decorative elements */
98
+ .ornate .corner {
99
+ width: 40px;
100
+ height: 40px;
101
+ }
102
+
103
+ .ornate::before {
104
+ content: '✦';
105
+ position: absolute;
106
+ top: -0.5em;
107
+ left: 50%;
108
+ transform: translateX(-50%);
109
+ color: var(--frame-color);
110
+ font-size: 1rem;
111
+ }
112
+
113
+ .ornate::after {
114
+ content: '✦';
115
+ position: absolute;
116
+ bottom: -0.5em;
117
+ left: 50%;
118
+ transform: translateX(-50%);
119
+ color: var(--frame-color);
120
+ font-size: 1rem;
121
+ }
122
+
123
+ /* Variants */
124
+ .gold { --frame-color: #c9a227; }
125
+ .bone { --frame-color: #d4c5a9; }
126
+ .blood { --frame-color: #8b1a1a; }
127
+ .iron { --frame-color: #4a4a4a; }
128
+ .cyan { --frame-color: #00f0ff; }
129
+
130
+ /* Glow effect */
131
+ .glow {
132
+ box-shadow: 0 0 20px rgba(201, 162, 39, 0.2);
133
+ }
134
+
135
+ .glow.cyan {
136
+ box-shadow: 0 0 20px rgba(0, 240, 255, 0.2);
137
+ }
138
+
139
+ .glow.blood {
140
+ box-shadow: 0 0 20px rgba(139, 26, 26, 0.3);
141
+ }
@@ -0,0 +1,64 @@
1
+ 'use client';
2
+
3
+ import { forwardRef, HTMLAttributes, ReactNode } from 'react';
4
+
5
+ export interface VoidFrameProps extends HTMLAttributes<HTMLDivElement> {
6
+ children: ReactNode;
7
+ variant?: 'gold' | 'bone' | 'blood' | 'iron' | 'cyan';
8
+ cornerStyle?: 'simple' | 'extended' | 'ornate';
9
+ glow?: boolean;
10
+ padding?: 'sm' | 'md' | 'lg' | 'xl';
11
+ }
12
+
13
+ const variantStyles = {
14
+ gold: { border: 'border-amber-600', corner: 'border-amber-600', glow: 'shadow-[0_0_20px_rgba(201,162,39,0.2)]', ornament: 'text-amber-600' },
15
+ bone: { border: 'border-stone-400', corner: 'border-stone-400', glow: 'shadow-[0_0_20px_rgba(212,197,169,0.2)]', ornament: 'text-stone-400' },
16
+ blood: { border: 'border-red-800', corner: 'border-red-800', glow: 'shadow-[0_0_20px_rgba(139,26,26,0.3)]', ornament: 'text-red-800' },
17
+ iron: { border: 'border-zinc-600', corner: 'border-zinc-600', glow: 'shadow-[0_0_20px_rgba(74,74,74,0.2)]', ornament: 'text-zinc-600' },
18
+ cyan: { border: 'border-cyan-400', corner: 'border-cyan-400', glow: 'shadow-[0_0_20px_rgba(0,240,255,0.2)]', ornament: 'text-cyan-400' },
19
+ };
20
+
21
+ const paddingClasses = {
22
+ sm: 'p-4',
23
+ md: 'p-8',
24
+ lg: 'p-12',
25
+ xl: 'p-16',
26
+ };
27
+
28
+ export const VoidFrame = forwardRef<HTMLDivElement, VoidFrameProps>(
29
+ ({ children, variant = 'gold', cornerStyle = 'simple', glow = false, padding = 'md', className = '', ...props }, ref) => {
30
+ const colors = variantStyles[variant];
31
+ const cornerSize = cornerStyle === 'ornate' ? 'w-10 h-10' : cornerStyle === 'extended' ? 'w-[30px] h-[30px]' : 'w-5 h-5';
32
+
33
+ return (
34
+ <div
35
+ ref={ref}
36
+ className={`
37
+ relative bg-black/50 border ${colors.border} ${paddingClasses[padding]}
38
+ ${glow ? colors.glow : ''}
39
+ ${className}
40
+ `}
41
+ {...props}
42
+ >
43
+ {/* Corners */}
44
+ <span className={`absolute -top-px -left-px ${cornerSize} border-t-2 border-l-2 ${colors.corner}`} />
45
+ <span className={`absolute -top-px -right-px ${cornerSize} border-t-2 border-r-2 ${colors.corner}`} />
46
+ <span className={`absolute -bottom-px -left-px ${cornerSize} border-b-2 border-l-2 ${colors.corner}`} />
47
+ <span className={`absolute -bottom-px -right-px ${cornerSize} border-b-2 border-r-2 ${colors.corner}`} />
48
+
49
+ {/* Ornate decorations */}
50
+ {cornerStyle === 'ornate' && (
51
+ <>
52
+ <span className={`absolute -top-[0.5em] left-1/2 -translate-x-1/2 ${colors.ornament}`}>✦</span>
53
+ <span className={`absolute -bottom-[0.5em] left-1/2 -translate-x-1/2 ${colors.ornament}`}>✦</span>
54
+ </>
55
+ )}
56
+
57
+ {children}
58
+ </div>
59
+ );
60
+ }
61
+ );
62
+
63
+ VoidFrame.displayName = 'VoidFrame';
64
+ export default VoidFrame;