zero-query 1.1.1 → 1.2.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.
Files changed (154) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +2 -0
  3. package/cli/args.js +33 -33
  4. package/cli/commands/build-api.js +443 -442
  5. package/cli/commands/build.js +254 -247
  6. package/cli/commands/bundle.js +1228 -1224
  7. package/cli/commands/create.js +137 -121
  8. package/cli/commands/dev/devtools/index.js +56 -56
  9. package/cli/commands/dev/devtools/js/components.js +49 -49
  10. package/cli/commands/dev/devtools/js/core.js +423 -423
  11. package/cli/commands/dev/devtools/js/elements.js +421 -421
  12. package/cli/commands/dev/devtools/js/network.js +166 -166
  13. package/cli/commands/dev/devtools/js/performance.js +73 -73
  14. package/cli/commands/dev/devtools/js/router.js +105 -105
  15. package/cli/commands/dev/devtools/js/source.js +132 -132
  16. package/cli/commands/dev/devtools/js/stats.js +35 -35
  17. package/cli/commands/dev/devtools/js/tabs.js +79 -79
  18. package/cli/commands/dev/devtools/panel.html +95 -95
  19. package/cli/commands/dev/devtools/styles.css +244 -244
  20. package/cli/commands/dev/index.js +107 -107
  21. package/cli/commands/dev/logger.js +75 -75
  22. package/cli/commands/dev/overlay.js +858 -858
  23. package/cli/commands/dev/server.js +220 -220
  24. package/cli/commands/dev/validator.js +94 -94
  25. package/cli/commands/dev/watcher.js +172 -172
  26. package/cli/help.js +114 -112
  27. package/cli/index.js +52 -52
  28. package/cli/scaffold/default/LICENSE +21 -21
  29. package/cli/scaffold/default/app/app.js +207 -207
  30. package/cli/scaffold/default/app/components/about.js +201 -201
  31. package/cli/scaffold/default/app/components/api-demo.js +143 -143
  32. package/cli/scaffold/default/app/components/contact-card.js +231 -231
  33. package/cli/scaffold/default/app/components/contacts/contacts.css +706 -706
  34. package/cli/scaffold/default/app/components/contacts/contacts.html +200 -200
  35. package/cli/scaffold/default/app/components/contacts/contacts.js +196 -196
  36. package/cli/scaffold/default/app/components/counter.js +127 -127
  37. package/cli/scaffold/default/app/components/home.js +249 -249
  38. package/cli/scaffold/default/app/components/not-found.js +16 -16
  39. package/cli/scaffold/default/app/components/playground/playground.css +115 -115
  40. package/cli/scaffold/default/app/components/playground/playground.html +161 -161
  41. package/cli/scaffold/default/app/components/playground/playground.js +116 -116
  42. package/cli/scaffold/default/app/components/todos.js +225 -225
  43. package/cli/scaffold/default/app/components/toolkit/toolkit.css +97 -97
  44. package/cli/scaffold/default/app/components/toolkit/toolkit.html +146 -146
  45. package/cli/scaffold/default/app/components/toolkit/toolkit.js +280 -280
  46. package/cli/scaffold/default/app/routes.js +15 -15
  47. package/cli/scaffold/default/app/store.js +101 -101
  48. package/cli/scaffold/default/global.css +552 -552
  49. package/cli/scaffold/default/index.html +99 -99
  50. package/cli/scaffold/minimal/app/app.js +85 -85
  51. package/cli/scaffold/minimal/app/components/about.js +68 -68
  52. package/cli/scaffold/minimal/app/components/counter.js +122 -122
  53. package/cli/scaffold/minimal/app/components/home.js +68 -68
  54. package/cli/scaffold/minimal/app/components/not-found.js +16 -16
  55. package/cli/scaffold/minimal/app/routes.js +9 -9
  56. package/cli/scaffold/minimal/app/store.js +36 -36
  57. package/cli/scaffold/minimal/global.css +300 -300
  58. package/cli/scaffold/minimal/index.html +44 -44
  59. package/cli/scaffold/ssr/app/app.js +41 -41
  60. package/cli/scaffold/ssr/app/components/about.js +55 -55
  61. package/cli/scaffold/ssr/app/components/blog/index.js +65 -65
  62. package/cli/scaffold/ssr/app/components/blog/post.js +86 -86
  63. package/cli/scaffold/ssr/app/components/home.js +37 -37
  64. package/cli/scaffold/ssr/app/components/not-found.js +15 -15
  65. package/cli/scaffold/ssr/app/routes.js +8 -8
  66. package/cli/scaffold/ssr/global.css +228 -228
  67. package/cli/scaffold/ssr/index.html +37 -37
  68. package/cli/scaffold/ssr/package.json +8 -8
  69. package/cli/scaffold/ssr/server/data/posts.js +144 -144
  70. package/cli/scaffold/ssr/server/index.js +213 -213
  71. package/cli/scaffold/webrtc/app/app.js +11 -0
  72. package/cli/scaffold/webrtc/app/components/video-room.js +295 -0
  73. package/cli/scaffold/webrtc/app/lib/room.js +252 -0
  74. package/cli/scaffold/webrtc/assets/.gitkeep +0 -0
  75. package/cli/scaffold/webrtc/global.css +250 -0
  76. package/cli/scaffold/webrtc/index.html +21 -0
  77. package/cli/utils.js +305 -287
  78. package/dist/API.md +661 -0
  79. package/dist/zquery.dist.zip +0 -0
  80. package/dist/zquery.js +10313 -6614
  81. package/dist/zquery.min.js +8 -631
  82. package/index.d.ts +570 -371
  83. package/index.js +311 -240
  84. package/package.json +76 -70
  85. package/src/component.js +1709 -1691
  86. package/src/core.js +921 -921
  87. package/src/diff.js +497 -497
  88. package/src/errors.js +209 -209
  89. package/src/expression.js +922 -922
  90. package/src/http.js +242 -242
  91. package/src/package.json +1 -1
  92. package/src/reactive.js +255 -255
  93. package/src/router.js +843 -843
  94. package/src/ssr.js +418 -418
  95. package/src/store.js +318 -318
  96. package/src/utils.js +515 -515
  97. package/src/webrtc/e2ee.js +351 -0
  98. package/src/webrtc/errors.js +116 -0
  99. package/src/webrtc/ice.js +301 -0
  100. package/src/webrtc/index.js +131 -0
  101. package/src/webrtc/joinToken.js +119 -0
  102. package/src/webrtc/observe.js +172 -0
  103. package/src/webrtc/peer.js +351 -0
  104. package/src/webrtc/reactive.js +268 -0
  105. package/src/webrtc/room.js +625 -0
  106. package/src/webrtc/sdp.js +302 -0
  107. package/src/webrtc/sfu/index.js +43 -0
  108. package/src/webrtc/sfu/livekit.js +131 -0
  109. package/src/webrtc/sfu/mediasoup.js +150 -0
  110. package/src/webrtc/signaling.js +373 -0
  111. package/src/webrtc/turn.js +237 -0
  112. package/tests/_helpers/webrtcFakes.js +289 -0
  113. package/tests/audit.test.js +4158 -4158
  114. package/tests/cli.test.js +1136 -1103
  115. package/tests/compare.test.js +497 -486
  116. package/tests/component.test.js +3969 -3938
  117. package/tests/core.test.js +1910 -1910
  118. package/tests/dev-server.test.js +489 -489
  119. package/tests/diff.test.js +1416 -1416
  120. package/tests/docs.test.js +1664 -1650
  121. package/tests/electron-features.test.js +864 -864
  122. package/tests/errors.test.js +619 -619
  123. package/tests/expression.test.js +1056 -1056
  124. package/tests/http.test.js +648 -648
  125. package/tests/reactive.test.js +819 -819
  126. package/tests/router.test.js +2327 -2327
  127. package/tests/ssr.test.js +870 -870
  128. package/tests/store.test.js +830 -830
  129. package/tests/test-minifier.js +153 -153
  130. package/tests/test-ssr.js +27 -27
  131. package/tests/utils.test.js +1377 -1377
  132. package/tests/webrtc/e2ee.test.js +283 -0
  133. package/tests/webrtc/ice.test.js +202 -0
  134. package/tests/webrtc/joinToken.test.js +89 -0
  135. package/tests/webrtc/observe.test.js +111 -0
  136. package/tests/webrtc/peer.test.js +373 -0
  137. package/tests/webrtc/reactive.test.js +235 -0
  138. package/tests/webrtc/room.test.js +406 -0
  139. package/tests/webrtc/sdp.test.js +151 -0
  140. package/tests/webrtc/sfu-livekit.test.js +119 -0
  141. package/tests/webrtc/sfu.test.js +160 -0
  142. package/tests/webrtc/signaling.test.js +251 -0
  143. package/tests/webrtc/turn.test.js +256 -0
  144. package/types/collection.d.ts +383 -383
  145. package/types/component.d.ts +186 -186
  146. package/types/errors.d.ts +135 -135
  147. package/types/http.d.ts +92 -92
  148. package/types/misc.d.ts +201 -201
  149. package/types/reactive.d.ts +98 -98
  150. package/types/router.d.ts +190 -190
  151. package/types/ssr.d.ts +102 -102
  152. package/types/store.d.ts +146 -146
  153. package/types/utils.d.ts +245 -245
  154. package/types/webrtc.d.ts +653 -0
