@ibgib/space-gib 0.0.1

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 (84) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/Dockerfile +14 -0
  3. package/IMPLEMENTATION.md +484 -0
  4. package/README.md +46 -0
  5. package/dist/client/bootstrap.mjs +58 -0
  6. package/dist/client/bootstrap.mjs.map +7 -0
  7. package/dist/client/chunk-CT47Z5WU.mjs +21 -0
  8. package/dist/client/chunk-CT47Z5WU.mjs.map +7 -0
  9. package/dist/client/chunk-RHEDTRKF.mjs +235 -0
  10. package/dist/client/chunk-RHEDTRKF.mjs.map +7 -0
  11. package/dist/client/index.html +147 -0
  12. package/dist/client/index.mjs +2 -0
  13. package/dist/client/index.mjs.map +7 -0
  14. package/dist/client/script.mjs +2 -0
  15. package/dist/client/script.mjs.map +7 -0
  16. package/dist/client/style.css +605 -0
  17. package/dist/respec-gib.node.mjs +5 -0
  18. package/dist/server/server.mjs +20157 -0
  19. package/dist/server/server.mjs.map +7 -0
  20. package/generate-version-file.js +35 -0
  21. package/package.json +27 -0
  22. package/src/client/AUTO-GENERATED-version.mts +11 -0
  23. package/src/client/README.md +19 -0
  24. package/src/client/api/function-infos.web.mts +38 -0
  25. package/src/client/api/space-gib-api-bridge.mts +85 -0
  26. package/src/client/bootstrap.mts +49 -0
  27. package/src/client/components/keystone-creator/keystone-creator.css +139 -0
  28. package/src/client/components/keystone-creator/keystone-creator.html +26 -0
  29. package/src/client/components/keystone-creator/keystone-creator.mts +229 -0
  30. package/src/client/constants.mts +76 -0
  31. package/src/client/custom.d.ts +11 -0
  32. package/src/client/dev-tools.mts +540 -0
  33. package/src/client/helpers.web.mts +178 -0
  34. package/src/client/index.html +147 -0
  35. package/src/client/index.mts +59 -0
  36. package/src/client/script.mts +13 -0
  37. package/src/client/style.css +605 -0
  38. package/src/client/types.mts +85 -0
  39. package/src/client/ui/shell/space-gib-shell-constants.mts +24 -0
  40. package/src/client/ui/shell/space-gib-shell-service.mts +233 -0
  41. package/src/client/ui/shell/space-gib-shell-types.mts +5 -0
  42. package/src/client/witness/app/space-gib/space-gib-app-v1.mts +160 -0
  43. package/src/client/witness/app/space-gib/space-gib-constants.mts +38 -0
  44. package/src/client/witness/app/space-gib/space-gib-helper.mts +72 -0
  45. package/src/client/witness/app/space-gib/space-gib-types.mts +47 -0
  46. package/src/common/keystone-policies.mts +159 -0
  47. package/src/respec-gib.node.mts +6 -0
  48. package/src/server/README.md +18 -0
  49. package/src/server/bootstrap-helper.mts +141 -0
  50. package/src/server/bootstrap-helper.respec.mts +100 -0
  51. package/src/server/metaspace-nodeindexedspace/metaspace-nodeindexedspace.mts +85 -0
  52. package/src/server/path-constants.mts +89 -0
  53. package/src/server/path-helper.mts +101 -0
  54. package/src/server/path-helper.respec.mts +94 -0
  55. package/src/server/serve-gib/CHANGELOG.md +29 -0
  56. package/src/server/serve-gib/README.md +34 -0
  57. package/src/server/serve-gib/constants.mts +1 -0
  58. package/src/server/serve-gib/handlers/api/debug/ws-echo.handler.mts +104 -0
  59. package/src/server/serve-gib/handlers/api/health.handler.mts +23 -0
  60. package/src/server/serve-gib/handlers/api/health.respec.mts +51 -0
  61. package/src/server/serve-gib/handlers/api/ibgib/ibgib-handler-types.mts +49 -0
  62. package/src/server/serve-gib/handlers/api/ibgib/ibgib.handler.mts +176 -0
  63. package/src/server/serve-gib/handlers/api/keystone/keystone-evolve.handler.mts +261 -0
  64. package/src/server/serve-gib/handlers/api/keystone/keystone-genesis.handler.mts +146 -0
  65. package/src/server/serve-gib/handlers/api/keystone/keystone-get.handler.mts +198 -0
  66. package/src/server/serve-gib/handlers/api/keystone/keystone-get.respec.mts +107 -0
  67. package/src/server/serve-gib/handlers/api/keystone/keystone-handler-types.mts +29 -0
  68. package/src/server/serve-gib/handlers/api/keystone/keystone-post.handler.mts +70 -0
  69. package/src/server/serve-gib/handlers/api/keystone/keystone-post.respec.mts +130 -0
  70. package/src/server/serve-gib/handlers/error-handler.mts +36 -0
  71. package/src/server/serve-gib/handlers/handler-base.mts +383 -0
  72. package/src/server/serve-gib/handlers/static-handler.mts +82 -0
  73. package/src/server/serve-gib/handlers/ws/sync-upgrade.handler.mts +498 -0
  74. package/src/server/serve-gib/handlers/ws/ws-helper.mts +111 -0
  75. package/src/server/serve-gib/handlers/ws/ws-types.mts +53 -0
  76. package/src/server/serve-gib/serve-gib-helpers.mts +32 -0
  77. package/src/server/serve-gib/serve-gib-v1.mts +172 -0
  78. package/src/server/serve-gib/serve-gib.respec.mts +90 -0
  79. package/src/server/serve-gib/types.mts +102 -0
  80. package/src/server/server-constants.mts +2 -0
  81. package/src/server/server.mts +96 -0
  82. package/tsconfig.json +29 -0
  83. package/tsconfig.server.json +29 -0
  84. package/tsconfig.test.json +27 -0
