@myxo-victor/chexjs 6.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,609 @@
1
+ const { div, section, header, footer, nav, h1, h2, h3, p, span, a, ul, li, strong, pre, code, button, img } = Chex;
2
+
3
+ const injectWelcomeStyles = () => {
4
+ if (document.getElementById('chex-welcome-styles')) return;
5
+
6
+ const style = document.createElement('style');
7
+ style.id = 'chex-welcome-styles';
8
+ style.textContent = `
9
+ .chex-page {
10
+ position: relative;
11
+ min-height: 100vh;
12
+ }
13
+
14
+ /* -------------------- nav -------------------- */
15
+ .chex-nav {
16
+ position: sticky;
17
+ top: 0;
18
+ z-index: 50;
19
+ background: rgba(10, 10, 12, 0.82);
20
+ backdrop-filter: blur(10px);
21
+ border-bottom: 1px solid var(--chex-border);
22
+ }
23
+
24
+ .chex-nav-inner {
25
+ width: min(1180px, calc(100% - 40px));
26
+ margin: 0 auto;
27
+ height: 68px;
28
+ display: flex;
29
+ align-items: center;
30
+ justify-content: space-between;
31
+ gap: 20px;
32
+ }
33
+
34
+ .chex-brand {
35
+ display: inline-flex;
36
+ align-items: center;
37
+ gap: 10px;
38
+ text-decoration: none;
39
+ }
40
+
41
+ .chex-brand-mark {
42
+ display: grid;
43
+ grid-template-columns: repeat(2, 1fr);
44
+ grid-template-rows: repeat(2, 1fr);
45
+ width: 26px;
46
+ height: 26px;
47
+ border-radius: 7px;
48
+ overflow: hidden;
49
+ border: 1px solid var(--chex-border-strong);
50
+ }
51
+ .chex-brand-mark span { display: block; }
52
+ .chex-brand-mark span:nth-child(1) { background: var(--chex-accent); }
53
+ .chex-brand-mark span:nth-child(2) { background: var(--chex-surface-2); }
54
+ .chex-brand-mark span:nth-child(3) { background: var(--chex-surface-2); }
55
+ .chex-brand-mark span:nth-child(4) { background: var(--chex-accent); }
56
+
57
+ .chex-brand-name {
58
+ font-family: var(--chex-font-display);
59
+ font-weight: 700;
60
+ font-size: 1.05rem;
61
+ letter-spacing: -0.02em;
62
+ color: var(--chex-text);
63
+ }
64
+
65
+ .chex-nav-links {
66
+ display: flex;
67
+ align-items: center;
68
+ gap: 6px;
69
+ }
70
+
71
+ .chex-nav-link {
72
+ padding: 8px 14px;
73
+ border-radius: 999px;
74
+ color: var(--chex-text-dim);
75
+ font-size: 0.9rem;
76
+ text-decoration: none;
77
+ transition: color .15s ease, background .15s ease;
78
+ }
79
+ .chex-nav-link:hover { color: var(--chex-text); background: rgba(255,255,255,0.06); }
80
+
81
+ .chex-nav-cta {
82
+ display: inline-flex;
83
+ align-items: center;
84
+ gap: 6px;
85
+ padding: 8px 16px;
86
+ border-radius: 999px;
87
+ background: var(--chex-accent);
88
+ color: var(--chex-accent-ink);
89
+ font-weight: 700;
90
+ font-size: 0.88rem;
91
+ text-decoration: none;
92
+ margin-left: 6px;
93
+ transition: transform .15s ease, background .15s ease;
94
+ }
95
+ .chex-nav-cta:hover { background: var(--chex-accent-dim); transform: translateY(-1px); }
96
+
97
+ /* -------------------- hero -------------------- */
98
+ .chex-hero {
99
+ position: relative;
100
+ width: min(1180px, calc(100% - 40px));
101
+ margin: 0 auto;
102
+ padding: 96px 0 64px;
103
+ overflow: hidden;
104
+ }
105
+
106
+ .chex-hero::before {
107
+ content: '';
108
+ position: absolute;
109
+ top: -40px;
110
+ right: -80px;
111
+ width: 420px;
112
+ height: 420px;
113
+ background-image: repeating-conic-gradient(rgba(201,255,63,0.05) 0% 25%, transparent 0% 50%);
114
+ background-size: 34px 34px;
115
+ border-radius: 40px;
116
+ mask-image: radial-gradient(circle, black 40%, transparent 72%);
117
+ pointer-events: none;
118
+ z-index: 0;
119
+ }
120
+
121
+ .chex-hero-content {
122
+ position: relative;
123
+ z-index: 1;
124
+ max-width: 700px;
125
+ }
126
+
127
+ .chex-eyebrow-row {
128
+ display: inline-flex;
129
+ align-items: center;
130
+ gap: 9px;
131
+ padding: 7px 13px 7px 10px;
132
+ border-radius: 999px;
133
+ border: 1px solid var(--chex-border-strong);
134
+ background: var(--chex-surface);
135
+ margin-bottom: 26px;
136
+ }
137
+
138
+ .chex-pulse-dot {
139
+ width: 7px; height: 7px; border-radius: 50%;
140
+ background: var(--chex-accent);
141
+ box-shadow: 0 0 0 0 rgba(201,255,63,0.55);
142
+ animation: chex-pulse 1.8s infinite;
143
+ }
144
+ @keyframes chex-pulse {
145
+ 0% { box-shadow: 0 0 0 0 rgba(201,255,63,0.5); }
146
+ 70% { box-shadow: 0 0 0 7px rgba(201,255,63,0); }
147
+ 100% { box-shadow: 0 0 0 0 rgba(201,255,63,0); }
148
+ }
149
+
150
+ .chex-eyebrow-text {
151
+ font-family: var(--chex-font-mono);
152
+ font-size: 0.76rem;
153
+ letter-spacing: 0.06em;
154
+ color: var(--chex-text-dim);
155
+ }
156
+
157
+ .chex-hero h1 {
158
+ font-size: clamp(2.6rem, 5.2vw, 4.2rem);
159
+ line-height: 1.04;
160
+ letter-spacing: -0.03em;
161
+ margin-bottom: 22px;
162
+ }
163
+ .chex-hero h1 em {
164
+ font-style: normal;
165
+ color: var(--chex-accent);
166
+ }
167
+
168
+ .chex-hero-copy {
169
+ font-size: 1.08rem;
170
+ line-height: 1.7;
171
+ color: var(--chex-text-dim);
172
+ max-width: 560px;
173
+ margin-bottom: 34px;
174
+ }
175
+
176
+ .chex-hero-actions {
177
+ display: flex;
178
+ flex-wrap: wrap;
179
+ gap: 14px;
180
+ margin-bottom: 46px;
181
+ }
182
+
183
+ .chex-btn {
184
+ display: inline-flex;
185
+ align-items: center;
186
+ justify-content: center;
187
+ gap: 8px;
188
+ height: 48px;
189
+ padding: 0 22px;
190
+ border-radius: var(--chex-radius-sm);
191
+ font-weight: 600;
192
+ font-size: 0.95rem;
193
+ text-decoration: none;
194
+ border: 1px solid transparent;
195
+ cursor: pointer;
196
+ transition: transform .15s ease, background .15s ease, border-color .15s ease;
197
+ }
198
+ .chex-btn-primary {
199
+ background: var(--chex-accent);
200
+ color: var(--chex-accent-ink);
201
+ }
202
+ .chex-btn-primary:hover { background: var(--chex-accent-dim); transform: translateY(-2px); }
203
+ .chex-btn-secondary {
204
+ background: transparent;
205
+ color: var(--chex-text);
206
+ border-color: var(--chex-border-strong);
207
+ }
208
+ .chex-btn-secondary:hover { border-color: var(--chex-text-dim); transform: translateY(-2px); }
209
+
210
+ .chex-proof-row {
211
+ display: flex;
212
+ flex-wrap: wrap;
213
+ gap: 28px;
214
+ }
215
+ .chex-proof-item {
216
+ display: flex;
217
+ flex-direction: column;
218
+ gap: 2px;
219
+ }
220
+ .chex-proof-item strong {
221
+ font-family: var(--chex-font-display);
222
+ font-size: 1.3rem;
223
+ color: var(--chex-text);
224
+ }
225
+ .chex-proof-item span {
226
+ font-size: 0.8rem;
227
+ color: var(--chex-text-faint);
228
+ }
229
+
230
+ /* -------------------- demo -------------------- */
231
+ .chex-demo-wrap {
232
+ width: min(1180px, calc(100% - 40px));
233
+ margin: 0 auto 90px;
234
+ display: grid;
235
+ grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
236
+ gap: 18px;
237
+ }
238
+
239
+ .chex-panel {
240
+ background: var(--chex-surface);
241
+ border: 1px solid var(--chex-border);
242
+ border-radius: var(--chex-radius-md);
243
+ overflow: hidden;
244
+ }
245
+
246
+ .chex-panel-head {
247
+ display: flex;
248
+ align-items: center;
249
+ justify-content: space-between;
250
+ padding: 12px 16px;
251
+ border-bottom: 1px solid var(--chex-border);
252
+ font-family: var(--chex-font-mono);
253
+ font-size: 0.72rem;
254
+ letter-spacing: 0.06em;
255
+ text-transform: uppercase;
256
+ color: var(--chex-text-faint);
257
+ }
258
+
259
+ .chex-live-tag {
260
+ display: inline-flex;
261
+ align-items: center;
262
+ gap: 6px;
263
+ color: var(--chex-accent);
264
+ }
265
+
266
+ .chex-demo-stage {
267
+ min-height: 220px;
268
+ display: flex;
269
+ flex-direction: column;
270
+ align-items: center;
271
+ justify-content: center;
272
+ gap: 20px;
273
+ padding: 32px 20px;
274
+ }
275
+
276
+ .chex-count-display {
277
+ font-family: var(--chex-font-display);
278
+ font-size: 3.4rem;
279
+ font-weight: 700;
280
+ color: var(--chex-text);
281
+ letter-spacing: -0.02em;
282
+ }
283
+
284
+ .chex-count-controls {
285
+ display: flex;
286
+ gap: 10px;
287
+ }
288
+
289
+ .chex-count-btn {
290
+ width: 40px; height: 40px;
291
+ border-radius: var(--chex-radius-sm);
292
+ border: 1px solid var(--chex-border-strong);
293
+ background: var(--chex-surface-2);
294
+ color: var(--chex-text);
295
+ font-family: var(--chex-font-mono);
296
+ font-size: 1.1rem;
297
+ cursor: pointer;
298
+ transition: border-color .15s ease, transform .1s ease;
299
+ }
300
+ .chex-count-btn:hover { border-color: var(--chex-accent); }
301
+ .chex-count-btn:active { transform: scale(0.94); }
302
+ .chex-count-btn.reset {
303
+ width: auto; padding: 0 14px; font-family: var(--chex-font-body); font-size: 0.82rem; color: var(--chex-text-dim);
304
+ }
305
+
306
+ .chex-code-panel pre {
307
+ margin: 0;
308
+ padding: 18px 20px;
309
+ font-size: 0.83rem;
310
+ line-height: 1.75;
311
+ color: #d8dce1;
312
+ overflow-x: auto;
313
+ white-space: pre;
314
+ }
315
+ .chex-tok-kw { color: #ff8f7a; }
316
+ .chex-tok-fn { color: var(--chex-accent); }
317
+ .chex-tok-str { color: #9fd9ff; }
318
+ .chex-tok-com { color: var(--chex-text-faint); }
319
+
320
+ /* -------------------- features -------------------- */
321
+ .chex-section {
322
+ width: min(1180px, calc(100% - 40px));
323
+ margin: 0 auto 90px;
324
+ }
325
+
326
+ .chex-section-head {
327
+ display: flex;
328
+ align-items: flex-end;
329
+ justify-content: space-between;
330
+ gap: 20px;
331
+ margin-bottom: 30px;
332
+ flex-wrap: wrap;
333
+ }
334
+ .chex-section-head h2 {
335
+ font-size: clamp(1.7rem, 2.6vw, 2.2rem);
336
+ letter-spacing: -0.02em;
337
+ }
338
+ .chex-section-head p {
339
+ color: var(--chex-text-faint);
340
+ font-size: 0.92rem;
341
+ max-width: 360px;
342
+ }
343
+
344
+ .chex-feature-grid {
345
+ display: grid;
346
+ grid-template-columns: repeat(3, minmax(0, 1fr));
347
+ gap: 14px;
348
+ }
349
+
350
+ .chex-feature-card {
351
+ position: relative;
352
+ padding: 24px 22px;
353
+ border-radius: var(--chex-radius-md);
354
+ background: var(--chex-surface);
355
+ border: 1px solid var(--chex-border);
356
+ transition: border-color .15s ease, transform .15s ease;
357
+ }
358
+ .chex-feature-card:hover {
359
+ border-color: var(--chex-border-strong);
360
+ transform: translateY(-3px);
361
+ }
362
+
363
+ .chex-feature-icon {
364
+ display: grid;
365
+ grid-template-columns: repeat(2, 1fr);
366
+ grid-template-rows: repeat(2, 1fr);
367
+ width: 22px; height: 22px;
368
+ border-radius: 5px;
369
+ overflow: hidden;
370
+ margin-bottom: 16px;
371
+ }
372
+ .chex-feature-icon span { display:block; background: var(--chex-surface-2); }
373
+ .chex-feature-icon span.on { background: var(--chex-accent); }
374
+
375
+ .chex-feature-card h3 {
376
+ font-size: 1rem;
377
+ margin-bottom: 8px;
378
+ font-family: var(--chex-font-body);
379
+ font-weight: 600;
380
+ }
381
+ .chex-feature-card p {
382
+ color: var(--chex-text-dim);
383
+ font-size: 0.88rem;
384
+ line-height: 1.65;
385
+ }
386
+
387
+ /* -------------------- quickstart -------------------- */
388
+ .chex-quickstart-panel {
389
+ background: var(--chex-surface);
390
+ border: 1px solid var(--chex-border);
391
+ border-radius: var(--chex-radius-md);
392
+ padding: 8px;
393
+ }
394
+
395
+ .chex-quickstart-panel pre {
396
+ margin: 0;
397
+ padding: 22px 24px;
398
+ font-size: 0.86rem;
399
+ line-height: 1.8;
400
+ color: #d8dce1;
401
+ overflow-x: auto;
402
+ }
403
+
404
+ /* -------------------- footer -------------------- */
405
+ .chex-footer {
406
+ border-top: 1px solid var(--chex-border);
407
+ padding: 30px 0 60px;
408
+ }
409
+ .chex-footer-inner {
410
+ width: min(1180px, calc(100% - 40px));
411
+ margin: 0 auto;
412
+ display: flex;
413
+ flex-wrap: wrap;
414
+ gap: 14px;
415
+ align-items: center;
416
+ justify-content: space-between;
417
+ }
418
+ .chex-footer-credit {
419
+ font-size: 0.85rem;
420
+ color: var(--chex-text-faint);
421
+ }
422
+ .chex-footer-links {
423
+ display: flex;
424
+ gap: 20px;
425
+ }
426
+ .chex-footer-links a {
427
+ font-size: 0.85rem;
428
+ color: var(--chex-text-dim);
429
+ text-decoration: none;
430
+ }
431
+ .chex-footer-links a:hover { color: var(--chex-accent); }
432
+
433
+ @media (max-width: 900px) {
434
+ .chex-demo-wrap { grid-template-columns: 1fr; }
435
+ .chex-feature-grid { grid-template-columns: repeat(2, minmax(0,1fr)); }
436
+ }
437
+
438
+ @media (max-width: 640px) {
439
+ .chex-nav-links a.chex-nav-link { display: none; }
440
+ .chex-feature-grid { grid-template-columns: 1fr; }
441
+ .chex-hero { padding: 64px 0 48px; }
442
+ .chex-proof-row { gap: 20px; }
443
+ }
444
+ `;
445
+ document.head.appendChild(style);
446
+ };
447
+
448
+ const checkerMark = () =>
449
+ img({class:'logo', src:'./images/logo.png', alt:'Chex Logo'});
450
+
451
+ const featureItems = [
452
+ {
453
+ title: 'Signal-based reactivity',
454
+ description: 'Change a value, and every part of the UI that depends on it updates — no virtual DOM diffing to reason about.'
455
+ },
456
+ {
457
+ title: 'Zero build, zero bundler',
458
+ description: 'Drop in a script tag and start writing components. No compiler step between you and the browser.'
459
+ },
460
+ {
461
+ title: 'Composable by default',
462
+ description: 'Every element is a function. Build UI the same way you build any other piece of JavaScript.'
463
+ },
464
+ {
465
+ title: 'Router included',
466
+ description: 'Client-side routing ships in the core — no separate package to install and wire up.'
467
+ },
468
+ {
469
+ title: 'Backend-ready',
470
+ description: 'Chex.db connects straight to a PHP backend, so data fetching needs no extra glue code.'
471
+ },
472
+ {
473
+ title: 'No dependencies',
474
+ description: 'The entire engine is self-contained. Nothing to audit in your lockfile, nothing to update.'
475
+ }
476
+ ];
477
+
478
+ const demoCount = Chex.signal(0);
479
+
480
+ const DemoCounter = () => {
481
+ return div({ class: 'chex-demo-stage' }, [
482
+ span({ class: 'chex-count-display' }, `${demoCount.value}`),
483
+ div({ class: 'chex-count-controls' }, [
484
+ button({ class: 'chex-count-btn', onClick: () => demoCount.value -= 1 }, '−'),
485
+ button({ class: 'chex-count-btn', onClick: () => demoCount.value += 1 }, '+'),
486
+ button({ class: 'chex-count-btn reset', onClick: () => demoCount.value = 0 }, 'Reset')
487
+ ])
488
+ ]);
489
+ };
490
+
491
+ const WelcomePage = () => {
492
+ injectWelcomeStyles();
493
+
494
+ return div({ class: 'chex-page' }, [
495
+
496
+ header({ class: 'chex-nav' }, [
497
+ div({ class: 'chex-nav-inner' }, [
498
+ a({ class: 'chex-brand', href: '#' }, [
499
+ checkerMark(),
500
+ span({ class: 'chex-brand-name' }, 'Chex')
501
+ ]),
502
+ nav({ class: 'chex-nav-links' }, [
503
+ a({ class: 'chex-nav-link', href: 'docs/index.html' }, 'Docs'),
504
+ a({ class: 'chex-nav-link', href: 'README.md' }, 'Quick start'),
505
+ a({ class: 'chex-nav-link', href: 'api/read.txt' }, 'API'),
506
+ a({ class: 'chex-nav-cta', href: 'README.md' }, 'Get started →')
507
+ ])
508
+ ])
509
+ ]),
510
+
511
+ section({ class: 'chex-hero' }, [
512
+ div({ class: 'chex-hero-content' }, [
513
+ div({ class: 'chex-eyebrow-row' }, [
514
+ span({ class: 'chex-pulse-dot' }),
515
+ span({ class: 'chex-eyebrow-text' }, 'BROWSER-NATIVE · ZERO BUILD')
516
+ ]),
517
+ h1('UI that reacts — no compiler required.'),
518
+ p({ class: 'chex-hero-copy' }, 'Chex is a lightweight, signal-based UI engine you write directly in the browser. No bundler, no JSX transform, no framework lock-in — just functions that return elements.'),
519
+ div({ class: 'chex-hero-actions' }, [
520
+ a({ class: 'chex-btn chex-btn-primary', href: 'README.md' }, 'Get started'),
521
+ a({ class: 'chex-btn chex-btn-secondary', href: 'docs/index.html' }, 'Browse docs')
522
+ ]),
523
+ div({ class: 'chex-proof-row' }, [
524
+ div({ class: 'chex-proof-item' }, [ strong('0'), span('build steps') ]),
525
+ div({ class: 'chex-proof-item' }, [ strong('0'), span('dependencies') ]),
526
+ div({ class: 'chex-proof-item' }, [ strong('1 tag') , span('to get started') ])
527
+ ])
528
+ ])
529
+ ]),
530
+
531
+ div({ class: 'chex-demo-wrap' }, [
532
+ div({ class: 'chex-panel' }, [
533
+ div({ class: 'chex-panel-head' }, [
534
+ span({ class: 'chex-live-tag' }, [ span({ class: 'chex-pulse-dot' }), 'Live signal' ]),
535
+ span('demo.js')
536
+ ]),
537
+ DemoCounter()
538
+ ]),
539
+ div({ class: 'chex-panel chex-code-panel' }, [
540
+ div({ class: 'chex-panel-head' }, [ span('source'), span('4 lines') ]),
541
+ pre({ innerHTML:
542
+ `<span class="chex-tok-kw">const</span> count = Chex.<span class="chex-tok-fn">signal</span>(0);
543
+
544
+ <span class="chex-tok-kw">const</span> Counter = () => div([
545
+ span(<span class="chex-tok-str">\`\${count.value}\`</span>),
546
+ button({ onClick: () => count.value += 1 }, <span class="chex-tok-str">'+'</span>)
547
+ ]);
548
+
549
+ <span class="chex-tok-com">// updates automatically — no re-render call</span>` })
550
+ ])
551
+ ]),
552
+
553
+ section({ class: 'chex-section' }, [
554
+ div({ class: 'chex-section-head' }, [
555
+ h2('Everything you need, nothing you don\u2019t'),
556
+ p('A small core with the parts most projects actually reach for.')
557
+ ]),
558
+ div({ class: 'chex-feature-grid' },
559
+ featureItems.map((item, i) =>
560
+ div({ class: 'chex-feature-card' }, [
561
+ div({ class: 'chex-feature-icon' }, [
562
+ span({ class: i % 2 === 0 ? 'on' : '' }),
563
+ span({ class: i % 2 === 0 ? '' : 'on' }),
564
+ span({ class: i % 2 === 0 ? '' : 'on' }),
565
+ span({ class: i % 2 === 0 ? 'on' : '' })
566
+ ]),
567
+ h3(item.title),
568
+ p(item.description)
569
+ ])
570
+ )
571
+ )
572
+ ]),
573
+
574
+ section({ class: 'chex-section' }, [
575
+ div({ class: 'chex-section-head' }, [
576
+ h2('Up and running in under a minute'),
577
+ p('Paste this, open the file in a browser. That\u2019s the whole setup.')
578
+ ]),
579
+ div({ class: 'chex-quickstart-panel' }, [
580
+ pre({ innerHTML:
581
+ `<span class="chex-tok-kw">&lt;script</span> src=<span class="chex-tok-str">"chex.js"</span><span class="chex-tok-kw">&gt;&lt;/script&gt;</span>
582
+ <span class="chex-tok-kw">&lt;script&gt;</span>
583
+ <span class="chex-tok-kw">const</span> { div, h1, button } = Chex;
584
+ <span class="chex-tok-kw">const</span> count = Chex.<span class="chex-tok-fn">signal</span>(0);
585
+
586
+ <span class="chex-tok-kw">const</span> App = () => div([
587
+ h1(<span class="chex-tok-str">\`Count: \${count.value}\`</span>),
588
+ button({ onClick: () => count.value += 1 }, <span class="chex-tok-str">'Increment'</span>)
589
+ ]);
590
+
591
+ Chex.<span class="chex-tok-fn">render</span>(document.getElementById(<span class="chex-tok-str">'app'</span>), App);
592
+ <span class="chex-tok-kw">&lt;/script&gt;</span>` })
593
+ ])
594
+ ]),
595
+
596
+ footer({ class: 'chex-footer' }, [
597
+ div({ class: 'chex-footer-inner' }, [
598
+ span({ class: 'chex-footer-credit' }, '© Chex — a browser-native UI engine.'),
599
+ div({ class: 'chex-footer-links' }, [
600
+ a({ href: 'docs/index.html' }, 'Docs'),
601
+ a({ href: 'README.md' }, 'Quick start'),
602
+ a({ href: 'api/read.txt' }, 'API')
603
+ ])
604
+ ])
605
+ ])
606
+ ]);
607
+ };
608
+
609
+ Chex.render(document.getElementById('app'), WelcomePage);
Binary file