freertc 0.1.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,821 @@
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">
6
+ <title>freertc</title>
7
+ <style>
8
+ :root {
9
+ color-scheme: dark;
10
+ --bg: #0b0f14;
11
+ --bg-strong: #111821;
12
+ --paper: rgba(18, 24, 33, 0.82);
13
+ --paper-strong: rgba(23, 30, 41, 0.96);
14
+ --ink: #f2f5f7;
15
+ --ink-soft: #c2cad2;
16
+ --muted: #8e9aa7;
17
+ --line: rgba(197, 214, 230, 0.12);
18
+ --line-strong: rgba(197, 214, 230, 0.24);
19
+ --accent: #f2f5f7;
20
+ --accent-soft: #1b2531;
21
+ --success: #66d18f;
22
+ --warn: #ffb357;
23
+ --shadow: 0 28px 90px rgba(0, 0, 0, 0.38);
24
+ }
25
+ * {
26
+ box-sizing: border-box;
27
+ }
28
+ body {
29
+ margin: 0;
30
+ min-height: 100vh;
31
+ font-family: "Space Grotesk", "Avenir Next", "Segoe UI", sans-serif;
32
+ color: var(--ink);
33
+ background:
34
+ radial-gradient(circle at top left, rgba(117, 174, 255, 0.12), transparent 24%),
35
+ radial-gradient(circle at 85% 10%, rgba(54, 86, 132, 0.22), transparent 18%),
36
+ linear-gradient(180deg, #090d12 0%, var(--bg) 52%, var(--bg-strong) 100%);
37
+ }
38
+ #app {
39
+ min-height: 100vh;
40
+ padding: 28px;
41
+ }
42
+ .shell {
43
+ width: min(1180px, 100%);
44
+ margin: 0 auto;
45
+ display: grid;
46
+ gap: 18px;
47
+ }
48
+ .card {
49
+ background: var(--paper);
50
+ border: 1px solid var(--line);
51
+ border-radius: 24px;
52
+ padding: 20px;
53
+ box-shadow: var(--shadow);
54
+ backdrop-filter: blur(18px);
55
+ }
56
+ .hero {
57
+ display: flex;
58
+ align-items: flex-start;
59
+ justify-content: space-between;
60
+ gap: 24px;
61
+ }
62
+ .hero-compact {
63
+ display: grid;
64
+ gap: 8px;
65
+ }
66
+ .brand-lockup {
67
+ display: inline-flex;
68
+ align-items: center;
69
+ gap: 12px;
70
+ }
71
+ .logo-badge {
72
+ width: 42px;
73
+ height: 42px;
74
+ border-radius: 12px;
75
+ display: grid;
76
+ place-items: center;
77
+ }
78
+ .brand-icon {
79
+ width: 34px;
80
+ height: 34px;
81
+ display: block;
82
+ }
83
+ .hero-compact h1 {
84
+ margin: 0;
85
+ font-size: 1.35rem;
86
+ font-weight: 700;
87
+ letter-spacing: 0.01em;
88
+ text-transform: uppercase;
89
+ }
90
+ .brand-wordmark {
91
+ text-transform: none;
92
+ letter-spacing: 0.01em;
93
+ }
94
+ .brand-free {
95
+ color: #f2f5f7;
96
+ }
97
+ .brand-rtc {
98
+ color: #8b5cf6;
99
+ }
100
+ .hero-copy {
101
+ margin: 0;
102
+ max-width: 42rem;
103
+ color: var(--ink-soft);
104
+ font-size: 1rem;
105
+ line-height: 1.5;
106
+ }
107
+ .inline-link,
108
+ .pill-link {
109
+ color: #9bc6ff;
110
+ text-decoration: underline;
111
+ text-decoration-thickness: 1.5px;
112
+ text-underline-offset: 2px;
113
+ }
114
+ .inline-link:hover,
115
+ .pill-link:hover {
116
+ color: #c8e0ff;
117
+ }
118
+ .hero-status {
119
+ min-width: 220px;
120
+ display: grid;
121
+ gap: 12px;
122
+ }
123
+ .status-pill,
124
+ .pill,
125
+ .tab {
126
+ display: inline-flex;
127
+ align-items: center;
128
+ justify-content: center;
129
+ gap: 8px;
130
+ border-radius: 999px;
131
+ border: 1px solid var(--line-strong);
132
+ padding: 8px 14px;
133
+ font-size: 0.84rem;
134
+ text-transform: uppercase;
135
+ letter-spacing: 0.08em;
136
+ background: rgba(255, 255, 255, 0.03);
137
+ }
138
+ .status-pill strong,
139
+ .pill strong {
140
+ font-weight: 700;
141
+ }
142
+ .pill.pill-warn {
143
+ color: var(--warn);
144
+ border-color: rgba(255, 179, 87, 0.35);
145
+ background: rgba(92, 59, 18, 0.42);
146
+ }
147
+ .pill.pill-ok {
148
+ color: var(--success);
149
+ border-color: rgba(102, 209, 143, 0.35);
150
+ background: rgba(34, 71, 48, 0.48);
151
+ }
152
+ .status-pill.connected {
153
+ color: var(--success);
154
+ border-color: rgba(102, 209, 143, 0.25);
155
+ background: rgba(34, 71, 48, 0.42);
156
+ }
157
+ .status-pill.connecting {
158
+ color: var(--warn);
159
+ border-color: rgba(255, 179, 87, 0.25);
160
+ background: rgba(92, 59, 18, 0.42);
161
+ }
162
+ .status-pill.disconnected {
163
+ color: #ff9488;
164
+ border-color: rgba(255, 148, 136, 0.18);
165
+ background: rgba(88, 29, 31, 0.42);
166
+ }
167
+ .headline-grid {
168
+ display: grid;
169
+ grid-template-columns: minmax(0, 1.2fr) minmax(320px, 0.8fr);
170
+ gap: 18px;
171
+ }
172
+ .info-grid,
173
+ .control-grid {
174
+ display: grid;
175
+ gap: 14px;
176
+ }
177
+ .field-grid {
178
+ display: grid;
179
+ grid-template-columns: repeat(2, minmax(0, 1fr));
180
+ gap: 12px;
181
+ }
182
+ .info-grid {
183
+ grid-template-columns: repeat(3, minmax(0, 1fr));
184
+ }
185
+ .control-grid {
186
+ grid-template-columns: minmax(0, 1.45fr) minmax(320px, 0.75fr);
187
+ }
188
+ .sidebar-stack {
189
+ display: grid;
190
+ gap: 14px;
191
+ align-content: start;
192
+ }
193
+ .stack {
194
+ display: grid;
195
+ gap: 12px;
196
+ }
197
+ .panel-title {
198
+ margin: 0;
199
+ font-size: 0.82rem;
200
+ text-transform: uppercase;
201
+ letter-spacing: 0.14em;
202
+ color: var(--muted);
203
+ }
204
+ .spec-warning-card {
205
+ border-color: rgba(255, 179, 87, 0.28);
206
+ background: rgba(92, 59, 18, 0.18);
207
+ }
208
+ .spec-warning-list {
209
+ margin: 0;
210
+ padding-left: 20px;
211
+ display: grid;
212
+ gap: 8px;
213
+ }
214
+ .spec-warning-item {
215
+ color: #ffd9ab;
216
+ font-size: 0.9rem;
217
+ line-height: 1.35;
218
+ }
219
+ .stat-card {
220
+ display: grid;
221
+ gap: 10px;
222
+ min-height: 120px;
223
+ min-width: 0;
224
+ padding: 18px;
225
+ background: var(--paper-strong);
226
+ border: 1px solid var(--line);
227
+ border-radius: 20px;
228
+ }
229
+ .stat-label {
230
+ font-size: 0.74rem;
231
+ text-transform: uppercase;
232
+ letter-spacing: 0.16em;
233
+ color: var(--muted);
234
+ }
235
+ .stat-value {
236
+ font-size: clamp(1rem, 2.2vw, 1.45rem);
237
+ line-height: 1.2;
238
+ word-break: break-word;
239
+ }
240
+ .stat-input {
241
+ width: 100%;
242
+ border-radius: 12px;
243
+ border: 1px solid var(--line-strong);
244
+ background: rgba(255, 255, 255, 0.03);
245
+ color: var(--ink);
246
+ padding: 10px 12px;
247
+ font-size: 0.88rem;
248
+ }
249
+ .mono,
250
+ input,
251
+ textarea,
252
+ select,
253
+ .log,
254
+ .mini-log,
255
+ code {
256
+ font-family: "IBM Plex Mono", "SFMono-Regular", Menlo, Monaco, monospace;
257
+ }
258
+ label {
259
+ display: grid;
260
+ gap: 6px;
261
+ font-size: 0.78rem;
262
+ text-transform: uppercase;
263
+ letter-spacing: 0.12em;
264
+ color: var(--muted);
265
+ }
266
+ input,
267
+ textarea,
268
+ select {
269
+ width: 100%;
270
+ border: 1px solid var(--line);
271
+ border-radius: 16px;
272
+ background: rgba(255, 255, 255, 0.04);
273
+ color: var(--ink);
274
+ padding: 12px 14px;
275
+ font-size: 0.94rem;
276
+ }
277
+ textarea {
278
+ min-height: 180px;
279
+ resize: vertical;
280
+ }
281
+ .row {
282
+ display: flex;
283
+ gap: 10px;
284
+ flex-wrap: wrap;
285
+ }
286
+ button {
287
+ appearance: none;
288
+ border: 1px solid var(--accent);
289
+ background: var(--accent);
290
+ color: #0b0f14;
291
+ border-radius: 999px;
292
+ padding: 11px 16px;
293
+ cursor: pointer;
294
+ font: inherit;
295
+ font-size: 0.86rem;
296
+ font-weight: 600;
297
+ letter-spacing: 0.02em;
298
+ transition: transform 120ms ease, background 120ms ease, border-color 120ms ease;
299
+ }
300
+ button:hover {
301
+ transform: translateY(-1px);
302
+ }
303
+ button.secondary {
304
+ background: var(--accent-soft);
305
+ color: var(--ink);
306
+ border-color: var(--line-strong);
307
+ }
308
+ button.secondary.active {
309
+ background: #9bc6ff;
310
+ border-color: #9bc6ff;
311
+ color: #101722;
312
+ box-shadow: none;
313
+ }
314
+ button:disabled {
315
+ opacity: 0.5;
316
+ cursor: not-allowed;
317
+ transform: none;
318
+ }
319
+ .tabs {
320
+ display: inline-flex;
321
+ gap: 8px;
322
+ padding: 6px;
323
+ border-radius: 999px;
324
+ background: rgba(255, 255, 255, 0.03);
325
+ border: 1px solid var(--line);
326
+ }
327
+ .tab {
328
+ cursor: pointer;
329
+ min-width: 140px;
330
+ color: var(--ink);
331
+ }
332
+ .tab.active {
333
+ background: var(--accent);
334
+ color: #0b0f14;
335
+ border-color: var(--accent);
336
+ }
337
+ .section-header {
338
+ display: flex;
339
+ justify-content: space-between;
340
+ align-items: center;
341
+ gap: 16px;
342
+ flex-wrap: wrap;
343
+ }
344
+ .metrics {
345
+ display: grid;
346
+ grid-template-columns: repeat(4, minmax(0, 1fr));
347
+ gap: 12px;
348
+ }
349
+ .metric {
350
+ padding: 14px 16px;
351
+ border-radius: 18px;
352
+ border: 1px solid var(--line);
353
+ background: rgba(255, 255, 255, 0.04);
354
+ min-width: 0;
355
+ }
356
+ .metric dt {
357
+ margin: 0 0 8px;
358
+ font-size: 0.7rem;
359
+ text-transform: uppercase;
360
+ letter-spacing: 0.14em;
361
+ color: var(--muted);
362
+ }
363
+ .metric dd {
364
+ margin: 0;
365
+ font-size: 1rem;
366
+ line-height: 1.3;
367
+ }
368
+ .peer-value {
369
+ display: block;
370
+ max-width: 100%;
371
+ overflow: hidden;
372
+ text-overflow: ellipsis;
373
+ white-space: nowrap;
374
+ }
375
+ .mesh-list {
376
+ display: grid;
377
+ gap: 10px;
378
+ }
379
+ .mesh-row {
380
+ width: 100%;
381
+ display: flex;
382
+ align-items: center;
383
+ justify-content: space-between;
384
+ gap: 12px;
385
+ padding: 14px 16px;
386
+ text-align: left;
387
+ border-radius: 18px;
388
+ background: rgba(255, 255, 255, 0.04);
389
+ color: var(--ink);
390
+ border: 1px solid var(--line);
391
+ }
392
+ .mesh-row.is-selected {
393
+ border-color: rgba(111, 99, 255, 0.42);
394
+ background: rgba(111, 99, 255, 0.12);
395
+ }
396
+ .mesh-row.is-connected {
397
+ box-shadow: inset 0 0 0 1px rgba(102, 209, 143, 0.18);
398
+ }
399
+ .mesh-main {
400
+ display: grid;
401
+ gap: 4px;
402
+ min-width: 0;
403
+ }
404
+ .mesh-peer-row {
405
+ display: flex;
406
+ align-items: center;
407
+ justify-content: space-between;
408
+ gap: 8px;
409
+ min-width: 0;
410
+ }
411
+ .mesh-peer {
412
+ font-size: 0.95rem;
413
+ color: var(--ink);
414
+ }
415
+ .mesh-badges {
416
+ display: inline-flex;
417
+ align-items: center;
418
+ gap: 6px;
419
+ flex-wrap: wrap;
420
+ justify-content: flex-end;
421
+ }
422
+ .mesh-badge {
423
+ border-radius: 999px;
424
+ padding: 2px 8px;
425
+ font-size: 0.66rem;
426
+ text-transform: uppercase;
427
+ letter-spacing: 0.08em;
428
+ border: 1px solid var(--line-strong);
429
+ background: rgba(255, 255, 255, 0.04);
430
+ color: var(--ink-soft);
431
+ }
432
+ .mesh-badge.ok {
433
+ color: var(--success);
434
+ border-color: rgba(102, 209, 143, 0.28);
435
+ background: rgba(102, 209, 143, 0.09);
436
+ }
437
+ .mesh-badge.warn {
438
+ color: var(--warn);
439
+ border-color: rgba(255, 179, 87, 0.3);
440
+ background: rgba(255, 179, 87, 0.1);
441
+ }
442
+ .mesh-badge.error {
443
+ color: #ff9488;
444
+ border-color: rgba(255, 148, 136, 0.28);
445
+ background: rgba(255, 148, 136, 0.09);
446
+ }
447
+ .mesh-badge.idle {
448
+ color: var(--ink-soft);
449
+ }
450
+ .mesh-badge.mesh-role {
451
+ color: #9bc6ff;
452
+ border-color: rgba(155, 198, 255, 0.3);
453
+ background: rgba(86, 128, 179, 0.18);
454
+ }
455
+ .mesh-badge.mesh-role.responder {
456
+ color: #c9c6ff;
457
+ border-color: rgba(201, 198, 255, 0.28);
458
+ background: rgba(114, 111, 164, 0.18);
459
+ }
460
+ .mesh-state-line {
461
+ color: var(--muted);
462
+ font-size: 0.76rem;
463
+ text-transform: uppercase;
464
+ letter-spacing: 0.08em;
465
+ }
466
+ .mesh-empty {
467
+ height: auto;
468
+ min-height: 128px;
469
+ }
470
+ .mesh-helper {
471
+ margin: 0;
472
+ font-size: 0.8rem;
473
+ color: var(--ink-soft);
474
+ }
475
+ .runtime-strip {
476
+ display: grid;
477
+ grid-template-columns: repeat(4, minmax(0, 1fr));
478
+ gap: 10px;
479
+ }
480
+ .runtime-chip {
481
+ border: 1px solid var(--line);
482
+ border-radius: 16px;
483
+ padding: 10px 12px;
484
+ background: rgba(255, 255, 255, 0.035);
485
+ min-width: 0;
486
+ }
487
+ .runtime-chip.ok {
488
+ border-color: rgba(102, 209, 143, 0.28);
489
+ background: rgba(102, 209, 143, 0.08);
490
+ }
491
+ .runtime-chip.warn {
492
+ border-color: rgba(255, 179, 87, 0.3);
493
+ background: rgba(255, 179, 87, 0.08);
494
+ }
495
+ .runtime-chip.selected {
496
+ border-color: rgba(155, 198, 255, 0.28);
497
+ background: rgba(86, 128, 179, 0.12);
498
+ }
499
+ .runtime-label {
500
+ font-size: 0.67rem;
501
+ text-transform: uppercase;
502
+ letter-spacing: 0.12em;
503
+ color: var(--muted);
504
+ margin-bottom: 4px;
505
+ }
506
+ .runtime-value {
507
+ font-size: 0.94rem;
508
+ line-height: 1.25;
509
+ color: var(--ink);
510
+ min-width: 0;
511
+ }
512
+ .runtime-route-value {
513
+ white-space: normal;
514
+ overflow-wrap: anywhere;
515
+ word-break: break-word;
516
+ }
517
+ .mode-toggle {
518
+ display: inline-flex;
519
+ border: 1px solid var(--line-strong);
520
+ border-radius: 999px;
521
+ overflow: hidden;
522
+ background: rgba(255, 255, 255, 0.03);
523
+ min-width: 0;
524
+ }
525
+ .mode-btn {
526
+ appearance: none;
527
+ border: 0;
528
+ margin: 0;
529
+ border-radius: 0;
530
+ background: transparent;
531
+ color: var(--ink-soft);
532
+ padding: 9px 14px;
533
+ font: inherit;
534
+ font-size: 0.82rem;
535
+ font-weight: 600;
536
+ letter-spacing: 0.02em;
537
+ cursor: pointer;
538
+ }
539
+ .mode-btn + .mode-btn {
540
+ border-left: 1px solid var(--line-strong);
541
+ }
542
+ .mode-btn.active {
543
+ background: var(--accent);
544
+ color: #0b0f14;
545
+ }
546
+ .chat-composer {
547
+ gap: 10px;
548
+ padding: 12px;
549
+ border: 1px solid var(--line);
550
+ border-radius: 16px;
551
+ background: rgba(255, 255, 255, 0.02);
552
+ }
553
+ .chat-label {
554
+ gap: 8px;
555
+ text-transform: none;
556
+ letter-spacing: 0.01em;
557
+ font-size: 0.84rem;
558
+ color: var(--ink-soft);
559
+ }
560
+ .chat-toolbar {
561
+ display: flex;
562
+ align-items: center;
563
+ justify-content: space-between;
564
+ gap: 10px;
565
+ flex-wrap: wrap;
566
+ }
567
+ .chat-send-btn {
568
+ min-width: 88px;
569
+ }
570
+ .console-action-btn {
571
+ display: inline-flex;
572
+ align-items: center;
573
+ justify-content: center;
574
+ min-width: 132px;
575
+ height: 42px;
576
+ padding: 0 16px;
577
+ line-height: 1;
578
+ white-space: nowrap;
579
+ }
580
+ .mode-indicator {
581
+ margin: 0;
582
+ font-size: 0.82rem;
583
+ letter-spacing: 0.01em;
584
+ color: var(--ink-soft);
585
+ }
586
+ .chat-thread {
587
+ display: flex;
588
+ flex-direction: column;
589
+ gap: 12px;
590
+ height: 320px;
591
+ overflow-y: auto;
592
+ overflow-x: hidden;
593
+ scrollbar-gutter: stable;
594
+ padding: 6px;
595
+ border-radius: 18px;
596
+ background: rgba(255, 255, 255, 0.03);
597
+ border: 1px solid var(--line);
598
+ }
599
+ .chat-row {
600
+ display: flex;
601
+ }
602
+ .chat-row.outgoing {
603
+ justify-content: flex-end;
604
+ }
605
+ .chat-row.incoming,
606
+ .chat-row.system,
607
+ .chat-row.error {
608
+ justify-content: flex-start;
609
+ }
610
+ .chat-bubble {
611
+ width: fit-content;
612
+ max-width: min(100%, 32rem);
613
+ padding: 12px 14px;
614
+ border-radius: 18px;
615
+ border: 1px solid var(--line);
616
+ background: rgba(255, 255, 255, 0.04);
617
+ }
618
+ .chat-row.outgoing .chat-bubble {
619
+ background: rgba(111, 99, 255, 0.18);
620
+ border-color: rgba(111, 99, 255, 0.32);
621
+ }
622
+ .chat-row.incoming .chat-bubble {
623
+ background: rgba(255, 255, 255, 0.06);
624
+ }
625
+ .chat-row.system .chat-bubble {
626
+ background: rgba(102, 209, 143, 0.08);
627
+ border-color: rgba(102, 209, 143, 0.2);
628
+ }
629
+ .chat-row.error .chat-bubble {
630
+ background: rgba(255, 148, 136, 0.12);
631
+ border-color: rgba(255, 148, 136, 0.24);
632
+ }
633
+ .chat-meta {
634
+ margin-bottom: 6px;
635
+ color: var(--muted);
636
+ font-size: 0.72rem;
637
+ text-transform: uppercase;
638
+ letter-spacing: 0.1em;
639
+ }
640
+ .chat-body {
641
+ color: var(--ink);
642
+ font-size: 0.96rem;
643
+ line-height: 1.45;
644
+ white-space: pre-wrap;
645
+ word-break: break-word;
646
+ }
647
+ .chat-empty {
648
+ height: 320px;
649
+ display: grid;
650
+ place-items: center;
651
+ padding: 14px;
652
+ border-radius: 18px;
653
+ border: 1px dashed var(--line-strong);
654
+ color: var(--muted);
655
+ text-align: center;
656
+ background: rgba(255, 255, 255, 0.02);
657
+ }
658
+ .console-card,
659
+ .debug-card {
660
+ background: #0e1319;
661
+ color: #edf3f8;
662
+ border: 1px solid rgba(255, 255, 255, 0.08);
663
+ }
664
+ .debug-card {
665
+ min-height: 340px;
666
+ }
667
+ .console-card .panel-title,
668
+ .debug-card .panel-title,
669
+ .console-card .muted,
670
+ .debug-card .muted {
671
+ color: #9aadc0;
672
+ }
673
+ .log {
674
+ background: transparent;
675
+ color: inherit;
676
+ border-radius: 16px;
677
+ min-height: 220px;
678
+ max-height: 220px;
679
+ overflow: auto;
680
+ padding: 0;
681
+ font-size: 0.84rem;
682
+ white-space: pre-wrap;
683
+ word-break: break-word;
684
+ line-height: 1.55;
685
+ }
686
+ .log-preview {
687
+ margin: 0;
688
+ padding: 10px 12px;
689
+ border-radius: 12px;
690
+ border: 1px dashed rgba(255, 255, 255, 0.16);
691
+ background: rgba(255, 255, 255, 0.02);
692
+ font-size: 0.82rem;
693
+ display: grid;
694
+ gap: 10px;
695
+ min-height: 220px;
696
+ max-height: 220px;
697
+ overflow: auto;
698
+ }
699
+ .log-preview-head {
700
+ font-size: 0.78rem;
701
+ letter-spacing: 0.02em;
702
+ color: #b7c8d8;
703
+ }
704
+ .log-preview-list {
705
+ margin: 0;
706
+ padding: 0;
707
+ list-style: none;
708
+ display: grid;
709
+ gap: 8px;
710
+ }
711
+ .log-preview-item {
712
+ display: grid;
713
+ gap: 2px;
714
+ padding: 8px 10px;
715
+ border-radius: 10px;
716
+ background: rgba(255, 255, 255, 0.03);
717
+ }
718
+ .log-preview-time {
719
+ color: #93a7bc;
720
+ font-size: 0.72rem;
721
+ letter-spacing: 0.08em;
722
+ text-transform: uppercase;
723
+ }
724
+ .log-preview-label {
725
+ color: #ecf3fb;
726
+ font-size: 0.8rem;
727
+ }
728
+ .log-preview-text {
729
+ color: #b9c9d8;
730
+ font-size: 0.76rem;
731
+ line-height: 1.35;
732
+ word-break: break-word;
733
+ }
734
+ .muted {
735
+ color: var(--muted);
736
+ font-size: 0.94rem;
737
+ line-height: 1.5;
738
+ }
739
+ code {
740
+ display: inline-block;
741
+ background: rgba(255, 255, 255, 0.08);
742
+ padding: 4px 8px;
743
+ border-radius: 8px;
744
+ font-size: 0.88em;
745
+ }
746
+ .footer-note {
747
+ display: flex;
748
+ align-items: center;
749
+ justify-content: space-between;
750
+ gap: 12px;
751
+ flex-wrap: wrap;
752
+ }
753
+ @media (max-width: 980px) {
754
+ .headline-grid,
755
+ .control-grid,
756
+ .field-grid,
757
+ .info-grid,
758
+ .runtime-strip,
759
+ .metrics {
760
+ grid-template-columns: 1fr;
761
+ }
762
+ .chat-toolbar {
763
+ flex-direction: column;
764
+ align-items: stretch;
765
+ }
766
+ .chat-send-btn {
767
+ width: 100%;
768
+ }
769
+ .mode-toggle {
770
+ width: 100%;
771
+ }
772
+ .mode-btn {
773
+ flex: 1;
774
+ }
775
+ .hero {
776
+ flex-direction: column;
777
+ }
778
+ }
779
+ @media (max-width: 720px) {
780
+ #app {
781
+ padding: 16px;
782
+ }
783
+ .card {
784
+ border-radius: 20px;
785
+ padding: 16px;
786
+ }
787
+ .hero h1 {
788
+ font-size: clamp(2rem, 16vw, 3.6rem);
789
+ }
790
+ .brand-lockup {
791
+ align-items: flex-start;
792
+ }
793
+ .logo-badge {
794
+ width: 48px;
795
+ height: 48px;
796
+ }
797
+ .brand-icon {
798
+ width: 40px;
799
+ height: 40px;
800
+ }
801
+ .tabs {
802
+ width: 100%;
803
+ }
804
+ .tab {
805
+ flex: 1;
806
+ min-width: 0;
807
+ }
808
+ }
809
+ @media (max-width: 560px) {
810
+ .info-grid,
811
+ .metrics {
812
+ grid-template-columns: 1fr;
813
+ }
814
+ }
815
+ </style>
816
+ </head>
817
+ <body>
818
+ <div id="app"></div>
819
+ <script type="module" src="/app.js"></script>
820
+ </body>
821
+ </html>