AARIFSHABIR commited on
Commit
3fe476d
·
verified ·
1 Parent(s): ec545fe

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. index.html +607 -19
index.html CHANGED
@@ -1,19 +1,607 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Orbital UI Customizer</title>
7
+
8
+ <!-- Fonts -->
9
+ <link rel="preconnect" href="https://fonts.googleapis.com">
10
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600;800&family=Space+Grotesk:wght@300;500;700&display=swap" rel="stylesheet">
12
+
13
+ <!-- Icons -->
14
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
15
+
16
+ <!-- Tailwind CSS -->
17
+ <script src="https://cdn.tailwindcss.com"></script>
18
+ <script>
19
+ tailwind.config = {
20
+ theme: {
21
+ extend: {
22
+ fontFamily: {
23
+ sans: ['Inter', 'sans-serif'],
24
+ display: ['Space Grotesk', 'sans-serif'],
25
+ },
26
+ colors: {
27
+ brand: 'var(--brand-color)',
28
+ surface: 'rgba(255, 255, 255, 0.05)',
29
+ surfaceHover: 'rgba(255, 255, 255, 0.1)',
30
+ }
31
+ }
32
+ }
33
+ }
34
+ </script>
35
+
36
+ <style>
37
+ /* CSS Variables for Dynamic Theming */
38
+ :root {
39
+ --brand-color: #6366f1;
40
+ --bg-gradient-start: #0f172a;
41
+ --bg-gradient-end: #1e293b;
42
+ --glass-blur: 16px;
43
+ --glass-opacity: 0.1;
44
+ --border-radius: 1rem;
45
+ --animation-speed: 20s;
46
+ --glow-intensity: 0.5;
47
+ }
48
+
49
+ body {
50
+ background: linear-gradient(135deg, var(--bg-gradient-start), var(--bg-gradient-end));
51
+ color: white;
52
+ overflow-x: hidden;
53
+ transition: background 0.5s ease;
54
+ }
55
+
56
+ /* --- Custom Scrollbar --- */
57
+ ::-webkit-scrollbar {
58
+ width: 6px;
59
+ }
60
+ ::-webkit-scrollbar-track {
61
+ background: rgba(0,0,0,0.2);
62
+ }
63
+ ::-webkit-scrollbar-thumb {
64
+ background: var(--brand-color);
65
+ border-radius: 10px;
66
+ }
67
+
68
+ /* --- 3D Orbital Scene --- */
69
+ .scene-container {
70
+ perspective: 1000px;
71
+ width: 100%;
72
+ height: 400px;
73
+ display: flex;
74
+ align-items: center;
75
+ justify-content: center;
76
+ position: relative;
77
+ overflow: hidden;
78
+ }
79
+
80
+ .orbital-system {
81
+ position: relative;
82
+ width: 200px;
83
+ height: 200px;
84
+ transform-style: preserve-3d;
85
+ animation: rotateSystem var(--animation-speed) linear infinite;
86
+ }
87
+
88
+ .planet {
89
+ width: 100px;
90
+ height: 100px;
91
+ border-radius: 50%;
92
+ background: radial-gradient(circle at 30% 30%, var(--brand-color), #000);
93
+ box-shadow: 0 0 50px var(--brand-color);
94
+ position: absolute;
95
+ top: 50%;
96
+ left: 50%;
97
+ transform: translate(-50%, -50%);
98
+ z-index: 10;
99
+ transition: all 0.3s ease;
100
+ }
101
+
102
+ .orbit-ring {
103
+ position: absolute;
104
+ top: 50%;
105
+ left: 50%;
106
+ border: 2px solid rgba(255, 255, 255, 0.1);
107
+ border-radius: 50%;
108
+ transform: translate(-50%, -50%) rotateX(70deg);
109
+ transform-style: preserve-3d;
110
+ }
111
+
112
+ .satellite {
113
+ width: 20px;
114
+ height: 20px;
115
+ background: white;
116
+ border-radius: 50%;
117
+ position: absolute;
118
+ top: -10px;
119
+ left: 50%;
120
+ transform: translateX(-50%) rotateX(-70deg);
121
+ box-shadow: 0 0 15px white;
122
+ }
123
+
124
+ /* Dynamic Orbit Sizes */
125
+ .ring-1 { width: 200px; height: 200px; animation: spin 10s linear infinite; }
126
+ .ring-2 { width: 300px; height: 300px; animation: spin 15s linear infinite reverse; border-color: var(--brand-color); }
127
+ .ring-3 { width: 400px; height: 400px; animation: spin 25s linear infinite; }
128
+
129
+ @keyframes rotateSystem {
130
+ 0% { transform: rotateY(0deg); }
131
+ 100% { transform: rotateY(360deg); }
132
+ }
133
+
134
+ @keyframes spin {
135
+ 0% { transform: translate(-50%, -50%) rotateX(70deg) rotateZ(0deg); }
136
+ 100% { transform: translate(-50%, -50%) rotateX(70deg) rotateZ(360deg); }
137
+ }
138
+
139
+ /* --- Glassmorphism UI --- */
140
+ .glass-panel {
141
+ background: rgba(255, 255, 255, var(--glass-opacity));
142
+ backdrop-filter: blur(var(--glass-blur));
143
+ -webkit-backdrop-filter: blur(var(--glass-blur));
144
+ border: 1px solid rgba(255, 255, 255, 0.1);
145
+ border-radius: var(--border-radius);
146
+ box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.37);
147
+ transition: all 0.3s ease;
148
+ }
149
+
150
+ .glass-input {
151
+ background: rgba(0, 0, 0, 0.2);
152
+ border: 1px solid rgba(255, 255, 255, 0.1);
153
+ color: white;
154
+ transition: all 0.2s;
155
+ }
156
+ .glass-input:focus {
157
+ outline: none;
158
+ border-color: var(--brand-color);
159
+ box-shadow: 0 0 0 2px rgba(99, 102, 241, 0.2);
160
+ }
161
+
162
+ /* --- Range Slider Styling --- */
163
+ input[type=range] {
164
+ -webkit-appearance: none;
165
+ width: 100%;
166
+ background: transparent;
167
+ }
168
+ input[type=range]::-webkit-slider-thumb {
169
+ -webkit-appearance: none;
170
+ height: 16px;
171
+ width: 16px;
172
+ border-radius: 50%;
173
+ background: var(--brand-color);
174
+ cursor: pointer;
175
+ margin-top: -6px;
176
+ box-shadow: 0 0 10px var(--brand-color);
177
+ }
178
+ input[type=range]::-webkit-slider-runnable-track {
179
+ width: 100%;
180
+ height: 4px;
181
+ cursor: pointer;
182
+ background: rgba(255,255,255,0.2);
183
+ border-radius: 2px;
184
+ }
185
+
186
+ /* --- Color Swatches --- */
187
+ .swatch {
188
+ width: 32px;
189
+ height: 32px;
190
+ border-radius: 50%;
191
+ cursor: pointer;
192
+ border: 2px solid transparent;
193
+ transition: transform 0.2s;
194
+ }
195
+ .swatch:hover { transform: scale(1.1); }
196
+ .swatch.active { border-color: white; box-shadow: 0 0 10px currentColor; }
197
+
198
+ /* --- Toast Notification --- */
199
+ .toast {
200
+ position: fixed;
201
+ bottom: 20px;
202
+ right: 20px;
203
+ background: var(--brand-color);
204
+ color: white;
205
+ padding: 12px 24px;
206
+ border-radius: 8px;
207
+ box-shadow: 0 10px 30px rgba(0,0,0,0.5);
208
+ transform: translateY(100px);
209
+ opacity: 0;
210
+ transition: all 0.4s cubic-bezier(0.68, -0.55, 0.27, 1.55);
211
+ z-index: 1000;
212
+ font-weight: 600;
213
+ }
214
+ .toast.show {
215
+ transform: translateY(0);
216
+ opacity: 1;
217
+ }
218
+
219
+ /* --- Grid Pattern Background --- */
220
+ .bg-grid {
221
+ position: fixed;
222
+ top: 0; left: 0; width: 100%; height: 100%;
223
+ background-image: linear-gradient(rgba(255, 255, 255, 0.03) 1px, transparent 1px),
224
+ linear-gradient(90deg, rgba(255, 255, 255, 0.03) 1px, transparent 1px);
225
+ background-size: 40px 40px;
226
+ pointer-events: none;
227
+ z-index: -1;
228
+ }
229
+ </style>
230
+ </head>
231
+ <body class="min-h-screen flex flex-col font-sans selection:bg-brand selection:text-white">
232
+
233
+ <!-- Background Grid -->
234
+ <div class="bg-grid"></div>
235
+
236
+ <!-- Header -->
237
+ <header class="w-full p-6 flex justify-between items-center z-50 relative">
238
+ <div class="flex items-center gap-3">
239
+ <div class="w-10 h-10 rounded-lg bg-gradient-to-br from-white/20 to-white/5 flex items-center justify-center border border-white/10 shadow-lg">
240
+ <i class="fa-solid fa-layer-group text-brand text-xl"></i>
241
+ </div>
242
+ <div>
243
+ <h1 class="font-display font-bold text-2xl tracking-tight">Orbital UI</h1>
244
+ <p class="text-xs text-gray-400 font-medium tracking-wider uppercase">Customizer Engine v1.0</p>
245
+ </div>
246
+ </div>
247
+ <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="text-xs text-gray-400 hover:text-white transition-colors flex items-center gap-2 group">
248
+ <span>Built with anycoder</span>
249
+ <i class="fa-solid fa-arrow-up-right-from-square group-hover:translate-x-1 group-hover:-translate-y-1 transition-transform"></i>
250
+ </a>
251
+ </header>
252
+
253
+ <!-- Main Content -->
254
+ <main class="flex-grow container mx-auto px-4 py-4 flex flex-col lg:flex-row gap-8 relative z-10">
255
+
256
+ <!-- Left Column: Preview Area -->
257
+ <div class="lg:w-1/2 flex flex-col gap-6">
258
+
259
+ <!-- 3D Preview -->
260
+ <div class="glass-panel p-1 flex-grow min-h-[400px] relative overflow-hidden group">
261
+ <div class="absolute top-4 left-4 z-20">
262
+ <span class="px-3 py-1 rounded-full bg-black/30 border border-white/10 text-xs font-mono text-gray-300 backdrop-blur-md">
263
+ <i class="fa-solid fa-eye mr-2"></i>Live Preview
264
+ </span>
265
+ </div>
266
+
267
+ <!-- The 3D Scene -->
268
+ <div class="scene-container bg-gradient-to-b from-transparent to-black/20 rounded-xl" id="previewContainer">
269
+ <div class="orbital-system">
270
+ <div class="planet"></div>
271
+ <div class="orbit-ring ring-1"><div class="satellite"></div></div>
272
+ <div class="orbit-ring ring-2"><div class="satellite"></div></div>
273
+ <div class="orbit-ring ring-3"><div class="satellite"></div></div>
274
+ </div>
275
+ </div>
276
+
277
+ <!-- Reflection/Gloss effect -->
278
+ <div class="absolute inset-0 bg-gradient-to-tr from-white/5 to-transparent pointer-events-none rounded-xl"></div>
279
+ </div>
280
+
281
+ <!-- Code Output Preview (Mini) -->
282
+ <div class="glass-panel p-4">
283
+ <div class="flex justify-between items-center mb-2">
284
+ <h3 class="text-sm font-semibold text-gray-300"><i class="fa-solid fa-code mr-2"></i>Generated CSS</h3>
285
+ <button onclick="copyCSS()" class="text-xs bg-white/10 hover:bg-white/20 px-2 py-1 rounded transition-colors">
286
+ <i class="fa-regular fa-copy"></i> Copy
287
+ </button>
288
+ </div>
289
+ <div class="bg-black/40 rounded-lg p-3 font-mono text-xs text-gray-400 overflow-x-auto border border-white/5">
290
+ <code id="cssOutput">
291
+ :root {<br>
292
+ &nbsp;&nbsp;--brand-color: #6366f1;<br>
293
+ &nbsp;&nbsp;--border-radius: 1rem;<br>
294
+ }
295
+ </code>
296
+ </div>
297
+ </div>
298
+ </div>
299
+
300
+ <!-- Right Column: Controls -->
301
+ <div class="lg:w-1/2 flex flex-col gap-6">
302
+
303
+ <!-- Controls Container -->
304
+ <div class="glass-panel p-6 lg:p-8 h-full flex flex-col">
305
+ <h2 class="font-display text-2xl font-bold mb-6 flex items-center gap-2">
306
+ <i class="fa-solid fa-sliders text-brand"></i> Configuration
307
+ </h2>
308
+
309
+ <div class="space-y-8 overflow-y-auto pr-2 custom-scrollbar flex-grow">
310
+
311
+ <!-- Section: Colors -->
312
+ <div class="space-y-3">
313
+ <label class="text-sm font-medium text-gray-300 uppercase tracking-wider">Brand Color</label>
314
+ <div class="flex flex-wrap gap-3" id="colorPalette">
315
+ <!-- Generated by JS -->
316
+ </div>
317
+ <div class="flex items-center gap-3 mt-2">
318
+ <input type="color" id="customColorPicker" class="w-8 h-8 rounded cursor-pointer bg-transparent border-0 p-0" value="#6366f1">
319
+ <span class="text-xs text-gray-400">Custom Hex</span>
320
+ <input type="text" id="hexInput" class="glass-input px-2 py-1 rounded text-xs w-24 font-mono" value="#6366f1">
321
+ </div>
322
+ </div>
323
+
324
+ <hr class="border-white/10">
325
+
326
+ <!-- Section: Geometry -->
327
+ <div class="space-y-6">
328
+ <div class="space-y-2">
329
+ <div class="flex justify-between">
330
+ <label class="text-sm text-gray-300">Border Radius</label>
331
+ <span id="radiusVal" class="text-xs font-mono text-brand">16px</span>
332
+ </div>
333
+ <input type="range" min="0" max="50" value="16" id="radiusRange">
334
+ </div>
335
+
336
+ <div class="space-y-2">
337
+ <div class="flex justify-between">
338
+ <label class="text-sm text-gray-300">Glass Blur</label>
339
+ <span id="blurVal" class="text-xs font-mono text-brand">16px</span>
340
+ </div>
341
+ <input type="range" min="0" max="40" value="16" id="blurRange">
342
+ </div>
343
+
344
+ <div class="space-y-2">
345
+ <div class="flex justify-between">
346
+ <label class="text-sm text-gray-300">Glass Opacity</label>
347
+ <span id="opacityVal" class="text-xs font-mono text-brand">10%</span>
348
+ </div>
349
+ <input type="range" min="0" max="50" value="10" id="opacityRange">
350
+ </div>
351
+ </div>
352
+
353
+ <hr class="border-white/10">
354
+
355
+ <!-- Section: Animation -->
356
+ <div class="space-y-2">
357
+ <div class="flex justify-between">
358
+ <label class="text-sm text-gray-300">Orbit Speed</label>
359
+ <span id="speedVal" class="text-xs font-mono text-brand">Normal</span>
360
+ </div>
361
+ <input type="range" min="1" max="50" value="20" id="speedRange">
362
+ </div>
363
+
364
+ <!-- Section: Background -->
365
+ <div class="space-y-3">
366
+ <label class="text-sm font-medium text-gray-300 uppercase tracking-wider">Background Mood</label>
367
+ <div class="grid grid-cols-3 gap-2">
368
+ <button class="bg-mood-btn p-2 rounded border border-white/10 hover:bg-white/5 text-xs transition-all active-mood" data-start="#0f172a" data-end="#1e293b">Midnight</button>
369
+ <button class="bg-mood-btn p-2 rounded border border-white/10 hover:bg-white/5 text-xs transition-all" data-start="#2e1065" data-end="#4c1d95">Deep Purple</button>
370
+ <button class="bg-mood-btn p-2 rounded border border-white/10 hover:bg-white/5 text-xs transition-all" data-start="#1e1b4b" data-end="#312e81">Indigo</button>
371
+ <button class="bg-mood-btn p-2 rounded border border-white/10 hover:bg-white/5 text-xs transition-all" data-start="#111827" data-end="#374151">Obsidian</button>
372
+ <button class="bg-mood-btn p-2 rounded border border-white/10 hover:bg-white/5 text-xs transition-all" data-start="#4c0519" data-end="#881337">Rose Noir</button>
373
+ <button class="bg-mood-btn p-2 rounded border border-white/10 hover:bg-white/5 text-xs transition-all" data-start="#064e3b" data-end="#065f46">Emerald</button>
374
+ </div>
375
+ </div>
376
+
377
+ </div>
378
+
379
+ <!-- Action Buttons -->
380
+ <div class="mt-8 pt-6 border-t border-white/10 flex gap-4">
381
+ <button onclick="randomize()" class="flex-1 py-3 rounded-lg border border-white/20 hover:bg-white/5 transition-all font-medium text-sm flex items-center justify-center gap-2">
382
+ <i class="fa-solid fa-shuffle"></i> Randomize
383
+ </button>
384
+ <button onclick="exportConfig()" class="flex-1 py-3 rounded-lg bg-brand hover:brightness-110 transition-all font-bold text-sm shadow-lg shadow-brand/25 flex items-center justify-center gap-2">
385
+ <i class="fa-solid fa-download"></i> Export JSON
386
+ </button>
387
+ </div>
388
+ </div>
389
+ </div>
390
+ </main>
391
+
392
+ <!-- Toast Element -->
393
+ <div id="toast" class="toast">
394
+ <i class="fa-solid fa-check-circle mr-2"></i> Configuration Copied!
395
+ </div>
396
+
397
+ <script>
398
+ // --- State Management ---
399
+ const state = {
400
+ brandColor: '#6366f1',
401
+ borderRadius: 16,
402
+ glassBlur: 16,
403
+ glassOpacity: 10,
404
+ animationSpeed: 20,
405
+ bgStart: '#0f172a',
406
+ bgEnd: '#1e293b'
407
+ };
408
+
409
+ const presets = [
410
+ '#ef4444', '#f97316', '#f59e0b', '#84cc16',
411
+ '#10b981', '#06b6d4', '#3b82f6', '#6366f1',
412
+ '#8b5cf6', '#d946ef', '#f43f5e', '#ffffff'
413
+ ];
414
+
415
+ // --- DOM Elements ---
416
+ const root = document.documentElement;
417
+ const colorContainer = document.getElementById('colorPalette');
418
+ const customPicker = document.getElementById('customColorPicker');
419
+ const hexInput = document.getElementById('hexInput');
420
+
421
+ // --- Initialization ---
422
+ function init() {
423
+ renderColorPalette();
424
+ setupEventListeners();
425
+ updateUI();
426
+ }
427
+
428
+ // --- Render Functions ---
429
+ function renderColorPalette() {
430
+ colorContainer.innerHTML = '';
431
+ presets.forEach(color => {
432
+ const div = document.createElement('div');
433
+ div.className = `swatch ${state.brandColor === color ? 'active' : ''}`;
434
+ div.style.backgroundColor = color;
435
+ div.style.color = color; // for shadow
436
+ div.onclick = () => setColor(color);
437
+ colorContainer.appendChild(div);
438
+ });
439
+ }
440
+
441
+ // --- Logic Functions ---
442
+ function setColor(color) {
443
+ state.brandColor = color;
444
+ root.style.setProperty('--brand-color', color);
445
+
446
+ // Update UI inputs
447
+ customPicker.value = color;
448
+ hexInput.value = color;
449
+
450
+ // Update active state in palette
451
+ document.querySelectorAll('.swatch').forEach(el => {
452
+ el.classList.toggle('active', el.style.backgroundColor === color || rgbToHex(el.style.backgroundColor) === color);
453
+ });
454
+
455
+ updateCSSOutput();
456
+ }
457
+
458
+ function setRadius(val) {
459
+ state.borderRadius = val;
460
+ root.style.setProperty('--border-radius', `${val}px`);
461
+ document.getElementById('radiusVal').innerText = `${val}px`;
462
+ updateCSSOutput();
463
+ }
464
+
465
+ function setBlur(val) {
466
+ state.glassBlur = val;
467
+ root.style.setProperty('--glass-blur', `${val}px`);
468
+ document.getElementById('blurVal').innerText = `${val}px`;
469
+ }
470
+
471
+ function setOpacity(val) {
472
+ state.glassOpacity = val;
473
+ root.style.setProperty('--glass-opacity', val / 100);
474
+ document.getElementById('opacityVal').innerText = `${val}%`;
475
+ }
476
+
477
+ function setSpeed(val) {
478
+ // Invert logic: lower value = faster speed (lower duration)
479
+ // Map 1-50 to 50s - 1s
480
+ const duration = 51 - val;
481
+ state.animationSpeed = duration;
482
+ root.style.setProperty('--animation-speed', `${duration}s`);
483
+
484
+ let label = "Normal";
485
+ if(val > 40) label = "Warp Speed";
486
+ else if(val > 25) label = "Fast";
487
+ else if(val < 10) label = "Slow Motion";
488
+
489
+ document.getElementById('speedVal').innerText = label;
490
+ }
491
+
492
+ function setBackground(start, end, btn) {
493
+ state.bgStart = start;
494
+ state.bgEnd = end;
495
+ root.style.setProperty('--bg-gradient-start', start);
496
+ root.style.setProperty('--bg-gradient-end', end);
497
+
498
+ // Update active button state
499
+ document.querySelectorAll('.bg-mood-btn').forEach(b => {
500
+ b.classList.remove('bg-white/20', 'border-brand');
501
+ b.classList.add('border-white/10');
502
+ });
503
+ btn.classList.remove('border-white/10');
504
+ btn.classList.add('bg-white/20', 'border-brand');
505
+ }
506
+
507
+ // --- Event Listeners ---
508
+ function setupEventListeners() {
509
+ // Range Inputs
510
+ document.getElementById('radiusRange').addEventListener('input', (e) => setRadius(e.target.value));
511
+ document.getElementById('blurRange').addEventListener('input', (e) => setBlur(e.target.value));
512
+ document.getElementById('opacityRange').addEventListener('input', (e) => setOpacity(e.target.value));
513
+ document.getElementById('speedRange').addEventListener('input', (e) => setSpeed(e.target.value));
514
+
515
+ // Color Inputs
516
+ customPicker.addEventListener('input', (e) => setColor(e.target.value));
517
+ hexInput.addEventListener('change', (e) => {
518
+ let hex = e.target.value;
519
+ if(!hex.startsWith('#')) hex = '#' + hex;
520
+ if(/^#[0-9A-F]{6}$/i.test(hex)) setColor(hex);
521
+ });
522
+
523
+ // Background Buttons
524
+ document.querySelectorAll('.bg-mood-btn').forEach(btn => {
525
+ btn.addEventListener('click', () => {
526
+ setBackground(btn.dataset.start, btn.dataset.end, btn);
527
+ });
528
+ });
529
+ }
530
+
531
+ // --- Utilities ---
532
+ function updateCSSOutput() {
533
+ const code = `:root {
534
+ --brand-color: ${state.brandColor};
535
+ --border-radius: ${state.borderRadius}px;
536
+ --glass-blur: ${state.glassBlur}px;
537
+ --glass-opacity: ${state.glassOpacity / 100};
538
+ --animation-speed: ${state.animationSpeed}s;
539
+ }`;
540
+ document.getElementById('cssOutput').innerHTML = code.replace(/\n/g, '<br>').replace(/ /g, '&nbsp;');
541
+ }
542
+
543
+ function updateUI() {
544
+ // Trigger initial updates to sync UI with state
545
+ setColor(state.brandColor);
546
+ setRadius(state.borderRadius);
547
+ setBlur(state.glassBlur);
548
+ setOpacity(state.glassOpacity);
549
+ setSpeed(20); // Default middle
550
+ }
551
+
552
+ function rgbToHex(rgb) {
553
+ if(!rgb) return '';
554
+ if(rgb.startsWith('#')) return rgb;
555
+ // Basic rgb to hex conversion if needed for comparison
556
+ // Not fully implemented as inputs are usually hex
557
+ return rgb;
558
+ }
559
+
560
+ function showToast(msg) {
561
+ const toast = document.getElementById('toast');
562
+ toast.innerHTML = `<i class="fa-solid fa-check-circle mr-2"></i> ${msg}`;
563
+ toast.classList.add('show');
564
+ setTimeout(() => toast.classList.remove('show'), 3000);
565
+ }
566
+
567
+ function copyCSS() {
568
+ const code = document.getElementById('cssOutput').innerText;
569
+ navigator.clipboard.writeText(code).then(() => {
570
+ showToast("CSS copied to clipboard!");
571
+ });
572
+ }
573
+
574
+ function randomize() {
575
+ const randomColor = presets[Math.floor(Math.random() * presets.length)];
576
+ const randomRadius = Math.floor(Math.random() * 40);
577
+ const randomSpeed = Math.floor(Math.random() * 50) + 1;
578
+
579
+ setColor(randomColor);
580
+
581
+ // Update inputs visually
582
+ document.getElementById('radiusRange').value = randomRadius;
583
+ setRadius(randomRadius);
584
+
585
+ document.getElementById('speedRange').value = randomSpeed;
586
+ setSpeed(randomSpeed);
587
+
588
+ showToast("Randomized Style!");
589
+ }
590
+
591
+ function exportConfig() {
592
+ const dataStr = "data:text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(state, null, 2));
593
+ const downloadAnchorNode = document.createElement('a');
594
+ downloadAnchorNode.setAttribute("href", dataStr);
595
+ downloadAnchorNode.setAttribute("download", "orbital-theme-config.json");
596
+ document.body.appendChild(downloadAnchorNode);
597
+ downloadAnchorNode.click();
598
+ downloadAnchorNode.remove();
599
+ showToast("Config Downloaded!");
600
+ }
601
+
602
+ // Run
603
+ init();
604
+
605
+ </script>
606
+ </body>
607
+ </html>