wozie 3.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,117 @@
1
+ // Woozie Client Runtime v3.0 — Interactive component logic
2
+ // Built by Woozlit 2026
3
+
4
+ (function () {
5
+ 'use strict';
6
+
7
+ document.addEventListener('DOMContentLoaded', () => {
8
+ initTabs();
9
+ initAccordion();
10
+ initModals();
11
+ initSliders();
12
+ initDropdowns();
13
+ initScrollAnimations();
14
+ });
15
+
16
+ function initTabs() {
17
+ document.querySelectorAll('.wz-tabs').forEach(tabGroup => {
18
+ const tabs = tabGroup.querySelectorAll('.wz-tab');
19
+ if (tabs.length === 0) return;
20
+
21
+ // Create tab header bar
22
+ const bar = document.createElement('div');
23
+ bar.className = 'wz-tab-bar';
24
+ tabs.forEach((tab, i) => {
25
+ const btn = document.createElement('button');
26
+ btn.className = 'wz-tab-btn' + (i === 0 ? ' active' : '');
27
+ btn.textContent = tab.dataset.tab || `Tab ${i + 1}`;
28
+ btn.addEventListener('click', () => {
29
+ bar.querySelectorAll('.wz-tab-btn').forEach(b => b.classList.remove('active'));
30
+ btn.classList.add('active');
31
+ tabs.forEach(t => t.style.display = 'none');
32
+ tab.style.display = '';
33
+ });
34
+ bar.appendChild(btn);
35
+ });
36
+ tabGroup.insertBefore(bar, tabs[0]);
37
+ tabs.forEach((t, i) => { if (i > 0) t.style.display = 'none'; });
38
+ });
39
+ }
40
+
41
+ function initAccordion() {
42
+ document.querySelectorAll('.wz-accordion-title').forEach(title => {
43
+ title.addEventListener('click', () => {
44
+ const item = title.parentElement;
45
+ const isOpen = item.classList.contains('active');
46
+ // Close siblings
47
+ item.parentElement.querySelectorAll('.wz-accordion-item').forEach(s => s.classList.remove('active'));
48
+ if (!isOpen) item.classList.add('active');
49
+ });
50
+ });
51
+ }
52
+
53
+ function initModals() {
54
+ // Open triggers
55
+ document.querySelectorAll('[data-modal]').forEach(trigger => {
56
+ trigger.addEventListener('click', () => {
57
+ const modal = document.getElementById(trigger.dataset.modal);
58
+ if (modal) modal.classList.add('active');
59
+ });
60
+ });
61
+ // Backdrop close
62
+ document.querySelectorAll('.wz-modal-backdrop').forEach(backdrop => {
63
+ backdrop.addEventListener('click', () => {
64
+ backdrop.parentElement.classList.remove('active');
65
+ });
66
+ });
67
+ // Escape key close
68
+ document.addEventListener('keydown', e => {
69
+ if (e.key === 'Escape') {
70
+ document.querySelectorAll('.wz-modal.active').forEach(m => m.classList.remove('active'));
71
+ }
72
+ });
73
+ }
74
+
75
+ function initSliders() {
76
+ document.querySelectorAll('.wz-slider').forEach(slider => {
77
+ const display = slider.parentElement.querySelector('.wz-slider-value');
78
+ if (display) {
79
+ slider.addEventListener('input', () => { display.textContent = slider.value; });
80
+ }
81
+ });
82
+ }
83
+
84
+ function initDropdowns() {
85
+ document.querySelectorAll('.wz-dropdown').forEach(dropdown => {
86
+ const first = dropdown.children[0];
87
+ if (!first) return;
88
+ first.style.cursor = 'pointer';
89
+ const rest = Array.from(dropdown.children).slice(1);
90
+ const menu = document.createElement('div');
91
+ menu.className = 'wz-dropdown-menu';
92
+ rest.forEach(c => { dropdown.removeChild(c); menu.appendChild(c); });
93
+ dropdown.appendChild(menu);
94
+ first.addEventListener('click', e => {
95
+ e.stopPropagation();
96
+ dropdown.classList.toggle('active');
97
+ });
98
+ });
99
+ document.addEventListener('click', () => {
100
+ document.querySelectorAll('.wz-dropdown.active').forEach(d => d.classList.remove('active'));
101
+ });
102
+ }
103
+
104
+ function initScrollAnimations() {
105
+ const els = document.querySelectorAll('.wz-card, .wz-alert, .wz-stat, .wz-hero, .wz-section');
106
+ if (!els.length) return;
107
+ const observer = new IntersectionObserver((entries) => {
108
+ entries.forEach(entry => {
109
+ if (entry.isIntersecting) {
110
+ entry.target.classList.add('wz-visible');
111
+ observer.unobserve(entry.target);
112
+ }
113
+ });
114
+ }, { threshold: 0.1, rootMargin: '0px 0px -50px 0px' });
115
+ els.forEach(el => observer.observe(el));
116
+ }
117
+ })();
@@ -0,0 +1,49 @@
1
+ // Woozie Router v3.0 — Client-side page transitions
2
+ // Built by Woozlit 2026
3
+
4
+ (function () {
5
+ 'use strict';
6
+
7
+ // Intercept [data-page] links for smooth page navigation
8
+ document.addEventListener('click', function (e) {
9
+ const link = e.target.closest('a[data-page], button[data-page]');
10
+ if (!link) return;
11
+
12
+ const page = link.dataset.page;
13
+ if (!page) return;
14
+
15
+ // If already on this page, ignore
16
+ if (window.location.pathname.endsWith(page + '.html')) return;
17
+
18
+ e.preventDefault();
19
+
20
+ // Add exit animation
21
+ const app = document.getElementById('app') || document.body;
22
+ app.classList.add('wz-page-exit');
23
+
24
+ setTimeout(() => {
25
+ window.location.href = page + '.html';
26
+ }, 200);
27
+ });
28
+
29
+ // On page load, add entrance animation
30
+ window.addEventListener('load', () => {
31
+ const app = document.getElementById('app') || document.body;
32
+ app.classList.add('wz-page-enter');
33
+ setTimeout(() => app.classList.remove('wz-page-enter'), 400);
34
+ });
35
+
36
+ // Highlight active navlink based on current page
37
+ const currentPage = window.location.pathname
38
+ .split('/').pop()
39
+ .replace('.html', '') || 'index';
40
+
41
+ document.addEventListener('DOMContentLoaded', () => {
42
+ document.querySelectorAll('.wz-navlink[data-page]').forEach(link => {
43
+ if (link.dataset.page === currentPage ||
44
+ (currentPage === 'index' && link.dataset.page === 'index')) {
45
+ link.classList.add('active');
46
+ }
47
+ });
48
+ });
49
+ })();
@@ -0,0 +1,79 @@
1
+ /* === WOOZIE RESET & VARIABLES === */
2
+ *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
3
+ html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
4
+ img, video, audio { max-width: 100%; display: block; }
5
+ a { color: var(--wz-primary); text-decoration: none; }
6
+ a:hover { text-decoration: underline; }
7
+
8
+ :root {
9
+ --wz-primary: #6366f1;
10
+ --wz-primary-hover: #4f46e5;
11
+ --wz-primary-light: rgba(99, 102, 241, 0.1);
12
+ --wz-primary-glow: rgba(99, 102, 241, 0.4);
13
+ --wz-success: #10b981; --wz-success-light: rgba(16, 185, 129, 0.1);
14
+ --wz-warning: #f59e0b; --wz-warning-light: rgba(245, 158, 11, 0.1);
15
+ --wz-error: #ef4444; --wz-error-light: rgba(239, 68, 68, 0.1);
16
+ --wz-info: #3b82f6; --wz-info-light: rgba(59, 130, 246, 0.1);
17
+ --wz-green: #10b981; --wz-green-light: rgba(16, 185, 129, 0.1);
18
+ --wz-red: #ef4444; --wz-red-light: rgba(239, 68, 68, 0.1);
19
+ --wz-yellow: #f59e0b; --wz-yellow-light: rgba(245, 158, 11, 0.1);
20
+ --wz-purple: #8b5cf6; --wz-purple-light: rgba(139, 92, 246, 0.1);
21
+ --wz-blue: #3b82f6; --wz-blue-light: rgba(59, 130, 246, 0.1);
22
+ --wz-orange: #f97316; --wz-orange-light: rgba(249, 115, 22, 0.1);
23
+ --wz-pink: #ec4899; --wz-pink-light: rgba(236, 72, 153, 0.1);
24
+ --wz-bg: #fafbff;
25
+ --wz-bg-gradient: linear-gradient(135deg, #f0f4ff 0%, #faf5ff 50%, #f0f9ff 100%);
26
+ --wz-surface: #ffffff;
27
+ --wz-surface-glass: rgba(255, 255, 255, 0.7);
28
+ --wz-surface-hover: #f8fafc;
29
+ --wz-border: #e2e8f0; --wz-border-light: #f1f5f9;
30
+ --wz-text: #0f172a; --wz-text-secondary: #475569;
31
+ --wz-text-muted: #94a3b8; --wz-text-inverse: #ffffff;
32
+ --wz-font: 'Inter', system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
33
+ --wz-font-mono: 'Fira Code', 'Cascadia Code', 'JetBrains Mono', monospace;
34
+ --wz-shadow-xs: 0 1px 2px rgba(0,0,0,0.04);
35
+ --wz-shadow-sm: 0 1px 3px rgba(0,0,0,0.06), 0 1px 2px rgba(0,0,0,0.04);
36
+ --wz-shadow: 0 2px 8px rgba(0,0,0,0.08);
37
+ --wz-shadow-md: 0 4px 12px rgba(0,0,0,0.1);
38
+ --wz-shadow-lg: 0 8px 24px rgba(0,0,0,0.12);
39
+ --wz-shadow-xl: 0 16px 48px rgba(0,0,0,0.16);
40
+ --wz-radius-sm: 0.375rem; --wz-radius: 0.625rem;
41
+ --wz-radius-md: 0.75rem; --wz-radius-lg: 1rem;
42
+ --wz-radius-xl: 1.25rem; --wz-radius-2xl: 1.5rem;
43
+ --wz-radius-full: 9999px;
44
+ --wz-transition-fast: 150ms cubic-bezier(0.4,0,0.2,1);
45
+ --wz-transition: 200ms cubic-bezier(0.4,0,0.2,1);
46
+ --wz-transition-slow: 300ms cubic-bezier(0.4,0,0.2,1);
47
+ --wz-transition-spring: 500ms cubic-bezier(0.34,1.56,0.64,1);
48
+ }
49
+
50
+ [data-theme="dark"] {
51
+ --wz-bg: #0c0f1a;
52
+ --wz-bg-gradient: linear-gradient(135deg, #0c0f1a 0%, #131627 50%, #0c0f1a 100%);
53
+ --wz-surface: #1a1f35; --wz-surface-glass: rgba(26,31,53,0.85);
54
+ --wz-surface-hover: #232845;
55
+ --wz-border: #2a3050; --wz-border-light: #1f2540;
56
+ --wz-text: #e8ecf4; --wz-text-secondary: #a0aec0; --wz-text-muted: #5a6580;
57
+ --wz-shadow-xs: 0 1px 2px rgba(0,0,0,0.2);
58
+ --wz-shadow-sm: 0 1px 3px rgba(0,0,0,0.3);
59
+ --wz-shadow: 0 2px 8px rgba(0,0,0,0.3);
60
+ --wz-shadow-md: 0 4px 12px rgba(0,0,0,0.4);
61
+ --wz-shadow-lg: 0 8px 24px rgba(0,0,0,0.4);
62
+ --wz-shadow-xl: 0 16px 48px rgba(0,0,0,0.5);
63
+ }
64
+ [data-theme="dark"] .wz-card { background: var(--wz-surface-glass); border-color: var(--wz-border); }
65
+ [data-theme="dark"] .wz-input,
66
+ [data-theme="dark"] .wz-textarea,
67
+ [data-theme="dark"] .wz-select { background: var(--wz-surface); color: var(--wz-text); }
68
+ [data-theme="dark"] .wz-code-block { background: #141828; }
69
+
70
+ body {
71
+ font-family: var(--wz-font);
72
+ background: var(--wz-bg-gradient);
73
+ background-attachment: fixed;
74
+ color: var(--wz-text);
75
+ line-height: 1.65;
76
+ min-height: 100vh;
77
+ -webkit-font-smoothing: antialiased;
78
+ -moz-osx-font-smoothing: grayscale;
79
+ }
@@ -0,0 +1,135 @@
1
+ /* === NAVIGATION === */
2
+ .wz-nav {
3
+ background: var(--wz-surface-glass); backdrop-filter: blur(20px);
4
+ -webkit-backdrop-filter: blur(20px); border-bottom: 1px solid var(--wz-border);
5
+ padding: 0 2rem; position: sticky; top: 0; z-index: 100;
6
+ margin: -2rem -1.5rem 2rem;
7
+ }
8
+ .wz-nav-inner {
9
+ max-width: 1200px; margin: 0 auto; display: flex;
10
+ align-items: center; gap: 0.5rem; height: 64px; overflow-x: auto;
11
+ }
12
+ .wz-navlink {
13
+ display: inline-flex; align-items: center; padding: 0.5rem 1rem;
14
+ font-size: 0.9rem; font-weight: 500; color: var(--wz-text-secondary);
15
+ border-radius: var(--wz-radius); transition: all var(--wz-transition);
16
+ text-decoration: none; white-space: nowrap;
17
+ }
18
+ .wz-navlink:hover { color: var(--wz-primary); background: var(--wz-primary-light); text-decoration: none; }
19
+ .wz-navlink.active { color: var(--wz-primary); background: var(--wz-primary-light); font-weight: 600; }
20
+
21
+ /* === HERO === */
22
+ .wz-hero {
23
+ text-align: center; padding: 6rem 2rem; margin: -2rem -1.5rem 2rem;
24
+ position: relative; overflow: hidden;
25
+ }
26
+ .wz-hero::before {
27
+ content: ''; position: absolute; top: -50%; left: -50%; width: 200%; height: 200%;
28
+ background: radial-gradient(circle at 30% 50%, var(--wz-primary-light) 0%, transparent 50%),
29
+ radial-gradient(circle at 70% 50%, rgba(168,85,247,0.08) 0%, transparent 50%);
30
+ animation: wz-hero-glow 10s ease-in-out infinite alternate;
31
+ }
32
+ @keyframes wz-hero-glow {
33
+ 0% { transform: translate(-5%, -5%) rotate(0deg); }
34
+ 100% { transform: translate(5%, 5%) rotate(3deg); }
35
+ }
36
+ .wz-hero-content { position: relative; z-index: 1; }
37
+ .wz-hero-title {
38
+ font-size: clamp(2.5rem, 7vw, 4.5rem); font-weight: 800;
39
+ background: linear-gradient(135deg, var(--wz-primary), #a855f7, #ec4899);
40
+ -webkit-background-clip: text; -webkit-text-fill-color: transparent;
41
+ background-clip: text; margin-bottom: 1rem; letter-spacing: -0.04em; line-height: 1.1;
42
+ }
43
+ .wz-hero .wz-text { font-size: 1.25rem; color: var(--wz-text-muted); max-width: 600px; margin: 0 auto 2rem; }
44
+ .wz-hero .wz-row { justify-content: center; }
45
+
46
+ /* === ALERTS === */
47
+ .wz-alert {
48
+ display: flex; align-items: center; gap: 0.75rem; padding: 1rem 1.25rem;
49
+ border-radius: var(--wz-radius-md); font-size: 0.9rem; font-weight: 500; border: 1px solid transparent;
50
+ }
51
+ .wz-alert-icon { font-size: 1.1rem; flex-shrink: 0; }
52
+ .wz-alert-info { background: var(--wz-info-light); color: var(--wz-info); border-color: rgba(59,130,246,0.2); }
53
+ .wz-alert-success { background: var(--wz-success-light); color: var(--wz-success); border-color: rgba(16,185,129,0.2); }
54
+ .wz-alert-warning { background: var(--wz-warning-light); color: var(--wz-warning); border-color: rgba(245,158,11,0.2); }
55
+ .wz-alert-error { background: var(--wz-error-light); color: var(--wz-error); border-color: rgba(239,68,68,0.2); }
56
+
57
+ /* === BADGES === */
58
+ .wz-badge {
59
+ display: inline-flex; align-items: center; padding: 0.25rem 0.75rem;
60
+ font-size: 0.75rem; font-weight: 600; border-radius: var(--wz-radius-full);
61
+ letter-spacing: 0.025em; text-transform: uppercase;
62
+ }
63
+ .wz-badge-primary { background: var(--wz-primary-light); color: var(--wz-primary); }
64
+ .wz-badge-green, .wz-badge-success { background: var(--wz-green-light); color: var(--wz-green); }
65
+ .wz-badge-red, .wz-badge-error, .wz-badge-danger { background: var(--wz-red-light); color: var(--wz-red); }
66
+ .wz-badge-yellow, .wz-badge-warning { background: var(--wz-yellow-light); color: var(--wz-yellow); }
67
+ .wz-badge-purple { background: var(--wz-purple-light); color: var(--wz-purple); }
68
+ .wz-badge-blue { background: var(--wz-blue-light); color: var(--wz-blue); }
69
+ .wz-badge-orange { background: var(--wz-orange-light); color: var(--wz-orange); }
70
+ .wz-badge-pink { background: var(--wz-pink-light); color: var(--wz-pink); }
71
+
72
+ /* === PROGRESS === */
73
+ .wz-progress { width: 100%; height: 12px; background: var(--wz-border); border-radius: var(--wz-radius-full); overflow: hidden; }
74
+ .wz-progress-bar {
75
+ height: 100%; background: linear-gradient(90deg, var(--wz-primary), #a855f7);
76
+ border-radius: var(--wz-radius-full); display: flex; align-items: center;
77
+ justify-content: flex-end; padding-right: 0.5rem;
78
+ transition: width 0.6s cubic-bezier(0.4,0,0.2,1); position: relative; overflow: hidden;
79
+ }
80
+ .wz-progress-bar::after {
81
+ content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0;
82
+ background: linear-gradient(90deg, transparent, rgba(255,255,255,0.25), transparent);
83
+ animation: wz-shimmer 2s infinite;
84
+ }
85
+ .wz-progress-bar span { font-size: 0.6rem; font-weight: 700; color: white; position: relative; z-index: 1; }
86
+ @keyframes wz-shimmer { 0% { transform: translateX(-100%); } 100% { transform: translateX(100%); } }
87
+
88
+ /* === SPINNER === */
89
+ .wz-spinner { width: 36px; height: 36px; border: 3px solid var(--wz-border); border-top-color: var(--wz-primary); border-radius: 50%; animation: wz-spin 0.8s linear infinite; }
90
+ @keyframes wz-spin { to { transform: rotate(360deg); } }
91
+
92
+ /* === STATS === */
93
+ .wz-stat { text-align: center; padding: 1.5rem 2rem; flex: 1; min-width: 140px; }
94
+ .wz-stat-value {
95
+ font-size: clamp(1.75rem, 4vw, 2.75rem); font-weight: 800;
96
+ background: linear-gradient(135deg, var(--wz-primary), #a855f7);
97
+ -webkit-background-clip: text; -webkit-text-fill-color: transparent;
98
+ background-clip: text; line-height: 1.1; letter-spacing: -0.03em;
99
+ }
100
+ .wz-stat-label { font-size: 0.8rem; font-weight: 600; color: var(--wz-text-muted); text-transform: uppercase; letter-spacing: 0.08em; margin-top: 0.375rem; }
101
+
102
+ /* === LISTS === */
103
+ .wz-list { list-style: none; padding: 0; }
104
+ .wz-list .wz-listitem {
105
+ padding: 0.75rem 1rem; border-bottom: 1px solid var(--wz-border-light);
106
+ color: var(--wz-text-secondary); font-size: 0.95rem;
107
+ transition: background var(--wz-transition); display: flex; align-items: center;
108
+ }
109
+ .wz-list .wz-listitem:last-child { border-bottom: none; }
110
+ .wz-list .wz-listitem:hover { background: var(--wz-surface-hover); }
111
+ .wz-list .wz-listitem::before { content: '›'; margin-right: 0.75rem; color: var(--wz-primary); font-weight: bold; font-size: 1.2em; }
112
+ ol.wz-list { counter-reset: wz-list-counter; }
113
+ ol.wz-list .wz-listitem::before {
114
+ counter-increment: wz-list-counter; content: counter(wz-list-counter);
115
+ margin-right: 0.75rem; color: var(--wz-primary); font-weight: 700; font-size: 0.85em;
116
+ background: var(--wz-primary-light); width: 24px; height: 24px;
117
+ border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
118
+ }
119
+
120
+ /* === TABLE === */
121
+ .wz-table { width: 100%; border-collapse: separate; border-spacing: 0; border: 1px solid var(--wz-border); border-radius: var(--wz-radius-md); overflow: hidden; }
122
+ .wz-table th, .wz-table td { padding: 0.75rem 1rem; text-align: left; border-bottom: 1px solid var(--wz-border-light); }
123
+ .wz-table th { background: var(--wz-surface-hover); font-weight: 600; font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--wz-text-muted); }
124
+ .wz-table tr:last-child td { border-bottom: none; }
125
+ .wz-table tr:hover td { background: var(--wz-surface-hover); }
126
+
127
+ /* === BREADCRUMB === */
128
+ .wz-breadcrumb { display: flex; align-items: center; gap: 0.5rem; font-size: 0.875rem; color: var(--wz-text-muted); }
129
+ .wz-breadcrumb > *:not(:last-child)::after { content: '/'; margin-left: 0.5rem; color: var(--wz-border); }
130
+
131
+ /* === FOOTER / HEADER === */
132
+ .wz-footer { margin-top: 4rem; padding: 2rem 0; border-top: 1px solid var(--wz-border); text-align: center; color: var(--wz-text-muted); font-size: 0.875rem; }
133
+ .wz-footer .wz-row { justify-content: center; }
134
+ .wz-footer .wz-link { font-size: 0.875rem; }
135
+ .wz-header { padding: 1.5rem 0; margin-bottom: 2rem; border-bottom: 1px solid var(--wz-border); }
@@ -0,0 +1,110 @@
1
+ /* === BUTTONS === */
2
+ .wz-btn {
3
+ display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem;
4
+ font-family: var(--wz-font); font-weight: 600; font-size: 0.9rem;
5
+ padding: 0.75rem 1.75rem; border-radius: var(--wz-radius-full);
6
+ border: 2px solid transparent; cursor: pointer;
7
+ transition: all var(--wz-transition); line-height: 1; white-space: nowrap; text-decoration: none;
8
+ }
9
+ .wz-btn:active { transform: scale(0.97); }
10
+ .wz-btn-solid, .wz-btn-solid.wz-btn-primary {
11
+ background: linear-gradient(135deg, var(--wz-primary), var(--wz-primary-hover));
12
+ color: var(--wz-text-inverse); box-shadow: 0 2px 8px var(--wz-primary-glow);
13
+ }
14
+ .wz-btn-solid:hover, .wz-btn-solid.wz-btn-primary:hover {
15
+ transform: translateY(-1px); box-shadow: 0 4px 16px var(--wz-primary-glow); filter: brightness(1.1);
16
+ }
17
+ .wz-btn-outline { background: transparent; color: var(--wz-primary); border-color: var(--wz-primary); }
18
+ .wz-btn-outline:hover { background: var(--wz-primary-light); transform: translateY(-1px); }
19
+ .wz-btn-ghost { background: transparent; color: var(--wz-text-secondary); border: 2px solid transparent; }
20
+ .wz-btn-ghost:hover { background: var(--wz-surface-hover); color: var(--wz-text); }
21
+ .wz-btn-sm { font-size: 0.8rem; padding: 0.5rem 1.25rem; }
22
+ .wz-btn-lg { font-size: 1rem; padding: 1rem 2.5rem; }
23
+ .wz-btn-success.wz-btn-solid { background: linear-gradient(135deg, var(--wz-success), #059669); box-shadow: 0 2px 8px rgba(16,185,129,0.4); }
24
+ .wz-btn-error.wz-btn-solid, .wz-btn-danger.wz-btn-solid { background: linear-gradient(135deg, var(--wz-error), #dc2626); box-shadow: 0 2px 8px rgba(239,68,68,0.4); }
25
+ .wz-btn-warning.wz-btn-solid { background: linear-gradient(135deg, var(--wz-warning), #d97706); box-shadow: 0 2px 8px rgba(245,158,11,0.4); }
26
+ .wz-btn-success.wz-btn-outline { color: var(--wz-success); border-color: var(--wz-success); }
27
+ .wz-btn-error.wz-btn-outline, .wz-btn-danger.wz-btn-outline { color: var(--wz-error); border-color: var(--wz-error); }
28
+ .wz-btn-warning.wz-btn-outline { color: var(--wz-warning); border-color: var(--wz-warning); }
29
+ .wz-btn-success.wz-btn-outline:hover { background: var(--wz-success-light); }
30
+ .wz-btn-error.wz-btn-outline:hover, .wz-btn-danger.wz-btn-outline:hover { background: var(--wz-error-light); }
31
+ .wz-btn-warning.wz-btn-outline:hover { background: var(--wz-warning-light); }
32
+
33
+ /* === INPUTS & FORMS === */
34
+ .wz-input, .wz-textarea, .wz-select {
35
+ display: block; width: 100%; padding: 0.75rem 1rem;
36
+ font-family: var(--wz-font); font-size: 0.95rem; color: var(--wz-text);
37
+ background: var(--wz-surface); border: 2px solid var(--wz-border);
38
+ border-radius: var(--wz-radius-md); transition: all var(--wz-transition); outline: none;
39
+ }
40
+ .wz-input:focus, .wz-textarea:focus, .wz-select:focus {
41
+ border-color: var(--wz-primary); box-shadow: 0 0 0 4px var(--wz-primary-light);
42
+ }
43
+ .wz-input::placeholder, .wz-textarea::placeholder { color: var(--wz-text-muted); }
44
+ .wz-textarea { resize: vertical; min-height: 100px; }
45
+ .wz-select {
46
+ appearance: none; cursor: pointer; padding-right: 2.5rem;
47
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%2394a3b8' d='M6 8L1 3h10z'/%3E%3C/svg%3E");
48
+ background-repeat: no-repeat; background-position: right 1rem center;
49
+ }
50
+
51
+ /* === TOGGLE === */
52
+ .wz-toggle { display: inline-flex; align-items: center; gap: 0.75rem; cursor: pointer; user-select: none; }
53
+ .wz-toggle input { display: none; }
54
+ .wz-toggle-slider {
55
+ width: 48px; height: 26px; background: var(--wz-border);
56
+ border-radius: var(--wz-radius-full); position: relative; transition: background var(--wz-transition);
57
+ }
58
+ .wz-toggle-slider::after {
59
+ content: ''; position: absolute; top: 3px; left: 3px;
60
+ width: 20px; height: 20px; background: white; border-radius: 50%;
61
+ transition: transform var(--wz-transition); box-shadow: var(--wz-shadow-sm);
62
+ }
63
+ .wz-toggle input:checked + .wz-toggle-slider { background: var(--wz-primary); }
64
+ .wz-toggle input:checked + .wz-toggle-slider::after { transform: translateX(22px); }
65
+ .wz-toggle-label { font-size: 0.9rem; color: var(--wz-text-secondary); }
66
+
67
+ /* === CHECKBOX === */
68
+ .wz-checkbox { display: inline-flex; align-items: center; gap: 0.625rem; cursor: pointer; user-select: none; font-size: 0.9rem; color: var(--wz-text-secondary); }
69
+ .wz-checkbox input { display: none; }
70
+ .wz-checkbox-mark {
71
+ width: 20px; height: 20px; border: 2px solid var(--wz-border);
72
+ border-radius: var(--wz-radius-sm); display: flex; align-items: center;
73
+ justify-content: center; transition: all var(--wz-transition); flex-shrink: 0;
74
+ }
75
+ .wz-checkbox-mark::after { content: '✓'; font-size: 12px; color: white; opacity: 0; transition: opacity var(--wz-transition); }
76
+ .wz-checkbox input:checked + .wz-checkbox-mark { background: var(--wz-primary); border-color: var(--wz-primary); }
77
+ .wz-checkbox input:checked + .wz-checkbox-mark::after { opacity: 1; }
78
+
79
+ /* === RADIO === */
80
+ .wz-radio { display: inline-flex; align-items: center; gap: 0.625rem; cursor: pointer; user-select: none; font-size: 0.9rem; color: var(--wz-text-secondary); }
81
+ .wz-radio input { display: none; }
82
+ .wz-radio-mark {
83
+ width: 20px; height: 20px; border: 2px solid var(--wz-border);
84
+ border-radius: 50%; display: flex; align-items: center;
85
+ justify-content: center; transition: all var(--wz-transition); flex-shrink: 0;
86
+ }
87
+ .wz-radio-mark::after {
88
+ content: ''; width: 10px; height: 10px; background: var(--wz-primary);
89
+ border-radius: 50%; opacity: 0; transition: opacity var(--wz-transition);
90
+ }
91
+ .wz-radio input:checked + .wz-radio-mark { border-color: var(--wz-primary); }
92
+ .wz-radio input:checked + .wz-radio-mark::after { opacity: 1; }
93
+
94
+ /* === SLIDER === */
95
+ .wz-slider-wrap { display: flex; align-items: center; gap: 1rem; width: 100%; }
96
+ .wz-slider {
97
+ -webkit-appearance: none; appearance: none; width: 100%; height: 6px;
98
+ background: var(--wz-border); border-radius: var(--wz-radius-full); outline: none;
99
+ }
100
+ .wz-slider::-webkit-slider-thumb {
101
+ -webkit-appearance: none; width: 20px; height: 20px; background: var(--wz-primary);
102
+ border-radius: 50%; cursor: pointer; box-shadow: 0 2px 6px var(--wz-primary-glow);
103
+ transition: transform var(--wz-transition);
104
+ }
105
+ .wz-slider::-webkit-slider-thumb:hover { transform: scale(1.2); }
106
+ .wz-slider::-moz-range-thumb {
107
+ width: 20px; height: 20px; background: var(--wz-primary);
108
+ border-radius: 50%; cursor: pointer; border: none;
109
+ }
110
+ .wz-slider-value { font-size: 0.875rem; font-weight: 600; color: var(--wz-primary); min-width: 2.5rem; text-align: center; }
@@ -0,0 +1,111 @@
1
+ /* === TABS === */
2
+ .wz-tabs { width: 100%; }
3
+ .wz-tab-buttons {
4
+ display: flex; gap: 0.25rem; border-bottom: 2px solid var(--wz-border);
5
+ margin-bottom: 1.5rem; overflow-x: auto;
6
+ }
7
+ .wz-tab-btn {
8
+ padding: 0.75rem 1.25rem; background: none; border: none;
9
+ border-bottom: 2px solid transparent; margin-bottom: -2px;
10
+ font-family: var(--wz-font); font-size: 0.9rem; font-weight: 500;
11
+ color: var(--wz-text-muted); cursor: pointer; transition: all var(--wz-transition); white-space: nowrap;
12
+ }
13
+ .wz-tab-btn:hover { color: var(--wz-text); }
14
+ .wz-tab-btn.active { color: var(--wz-primary); border-bottom-color: var(--wz-primary); }
15
+ .wz-tab { display: none; }
16
+ .wz-tab.active { display: block; }
17
+
18
+ /* === ACCORDION === */
19
+ .wz-accordion { border: 1px solid var(--wz-border); border-radius: var(--wz-radius-md); overflow: hidden; }
20
+ .wz-accordion-item { border-bottom: 1px solid var(--wz-border); }
21
+ .wz-accordion-item:last-child { border-bottom: none; }
22
+ .wz-accordion-title {
23
+ padding: 1rem 1.25rem; font-weight: 600; font-size: 0.95rem; cursor: pointer;
24
+ display: flex; justify-content: space-between; align-items: center;
25
+ transition: background var(--wz-transition); user-select: none; color: var(--wz-text);
26
+ }
27
+ .wz-accordion-title:hover { background: var(--wz-surface-hover); }
28
+ .wz-accordion-title::after { content: '▸'; transition: transform var(--wz-transition); color: var(--wz-text-muted); }
29
+ .wz-accordion-item.active .wz-accordion-title::after { transform: rotate(90deg); }
30
+ .wz-accordion-body { max-height: 0; overflow: hidden; transition: max-height 0.3s ease, padding 0.3s ease; padding: 0 1.25rem; }
31
+ .wz-accordion-item.active .wz-accordion-body { max-height: 500px; padding: 0 1.25rem 1rem; }
32
+
33
+ /* === MODAL === */
34
+ .wz-modal {
35
+ display: none; position: fixed; top: 0; left: 0; right: 0; bottom: 0;
36
+ z-index: 1000; align-items: center; justify-content: center;
37
+ }
38
+ .wz-modal.active { display: flex; }
39
+ .wz-modal-backdrop {
40
+ position: absolute; top: 0; left: 0; right: 0; bottom: 0;
41
+ background: rgba(0,0,0,0.5); backdrop-filter: blur(4px);
42
+ }
43
+ .wz-modal-content {
44
+ position: relative; background: var(--wz-surface); border-radius: var(--wz-radius-xl);
45
+ padding: 2rem; max-width: 500px; width: 90%; box-shadow: var(--wz-shadow-xl);
46
+ z-index: 1; animation: wz-modal-in 0.25s ease-out;
47
+ }
48
+ @keyframes wz-modal-in {
49
+ from { opacity: 0; transform: scale(0.95) translateY(10px); }
50
+ to { opacity: 1; transform: scale(1) translateY(0); }
51
+ }
52
+ .wz-modal-close {
53
+ position: absolute; top: 1rem; right: 1rem; background: none; border: none;
54
+ font-size: 1.25rem; color: var(--wz-text-muted); cursor: pointer;
55
+ width: 32px; height: 32px; display: flex; align-items: center; justify-content: center;
56
+ border-radius: 50%; transition: all var(--wz-transition);
57
+ }
58
+ .wz-modal-close:hover { background: var(--wz-surface-hover); color: var(--wz-text); }
59
+
60
+ /* === DROPDOWN === */
61
+ .wz-dropdown { position: relative; display: inline-block; }
62
+ .wz-dropdown-menu {
63
+ position: absolute; top: 100%; left: 0; min-width: 200px;
64
+ background: var(--wz-surface); border: 1px solid var(--wz-border);
65
+ border-radius: var(--wz-radius-md); box-shadow: var(--wz-shadow-lg); padding: 0.5rem;
66
+ opacity: 0; visibility: hidden; transform: translateY(-4px);
67
+ transition: all var(--wz-transition); z-index: 50;
68
+ }
69
+ .wz-dropdown.active .wz-dropdown-menu { opacity: 1; visibility: visible; transform: translateY(4px); }
70
+
71
+ /* === TOOLTIP === */
72
+ .wz-tooltip { position: relative; display: inline-block; }
73
+ .wz-tooltip::after {
74
+ content: attr(data-tooltip); position: absolute; bottom: 100%; left: 50%;
75
+ transform: translateX(-50%) translateY(-4px); background: var(--wz-text);
76
+ color: var(--wz-text-inverse); padding: 0.375rem 0.75rem; border-radius: var(--wz-radius);
77
+ font-size: 0.75rem; white-space: nowrap; opacity: 0; visibility: hidden;
78
+ transition: all var(--wz-transition); pointer-events: none; z-index: 50;
79
+ }
80
+ .wz-tooltip:hover::after { opacity: 1; visibility: visible; transform: translateX(-50%) translateY(-8px); }
81
+
82
+ /* === PAGE TRANSITIONS (multi-page) === */
83
+ .wz-page { animation: wz-page-in 0.3s ease-out; }
84
+ @keyframes wz-page-in {
85
+ from { opacity: 0; transform: translateY(12px); }
86
+ to { opacity: 1; transform: translateY(0); }
87
+ }
88
+
89
+ /* === SCROLL ANIMATIONS === */
90
+ .wz-animate { opacity: 0; transform: translateY(24px); transition: opacity 0.6s ease, transform 0.6s ease; }
91
+ .wz-animate.wz-visible { opacity: 1; transform: translateY(0); }
92
+
93
+ /* === RESPONSIVE === */
94
+ @media (max-width: 768px) {
95
+ #app { padding: 1rem; }
96
+ #app > h1 { margin-bottom: 1.5rem; }
97
+ .wz-grid { grid-template-columns: 1fr !important; }
98
+ .wz-row { flex-direction: column; align-items: stretch; }
99
+ .wz-hero { padding: 3rem 1rem; margin: -1rem -1rem 1.5rem; }
100
+ .wz-nav { margin: -1rem -1rem 1.5rem; padding: 0 1rem; }
101
+ .wz-nav-inner { gap: 0.25rem; }
102
+ .wz-stat { min-width: auto; padding: 1rem; }
103
+ .wz-stat-value { font-size: 1.75rem; }
104
+ .wz-card { padding: 1.25rem; }
105
+ .wz-hero .wz-row { flex-direction: row; justify-content: center; }
106
+ }
107
+ @media (max-width: 480px) {
108
+ .wz-hero-title { font-size: 2rem; }
109
+ .wz-heading { font-size: 1.5rem; }
110
+ .wz-btn { padding: 0.625rem 1.25rem; font-size: 0.85rem; }
111
+ }