Bc-AI commited on
Commit
befafa1
Β·
verified Β·
1 Parent(s): 2b1b1ec

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +432 -229
index.html CHANGED
@@ -3,43 +3,69 @@
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>CodVa-2 Β· Code Assistant</title>
 
 
7
  <style>
8
  /* ── RESET & BASE ─────────────────────────────────────────────────── */
9
  *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
10
 
11
  :root {
12
- --bg: #0d0f14;
13
- --surface: #13161f;
14
- --surface2: #1a1e2b;
15
- --surface3: #21263a;
16
- --border: #2a2f45;
17
- --accent: #7c6aff;
18
- --accent2: #4fc3f7;
19
- --accent3: #43e97b;
20
- --think: #f7971e;
21
- --text: #e8eaf6;
22
- --text2: #9099bb;
23
- --text3: #5a6280;
24
- --red: #ff5370;
25
- --radius: 12px;
26
- --radius-sm: 8px;
 
 
 
 
 
 
 
 
 
 
 
 
27
  }
28
 
29
  html, body {
30
  height: 100%;
31
  background: var(--bg);
32
  color: var(--text);
33
- font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
34
  font-size: 14px;
35
  line-height: 1.6;
36
  }
37
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  /* ── LAYOUT ───────────────────────────────────────────────────────── */
39
  .app {
40
  display: grid;
41
  grid-template-rows: auto 1fr;
42
- grid-template-columns: 340px 1fr;
43
  grid-template-areas:
44
  "header header"
45
  "sidebar main";
@@ -52,8 +78,9 @@
52
  grid-area: header;
53
  display: flex;
54
  align-items: center;
55
- gap: 16px;
56
- padding: 12px 24px;
 
57
  background: var(--surface);
58
  border-bottom: 1px solid var(--border);
59
  z-index: 10;
@@ -62,42 +89,62 @@
62
  .logo {
63
  display: flex;
64
  align-items: center;
65
- gap: 10px;
66
  }
67
 
68
  .logo-icon {
69
- width: 36px;
70
- height: 36px;
71
- background: linear-gradient(135deg, var(--accent), var(--accent2));
72
- border-radius: 10px;
 
73
  display: flex;
74
  align-items: center;
75
  justify-content: center;
76
- font-size: 18px;
77
- font-weight: 800;
78
- color: white;
79
- letter-spacing: -1px;
 
80
  flex-shrink: 0;
 
 
 
 
 
 
 
 
 
81
  }
82
 
83
  .logo-text h1 {
84
- font-size: 16px;
 
85
  font-weight: 700;
86
- background: linear-gradient(90deg, var(--accent), var(--accent2));
87
- -webkit-background-clip: text;
88
- -webkit-text-fill-color: transparent;
89
- background-clip: text;
90
  }
91
 
92
  .logo-text p {
93
- font-size: 11px;
94
- color: var(--text3);
 
 
 
 
 
 
 
 
 
 
95
  }
96
 
97
  .header-stats {
98
  margin-left: auto;
99
  display: flex;
100
- gap: 12px;
101
  align-items: center;
102
  }
103
 
@@ -105,25 +152,28 @@
105
  background: var(--surface2);
106
  border: 1px solid var(--border);
107
  border-radius: 20px;
108
- padding: 4px 12px;
 
109
  font-size: 11px;
110
- color: var(--text2);
111
  display: flex;
112
  align-items: center;
113
- gap: 6px;
 
114
  }
115
 
116
  .stat-pill .dot {
117
  width: 6px;
118
  height: 6px;
119
  border-radius: 50%;
120
- background: var(--accent3);
 
121
  animation: pulse 2s infinite;
122
  }
123
 
124
  @keyframes pulse {
125
  0%, 100% { opacity: 1; }
126
- 50% { opacity: 0.4; }
127
  }
128
 
129
  /* ── SIDEBAR ──────────────────────────────────────────────────────── */
@@ -138,70 +188,93 @@
138
  }
139
 
140
  .sidebar-section {
141
- padding: 16px;
142
  border-bottom: 1px solid var(--border);
143
  }
144
 
145
  .sidebar-section:last-child { border-bottom: none; }
146
 
147
  .section-label {
 
148
  font-size: 10px;
149
- font-weight: 700;
150
- letter-spacing: 1px;
151
  text-transform: uppercase;
152
- color: var(--text3);
153
- margin-bottom: 12px;
 
 
 
 
 
 
 
 
 
 
154
  }
155
 
156
- /* ── CONTEXT RING ─────────────────────────────────────────────────── */
157
  .ctx-ring-wrap {
158
  display: flex;
159
  flex-direction: column;
160
  align-items: center;
161
- gap: 12px;
162
- padding: 8px 0;
163
  }
164
 
165
  .ctx-ring-svg {
166
  position: relative;
167
- width: 140px;
168
- height: 140px;
169
  }
170
 
171
  .ctx-ring-svg svg {
172
- width: 140px;
173
- height: 140px;
174
- transform: rotate(-90deg);
 
 
 
 
 
 
 
 
 
175
  }
176
 
177
  .ctx-track {
178
  fill: none;
179
  stroke: var(--surface3);
180
- stroke-width: 10;
181
  }
182
 
183
  .ctx-prompt {
184
  fill: none;
185
- stroke: var(--accent2);
186
- stroke-width: 10;
187
  stroke-linecap: round;
188
  transition: stroke-dashoffset 0.3s ease;
 
189
  }
190
 
191
  .ctx-generated {
192
  fill: none;
193
- stroke: var(--accent);
194
- stroke-width: 10;
195
  stroke-linecap: round;
196
  transition: stroke-dashoffset 0.3s ease;
 
197
  }
198
 
199
  .ctx-think {
200
  fill: none;
201
- stroke: var(--think);
202
- stroke-width: 10;
203
  stroke-linecap: round;
204
  transition: stroke-dashoffset 0.3s ease;
 
205
  }
206
 
207
  .ctx-ring-center {
@@ -214,21 +287,26 @@
214
  }
215
 
216
  .ctx-ring-center .ctx-num {
217
- font-size: 22px;
218
- font-weight: 800;
 
219
  color: var(--text);
220
  line-height: 1;
 
221
  }
222
 
223
  .ctx-ring-center .ctx-denom {
224
- font-size: 11px;
225
- color: var(--text3);
 
 
 
226
  }
227
 
228
  .ctx-legend {
229
  display: flex;
230
  flex-direction: column;
231
- gap: 6px;
232
  width: 100%;
233
  }
234
 
@@ -236,21 +314,22 @@
236
  display: flex;
237
  align-items: center;
238
  gap: 8px;
239
- font-size: 12px;
240
- color: var(--text2);
 
241
  }
242
 
243
  .legend-dot {
244
- width: 10px;
245
- height: 10px;
246
- border-radius: 3px;
247
  flex-shrink: 0;
248
  }
249
 
250
  .legend-row span:last-child {
251
  margin-left: auto;
252
  font-variant-numeric: tabular-nums;
253
- color: var(--text3);
254
  font-size: 11px;
255
  }
256
 
@@ -258,33 +337,39 @@
258
  .think-budget {
259
  background: var(--surface2);
260
  border: 1px solid var(--border);
 
261
  border-radius: var(--radius-sm);
262
- padding: 10px 12px;
263
  }
264
 
265
  .think-budget-header {
266
  display: flex;
267
  justify-content: space-between;
268
  align-items: center;
269
- margin-bottom: 8px;
270
- font-size: 12px;
271
  }
272
 
273
  .think-budget-label {
274
- color: var(--think);
 
 
275
  font-weight: 600;
 
276
  display: flex;
277
  align-items: center;
278
  gap: 6px;
 
279
  }
280
 
281
  .think-budget-val {
282
- color: var(--text2);
 
 
283
  font-variant-numeric: tabular-nums;
284
  }
285
 
