xaura 1.0.0

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.
@@ -0,0 +1,79 @@
1
+ /* ============================================================
2
+ CSS CUSTOM PROPERTIES — xaura DESIGN TOKENS
3
+ ============================================================ */
4
+ :root {
5
+ /* Core Colors */
6
+ --xaura-primary: #6C5CE7;
7
+ --xaura-energy: #00E5FF;
8
+ --xaura-power: #FF2BD6;
9
+ --xaura-dark: #0F172A;
10
+ --xaura-light: #F8FAFC;
11
+
12
+ /* Extended Palette */
13
+ --xaura-electric: #22D3EE;
14
+ --xaura-violet: #A78BFA;
15
+ --xaura-plasma: #F472B6;
16
+ --xaura-danger: #FF4757;
17
+ --xaura-success: #00FFB3;
18
+ --xaura-warning: #FFD60A;
19
+
20
+ /* Surface Layers */
21
+ --xaura-surface-0: #0F172A;
22
+ --xaura-surface-1: #1E293B;
23
+ --xaura-surface-2: #263348;
24
+ --xaura-surface-3: #334155;
25
+ --xaura-surface-4: #3D4F6B;
26
+
27
+ /* Text */
28
+ --xaura-text: #F8FAFC;
29
+ --xaura-text-muted: #94A3B8;
30
+ --xaura-text-dim: #64748B;
31
+
32
+ /* Gradients */
33
+ --xaura-gradient-energy: linear-gradient(135deg, #6C5CE7, #00E5FF);
34
+ --xaura-gradient-plasma: linear-gradient(135deg, #FF2BD6, #6C5CE7);
35
+ --xaura-gradient-cosmic: linear-gradient(135deg, #FF2BD6, #6C5CE7, #00E5FF);
36
+ --xaura-gradient-neon: linear-gradient(135deg, #22D3EE, #A78BFA);
37
+
38
+ /* Glow Effects */
39
+ --xaura-glow-sm: 0 0 8px var(--xaura-energy), 0 0 16px rgba(0,229,255,0.3);
40
+ --xaura-glow-md: 0 0 12px var(--xaura-energy), 0 0 24px rgba(0,229,255,0.4), 0 0 48px rgba(0,229,255,0.15);
41
+ --xaura-glow-lg: 0 0 20px var(--xaura-energy), 0 0 40px rgba(0,229,255,0.4), 0 0 80px rgba(0,229,255,0.2);
42
+ --xaura-glow-primary:0 0 12px var(--xaura-primary), 0 0 24px rgba(108,92,231,0.4);
43
+ --xaura-glow-power: 0 0 12px var(--xaura-power), 0 0 24px rgba(255,43,214,0.4);
44
+ --xaura-glow-danger: 0 0 12px var(--xaura-danger), 0 0 24px rgba(255,71,87,0.4);
45
+ --xaura-glow-success:0 0 12px var(--xaura-success), 0 0 24px rgba(0,255,179,0.4);
46
+
47
+ /* Borders */
48
+ --xaura-border: 1px solid rgba(108,92,231,0.25);
49
+ --xaura-border-glow: 1px solid var(--xaura-energy);
50
+ --xaura-border-energy:1px solid rgba(0,229,255,0.5);
51
+
52
+ /* Typography */
53
+ --font-ui: 'Inter', system-ui, sans-serif;
54
+ --font-power: 'Orbitron', monospace;
55
+
56
+ /* Spacing */
57
+ --xaura-space-1: 4px;
58
+ --xaura-space-2: 8px;
59
+ --xaura-space-3: 12px;
60
+ --xaura-space-4: 16px;
61
+ --xaura-space-5: 20px;
62
+ --xaura-space-6: 24px;
63
+ --xaura-space-8: 32px;
64
+ --xaura-space-10: 40px;
65
+ --xaura-space-12: 48px;
66
+ --xaura-space-16: 64px;
67
+
68
+ /* Radius */
69
+ --xaura-radius-sm: 4px;
70
+ --xaura-radius-md: 8px;
71
+ --xaura-radius-lg: 12px;
72
+ --xaura-radius-xl: 16px;
73
+ --xaura-radius-full:9999px;
74
+
75
+ /* Transitions */
76
+ --xaura-transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
77
+ --xaura-transition-fast: all 0.15s ease;
78
+ --xaura-transition-slow: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
79
+ }
@@ -0,0 +1,115 @@
1
+ /* ============================================================
2
+ ANIMATION UTILITY CLASSES
3
+ ============================================================ */
4
+ .xaura-pulse { animation: xaura-pulse-glow 2s ease-in-out infinite; }
5
+ .xaura-float { animation: xaura-float 3s ease-in-out infinite; }
6
+ .xaura-charge { animation: xaura-charge 1.5s ease-out forwards; }
7
+ .xaura-fade-in { animation: xaura-fade-in 0.4s ease forwards; }
8
+ .xaura-slide-in { animation: xaura-slide-in 0.35s cubic-bezier(0.4, 0, 0.2, 1) forwards; }
9
+ .xaura-slide-up { animation: xaura-slide-up 0.35s cubic-bezier(0.4, 0, 0.2, 1) forwards; }
10
+ .xaura-scale-in { animation: xaura-scale-in 0.3s cubic-bezier(0.34, 1.56, 0.64, 1) forwards; }
11
+
12
+ /* ============================================================
13
+ GLOW UTILITY CLASSES
14
+ ============================================================ */
15
+ .xaura-glow { box-shadow: var(--xaura-glow-sm); }
16
+ .xaura-glow-md { box-shadow: var(--xaura-glow-md); }
17
+ .xaura-glow-lg { box-shadow: var(--xaura-glow-lg); }
18
+ .xaura-glow-primary { box-shadow: var(--xaura-glow-primary); }
19
+ .xaura-glow-power { box-shadow: var(--xaura-glow-power); }
20
+ .xaura-glow-danger { box-shadow: var(--xaura-glow-danger); }
21
+ .xaura-glow-success { box-shadow: var(--xaura-glow-success); }
22
+
23
+ .xaura-text-glow { text-shadow: 0 0 10px var(--xaura-energy), 0 0 20px rgba(0,229,255,0.5); }
24
+ .xaura-text-glow-primary { text-shadow: 0 0 10px var(--xaura-primary), 0 0 20px rgba(108,92,231,0.5); }
25
+ .xaura-text-glow-power { text-shadow: 0 0 10px var(--xaura-power), 0 0 20px rgba(255,43,214,0.5); }
26
+
27
+ /* ============================================================
28
+ TYPOGRAPHY
29
+ ============================================================ */
30
+ .xaura-font-power { font-family: var(--font-power); }
31
+ .xaura-font-ui { font-family: var(--font-ui); }
32
+
33
+ .xaura-title-xl {
34
+ font-family: var(--font-power);
35
+ font-size: clamp(2rem, 5vw, 4rem);
36
+ font-weight: 800;
37
+ letter-spacing: 0.05em;
38
+ line-height: 1.1;
39
+ }
40
+ .xaura-title-lg {
41
+ font-family: var(--font-power);
42
+ font-size: clamp(1.5rem, 3.5vw, 2.5rem);
43
+ font-weight: 700;
44
+ letter-spacing: 0.04em;
45
+ line-height: 1.2;
46
+ }
47
+ .xaura-title-md {
48
+ font-family: var(--font-power);
49
+ font-size: clamp(1.2rem, 2.5vw, 1.75rem);
50
+ font-weight: 600;
51
+ letter-spacing: 0.03em;
52
+ line-height: 1.3;
53
+ }
54
+ .xaura-title-sm {
55
+ font-family: var(--font-power);
56
+ font-size: 1.1rem;
57
+ font-weight: 600;
58
+ letter-spacing: 0.02em;
59
+ }
60
+ .xaura-text { font-size: 1rem; color: var(--xaura-text); }
61
+ .xaura-text-sm { font-size: 0.875rem; color: var(--xaura-text); }
62
+ .xaura-caption { font-size: 0.75rem; color: var(--xaura-text-muted); letter-spacing: 0.05em; }
63
+ .xaura-label { font-size: 0.75rem; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; color: var(--xaura-text-muted); }
64
+
65
+ .xaura-gradient-text {
66
+ background: var(--xaura-gradient-energy);
67
+ -webkit-background-clip: text;
68
+ -webkit-text-fill-color: transparent;
69
+ background-clip: text;
70
+ }
71
+ .xaura-gradient-text-plasma {
72
+ background: var(--xaura-gradient-plasma);
73
+ -webkit-background-clip: text;
74
+ -webkit-text-fill-color: transparent;
75
+ background-clip: text;
76
+ }
77
+ .xaura-gradient-text-cosmic {
78
+ background: var(--xaura-gradient-cosmic);
79
+ background-size: 200% auto;
80
+ -webkit-background-clip: text;
81
+ -webkit-text-fill-color: transparent;
82
+ background-clip: text;
83
+ animation: xaura-gradient-shift 3s linear infinite;
84
+ }
85
+
86
+ /* ============================================================
87
+ SURFACE LAYERS
88
+ ============================================================ */
89
+ .xaura-surface { background: var(--xaura-surface-1); }
90
+ .xaura-elevated { background: var(--xaura-surface-2); }
91
+ .xaura-powered {
92
+ background: var(--xaura-surface-2);
93
+ box-shadow: var(--xaura-glow-sm);
94
+ border: var(--xaura-border-energy);
95
+ }
96
+
97
+ /* ============================================================
98
+ COLOR UTILITIES
99
+ ============================================================ */
100
+ .text-energy { color: var(--xaura-energy); }
101
+ .text-primary { color: var(--xaura-primary); }
102
+ .text-power { color: var(--xaura-power); }
103
+ .text-danger { color: var(--xaura-danger); }
104
+ .text-success { color: var(--xaura-success); }
105
+ .text-warning { color: var(--xaura-warning); }
106
+ .text-muted { color: var(--xaura-text-muted); }
107
+ .text-dim { color: var(--xaura-text-dim); }
108
+
109
+ .bg-energy { background: var(--xaura-energy); color: var(--xaura-dark); }
110
+ .bg-primary { background: var(--xaura-primary); }
111
+ .bg-surface-1 { background: var(--xaura-surface-1); }
112
+ .bg-surface-2 { background: var(--xaura-surface-2); }
113
+ .bg-gradient-energy { background: var(--xaura-gradient-energy); }
114
+ .bg-gradient-plasma { background: var(--xaura-gradient-plasma); }
115
+ .bg-gradient-cosmic { background: var(--xaura-gradient-cosmic); }
package/js/core.js ADDED
@@ -0,0 +1,388 @@
1
+ /**
2
+ * xaura UI FRAMEWORK — v1.0.0
3
+ * JavaScript Core
4
+ * UI WITH POWER ⚡
5
+ */
6
+
7
+ (function (global) {
8
+ 'use strict';
9
+
10
+ const xaura = {};
11
+
12
+ // ─── UTILS ───────────────────────────────────────────────
13
+ xaura.$ = (sel, ctx = document) => ctx.querySelector(sel);
14
+ xaura.$$ = (sel, ctx = document) => [...ctx.querySelectorAll(sel)];
15
+
16
+ function on(el, event, handler, opts) {
17
+ if (!el) return;
18
+ el.addEventListener(event, handler, opts);
19
+ }
20
+
21
+ // ─── TABS ─────────────────────────────────────────────────
22
+ xaura.initTabs = function () {
23
+ xaura.$$('[data-xaura-tabs]').forEach(wrapper => {
24
+ const buttons = xaura.$$('.xaura-tab-btn', wrapper);
25
+ const panels = xaura.$$('.xaura-tab-panel', wrapper);
26
+
27
+ buttons.forEach(btn => {
28
+ on(btn, 'click', () => {
29
+ const target = btn.dataset.target;
30
+ buttons.forEach(b => b.classList.remove('active'));
31
+ panels.forEach(p => p.classList.remove('active'));
32
+ btn.classList.add('active');
33
+ const panel = xaura.$('#' + target, wrapper) || xaura.$('[data-tab="' + target + '"]', wrapper);
34
+ if (panel) panel.classList.add('active');
35
+ });
36
+ });
37
+ });
38
+ };
39
+
40
+ // ─── ACCORDION ────────────────────────────────────────────
41
+ xaura.initAccordion = function () {
42
+ xaura.$$('.xaura-accordion-trigger').forEach(trigger => {
43
+ on(trigger, 'click', () => {
44
+ const item = trigger.closest('.xaura-accordion-item');
45
+ const isOpen = item.classList.contains('open');
46
+
47
+ // Close all siblings if exclusive
48
+ const accordion = item.closest('.xaura-accordion');
49
+ if (accordion && accordion.dataset.exclusive !== 'false') {
50
+ xaura.$$('.xaura-accordion-item', accordion).forEach(i => i.classList.remove('open'));
51
+ }
52
+ item.classList.toggle('open', !isOpen);
53
+ });
54
+ });
55
+ };
56
+
57
+ // ─── DRAWER ───────────────────────────────────────────────
58
+ xaura.initDrawers = function () {
59
+ xaura.$$('[data-xaura-drawer-open]').forEach(btn => {
60
+ on(btn, 'click', () => xaura.openDrawer(btn.dataset.xauraDrawerOpen));
61
+ });
62
+ xaura.$$('[data-xaura-drawer-close]').forEach(btn => {
63
+ on(btn, 'click', () => {
64
+ const overlay = btn.closest('.xaura-drawer-overlay');
65
+ if (overlay) xaura.closeDrawer(overlay.id);
66
+ });
67
+ });
68
+ xaura.$$('.xaura-drawer-overlay').forEach(overlay => {
69
+ on(overlay, 'click', e => {
70
+ if (e.target === overlay) xaura.closeDrawer(overlay.id);
71
+ });
72
+ });
73
+ };
74
+
75
+ xaura.openDrawer = function (id) {
76
+ const el = document.getElementById(id);
77
+ if (!el) return;
78
+ el.classList.add('open');
79
+ const drawer = xaura.$('.xaura-drawer', el);
80
+ if (drawer) drawer.classList.add('open');
81
+ document.body.style.overflow = 'hidden';
82
+ };
83
+
84
+ xaura.closeDrawer = function (id) {
85
+ const el = document.getElementById(id);
86
+ if (!el) return;
87
+ el.classList.remove('open');
88
+ const drawer = xaura.$('.xaura-drawer', el);
89
+ if (drawer) drawer.classList.remove('open');
90
+ document.body.style.overflow = '';
91
+ };
92
+
93
+ // ─── DROPDOWN ─────────────────────────────────────────────
94
+ xaura.initDropdowns = function () {
95
+ xaura.$$('[data-xaura-dropdown]').forEach(trigger => {
96
+ const dropdown = trigger.closest('.xaura-dropdown');
97
+ on(trigger, 'click', e => {
98
+ e.stopPropagation();
99
+ dropdown.classList.toggle('open');
100
+ });
101
+ });
102
+
103
+ on(document, 'click', () => {
104
+ xaura.$$('.xaura-dropdown.open').forEach(d => d.classList.remove('open'));
105
+ });
106
+
107
+ on(document, 'keydown', e => {
108
+ if (e.key === 'Escape') {
109
+ xaura.$$('.xaura-dropdown.open').forEach(d => d.classList.remove('open'));
110
+ }
111
+ });
112
+ };
113
+
114
+ // ─── COMMAND PALETTE ─────────────────────────────────────
115
+ xaura.initCommandPalette = function () {
116
+ const overlay = xaura.$('.xaura-command-overlay');
117
+ if (!overlay) return;
118
+
119
+ const input = xaura.$('.xaura-command-input', overlay);
120
+ const items = xaura.$$('.xaura-command-item', overlay);
121
+ let selectedIndex = -1;
122
+
123
+ const open = () => { overlay.classList.add('open'); input?.focus(); selectedIndex = -1; };
124
+ const close = () => overlay.classList.remove('open');
125
+
126
+ // Keyboard shortcut
127
+ on(document, 'keydown', e => {
128
+ if ((e.ctrlKey || e.metaKey) && e.key === 'k') {
129
+ e.preventDefault();
130
+ overlay.classList.contains('open') ? close() : open();
131
+ }
132
+ if (e.key === 'Escape' && overlay.classList.contains('open')) close();
133
+
134
+ if (overlay.classList.contains('open')) {
135
+ if (e.key === 'ArrowDown') {
136
+ e.preventDefault();
137
+ selectedIndex = Math.min(selectedIndex + 1, items.length - 1);
138
+ updateSelection();
139
+ }
140
+ if (e.key === 'ArrowUp') {
141
+ e.preventDefault();
142
+ selectedIndex = Math.max(selectedIndex - 1, 0);
143
+ updateSelection();
144
+ }
145
+ if (e.key === 'Enter' && selectedIndex >= 0) {
146
+ items[selectedIndex]?.click();
147
+ close();
148
+ }
149
+ }
150
+ });
151
+
152
+ function updateSelection() {
153
+ items.forEach((item, i) => {
154
+ item.classList.toggle('selected', i === selectedIndex);
155
+ if (i === selectedIndex) item.scrollIntoView({ block: 'nearest' });
156
+ });
157
+ }
158
+
159
+ // Filter on input
160
+ if (input) {
161
+ on(input, 'input', () => {
162
+ const query = input.value.toLowerCase();
163
+ items.forEach(item => {
164
+ const text = item.textContent.toLowerCase();
165
+ item.style.display = text.includes(query) ? '' : 'none';
166
+ });
167
+ selectedIndex = -1;
168
+ });
169
+ }
170
+
171
+ // Close on overlay click
172
+ on(overlay, 'click', e => { if (e.target === overlay) close(); });
173
+
174
+ // Open button
175
+ xaura.$$('[data-xaura-command-open]').forEach(btn => on(btn, 'click', open));
176
+ };
177
+
178
+ // ─── TOAST ───────────────────────────────────────────────
179
+ xaura.toast = function (message, type = 'energy', duration = 4000) {
180
+ let container = xaura.$('.xaura-toast-container');
181
+ if (!container) {
182
+ container = document.createElement('div');
183
+ container.className = 'xaura-toast-container';
184
+ document.body.appendChild(container);
185
+ }
186
+
187
+ const icons = { energy: '⚡', success: '✅', danger: '⚠️', warning: '🔔', primary: '🔮' };
188
+ const colors = {
189
+ energy: 'var(--xaura-energy)', success: 'var(--xaura-success)',
190
+ danger: 'var(--xaura-danger)', warning: 'var(--xaura-warning)',
191
+ primary: 'var(--xaura-primary)'
192
+ };
193
+
194
+ const toast = document.createElement('div');
195
+ toast.className = 'xaura-toast';
196
+ toast.style.borderColor = colors[type] || colors.energy;
197
+ toast.innerHTML = `
198
+ <span style="font-size:1.1rem">${icons[type] || icons.energy}</span>
199
+ <span style="flex:1;color:var(--xaura-text)">${message}</span>
200
+ <button onclick="this.closest('.xaura-toast').remove()" style="background:none;border:none;color:var(--xaura-text-muted);cursor:pointer;font-size:1rem;padding:0;line-height:1">×</button>
201
+ `;
202
+ container.appendChild(toast);
203
+
204
+ setTimeout(() => {
205
+ toast.style.animation = 'xaura-fade-in 0.3s ease reverse forwards';
206
+ setTimeout(() => toast.remove(), 300);
207
+ }, duration);
208
+ };
209
+
210
+ // ─── ENERGY RING ─────────────────────────────────────────
211
+ xaura.initEnergyRings = function () {
212
+ xaura.$$('.xaura-energy-ring').forEach(ring => {
213
+ const percent = parseFloat(ring.dataset.percent || 75);
214
+ const fill = xaura.$('.xaura-energy-ring-fill', ring);
215
+ const size = ring.dataset.size || 100;
216
+ const r = 45;
217
+ const circ = 2 * Math.PI * r;
218
+ if (fill) {
219
+ fill.setAttribute('stroke-dasharray', circ);
220
+ fill.setAttribute('stroke-dashoffset', circ);
221
+ // Animate
222
+ setTimeout(() => {
223
+ fill.setAttribute('stroke-dashoffset', circ * (1 - percent / 100));
224
+ }, 300);
225
+ }
226
+ });
227
+ };
228
+
229
+ // ─── POWER METER ─────────────────────────────────────────
230
+ xaura.initPowerMeters = function () {
231
+ xaura.$$('.xaura-power-meter').forEach(meter => {
232
+ const fill = xaura.$('.xaura-power-meter-fill', meter);
233
+ const percent = parseFloat(meter.dataset.percent || 75);
234
+ if (fill) {
235
+ setTimeout(() => { fill.style.width = percent + '%'; }, 300);
236
+ }
237
+ });
238
+ };
239
+
240
+ // ─── PROGRESS BARS ──────────────────────────────────────
241
+ xaura.initProgress = function () {
242
+ xaura.$$('.xaura-progress-bar[data-width]').forEach(bar => {
243
+ setTimeout(() => { bar.style.width = bar.dataset.width; }, 200);
244
+ });
245
+ };
246
+
247
+ // ─── RATING ──────────────────────────────────────────────
248
+ xaura.initRating = function () {
249
+ xaura.$$('.xaura-rating').forEach(widget => {
250
+ const stars = xaura.$$('.xaura-rating-star', widget);
251
+ let currentRating = parseInt(widget.dataset.rating || 0);
252
+
253
+ const setActive = n => {
254
+ stars.forEach((s, i) => s.classList.toggle('active', i < n));
255
+ };
256
+
257
+ setActive(currentRating);
258
+
259
+ stars.forEach((star, i) => {
260
+ on(star, 'mouseenter', () => setActive(i + 1));
261
+ on(star, 'mouseleave', () => setActive(currentRating));
262
+ on(star, 'click', () => {
263
+ currentRating = i + 1;
264
+ widget.dataset.rating = currentRating;
265
+ setActive(currentRating);
266
+ widget.dispatchEvent(new CustomEvent('xaura:rating', { detail: { rating: currentRating } }));
267
+ });
268
+ });
269
+ });
270
+ };
271
+
272
+ // ─── COPY BUTTON ─────────────────────────────────────────
273
+ xaura.initCopyButtons = function () {
274
+ xaura.$$('.xaura-copy-btn').forEach(btn => {
275
+ on(btn, 'click', () => {
276
+ const block = btn.closest('.xaura-code-block');
277
+ const code = block ? block.textContent.trim().replace('COPY', '').replace('COPIED!', '').trim() : '';
278
+ navigator.clipboard?.writeText(code).then(() => {
279
+ btn.textContent = 'COPIED!';
280
+ btn.style.color = 'var(--xaura-success)';
281
+ btn.style.borderColor = 'var(--xaura-success)';
282
+ setTimeout(() => {
283
+ btn.textContent = 'COPY';
284
+ btn.style.color = '';
285
+ btn.style.borderColor = '';
286
+ }, 2000);
287
+ });
288
+ });
289
+ });
290
+ };
291
+
292
+ // ─── SWITCH TOGGLE ───────────────────────────────────────
293
+ xaura.initSwitches = function () {
294
+ xaura.$$('.xaura-switch input').forEach(input => {
295
+ on(input, 'change', () => {
296
+ const label = input.closest('.xaura-switch');
297
+ if (!label) return;
298
+ label.dispatchEvent(new CustomEvent('xaura:switch', { detail: { checked: input.checked } }));
299
+ });
300
+ });
301
+ };
302
+
303
+ // ─── INTERSECTION OBSERVER (animate on scroll) ───────────
304
+ xaura.initScrollReveal = function () {
305
+ const observer = new IntersectionObserver(entries => {
306
+ entries.forEach(entry => {
307
+ if (entry.isIntersecting) {
308
+ entry.target.style.animation = 'xaura-slide-up 0.5s cubic-bezier(0.4, 0, 0.2, 1) both';
309
+ observer.unobserve(entry.target);
310
+ }
311
+ });
312
+ }, { threshold: 0.1 });
313
+
314
+ xaura.$$('[data-xaura-reveal]').forEach(el => {
315
+ el.style.opacity = '0';
316
+ observer.observe(el);
317
+ });
318
+ };
319
+
320
+ // ─── GLOW RIPPLE EFFECT ─────────────────────────────────
321
+ xaura.initRipple = function () {
322
+ xaura.$$('.xaura-btn:not(.no-ripple)').forEach(btn => {
323
+ on(btn, 'click', e => {
324
+ const rect = btn.getBoundingClientRect();
325
+ const x = e.clientX - rect.left;
326
+ const y = e.clientY - rect.top;
327
+
328
+ const ripple = document.createElement('span');
329
+ const size = Math.max(rect.width, rect.height) * 2;
330
+ ripple.style.cssText = `
331
+ position:absolute; width:${size}px; height:${size}px;
332
+ left:${x - size/2}px; top:${y - size/2}px;
333
+ border-radius:50%; background:rgba(255,255,255,0.15);
334
+ transform:scale(0); animation:xaura-wave 0.6s ease-out forwards;
335
+ pointer-events:none;
336
+ `;
337
+
338
+ const pos = getComputedStyle(btn).position;
339
+ if (pos === 'static') btn.style.position = 'relative';
340
+ btn.appendChild(ripple);
341
+ setTimeout(() => ripple.remove(), 700);
342
+ });
343
+ });
344
+ };
345
+
346
+ // ─── NAVBAR SCROLL ───────────────────────────────────────
347
+ xaura.initNavbar = function () {
348
+ const navbar = xaura.$('.xaura-navbar');
349
+ if (!navbar) return;
350
+ on(window, 'scroll', () => {
351
+ navbar.style.borderBottomColor = window.scrollY > 20
352
+ ? 'rgba(0,229,255,0.25)'
353
+ : 'rgba(108,92,231,0.2)';
354
+ navbar.style.boxShadow = window.scrollY > 20
355
+ ? '0 4px 24px rgba(0,0,0,0.3)'
356
+ : '';
357
+ });
358
+ };
359
+
360
+ // ─── INIT ALL (excluding modal and tooltip) ──────────────
361
+ xaura.init = function () {
362
+ xaura.initTabs();
363
+ xaura.initAccordion();
364
+ xaura.initDrawers();
365
+ xaura.initDropdowns();
366
+ xaura.initCommandPalette();
367
+ xaura.initEnergyRings();
368
+ xaura.initPowerMeters();
369
+ xaura.initProgress();
370
+ xaura.initRating();
371
+ xaura.initCopyButtons();
372
+ xaura.initSwitches();
373
+ xaura.initScrollReveal();
374
+ xaura.initRipple();
375
+ xaura.initNavbar();
376
+ // Modal and Tooltip are initialized separately via their own files
377
+ console.log('%c⚡ xaura UI v1.0.0 — UI WITH POWER', 'font-family:monospace;color:#00E5FF;font-size:14px;font-weight:bold;');
378
+ };
379
+
380
+ // Auto-init on DOM ready (only if not prevented)
381
+ if (document.readyState === 'loading') {
382
+ document.addEventListener('DOMContentLoaded', xaura.init);
383
+ } else {
384
+ xaura.init();
385
+ }
386
+
387
+ global.xaura = xaura;
388
+ })(window);
package/js/modal.js ADDED
@@ -0,0 +1,52 @@
1
+ /**
2
+ * xaura UI FRAMEWORK — Modal Module
3
+ */
4
+
5
+ (function (global) {
6
+ 'use strict';
7
+
8
+ const xaura = global.xaura || {};
9
+
10
+ // ─── MODAL ────────────────────────────────────────────────
11
+ xaura.initModals = function () {
12
+ // Open triggers
13
+ xaura.$$('[data-xaura-modal-open]').forEach(btn => {
14
+ xaura.on(btn, 'click', () => {
15
+ const id = btn.dataset.xauraModalOpen;
16
+ xaura.openModal(id);
17
+ });
18
+ });
19
+
20
+ // Close triggers
21
+ xaura.$$('.xaura-modal-close, [data-xaura-modal-close]').forEach(btn => {
22
+ xaura.on(btn, 'click', () => {
23
+ const overlay = btn.closest('.xaura-modal-overlay');
24
+ if (overlay) xaura.closeModal(overlay.id);
25
+ });
26
+ });
27
+
28
+ // Click outside
29
+ xaura.$$('.xaura-modal-overlay').forEach(overlay => {
30
+ xaura.on(overlay, 'click', e => {
31
+ if (e.target === overlay) xaura.closeModal(overlay.id);
32
+ });
33
+ });
34
+ };
35
+
36
+ xaura.openModal = function (id) {
37
+ const el = document.getElementById(id);
38
+ if (!el) return;
39
+ el.classList.add('open');
40
+ document.body.style.overflow = 'hidden';
41
+ };
42
+
43
+ xaura.closeModal = function (id) {
44
+ const el = document.getElementById(id);
45
+ if (!el) return;
46
+ el.classList.remove('open');
47
+ document.body.style.overflow = '';
48
+ };
49
+
50
+ // Attach to global
51
+ global.xaura = xaura;
52
+ })(window);
package/js/tooltip.js ADDED
@@ -0,0 +1,27 @@
1
+ /**
2
+ * xaura UI FRAMEWORK — Tooltip Module
3
+ */
4
+
5
+ (function (global) {
6
+ 'use strict';
7
+
8
+ const xaura = global.xaura || {};
9
+
10
+ // ─── TOOLTIP (keyboard accessible) ───────────────────────
11
+ xaura.initTooltips = function () {
12
+ xaura.$$('[data-tooltip]').forEach(el => {
13
+ const text = el.dataset.tooltip;
14
+ const wrap = document.createElement('span');
15
+ wrap.className = 'xaura-tooltip-wrap';
16
+ el.parentNode.insertBefore(wrap, el);
17
+ wrap.appendChild(el);
18
+ const tip = document.createElement('span');
19
+ tip.className = 'xaura-tooltip';
20
+ tip.textContent = text;
21
+ wrap.appendChild(tip);
22
+ });
23
+ };
24
+
25
+ // Attach to global
26
+ global.xaura = xaura;
27
+ })(window);
package/package.json ADDED
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "xaura",
3
+ "version": "1.0.0",
4
+ "description": "xaura UI Framework — UI with Power ⚡",
5
+ "main": "js/core.js",
6
+ "style": "css/tokens/index.css",
7
+ "scripts": {
8
+ "test": "echo \"Error: no test specified\" && exit 1"
9
+ },
10
+ "keywords": ["ui", "framework", "css", "js", "anime", "energy", "glow"],
11
+ "author": "Imed Rebhi",
12
+ "license": "MIT"
13
+ }
Binary file