@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,204 @@
1
+ /* tension-bar - Barre de tension/progression dramatique */
2
+ .container {
3
+ width: 100%;
4
+ position: relative;
5
+ font-family: var(--chaos-font-mono, 'Space Mono', monospace);
6
+ }
7
+
8
+ .labels {
9
+ display: flex;
10
+ justify-content: space-between;
11
+ margin-bottom: 0.5rem;
12
+ font-size: 0.65rem;
13
+ letter-spacing: 0.2em;
14
+ text-transform: uppercase;
15
+ }
16
+
17
+ .labelLeft {
18
+ color: var(--chaos-bone-dark, #666);
19
+ }
20
+
21
+ .labelRight {
22
+ color: var(--chaos-blood, #ff0040);
23
+ }
24
+
25
+ .track {
26
+ height: 8px;
27
+ background: var(--chaos-iron, #222);
28
+ position: relative;
29
+ overflow: hidden;
30
+ }
31
+
32
+ .fill {
33
+ height: 100%;
34
+ background: var(--chaos-blood, #ff0040);
35
+ transition: width 0.5s ease-out;
36
+ position: relative;
37
+ }
38
+
39
+ .fill::after {
40
+ content: '';
41
+ position: absolute;
42
+ right: 0;
43
+ top: 0;
44
+ bottom: 0;
45
+ width: 20px;
46
+ background: linear-gradient(to right, transparent, rgba(255, 255, 255, 0.3));
47
+ animation: shimmer 1.5s infinite;
48
+ }
49
+
50
+ @keyframes shimmer {
51
+ 0% { opacity: 0; }
52
+ 50% { opacity: 1; }
53
+ 100% { opacity: 0; }
54
+ }
55
+
56
+ /* Percentage display */
57
+ .percentage {
58
+ position: absolute;
59
+ right: 0;
60
+ top: -1.5rem;
61
+ font-size: 0.7rem;
62
+ color: var(--chaos-blood, #ff0040);
63
+ font-weight: bold;
64
+ }
65
+
66
+ /* Markers */
67
+ .markers {
68
+ display: flex;
69
+ justify-content: space-between;
70
+ margin-top: 0.3rem;
71
+ }
72
+
73
+ .marker {
74
+ width: 1px;
75
+ height: 6px;
76
+ background: var(--chaos-iron, #333);
77
+ }
78
+
79
+ .markerActive {
80
+ background: var(--chaos-blood, #ff0040);
81
+ }
82
+
83
+ /* Variant: gold */
84
+ .variantGold .fill {
85
+ background: linear-gradient(to right, var(--chaos-gold-dark, #8b7017), var(--chaos-gold, #c9a227));
86
+ }
87
+
88
+ .variantGold .labelRight,
89
+ .variantGold .percentage {
90
+ color: var(--chaos-gold, #c9a227);
91
+ }
92
+
93
+ .variantGold .markerActive {
94
+ background: var(--chaos-gold, #c9a227);
95
+ }
96
+
97
+ /* Variant: danger (pulsing when high) */
98
+ .variantDanger .fill {
99
+ background: var(--chaos-blood, #ff0040);
100
+ }
101
+
102
+ .variantDanger.high .fill {
103
+ animation: dangerPulse 0.5s ease-in-out infinite;
104
+ }
105
+
106
+ .variantDanger.high .track {
107
+ animation: dangerGlow 0.5s ease-in-out infinite;
108
+ }
109
+
110
+ @keyframes dangerPulse {
111
+ 0%, 100% { opacity: 1; }
112
+ 50% { opacity: 0.7; }
113
+ }
114
+
115
+ @keyframes dangerGlow {
116
+ 0%, 100% { box-shadow: 0 0 5px var(--chaos-blood, #ff0040); }
117
+ 50% { box-shadow: 0 0 15px var(--chaos-blood, #ff0040); }
118
+ }
119
+
120
+ /* Variant: segmented */
121
+ .variantSegmented .track {
122
+ display: flex;
123
+ gap: 2px;
124
+ background: transparent;
125
+ }
126
+
127
+ .segment {
128
+ flex: 1;
129
+ height: 8px;
130
+ background: var(--chaos-iron, #222);
131
+ transition: background 0.3s;
132
+ }
133
+
134
+ .segmentFilled {
135
+ background: var(--chaos-blood, #ff0040);
136
+ }
137
+
138
+ /* Variant: dramatic (with cracks) */
139
+ .variantDramatic .track {
140
+ height: 12px;
141
+ background:
142
+ linear-gradient(135deg, transparent 10%, var(--chaos-iron, #222) 10%, var(--chaos-iron, #222) 90%, transparent 90%);
143
+ }
144
+
145
+ .variantDramatic .fill::before {
146
+ content: '';
147
+ position: absolute;
148
+ inset: 0;
149
+ background:
150
+ repeating-linear-gradient(
151
+ 90deg,
152
+ transparent,
153
+ transparent 10px,
154
+ rgba(0, 0, 0, 0.2) 10px,
155
+ rgba(0, 0, 0, 0.2) 12px
156
+ );
157
+ }
158
+
159
+ /* Size variants */
160
+ .sizeSm .track,
161
+ .sizeSm .segment {
162
+ height: 4px;
163
+ }
164
+
165
+ .sizeLg .track,
166
+ .sizeLg .segment {
167
+ height: 16px;
168
+ }
169
+
170
+ /* With text inside */
171
+ .withText .track {
172
+ height: 30px;
173
+ display: flex;
174
+ align-items: center;
175
+ padding: 0 1rem;
176
+ }
177
+
178
+ .innerText {
179
+ position: absolute;
180
+ left: 1rem;
181
+ font-size: 0.7rem;
182
+ color: var(--chaos-bone, #e8e8e8);
183
+ z-index: 1;
184
+ text-transform: uppercase;
185
+ letter-spacing: 0.1em;
186
+ }
187
+
188
+ /* Animated stripes */
189
+ .animated .fill {
190
+ background: repeating-linear-gradient(
191
+ 45deg,
192
+ var(--chaos-blood, #ff0040),
193
+ var(--chaos-blood, #ff0040) 10px,
194
+ var(--chaos-blood-dark, #cc0033) 10px,
195
+ var(--chaos-blood-dark, #cc0033) 20px
196
+ );
197
+ background-size: 200% 100%;
198
+ animation: stripeMove 1s linear infinite;
199
+ }
200
+
201
+ @keyframes stripeMove {
202
+ 0% { background-position: 0 0; }
203
+ 100% { background-position: 28px 0; }
204
+ }
@@ -0,0 +1,122 @@
1
+ 'use client';
2
+
3
+ import { forwardRef, HTMLAttributes } from 'react';
4
+
5
+ export interface TensionBarProps extends HTMLAttributes<HTMLDivElement> {
6
+ value: number;
7
+ max?: number;
8
+ labelLeft?: string;
9
+ labelRight?: string;
10
+ showPercentage?: boolean;
11
+ showMarkers?: boolean;
12
+ markerCount?: number;
13
+ variant?: 'default' | 'gold' | 'danger' | 'segmented' | 'dramatic';
14
+ size?: 'sm' | 'md' | 'lg';
15
+ innerText?: string;
16
+ animated?: boolean;
17
+ dangerThreshold?: number;
18
+ }
19
+
20
+ const sizeHeights: Record<string, string> = {
21
+ sm: 'h-1',
22
+ md: 'h-2',
23
+ lg: 'h-4',
24
+ };
25
+
26
+ const variantColors: Record<string, { fill: string; text: string }> = {
27
+ default: { fill: 'bg-red-500', text: 'text-red-500' },
28
+ gold: { fill: 'bg-gradient-to-r from-amber-700 to-amber-500', text: 'text-amber-500' },
29
+ danger: { fill: 'bg-red-500', text: 'text-red-500' },
30
+ segmented: { fill: 'bg-red-500', text: 'text-red-500' },
31
+ dramatic: { fill: 'bg-red-500', text: 'text-red-500' },
32
+ };
33
+
34
+ export const TensionBar = forwardRef<HTMLDivElement, TensionBarProps>(
35
+ ({ value, max = 100, labelLeft, labelRight, showPercentage = false, showMarkers = false, markerCount = 10, variant = 'default', size = 'md', innerText, animated = false, dangerThreshold = 80, className, ...props }, ref) => {
36
+ const percentage = Math.min(100, Math.max(0, (value / max) * 100));
37
+ const isHigh = variant === 'danger' && percentage >= dangerThreshold;
38
+ const colors = variantColors[variant];
39
+ const height = sizeHeights[size];
40
+
41
+ const renderSegmented = () => {
42
+ const filledCount = Math.floor((percentage / 100) * markerCount);
43
+ return (
44
+ <div className="flex gap-0.5">
45
+ {Array.from({ length: markerCount }).map((_, i) => (
46
+ <div
47
+ key={i}
48
+ className={`
49
+ flex-1 ${height} transition-colors
50
+ ${i < filledCount ? colors.fill : 'bg-gray-800'}
51
+ `}
52
+ />
53
+ ))}
54
+ </div>
55
+ );
56
+ };
57
+
58
+ return (
59
+ <div ref={ref} className={`w-full relative font-mono ${className || ''}`} {...props}>
60
+ {(labelLeft || labelRight) && (
61
+ <div className="flex justify-between mb-2 text-[0.65rem] tracking-[0.2em] uppercase">
62
+ <span className="text-gray-500">{labelLeft}</span>
63
+ <span className={colors.text}>{labelRight}</span>
64
+ </div>
65
+ )}
66
+
67
+ <div className={`
68
+ relative overflow-hidden bg-gray-800
69
+ ${innerText ? 'h-8 flex items-center px-4' : height}
70
+ ${isHigh ? 'animate-pulse shadow-[0_0_10px_#ff0040]' : ''}
71
+ `}>
72
+ {innerText && (
73
+ <span className="absolute left-4 text-xs text-stone-200 uppercase tracking-widest z-10">
74
+ {innerText}
75
+ </span>
76
+ )}
77
+
78
+ {variant === 'segmented' ? (
79
+ renderSegmented()
80
+ ) : (
81
+ <div
82
+ className={`
83
+ h-full transition-[width] duration-500 ease-out relative
84
+ ${colors.fill}
85
+ ${animated ? 'bg-[length:200%_100%] animate-[stripeMove_1s_linear_infinite] bg-[repeating-linear-gradient(45deg,#ff0040,#ff0040_10px,#cc0033_10px,#cc0033_20px)]' : ''}
86
+ `}
87
+ style={{ width: `${percentage}%` }}
88
+ >
89
+ <div className="absolute right-0 top-0 bottom-0 w-5 bg-gradient-to-r from-transparent to-white/30 animate-pulse" />
90
+ </div>
91
+ )}
92
+
93
+ {showPercentage && (
94
+ <span className={`absolute -top-6 right-0 text-xs font-bold ${colors.text}`}>
95
+ {Math.round(percentage)}%
96
+ </span>
97
+ )}
98
+ </div>
99
+
100
+ {showMarkers && variant !== 'segmented' && (
101
+ <div className="flex justify-between mt-1">
102
+ {Array.from({ length: markerCount + 1 }).map((_, i) => {
103
+ const markerPercent = (i / markerCount) * 100;
104
+ return (
105
+ <div
106
+ key={i}
107
+ className={`
108
+ w-px h-1.5 transition-colors
109
+ ${markerPercent <= percentage ? colors.fill : 'bg-gray-700'}
110
+ `}
111
+ />
112
+ );
113
+ })}
114
+ </div>
115
+ )}
116
+ </div>
117
+ );
118
+ }
119
+ );
120
+
121
+ TensionBar.displayName = 'TensionBar';
122
+ export default TensionBar;
@@ -0,0 +1,66 @@
1
+ 'use client';
2
+
3
+ import { forwardRef, HTMLAttributes, ReactNode } from 'react';
4
+ import styles from './inscription.module.css';
5
+
6
+ export interface InscriptionProps extends HTMLAttributes<HTMLDivElement> {
7
+ /** Text content */
8
+ children: ReactNode;
9
+ /** Carving style */
10
+ effect?: 'carved' | 'deepCarved' | 'embossed' | 'weathered' | 'ancient' | 'roman';
11
+ /** Stone color variant */
12
+ variant?: 'bone' | 'marble' | 'granite' | 'obsidian' | 'gold';
13
+ /** Text size */
14
+ size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
15
+ /** Add stone texture overlay */
16
+ textured?: boolean;
17
+ /** Add decorative border */
18
+ bordered?: boolean;
19
+ /** Add crack effect */
20
+ cracked?: boolean;
21
+ /** HTML tag to render */
22
+ as?: 'div' | 'span' | 'h1' | 'h2' | 'h3' | 'h4' | 'p';
23
+ }
24
+
25
+ export const Inscription = forwardRef<HTMLDivElement, InscriptionProps>(
26
+ (
27
+ {
28
+ children,
29
+ effect = 'carved',
30
+ variant = 'bone',
31
+ size = 'md',
32
+ textured = false,
33
+ bordered = false,
34
+ cracked = false,
35
+ as: Component = 'div',
36
+ className,
37
+ ...props
38
+ },
39
+ ref
40
+ ) => {
41
+ const text = typeof children === 'string' ? children : '';
42
+
43
+ return (
44
+ <Component
45
+ ref={ref as React.Ref<HTMLDivElement>}
46
+ className={`
47
+ ${styles.inscription}
48
+ ${styles[effect]}
49
+ ${styles[variant]}
50
+ ${styles[size]}
51
+ ${textured ? styles.textured : ''}
52
+ ${bordered ? styles.bordered : ''}
53
+ ${cracked ? styles.cracked : ''}
54
+ ${className || ''}
55
+ `}
56
+ data-text={text}
57
+ {...props}
58
+ >
59
+ {children}
60
+ </Component>
61
+ );
62
+ }
63
+ );
64
+
65
+ Inscription.displayName = 'Inscription';
66
+ export default Inscription;
@@ -0,0 +1,160 @@
1
+ .inscription {
2
+ --stone-color: #d4c5a9;
3
+ --shadow-color: rgba(0, 0, 0, 0.5);
4
+ --highlight-color: rgba(255, 255, 255, 0.1);
5
+
6
+ font-family: 'Cinzel', serif;
7
+ color: var(--stone-color);
8
+ text-transform: uppercase;
9
+ letter-spacing: 0.2em;
10
+ position: relative;
11
+ }
12
+
13
+ /* Carved/engraved effect */
14
+ .carved {
15
+ text-shadow:
16
+ 1px 1px 1px var(--shadow-color),
17
+ -1px -1px 1px var(--highlight-color),
18
+ 0 0 3px rgba(0, 0, 0, 0.3);
19
+ background: linear-gradient(
20
+ 180deg,
21
+ rgba(255, 255, 255, 0.1) 0%,
22
+ transparent 50%,
23
+ rgba(0, 0, 0, 0.1) 100%
24
+ );
25
+ -webkit-background-clip: text;
26
+ background-clip: text;
27
+ }
28
+
29
+ /* Deep engraved effect */
30
+ .deepCarved {
31
+ text-shadow:
32
+ 2px 2px 2px var(--shadow-color),
33
+ -1px -1px 1px var(--highlight-color),
34
+ 1px 1px 4px rgba(0, 0, 0, 0.4),
35
+ inset 0 0 20px rgba(0, 0, 0, 0.2);
36
+ }
37
+
38
+ /* Raised/embossed effect */
39
+ .embossed {
40
+ text-shadow:
41
+ -1px -1px 1px var(--shadow-color),
42
+ 1px 1px 1px var(--highlight-color),
43
+ 0 0 5px rgba(255, 255, 255, 0.1);
44
+ }
45
+
46
+ /* Weathered stone effect */
47
+ .weathered {
48
+ opacity: 0.7;
49
+ filter: blur(0.3px);
50
+ text-shadow:
51
+ 1px 1px 2px var(--shadow-color),
52
+ -1px -1px 1px var(--highlight-color),
53
+ 0 0 8px rgba(0, 0, 0, 0.2);
54
+ }
55
+
56
+ .weathered::before {
57
+ content: attr(data-text);
58
+ position: absolute;
59
+ top: 0;
60
+ left: 0;
61
+ opacity: 0.3;
62
+ filter: blur(1px);
63
+ transform: translate(1px, 1px);
64
+ }
65
+
66
+ /* Ancient/runic style */
67
+ .ancient {
68
+ font-family: 'UnifrakturMaguntia', serif;
69
+ letter-spacing: 0.1em;
70
+ text-shadow:
71
+ 2px 2px 3px var(--shadow-color),
72
+ -1px -1px 2px var(--highlight-color);
73
+ }
74
+
75
+ /* Roman numerals style */
76
+ .roman {
77
+ font-weight: 700;
78
+ letter-spacing: 0.3em;
79
+ text-shadow:
80
+ 1px 2px 2px var(--shadow-color),
81
+ -1px -1px 1px var(--highlight-color);
82
+ }
83
+
84
+ /* Stone texture overlay */
85
+ .textured::after {
86
+ content: '';
87
+ position: absolute;
88
+ inset: -10px;
89
+ background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 100 100' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)'/%3E%3C/svg%3E");
90
+ opacity: 0.05;
91
+ mix-blend-mode: overlay;
92
+ pointer-events: none;
93
+ }
94
+
95
+ /* Color variants */
96
+ .bone { --stone-color: #d4c5a9; }
97
+ .marble { --stone-color: #e8e8e8; }
98
+ .granite { --stone-color: #6a6a6a; }
99
+ .obsidian { --stone-color: #2a2a2a; --shadow-color: rgba(255, 255, 255, 0.2); --highlight-color: rgba(0, 0, 0, 0.3); }
100
+ .gold { --stone-color: #c9a227; }
101
+
102
+ /* Size variants */
103
+ .xs { font-size: 0.75rem; letter-spacing: 0.15em; }
104
+ .sm { font-size: 1rem; letter-spacing: 0.2em; }
105
+ .md { font-size: 1.5rem; letter-spacing: 0.2em; }
106
+ .lg { font-size: 2.5rem; letter-spacing: 0.25em; }
107
+ .xl { font-size: 4rem; letter-spacing: 0.3em; }
108
+
109
+ /* Decorative border */
110
+ .bordered {
111
+ padding: 1em 1.5em;
112
+ border: 1px solid var(--stone-color);
113
+ position: relative;
114
+ }
115
+
116
+ .bordered::before,
117
+ .bordered::after {
118
+ content: '';
119
+ position: absolute;
120
+ width: 10px;
121
+ height: 10px;
122
+ border: 1px solid var(--stone-color);
123
+ }
124
+
125
+ .bordered::before {
126
+ top: -5px;
127
+ left: -5px;
128
+ border-right: none;
129
+ border-bottom: none;
130
+ }
131
+
132
+ .bordered::after {
133
+ bottom: -5px;
134
+ right: -5px;
135
+ border-left: none;
136
+ border-top: none;
137
+ }
138
+
139
+ /* Crack effect */
140
+ .cracked {
141
+ position: relative;
142
+ }
143
+
144
+ .cracked::before {
145
+ content: '';
146
+ position: absolute;
147
+ top: 50%;
148
+ left: 30%;
149
+ width: 40%;
150
+ height: 1px;
151
+ background: linear-gradient(
152
+ 90deg,
153
+ transparent 0%,
154
+ rgba(0, 0, 0, 0.3) 20%,
155
+ rgba(0, 0, 0, 0.5) 50%,
156
+ rgba(0, 0, 0, 0.3) 80%,
157
+ transparent 100%
158
+ );
159
+ transform: rotate(-5deg);
160
+ }
@@ -0,0 +1,91 @@
1
+ 'use client';
2
+
3
+ import { forwardRef, HTMLAttributes, ReactNode } from 'react';
4
+
5
+ export interface InscriptionProps extends HTMLAttributes<HTMLDivElement> {
6
+ children: ReactNode;
7
+ effect?: 'carved' | 'deepCarved' | 'embossed' | 'weathered' | 'ancient' | 'roman';
8
+ variant?: 'bone' | 'marble' | 'granite' | 'obsidian' | 'gold';
9
+ size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
10
+ textured?: boolean;
11
+ bordered?: boolean;
12
+ cracked?: boolean;
13
+ as?: 'div' | 'span' | 'h1' | 'h2' | 'h3' | 'h4' | 'p';
14
+ }
15
+
16
+ const variantColors = {
17
+ bone: 'text-stone-300',
18
+ marble: 'text-gray-200',
19
+ granite: 'text-gray-500',
20
+ obsidian: 'text-zinc-700',
21
+ gold: 'text-amber-500',
22
+ };
23
+
24
+ const sizeClasses = {
25
+ xs: 'text-xs tracking-[0.15em]',
26
+ sm: 'text-base tracking-[0.2em]',
27
+ md: 'text-2xl tracking-[0.2em]',
28
+ lg: 'text-4xl tracking-[0.25em]',
29
+ xl: 'text-6xl tracking-[0.3em]',
30
+ };
31
+
32
+ const effectStyles = {
33
+ carved: '[text-shadow:1px_1px_1px_rgba(0,0,0,0.5),-1px_-1px_1px_rgba(255,255,255,0.1),0_0_3px_rgba(0,0,0,0.3)]',
34
+ deepCarved: '[text-shadow:2px_2px_2px_rgba(0,0,0,0.5),-1px_-1px_1px_rgba(255,255,255,0.1),1px_1px_4px_rgba(0,0,0,0.4)]',
35
+ embossed: '[text-shadow:-1px_-1px_1px_rgba(0,0,0,0.5),1px_1px_1px_rgba(255,255,255,0.1),0_0_5px_rgba(255,255,255,0.1)]',
36
+ weathered: 'opacity-70 blur-[0.3px] [text-shadow:1px_1px_2px_rgba(0,0,0,0.5),-1px_-1px_1px_rgba(255,255,255,0.1),0_0_8px_rgba(0,0,0,0.2)]',
37
+ ancient: "font-['UnifrakturMaguntia',serif] tracking-[0.1em] [text-shadow:2px_2px_3px_rgba(0,0,0,0.5),-1px_-1px_2px_rgba(255,255,255,0.1)]",
38
+ roman: 'font-bold tracking-[0.3em] [text-shadow:1px_2px_2px_rgba(0,0,0,0.5),-1px_-1px_1px_rgba(255,255,255,0.1)]',
39
+ };
40
+
41
+ export const Inscription = forwardRef<HTMLDivElement, InscriptionProps>(
42
+ ({ children, effect = 'carved', variant = 'bone', size = 'md', textured = false, bordered = false, cracked = false, as: Component = 'div', className = '', ...props }, ref) => {
43
+ const text = typeof children === 'string' ? children : '';
44
+
45
+ return (
46
+ <Component
47
+ ref={ref as React.Ref<HTMLDivElement>}
48
+ className={`
49
+ font-['Cinzel',serif] uppercase relative
50
+ ${variantColors[variant]}
51
+ ${sizeClasses[size]}
52
+ ${effectStyles[effect]}
53
+ ${bordered ? 'p-4 px-6 border border-current' : ''}
54
+ ${className}
55
+ `}
56
+ data-text={text}
57
+ {...props}
58
+ >
59
+ {children}
60
+
61
+ {textured && (
62
+ <span
63
+ className="absolute inset-[-10px] opacity-5 mix-blend-overlay pointer-events-none"
64
+ style={{
65
+ backgroundImage: `url("data:image/svg+xml,%3Csvg viewBox='0 0 100 100' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)'/%3E%3C/svg%3E")`,
66
+ }}
67
+ />
68
+ )}
69
+
70
+ {bordered && (
71
+ <>
72
+ <span className="absolute -top-[5px] -left-[5px] w-2.5 h-2.5 border border-current border-r-0 border-b-0" />
73
+ <span className="absolute -bottom-[5px] -right-[5px] w-2.5 h-2.5 border border-current border-l-0 border-t-0" />
74
+ </>
75
+ )}
76
+
77
+ {cracked && (
78
+ <span
79
+ className="absolute top-1/2 left-[30%] w-[40%] h-px -rotate-[5deg]"
80
+ style={{
81
+ background: 'linear-gradient(90deg, transparent 0%, rgba(0,0,0,0.3) 20%, rgba(0,0,0,0.5) 50%, rgba(0,0,0,0.3) 80%, transparent 100%)',
82
+ }}
83
+ />
84
+ )}
85
+ </Component>
86
+ );
87
+ }
88
+ );
89
+
90
+ Inscription.displayName = 'Inscription';
91
+ export default Inscription;