286
  .think-bar-track {
287
- height: 6px;
288
  background: var(--surface3);
289
  border-radius: 3px;
290
  overflow: hidden;
@@ -292,40 +377,43 @@
292
 
293
  .think-bar-fill {
294
  height: 100%;
295
- background: linear-gradient(90deg, var(--think), #ff6b6b);
 
296
  border-radius: 3px;
297
  transition: width 0.3s ease;
298
  width: 0%;
299
  }
300
 
301
  .think-hint {
 
302
  font-size: 10px;
303
- color: var(--text3);
304
- margin-top: 6px;
305
  }
306
 
307
  /* ── CONTROLS ─────────────────────────────────────────────────────── */
308
  label {
309
  display: block;
310
- font-size: 11px;
 
311
  font-weight: 600;
312
- color: var(--text3);
313
- margin-bottom: 6px;
314
  text-transform: uppercase;
315
- letter-spacing: 0.5px;
316
  }
317
 
318
  .slider-wrap {
319
  display: flex;
320
  align-items: center;
321
  gap: 10px;
322
- margin-bottom: 14px;
323
  }
324
 
325
  input[type=range] {
326
  flex: 1;
327
  -webkit-appearance: none;
328
- height: 4px;
329
  border-radius: 2px;
330
  background: var(--surface3);
331
  outline: none;
@@ -334,25 +422,42 @@
334
 
335
  input[type=range]::-webkit-slider-thumb {
336
  -webkit-appearance: none;
337
- width: 14px;
338
- height: 14px;
339
- border-radius: 50%;
340
- background: var(--accent);
 
 
341
  cursor: pointer;
342
- transition: background 0.2s;
343
  }
344
 
345
  input[type=range]::-webkit-slider-thumb:hover {
346
- background: var(--accent2);
 
 
 
 
 
 
 
 
 
 
347
  }
348
 
349
  .slider-val {
350
- font-size: 12px;
 
351
  color: var(--text);
352
  font-variant-numeric: tabular-nums;
353
- min-width: 36px;
354
  text-align: right;
355
  font-weight: 600;
 
 
 
 
356
  }
357
 
358
  /* ── EXAMPLES ─────────────────────────────────────────────────────── */
@@ -366,19 +471,24 @@
366
  background: var(--surface2);
367
  border: 1px solid var(--border);
368
  border-radius: var(--radius-sm);
369
- padding: 8px 10px;
370
- color: var(--text2);
 
371
  font-size: 12px;
372
  cursor: pointer;
373
  text-align: left;
374
  transition: all 0.15s;
375
  line-height: 1.4;
 
 
 
376
  }
377
 
378
  .example-btn:hover {
379
- border-color: var(--accent);
380
  color: var(--text);
381
  background: var(--surface3);
 
382
  }
383
 
384
  /* ── MAIN ─────────────────────────────────────────────────────────── */
@@ -389,14 +499,52 @@
389
  overflow: hidden;
390
  }
391
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
392
  /* ── CHAT AREA ────────────────────────────────────────────────────── */
393
  .chat-area {
394
  flex: 1;
395
  overflow-y: auto;
396
- padding: 24px;
397
  display: flex;
398
  flex-direction: column;
399
- gap: 16px;
400
  }
401
 
402
  .chat-area::-webkit-scrollbar { width: 6px; }
@@ -405,7 +553,7 @@
405
 
406
  /* ── MESSAGES ─────────────────────────────────────────────────────── */
407
  .msg {
408
- max-width: 820px;
409
  width: 100%;
410
  }
411
 
@@ -421,35 +569,38 @@
421
  border-radius: var(--radius);
422
  padding: 14px 18px;
423
  line-height: 1.7;
 
424
  }
425
 
426
  .msg-user .msg-bubble {
427
- background: linear-gradient(135deg, var(--accent), #5a4fcf);
428
- color: white;
429
- border-bottom-right-radius: 4px;
 
430
  }
431
 
432
  .msg-assistant .msg-bubble {
433
  background: var(--surface);
434
  border: 1px solid var(--border);
435
- border-bottom-left-radius: 4px;
436
  }
437
 
438
  .msg-label {
439
- font-size: 11px;
440
- color: var(--text3);
441
- margin-bottom: 6px;
 
442
  font-weight: 600;
443
  text-transform: uppercase;
444
- letter-spacing: 0.5px;
445
  }
446
 
447
  .msg-user .msg-label { text-align: right; }
448
 
449
  /* ── THINK BLOCK ──────────────────────────────────────────────────── */
450
  .think-block {
451
- background: rgba(247, 151, 30, 0.06);
452
- border: 1px solid rgba(247, 151, 30, 0.25);
453
  border-radius: var(--radius-sm);
454
  margin-bottom: 12px;
455
  overflow: hidden;
@@ -459,17 +610,20 @@
459
  display: flex;
460
  align-items: center;
461
  gap: 8px;
462
- padding: 8px 12px;
463
- background: rgba(247, 151, 30, 0.08);
464
- border-bottom: 1px solid rgba(247, 151, 30, 0.15);
465
  cursor: pointer;
466
  user-select: none;
467
- font-size: 12px;
 
468
  font-weight: 600;
469
- color: var(--think);
 
 
470
  }
471
 
472
- .think-header:hover { background: rgba(247, 151, 30, 0.12); }
473
 
474
  .think-chevron {
475
  margin-left: auto;
@@ -482,12 +636,12 @@
482
  }
483
 
484
  .think-body {
485
- padding: 12px 14px;
486
- font-size: 13px;
487
- color: var(--text2);
488
  white-space: pre-wrap;
489
- font-family: 'JetBrains Mono', 'Fira Code', monospace;
490
- line-height: 1.6;
491
  max-height: 300px;
492
  overflow-y: auto;
493
  }
@@ -496,7 +650,7 @@
496
 
497
  /* ── CODE BLOCK ───────────────────────────────────────────────────── */
498
  .code-block {
499
- background: var(--surface2);
500
  border: 1px solid var(--border);
501
  border-radius: var(--radius-sm);
502
  overflow: hidden;
@@ -507,32 +661,36 @@
507
  display: flex;
508
  align-items: center;
509
  justify-content: space-between;
510
- padding: 6px 12px;
511
  background: var(--surface3);
512
  border-bottom: 1px solid var(--border);
513
- font-size: 11px;
514
- color: var(--text3);
 
 
 
515
  }
516
 
517
  .copy-btn {
518
  background: none;
519
- border: 1px solid var(--border);
520
  border-radius: 4px;
521
- padding: 2px 8px;
522
- color: var(--text3);
523
- font-size: 11px;
 
524
  cursor: pointer;
525
  transition: all 0.15s;
526
  }
527
 
528
- .copy-btn:hover { border-color: var(--accent); color: var(--accent); }
529
 
530
  pre {
531
- padding: 14px;
532
  overflow-x: auto;
533
- font-family: 'JetBrains Mono', 'Fira Code', 'Cascadia Code', monospace;
534
- font-size: 13px;
535
- line-height: 1.6;
536
  color: var(--text);
537
  margin: 0;
538
  }
@@ -548,7 +706,7 @@
548
  display: inline-block;
549
  width: 2px;
550
  height: 1em;
551
- background: var(--accent);
552
  margin-left: 2px;
553
  vertical-align: text-bottom;
554
  animation: blink 0.8s steps(1) infinite;
@@ -556,34 +714,9 @@
556
 
557
  @keyframes blink { 0%, 100% { opacity: 1; } 50% { opacity: 0; } }
558
 
559
- /* ── STATUS BAR ───────────────────────────────────────────────────── */
560
- .status-bar {
561
- display: flex;
562
- gap: 16px;
563
- padding: 8px 18px;
564
- background: var(--surface);
565
- border-top: 1px solid var(--border);
566
- border-bottom: 1px solid var(--border);
567
- font-size: 11px;
568
- color: var(--text3);
569
- font-variant-numeric: tabular-nums;
570
- flex-wrap: wrap;
571
- }
572
-
573
- .status-item {
574
- display: flex;
575
- align-items: center;
576
- gap: 4px;
577
- }
578
-
579
- .status-item .val {
580
- color: var(--text2);
581
- font-weight: 600;
582
- }
583
-
584
  /* ── INPUT AREA ───────────────────────────────────────────────────── */
585
  .input-area {
586
- padding: 16px 24px 20px;
587
  background: var(--surface);
588
  border-top: 1px solid var(--border);
589
  }
@@ -595,12 +728,13 @@
595
  background: var(--surface2);
596
  border: 1px solid var(--border);
597
  border-radius: var(--radius);
598
- padding: 10px 12px;
599
- transition: border-color 0.2s;
600
  }