@@ -1,300 +1,300 @@
1
- /* global.css - minimal scaffold styles
2
- *
3
- * Dark theme by default, light theme via [data-theme="light"].
4
- * Modify the CSS variables below to customise the look and feel.
5
- */
6
-
7
- /* -- Theme Variables -- */
8
- :root {
9
- --bg: #0d1117;
10
- --bg-surface: #161b22;
11
- --bg-card: rgba(22, 27, 34, 0.55);
12
- --bg-hover: #21262d;
13
- --border: rgba(48, 54, 61, 0.45);
14
- --text: #e6edf3;
15
- --text-muted: #7d8590;
16
- --accent: #58a6ff;
17
- --accent-hover:#79c0ff;
18
- --accent-soft: rgba(88, 166, 255, 0.10);
19
- --accent-glow: rgba(88, 166, 255, 0.06);
20
- --success: #3fb950;
21
- --danger: #f85149;
22
- --radius: 8px;
23
- --radius-lg: 12px;
24
- --sidebar-w: 220px;
25
- --sidebar-bg: var(--bg-surface);
26
- --sidebar-border: var(--border);
27
- --topbar-h: 56px;
28
- --font: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
29
- --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
30
- }
31
-
32
- [data-theme="light"] {
33
- --bg: #f6f8fa;
34
- --bg-surface: #ffffff;
35
- --bg-card: rgba(255, 255, 255, 0.8);
36
- --bg-hover: #eaeef2;
37
- --border: rgba(208, 215, 222, 0.65);
38
- --text: #1f2328;
39
- --text-muted: #656d76;
40
- --accent: #0969da;
41
- --accent-hover:#0550ae;
42
- --accent-soft: rgba(9,105,218,0.08);
43
- --accent-glow: rgba(9,105,218,0.04);
44
- --sidebar-bg: #eef2f9;
45
- --sidebar-border: rgba(9, 105, 218, 0.12);
46
- --success: #1a7f37;
47
- --danger: #cf222e;
48
- }
49
-
50
- /* -- Reset -- */
51
- *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
52
-
53
- body {
54
- font-family: var(--font);
55
- font-size: 15px;
56
- line-height: 1.6;
57
- color: var(--text);
58
- background: var(--bg);
59
- overflow-x: hidden;
60
- }
61
-
62
- a { color: var(--accent); text-decoration: none; transition: color .15s; }
63
- a:hover { color: var(--accent-hover); }
64
- code { background: var(--bg-hover); padding: 2px 6px; border-radius: 4px; font-size: 0.85em; }
65
-
66
- /* -- Sidebar -- */
67
- .sidebar {
68
- position: fixed;
69
- top: 0; left: 0; bottom: 0;
70
- width: var(--sidebar-w);
71
- background: var(--sidebar-bg);
72
- border-right: 1px solid var(--sidebar-border);
73
- display: flex;
74
- flex-direction: column;
75
- z-index: 100;
76
- transition: transform 0.3s var(--ease-out);
77
- }
78
-
79
- .sidebar-header {
80
- padding: 1.25rem 1.25rem 1rem;
81
- border-bottom: 1px solid var(--border);
82
- }
83
-
84
- .brand {
85
- font-size: 1.15rem;
86
- font-weight: 700;
87
- color: var(--text);
88
- letter-spacing: -0.02em;
89
- }
90
-
91
- .sidebar-nav {
92
- flex: 1;
93
- padding: 0.75rem 0;
94
- overflow-y: auto;
95
- }
96
-
97
- .nav-link {
98
- display: block;
99
- padding: 0.6rem 1.25rem;
100
- color: var(--text-muted);
101
- font-size: 0.9rem;
102
- font-weight: 500;
103
- transition: all 0.15s ease;
104
- border-left: 3px solid transparent;
105
- }
106
-
107
- .nav-link:hover {
108
- color: var(--text);
109
- background: var(--bg-hover);
110
- }
111
-
112
- .nav-link.active {
113
- color: var(--accent);
114
- background: var(--accent-soft);
115
- border-left-color: var(--accent);
116
- }
117
-
118
- .sidebar-footer {
119
- padding: 0.75rem 1.25rem;
120
- border-top: 1px solid var(--border);
121
- color: var(--text-muted);
122
- font-size: 0.8rem;
123
- }
124
-
125
- [data-theme="light"] .sidebar {
126
- background: var(--sidebar-bg);
127
- border-right-color: var(--sidebar-border);
128
- }
129
-
130
- /* -- Mobile Top Bar -- */
131
- .topbar {
132
- display: none;
133
- position: fixed;
134
- top: 0; left: 0; right: 0;
135
- height: var(--topbar-h);
136
- background: var(--bg-surface);
137
- border-bottom: 1px solid var(--border);
138
- align-items: center;
139
- padding: 0 1rem;
140
- z-index: 101;
141
- }
142
-
143
- .topbar-brand {
144
- font-weight: 700;
145
- font-size: 1.05rem;
146
- margin-left: 0.75rem;
147
- }
148
-
149
- /* Hamburger */
150
- .hamburger {
151
- display: flex;
152
- flex-direction: column;
153
- justify-content: center;
154
- gap: 5px;
155
- width: 32px;
156
- height: 32px;
157
- background: none;
158
- border: none;
159
- cursor: pointer;
160
- padding: 4px;
161
- }
162
-
163
- .hamburger span {
164
- display: block;
165
- height: 2px;
166
- background: var(--text);
167
- border-radius: 2px;
168
- transition: all 0.25s var(--ease-out);
169
- }
170
-
171
- .hamburger.active span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
172
- .hamburger.active span:nth-child(2) { opacity: 0; }
173
- .hamburger.active span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }
174
-
175
- /* Overlay */
176
- .overlay {
177
- display: none;
178
- position: fixed;
179
- inset: 0;
180
- background: rgba(0, 0, 0, 0.5);
181
- z-index: 99;
182
- opacity: 0;
183
- transition: opacity 0.3s ease;
184
- }
185
-
186
- .overlay.visible { display: block; opacity: 1; }
187
-
188
- /* -- Main Content -- */
189
- .content {
190
- margin-left: auto;
191
- margin-right: auto;
192
- padding: 2.5rem 3rem 2.5rem calc(var(--sidebar-w) + 3rem);
193
- max-width: calc(1200px + var(--sidebar-w));
194
- min-height: 100vh;
195
- }
196
-
197
- /* -- Page Header -- */
198
- .page-header { margin-bottom: 2rem; }
199
- .page-header h1 { font-size: 1.85rem; font-weight: 700; margin-bottom: 0.35rem; letter-spacing: -0.02em; }
200
- .subtitle { color: var(--text-muted); font-size: 0.95rem; }
201
-
202
- /* -- Cards -- */
203
- .card {
204
- background: var(--bg-card);
205
- border: 1px solid var(--border);
206
- border-radius: var(--radius-lg);
207
- padding: 1.5rem;
208
- margin-bottom: 1.25rem;
209
- backdrop-filter: blur(8px);
210
- -webkit-backdrop-filter: blur(8px);
211
- transition: border-color .2s ease, box-shadow .2s ease;
212
- }
213
-
214
- .card:hover {
215
- border-color: rgba(88, 166, 255, 0.15);
216
- box-shadow: 0 4px 24px rgba(0, 0, 0, 0.15), 0 0 0 1px rgba(88, 166, 255, 0.04);
217
- }
218
-
219
- .card h3 { font-size: 1.1rem; margin-bottom: 0.5rem; }
220
- .card p { color: var(--text-muted); font-size: 0.9rem; margin-bottom: 0.75rem; }
221
-
222
- /* -- Buttons -- */
223
- .btn {
224
- display: inline-flex;
225
- align-items: center;
226
- gap: 0.4rem;
227
- padding: 0.5rem 1.1rem;
228
- font-size: 0.9rem;
229
- font-weight: 500;
230
- border: none;
231
- border-radius: var(--radius);
232
- cursor: pointer;
233
- transition: all 0.15s ease;
234
- font-family: inherit;
235
- }
236
-
237
- .btn:active { transform: scale(0.97); }
238
-
239
- .btn-primary { background: var(--accent); color: #fff; }
240
- .btn-primary:hover { background: var(--accent-hover); color: #fff; }
241
-
242
- .btn-outline { background: transparent; border: 1px solid var(--border); color: var(--accent); }
243
- .btn-outline:hover { border-color: var(--accent); background: var(--accent-soft); }
244
-
245
- .btn-ghost { background: transparent; color: var(--text-muted); }
246
- .btn-ghost:hover { color: var(--text); background: var(--bg-hover); }
247
-
248
- .btn-sm { padding: 0.35rem 0.75rem; font-size: 0.82rem; }
249
-
250
- /* -- Inputs -- */
251
- .input {
252
- width: 100%;
253
- padding: 0.55rem 0.85rem;
254
- background: var(--bg);
255
- border: 1px solid var(--border);
256
- border-radius: var(--radius);
257
- color: var(--text);
258
- font-size: 0.9rem;
259
- font-family: inherit;
260
- outline: none;
261
- transition: border-color 0.2s ease, box-shadow 0.2s ease;
262
- }
263
-
264
- .input:hover { border-color: rgba(88,166,255,0.2); }
265
- .input:focus { border-color: var(--accent); box-shadow: 0 0 0 2px rgba(88,166,255,0.1); }
266
- .input-sm { width: auto; padding: 0.35rem 0.6rem; font-size: 0.82rem; }
267
-
268
- .muted { color: var(--text-muted); }
269
-
270
- /* -- Route Transition -- */
271
- z-outlet { display: block; animation: fade-in 0.25s var(--ease-out); }
272
- @keyframes fade-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } }
273
-
274
- /* -- Responsive: Mobile -- */
275
- @media (max-width: 768px) {
276
- .sidebar {
277
- transform: translateX(-100%);
278
- width: 260px;
279
- }
280
- .sidebar.open { transform: translateX(0); }
281
-
282
- .topbar { display: flex; }
283
-
284
- .content {
285
- margin-left: 0;
286
- padding: 1.25rem;
287
- padding-top: calc(var(--topbar-h) + 1.25rem);
288
- max-width: 100%;
289
- }
290
-
291
- .card { padding: 1.15rem; }
292
- .page-header h1 { font-size: 1.4rem; }
293
- }
294
-
295
- @media (max-width: 480px) {
296
- .content { padding: 0.75rem; padding-top: calc(var(--topbar-h) + 0.75rem); }
297
- .card { padding: 1rem; }
298
- .page-header h1 { font-size: 1.25rem; }
299
- .subtitle { font-size: 0.85rem; }
300
- }
1
+ /* global.css - minimal scaffold styles
2
+ *
3
+ * Dark theme by default, light theme via [data-theme="light"].
4
+ * Modify the CSS variables below to customise the look and feel.
5
+ */
6
+
7
+ /* -- Theme Variables -- */
8
+ :root {
9
+ --bg: #0d1117;
10
+ --bg-surface: #161b22;
11
+ --bg-card: rgba(22, 27, 34, 0.55);
12
+ --bg-hover: #21262d;
13
+ --border: rgba(48, 54, 61, 0.45);
14
+ --text: #e6edf3;
15
+ --text-muted: #7d8590;
16
+ --accent: #58a6ff;
17
+ --accent-hover:#79c0ff;
18
+ --accent-soft: rgba(88, 166, 255, 0.10);
19
+ --accent-glow: rgba(88, 166, 255, 0.06);
20
+ --success: #3fb950;
21
+ --danger: #f85149;
22
+ --radius: 8px;
23
+ --radius-lg: 12px;
24
+ --sidebar-w: 220px;
25
+ --sidebar-bg: var(--bg-surface);
26
+ --sidebar-border: var(--border);
27
+ --topbar-h: 56px;
28
+ --font: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
29
+ --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
30
+ }
31
+
32
+ [data-theme="light"] {
33
+ --bg: #f6f8fa;
34
+ --bg-surface: #ffffff;
35
+ --bg-card: rgba(255, 255, 255, 0.8);
36
+ --bg-hover: #eaeef2;
37
+ --border: rgba(208, 215, 222, 0.65);
38
+ --text: #1f2328;
39
+ --text-muted: #656d76;
40
+ --accent: #0969da;
41
+ --accent-hover:#0550ae;
42
+ --accent-soft: rgba(9,105,218,0.08);
43
+ --accent-glow: rgba(9,105,218,0.04);
44
+ --sidebar-bg: #eef2f9;
45
+ --sidebar-border: rgba(9, 105, 218, 0.12);
46
+ --success: #1a7f37;
47
+ --danger: #cf222e;
48
+ }
49
+
50
+ /* -- Reset -- */
51
+ *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
52
+
53
+ body {
54
+ font-family: var(--font);
55
+ font-size: 15px;
56
+ line-height: 1.6;
57
+ color: var(--text);
58
+ background: var(--bg);
59
+ overflow-x: hidden;
60
+ }
61
+
62
+ a { color: var(--accent); text-decoration: none; transition: color .15s; }
63
+ a:hover { color: var(--accent-hover); }
64
+ code { background: var(--bg-hover); padding: 2px 6px; border-radius: 4px; font-size: 0.85em; }
65
+
66
+ /* -- Sidebar -- */
67
+ .sidebar {
68
+ position: fixed;
69
+ top: 0; left: 0; bottom: 0;
70
+ width: var(--sidebar-w);
71
+ background: var(--sidebar-bg);
72
+ border-right: 1px solid var(--sidebar-border);
73
+ display: flex;
74
+ flex-direction: column;
75
+ z-index: 100;
76
+ transition: transform 0.3s var(--ease-out);
77
+ }
78
+
79
+ .sidebar-header {
80
+ padding: 1.25rem 1.25rem 1rem;
81
+ border-bottom: 1px solid var(--border);
82
+ }
83
+
84
+ .brand {
85
+ font-size: 1.15rem;
86
+ font-weight: 700;
87
+ color: var(--text);
88
+ letter-spacing: -0.02em;
89
+ }
90
+
91
+ .sidebar-nav {
92
+ flex: 1;
93
+ padding: 0.75rem 0;
94
+ overflow-y: auto;
95
+ }
96
+
97
+ .nav-link {
98
+ display: block;
99
+ padding: 0.6rem 1.25rem;
100
+ color: var(--text-muted);
101
+ font-size: 0.9rem;
102
+ font-weight: 500;
103
+ transition: all 0.15s ease;
104
+ border-left: 3px solid transparent;
105
+ }
106
+
107
+ .nav-link:hover {
108
+ color: var(--text);
109
+ background: var(--bg-hover);
110
+ }
111
+
112
+ .nav-link.active {
113
+ color: var(--accent);
114
+ background: var(--accent-soft);
115
+ border-left-color: var(--accent);
116
+ }
117
+
118
+ .sidebar-footer {
119
+ padding: 0.75rem 1.25rem;
120
+ border-top: 1px solid var(--border);
121
+ color: var(--text-muted);
122
+ font-size: 0.8rem;
123
+ }
124
+
125
+ [data-theme="light"] .sidebar {
126
+ background: var(--sidebar-bg);
127
+ border-right-color: var(--sidebar-border);
128
+ }
129
+
130
+ /* -- Mobile Top Bar -- */
131
+ .topbar {
132
+ display: none;
133
+ position: fixed;
134
+ top: 0; left: 0; right: 0;
135
+ height: var(--topbar-h);
136
+ background: var(--bg-surface);
137
+ border-bottom: 1px solid var(--border);
138
+ align-items: center;
139
+ padding: 0 1rem;
140
+ z-index: 101;
141
+ }
142
+
143
+ .topbar-brand {
144
+ font-weight: 700;
145
+ font-size: 1.05rem;
146
+ margin-left: 0.75rem;
147
+ }
148
+
149
+ /* Hamburger */
150
+ .hamburger {
151
+ display: flex;
152
+ flex-direction: column;
153
+ justify-content: center;
154
+ gap: 5px;
155
+ width: 32px;
156
+ height: 32px;
157
+ background: none;
158
+ border: none;
159
+ cursor: pointer;
160
+ padding: 4px;
161
+ }
162
+
163
+ .hamburger span {
164
+ display: block;
165
+ height: 2px;
166
+ background: var(--text);
167
+ border-radius: 2px;
168
+ transition: all 0.25s var(--ease-out);
169
+ }
170
+
171
+ .hamburger.active span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
172
+ .hamburger.active span:nth-child(2) { opacity: 0; }
173
+ .hamburger.active span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }
174
+
175
+ /* Overlay */
176
+ .overlay {
177
+ display: none;
178
+ position: fixed;
179
+ inset: 0;
180
+ background: rgba(0, 0, 0, 0.5);
181
+ z-index: 99;
182
+ opacity: 0;
183
+ transition: opacity 0.3s ease;
184
+ }
185
+
186
+ .overlay.visible { display: block; opacity: 1; }
187
+
188
+ /* -- Main Content -- */
189
+ .content {
190
+ margin-left: auto;
191
+ margin-right: auto;
192
+ padding: 2.5rem 3rem 2.5rem calc(var(--sidebar-w) + 3rem);
193
+ max-width: calc(1200px + var(--sidebar-w));
194
+ min-height: 100vh;
195
+ }
196
+
197
+ /* -- Page Header -- */
198
+ .page-header { margin-bottom: 2rem; }
199
+ .page-header h1 { font-size: 1.85rem; font-weight: 700; margin-bottom: 0.35rem; letter-spacing: -0.02em; }
200
+ .subtitle { color: var(--text-muted); font-size: 0.95rem; }
201
+
202
+ /* -- Cards -- */
203
+ .card {
204
+ background: var(--bg-card);
205
+ border: 1px solid var(--border);
206
+ border-radius: var(--radius-lg);
207
+ padding: 1.5rem;
208
+ margin-bottom: 1.25rem;
209
+ backdrop-filter: blur(8px);
210
+ -webkit-backdrop-filter: blur(8px);
211
+ transition: border-color .2s ease, box-shadow .2s ease;
212
+ }
213
+
214
+ .card:hover {
215
+ border-color: rgba(88, 166, 255, 0.15);
216
+ box-shadow: 0 4px 24px rgba(0, 0, 0, 0.15), 0 0 0 1px rgba(88, 166, 255, 0.04);
217
+ }
218
+
219
+ .card h3 { font-size: 1.1rem; margin-bottom: 0.5rem; }
220
+ .card p { color: var(--text-muted); font-size: 0.9rem; margin-bottom: 0.75rem; }
221
+
222
+ /* -- Buttons -- */
223
+ .btn {
224
+ display: inline-flex;
225
+ align-items: center;
226
+ gap: 0.4rem;
227
+ padding: 0.5rem 1.1rem;
228
+ font-size: 0.9rem;
229
+ font-weight: 500;
230
+ border: none;
231
+ border-radius: var(--radius);
232
+ cursor: pointer;
233
+ transition: all 0.15s ease;
234
+ font-family: inherit;
235
+ }
236
+
237
+ .btn:active { transform: scale(0.97); }
238
+
239
+ .btn-primary { background: var(--accent); color: #fff; }
240
+ .btn-primary:hover { background: var(--accent-hover); color: #fff; }
241
+
242
+ .btn-outline { background: transparent; border: 1px solid var(--border); color: var(--accent); }
243
+ .btn-outline:hover { border-color: var(--accent); background: var(--accent-soft); }
244
+
245
+ .btn-ghost { background: transparent; color: var(--text-muted); }
246
+ .btn-ghost:hover { color: var(--text); background: var(--bg-hover); }
247
+
248
+ .btn-sm { padding: 0.35rem 0.75rem; font-size: 0.82rem; }
249
+
250
+ /* -- Inputs -- */
251
+ .input {
252
+ width: 100%;
253
+ padding: 0.55rem 0.85rem;
254
+ background: var(--bg);
255
+ border: 1px solid var(--border);
256
+ border-radius: var(--radius);
257
+ color: var(--text);
258
+ font-size: 0.9rem;
259
+ font-family: inherit;
260
+ outline: none;
261
+ transition: border-color 0.2s ease, box-shadow 0.2s ease;
262
+ }
263
+
264
+ .input:hover { border-color: rgba(88,166,255,0.2); }
265
+ .input:focus { border-color: var(--accent); box-shadow: 0 0 0 2px rgba(88,166,255,0.1); }
266
+ .input-sm { width: auto; padding: 0.35rem 0.6rem; font-size: 0.82rem; }
267
+
268
+ .muted { color: var(--text-muted); }
269
+
270
+ /* -- Route Transition -- */
271
+ z-outlet { display: block; animation: fade-in 0.25s var(--ease-out); }
272
+ @keyframes fade-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } }
273
+
274
+ /* -- Responsive: Mobile -- */
275
+ @media (max-width: 768px) {
276
+ .sidebar {
277
+ transform: translateX(-100%);
278
+ width: 260px;
279
+ }
280
+ .sidebar.open { transform: translateX(0); }
281
+
282
+ .topbar { display: flex; }
283
+
284
+ .content {
285
+ margin-left: 0;
286
+ padding: 1.25rem;
287
+ padding-top: calc(var(--topbar-h) + 1.25rem);
288
+ max-width: 100%;
289
+ }
290
+
291
+ .card { padding: 1.15rem; }
292
+ .page-header h1 { font-size: 1.4rem; }
293
+ }
294
+
295
+ @media (max-width: 480px) {
296
+ .content { padding: 0.75rem; padding-top: calc(var(--topbar-h) + 0.75rem); }
297
+ .card { padding: 1rem; }
298
+ .page-header h1 { font-size: 1.25rem; }
299
+ .subtitle { font-size: 0.85rem; }
300
+ }
@@ -1,44 +1,44 @@
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>{{NAME}}</title>
7
- <base href="/">
8
- <link rel="stylesheet" href="global.css">
9
- <script src="zquery.min.js"></script>
10
- <script type="module" src="app/app.js"></script>
11
- </head>
12
- <body>
13
-
14
- <!-- Sidebar Navigation -->
15
- <aside class="sidebar" id="sidebar">
16
- <div class="sidebar-header">
17
- <span class="brand">⚡ {{NAME}}</span>
18
- </div>
19
- <nav class="sidebar-nav">
20
- <a z-link="/" class="nav-link" z-active-route="/" z-active-exact>Home</a>
21
- <a z-link="/counter" class="nav-link" z-active-route="/counter">Counter</a>
22
- <a z-link="/about" class="nav-link" z-active-route="/about">About</a>
23
- </nav>
24
- <div class="sidebar-footer">
25
- <small>zQuery <span id="nav-version"></span></small>
26
- </div>
27
- </aside>
28
-
29
- <!-- Mobile Top Bar -->
30
- <header class="topbar" id="topbar">
31
- <button class="hamburger" id="menu-toggle" aria-label="Toggle menu">
32
- <span></span><span></span><span></span>
33
- </button>
34
- <span class="topbar-brand">⚡ {{NAME}}</span>
35
- </header>
36
-
37
- <!-- Overlay for mobile menu -->
38
- <div class="overlay" id="overlay"></div>
39
-
40
- <!-- Router Outlet -->
41
- <z-outlet class="content"></z-outlet>
42
-
43
- </body>
44
- </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>{{NAME}}</title>
7
+ <base href="/">
8
+ <link rel="stylesheet" href="global.css">
9
+ <script src="zquery.min.js"></script>
10
+ <script type="module" src="app/app.js"></script>
11
+ </head>
12
+ <body>
13
+
14
+ <!-- Sidebar Navigation -->
15
+ <aside class="sidebar" id="sidebar">
16
+ <div class="sidebar-header">
17
+ <span class="brand">⚡ {{NAME}}</span>
18
+ </div>
19
+ <nav class="sidebar-nav">
20
+ <a z-link="/" class="nav-link" z-active-route="/" z-active-exact>Home</a>
21
+ <a z-link="/counter" class="nav-link" z-active-route="/counter">Counter</a>
22
+ <a z-link="/about" class="nav-link" z-active-route="/about">About</a>
23
+ </nav>
24
+ <div class="sidebar-footer">
25
+ <small>zQuery <span id="nav-version"></span></small>
26
+ </div>
27
+ </aside>
28
+
29
+ <!-- Mobile Top Bar -->
30
+ <header class="topbar" id="topbar">
31
+ <button class="hamburger" id="menu-toggle" aria-label="Toggle menu">
32
+ <span></span><span></span><span></span>
33
+ </button>
34
+ <span class="topbar-brand">⚡ {{NAME}}</span>
35
+ </header>
36
+
37
+ <!-- Overlay for mobile menu -->
38
+ <div class="overlay" id="overlay"></div>
39
+
40
+ <!-- Router Outlet -->
41
+ <z-outlet class="content"></z-outlet>
42
+
43
+ </body>
44
+ </html>