@@ -0,0 +1,605 @@
1
+ /* =========================================================================
2
+ space-gib — style.css
3
+ Dark-first, glassmorphism, premium design.
4
+ ========================================================================= */
5
+
6
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap');
7
+
8
+ /* ── Custom properties ── */
9
+ :root {
10
+ /* Palette */
11
+ --clr-bg-deep: #05080f;
12
+ --clr-bg-surface: #0b1120;
13
+ --clr-bg-glass: rgba(11, 17, 32, 0.7);
14
+ --clr-border: rgba(120, 248, 126, 0.12);
15
+ --clr-border-hover: rgba(120, 248, 126, 0.32);
16
+
17
+ --clr-accent: #78f87e;
18
+ --clr-accent-dim: rgba(120, 248, 126, 0.35);
19
+ --clr-accent-glow: rgba(120, 248, 126, 0.15);
20
+
21
+ --clr-text-primary: #e8f0e8;
22
+ --clr-text-secondary: #8fa08f;
23
+ --clr-text-muted: #4a604a;
24
+
25
+ --clr-danger: #ff5b5b;
26
+ --clr-warn: #ffcc44;
27
+ --clr-info: #44aaff;
28
+
29
+ /* Typography */
30
+ --font-sans: 'Inter', system-ui, -apple-system, sans-serif;
31
+ --font-mono: 'JetBrains Mono', 'Fira Code', monospace;
32
+
33
+ /* Spacing / Layout */
34
+ --header-h: 60px;
35
+ --footer-h: 48px;
36
+ --radius-sm: 6px;
37
+ --radius-md: 12px;
38
+ --radius-lg: 20px;
39
+
40
+ /* Shadows */
41
+ --shadow-card: 0 4px 24px rgba(0,0,0,0.5), 0 0 0 1px var(--clr-border);
42
+ --shadow-glow: 0 0 32px var(--clr-accent-glow);
43
+ --shadow-dialog: 0 8px 48px rgba(0,0,0,0.8), 0 0 0 1px var(--clr-border);
44
+
45
+ /* Panel Dimensions */
46
+ --left-panel-width: 250px;
47
+ --right-panel-width: 250px;
48
+ --footer-panel-height: 48px;
49
+
50
+ /* Transition */
51
+ --t-fast: 120ms ease;
52
+ --t-med: 240ms ease;
53
+ --t-slow: 400ms cubic-bezier(0.4, 0, 0.2, 1);
54
+ }
55
+
56
+ /* ── Reset ── */
57
+ *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
58
+ html { font-size: 16px; -webkit-text-size-adjust: 100%; }
59
+ body {
60
+ font-family: var(--font-sans);
61
+ background: var(--clr-bg-deep);
62
+ color: var(--clr-text-primary);
63
+ min-height: 100dvh;
64
+ overflow-x: hidden;
65
+ line-height: 1.6;
66
+ }
67
+
68
+ /* Subtle animated background gradient */
69
+ body::before {
70
+ content: '';
71
+ position: fixed;
72
+ inset: 0;
73
+ background:
74
+ radial-gradient(ellipse 80% 60% at 10% 5%, rgba(120,248,126,0.06) 0%, transparent 60%),
75
+ radial-gradient(ellipse 60% 50% at 90% 95%, rgba(68,170,255,0.05) 0%, transparent 55%);
76
+ pointer-events: none;
77
+ z-index: 0;
78
+ }
79
+
80
+ /* ── Fullscreen dialog (required by @ibgib/web-gib) ── */
81
+ .fullscreen-dialog {
82
+ border: 1px solid var(--clr-border);
83
+ border-radius: var(--radius-lg);
84
+ background: var(--clr-bg-surface);
85
+ color: var(--clr-text-primary);
86
+ box-shadow: var(--shadow-dialog);
87
+ max-width: min(520px, 92vw);
88
+ width: 100%;
89
+ padding: 0;
90
+ outline: none;
91
+ }
92
+ .fullscreen-dialog::backdrop {
93
+ background: rgba(0, 0, 0, 0.72);
94
+ backdrop-filter: blur(4px);
95
+ }
96
+ .fullscreen-dialog-content {
97
+ display: flex;
98
+ flex-direction: column;
99
+ }
100
+ .fullscreen-dialog-header {
101
+ padding: 1.5rem 1.5rem 0.5rem;
102
+ border-bottom: 1px solid var(--clr-border);
103
+ }
104
+ .fullscreen-dialog-header h2 {
105
+ font-size: 1.1rem;
106
+ font-weight: 600;
107
+ color: var(--clr-accent);
108
+ }
109
+ .fullscreen-dialog-body {
110
+ padding: 1rem 1.5rem;
111
+ display: flex;
112
+ flex-direction: column;
113
+ gap: 0.75rem;
114
+ }
115
+ .fullscreen-dialog-message {
116
+ font-size: 0.9375rem;
117
+ color: var(--clr-text-primary);
118
+ white-space: pre-wrap;
119
+ }
120
+ #fullscreen-dialog-prompt-input {
121
+ background: rgba(255,255,255,0.04);
122
+ border: 1px solid var(--clr-border);
123
+ border-radius: var(--radius-sm);
124
+ padding: 0.6rem 0.75rem;
125
+ color: var(--clr-text-primary);
126
+ font-family: var(--font-sans);
127
+ font-size: 0.9375rem;
128
+ outline: none;
129
+ transition: border-color var(--t-fast), box-shadow var(--t-fast);
130
+ }
131
+ #fullscreen-dialog-prompt-input:focus {
132
+ border-color: var(--clr-accent);
133
+ box-shadow: 0 0 0 3px var(--clr-accent-glow);
134
+ }
135
+ #fullscreen-dialog-prompt-input.collapsed { display: none; }
136
+ .fullscreen-dialog-footer {
137
+ display: flex;
138
+ justify-content: flex-end;
139
+ gap: 0.5rem;
140
+ padding: 0.75rem 1.5rem 1.25rem;
141
+ }
142
+ .dialog-button {
143
+ padding: 0.5rem 1.25rem;
144
+ border-radius: var(--radius-sm);
145
+ border: 1px solid var(--clr-border);
146
+ background: transparent;
147
+ color: var(--clr-text-primary);
148
+ font-family: var(--font-sans);
149
+ font-size: 0.875rem;
150
+ cursor: pointer;
151
+ transition: background var(--t-fast), border-color var(--t-fast), color var(--t-fast);
152
+ }
153
+ .dialog-button:first-child {
154
+ background: var(--clr-accent);
155
+ border-color: var(--clr-accent);
156
+ color: var(--clr-bg-deep);
157
+ font-weight: 600;
158
+ }
159
+ .dialog-button:first-child:hover {
160
+ background: #9fffa5;
161
+ }
162
+ .dialog-button:last-child:hover {
163
+ border-color: var(--clr-border-hover);
164
+ background: rgba(255,255,255,0.04);
165
+ }
166
+
167
+ /* ── App root layout ── */
168
+ .app-root {
169
+ position: relative;
170
+ z-index: 1;
171
+ display: flex;
172
+ flex-direction: column;
173
+ height: 100dvh;
174
+ overflow: hidden;
175
+ }
176
+
177
+ .middle-row {
178
+ display: flex;
179
+ flex: 1;
180
+ overflow: hidden;
181
+ position: relative;
182
+ }
183
+
184
+ /* ── Header ── */
185
+ .header-panel {
186
+ position: sticky;
187
+ top: 0;
188
+ z-index: 100;
189
+ height: var(--header-h);
190
+ background: var(--clr-bg-glass);
191
+ border-bottom: 1px solid var(--clr-border);
192
+ backdrop-filter: blur(16px);
193
+ -webkit-backdrop-filter: blur(16px);
194
+ }
195
+ .header-content {
196
+ max-width: 1100px;
197
+ margin: 0 auto;
198
+ height: 100%;
199
+ display: flex;
200
+ align-items: center;
201
+ padding: 0 1.5rem;
202
+ gap: 1rem;
203
+ }
204
+ .brand-link {
205
+ text-decoration: none;
206
+ display: flex;
207
+ align-items: center;
208
+ gap: 0.4rem;
209
+ font-size: 1.2rem;
210
+ font-weight: 700;
211
+ color: var(--clr-text-primary);
212
+ letter-spacing: -0.02em;
213
+ transition: color var(--t-fast);
214
+ margin-right: auto;
215
+ }
216
+ .brand-link:hover { color: var(--clr-accent); }
217
+ .brand-icon {
218
+ color: var(--clr-accent);
219
+ font-size: 1.4rem;
220
+ animation: spin-slow 12s linear infinite;
221
+ }
222
+ .brand-accent { color: var(--clr-accent); }
223
+ @keyframes spin-slow {
224
+ from { transform: rotate(0deg); }
225
+ to { transform: rotate(360deg); }
226
+ }
227
+ .header-nav {
228
+ display: flex;
229
+ gap: 0.25rem;
230
+ }
231
+ .nav-link {
232
+ text-decoration: none;
233
+ color: var(--clr-text-secondary);
234
+ font-size: 0.875rem;
235
+ font-weight: 500;
236
+ padding: 0.35rem 0.75rem;
237
+ border-radius: var(--radius-sm);
238
+ transition: color var(--t-fast), background var(--t-fast);
239
+ }
240
+ .nav-link:hover {
241
+ color: var(--clr-text-primary);
242
+ background: rgba(255,255,255,0.04);
243
+ }
244
+ .config-btn {
245
+ background: none;
246
+ border: 1px solid var(--clr-border);
247
+ border-radius: var(--radius-sm);
248
+ padding: 0.3rem 0.6rem;
249
+ color: var(--clr-text-secondary);
250
+ cursor: pointer;
251
+ font-size: 1rem;
252
+ transition: border-color var(--t-fast), color var(--t-fast);
253
+ }
254
+ .config-btn:hover {
255
+ border-color: var(--clr-border-hover);
256
+ color: var(--clr-text-primary);
257
+ }
258
+ .config-popover {
259
+ position: absolute;
260
+ top: var(--header-h);
261
+ right: 1rem;
262
+ background: var(--clr-bg-surface);
263
+ border: 1px solid var(--clr-border);
264
+ border-radius: var(--radius-md);
265
+ box-shadow: var(--shadow-card);
266
+ padding: 0.5rem;
267
+ min-width: 200px;
268
+ margin: 0;
269
+ }
270
+ .config-popover-option {
271
+ display: block;
272
+ width: 100%;
273
+ text-align: left;
274
+ padding: 0.6rem 0.9rem;
275
+ border: none;
276
+ border-radius: var(--radius-sm);
277
+ background: transparent;
278
+ color: var(--clr-text-primary);
279
+ font-family: var(--font-sans);
280
+ font-size: 0.875rem;
281
+ cursor: pointer;
282
+ transition: background var(--t-fast);
283
+ }
284
+ .config-popover-option:hover { background: rgba(120,248,126,0.08); }
285
+
286
+ /* ── Header Toggle Buttons ── */
287
+ .panel-toggle-btn {
288
+ background: none;
289
+ border: none;
290
+ color: var(--clr-text-secondary);
291
+ font-size: 1.4rem;
292
+ cursor: pointer;
293
+ padding: 0.2rem 0.5rem;
294
+ transition: color var(--t-fast);
295
+ }
296
+ .panel-toggle-btn:hover { color: var(--clr-accent); }
297
+
298
+ /* ── Center panel / main ── */
299
+ .center-panel {
300
+ flex: 1;
301
+ display: flex;
302
+ flex-direction: column;
303
+ overflow: hidden;
304
+ }
305
+ .center-panel-content {
306
+ flex: 1;
307
+ overflow-y: auto;
308
+ }
309
+
310
+ /* ── Side Panels ── */
311
+ .side-panel {
312
+ background: var(--clr-bg-glass);
313
+ overflow: hidden;
314
+ transition: width var(--t-fast);
315
+ z-index: 5;
316
+ }
317
+ .left-panel {
318
+ width: var(--left-panel-width);
319
+ border-right: 1px solid var(--clr-border);
320
+ }
321
+ .left-panel.collapsed { width: 0 !important; border: none; }
322
+
323
+ .right-panel {
324
+ width: var(--right-panel-width);
325
+ border-left: 1px solid var(--clr-border);
326
+ }
327
+ .right-panel.collapsed { width: 0 !important; border: none; }
328
+
329
+ .panel-content-inner {
330
+ padding: 1rem;
331
+ width: 100%;
332
+ min-width: 150px;
333
+ height: 100%;
334
+ overflow-y: auto;
335
+ }
336
+ .placeholder-text {
337
+ color: var(--clr-text-muted);
338
+ font-size: 0.9rem;
339
+ font-style: italic;
340
+ }
341
+
342
+ /* ── Resizers ── */
343
+ .resizer {
344
+ background: transparent;
345
+ transition: background var(--t-fast);
346
+ z-index: 10;
347
+ }
348
+ .resizer:hover, .resizer:active {
349
+ background: var(--clr-accent-dim);
350
+ }
351
+ .resizer-v {
352
+ width: 6px;
353
+ cursor: col-resize;
354
+ margin-left: -3px;
355
+ margin-right: -3px;
356
+ }
357
+ .resizer-h {
358
+ height: 6px;
359
+ cursor: row-resize;
360
+ margin-top: -3px;
361
+ margin-bottom: -3px;
362
+ }
363
+
364
+ /* ── Hero section ── */
365
+ .hero-section {
366
+ max-width: 720px;
367
+ margin: 0 auto;
368
+ padding: 6rem 1.5rem 4rem;
369
+ text-align: center;
370
+ display: flex;
371
+ flex-direction: column;
372
+ align-items: center;
373
+ gap: 1.25rem;
374
+ }
375
+ .hero-glyph {
376
+ font-size: 4rem;
377
+ color: var(--clr-accent);
378
+ animation: pulse-glyph 3s ease-in-out infinite;
379
+ }
380
+ @keyframes pulse-glyph {
381
+ 0%, 100% { text-shadow: 0 0 0 transparent; opacity: 1; }
382
+ 50% { text-shadow: 0 0 30px var(--clr-accent-glow); opacity: 0.85; }
383
+ }
384
+ .hero-title {
385
+ font-size: clamp(2.5rem, 6vw, 4rem);
386
+ font-weight: 700;
387
+ letter-spacing: -0.03em;
388
+ background: linear-gradient(135deg, var(--clr-accent) 0%, #44aaff 100%);
389
+ -webkit-background-clip: text;
390
+ -webkit-text-fill-color: transparent;
391
+ background-clip: text;
392
+ line-height: 1.1;
393
+ }
394
+ .hero-tagline {
395
+ font-size: 1.125rem;
396
+ color: var(--clr-text-secondary);
397
+ max-width: 480px;
398
+ line-height: 1.7;
399
+ }
400
+ .cta-row {
401
+ display: flex;
402
+ gap: 0.75rem;
403
+ flex-wrap: wrap;
404
+ justify-content: center;
405
+ margin-top: 0.5rem;
406
+ }
407
+ .cta-btn {
408
+ padding: 0.75rem 1.75rem;
409
+ border-radius: var(--radius-md);
410
+ font-family: var(--font-sans);
411
+ font-size: 0.9375rem;
412
+ font-weight: 600;
413
+ cursor: pointer;
414
+ text-decoration: none;
415
+ transition: all var(--t-med);
416
+ display: inline-flex;
417
+ align-items: center;
418
+ gap: 0.4rem;
419
+ }
420
+ .cta-primary {
421
+ background: var(--clr-accent);
422
+ color: var(--clr-bg-deep);
423
+ border: none;
424
+ box-shadow: 0 0 20px var(--clr-accent-glow);
425
+ }
426
+ .cta-primary:hover {
427
+ background: #9fffa5;
428
+ box-shadow: 0 0 32px rgba(120,248,126,0.35);
429
+ transform: translateY(-1px);
430
+ }
431
+ .cta-secondary {
432
+ background: transparent;
433
+ color: var(--clr-text-primary);
434
+ border: 1px solid var(--clr-border);
435
+ }
436
+ .cta-secondary:hover {
437
+ border-color: var(--clr-border-hover);
438
+ background: rgba(255,255,255,0.04);
439
+ transform: translateY(-1px);
440
+ }
441
+
442
+ /* ── Features section ── */
443
+ .features-section {
444
+ max-width: 1000px;
445
+ margin: 0 auto;
446
+ padding: 0 1.5rem 5rem;
447
+ display: grid;
448
+ grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
449
+ gap: 1.25rem;
450
+ }
451
+ .feature-card {
452
+ background: var(--clr-bg-glass);
453
+ border: 1px solid var(--clr-border);
454
+ border-radius: var(--radius-lg);
455
+ padding: 1.75rem;
456
+ backdrop-filter: blur(12px);
457
+ transition: border-color var(--t-med), box-shadow var(--t-med), transform var(--t-med);
458
+ display: flex;
459
+ flex-direction: column;
460
+ gap: 0.75rem;
461
+ }
462
+ .feature-card:hover {
463
+ border-color: var(--clr-border-hover);
464
+ box-shadow: var(--shadow-glow);
465
+ transform: translateY(-3px);
466
+ }
467
+ .feature-icon {
468
+ font-size: 1.75rem;
469
+ }
470
+ .feature-title {
471
+ font-size: 1.1rem;
472
+ font-weight: 600;
473
+ color: var(--clr-text-primary);
474
+ }
475
+ .feature-desc {
476
+ font-size: 0.9rem;
477
+ color: var(--clr-text-secondary);
478
+ line-height: 1.65;
479
+ }
480
+ .feature-desc code {
481
+ font-family: var(--font-mono);
482
+ font-size: 0.8rem;
483
+ background: rgba(120,248,126,0.1);
484
+ color: var(--clr-accent);
485
+ padding: 0.1em 0.35em;
486
+ border-radius: 3px;
487
+ }
488
+
489
+ /* ── Status section ── */
490
+ .status-section {
491
+ max-width: 400px;
492
+ margin: 0 auto;
493
+ padding: 0 1.5rem 4rem;
494
+ display: flex;
495
+ justify-content: center;
496
+ }
497
+ .status-badge {
498
+ display: inline-flex;
499
+ align-items: center;
500
+ gap: 0.5rem;
501
+ padding: 0.5rem 1rem;
502
+ border-radius: 999px;
503
+ font-size: 0.85rem;
504
+ font-weight: 500;
505
+ border: 1px solid var(--clr-border);
506
+ background: var(--clr-bg-glass);
507
+ backdrop-filter: blur(8px);
508
+ }
509
+ .status-loading { color: var(--clr-text-secondary); }
510
+ .status-ready { color: var(--clr-accent); border-color: var(--clr-accent-dim); }
511
+ .status-error { color: var(--clr-danger); }
512
+
513
+ /* ── Footer ── */
514
+ .footer-panel {
515
+ height: var(--footer-panel-height);
516
+ display: flex;
517
+ align-items: center;
518
+ justify-content: center;
519
+ border-top: 1px solid var(--clr-border);
520
+ background: var(--clr-bg-glass);
521
+ }
522
+ .footer-text {
523
+ font-size: 0.8rem;
524
+ color: var(--clr-text-muted);
525
+ display: flex;
526
+ gap: 0.5rem;
527
+ flex-wrap: wrap;
528
+ justify-content: center;
529
+ align-items: center;
530
+ }
531
+ .footer-link {
532
+ color: var(--clr-text-secondary);
533
+ text-decoration: none;
534
+ transition: color var(--t-fast);
535
+ }
536
+ .footer-link:hover { color: var(--clr-accent); }
537
+
538
+ /* ── Responsive ── */
539
+ @media (max-width: 600px) {
540
+ .header-nav { display: none; }
541
+ .hero-section { padding: 3rem 1rem 2.5rem; }
542
+ .features-section { padding: 0 1rem 3rem; }
543
+ }
544
+
545
+ /* ── Dev Tools Panel (diagnostic only — remove when WS sync confirmed) ── */
546
+ .dev-panel {
547
+ max-width: 720px;
548
+ margin: 0 auto;
549
+ padding: 1.5rem;
550
+ border: 1px dashed rgba(255, 204, 68, 0.35);
551
+ border-radius: var(--radius-md);
552
+ background: rgba(255, 204, 68, 0.04);
553
+ display: flex;
554
+ flex-direction: column;
555
+ gap: 1rem;
556
+ margin-bottom: 3rem;
557
+ }
558
+ .dev-panel-title {
559
+ font-size: 0.8rem;
560
+ font-weight: 600;
561
+ text-transform: uppercase;
562
+ letter-spacing: 0.12em;
563
+ color: var(--clr-warn);
564
+ opacity: 0.7;
565
+ }
566
+ .dev-panel-row {
567
+ display: flex;
568
+ gap: 0.75rem;
569
+ flex-wrap: wrap;
570
+ }
571
+ .dev-btn {
572
+ padding: 0.55rem 1.25rem;
573
+ border-radius: var(--radius-sm);
574
+ background: transparent;
575
+ border: 1px solid rgba(255, 204, 68, 0.4);
576
+ color: var(--clr-warn);
577
+ font-family: var(--font-sans);
578
+ font-size: 0.875rem;
579
+ font-weight: 500;
580
+ cursor: pointer;
581
+ transition: background var(--t-fast), border-color var(--t-fast);
582
+ }
583
+ .dev-btn:hover:not(:disabled) {
584
+ background: rgba(255, 204, 68, 0.08);
585
+ border-color: rgba(255, 204, 68, 0.7);
586
+ }
587
+ .dev-btn:disabled {
588
+ opacity: 0.5;
589
+ cursor: not-allowed;
590
+ border-color: rgba(255, 204, 68, 0.2);
591
+ }
592
+ .dev-panel-log {
593
+ font-family: var(--font-mono);
594
+ font-size: 0.75rem;
595
+ color: var(--clr-text-secondary);
596
+ background: rgba(0, 0, 0, 0.35);
597
+ border: 1px solid var(--clr-border);
598
+ border-radius: var(--radius-sm);
599
+ padding: 0.75rem 1rem;
600
+ max-height: 240px;
601
+ overflow-y: auto;
602
+ white-space: pre-wrap;
603
+ word-break: break-all;
604
+ min-height: 3rem;
605
+ }
@@ -0,0 +1,5 @@
1
+ import { RespecNodeRunner } from '@ibgib/helper-gib/dist/respec-gib/respec-node-runner.mjs';
2
+ const runner = new RespecNodeRunner({
3
+ respecFileRegExp: /\.respec/,
4
+ });
5
+ await runner.run();