601
 
602
  .input-wrap:focus-within {
603
- border-color: var(--accent);
 
604
  }
605
 
606
  textarea {
@@ -609,8 +743,8 @@
609
  border: none;
610
  outline: none;
611
  color: var(--text);
612
- font-size: 14px;
613
- font-family: inherit;
614
  line-height: 1.6;
615
  resize: none;
616
  min-height: 44px;
@@ -618,16 +752,16 @@
618
  overflow-y: auto;
619
  }
620
 
621
- textarea::placeholder { color: var(--text3); }
622
 
623
  .send-btn {
624
  width: 40px;
625
  height: 40px;
626
  border-radius: var(--radius-sm);
627
- border: none;
628
- background: linear-gradient(135deg, var(--accent), #5a4fcf);
629
- color: white;
630
- font-size: 18px;
631
  cursor: pointer;
632
  display: flex;
633
  align-items: center;
@@ -637,20 +771,20 @@
637
  }
638
 
639
  .send-btn:hover:not(:disabled) {
640
- transform: scale(1.05);
641
- box-shadow: 0 4px 12px rgba(124, 106, 255, 0.4);
642
  }
643
 
644
- .send-btn:disabled { opacity: 0.5; cursor: not-allowed; }
645
 
646
  .stop-btn {
647
  width: 40px;
648
  height: 40px;
649
  border-radius: var(--radius-sm);
650
- border: 1px solid var(--red);
651
- background: rgba(255, 83, 112, 0.1);
652
- color: var(--red);
653
- font-size: 14px;
654
  cursor: pointer;
655
  display: flex;
656
  align-items: center;
@@ -660,11 +794,27 @@
660
  }
661
 
662
  .stop-btn:hover {
663
- background: rgba(255, 83, 112, 0.2);
664
  }
665
 
666
  .stop-btn.hidden { display: none; }
667
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
668
  /* ── EMPTY STATE ──────────────────────────────────────────────────── */
669
  .empty-state {
670
  flex: 1;
@@ -672,26 +822,38 @@
672
  flex-direction: column;
673
  align-items: center;
674
  justify-content: center;
675
- gap: 16px;
676
- opacity: 0.6;
677
  pointer-events: none;
678
  }
679
 
680
  .empty-icon {
681
- font-size: 48px;
 
 
 
 
 
 
 
 
 
 
 
682
  }
683
 
684
  .empty-state h2 {
685
- font-size: 20px;
 
686
  font-weight: 700;
687
- color: var(--text2);
688
  }
689
 
690
  .empty-state p {
691
  font-size: 13px;
692
- color: var(--text3);
693
  text-align: center;
694
  max-width: 300px;
 
695
  }
696
 
697
  /* ── SCROLLBAR ────────────────────────────────────────────────────── */
@@ -699,6 +861,12 @@
699
  ::-webkit-scrollbar-track { background: transparent; }
700
  ::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }
701
 
 
 
 
 
 
 
702
  /* ── RESPONSIVE ───────────────────────────────────────────────────── */
703
  @media (max-width: 700px) {
704
  .app {
@@ -707,11 +875,15 @@
707
  grid-template-areas: "header" "sidebar" "main";
708
  }
709
  .sidebar {
710
- max-height: 260px;
711
  border-right: none;
712
  border-bottom: 1px solid var(--border);
713
  }
714
  }
 
 
 
 
715
  </style>
716
  </head>
717
  <body>
@@ -720,65 +892,71 @@
720
  <!-- ── HEADER ──────────────────────────────────────────────────────── -->
721
  <header>
722
  <div class="logo">
723
- <div class="logo-icon">C2</div>
724
  <div class="logo-text">
725
- <h1>CodVa-2</h1>
726
- <p>213M Β· Instruction Tuned Β· SFT</p>
727
  </div>
728
  </div>
 
729
  <div class="header-stats">
730
  <div class="stat-pill">
731
  <div class="dot"></div>
732
  <span id="hdr-status">Ready</span>
733
  </div>
734
- <div class="stat-pill">⚑ <span id="hdr-tps">β€”</span> tok/s</div>
735
- <div class="stat-pill">🧠 213M params</div>
736
  </div>
737
  </header>
738
 
739
  <!-- ── SIDEBAR ─────────────────────────────────────────────────────── -->
740
  <aside class="sidebar">
741
 
742
- <!-- Context Ring -->
743
  <div class="sidebar-section">
744
  <div class="section-label">Context Window</div>
745
  <div class="ctx-ring-wrap">
746
  <div class="ctx-ring-svg">
747
- <svg viewBox="0 0 140 140">
748
- <circle class="ctx-track" cx="70" cy="70" r="55"/>
 
 
749
  <!-- Prompt arc (cyan) -->
750
- <circle class="ctx-prompt" id="ring-prompt" cx="70" cy="70" r="55"
 
751
  stroke-dasharray="345.6" stroke-dashoffset="345.6"/>
752
- <!-- Think arc (orange) -->
753
- <circle class="ctx-think" id="ring-think" cx="70" cy="70" r="55"
 
754
  stroke-dasharray="345.6" stroke-dashoffset="345.6"/>
755
- <!-- Generated arc (purple) -->
756
- <circle class="ctx-generated" id="ring-gen" cx="70" cy="70" r="55"
 
757
  stroke-dasharray="345.6" stroke-dashoffset="345.6"/>
758
  </svg>
759
  <div class="ctx-ring-center">
760
  <div class="ctx-num" id="ring-used">0</div>
761
- <div class="ctx-denom">/ 2048</div>
762
  </div>
763
  </div>
764
  <div class="ctx-legend">
765
  <div class="legend-row">
766
- <div class="legend-dot" style="background:var(--accent2)"></div>
767
  <span>Prompt</span>
768
  <span id="leg-prompt">0 tok</span>
769
  </div>
770
  <div class="legend-row">
771
- <div class="legend-dot" style="background:var(--think)"></div>
772
  <span>Thinking</span>
773
  <span id="leg-think">0 tok</span>
774
  </div>
775
  <div class="legend-row">
776
- <div class="legend-dot" style="background:var(--accent)"></div>
777
  <span>Response</span>
778
  <span id="leg-gen">0 tok</span>
779
  </div>
780
  <div class="legend-row">
781
- <div class="legend-dot" style="background:var(--surface3)"></div>
782
  <span>Free</span>
783
  <span id="leg-free">2048 tok</span>
784
  </div>
@@ -792,7 +970,7 @@
792
  <div class="think-budget">
793
  <div class="think-budget-header">
794
  <div class="think-budget-label">
795
- <span>🧠</span> Think tokens
796
  </div>
797
  <div class="think-budget-val">
798
  <span id="think-used">0</span> / <span id="think-max">512</span>
@@ -801,7 +979,7 @@
801
  <div class="think-bar-track">
802
  <div class="think-bar-fill" id="think-bar"></div>
803
  </div>
804
- <div class="think-hint">Orange = model reasoning tokens</div>
805
  </div>
806
  </div>
807
 
@@ -839,22 +1017,22 @@
839
  <div class="section-label">Examples</div>
840
  <div class="examples-list">
841
  <button class="example-btn" onclick="setPrompt('Write a Python function to compute fibonacci numbers recursively with memoization')">
842
- 🐍 Fibonacci with memoization
843
  </button>
844
  <button class="example-btn" onclick="setPrompt('Implement a binary search algorithm in Python with detailed comments')">
845
- πŸ” Binary search
846
  </button>
847
  <button class="example-btn" onclick="setPrompt('Write a quicksort implementation and explain the time complexity')">
848
- ⚑ Quicksort + complexity
849
  </button>
850
  <button class="example-btn" onclick="setPrompt('Create a Python class for a linked list with insert, delete, and search methods')">
851
- πŸ”— Linked list class
852
  </button>
853
  <button class="example-btn" onclick="setPrompt('How do I reverse a string in Python? Show multiple methods')">
