fusee-framework 1.5.3 → 1.7.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 (115) hide show
  1. package/README.md +30 -13
  2. package/app/benchmark/benchmark.js +633 -0
  3. package/app/benchmark/index.html +102 -0
  4. package/app/benchmark/styles.css +249 -0
  5. package/app/components/Counter.js +17 -7
  6. package/app/components/Counter.ts +1 -1
  7. package/app/components/CounterSection.js +3 -4
  8. package/app/main.js +29 -62
  9. package/app/main.ts +72 -63
  10. package/app/pages/404.js +16 -0
  11. package/app/pages/[...all].js +35 -0
  12. package/app/pages/[...all].ts +35 -0
  13. package/app/pages/_layout.js +26 -0
  14. package/app/pages/_layout.ts +26 -0
  15. package/app/pages/about.js +23 -0
  16. package/app/pages/about.ts +29 -0
  17. package/app/pages/composables.js +158 -0
  18. package/app/pages/composables.ts +158 -0
  19. package/app/pages/dynamic.js +40 -0
  20. package/app/pages/dynamic.ts +40 -0
  21. package/app/pages/index.js +117 -0
  22. package/app/pages/index.ts +78 -0
  23. package/app/pages/login.ts +21 -0
  24. package/app/pages/objects/[id].js +56 -0
  25. package/app/pages/objects/[id].ts +56 -0
  26. package/app/pages/posts/[category]/[slug].js +56 -0
  27. package/app/pages/posts/[category]/[slug].ts +56 -0
  28. package/app/pages/router-example.js +56 -0
  29. package/app/pages/router-example.ts +56 -0
  30. package/app/pages/test-for.js +65 -0
  31. package/app/pages/test-for.ts +80 -0
  32. package/app/pages/users/[id].js +24 -0
  33. package/app/pages/users/[id].ts +46 -0
  34. package/app/pages/users/index.js +22 -0
  35. package/app/pages/users/index.ts +29 -0
  36. package/app/pages/users.js +43 -0
  37. package/app/pages/users.ts +78 -0
  38. package/app/routes/About.js +1 -1
  39. package/app/routes/About.ts +1 -1
  40. package/app/routes/AuthRoutes.ts +41 -0
  41. package/app/routes/Home.js +9 -0
  42. package/app/routes/NotFound.js +16 -0
  43. package/app/routes/NotFound.ts +16 -0
  44. package/app/routes/RouterExample.js +56 -0
  45. package/app/routes/RouterExample.ts +56 -0
  46. package/app/routes/WildcardDemo.js +35 -0
  47. package/app/routes/WildcardDemo.ts +35 -0
  48. package/auto-imports.d.ts +1 -0
  49. package/bin/create-fusee-linux +0 -0
  50. package/bin/create-fusee-mac-arm64 +0 -0
  51. package/bin/create-fusee-mac-intel +0 -0
  52. package/bin/create-fusee-win.exe +0 -0
  53. package/bin/create-fusee.exe +0 -0
  54. package/bin/index.js +38 -0
  55. package/create-fusee-go/cmd/generate.go +72 -0
  56. package/create-fusee-go/cmd/init.go +38 -0
  57. package/create-fusee-go/cmd/root.go +121 -0
  58. package/create-fusee-go/go.mod +10 -0
  59. package/create-fusee-go/go.sum +10 -0
  60. package/create-fusee-go/internal/assets/assets.go +78 -0
  61. package/create-fusee-go/internal/assets/embed/framework/auto-import-preset.js +9 -0
  62. package/create-fusee-go/internal/assets/embed/framework/core/compiler.js +253 -0
  63. package/create-fusee-go/internal/assets/embed/framework/core/component.js +266 -0
  64. package/create-fusee-go/internal/assets/embed/framework/core/composable.js +27 -0
  65. package/create-fusee-go/internal/assets/embed/framework/core/directives.js +875 -0
  66. package/create-fusee-go/internal/assets/embed/framework/core/evaluator.js +153 -0
  67. package/create-fusee-go/internal/assets/embed/framework/core/event-delegation.js +191 -0
  68. package/create-fusee-go/internal/assets/embed/framework/core/signal.js +412 -0
  69. package/create-fusee-go/internal/assets/embed/framework/core/store.js +81 -0
  70. package/create-fusee-go/internal/assets/embed/framework/index.d.ts +3 -0
  71. package/create-fusee-go/internal/assets/embed/framework/index.js +10 -0
  72. package/create-fusee-go/internal/assets/embed/framework/router/file-router.js +177 -0
  73. package/create-fusee-go/internal/assets/embed/framework/router/router.js +462 -0
  74. package/create-fusee-go/internal/assets/embed/framework/types/compiler.d.ts +15 -0
  75. package/create-fusee-go/internal/assets/embed/framework/types/component.d.ts +88 -0
  76. package/create-fusee-go/internal/assets/embed/framework/types/composable.d.ts +14 -0
  77. package/create-fusee-go/internal/assets/embed/framework/types/directives.d.ts +55 -0
  78. package/create-fusee-go/internal/assets/embed/framework/types/evaluator.d.ts +13 -0
  79. package/create-fusee-go/internal/assets/embed/framework/types/event-delegation.d.ts +32 -0
  80. package/create-fusee-go/internal/assets/embed/framework/types/index.d.ts +22 -0
  81. package/create-fusee-go/internal/assets/embed/framework/types/router.d.ts +32 -0
  82. package/create-fusee-go/internal/assets/embed/framework/types/signal.d.ts +79 -0
  83. package/create-fusee-go/internal/assets/embed/framework/types/store.d.ts +8 -0
  84. package/create-fusee-go/internal/assets/templates/Counter.tmpl +26 -0
  85. package/create-fusee-go/internal/assets/templates/component.tmpl +11 -0
  86. package/create-fusee-go/internal/assets/templates/components/Loading.tmpl +24 -0
  87. package/create-fusee-go/internal/assets/templates/index.html.tmpl +15 -0
  88. package/create-fusee-go/internal/assets/templates/main.tmpl +14 -0
  89. package/create-fusee-go/internal/assets/templates/package.json.tmpl +14 -0
  90. package/create-fusee-go/internal/assets/templates/page.tmpl +12 -0
  91. package/create-fusee-go/internal/assets/templates/pages/about.tmpl +20 -0
  92. package/create-fusee-go/internal/assets/templates/pages/index.tmpl +22 -0
  93. package/create-fusee-go/internal/assets/templates/pages/layout.tmpl +18 -0
  94. package/create-fusee-go/internal/assets/templates/tsconfig.json.tmpl +14 -0
  95. package/create-fusee-go/internal/assets/templates/vite.config.js.tmpl +18 -0
  96. package/create-fusee-go/main.go +7 -0
  97. package/framework/auto-import-preset.js +1 -1
  98. package/framework/core/compiler.js +252 -249
  99. package/framework/core/component.js +265 -260
  100. package/framework/core/directives.js +875 -632
  101. package/framework/core/evaluator.js +153 -70
  102. package/framework/core/event-delegation.js +191 -0
  103. package/framework/core/signal.js +412 -404
  104. package/framework/index.js +10 -11
  105. package/framework/router/file-router.js +177 -0
  106. package/framework/router/router.js +462 -80
  107. package/framework/types/component.d.ts +0 -4
  108. package/framework/types/event-delegation.d.ts +32 -0
  109. package/framework/types/index.d.ts +3 -0
  110. package/framework/types/router.d.ts +32 -15
  111. package/framework/types/signal.d.ts +1 -0
  112. package/index.html +638 -563
  113. package/package.json +5 -3
  114. package/tsconfig.json +1 -0
  115. /package/{framework → create-fusee-go/internal/assets/embed/framework}/bin/create-fusee.js +0 -0