854
- πŸ”„ Reverse a string
855
  </button>
856
  <button class="example-btn" onclick="setPrompt('Explain what a decorator is in Python and write an example')">
857
- 🎨 Python decorators
858
  </button>
859
  </div>
860
  </div>
@@ -866,19 +1044,19 @@
866
 
867
  <!-- Status bar -->
868
  <div class="status-bar" id="status-bar">
869
- <div class="status-item">🟒 <span class="val" id="st-state">Idle</span></div>
870
- <div class="status-item">⏱ <span class="val" id="st-time">β€”</span></div>
871
- <div class="status-item">⚑ <span class="val" id="st-tps">β€”</span> tok/s</div>
872
- <div class="status-item">πŸ”€ <span class="val" id="st-tokens">β€”</span> tokens</div>
873
- <div class="status-item">πŸ’­ <span class="val" id="st-think">no thinking</span></div>
874
  </div>
875
 
876
  <!-- Chat area -->
877
  <div class="chat-area" id="chat-area">
878
  <div class="empty-state" id="empty-state">
879
- <div class="empty-icon">🧠</div>
880
- <h2>CodVa-2 SFT</h2>
881
- <p>Instruction-tuned code assistant.<br>Ask me anything about code!</p>
882
  </div>
883
  </div>
884
 
@@ -895,6 +1073,7 @@
895
  <button class="stop-btn hidden" id="stop-btn" onclick="stopGen()" title="Stop generation">β– </button>
896
  <button class="send-btn" id="send-btn" onclick="sendMessage()" title="Send (Ctrl+Enter)">β–Ά</button>
897
  </div>
 
898
  </div>
899
 
900
  </main>
@@ -909,6 +1088,28 @@ let thinkTokens = 0;
909
  let genTokens = 0;
910
  let promptTokens = 0;
911
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
912
  // ── SLIDERS ──────────────────────────────────────────────────────────────
913
  function linkSlider(id, valId, decimals = 0) {
914
  const s = document.getElementById(id);
@@ -1046,7 +1247,7 @@ function renderAnswer(text, isStreaming) {
1046
  function copyCode(btn) {
1047
  const code = btn.closest('.code-block').querySelector('pre').textContent;
1048
  navigator.clipboard.writeText(code).then(() => {
1049
- btn.textContent = 'Copied!';
1050
  setTimeout(() => btn.textContent = 'Copy', 1500);
1051
  });
1052
  }
@@ -1069,7 +1270,7 @@ function addAssistantMsg() {
1069
  const div = document.createElement('div');
1070
  div.className = 'msg msg-assistant';
1071
  div.innerHTML = `
1072
- <div class="msg-label">CodVa-2</div>
1073
  <div class="msg-bubble" id="current-bubble">
1074
  <span class="cursor"></span>
1075
  </div>
@@ -1092,9 +1293,8 @@ function updateBubble(raw, streaming) {
1092
  html += `
1093
  <div class="think-block">
1094
  <div class="think-header" onclick="toggleThink(this)">
1095
- <span>🧠</span>
1096
- <span>Thinking${streaming && !raw.includes('</THINK>') && !raw.includes('<|/think|>') ? '...' : ''}</span>
1097
- <span>~${thinkTokEst} tokens</span>
1098
  <span class="think-chevron">β–Ό</span>
1099
  </div>
1100
  <div class="think-body">${thinkContent.replace(/</g,'&lt;').replace(/>/g,'&gt;')}</div>
@@ -1123,9 +1323,12 @@ function updateStatus(state, tps, elapsed, tokens, thinkTok) {
1123
  document.getElementById('st-time').textContent = elapsed ? elapsed + 's' : 'β€”';
1124
  document.getElementById('st-tps').textContent = tps ? tps : 'β€”';
1125
  document.getElementById('st-tokens').textContent = tokens ? tokens : 'β€”';
1126
- document.getElementById('st-think').textContent = thinkTok > 0 ? `${thinkTok} think tok` : 'no thinking';
1127
  document.getElementById('hdr-status').textContent = state;
1128
  document.getElementById('hdr-tps').textContent = tps || 'β€”';
 
 
 
1129
  }
1130
 
1131
  // ── SEND MESSAGE ──────────────────────────────────────────────────────────
@@ -1211,7 +1414,7 @@ async function sendMessage() {
1211
  }
1212
  } catch (e) {
1213
  const bubble = document.getElementById('current-bubble');
1214
- if (bubble) bubble.innerHTML = `<span style="color:var(--red)">Error: ${e.message}</span>`;
1215
  updateStatus('Error', null, null, null, 0);
1216
  }
1217
 
 
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>MiniCoder-1 Instruct Β· Inference Console</title>
7
+ <link rel="preconnect" href="https://fonts.googleapis.com">
8
+ <link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@500;600;700&family=JetBrains+Mono:wght@400;500;600;700&family=Inter:wght@400;500;600&display=swap" rel="stylesheet">
9
  <style>
10
  /* ── RESET & BASE ─────────────────────────────────────────────────── */
11
  *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
12
 
13
  :root {
14
+ /* base surfaces β€” dim instrument-panel graphite */
15
+ --bg: #0a0c0b;
16
+ --surface: #111512;
17
+ --surface2: #171d19;
18
+ --surface3: #1e2621;
19
+ --border: #253028;
20
+ --border-hi: #3a4a3f;
21
+
22
+ /* signal colors β€” three token streams, each its own channel */
23
+ --sig-prompt: #5fd0d6; /* cyan β€” prompt tokens */
24
+ --sig-think: #ffb454; /* amber β€” reasoning tokens */
25
+ --sig-gen: #8b7bff; /* violet β€” response tokens */
26
+ --sig-free: #2a352d;
27
+
28
+ --ok: #7ee787;
29
+ --danger: #ff6b6b;
30
+
31
+ --text: #e8ece6;
32
+ --text-dim: #93a099;
33
+ --text-faint: #56635b;
34
+
35
+ --radius: 10px;
36
+ --radius-sm: 6px;
37
+
38
+ --font-display: 'Space Grotesk', sans-serif;
39
+ --font-mono: 'JetBrains Mono', 'Fira Code', monospace;
40
+ --font-body: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
41
  }
42
 
43
  html, body {
44
  height: 100%;
45
  background: var(--bg);
46
  color: var(--text);
47
+ font-family: var(--font-body);
48
  font-size: 14px;
49
  line-height: 1.6;
50
  }
51
 
52
+ /* faint fixed grain / vignette β€” sets the instrument-panel mood without being loud */
53
+ body::before {
54
+ content: "";
55
+ position: fixed;
56
+ inset: 0;
57
+ pointer-events: none;
58
+ z-index: 999;
59
+ background:
60
+ radial-gradient(ellipse at 50% -10%, rgba(255,255,255,0.035), transparent 55%);
61
+ mix-blend-mode: screen;
62
+ }
63
+
64
  /* ── LAYOUT ───────────────────────────────────────────────────────── */
65
  .app {
66
  display: grid;
67
  grid-template-rows: auto 1fr;
68
+ grid-template-columns: 320px 1fr;
69
  grid-template-areas:
70
  "header header"
71
  "sidebar main";
 
78
  grid-area: header;
79
  display: flex;
80
  align-items: center;
81
+ gap: 18px;
82
+ padding: 0 22px;
83
+ height: 60px;
84
  background: var(--surface);
85
  border-bottom: 1px solid var(--border);
86
  z-index: 10;
 
89
  .logo {
90
  display: flex;
91
  align-items: center;
92
+ gap: 12px;
93
  }
94
 
95
  .logo-icon {
96
+ width: 34px;
97
+ height: 34px;
98
+ background: var(--surface3);
99
+ border: 1px solid var(--border-hi);
100
+ border-radius: var(--radius-sm);
101
  display: flex;
102
  align-items: center;
103
  justify-content: center;
104
+ font-family: var(--font-mono);
105
+ font-size: 12px;
106
+ font-weight: 700;
107
+ color: var(--sig-think);
108
+ letter-spacing: -0.5px;
109
  flex-shrink: 0;
110
+ position: relative;
111
+ }
112
+ .logo-icon::after {
113
+ content: "";
114
+ position: absolute;
115
+ inset: -1px;
116
+ border-radius: inherit;
117
+ box-shadow: 0 0 12px 0 rgba(255,180,84,0.25);
118
+ pointer-events: none;
119
  }
120
 
121
  .logo-text h1 {
122
+ font-family: var(--font-display);
123
+ font-size: 15px;
124
  font-weight: 700;
125
+ letter-spacing: 0.2px;
126
+ color: var(--text);
 
 
127
  }
128
 
129
  .logo-text p {
130
+ font-family: var(--font-mono);
131
+ font-size: 10px;
132
+ color: var(--text-faint);
133
+ letter-spacing: 0.5px;
134
+ margin-top: 1px;
135
+ }
136
+
137
+ .header-divider {
138
+ width: 1px;
139
+ height: 26px;
140
+ background: var(--border);
141
+ margin: 0 2px;
142
  }
143
 
144
  .header-stats {
145
  margin-left: auto;
146
  display: flex;
147
+ gap: 10px;
148
  align-items: center;
149
  }
150
 
 
152
  background: var(--surface2);
153
  border: 1px solid var(--border);
154
  border-radius: 20px;
155
+ padding: 5px 12px;
156
+ font-family: var(--font-mono);
157
  font-size: 11px;
158
+ color: var(--text-dim);
159
  display: flex;
160
  align-items: center;
161
+ gap: 7px;
162
+ letter-spacing: 0.2px;
163
  }
164
 
165
  .stat-pill .dot {
166
  width: 6px;
167
  height: 6px;
168
  border-radius: 50%;
169
+ background: var(--ok);
170
+ box-shadow: 0 0 6px var(--ok);
171
  animation: pulse 2s infinite;
172
  }
173
 
174
  @keyframes pulse {
175
  0%, 100% { opacity: 1; }
176
+ 50% { opacity: 0.35; }
177
  }
178
 
179
  /* ── SIDEBAR ──────────────────────────────────────────────────────── */
 
188
  }
189
 
190
  .sidebar-section {
191
+ padding: 18px 16px;
192
  border-bottom: 1px solid var(--border);
193
  }
194
 
195
  .sidebar-section:last-child { border-bottom: none; }
196
 
197
  .section-label {
198
+ font-family: var(--font-mono);
199
  font-size: 10px;
200
+ font-weight: 600;
201
+ letter-spacing: 1.4px;
202
  text-transform: uppercase;
203
+ color: var(--text-faint);
204
+ margin-bottom: 14px;
205
+ display: flex;
206
+ align-items: center;
207
+ gap: 6px;
208
+ }
209
+ .section-label::before {
210
+ content: "";
211
+ width: 3px;
212
+ height: 3px;
213
+ background: var(--text-faint);
214
+ border-radius: 50%;
215
  }
216
 
217
+ /* ── CONTEXT GAUGE (signature element) ───────────────────────────── */
218
  .ctx-ring-wrap {
219
  display: flex;
220
  flex-direction: column;
221
  align-items: center;
222
+ gap: 14px;
223
+ padding: 4px 0 2px;
224
  }
225
 
226
  .ctx-ring-svg {
227
  position: relative;
228
+ width: 152px;
229
+ height: 152px;
230
  }
231
 
232
  .ctx-ring-svg svg {
233
+ width: 152px;
234
+ height: 152px;
235
+ }
236
+
237
+ /* tick ring, decorative β€” analog gauge marks */
238
+ .ctx-ticks line {
239
+ stroke: var(--border-hi);
240
+ stroke-width: 1;
241
+ }
242
+ .ctx-ticks line.major {
243
+ stroke: var(--text-faint);
244
+ stroke-width: 1.5;
245
  }
246
 
247
  .ctx-track {
248
  fill: none;
249
  stroke: var(--surface3);
250
+ stroke-width: 8;
251
  }
252
 
253
  .ctx-prompt {
254
  fill: none;
255
+ stroke: var(--sig-prompt);
256
+ stroke-width: 8;
257
  stroke-linecap: round;
258
  transition: stroke-dashoffset 0.3s ease;
259
+ filter: drop-shadow(0 0 3px rgba(95,208,214,0.5));
260
  }
261
 
262
  .ctx-generated {
263
  fill: none;
264
+ stroke: var(--sig-gen);
265
+ stroke-width: 8;
266
  stroke-linecap: round;
267
  transition: stroke-dashoffset 0.3s ease;
268
+ filter: drop-shadow(0 0 3px rgba(139,123,255,0.5));
269
  }
270
 
271
  .ctx-think {
272
  fill: none;
273
+ stroke: var(--sig-think);
274
+ stroke-width: 8;
275
  stroke-linecap: round;
276
  transition: stroke-dashoffset 0.3s ease;
277
+ filter: drop-shadow(0 0 3px rgba(255,180,84,0.5));
278
  }
279
 
280
  .ctx-ring-center {
 
287
  }
288
 
289
  .ctx-ring-center .ctx-num {
290
+ font-family: var(--font-mono);
291
+ font-size: 24px;
292
+ font-weight: 700;
293
  color: var(--text);
294
  line-height: 1;
295
+ font-variant-numeric: tabular-nums;
296
  }
297
 
298
  .ctx-ring-center .ctx-denom {
299
+ font-family: var(--font-mono);
300
+ font-size: 10px;
301
+ color: var(--text-faint);
302
+ margin-top: 3px;
303
+ letter-spacing: 0.4px;
304
  }
305
 
306
  .ctx-legend {
307
  display: flex;
308
  flex-direction: column;
309
+ gap: 7px;
310
  width: 100%;
311
  }
312
 
 
314
  display: flex;
315
  align-items: center;
316
  gap: 8px;
317
+ font-family: var(--font-mono);
318
+ font-size: 11px;
319
+ color: var(--text-dim);
320
  }
321
 
322
  .legend-dot {
323
+ width: 8px;
324
+ height: 8px;
325
+ border-radius: 2px;
326
  flex-shrink: 0;
327
  }
328
 
329
  .legend-row span:last-child {
330
  margin-left: auto;
331
  font-variant-numeric: tabular-nums;
332
+ color: var(--text-faint);
333
  font-size: 11px;
334
  }
335
 
 
337
  .think-budget {
338
  background: var(--surface2);
339
  border: 1px solid var(--border);
340
+ border-left: 2px solid var(--sig-think);
341
  border-radius: var(--radius-sm);
342
+ padding: 11px 13px;
343
  }
344
 
345
  .think-budget-header {
346
  display: flex;
347
  justify-content: space-between;
348
  align-items: center;
349
+ margin-bottom: 9px;
 
350
  }
351
 
352
  .think-budget-label {
353
+ color: var(--sig-think);
354
+ font-family: var(--font-mono);
355
+ font-size: 11px;
356
  font-weight: 600;
357
+ letter-spacing: 0.3px;
358
  display: flex;
359
  align-items: center;
360
  gap: 6px;
361
+ text-transform: uppercase;
362
  }
363
 
364
  .think-budget-val {
365
+ color: var(--text-dim);
366
+ font-family: var(--font-mono);
367
+ font-size: 11px;
368
  font-variant-numeric: tabular-nums;
369
  }
370
 