package/index.html CHANGED
@@ -1,564 +1,639 @@
1
- <!DOCTYPE html>
2
- <html lang="ro">
3
-
4
- <head>
5
- <meta charset="UTF-8" />
6
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
- <title>MyFramework — SPA Demo</title>
8
- <style>
9
- *,
10
- *::before,
11
- *::after {
12
- box-sizing: border-box;
13
- margin: 0;
14
- padding: 0;
15
- }
16
-
17
- body {
18
- font-family: system-ui, sans-serif;
19
- background: #0f0f13;
20
- color: #e8e8f0;
21
- min-height: 100vh;
22
- }
23
-
24
- nav {
25
- display: flex;
26
- gap: 1rem;
27
- padding: 1rem 2rem;
28
- background: #1a1a24;
29
- border-bottom: 1px solid #2a2a3a;
30
- }
31
-
32
- nav a {
33
- color: #ff3333;
34
- text-decoration: none;
35
- font-weight: 500;
36
- }
37
-
38
- /* Temă Red Fusée */
39
- #app h1 {
40
- color: #ff3333;
41
- text-shadow: 0 0 20px rgba(255, 51, 51, 0.4);
42
- margin-bottom: 1rem;
43
- }
44
-
45
- #app p {
46
- color: #ff9999;
47
- opacity: 0.9;
48
- }
49
-
50
- nav a:hover {
51
- color: #fff;
52
- }
53
-
54
- #app {
55
- padding: 2rem;
56
- max-width: 600px;
57
- margin: 0 auto;
58
- }
59
-
60
- .page h1 {
61
- margin-bottom: 1rem;
62
- font-size: 1.8rem;
63
- }
64
-
65
- .page p {
66
- margin-bottom: 0.5rem;
67
- color: #aaa;
68
- line-height: 1.6;
69
- }
70
-
71
- .counter {
72
- margin-top: 2rem;
73
- padding: 1.5rem;
74
- background: #1a1a24;
75
- border: 1px solid #2a2a3a;
76
- border-radius: 10px;
77
- display: inline-block;
78
- }
79
-
80
- .counter h2 {
81
- margin-bottom: 1rem;
82
- font-size: 1rem;
83
- color: #888;
84
- text-transform: uppercase;
85
- letter-spacing: 0.1em;
86
- }
87
-
88
- .value {
89
- font-size: 4rem !important;
90
- font-weight: 700;
91
- color: #8b8bff !important;
92
- text-align: center;
93
- line-height: 1;
94
- margin-bottom: 0.25rem !important;
95
- }
96
-
97
- .derived {
98
- text-align: center;
99
- font-size: 0.85rem !important;
100
- color: #555 !important;
101
- margin-bottom: 1rem !important;
102
- }
103
-
104
- .actions {
105
- display: flex;
106
- gap: 0.5rem;
107
- justify-content: center;
108
- }
109
-
110
- .actions button {
111
- padding: 0.5rem 1.25rem;
112
- border: 1px solid #3a3a5a;
113
- background: #0f0f1a;
114
- color: #e8e8f0;
115
- border-radius: 6px;
116
- cursor: pointer;
117
- font-size: 1.1rem;
118
- transition: background 0.15s;
119
- }
120
-
121
- .actions button:hover {
122
- background: #2a2a3a;
123
- }
124
-
125
- .primary-btn {
126
- padding: 0.6rem 1.25rem;
127
- border: none;
128
- background: #8b8bff;
129
- color: #fff;
130
- font-weight: 600;
131
- border-radius: 6px;
132
- cursor: pointer;
133
- font-size: 1rem;
134
- transition: background 0.15s, transform 0.1s;
135
- }
136
-
137
- .primary-btn:hover {
138
- background: #7171e5;
139
- }
140
-
141
- .primary-btn:active {
142
- transform: scale(0.97);
143
- }
144
-
145
- .status {
146
- margin-top: 1rem;
147
- font-size: 0.8rem;
148
- color: #4caf50 !important;
149
- }
150
-
151
- .positive {
152
- color: #8b8bff !important;
153
- }
154
-
155
- .negative {
156
- color: #ff6b6b !important;
157
- }
158
-
159
- .actions button:disabled {
160
- opacity: 0.3;
161
- cursor: not-allowed;
162
- }
163
-
164
- /* ── Composables demo ──────────────────────────────────────────── */
165
- .demo-card {
166
- background: #13131d;
167
- border: 1px solid #2a2a3a;
168
- border-radius: 12px;
169
- padding: 1.5rem;
170
- margin-bottom: 1.5rem;
171
- }
172
-
173
- .demo-card h2 {
174
- font-size: 1rem;
175
- font-weight: 600;
176
- color: #e8e8f0;
177
- margin-bottom: 0.35rem;
178
- }
179
-
180
- .demo-desc {
181
- font-size: 0.8rem;
182
- color: #555 !important;
183
- margin-bottom: 1rem !important;
184
- }
185
-
186
- .counter-display {
187
- display: flex;
188
- flex-direction: column;
189
- align-items: center;
190
- margin-bottom: 1rem;
191
- }
192
-
193
- .big-num {
194
- font-size: 3.5rem;
195
- font-weight: 700;
196
- line-height: 1;
197
- transition: color 0.2s;
198
- }
199
-
200
- .big-num.even {
201
- color: #8b8bff;
202
- }
203
-
204
- .big-num.odd {
205
- color: #ff3333;
206
- }
207
-
208
- .derived-label {
209
- font-size: 0.8rem;
210
- color: #555;
211
- margin-top: 0.25rem;
212
- }
213
-
214
- .btn-row {
215
- display: flex;
216
- gap: 0.5rem;
217
- justify-content: center;
218
- margin-bottom: 0.75rem;
219
- }
220
-
221
- .cmp-btn {
222
- padding: 0.45rem 1.1rem;
223
- border-radius: 6px;
224
- border: 1px solid #2a2a3a;
225
- background: #0f0f1a;
226
- color: #e8e8f0;
227
- cursor: pointer;
228
- font-size: 1rem;
229
- transition: background 0.15s;
230
- }
231
-
232
- .cmp-btn:hover {
233
- background: #1f1f30;
234
- }
235
-
236
- .cmp-btn.plus {
237
- border-color: #8b8bff;
238
- color: #8b8bff;
239
- }
240
-
241
- .cmp-btn.minus {
242
- border-color: #ff3333;
243
- color: #ff3333;
244
- }
245
-
246
- .cmp-btn.reset {
247
- border-color: #555;
248
- color: #888;
249
- }
250
-
251
- .badge {
252
- display: inline-block;
253
- padding: 0.2rem 0.65rem;
254
- border-radius: 999px;
255
- font-size: 0.75rem;
256
- font-weight: 600;
257
- }
258
-
259
- .badge-blue {
260
- background: rgba(139, 139, 255, 0.15);
261
- color: #8b8bff;
262
- }
263
-
264
- .badge-red {
265
- background: rgba(255, 51, 51, 0.12);
266
- color: #ff3333;
267
- }
268
-
269
- .mouse-display {
270
- display: flex;
271
- gap: 2rem;
272
- font-size: 1.1rem;
273
- color: #aaa;
274
- margin-bottom: 0.5rem;
275
- }
276
-
277
- .mouse-display strong {
278
- color: #e8e8f0;
279
- }
280
-
281
- .cmp-input {
282
- width: 100%;
283
- padding: 0.5rem 0.75rem;
284
- background: #0f0f1a;
285
- border: 1px solid #2a2a3a;
286
- border-radius: 6px;
287
- color: #e8e8f0;
288
- font-size: 0.95rem;
289
- outline: none;
290
- transition: border-color 0.15s;
291
- }
292
-
293
- .cmp-input:focus {
294
- border-color: #8b8bff;
295
- }
296
-
297
- /* ── f-classList demo styles (Home page) ─────────────────────── */
298
- .demo-box {
299
- width: 200px;
300
- height: 100px;
301
- background: #1a1a24;
302
- border: 2px solid #3a3a5a;
303
- border-radius: 8px;
304
- display: flex;
305
- align-items: center;
306
- justify-content: center;
307
- font-weight: 600;
308
- transition: all 0.3s ease;
309
- margin-top: 1rem;
310
- }
311
-
312
- .demo-box.active {
313
- border-color: #8b8bff;
314
- background: rgba(139, 139, 255, 0.1);
315
- box-shadow: 0 0 20px rgba(139, 139, 255, 0.3);
316
- }
317
-
318
- .demo-box.disabled {
319
- opacity: 0.5;
320
- cursor: not-allowed;
321
- }
322
-
323
- .demo-box.is-large {
324
- width: 300px;
325
- height: 150px;
326
- font-size: 1.2rem;
327
- }
328
-
329
- .btn-on {
330
- background: #8b8bff !important;
331
- border-color: #8b8bff !important;
332
- color: #fff !important;
333
- }
334
-
335
- .btn-off {
336
- background: #1a1a24 !important;
337
- border-color: #555 !important;
338
- color: #888 !important;
339
- }
340
-
341
- .test-classlist h1 {
342
- color: #f59e0b;
343
- text-shadow: 0 0 20px rgba(245, 158, 11, 0.3);
344
- }
345
-
346
- .test-classlist .subtitle {
347
- color: #aaa;
348
- font-size: 0.9rem;
349
- margin-bottom: 2rem;
350
- }
351
-
352
- .demo-section {
353
- background: #13131d;
354
- border: 1px solid #2a2a3a;
355
- border-radius: 12px;
356
- padding: 1.5rem;
357
- margin-bottom: 1.5rem;
358
- }
359
-
360
- .demo-section h2 {
361
- font-size: 1rem;
362
- font-weight: 600;
363
- color: #e8e8f0;
364
- margin-bottom: 1rem;
365
- }
366
-
367
- .demo-box {
368
- width: 200px;
369
- height: 100px;
370
- background: #1a1a24;
371
- border: 2px solid #3a3a5a;
372
- border-radius: 8px;
373
- display: flex;
374
- align-items: center;
375
- justify-content: center;
376
- font-weight: 600;
377
- transition: all 0.3s ease;
378
- margin-bottom: 1rem;
379
- }
380
-
381
- .demo-box.active {
382
- border-color: #8b8bff;
383
- background: rgba(139, 139, 255, 0.1);
384
- box-shadow: 0 0 20px rgba(139, 139, 255, 0.3);
385
- }
386
-
387
- .demo-box.disabled {
388
- opacity: 0.5;
389
- cursor: not-allowed;
390
- }
391
-
392
- .demo-box.is-large {
393
- width: 300px;
394
- height: 150px;
395
- font-size: 1.2rem;
396
- }
397
-
398
- .controls {
399
- display: flex;
400
- gap: 0.5rem;
401
- flex-wrap: wrap;
402
- }
403
-
404
- .controls button {
405
- padding: 0.5rem 1rem;
406
- border: 1px solid #3a3a5a;
407
- background: #0f0f1a;
408
- color: #e8e8f0;
409
- border-radius: 6px;
410
- cursor: pointer;
411
- transition: all 0.15s;
412
- }
413
-
414
- .controls button:hover {
415
- background: #2a2a3a;
416
- }
417
-
418
- .controls button.btn-on {
419
- background: #8b8bff;
420
- border-color: #8b8bff;
421
- color: #fff;
422
- }
423
-
424
- .controls button.btn-off {
425
- background: #1a1a24;
426
- border-color: #555;
427
- color: #888;
428
- }
429
-
430
- .theme-box {
431
- padding: 1.5rem;
432
- border-radius: 8px;
433
- border: 2px solid #3a3a5a;
434
- transition: all 0.3s ease;
435
- margin-bottom: 1rem;
436
- }
437
-
438
- .theme-box.theme-light {
439
- background: rgba(245, 158, 11, 0.1);
440
- border-color: #f59e0b;
441
- color: #f59e0b;
442
- }
443
-
444
- .theme-box.theme-dark {
445
- background: rgba(139, 139, 255, 0.1);
446
- border-color: #8b8bff;
447
- color: #8b8bff;
448
- }
449
-
450
- .theme-toggle {
451
- padding: 0.6rem 1.25rem;
452
- background: #f59e0b;
453
- color: #000;
454
- border: none;
455
- border-radius: 6px;
456
- font-weight: 600;
457
- cursor: pointer;
458
- transition: background 0.15s;
459
- }
460
-
461
- .theme-toggle:hover {
462
- background: #d97706;
463
- }
464
-
465
- .action-btn {
466
- padding: 0.75rem 1.5rem;
467
- border: 2px solid #3a3a5a;
468
- background: #1a1a24;
469
- color: #e8e8f0;
470
- border-radius: 8px;
471
- font-weight: 600;
472
- cursor: pointer;
473
- transition: all 0.3s ease;
474
- margin-bottom: 1rem;
475
- }
476
-
477
- .action-btn.btn-primary {
478
- border-color: #8b8bff;
479
- color: #8b8bff;
480
- }
481
-
482
- .action-btn.btn-primary:hover {
483
- background: rgba(139, 139, 255, 0.1);
484
- }
485
-
486
- .action-btn.btn-loading {
487
- border-color: #f59e0b;
488
- color: #f59e0b;
489
- animation: pulse 1.5s infinite;
490
- }
491
-
492
- .action-btn.btn-error {
493
- border-color: #ff3333;
494
- background: rgba(255, 51, 51, 0.1);
495
- color: #ff3333;
496
- }
497
-
498
- .action-btn.btn-active {
499
- transform: scale(0.95);
500
- }
501
-
502
- @keyframes pulse {
503
- 0%, 100% { opacity: 1; }
504
- 50% { opacity: 0.5; }
505
- }
506
-
507
- .info-section {
508
- background: #0f0f1a;
509
- border: 1px solid #2a2a3a;
510
- border-radius: 12px;
511
- padding: 1.5rem;
512
- margin-top: 2rem;
513
- }
514
-
515
- .info-section h2 {
516
- color: #34d399;
517
- margin-bottom: 1rem;
518
- }
519
-
520
- .info-section ul {
521
- margin-left: 1.5rem;
522
- margin-bottom: 1.5rem;
523
- }
524
-
525
- .info-section li {
526
- color: #aaa;
527
- margin-bottom: 0.5rem;
528
- line-height: 1.5;
529
- }
530
-
531
- .info-section li strong {
532
- color: #e8e8f0;
533
- }
534
-
535
- .code-example {
536
- background: #1a1a24;
537
- border: 1px solid #2a2a3a;
538
- border-radius: 8px;
539
- padding: 1rem;
540
- }
541
-
542
- .code-example pre {
543
- color: #8b8bff;
544
- font-family: 'Courier New', monospace;
545
- font-size: 0.85rem;
546
- margin: 0;
547
- overflow-x: auto;
548
- }
549
- </style>
550
- </head>
551
-
552
- <body>
553
- <nav>
554
- <a href="#/">Home</a>
555
- <a href="#/about">About</a>
556
- <a href="#/test-for">Loops Test</a>
557
- <a href="#/dynamic" style="color: #ec4899;">Dynamic Components</a>
558
- <a href="#/composables" style="color: #34d399;">Composables</a>
559
- </nav>
560
- <div id="app"></div>
561
- <script type="module" src="./app/main.js"></script>
562
- </body>
563
-
1
+ <!DOCTYPE html>
2
+ <html lang="ro">
3
+
4
+ <head>
5
+ <meta charset="UTF-8" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>MyFramework — SPA Demo</title>
8
+ <style>
9
+ *,
10
+ *::before,
11
+ *::after {
12
+ box-sizing: border-box;
13
+ margin: 0;
14
+ padding: 0;
15
+ }
16
+
17
+ body {
18
+ font-family: system-ui, sans-serif;
19
+ background: #0f0f13;
20
+ color: #e8e8f0;
21
+ min-height: 100vh;
22
+ }
23
+
24
+ nav {
25
+ display: flex;
26
+ flex-wrap: wrap;
27
+ gap: 1rem;
28
+ padding: 1rem 2rem;
29
+ background: #1a1a24;
30
+ border-bottom: 1px solid #2a2a3a;
31
+ }
32
+
33
+ nav a {
34
+ color: #ff3333;
35
+ text-decoration: none;
36
+ font-weight: 500;
37
+ transition: color 0.15s;
38
+ }
39
+
40
+ nav a.active {
41
+ color: #fff;
42
+ text-shadow: 0 0 10px rgba(255, 255, 255, 0.5);
43
+ }
44
+
45
+ /* Temă Red Fusée */
46
+ #app h1 {
47
+ color: #ff3333;
48
+ text-shadow: 0 0 20px rgba(255, 51, 51, 0.4);
49
+ margin-bottom: 1rem;
50
+ }
51
+
52
+ #app p {
53
+ color: #ff9999;
54
+ opacity: 0.9;
55
+ }
56
+
57
+ nav a:hover {
58
+ color: #fff;
59
+ }
60
+
61
+ #app {
62
+ min-height: 100vh;
63
+ display: flex;
64
+ flex-direction: column;
65
+ }
66
+
67
+ .content-wrap {
68
+ padding: 2rem;
69
+ max-width: 800px;
70
+ margin: 0 auto;
71
+ width: 100%;
72
+ }
73
+ .page h1 {
74
+ margin-bottom: 1rem;
75
+ font-size: 1.8rem;
76
+ }
77
+
78
+ .page p {
79
+ margin-bottom: 0.5rem;
80
+ color: #aaa;
81
+ line-height: 1.6;
82
+ }
83
+
84
+ .counter {
85
+ margin-top: 2rem;
86
+ padding: 1.5rem;
87
+ background: #1a1a24;
88
+ border: 1px solid #2a2a3a;
89
+ border-radius: 10px;
90
+ display: inline-block;
91
+ }
92
+
93
+ .counter h2 {
94
+ margin-bottom: 1rem;
95
+ font-size: 1rem;
96
+ color: #888;
97
+ text-transform: uppercase;
98
+ letter-spacing: 0.1em;
99
+ }
100
+
101
+ .value {
102
+ font-size: 4rem !important;
103
+ font-weight: 700;
104
+ color: #8b8bff !important;
105
+ text-align: center;
106
+ line-height: 1;
107
+ margin-bottom: 0.25rem !important;
108
+ }
109
+
110
+ .derived {
111
+ text-align: center;
112
+ font-size: 0.85rem !important;
113
+ color: #555 !important;
114
+ margin-bottom: 1rem !important;
115
+ }
116
+
117
+ .actions {
118
+ display: flex;
119
+ gap: 0.5rem;
120
+ justify-content: center;
121
+ }
122
+
123
+ .actions button {
124
+ padding: 0.5rem 1.25rem;
125
+ border: 1px solid #3a3a5a;
126
+ background: #0f0f1a;
127
+ color: #e8e8f0;
128
+ border-radius: 6px;
129
+ cursor: pointer;
130
+ font-size: 1.1rem;
131
+ transition: background 0.15s;
132
+ }
133
+
134
+ .actions button:hover {
135
+ background: #2a2a3a;
136
+ }
137
+
138
+ .primary-btn {
139
+ padding: 0.6rem 1.25rem;
140
+ border: none;
141
+ background: #8b8bff;
142
+ color: #fff;
143
+ font-weight: 600;
144
+ border-radius: 6px;
145
+ cursor: pointer;
146
+ font-size: 1rem;
147
+ transition: background 0.15s, transform 0.1s;
148
+ }
149
+
150
+ .primary-btn:hover {
151
+ background: #7171e5;
152
+ }
153
+
154
+ .primary-btn:active {
155
+ transform: scale(0.97);
156
+ }
157
+
158
+ .status {
159
+ margin-top: 1rem;
160
+ font-size: 0.8rem;
161
+ color: #4caf50 !important;
162
+ }
163
+
164
+ .positive {
165
+ color: #8b8bff !important;
166
+ }
167
+
168
+ .negative {
169
+ color: #ff6b6b !important;
170
+ }
171
+
172
+ .actions button:disabled {
173
+ opacity: 0.3;
174
+ cursor: not-allowed;
175
+ }
176
+
177
+ /* ── Composables demo ──────────────────────────────────────────── */
178
+ .demo-card {
179
+ background: #13131d;
180
+ border: 1px solid #2a2a3a;
181
+ border-radius: 12px;
182
+ padding: 1.5rem;
183
+ margin-bottom: 1.5rem;
184
+ }
185
+
186
+ .demo-card h2 {
187
+ font-size: 1rem;
188
+ font-weight: 600;
189
+ color: #e8e8f0;
190
+ margin-bottom: 0.35rem;
191
+ }
192
+
193
+ .demo-desc {
194
+ font-size: 0.8rem;
195
+ color: #555 !important;
196
+ margin-bottom: 1rem !important;
197
+ }
198
+
199
+ .counter-display {
200
+ display: flex;
201
+ flex-direction: column;
202
+ align-items: center;
203
+ margin-bottom: 1rem;
204
+ }
205
+
206
+ .big-num {
207
+ font-size: 3.5rem;
208
+ font-weight: 700;
209
+ line-height: 1;
210
+ transition: color 0.2s;
211
+ }
212
+
213
+ .big-num.even {
214
+ color: #8b8bff;
215
+ }
216
+
217
+ .big-num.odd {
218
+ color: #ff3333;
219
+ }
220
+
221
+ .derived-label {
222
+ font-size: 0.8rem;
223
+ color: #555;
224
+ margin-top: 0.25rem;
225
+ }
226
+
227
+ .btn-row {
228
+ display: flex;
229
+ gap: 0.5rem;
230
+ justify-content: center;
231
+ margin-bottom: 0.75rem;
232
+ }
233
+
234
+ .cmp-btn {
235
+ padding: 0.45rem 1.1rem;
236
+ border-radius: 6px;
237
+ border: 1px solid #2a2a3a;
238
+ background: #0f0f1a;
239
+ color: #e8e8f0;
240
+ cursor: pointer;
241
+ font-size: 1rem;
242
+ transition: background 0.15s;
243
+ }
244
+
245
+ .cmp-btn:hover {
246
+ background: #1f1f30;
247
+ }
248
+
249
+ .cmp-btn.plus {
250
+ border-color: #8b8bff;
251
+ color: #8b8bff;
252
+ }
253
+
254
+ .cmp-btn.minus {
255
+ border-color: #ff3333;
256
+ color: #ff3333;
257
+ }
258
+
259
+ .cmp-btn.reset {
260
+ border-color: #555;
261
+ color: #888;
262
+ }
263
+
264
+ .badge {
265
+ display: inline-block;
266
+ padding: 0.2rem 0.65rem;
267
+ border-radius: 999px;
268
+ font-size: 0.75rem;
269
+ font-weight: 600;
270
+ }
271
+
272
+ .badge-blue {
273
+ background: rgba(139, 139, 255, 0.15);
274
+ color: #8b8bff;
275
+ }
276
+
277
+ .badge-red {
278
+ background: rgba(255, 51, 51, 0.12);
279
+ color: #ff3333;
280
+ }
281
+
282
+ .mouse-display {
283
+ display: flex;
284
+ gap: 2rem;
285
+ font-size: 1.1rem;
286
+ color: #aaa;
287
+ margin-bottom: 0.5rem;
288
+ }
289
+
290
+ .mouse-display strong {
291
+ color: #e8e8f0;
292
+ }
293
+
294
+ .cmp-input {
295
+ width: 100%;
296
+ padding: 0.5rem 0.75rem;
297
+ background: #0f0f1a;
298
+ border: 1px solid #2a2a3a;
299
+ border-radius: 6px;
300
+ color: #e8e8f0;
301
+ font-size: 0.95rem;
302
+ outline: none;
303
+ transition: border-color 0.15s;
304
+ }
305
+
306
+ .cmp-input:focus {
307
+ border-color: #8b8bff;
308
+ }
309
+
310
+ .demo-box {
311
+ width: 200px;
312
+ height: 100px;
313
+ background: #1a1a24;
314
+ border: 2px solid #3a3a5a;
315
+ border-radius: 8px;
316
+ display: flex;
317
+ align-items: center;
318
+ justify-content: center;
319
+ font-weight: 600;
320
+ transition: all 0.3s ease;
321
+ margin-top: 1rem;
322
+ }
323
+
324
+ .demo-box.active {
325
+ border-color: #8b8bff;
326
+ background: rgba(139, 139, 255, 0.1);
327
+ box-shadow: 0 0 20px rgba(139, 139, 255, 0.3);
328
+ }
329
+
330
+ .demo-box.disabled {
331
+ opacity: 0.5;
332
+ cursor: not-allowed;
333
+ }
334
+
335
+ .demo-box.is-large {
336
+ width: 300px;
337
+ height: 150px;
338
+ font-size: 1.2rem;
339
+ }
340
+
341
+ .btn-on {
342
+ background: #8b8bff !important;
343
+ border-color: #8b8bff !important;
344
+ color: #fff !important;
345
+ }
346
+
347
+ .btn-off {
348
+ background: #1a1a24 !important;
349
+ border-color: #555 !important;
350
+ color: #888 !important;
351
+ }
352
+
353
+ .test-classlist h1 {
354
+ color: #f59e0b;
355
+ text-shadow: 0 0 20px rgba(245, 158, 11, 0.3);
356
+ }
357
+
358
+ .test-classlist .subtitle {
359
+ color: #aaa;
360
+ font-size: 0.9rem;
361
+ margin-bottom: 2rem;
362
+ }
363
+
364
+ .demo-section {
365
+ background: #13131d;
366
+ border: 1px solid #2a2a3a;
367
+ border-radius: 12px;
368
+ padding: 1.5rem;
369
+ margin-bottom: 1.5rem;
370
+ }
371
+
372
+ .demo-section h2 {
373
+ font-size: 1rem;
374
+ font-weight: 600;
375
+ color: #e8e8f0;
376
+ margin-bottom: 1rem;
377
+ }
378
+
379
+ .demo-box {
380
+ width: 200px;
381
+ height: 100px;
382
+ background: #1a1a24;
383
+ border: 2px solid #3a3a5a;
384
+ border-radius: 8px;
385
+ display: flex;
386
+ align-items: center;
387
+ justify-content: center;
388
+ font-weight: 600;
389
+ transition: all 0.3s ease;
390
+ margin-bottom: 1rem;
391
+ }
392
+
393
+ .demo-box.active {
394
+ border-color: #8b8bff;
395
+ background: rgba(139, 139, 255, 0.1);
396
+ box-shadow: 0 0 20px rgba(139, 139, 255, 0.3);
397
+ }
398
+
399
+ .demo-box.disabled {
400
+ opacity: 0.5;
401
+ cursor: not-allowed;
402
+ }
403
+
404
+ .demo-box.is-large {
405
+ width: 300px;
406
+ height: 150px;
407
+ font-size: 1.2rem;
408
+ }
409
+
410
+ .controls {
411
+ display: flex;
412
+ gap: 0.5rem;
413
+ flex-wrap: wrap;
414
+ }
415
+
416
+ .controls button {
417
+ padding: 0.5rem 1rem;
418
+ border: 1px solid #3a3a5a;
419
+ background: #0f0f1a;
420
+ color: #e8e8f0;
421
+ border-radius: 6px;
422
+ cursor: pointer;
423
+ transition: all 0.15s;
424
+ }
425
+
426
+ .controls button:hover {
427
+ background: #2a2a3a;
428
+ }
429
+
430
+ .controls button.btn-on {
431
+ background: #8b8bff;
432
+ border-color: #8b8bff;
433
+ color: #fff;
434
+ }
435
+
436
+ .controls button.btn-off {
437
+ background: #1a1a24;
438
+ border-color: #555;
439
+ color: #888;
440
+ }
441
+
442
+ .theme-box {
443
+ padding: 1.5rem;
444
+ border-radius: 8px;
445
+ border: 2px solid #3a3a5a;
446
+ transition: all 0.3s ease;
447
+ margin-bottom: 1rem;
448
+ }
449
+
450
+ .theme-box.theme-light {
451
+ background: rgba(245, 158, 11, 0.1);
452
+ border-color: #f59e0b;
453
+ color: #f59e0b;
454
+ }
455
+
456
+ .theme-box.theme-dark {
457
+ background: rgba(139, 139, 255, 0.1);
458
+ border-color: #8b8bff;
459
+ color: #8b8bff;
460
+ }
461
+
462
+ .theme-toggle {
463
+ padding: 0.6rem 1.25rem;
464
+ background: #f59e0b;
465
+ color: #000;
466
+ border: none;
467
+ border-radius: 6px;
468
+ font-weight: 600;
469
+ cursor: pointer;
470
+ transition: background 0.15s;
471
+ }
472
+
473
+ .theme-toggle:hover {
474
+ background: #d97706;
475
+ }
476
+
477
+ .action-btn {
478
+ padding: 0.75rem 1.5rem;
479
+ border: 2px solid #3a3a5a;
480
+ background: #1a1a24;
481
+ color: #e8e8f0;
482
+ border-radius: 8px;
483
+ font-weight: 600;
484
+ cursor: pointer;
485
+ transition: all 0.3s ease;
486
+ margin-bottom: 1rem;
487
+ }
488
+
489
+ .action-btn.btn-primary {
490
+ border-color: #8b8bff;
491
+ color: #8b8bff;
492
+ }
493
+
494
+ .action-btn.btn-primary:hover {
495
+ background: rgba(139, 139, 255, 0.1);
496
+ }
497
+
498
+ .action-btn.btn-loading {
499
+ border-color: #f59e0b;
500
+ color: #f59e0b;
501
+ animation: pulse 1.5s infinite;
502
+ }
503
+
504
+ .action-btn.btn-error {
505
+ border-color: #ff3333;
506
+ background: rgba(255, 51, 51, 0.1);
507
+ color: #ff3333;
508
+ }
509
+
510
+ .action-btn.btn-active {
511
+ transform: scale(0.95);
512
+ }
513
+
514
+ @keyframes pulse {
515
+
516
+ 0%,
517
+ 100% {
518
+ opacity: 1;
519
+ }
520
+
521
+ 50% {
522
+ opacity: 0.5;
523
+ }
524
+ }
525
+
526
+ .info-section {
527
+ background: #0f0f1a;
528
+ border: 1px solid #2a2a3a;
529
+ border-radius: 12px;
530
+ padding: 1.5rem;
531
+ margin-top: 2rem;
532
+ }
533
+
534
+ .info-section h2 {
535
+ color: #34d399;
536
+ margin-bottom: 1rem;
537
+ }
538
+
539
+ .info-section ul {
540
+ margin-left: 1.5rem;
541
+ margin-bottom: 1.5rem;
542
+ }
543
+
544
+ .info-section li {
545
+ color: #aaa;
546
+ margin-bottom: 0.5rem;
547
+ line-height: 1.5;
548
+ }
549
+
550
+ .info-section li strong {
551
+ color: #e8e8f0;
552
+ }
553
+
554
+ .code-example {
555
+ background: #1a1a24;
556
+ border: 1px solid #2a2a3a;
557
+ border-radius: 8px;
558
+ padding: 1rem;
559
+ }
560
+
561
+ .code-example pre {
562
+ color: #8b8bff;
563
+ font-family: 'Courier New', monospace;
564
+ font-size: 0.85rem;
565
+ margin: 0;
566
+ overflow-x: auto;
567
+ }
568
+
569
+ .test-events h1 {
570
+ color: #ff3333;
571
+ text-shadow: 0 0 20px rgba(255, 51, 51, 0.4);
572
+ }
573
+
574
+ .test-events .subtitle {
575
+ color: #aaa;
576
+ font-size: 0.9rem;
577
+ margin-bottom: 2rem;
578
+ }
579
+
580
+ .button-grid {
581
+ display: grid;
582
+ grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
583
+ gap: 0.75rem;
584
+ margin-bottom: 1rem;
585
+ }
586
+
587
+ .demo-btn {
588
+ padding: 0.75rem 1rem;
589
+ border: 2px solid #3a3a5a;
590
+ background: #0f0f1a;
591
+ color: #e8e8f0;
592
+ border-radius: 8px;
593
+ cursor: pointer;
594
+ font-weight: 600;
595
+ transition: all 0.15s;
596
+ }
597
+
598
+ .demo-btn:hover {
599
+ background: #2a2a3a;
600
+ transform: translateY(-2px);
601
+ }
602
+
603
+ .demo-btn.native {
604
+ border-color: #34d399;
605
+ color: #34d399;
606
+ }
607
+
608
+ .demo-btn.native:hover {
609
+ background: rgba(52, 211, 153, 0.1);
610
+ }
611
+
612
+ .counter-display {
613
+ font-size: 1.1rem;
614
+ color: #aaa;
615
+ }
616
+
617
+ .counter-display strong {
618
+ color: #e8e8f0;
619
+ font-size: 1.3rem;
620
+ }
621
+
622
+ .stop-demo {
623
+ cursor: pointer;
624
+ transition: background 0.15s;
625
+ }
626
+
627
+ .stop-demo:hover {
628
+ background: #252535;
629
+ }
630
+ </style>
631
+ </head>
632
+
633
+ <body>
634
+
635
+ <div id="app"></div>
636
+ <script type="module" src="./app/main.js"></script>
637
+ </body>
638
+
564
639
  </html>