371
  .think-bar-track {
372
+ height: 5px;
373
  background: var(--surface3);
374
  border-radius: 3px;
375
  overflow: hidden;
 
377
 
378
  .think-bar-fill {
379
  height: 100%;
380
+ background: var(--sig-think);
381
+ box-shadow: 0 0 6px rgba(255,180,84,0.6);
382
  border-radius: 3px;
383
  transition: width 0.3s ease;
384
  width: 0%;
385
  }
386
 
387
  .think-hint {
388
+ font-family: var(--font-mono);
389
  font-size: 10px;
390
+ color: var(--text-faint);
391
+ margin-top: 7px;
392
  }
393
 
394
  /* ── CONTROLS ─────────────────────────────────────────────────────── */
395
  label {
396
  display: block;
397
+ font-family: var(--font-mono);
398
+ font-size: 10px;
399
  font-weight: 600;
400
+ color: var(--text-faint);
401
+ margin-bottom: 7px;
402
  text-transform: uppercase;
403
+ letter-spacing: 0.8px;
404
  }
405
 
406
  .slider-wrap {
407
  display: flex;
408
  align-items: center;
409
  gap: 10px;
410
+ margin-bottom: 16px;
411
  }
412
 
413
  input[type=range] {
414
  flex: 1;
415
  -webkit-appearance: none;
416
+ height: 3px;
417
  border-radius: 2px;
418
  background: var(--surface3);
419
  outline: none;
 
422
 
423
  input[type=range]::-webkit-slider-thumb {
424
  -webkit-appearance: none;
425
+ width: 13px;
426
+ height: 13px;
427
+ border-radius: 3px;
428
+ background: var(--text);
429
+ border: 2px solid var(--bg);
430
+ box-shadow: 0 0 0 1px var(--border-hi);
431
  cursor: pointer;
432
+ transition: box-shadow 0.15s;
433
  }
434
 
435
  input[type=range]::-webkit-slider-thumb:hover {
436
+ box-shadow: 0 0 0 1px var(--sig-prompt), 0 0 8px rgba(95,208,214,0.5);
437
+ }
438
+
439
+ input[type=range]::-moz-range-thumb {
440
+ width: 13px;
441
+ height: 13px;
442
+ border-radius: 3px;
443
+ background: var(--text);
444
+ border: 2px solid var(--bg);
445
+ box-shadow: 0 0 0 1px var(--border-hi);
446
+ cursor: pointer;
447
  }
448
 
449
  .slider-val {
450
+ font-family: var(--font-mono);
451
+ font-size: 11px;
452
  color: var(--text);
453
  font-variant-numeric: tabular-nums;
454
+ min-width: 34px;
455
  text-align: right;
456
  font-weight: 600;
457
+ background: var(--surface2);
458
+ border: 1px solid var(--border);
459
+ border-radius: 4px;
460
+ padding: 2px 5px;
461
  }
462
 
463
  /* ── EXAMPLES ─────────────────────────────────────────────────────── */
 
471
  background: var(--surface2);
472
  border: 1px solid var(--border);
473
  border-radius: var(--radius-sm);
474
+ padding: 9px 11px;
475
+ color: var(--text-dim);
476
+ font-family: var(--font-body);
477
  font-size: 12px;
478
  cursor: pointer;
479
  text-align: left;
480
  transition: all 0.15s;
481
  line-height: 1.4;
482
+ display: flex;
483
+ align-items: center;
484
+ gap: 9px;
485
  }
486
 
487
  .example-btn:hover {
488
+ border-color: var(--sig-prompt);
489
  color: var(--text);
490
  background: var(--surface3);
491
+ transform: translateX(2px);
492
  }
493
 
494
  /* ── MAIN ─────────────────────────────────────────────────────────── */
 
499
  overflow: hidden;
500
  }
501
 
502
+ /* ── STATUS BAR ───────────────────────────────────────────────────── */
503
+ .status-bar {
504
+ display: flex;
505
+ gap: 20px;
506
+ padding: 9px 20px;
507
+ background: var(--surface);
508
+ border-bottom: 1px solid var(--border);
509
+ font-family: var(--font-mono);
510
+ font-size: 11px;
511
+ color: var(--text-faint);
512
+ font-variant-numeric: tabular-nums;
513
+ flex-wrap: wrap;
514
+ }
515
+
516
+ .status-item {
517
+ display: flex;
518
+ align-items: center;
519
+ gap: 5px;
520
+ }
521
+
522
+ .status-item .status-icon {
523
+ width: 6px;
524
+ height: 6px;
525
+ border-radius: 50%;
526
+ background: var(--text-faint);
527
+ flex-shrink: 0;
528
+ }
529
+ .status-item .status-icon.live {
530
+ background: var(--ok);
531
+ box-shadow: 0 0 5px var(--ok);
532
+ animation: pulse 1.4s infinite;
533
+ }
534
+
535
+ .status-item .val {
536
+ color: var(--text-dim);
537
+ font-weight: 600;
538
+ }
539
+
540
  /* ── CHAT AREA ────────────────────────────────────────────────────── */
541
  .chat-area {
542
  flex: 1;
543
  overflow-y: auto;
544
+ padding: 26px 28px;
545
  display: flex;
546
  flex-direction: column;
547
+ gap: 18px;
548
  }
549
 
550
  .chat-area::-webkit-scrollbar { width: 6px; }
 
553
 
554
  /* ── MESSAGES ─────────────────────────────────────────────────────── */
555
  .msg {
556
+ max-width: 800px;
557
  width: 100%;
558
  }
559
 
 
569
  border-radius: var(--radius);
570
  padding: 14px 18px;
571
  line-height: 1.7;
572
+ font-size: 13.5px;
573
  }
574
 
575
  .msg-user .msg-bubble {
576
+ background: var(--surface2);
577
+ border: 1px solid var(--border-hi);
578
+ border-right: 2px solid var(--sig-prompt);
579
+ color: var(--text);
580
  }
581
 
582
  .msg-assistant .msg-bubble {
583
  background: var(--surface);
584
  border: 1px solid var(--border);
585
+ border-left: 2px solid var(--sig-gen);
586
  }
587
 
588
  .msg-label {
589
+ font-family: var(--font-mono);
590
+ font-size: 10px;
591
+ color: var(--text-faint);
592
+ margin-bottom: 7px;
593
  font-weight: 600;
594
  text-transform: uppercase;
595
+ letter-spacing: 1px;
596
  }
597
 
598
  .msg-user .msg-label { text-align: right; }
599
 
600
  /* ── THINK BLOCK ──────────────────────────────────────────────────── */
601
  .think-block {
602
+ background: rgba(255, 180, 84, 0.05);
603
+ border: 1px solid rgba(255, 180, 84, 0.22);
604
  border-radius: var(--radius-sm);
605
  margin-bottom: 12px;
606
  overflow: hidden;
 
610
  display: flex;
611
  align-items: center;
612
  gap: 8px;
613
+ padding: 9px 12px;
614
+ background: rgba(255, 180, 84, 0.07);
615
+ border-bottom: 1px solid rgba(255, 180, 84, 0.15);
616
  cursor: pointer;
617
  user-select: none;
618
+ font-family: var(--font-mono);
619
+ font-size: 11px;
620
  font-weight: 600;
621
+ color: var(--sig-think);
622
+ letter-spacing: 0.3px;
623
+ text-transform: uppercase;
624
  }
625
 
626
+ .think-header:hover { background: rgba(255, 180, 84, 0.12); }
627
 
628
  .think-chevron {
629
  margin-left: auto;
 
636
  }
637
 
638
  .think-body {
639
+ padding: 13px 15px;
640
+ font-size: 12.5px;
641
+ color: var(--text-dim);
642
  white-space: pre-wrap;
643
+ font-family: var(--font-mono);
644
+ line-height: 1.65;
645
  max-height: 300px;
646
  overflow-y: auto;
647
  }
 
650
 
651
  /* ── CODE BLOCK ───────────────────────────────────────────────────── */
652
  .code-block {
653
+ background: #0d100e;
654
  border: 1px solid var(--border);
655
  border-radius: var(--radius-sm);
656
  overflow: hidden;
 
661
  display: flex;
662
  align-items: center;
663
  justify-content: space-between;
664
+ padding: 7px 12px;
665
  background: var(--surface3);
666
  border-bottom: 1px solid var(--border);
667
+ font-family: var(--font-mono);
668
+ font-size: 10.5px;
669
+ color: var(--text-faint);
670
+ letter-spacing: 0.3px;
671
+ text-transform: uppercase;
672
  }
673
 
674
  .copy-btn {
675
  background: none;
676
+ border: 1px solid var(--border-hi);
677
  border-radius: 4px;
678
+ padding: 2px 9px;
679
+ color: var(--text-dim);
680
+ font-family: var(--font-mono);
681
+ font-size: 10.5px;
682
  cursor: pointer;
683
  transition: all 0.15s;
684
  }
685
 
686
+ .copy-btn:hover { border-color: var(--sig-prompt); color: var(--sig-prompt); }
687
 
688
  pre {
689
+ padding: 15px;
690
  overflow-x: auto;
691
+ font-family: var(--font-mono);
692
+ font-size: 12.5px;
693
+ line-height: 1.65;
694
  color: var(--text);
695
  margin: 0;
696
  }
 
706
  display: inline-block;
707
  width: 2px;
708
  height: 1em;
709
+ background: var(--sig-gen);
710
  margin-left: 2px;
711
  vertical-align: text-bottom;
712
  animation: blink 0.8s steps(1) infinite;
 
714
 
715
  @keyframes blink { 0%, 100% { opacity: 1; } 50% { opacity: 0; } }
716
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
717
  /* ── INPUT AREA ───────────────────────────────────────────────────── */
718
  .input-area {
719
+ padding: 16px 26px 22px;
720
  background: var(--surface);
721
  border-top: 1px solid var(--border);
722
  }
 
728
  background: var(--surface2);
729
  border: 1px solid var(--border);
730
  border-radius: var(--radius);
731
+ padding: 11px 12px;
732
+ transition: border-color 0.2s, box-shadow 0.2s;
733
  }
734
 
735
  .input-wrap:focus-within {
736
+ border-color: var(--sig-prompt);
737
+ box-shadow: 0 0 0 3px rgba(95,208,214,0.08);
738
  }
739
 
740
  textarea {
 
743
  border: none;
744
  outline: none;
745
  color: var(--text);
746
+ font-size: 13.5px;
747
+ font-family: var(--font-body);
748
  line-height: 1.6;
749
  resize: none;
750
  min-height: 44px;
 
752
  overflow-y: auto;
753
  }
754
 
755
+ textarea::placeholder { color: var(--text-faint); }
756
 
757
  .send-btn {
758
  width: 40px;
759
  height: 40px;
760
  border-radius: var(--radius-sm);
761
+ border: 1px solid var(--border-hi);
762
+ background: var(--surface3);
763
+ color: var(--sig-prompt);
764
+ font-size: 15px;
765
  cursor: pointer;
766
  display: flex;
767
  align-items: center;
 
771
  }
772
 
773
  .send-btn:hover:not(:disabled) {
774
+ border-color: var(--sig-prompt);
775
+ box-shadow: 0 0 10px rgba(95,208,214,0.25);
776
  }
777
 
778
+ .send-btn:disabled { opacity: 0.4; cursor: not-allowed; }
779
 
780
  .stop-btn {
781
  width: 40px;
782
  height: 40px;
783
  border-radius: var(--radius-sm);
784
+ border: 1px solid var(--danger);
785
+ background: rgba(255, 107, 107, 0.08);
786
+ color: var(--danger);
787
+ font-size: 13px;
788
  cursor: pointer;
789
  display: flex;
790
  align-items: center;
 
794
  }
795
 
796
  .stop-btn:hover {
797
+ background: rgba(255, 107, 107, 0.18);
798
  }
799
 
800
  .stop-btn.hidden { display: none; }
801
 
802
+ .input-hint {
803
+ font-family: var(--font-mono);
804
+ font-size: 10px;
805
+ color: var(--text-faint);
806
+ margin-top: 8px;
807
+ padding-left: 2px;
808
+ }
809
+ .input-hint kbd {
810
+ font-family: var(--font-mono);
811
+ background: var(--surface2);
812
+ border: 1px solid var(--border);
813
+ border-radius: 3px;
814
+ padding: 1px 5px;
815
+ color: var(--text-dim);
816
+ }
817
+
818
  /* ── EMPTY STATE ──────────────────────────────────────────────────── */
819
  .empty-state {
820
  flex: 1;
 
822
  flex-direction: column;
823
  align-items: center;
824
  justify-content: center;
825
+ gap: 14px;
 
826
  pointer-events: none;
827
  }
828
 
829
  .empty-icon {
830
+ width: 56px;
831
+ height: 56px;
832
+ border: 1px solid var(--border-hi);
833
+ border-radius: var(--radius);
834
+ display: flex;
835
+ align-items: center;
836
+ justify-content: center;
837
+ font-family: var(--font-mono);
838
+ font-size: 20px;
839
+ font-weight: 700;
840
+ color: var(--sig-think);
841
+ background: var(--surface2);
842
  }
843
 
844
  .empty-state h2 {
845
+ font-family: var(--font-display);
846
+ font-size: 19px;
847
  font-weight: 700;
848
+ color: var(--text);
849
  }
850
 
851
  .empty-state p {
852
  font-size: 13px;
853
+ color: var(--text-faint);
854
  text-align: center;
855
  max-width: 300px;
856
+ line-height: 1.6;
857
  }
858
 
859
  /* ── SCROLLBAR ────────────────────────────────────────────────────── */
 
861
  ::-webkit-scrollbar-track { background: transparent; }
862
  ::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }
863
 
864
+ /* ── FOCUS VISIBILITY ─────────────────────────────────────────────── */
865
+ button:focus-visible, input:focus-visible, textarea:focus-visible {
866
+ outline: 2px solid var(--sig-prompt);
867
+ outline-offset: 2px;
868
+ }
869
+
870
  /* ── RESPONSIVE ───────────────────────────────────────────────────── */
871
  @media (max-width: 700px) {
872
  .app {
 
875
  grid-template-areas: "header" "sidebar" "main";
876
  }
877
  .sidebar {
878
+ max-height: 280px;
879
  border-right: none;
880
  border-bottom: 1px solid var(--border);
881
  }
882
  }
883
+
884
+ @media (prefers-reduced-motion: reduce) {
885
+ * { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; }
886
+ }
887
  </style>
888
  </head>
889
  <body>
 
892
  <!-- ── HEADER ──────────────────────────────────────────────────────── -->
893
  <header>
894
  <div class="logo">
895
+ <div class="logo-icon">M1</div>
896
  <div class="logo-text">
897
+ <h1>MiniCoder-1 Instruct</h1>
898
+ <p>213M Β· SFT Β· LOCAL INFERENCE</p>
899
  </div>
900
  </div>
901
+ <div class="header-divider"></div>
902
  <div class="header-stats">
903
  <div class="stat-pill">
904
  <div class="dot"></div>
905
  <span id="hdr-status">Ready</span>
906
  </div>
907
+ <div class="stat-pill"><span id="hdr-tps">β€”</span> tok/s</div>
908
+ <div class="stat-pill">213M params</div>
909
  </div>
910
  </header>
911
 
912
  <!-- ── SIDEBAR ─────────────────────────────────────────────────────── -->
913
  <aside class="sidebar">
914
 
915
+ <!-- Context Gauge -->
916
  <div class="sidebar-section">
917
  <div class="section-label">Context Window</div>
918
  <div class="ctx-ring-wrap">
919
  <div class="ctx-ring-svg">
920
+ <svg viewBox="0 0 152 152">
921
+ <!-- decorative tick ring -->
922
+ <g class="ctx-ticks" transform="translate(76,76)" id="ctx-ticks"></g>
923
+ <circle class="ctx-track" cx="76" cy="76" r="55" transform="rotate(-90 76 76)"/>
924
  <!-- Prompt arc (cyan) -->
925
+ <circle class="ctx-prompt" id="ring-prompt" cx="76" cy="76" r="55"
926
+ transform="rotate(-90 76 76)"
927
  stroke-dasharray="345.6" stroke-dashoffset="345.6"/>
928
+ <!-- Think arc (amber) -->
929
+ <circle class="ctx-think" id="ring-think" cx="76" cy="76" r="55"
930
+ transform="rotate(-90 76 76)"
931
  stroke-dasharray="345.6" stroke-dashoffset="345.6"/>
932
+ <!-- Generated arc (violet) -->
933
+ <circle class="ctx-generated" id="ring-gen" cx="76" cy="76" r="55"
934
+ transform="rotate(-90 76 76)"
935
  stroke-dasharray="345.6" stroke-dashoffset="345.6"/>
936
  </svg>
937
  <div class="ctx-ring-center">
938
  <div class="ctx-num" id="ring-used">0</div>
939
+ <div class="ctx-denom">/ 2048 TOK</div>
940
  </div>
941
  </div>
942
  <div class="ctx-legend">
943
  <div class="legend-row">
944
+ <div class="legend-dot" style="background:var(--sig-prompt)"></div>
945
  <span>Prompt</span>
946
  <span id="leg-prompt">0 tok</span>
947
  </div>
948
  <div class="legend-row">
949
+ <div class="legend-dot" style="background:var(--sig-think)"></div>
950
  <span>Thinking</span>
951
  <span id="leg-think">0 tok</span>
952
  </div>
953
  <div class="legend-row">
954
+ <div class="legend-dot" style="background:var(--sig-gen)"></div>
955
  <span>Response</span>
956
  <span id="leg-gen">0 tok</span>
957
  </div>
958
  <div class="legend-row">
959
+ <div class="legend-dot" style="background:var(--sig-free)"></div>
960
  <span>Free</span>
961
  <span id="leg-free">2048 tok</span>
962
  </div>
 
970
  <div class="think-budget">
971
  <div class="think-budget-header">
972
  <div class="think-budget-label">
973
+ Think tokens
974
  </div>
975
  <div class="think-budget-val">
976
  <span id="think-used">0</span> / <span id="think-max">512</span>
 
979
  <div class="think-bar-track">
980
  <div class="think-bar-fill" id="think-bar"></div>
981
  </div>
982
+ <div class="think-hint">Amber = model reasoning tokens</div>
983
  </div>
984
  </div>
985
 
 
1017
  <div class="section-label">Examples</div>
1018
  <div class="examples-list">
1019
  <button class="example-btn" onclick="setPrompt('Write a Python function to compute fibonacci numbers recursively with memoization')">
1020
+ <span>🐍</span> Fibonacci with memoization
1021
  </button>
1022
  <button class="example-btn" onclick="setPrompt('Implement a binary search algorithm in Python with detailed comments')">
1023
+ <span>πŸ”</span> Binary search
1024
  </button>
1025
  <button class="example-btn" onclick="setPrompt('Write a quicksort implementation and explain the time complexity')">
1026
+ <span>⚑</span> Quicksort + complexity
1027
  </button>
1028
  <button class="example-btn" onclick="setPrompt('Create a Python class for a linked list with insert, delete, and search methods')">
1029
+ <span>πŸ”—</span> Linked list class
1030
  </button>
1031
  <button class="example-btn" onclick="setPrompt('How do I reverse a string in Python? Show multiple methods')">
1032
+ <span>πŸ”„</span> Reverse a string
1033
  </button>
1034
  <button class="example-btn" onclick="setPrompt('Explain what a decorator is in Python and write an example')">
1035
+ <span>🎨</span> Python decorators
1036
  </button>
1037
  </div>
1038
  </div>
 
1044
 
1045
  <!-- Status bar -->
1046
  <div class="status-bar" id="status-bar">
1047
+ <div class="status-item"><span class="status-icon" id="st-icon"></span><span class="val" id="st-state">Idle</span></div>
1048
+ <div class="status-item">TIME <span class="val" id="st-time">β€”</span></div>
1049
+ <div class="status-item">SPEED <span class="val" id="st-tps">β€”</span> tok/s</div>
1050
+ <div class="status-item">TOKENS <span class="val" id="st-tokens">β€”</span></div>
1051
+ <div class="status-item">THINK <span class="val" id="st-think">no thinking</span></div>
1052
  </div>
1053
 
1054
  <!-- Chat area -->
1055
  <div class="chat-area" id="chat-area">
1056
  <div class="empty-state" id="empty-state">
1057
+ <div class="empty-icon">M1</div>
1058
+ <h2>MiniCoder-1 Instruct</h2>
1059
+ <p>Instruction-tuned code assistant. Ask for code, an explanation, or a debug pass.</p>
1060
  </div>
1061
  </div>
1062
 
 
1073
  <button class="stop-btn hidden" id="stop-btn" onclick="stopGen()" title="Stop generation">β– </button>
1074
  <button class="send-btn" id="send-btn" onclick="sendMessage()" title="Send (Ctrl+Enter)">β–Ά</button>
1075
  </div>
1076
+ <div class="input-hint"><kbd>Ctrl</kbd> + <kbd>Enter</kbd> to send</div>
1077
  </div>
1078
 
1079
  </main>
 
1088
  let genTokens = 0;
1089
  let promptTokens = 0;
1090
 
1091
+ // ── DECORATIVE TICK RING (signature gauge marks) ──────────────────────────
1092
+ (function drawTicks() {
1093
+ const g = document.getElementById('ctx-ticks');
1094
+ const rOuter = 68, rInnerMinor = 62, rInnerMajor = 59;
1095
+ const count = 40;
1096
+ let svgNS = "http://www.w3.org/2000/svg";
1097
+ for (let i = 0; i < count; i++) {
1098
+ const angle = (i / count) * 2 * Math.PI - Math.PI / 2;
1099
+ const major = i % 5 === 0;
1100
+ const rInner = major ? rInnerMajor : rInnerMinor;
1101
+ const x1 = Math.cos(angle) * rOuter, y1 = Math.sin(angle) * rOuter;
1102
+ const x2 = Math.cos(angle) * rInner, y2 = Math.sin(angle) * rInner;
1103
+ const line = document.createElementNS(svgNS, 'line');
1104
+ line.setAttribute('x1', x1.toFixed(2));
1105
+ line.setAttribute('y1', y1.toFixed(2));
1106
+ line.setAttribute('x2', x2.toFixed(2));
1107
+ line.setAttribute('y2', y2.toFixed(2));
1108
+ if (major) line.setAttribute('class', 'major');
1109
+ g.appendChild(line);
1110
+ }
1111
+ })();
1112
+
1113
  // ── SLIDERS ──────────────────────────────────────────────────────────────
1114
  function linkSlider(id, valId, decimals = 0) {
1115
  const s = document.getElementById(id);
 
1247
  function copyCode(btn) {
1248
  const code = btn.closest('.code-block').querySelector('pre').textContent;
1249
  navigator.clipboard.writeText(code).then(() => {
1250
+ btn.textContent = 'Copied';
1251
  setTimeout(() => btn.textContent = 'Copy', 1500);
1252
  });
1253
  }
 
1270
  const div = document.createElement('div');
1271
  div.className = 'msg msg-assistant';
1272
  div.innerHTML = `
1273
+ <div class="msg-label">MiniCoder-1</div>
1274
  <div class="msg-bubble" id="current-bubble">
1275
  <span class="cursor"></span>
1276
  </div>
 
1293
  html += `
1294
  <div class="think-block">
1295
  <div class="think-header" onclick="toggleThink(this)">
1296
+ <span>Reasoning${streaming && !raw.includes('</THINK>') && !raw.includes('<|/think|>') ? '...' : ''}</span>
1297
+ <span>~${thinkTokEst} tok</span>
 
1298
  <span class="think-chevron">β–Ό</span>
1299
  </div>
1300
  <div class="think-body">${thinkContent.replace(/</g,'&lt;').replace(/>/g,'&gt;')}</div>
 
1323
  document.getElementById('st-time').textContent = elapsed ? elapsed + 's' : 'β€”';
1324
  document.getElementById('st-tps').textContent = tps ? tps : 'β€”';
1325
  document.getElementById('st-tokens').textContent = tokens ? tokens : 'β€”';
1326
+ document.getElementById('st-think').textContent = thinkTok > 0 ? `${thinkTok} tok` : 'no thinking';
1327
  document.getElementById('hdr-status').textContent = state;
1328
  document.getElementById('hdr-tps').textContent = tps || 'β€”';
1329
+
1330
+ const icon = document.getElementById('st-icon');
1331
+ icon.classList.toggle('live', state === 'Generating...');
1332
  }
1333
 
1334
  // ── SEND MESSAGE ──────────────────────────────────────────────────────────
 
1414
  }
1415
  } catch (e) {
1416
  const bubble = document.getElementById('current-bubble');
1417
+ if (bubble) bubble.innerHTML = `<span style="color:var(--danger)">Error: ${e.message}</span>`;
1418
  updateStatus('Error', null, null, null, 0);
1419
  }
1420