File size: 79,263 Bytes
a3c06dc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5957d6c
 
 
a3c06dc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
615bf9f
a3c06dc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
615bf9f
a3c06dc
 
615bf9f
 
a3c06dc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5957d6c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>FMN-GPT | CompactAI</title>
    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
    <style>
/* FMN-GPT Website Styles */
:root {
    --color-bg: #faf8f5;
    --color-bg-alt: #f5f0e8;
    --color-bg-dark: #1a1815;
    --color-bg-dark-alt: #252220;
    --color-accent: #e85d3b;
    --color-accent-light: #ff8a6b;
    --color-accent-dark: #c44a2d;
    --color-secondary: #d4a853;
    --color-secondary-light: #e8c87a;
    --color-text: #2d2a26;
    --color-text-light: #6b6560;
    --color-text-muted: #9a948d;
    --color-border: #e5e0d8;
    --color-border-dark: #3d3a36;
    --gradient-warm: linear-gradient(135deg, #e85d3b 0%, #d4a853 100%);
    --gradient-dark: linear-gradient(135deg, #1a1815 0%, #2d2a26 100%);
    --shadow-sm: 0 2px 8px rgba(45, 42, 38, 0.08);
    --shadow-md: 0 4px 20px rgba(45, 42, 38, 0.12);
    --shadow-lg: 0 8px 40px rgba(45, 42, 38, 0.16);
    --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
    --font-mono: 'JetBrains Mono', 'Fira Code', monospace;
    --container-max: 1200px;
    --section-padding: 100px;
}
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; font-size: 16px; }
html, body { height: 100%; }
body { font-family: var(--font-sans); background-color: var(--color-bg); color: var(--color-text); line-height: 1.7; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; display: flex; flex-direction: column; min-height: 100vh; }
main { flex: 1; }
.container { max-width: var(--container-max); margin: 0 auto; padding: 0 24px; }
h1, h2, h3, h4, h5, h6 { font-weight: 600; line-height: 1.2; color: var(--color-text); }
h1 { font-size: clamp(2.5rem, 6vw, 4.5rem); }
h2 { font-size: clamp(2rem, 4vw, 3rem); }
h3 { font-size: clamp(1.5rem, 3vw, 2rem); }
h4 { font-size: 1.25rem; }
p { margin-bottom: 1.5rem; color: var(--color-text-light); }
a { color: var(--color-accent); text-decoration: none; transition: color 0.2s ease; }
a:hover { color: var(--color-accent-dark); }
code { font-family: var(--font-mono); background: var(--color-bg-alt); padding: 0.2em 0.5em; border-radius: 4px; font-size: 0.9em; color: var(--color-accent-dark); }
pre { font-family: var(--font-mono); background: var(--color-bg-dark); color: #f5f0e8; padding: 1.5rem; border-radius: 12px; overflow-x: auto; font-size: 0.875rem; line-height: 1.6; }
pre code { background: none; padding: 0; color: inherit; }
blockquote { border-left: 4px solid var(--color-accent); padding-left: 1.5rem; margin: 2rem 0; font-style: italic; font-size: 1.25rem; color: var(--color-text); }
.section-title { text-align: center; margin-bottom: 1rem; position: relative; }
.section-title::after { content: ''; display: block; width: 60px; height: 4px; background: var(--gradient-warm); margin: 1rem auto 0; border-radius: 2px; }
.section-subtitle { text-align: center; color: var(--color-text-muted); font-size: 1.125rem; margin-bottom: 3rem; }
.hero { min-height: 100vh; display: flex; align-items: center; justify-content: center; position: relative; background: var(--color-bg-dark); overflow: hidden; }
.hero-content { text-align: center; z-index: 2; padding: 2rem; }
.apology-badge { display: inline-block; background: rgba(232, 93, 59, 0.15); color: var(--color-accent-light); padding: 0.5rem 1.25rem; border-radius: 50px; font-size: 0.875rem; font-weight: 500; margin-bottom: 2rem; border: 1px solid rgba(232, 93, 59, 0.3); }
.hero-title { color: #fff; margin-bottom: 1.5rem; letter-spacing: -0.02em; }
.hero-title .highlight { background: var(--gradient-warm); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; }
.hero-subtitle { color: var(--color-text-muted); font-size: 1.25rem; max-width: 500px; margin: 0 auto 3rem; }
.scroll-indicator { position: absolute; bottom: 3rem; left: 50%; transform: translateX(-50%); text-align: center; color: var(--color-text-muted); font-size: 0.875rem; }
.scroll-arrow { width: 24px; height: 24px; margin: 0.5rem auto 0; border-right: 2px solid var(--color-accent); border-bottom: 2px solid var(--color-accent); transform: rotate(45deg); animation: scrollBounce 2s infinite; }
@keyframes scrollBounce { 0%, 100% { transform: rotate(45deg) translateY(0); } 50% { transform: rotate(45deg) translateY(8px); } }
.hero-visual { position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 1; opacity: 0.4; }
#neuron-canvas { width: 100%; height: 100%; }
.preface { padding: calc(var(--section-padding) + 4rem) 0 var(--section-padding); background: var(--color-bg); }
.preface-content { max-width: 800px; margin: 0 auto; font-size: 1.125rem; }
.preface-content .drop-cap::first-letter { float: left; font-size: 4rem; line-height: 0.8; padding-right: 0.75rem; color: var(--color-accent); font-weight: 700; }
.confession { padding: var(--section-padding) 0; background: var(--color-bg); }
.confession-content { max-width: 800px; margin: 0 auto; }
.confession-text { font-size: 1.125rem; }
.confession-text .drop-cap::first-letter { float: left; font-size: 4rem; line-height: 0.8; padding-right: 0.75rem; color: var(--color-accent); font-weight: 700; }
.big-question { display: flex; align-items: flex-start; gap: 1rem; background: var(--color-bg-alt); padding: 2rem; border-radius: 16px; margin-top: 2rem; border-left: 4px solid var(--color-accent); }
.big-question .question-mark { font-size: 3rem; font-weight: 700; color: var(--color-accent); line-height: 1; }
.big-question p { font-size: 1.25rem; font-weight: 500; color: var(--color-text); margin: 0; align-self: center; }
.what-building { padding: var(--section-padding) 0; background: var(--color-bg-alt); }
.feature-grid { display: grid; gap: 2rem; margin-bottom: 4rem; }
.feature-card { background: var(--color-bg); border-radius: 20px; padding: 2.5rem; box-shadow: var(--shadow-md); }
.main-feature { text-align: center; }
.feature-icon { width: 100px; height: 100px; margin: 0 auto 1.5rem; }
.neuron-icon { width: 100%; height: 100%; }
.neuron-node { fill: var(--color-accent); opacity: 0.9; }
.neuron-connection { stroke: var(--color-secondary); stroke-width: 2; fill: none; }
.feature-card h3 { font-size: 2rem; margin-bottom: 0.5rem; color: var(--color-accent); }
.feature-subtitle { color: var(--color-text-muted); font-size: 1rem; margin-bottom: 1rem; }
.feature-stats { display: flex; justify-content: center; gap: 3rem; margin-top: 2rem; padding-top: 2rem; border-top: 1px solid var(--color-border); }
.stat { text-align: center; }
.stat-value { display: block; font-size: 2rem; font-weight: 700; color: var(--color-text); }
.stat-label { font-size: 0.875rem; color: var(--color-text-muted); }
.architecture-section { margin-top: 4rem; }
.architecture-section h3 { text-align: center; margin-bottom: 2rem; }
.architecture-diagram { max-width: 600px; margin: 0 auto; padding: 2rem; background: var(--color-bg); border-radius: 20px; box-shadow: var(--shadow-md); }
.arch-layer { display: flex; justify-content: center; }
.layer-box { padding: 1.5rem 2rem; border-radius: 12px; text-align: center; font-weight: 500; }
.input-layer { background: linear-gradient(135deg, #4a9eff 0%, #6bb3ff 100%); color: white; }
.recursive-layer { background: var(--color-accent); color: white; padding: 2rem; }
.output-layer { background: linear-gradient(135deg, #50c878 0%, #7dd8a0 100%); color: white; }
.layer-details { margin-top: 1rem; font-size: 0.875rem; font-weight: 400; opacity: 0.9; }
.detail-item { display: flex; justify-content: space-between; padding: 0.5rem 0; border-top: 1px solid rgba(255,255,255,0.2); }
.arch-arrow { text-align: center; font-size: 1.5rem; color: var(--color-text-muted); padding: 0.5rem 0; }
.loop-arrow { color: var(--color-accent); font-size: 0.875rem; }
.how-it-works { padding: var(--section-padding) 0; background: var(--color-bg); }
.mechanism-tabs { display: flex; justify-content: center; gap: 0.5rem; flex-wrap: wrap; margin-bottom: 3rem; }
.tab-btn { padding: 0.75rem 1.5rem; border: 2px solid var(--color-border); background: transparent; border-radius: 50px; font-family: var(--font-sans); font-size: 0.9375rem; font-weight: 500; color: var(--color-text-light); cursor: pointer; transition: all 0.2s ease; }
.tab-btn:hover { border-color: var(--color-accent); color: var(--color-accent); }
.tab-btn.active { background: var(--color-accent); border-color: var(--color-accent); color: white; }
.tab-content { max-width: 1000px; margin: 0 auto; }
.tab-pane { display: none; animation: fadeIn 0.3s ease; }
.tab-pane.active { display: block; }
@keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
.pane-content { display: grid; grid-template-columns: 1fr 1fr; gap: 3rem; align-items: start; }
@media (max-width: 768px) { .pane-content { grid-template-columns: 1fr; } }
.pane-text h3 { margin-bottom: 1rem; color: var(--color-accent); }
.equation { background: var(--color-bg-alt); padding: 1rem 1.5rem; border-radius: 8px; margin: 1rem 0; border-left: 3px solid var(--color-secondary); }
.equation code { background: none; padding: 0; font-size: 1rem; color: var(--color-text); }
.equation.small code { font-size: 0.875rem; }
.feature-list { list-style: none; padding: 0; }
.feature-list li { padding: 0.5rem 0; padding-left: 1.5rem; position: relative; color: var(--color-text-light); }
.feature-list li::before { content: '→'; position: absolute; left: 0; color: var(--color-accent); }
.feature-list li.classified::before { content: '█'; color: var(--color-text-muted); }
.classified { color: var(--color-text-muted); font-family: 'JetBrains Mono', monospace; background: repeating-linear-gradient(90deg, var(--color-border) 0px, var(--color-border) 8px, transparent 8px, transparent 12px); background-size: 100% 4px; background-position: 0 50%; background-repeat: repeat-x; }
.equation.redacted { border-left-color: var(--color-text-muted); background: linear-gradient(135deg, var(--color-bg-alt) 0%, rgba(154, 148, 141, 0.1) 100%); }
.equation.redacted code { color: var(--color-text-muted); text-transform: uppercase; letter-spacing: 0.1em; font-size: 0.875rem; }
.pane-visual { background: var(--color-bg-alt); border-radius: 16px; padding: 1.5rem; display: flex; align-items: center; justify-content: center; min-height: 300px; }
.pane-visual canvas { max-width: 100%; height: auto; }
.loop-demo { margin-top: 1.5rem; padding: 1.5rem; background: var(--color-bg-alt); border-radius: 12px; }
.loop-demo label { display: block; margin-bottom: 0.5rem; font-weight: 500; }
.loop-demo input[type="range"] { width: 100%; margin-bottom: 1rem; accent-color: var(--color-accent); }
.loop-indicator { display: flex; gap: 4px; flex-wrap: wrap; }
.loop-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--color-border); transition: background 0.2s ease; }
.loop-dot.active { background: var(--color-accent); }
.loop-dot.exhausted { background: var(--color-text-muted); }
.demo-section { padding: var(--section-padding) 0; background: var(--color-bg-dark); color: white; }
.demo-section .section-title { color: white; }
.demo-section .section-title::after { background: var(--gradient-warm); }
.demo-section .section-subtitle { color: var(--color-text-muted); }
.demo-container { max-width: 1000px; margin: 0 auto; }
.demo-controls { display: flex; justify-content: center; gap: 1rem; flex-wrap: wrap; margin-bottom: 2rem; }
.demo-btn { padding: 0.75rem 1.5rem; border: none; border-radius: 8px; font-family: var(--font-sans); font-size: 1rem; font-weight: 500; cursor: pointer; transition: all 0.2s ease; }
.demo-btn:first-child { background: var(--color-accent); color: white; }
.demo-btn:first-child:hover { background: var(--color-accent-dark); }
.demo-btn:nth-child(2) { background: var(--color-bg-dark-alt); color: white; border: 1px solid var(--color-border-dark); }
.demo-btn:nth-child(2):hover { background: var(--color-border-dark); }
.speed-control { display: flex; align-items: center; gap: 0.75rem; color: var(--color-text-muted); }
.speed-control input[type="range"] { width: 100px; accent-color: var(--color-accent); }
.demo-visual { background: var(--color-bg-dark-alt); border-radius: 16px; padding: 2rem; margin-bottom: 2rem; min-height: 400px; display: flex; align-items: center; justify-content: center; }
#demo-canvas { width: 100%; max-width: 800px; height: 350px; }
.demo-info { display: flex; justify-content: center; }
.info-panel { background: var(--color-bg-dark-alt); border: 1px solid var(--color-border-dark); border-radius: 12px; padding: 1.5rem 2rem; min-width: 250px; }
.info-panel h4 { color: var(--color-accent); margin-bottom: 1rem; font-size: 0.875rem; text-transform: uppercase; letter-spacing: 0.05em; }
.info-row { display: flex; justify-content: space-between; padding: 0.5rem 0; border-bottom: 1px solid var(--color-border-dark); }
.info-row:last-child { border-bottom: none; }
.info-row span:first-child { color: var(--color-text-muted); }
.info-row span:last-child { color: white; font-weight: 500; font-family: var(--font-mono); }
.why-stopped { padding: var(--section-padding) 0; background: var(--color-bg); }
.reasons-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 2rem; margin-bottom: 4rem; }
.reason-card { background: var(--color-bg-alt); border-radius: 16px; padding: 2rem; position: relative; }
.reason-number { font-size: 3rem; font-weight: 700; color: var(--color-border); position: absolute; top: 1rem; right: 1.5rem; line-height: 1; z-index: 1; }
.reason-card h3 { margin-bottom: 1rem; color: var(--color-accent); position: relative; z-index: 2; }
.reason-card p { margin: 0; font-size: 0.9375rem; position: relative; z-index: 2; }
.comparison-section { margin-top: 4rem; }
.comparison-section h3 { text-align: center; margin-bottom: 2rem; }
.comparison-grid { display: flex; justify-content: center; align-items: center; gap: 2rem; flex-wrap: wrap; }
.comparison-item { background: var(--color-bg-alt); border-radius: 16px; padding: 2rem; max-width: 350px; flex: 1; }
.comparison-item h4 { margin-bottom: 1rem; font-size: 1.25rem; }
.comparison-item.old h4 { color: var(--color-text-muted); }
.comparison-item.new { border: 2px solid var(--color-accent); }
.comparison-item.new h4 { color: var(--color-accent); }
.comparison-item ul { list-style: none; padding: 0; }
.comparison-item li { padding: 0.5rem 0; border-bottom: 1px solid var(--color-border); color: var(--color-text-light); }
.comparison-item li:last-child { border-bottom: none; }
.comparison-arrow { font-size: 2rem; color: var(--color-accent); }
.technical { padding: var(--section-padding) 0; background: var(--color-bg-alt); }
.tech-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 2rem; }
.tech-card { background: var(--color-bg); border-radius: 16px; padding: 1.5rem; box-shadow: var(--shadow-sm); }
.tech-card h4 { color: var(--color-accent); margin-bottom: 1rem; padding-bottom: 0.75rem; border-bottom: 2px solid var(--color-border); }
.tech-list { list-style: none; padding: 0; }
.tech-list li { padding: 0.75rem 0; border-bottom: 1px solid var(--color-border); font-size: 0.9375rem; color: var(--color-text-light); }
.tech-list li:last-child { border-bottom: none; }
.tech-list strong { color: var(--color-text); }
.closing { padding: var(--section-padding) 0; background: var(--color-bg); }
.closing-content { max-width: 800px; margin: 0 auto; text-align: center; }
.closing-content h2 { margin-bottom: 1.5rem; }
.closing-content > p { font-size: 1.125rem; max-width: 600px; margin: 0 auto 2rem; }
.closing-quote { margin: 3rem 0; }
.closing-quote blockquote { border: none; padding: 0; font-size: 1.5rem; max-width: 500px; margin: 0 auto; position: relative; }
.closing-quote blockquote::before { content: '"'; position: absolute; top: -1rem; left: -1rem; font-size: 4rem; color: var(--color-accent); opacity: 0.3; font-family: Georgia, serif; }
.cta-section p { color: var(--color-text-muted); }
.poem-section { margin: 4rem 0; padding: 2rem; background: var(--color-bg-alt); border-radius: 16px; }
.poem-intro { font-size: 0.875rem; color: var(--color-text-muted); margin-bottom: 1rem; letter-spacing: 0.15em; text-transform: uppercase; }
.poem { font-family: Georgia, serif; font-style: italic; color: var(--color-text); line-height: 2; }
.poem p { margin: 0; font-size: 1.125rem; }
.poem p:last-child { color: var(--color-accent); }
.footer { padding: 3rem 0; background: var(--color-bg-dark); text-align: center; }
.footer-text { color: white; font-size: 1.125rem; margin-bottom: 0.5rem; }
.footer-subtext { color: var(--color-text-muted); font-size: 0.875rem; margin: 0; }
@media (max-width: 768px) { :root { --section-padding: 60px; } .feature-stats { flex-direction: column; gap: 1.5rem; } .comparison-arrow { transform: rotate(90deg); } .mechanism-tabs { gap: 0.25rem; } .tab-btn { padding: 0.5rem 1rem; font-size: 0.875rem; } }
@media (max-width: 480px) { .hero-title { font-size: 2rem; } .big-question { flex-direction: column; text-align: center; } .reason-number { position: static; margin-bottom: 1rem; } }
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } }
@keyframes float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-10px); } }
.animate-pulse { animation: pulse 2s infinite; }
.animate-float { animation: float 3s ease-in-out infinite; }
.fade-in-up { opacity: 0; transform: translateY(30px); transition: opacity 0.6s ease, transform 0.6s ease; }
.fade-in-up.visible { opacity: 1; transform: translateY(0); }
.main-nav { position: fixed; top: 0; left: 0; right: 0; background: rgba(26, 24, 21, 0.95); backdrop-filter: blur(10px); z-index: 1000; padding: 1rem 0; }
.main-nav .container { display: flex; justify-content: space-between; align-items: center; }
.nav-brand { color: white; font-size: 1.25rem; font-weight: 600; text-decoration: none; }
.nav-links { display: flex; gap: 2rem; }
.nav-links a { color: var(--color-text-muted); text-decoration: none; font-size: 0.9375rem; transition: color 0.2s ease; }
.nav-links a:hover { color: var(--color-accent); }
.elief-section { padding: var(--section-padding) 0; background: var(--color-bg); }
.elief-content { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 2rem; max-width: 1000px; margin: 0 auto; }
.elief-card { background: var(--color-bg-alt); border-radius: 16px; padding: 2rem; }
.elief-card h3 { color: var(--color-accent); margin-bottom: 1rem; font-size: 1.25rem; }
.elief-card p { color: var(--color-text-light); margin: 0; line-height: 1.7; }
.demo-chat { background: var(--color-bg-dark-alt); border-radius: 16px; padding: 2rem; margin-bottom: 2rem; max-width: 700px; margin-left: auto; margin-right: auto; }
.chat-message { margin-bottom: 1.5rem; }
.chat-message:last-child { margin-bottom: 0; }
.chat-role { display: block; font-weight: 600; margin-bottom: 0.5rem; font-size: 0.875rem; text-transform: uppercase; letter-spacing: 0.05em; }
.user-message .chat-role { color: var(--color-info); }
.assistant-message .chat-role { color: var(--color-accent); }
.chat-text { color: white; font-size: 1.125rem; }
.chat-thinking { background: rgba(232, 93, 59, 0.1); border-left: 3px solid var(--color-accent); padding: 1rem 1.5rem; margin-bottom: 1rem; border-radius: 0 8px 8px 0; }
.thinking-line { color: var(--color-text-muted); font-size: 0.9375rem; padding: 0.25rem 0; opacity: 0; transition: opacity 0.3s ease; }
.thinking-line.visible { opacity: 1; }
.thinking-line.active { color: var(--color-accent-light); }
.demo-visual { background: var(--color-bg-dark-alt); border-radius: 16px; padding: 2rem; margin-bottom: 2rem; min-height: 500px; display: flex; align-items: center; justify-content: center; }
#demo-canvas { width: 100%; max-width: 900px; height: 450px; }
.demo-info { display: flex; justify-content: center; gap: 2rem; flex-wrap: wrap; }
.tokenization-panel { background: var(--color-bg-dark-alt); border: 1px solid var(--color-border-dark); border-radius: 12px; padding: 1.5rem 2rem; min-width: 250px; }
.tokenization-panel h4 { color: var(--color-accent); margin-bottom: 1rem; font-size: 0.875rem; text-transform: uppercase; letter-spacing: 0.05em; }
.token-display { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 0.75rem; }
.token { background: var(--color-bg-dark); color: var(--color-accent-light); padding: 0.25rem 0.5rem; border-radius: 4px; font-family: var(--font-mono); font-size: 0.875rem; border: 1px solid var(--color-border-dark); }
.token.space { width: 0.5rem; }
.token.active { background: var(--color-accent); color: white; border-color: var(--color-accent); }
.tokenization-note { font-size: 0.75rem; color: var(--color-text-muted); margin: 0; }
.cot-display { background: rgba(232, 93, 59, 0.1); border-left: 3px solid var(--color-accent); padding: 0.75rem 1rem; margin-bottom: 0.75rem; border-radius: 0 6px 6px 0; }
.cot-line { color: var(--color-accent-light); font-size: 0.875rem; font-family: var(--font-mono); padding: 0.15rem 0; opacity: 0; transition: opacity 0.3s ease; }
.blog-empty { text-align: center; padding: 4rem 2rem; color: var(--color-text-muted); }
.blog-empty p { margin: 0; font-size: 1.125rem; }
.roadmap-section { padding: var(--section-padding) 0; background: var(--color-bg-alt); }
.roadmap-timeline { max-width: 700px; margin: 0 auto; position: relative; }
.roadmap-timeline::before { content: ''; position: absolute; left: 20px; top: 0; bottom: 0; width: 2px; background: var(--color-border); }
.roadmap-item { display: flex; gap: 2rem; padding: 1.5rem 0; position: relative; }
.roadmap-marker { width: 42px; height: 42px; border-radius: 50%; background: var(--color-bg); border: 3px solid var(--color-border); flex-shrink: 0; position: relative; z-index: 1; }
.roadmap-item.completed .roadmap-marker { background: var(--color-accent); border-color: var(--color-accent); }
.roadmap-item.completed .roadmap-marker::after { content: ''; position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); width: 12px; height: 12px; background: white; border-radius: 50%; }
.roadmap-item.in-progress .roadmap-marker { border-color: var(--color-accent); animation: pulse 2s infinite; }
.roadmap-content { flex: 1; }
.roadmap-content h4 { margin-bottom: 0.5rem; color: var(--color-text); }
.roadmap-content p { color: var(--color-text-light); margin-bottom: 0.5rem; }
.roadmap-status { display: inline-block; font-size: 0.75rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; padding: 0.25rem 0.75rem; border-radius: 50px; background: var(--color-bg); color: var(--color-text-muted); }
.roadmap-item.completed .roadmap-status { background: rgba(80, 200, 120, 0.15); color: var(--color-success); }
.roadmap-item.in-progress .roadmap-status { background: rgba(232, 93, 59, 0.15); color: var(--color-accent); }
.credits-section { padding: var(--section-padding) 0; background: var(--color-bg); }
.credits-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 2rem; max-width: 1000px; margin: 0 auto; }
.credit-card { background: var(--color-bg-alt); border-radius: 16px; padding: 1.5rem; }
.credit-card h4 { color: var(--color-text-muted); font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 0.5rem; }
.credit-name { font-family: var(--font-mono); font-size: 0.9375rem; color: var(--color-accent); margin-bottom: 0.75rem; }
.credit-card p:not(.credit-name) { color: var(--color-text-light); font-size: 0.9375rem; margin-bottom: 1rem; }
.credit-card a { font-size: 0.875rem; font-weight: 500; }
.page-header { padding: 8rem 0 4rem; background: var(--color-bg-dark); text-align: center; }
.page-header h1 { color: white; margin-bottom: 0.5rem; }
.page-header p { color: var(--color-text-muted); font-size: 1.125rem; margin: 0; }
.blog-section { padding: var(--section-padding) 0; background: var(--color-bg); }
.blog-list { max-width: 800px; margin: 0 auto; }
.blog-card { background: var(--color-bg-alt); border-radius: 16px; padding: 2rem; margin-bottom: 1.5rem; cursor: pointer; transition: transform 0.2s ease, box-shadow 0.2s ease; display: block; text-decoration: none; }
.blog-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
.blog-meta { display: flex; gap: 1rem; margin-bottom: 1rem; }
.blog-date { color: var(--color-text-muted); font-size: 0.875rem; }
.blog-tag { background: rgba(232, 93, 59, 0.1); color: var(--color-accent); font-size: 0.75rem; font-weight: 600; padding: 0.25rem 0.75rem; border-radius: 50px; text-transform: uppercase; letter-spacing: 0.05em; }
.blog-card h2 { font-size: 1.5rem; margin-bottom: 0.75rem; }
.blog-card h2 a { color: var(--color-text); text-decoration: none; }
.blog-card h2 a:hover { color: var(--color-accent); }
.blog-card p { color: var(--color-text-light); margin-bottom: 1rem; }
.blog-read-more { color: var(--color-accent); font-weight: 500; font-size: 0.9375rem; }
.status-section { padding: var(--section-padding) 0; background: var(--color-bg); }
.status-overview { max-width: 600px; margin: 0 auto 4rem; }
.status-card { background: var(--color-bg-alt); border-radius: 20px; padding: 2rem; text-align: center; }
.status-card h3 { font-size: 1.5rem; margin-bottom: 1rem; }
.status-badge { display: inline-block; font-size: 0.75rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; padding: 0.5rem 1rem; border-radius: 50px; margin-bottom: 1.5rem; }
.status-badge.in-progress { background: rgba(232, 93, 59, 0.15); color: var(--color-accent); }
.status-badge.complete { background: rgba(80, 200, 120, 0.15); color: var(--color-success); }
.status-details { text-align: left; }
.status-row { display: flex; justify-content: space-between; padding: 0.75rem 0; border-bottom: 1px solid var(--color-border); }
.status-row:last-child { border-bottom: none; }
.status-row span:first-child { color: var(--color-text-muted); }
.status-row span:last-child { font-weight: 500; }
.training-log { max-width: 700px; margin: 0 auto 4rem; }
.training-log h3 { margin-bottom: 1.5rem; text-align: center; }
.log-entries { background: var(--color-bg-alt); border-radius: 16px; padding: 1.5rem; }
.log-entry { padding: 1rem 0; border-bottom: 1px solid var(--color-border); }
.log-entry:last-child { border-bottom: none; }
.log-date { color: var(--color-text-muted); font-size: 0.875rem; margin-right: 0.75rem; }
.log-status { font-size: 0.75rem; font-weight: 600; padding: 0.125rem 0.5rem; border-radius: 50px; background: rgba(80, 200, 120, 0.15); color: var(--color-success); }
.log-status.active { background: rgba(232, 93, 59, 0.15); color: var(--color-accent); }
.log-entry p { margin: 0.5rem 0 0; color: var(--color-text-light); font-size: 0.9375rem; }
.metrics-section { max-width: 900px; margin: 0 auto 4rem; }
.metrics-section h3 { text-align: center; margin-bottom: 2rem; }
.metrics-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 1.5rem; }
.metric-card { background: var(--color-bg-alt); border-radius: 12px; padding: 1.5rem; text-align: center; }
.metric-value { font-size: 2rem; font-weight: 700; color: var(--color-accent); margin-bottom: 0.25rem; }
.metric-label { font-size: 0.75rem; color: var(--color-text-muted); text-transform: uppercase; letter-spacing: 0.05em; }
.availability-section { max-width: 600px; margin: 0 auto; text-align: center; }
.availability-section h3 { margin-bottom: 1rem; }
.availability-section p { color: var(--color-text-light); margin-bottom: 1.5rem; }
.availability-link { display: inline-block; background: var(--color-accent); color: white; padding: 0.75rem 1.5rem; border-radius: 8px; font-weight: 500; text-decoration: none; }
.availability-link:hover { background: var(--color-accent-dark); color: white; }
.disclaimer-text { text-align: center; color: var(--color-text-muted); font-size: 0.875rem; font-style: italic; margin-top: 1rem; margin-bottom: 0; }
.features-section { max-width: 700px; margin: 0 auto 4rem; }
.features-section h3 { text-align: center; margin-bottom: 1.5rem; }
.features-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1rem; }
.feature-toggle { background: var(--color-bg-alt); border-radius: 12px; padding: 1rem 1.25rem; display: flex; justify-content: space-between; align-items: center; border: 2px solid transparent; }
.feature-toggle.enabled { border-color: rgba(80, 200, 120, 0.3); }
.feature-toggle.disabled { opacity: 0.6; }
.feature-name { font-weight: 500; color: var(--color-text); }
.feature-status { font-size: 0.75rem; padding: 0.25rem 0.5rem; border-radius: 50px; background: rgba(80, 200, 120, 0.15); color: var(--color-success); }
.feature-toggle.disabled .feature-status { background: rgba(154, 148, 141, 0.15); color: var(--color-text-muted); }
.blog-post-section { padding: var(--section-padding) 0; background: var(--color-bg); flex: 1; }
.blog-post-content { max-width: 700px; margin: 0 auto; }
.blog-loading { text-align: center; color: var(--color-text-muted); padding: 4rem 0; }
.blog-back { display: inline-block; color: var(--color-accent); font-weight: 500; margin-bottom: 2rem; text-decoration: none; }
.blog-back:hover { color: var(--color-accent-dark); }
.blog-post-header { margin-bottom: 3rem; }
.blog-post-header h1 { margin-top: 1rem; }
.blog-post-body p { font-size: 1.125rem; line-height: 1.8; margin-bottom: 1.75rem; color: var(--color-text); }
.blog-post-body p:first-of-type { font-size: 1.25rem; }
.blog-read-more { display: inline-block; margin-top: 0.5rem; }
.blog-post-body h1 { font-size: 2rem; margin: 2.5rem 0 1rem; padding-bottom: 0.5rem; border-bottom: 2px solid var(--color-border); }
.blog-post-body h2 { font-size: 1.6rem; margin: 2rem 0 0.8rem; color: var(--color-accent); }
.blog-post-body h3 { font-size: 1.3rem; margin: 1.5rem 0 0.6rem; color: var(--color-text); }
.blog-post-body blockquote { border-left: 4px solid var(--color-accent); padding: 1rem 1.5rem; margin: 2rem 0; background: var(--color-bg-alt); border-radius: 0 8px 8px 0; font-style: italic; font-size: 1.1rem; color: var(--color-text); }
.blog-post-body blockquote p { margin: 0; }
.blog-post-body ul, .blog-post-body ol { margin: 1.5rem 0; padding-left: 1.5rem; }
.blog-post-body li { margin-bottom: 0.75rem; color: var(--color-text); line-height: 1.7; }
.blog-post-body ul li { list-style-type: disc; }
.blog-post-body ol li { list-style-type: decimal; }
.blog-post-body hr { border: none; height: 2px; background: linear-gradient(to right, transparent, var(--color-border), transparent); margin: 3rem 0; }
.blog-post-body pre { background: var(--color-bg-dark); color: #f5f0e8; padding: 1.5rem; border-radius: 12px; overflow-x: auto; margin: 1.5rem 0; font-family: var(--font-mono); font-size: 0.9rem; line-height: 1.6; }
.blog-post-body pre code { background: none; padding: 0; color: inherit; font-size: inherit; }
.blog-post-body code { font-family: var(--font-mono); background: var(--color-bg-alt); padding: 0.2em 0.5em; border-radius: 4px; font-size: 0.85em; color: var(--color-accent-dark); }
.blog-post-body a { color: var(--color-accent); text-decoration: underline; text-underline-offset: 2px; }
.blog-post-body a:hover { color: var(--color-accent-dark); }
.blog-post-body strong { color: var(--color-text); font-weight: 600; }
.blog-post-body em { color: var(--color-text); }
.blog-post-body img { max-width: 100%; height: auto; border-radius: 12px; margin: 2rem 0; }
    </style>
</head>
<body>
    <nav class="main-nav">
        <div class="container">
            <a href="index.html" class="nav-brand">FMN-GPT</a>
            <div class="nav-links">
                <a href="blog.html">Blog</a>
                <a href="status.html">Model Status</a>
                <a href="https://huggingface.co/CompactAI" target="_blank">HuggingFace</a>
            </div>
        </div>
    </nav>

    <main>
        <!-- Hero Section -->
        <section class="hero">
        <div class="hero-content">
            <div class="apology-badge">Beta Tester Website In Progress</div>
            <h1 class="hero-title">Help Us <br><span class="highlight">Build AI the Hard Way</span></h1>
            <p class="hero-subtitle">We are working on a beta tester website so people can experience the pain of creating an AI with us.</p>
            <div class="scroll-indicator">
                <span>Scroll for the truth</span>
                <div class="scroll-arrow"></div>
            </div>
        </div>
        <div class="hero-visual">
            <canvas id="neuron-canvas"></canvas>
        </div>
    </section>

    <!-- A Note Before We Begin -->
    <section class="preface" id="preface">
        <div class="container">
            <h2 class="section-title">A Note Before We Begin</h2>
            <div class="preface-content">
                <p class="drop-cap">You might have noticed that everything on my profile got deleted. That was intentional. Let me explain why.</p>
                
                <p>I used to fill my profile with compressed models. Dozens of them. But I realized that quantity was masking the real problem. I wasn't building anything new. Just cloning and shrinking other people's work.</p>
                
                <p>So I wiped the slate clean. A fresh start. This time, I'm here to <strong>build from scratch</strong>.</p>
            </div>
        </div>
    </section>

    <!-- The Confession -->
    <section class="confession" id="confession">
        <div class="container">
            <h2 class="section-title">The Confession</h2>
            <div class="confession-content">
                <div class="confession-text">
                    <p class="drop-cap">Let me be honest with you. For months, I was that person. You know the one. Leaving my computer on overnight, running distillation scripts, trying to squeeze Claude opus 4.6 into something that could run on a potato.</p>
                    
                    <p>And you know what? <strong>It was boring.</strong></p>
                    
                    <p>Who actually enjoys watching loss curves descend at 3 AM? Who gets excited about shaving off 2% of parameters while the model forgets how to count?</p>
                    
                    <blockquote>
                        "I was cloning someone else's work and compressing it. The process lacked real creation. Just digital photocopying with extra steps."
                    </blockquote>
                    
                    <p>So I stopped. And I started asking a different question:</p>
                    
                    <div class="big-question">
                        <span class="question-mark">?</span>
                        <p>What if a model could be small <em>by design</em>, avoiding compression entirely?</p>
                    </div>
                </div>
            </div>
        </div>
    </section>

    <!-- What I'm Building -->
    <section class="what-building" id="what">
        <div class="container">
            <h2 class="section-title">What I'm Building Instead</h2>
            
            <div class="feature-grid">
                <div class="feature-card main-feature">
                    <div class="feature-icon">
                        <svg viewBox="0 0 100 100" class="neuron-icon">
                            <circle cx="50" cy="30" r="15" class="neuron-node"/>
                            <circle cx="25" cy="70" r="12" class="neuron-node"/>
                            <circle cx="75" cy="70" r="12" class="neuron-node"/>
                            <path d="M50 45 L30 58" class="neuron-connection"/>
                            <path d="M50 45 L70 58" class="neuron-connection"/>
                            <path d="M37 70 L63 70" class="neuron-connection" stroke-dasharray="5,3"/>
                        </svg>
                    </div>
                    <h3>FMN-GPT</h3>
                    <p class="feature-subtitle">Factored Multiplicative Neuron Transformer</p>
                    <p>A transformer architecture where each neuron can call backward into the network. A fundamentally different way to think, designed from scratch.</p>
                    <div class="feature-stats">
                        <div class="stat">
                            <span class="stat-value">491</span>
                            <span class="stat-label">Vocab Size</span>
                        </div>
                        <div class="stat">
                            <span class="stat-value">65K</span>
                            <span class="stat-label">Context Length</span>
                        </div>
                        <div class="stat">
                            <span class="stat-value">120</span>
                            <span class="stat-label">Max Loops/Neuron</span>
                        </div>
                    </div>
                    <p class="disclaimer-text">Everything is subject to change.</p>
                </div>
            </div>

            <!-- Architecture Diagram -->
            <div class="architecture-section">
                <h3>The Architecture</h3>
                <div class="architecture-diagram" id="arch-diagram">
                    <div class="arch-layer" data-layer="input">
                        <div class="layer-box input-layer">
                            <span>Input Embeddings</span>
                        </div>
                    </div>
                    
                    <div class="arch-arrow">v</div>
                    
                    <div class="arch-layer" data-layer="recursive">
                        <div class="layer-box recursive-layer">
                            <span>Shared Transformer Block x6</span>
                            <div class="layer-details">
                                <div class="detail-item">
                                    <span class="detail-label">Multi-Query Attention</span>
                                    <span class="detail-value">4 heads</span>
                                </div>
                                <div class="detail-item">
                                    <span class="detail-label">FMN Feedforward</span>
                                    <span class="detail-value">Rank 40</span>
                                </div>
                                <div class="detail-item">
                                    <span class="detail-label">Dynamic Routing</span>
                                    <span class="detail-value">REINFORCE based</span>
                                </div>
                            </div>
                        </div>
                    </div>
                    
                    <div class="arch-arrow loop-arrow">
                        <span>Recurrent State</span>
                    </div>
                    
                    <div class="arch-layer" data-layer="output">
                        <div class="layer-box output-layer">
                            <span>Output (Weight-Tied)</span>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </section>

    <!-- How It Works -->
    <section class="how-it-works" id="how">
        <div class="container">
            <h2 class="section-title">How It Actually Works</h2>
            
            <div class="mechanism-tabs">
                <button class="tab-btn active" data-tab="fmn">FMN Neurons</button>
                <button class="tab-btn" data-tab="routing">Dynamic Routing</button>
                <button class="tab-btn" data-tab="recurrent">Recurrent Mixer</button>
                <button class="tab-btn" data-tab="loops">Loop Counter</button>
            </div>
            
            <div class="tab-content">
                <!-- FMN Tab -->
                <div class="tab-pane active" id="fmn-pane">
                    <div class="pane-content">
                        <div class="pane-text">
                            <h3>Factored Multiplicative Neurons</h3>
                            <p>Traditional neurons compute <code>y = σ(Wx + b)</code>. Simple, but limited.</p>
                            <p>FMN neurons compute:</p>
                            <div class="equation">
                                <code>gate = tanh(W1(x)) * sigmoid(W2(x))</code>
                            </div>
                            <div class="equation">
                                <code>output = V(gate)</code>
                            </div>
                            <p>Each FMN uses a multiplicative gating mechanism with two weight matrices W1 and W2 that project to a rank 40 latent space, then combines via tanh and sigmoid before projecting back through V.</p>
                            <ul class="feature-list">
                                <li>Rank 40 latent dimension for efficient computation</li>
                                <li>Multiplicative gating enables complex interactions</li>
                                <li>Optional SwiGLU variant available</li>
                                <li>Initialized with Xavier uniform for stability</li>
                            </ul>
                        </div>
                        <div class="pane-visual">
                            <canvas id="fmn-canvas" width="400" height="300"></canvas>
                        </div>
                    </div>
                </div>
                
                <!-- Routing Tab -->
                <div class="tab-pane" id="routing-pane">
                    <div class="pane-content">
                        <div class="pane-text">
                            <h3>Dynamic Neuron Routing</h3>
                            <p>Each neuron can route its output to any layer and any neuron in the network using <strong>REINFORCE policy gradients</strong> for true gradient flow through hard routing decisions.</p>
                            <div class="equation">
                                <code>should_route ~ Bernoulli(sigmoid(logits))</code>
                            </div>
                            <div class="equation">
                                <code>target_layer ~ Categorical(softmax(layer_logits))</code>
                            </div>
                            <p>The router learns:</p>
                            <ul class="feature-list">
                                <li>Whether to route via learned sigmoid gate</li>
                                <li>Which layer to target (0 to n_layers)</li>
                                <li>Which neuron to target (0 to d_model)</li>
                                <li>Routing strength via learned parameter</li>
                            </ul>
                        </div>
                        <div class="pane-visual">
                            <canvas id="routing-canvas" width="400" height="300"></canvas>
                        </div>
                    </div>
                </div>
                
                <!-- Recurrent Tab -->
                <div class="tab-pane" id="recurrent-pane">
                    <div class="pane-content">
                        <div class="pane-text">
                            <h3>Recurrent Mixer</h3>
                            <p>A per-channel gated recurrent state that persists across layer iterations. Think of it as a tiny LSTM for each dimension.</p>
                            <div class="equation">
                                <code>g = sigmoid(x * w_x + s * w_s + b)</code>
                            </div>
                            <div class="equation">
                                <code>s_new = s * (1 - g) + x * g</code>
                            </div>
                            <p>This allows the model to accumulate information across the 6 layer passes, creating a form of <strong>internal memory</strong>. The state scale parameter controls how much the recurrent state influences each layer.</p>
                        </div>
                        <div class="pane-visual">
                            <canvas id="recurrent-canvas" width="400" height="300"></canvas>
                        </div>
                    </div>
                </div>
                
                <!-- Loops Tab -->
                <div class="tab-pane" id="loops-pane">
                    <div class="pane-content">
                        <div class="pane-text">
                            <h3>Loop Counter</h3>
                            <p>Each neuron has a hard limit on how many times it can participate in routing loops. This prevents infinite cycles and forces the model to be efficient.</p>
                            <div class="equation">
                                <code>loop_exhausted = loop_counts >= max_loops</code>
                            </div>
                            <p>With <code>max_loops = 120</code>, each neuron can participate in at most 120 routing events before being silenced. This creates a form of <strong>computational budget</strong>.</p>
                            <div class="loop-demo">
                                <label>Max Loops: <span id="loop-value">120</span></label>
                                <input type="range" id="loop-slider" min="1" max="200" value="120">
                                <div class="loop-indicator" id="loop-indicator"></div>
                            </div>
                        </div>
                        <div class="pane-visual">
                            <canvas id="loops-canvas" width="400" height="300"></canvas>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </section>

    <!-- Explain Like I'm Five -->
    <section class="elief-section" id="elief">
        <div class="container">
            <h2 class="section-title">Explain Like I'm Five</h2>
            <p class="section-subtitle">How does this tiny model think?</p>
            
            <div class="elief-content">
                <div class="elief-card">
                    <h3>What is FMN-GPT?</h3>
                    <p>Imagine a really tiny brain. Most AI brains today are huge, like a library with millions of books. FMN-GPT is more like a small notebook. But here's the trick. It can read that notebook over and over, each time understanding a little more.</p>
                </div>
                
                <div class="elief-card">
                    <h3>Why Character-Level?</h3>
                    <p>Most AI models learn whole words at a time. We taught this one to read letter by letter, like a child learning to read. This keeps it small. It only needs to know 491 characters instead of thousands of words. Every letter matters.</p>
                </div>
                
                <div class="elief-card">
                    <h3>How Does It Think?</h3>
                    <p>When you ask a question, the model passes it through the same brain circuit 6 times. Each pass, it thinks a little deeper. Like asking yourself "what's 2+2?" and then checking, "Wait, let me think again. 2+2... that's adding two groups of two... so that makes 4!"</p>
                </div>
                
                <div class="elief-card">
                    <h3>The Magic Number: 491 Characters</h3>
                    <p>The model uses a character-level vocabulary of exactly 491 tokens. This includes ASCII characters, special symbols, and custom thinking tokens (the thinking emoji and light bulb emoji). Every character matters.</p>
                </div>
            </div>
        </div>
    </section>

    <!-- Why I Stopped -->
    <section class="why-stopped" id="why">
        <div class="container">
            <h2 class="section-title">Why I Really Stopped</h2>
            
            <div class="reasons-grid">
                <div class="reason-card">
                    <div class="reason-number">01</div>
                    <h3>It Was Boring</h3>
                    <p>There's no creativity in distillation. You're just making a smaller copy of someone else's breakthrough. Where's the fun in that?</p>
                </div>
                
                <div class="reason-card">
                    <div class="reason-number">02</div>
                    <h3>Diminishing Returns</h3>
                    <p>Every 1% of parameter reduction came with a measurable drop in capability. The tradeoff wasn't worth it.</p>
                </div>
                
                <div class="reason-card">
                    <div class="reason-number">03</div>
                    <h3>Overnight Runs</h3>
                    <p>Who leaves their computer on overnight to clone someone else's work and compress it? The process lacks real creation. Mere photocopying in disguise.</p>
                </div>
                
                <div class="reason-card">
                    <div class="reason-number">04</div>
                    <h3>A Better Question</h3>
                    <p>Instead of asking "how do I make this smaller?", I started asking "what if it was designed to be small from the start?"</p>
                </div>
            </div>
            
            <div class="comparison-section">
                <h3>The Old Way vs. The New Way</h3>
                <div class="comparison-grid">
                    <div class="comparison-item old">
                        <h4>Model Compression</h4>
                        <ul>
                            <li>Start with 7B parameters</li>
                            <li>Distill, quantize, prune</li>
                            <li>End with 1B parameters</li>
                            <li>Capability: ???</li>
                            <li>Time: Weeks of compute</li>
                        </ul>
                    </div>
                    
                    <div class="comparison-arrow">-></div>
                    
                    <div class="comparison-item new">
                        <h4>Small by Design</h4>
                        <ul>
                            <li>Start with ~100K parameters</li>
                            <li>Novel architecture</li>
                            <li>End with ~100K parameters</li>
                            <li>Capability: Emergent</li>
                            <li>Time: One GPU, one night</li>
                        </ul>
                    </div>
                </div>
            </div>
        </div>
    </section>

    <!-- Roadmap -->
    <section class="roadmap-section" id="roadmap">
        <div class="container">
            <h2 class="section-title">Roadmap</h2>
            <p class="section-subtitle">Where we're headed (everything is subject to change)</p>
            
            <div class="roadmap-timeline">
<div class="roadmap-item completed">
                <div class="roadmap-marker"></div>
                <div class="roadmap-content">
                    <h4>Phase 1: Core Architecture</h4>
                    <p>FMN neurons with rank 40, REINFORCE based dynamic routing, recurrent mixer, QK normalization, gated residuals. The foundation is complete.</p>
                    <span class="roadmap-status">Completed</span>
                </div>
            </div>
            
            <div class="roadmap-item in-progress">
                <div class="roadmap-marker"></div>
                <div class="roadmap-content">
                    <h4>Phase 2: Training Pipeline</h4>
                    <p>Character-level tokenization (491 vocab), 7 instruction datasets, pretraining on English-Pretraining-Dataset, AdamW optimizer, bfloat16 precision.</p>
                    <span class="roadmap-status">In Progress</span>
                </div>
            </div>
                
                <div class="roadmap-item">
                    <div class="roadmap-marker"></div>
                    <div class="roadmap-content">
                        <h4>Phase 3: CoT Reasoning</h4>
                        <p>Teaching the model to think step-by-step with explicit reasoning traces.</p>
                        <span class="roadmap-status">Planned</span>
                    </div>
                </div>
                
                <div class="roadmap-item">
                    <div class="roadmap-marker"></div>
                    <div class="roadmap-content">
                        <h4>Phase 4: Evaluation Suite</h4>
                        <p>Comprehensive benchmarks to measure what 100K parameters can actually do.</p>
                        <span class="roadmap-status">Planned</span>
                    </div>
                </div>
                
                <div class="roadmap-item">
                    <div class="roadmap-marker"></div>
                    <div class="roadmap-content">
                        <h4>Phase 5: Model Release</h4>
                        <p>Open weights on HuggingFace for the community to experiment with.</p>
                        <span class="roadmap-status">Planned</span>
                    </div>
                </div>
            </div>
        </div>
    </section>

    <!-- Dataset Credits -->
    <section class="credits-section" id="credits">
        <div class="container">
            <h2 class="section-title">Dataset Credits</h2>
            <p class="section-subtitle">The data that trains our model (subject to change)</p>
            
            <div class="credits-grid">
                <div class="credit-card">
                    <h4>Pretraining Dataset</h4>
                    <p class="credit-name">shuyuej/English-Pretraining-Dataset</p>
                    <p>Large-scale English text for initial language understanding and general knowledge.</p>
                    <a href="https://huggingface.co/datasets/shuyuej/English-Pretraining-Dataset" target="_blank">View on HuggingFace</a>
                </div>
                
                <div class="credit-card">
                    <h4>Instruction Dataset 1</h4>
                    <p class="credit-name">TeichAI/Pony-Alpha-15k</p>
                    <p>Conversational instruction data for learning dialogue patterns and responses.</p>
                    <a href="https://huggingface.co/datasets/TeichAI/Pony-Alpha-15k" target="_blank">View on HuggingFace</a>
                </div>
                
                <div class="credit-card">
                    <h4>Instruction Dataset 2</h4>
                    <p class="credit-name">TeichAI/convo-v1</p>
                    <p>Multi-turn conversation data for context handling and coherent dialogue.</p>
                    <a href="https://huggingface.co/datasets/TeichAI/convo-v1" target="_blank">View on HuggingFace</a>
                </div>
                
                <div class="credit-card">
                    <h4>Instruction Dataset 3</h4>
                    <p class="credit-name">TeichAI/Step-3.5-Flash-2600x</p>
                    <p>High-quality instruction-response pairs for fine-tuning reasoning capabilities.</p>
                    <a href="https://huggingface.co/datasets/TeichAI/Step-3.5-Flash-2600x" target="_blank">View on HuggingFace</a>
                </div>
                
                <div class="credit-card">
                    <h4>Instruction Dataset 4</h4>
                    <p class="credit-name">TeichAI/sherlock-thinking-alpha-11000x</p>
                    <p>Thinking and reasoning data for chain of thought training.</p>
                    <a href="https://huggingface.co/datasets/TeichAI/sherlock-thinking-alpha-11000x" target="_blank">View on HuggingFace</a>
                </div>
                
                <div class="credit-card">
                    <h4>Instruction Dataset 5</h4>
                    <p class="credit-name">TeichAI/glm-4.7-2000x</p>
                    <p>GLM model outputs for diverse response patterns.</p>
                    <a href="https://huggingface.co/datasets/TeichAI/glm-4.7-2000x" target="_blank">View on HuggingFace</a>
                </div>
                
                <div class="credit-card">
                    <h4>Instruction Dataset 6</h4>
                    <p class="credit-name">TeichAI/claude-haiku-4.5-high-reasoning-1700x</p>
                    <p>Claude reasoning outputs for advanced thinking patterns.</p>
                    <a href="https://huggingface.co/datasets/TeichAI/claude-haiku-4.5-high-reasoning-1700x" target="_blank">View on HuggingFace</a>
                </div>
                
                <div class="credit-card">
                    <h4>Instruction Dataset 7</h4>
                    <p class="credit-name">TeichAI/gemini-3-flash-preview</p>
                    <p>Gemini model outputs for additional diversity.</p>
                    <a href="https://huggingface.co/datasets/TeichAI/gemini-3-flash-preview" target="_blank">View on HuggingFace</a>
                </div>
            </div>
        </div>
    </section>

    <!-- Closing -->
    <section class="closing" id="closing">
        <div class="container">
            <div class="closing-content">
                <h2>Beyond Competing with Claude opus 4.6</h2>
                <p>The real goal is understanding what's actually necessary for intelligence to emerge. Maybe 100K parameters is enough. Maybe it isn't. But we won't know until we try building from first principles instead of just compressing what already exists.</p>
                
                <p><strong>FMN-GPT will be 100% open-source.</strong> This includes the training script, full model weights, all checkpoints, the base model, the instruction model, and our custom inference engine. We believe that open research accelerates progress for everyone.</p>
                
                <div class="closing-quote">
                    <blockquote>
                        "Smaller models serve as a means toward a larger goal. Understanding what makes models work in the first place is the real objective."
                    </blockquote>
                </div>
                
                <div class="poem-section">
                    <p class="poem-intro">It's coming.</p>
                    <div class="poem">
                        <p>Small enough to hide in plain sight,</p>
                        <p>Big enough to twist the stars of night,</p>
                        <p>Quiet as a shadow, sharp as a spark,</p>
                        <p>A tiny flame that will light the dark.</p>
                    </div>
                </div>
                
                <div class="cta-section">
                    <p>This is an ongoing experiment. Everything described here is subject to change. Follow along if you're curious about what this architecture can actually do.</p>
                </div>
            </div>
        </div>
    </section>
    </main>

    <!-- Footer -->
    <footer class="footer">
        <div class="container">
            <div class="footer-content">
                <p class="footer-text">Built with curiosity over compute.</p>
                <p class="footer-subtext">FMN-GPT by <a href="https://huggingface.co/CompactAI" target="_blank">CompactAI</a> - 2026</p>
            </div>
        </div>
    </footer>

    <script>
const CONFIG = { colors: { accent: '#e85d3b', accentLight: '#ff8a6b', secondary: '#d4a853', secondaryLight: '#e8c87a', bg: '#faf8f5', bgAlt: '#f5f0e8', bgDark: '#1a1815', text: '#2d2a26', textLight: '#6b6560', textMuted: '#9a948d', border: '#e5e0d8', success: '#50c878', info: '#4a9eff' }, neuron: { count: 112, maxLoops: 30, layers: 6 } };
function lerp(a, b, t) { return a + (b - a) * t; }
function clamp(val, min, max) { return Math.max(min, Math.min(max, val)); }
function randomRange(min, max) { return Math.random() * (max - min) + min; }
function hexToRgba(hex, alpha) { const r = parseInt(hex.slice(1, 3), 16); const g = parseInt(hex.slice(3, 5), 16); const b = parseInt(hex.slice(5, 7), 16); return `rgba(${r}, ${g}, ${b}, ${alpha})`; }
class NeuronNetwork {
    constructor(canvas) { this.canvas = canvas; this.ctx = canvas.getContext('2d'); this.neurons = []; this.connections = []; this.particles = []; this.mouse = { x: 0, y: 0 }; this.animationId = null; this.resize(); this.init(); this.bindEvents(); this.animate(); }
    resize() { const rect = this.canvas.parentElement.getBoundingClientRect(); this.canvas.width = rect.width * window.devicePixelRatio; this.canvas.height = rect.height * window.devicePixelRatio; this.ctx.scale(window.devicePixelRatio, window.devicePixelRatio); this.width = rect.width; this.height = rect.height; }
    init() { const count = Math.min(50, Math.floor(this.width * this.height / 15000)); this.neurons = []; for (let i = 0; i < count; i++) { this.neurons.push({ x: randomRange(50, this.width - 50), y: randomRange(50, this.height - 50), vx: randomRange(-0.3, 0.3), vy: randomRange(-0.3, 0.3), radius: randomRange(3, 6), pulse: randomRange(0, Math.PI * 2), pulseSpeed: randomRange(0.02, 0.05) }); } this.updateConnections(); }
    updateConnections() { this.connections = []; const maxDist = 150; for (let i = 0; i < this.neurons.length; i++) { for (let j = i + 1; j < this.neurons.length; j++) { const dx = this.neurons[i].x - this.neurons[j].x; const dy = this.neurons[i].y - this.neurons[j].y; const dist = Math.sqrt(dx * dx + dy * dy); if (dist < maxDist) { this.connections.push({ from: i, to: j, strength: 1 - dist / maxDist }); } } } }
    bindEvents() { window.addEventListener('resize', () => { this.resize(); this.init(); }); this.canvas.addEventListener('mousemove', (e) => { const rect = this.canvas.getBoundingClientRect(); this.mouse.x = e.clientX - rect.left; this.mouse.y = e.clientY - rect.top; }); }
    animate() { this.ctx.clearRect(0, 0, this.width, this.height); for (const neuron of this.neurons) { neuron.x += neuron.vx; neuron.y += neuron.vy; neuron.pulse += neuron.pulseSpeed; if (neuron.x < 20 || neuron.x > this.width - 20) neuron.vx *= -1; if (neuron.y < 20 || neuron.y > this.height - 20) neuron.vy *= -1; const dx = this.mouse.x - neuron.x; const dy = this.mouse.y - neuron.y; const dist = Math.sqrt(dx * dx + dy * dy); if (dist < 100 && dist > 0) { neuron.x -= dx * 0.01; neuron.y -= dy * 0.01; } } this.updateConnections(); for (const conn of this.connections) { const from = this.neurons[conn.from]; const to = this.neurons[conn.to]; this.ctx.beginPath(); this.ctx.moveTo(from.x, from.y); this.ctx.lineTo(to.x, to.y); this.ctx.strokeStyle = hexToRgba(CONFIG.colors.accent, conn.strength * 0.3); this.ctx.lineWidth = conn.strength * 2; this.ctx.stroke(); } for (const neuron of this.neurons) { const pulseRadius = neuron.radius + Math.sin(neuron.pulse) * 2; const gradient = this.ctx.createRadialGradient(neuron.x, neuron.y, 0, neuron.x, neuron.y, pulseRadius * 3); gradient.addColorStop(0, hexToRgba(CONFIG.colors.accent, 0.3)); gradient.addColorStop(1, hexToRgba(CONFIG.colors.accent, 0)); this.ctx.beginPath(); this.ctx.arc(neuron.x, neuron.y, pulseRadius * 3, 0, Math.PI * 2); this.ctx.fillStyle = gradient; this.ctx.fill(); this.ctx.beginPath(); this.ctx.arc(neuron.x, neuron.y, pulseRadius, 0, Math.PI * 2); this.ctx.fillStyle = CONFIG.colors.accent; this.ctx.fill(); } this.animationId = requestAnimationFrame(() => this.animate()); }
    destroy() { if (this.animationId) { cancelAnimationFrame(this.animationId); } }
}
class FMNVisualization {
    constructor(canvas) { this.canvas = canvas; this.ctx = canvas.getContext('2d'); this.time = 0; this.animationId = null; this.dataFlow = []; this.resize(); this.initDataFlow(); this.animate(); }
    resize() { const dpr = window.devicePixelRatio || 1; this.canvas.width = 400 * dpr; this.canvas.height = 300 * dpr; this.ctx.scale(dpr, dpr); this.width = 400; this.height = 300; }
    initDataFlow() { this.dataFlow = []; for (let i = 0; i < 8; i++) { this.dataFlow.push({ progress: Math.random(), speed: 0.003 + Math.random() * 0.002, path: Math.floor(Math.random() * 3) }); } }
    animate() { this.ctx.clearRect(0, 0, this.width, this.height); this.time += 0.016; const centerX = this.width / 2; const centerY = this.height / 2; this.ctx.fillStyle = '#faf8f5'; this.ctx.fillRect(0, 0, this.width, this.height); const inputY = centerY - 90; const w1Y = centerY - 25; const w2Y = centerY + 25; const outputY = centerY + 90; this.ctx.strokeStyle = 'rgba(107, 101, 96, 0.15)'; this.ctx.lineWidth = 1; for (let i = 0; i < 5; i++) { for (let j = 0; j < 3; j++) { const x1 = centerX - 80 + i * 40; const x2 = centerX - 40 + j * 40; this.ctx.beginPath(); this.ctx.moveTo(x1, inputY + 14); this.ctx.lineTo(x2, w1Y - 14); this.ctx.stroke(); } } for (let i = 0; i < 3; i++) { for (let j = 0; j < 5; j++) { const x1 = centerX - 40 + i * 40; const x2 = centerX - 80 + j * 40; this.ctx.beginPath(); this.ctx.moveTo(x1, w2Y + 14); this.ctx.lineTo(x2, outputY - 14); this.ctx.stroke(); } } for (let i = 0; i < 5; i++) { const x = centerX - 80 + i * 40; this.drawNeuron(x, inputY, 14, '#4a9eff'); } for (let i = 0; i < 3; i++) { const x = centerX - 40 + i * 40; this.drawNeuron(x, w1Y, 16, CONFIG.colors.accent); } for (let i = 0; i < 3; i++) { const x = centerX - 40 + i * 40; this.drawNeuron(x, w2Y, 16, CONFIG.colors.secondary); } for (let i = 0; i < 5; i++) { const x = centerX - 80 + i * 40; this.drawNeuron(x, outputY, 14, '#50c878'); } this.ctx.font = 'bold 20px Inter, sans-serif'; this.ctx.fillStyle = CONFIG.colors.textMuted; this.ctx.textAlign = 'center'; this.ctx.textBaseline = 'middle'; this.ctx.fillText('?', centerX, centerY); for (const particle of this.dataFlow) { particle.progress += particle.speed; if (particle.progress > 1) { particle.progress = 0; particle.path = Math.floor(Math.random() * 3); } const alpha = Math.sin(particle.progress * Math.PI) * 0.8; const inputIdx = particle.path; const wIdx = particle.path % 3; const inputX = centerX - 80 + inputIdx * 40; const w1X = centerX - 40 + wIdx * 40; const w2X = centerX - 40 + wIdx * 40; const outX = centerX - 80 + wIdx * 40; let px, py; if (particle.progress < 0.33) { const t = particle.progress / 0.33; px = lerp(inputX, w1X, t); py = lerp(inputY, w1Y, t); } else if (particle.progress < 0.66) { const t = (particle.progress - 0.33) / 0.33; px = lerp(w1X, w2X, t); py = lerp(w1Y, w2Y, t); } else { const t = (particle.progress - 0.66) / 0.34; px = lerp(w2X, outX, t); py = lerp(w2Y, outputY, t); } this.ctx.beginPath(); this.ctx.arc(px, py, 4, 0, Math.PI * 2); this.ctx.fillStyle = `rgba(232, 93, 59, ${alpha})`; this.ctx.fill(); } this.ctx.font = '11px Inter, sans-serif'; this.ctx.fillStyle = CONFIG.colors.textMuted; this.ctx.textAlign = 'center'; this.ctx.textBaseline = 'top'; this.ctx.fillText('Input', centerX, inputY - 30); this.ctx.fillText('[REDACTED]', centerX - 70, w1Y - 8); this.ctx.fillText('[REDACTED]', centerX + 70, w2Y - 8); this.ctx.fillText('Output', centerX, outputY + 25); this.animationId = requestAnimationFrame(() => this.animate()); }
    drawNeuron(x, y, radius, color) { this.ctx.beginPath(); this.ctx.arc(x, y + 2, radius, 0, Math.PI * 2); this.ctx.fillStyle = 'rgba(0, 0, 0, 0.1)'; this.ctx.fill(); this.ctx.beginPath(); this.ctx.arc(x, y, radius, 0, Math.PI * 2); this.ctx.fillStyle = color; this.ctx.fill(); this.ctx.beginPath(); this.ctx.arc(x - radius * 0.3, y - radius * 0.3, radius * 0.4, 0, Math.PI * 2); this.ctx.fillStyle = 'rgba(255, 255, 255, 0.3)'; this.ctx.fill(); }
    destroy() { if (this.animationId) { cancelAnimationFrame(this.animationId); } }
}
class RoutingVisualization {
    constructor(canvas) { this.canvas = canvas; this.ctx = canvas.getContext('2d'); this.time = 0; this.particles = []; this.animationId = null; this.resize(); this.initParticles(); this.animate(); }
    resize() { const dpr = window.devicePixelRatio || 1; this.canvas.width = 400 * dpr; this.canvas.height = 300 * dpr; this.ctx.scale(dpr, dpr); this.width = 400; this.height = 300; }
    initParticles() { this.particles = []; const layers = 6; const layerSpacing = this.width / (layers + 1); for (let i = 0; i < 12; i++) { const startLayer = Math.floor(Math.random() * layers); const startY = randomRange(60, this.height - 60); this.particles.push({ x: (startLayer + 1) * layerSpacing, y: startY, targetX: 0, targetY: 0, speed: 0.8 + Math.random() * 0.4, color: Math.random() > 0.5 ? CONFIG.colors.accent : CONFIG.colors.secondary, trail: [] }); this.setNewTarget(this.particles[i]); } }
    setNewTarget(particle) { const layers = 6; const layerSpacing = this.width / (layers + 1); const targetLayer = Math.floor(Math.random() * layers); particle.targetX = (targetLayer + 1) * layerSpacing; particle.targetY = randomRange(60, this.height - 60); }
    animate() { this.ctx.clearRect(0, 0, this.width, this.height); this.time += 0.016; this.ctx.fillStyle = '#faf8f5'; this.ctx.fillRect(0, 0, this.width, this.height); const layers = 6; const layerSpacing = this.width / (layers + 1); for (let i = 1; i <= layers; i++) { const x = i * layerSpacing; this.ctx.fillStyle = 'rgba(229, 224, 216, 0.3)'; this.ctx.fillRect(x - 15, 40, 30, this.height - 70); this.ctx.font = '10px Inter, sans-serif'; this.ctx.fillStyle = CONFIG.colors.textMuted; this.ctx.textAlign = 'center'; this.ctx.fillText(`L${i - 1}`, x, this.height - 15); } this.ctx.font = 'bold 13px Inter, sans-serif'; this.ctx.fillStyle = CONFIG.colors.text; this.ctx.textAlign = 'center'; this.ctx.fillText('Cross-Layer Backward Routing', this.width / 2, 22); for (const p of this.particles) { const dx = p.targetX - p.x; const dy = p.targetY - p.y; const dist = Math.sqrt(dx * dx + dy * dy); if (dist < 3) { this.setNewTarget(p); } else { const moveX = (dx / dist) * p.speed; const moveY = (dy / dist) * p.speed; p.x += moveX; p.y += moveY; p.trail.push({ x: p.x, y: p.y }); if (p.trail.length > 15) { p.trail.shift(); } } for (let i = 0; i < p.trail.length - 1; i++) { const alpha = (i / p.trail.length) * 0.4; this.ctx.beginPath(); this.ctx.moveTo(p.trail[i].x, p.trail[i].y); this.ctx.lineTo(p.trail[i + 1].x, p.trail[i + 1].y); this.ctx.strokeStyle = `rgba(232, 93, 59, ${alpha})`; this.ctx.lineWidth = 2; this.ctx.stroke(); } this.ctx.beginPath(); this.ctx.arc(p.x, p.y, 5, 0, Math.PI * 2); this.ctx.fillStyle = p.color; this.ctx.fill(); } this.animationId = requestAnimationFrame(() => this.animate()); }
    destroy() { if (this.animationId) { cancelAnimationFrame(this.animationId); } }
}
class RecurrentVisualization {
    constructor(canvas) { this.canvas = canvas; this.ctx = canvas.getContext('2d'); this.time = 0; this.states = []; this.animationId = null; this.resize(); this.initStates(); this.animate(); }
    resize() { const dpr = window.devicePixelRatio || 1; this.canvas.width = 400 * dpr; this.canvas.height = 300 * dpr; this.ctx.scale(dpr, dpr); this.width = 400; this.height = 300; }
    initStates() { this.states = []; for (let i = 0; i < 8; i++) { this.states.push({ value: randomRange(0.3, 0.7), target: randomRange(0.3, 0.7), gate: randomRange(0.2, 0.8), history: [] }); } }
    animate() { this.ctx.clearRect(0, 0, this.width, this.height); this.time += 0.016; this.ctx.fillStyle = '#faf8f5'; this.ctx.fillRect(0, 0, this.width, this.height); const barWidth = 32; const barSpacing = 46; const startX = (this.width - (this.states.length * barSpacing)) / 2 + 5; const baseY = this.height - 50; const maxHeight = 140; this.ctx.font = 'bold 13px Inter, sans-serif'; this.ctx.fillStyle = CONFIG.colors.text; this.ctx.textAlign = 'center'; this.ctx.fillText('Per-Channel Gated State', this.width / 2, 22); for (let i = 0; i < this.states.length; i++) { const state = this.states[i]; const x = startX + i * barSpacing; state.gate = 0.4 + Math.sin(this.time * 0.8 + i * 0.7) * 0.35; state.value = lerp(state.value, state.target, state.gate * 0.08); if (Math.random() < 0.008) { state.target = randomRange(0.2, 0.95); } state.history.push(state.value); if (state.history.length > 50) state.history.shift(); this.ctx.fillStyle = 'rgba(229, 224, 216, 0.4)'; this.ctx.beginPath(); this.ctx.roundRect(x - barWidth / 2, baseY - maxHeight, barWidth, maxHeight, 4); this.ctx.fill(); const currentHeight = maxHeight * state.value; const gradient = this.ctx.createLinearGradient(x, baseY, x, baseY - currentHeight); gradient.addColorStop(0, CONFIG.colors.accent); gradient.addColorStop(1, CONFIG.colors.accentLight); this.ctx.fillStyle = gradient; this.ctx.beginPath(); this.ctx.roundRect(x - barWidth / 2, baseY - currentHeight, barWidth, currentHeight, 4); this.ctx.fill(); const gateHeight = 8; const gateY = baseY - maxHeight - 18; const gateFilled = state.gate * barWidth; this.ctx.fillStyle = 'rgba(229, 224, 216, 0.6)'; this.ctx.fillRect(x - barWidth / 2, gateY, barWidth, gateHeight); this.ctx.fillStyle = CONFIG.colors.success; this.ctx.fillRect(x - barWidth / 2, gateY, gateFilled, gateHeight); this.ctx.font = '10px Inter, sans-serif'; this.ctx.fillStyle = CONFIG.colors.textMuted; this.ctx.textAlign = 'center'; this.ctx.fillText(`c${i}`, x, baseY + 15); } this.ctx.font = '10px Inter, sans-serif'; this.ctx.fillStyle = CONFIG.colors.textMuted; this.ctx.textAlign = 'left'; this.ctx.fillText('Gate:', 15, 22); this.ctx.fillStyle = CONFIG.colors.success; this.ctx.fillRect(45, 14, 25, 8); this.animationId = requestAnimationFrame(() => this.animate()); }
    destroy() { if (this.animationId) { cancelAnimationFrame(this.animationId); } }
}
class LoopVisualization {
    constructor(canvas, slider, indicator, valueDisplay) { this.canvas = canvas; this.ctx = canvas.getContext('2d'); this.slider = slider; this.indicator = indicator; this.valueDisplay = valueDisplay; this.maxLoops = 30; this.loopCounts = []; this.animationId = null; this.resize(); this.initLoops(); this.bindEvents(); this.animate(); }
    resize() { const dpr = window.devicePixelRatio || 1; this.canvas.width = 400 * dpr; this.canvas.height = 300 * dpr; this.ctx.scale(dpr, dpr); this.width = 400; this.height = 300; }
    initLoops() { this.loopCounts = []; for (let i = 0; i < 20; i++) { this.loopCounts.push({ count: Math.floor(randomRange(0, this.maxLoops * 0.6)), targetCount: Math.floor(randomRange(5, this.maxLoops)), incrementing: Math.random() > 0.2 }); } this.updateIndicator(); }
    bindEvents() { if (this.slider) { this.slider.addEventListener('input', (e) => { this.maxLoops = parseInt(e.target.value); if (this.valueDisplay) { this.valueDisplay.textContent = this.maxLoops; } this.updateIndicator(); }); } }
    updateIndicator() { if (!this.indicator) return; this.indicator.innerHTML = ''; for (let i = 0; i < this.maxLoops; i++) { const dot = document.createElement('div'); dot.className = 'loop-dot'; if (i < this.maxLoops * 0.7) { dot.classList.add('active'); } else if (i < this.maxLoops) { dot.classList.add('exhausted'); } this.indicator.appendChild(dot); } }
    animate() { this.ctx.clearRect(0, 0, this.width, this.height); this.ctx.fillStyle = '#faf8f5'; this.ctx.fillRect(0, 0, this.width, this.height); const cols = 5; const rows = 4; const cellWidth = this.width / cols; const cellHeight = (this.height - 50) / rows; this.ctx.font = 'bold 13px Inter, sans-serif'; this.ctx.fillStyle = CONFIG.colors.text; this.ctx.textAlign = 'center'; this.ctx.fillText('Neuron Loop Budget', this.width / 2, 22); for (let i = 0; i < this.loopCounts.length; i++) { const state = this.loopCounts[i]; const col = i % cols; const row = Math.floor(i / cols); const x = col * cellWidth + cellWidth / 2; const y = row * cellHeight + cellHeight / 2 + 35; if (state.incrementing) { if (state.count < state.targetCount) { state.count += 0.05; } else if (Math.random() < 0.02) { state.targetCount = Math.floor(randomRange(state.count, this.maxLoops)); } if (state.count >= this.maxLoops) { state.count = this.maxLoops; state.incrementing = false; } } const radius = 26; const progress = Math.min(state.count / this.maxLoops, 1); const exhausted = state.count >= this.maxLoops; this.ctx.beginPath(); this.ctx.arc(x, y, radius, 0, Math.PI * 2); this.ctx.strokeStyle = 'rgba(229, 224, 216, 0.6)'; this.ctx.lineWidth = 5; this.ctx.stroke(); if (progress > 0) { this.ctx.beginPath(); this.ctx.arc(x, y, radius, -Math.PI / 2, -Math.PI / 2 + progress * Math.PI * 2); this.ctx.strokeStyle = exhausted ? CONFIG.colors.textMuted : CONFIG.colors.accent; this.ctx.lineWidth = 5; this.ctx.lineCap = 'round'; this.ctx.stroke(); } this.ctx.beginPath(); this.ctx.arc(x, y, radius - 10, 0, Math.PI * 2); this.ctx.fillStyle = exhausted ? 'rgba(154, 148, 141, 0.1)' : 'rgba(232, 93, 59, 0.1)'; this.ctx.fill(); this.ctx.font = 'bold 13px Inter, sans-serif'; this.ctx.fillStyle = exhausted ? CONFIG.colors.textMuted : CONFIG.colors.text; this.ctx.textAlign = 'center'; this.ctx.textBaseline = 'middle'; this.ctx.fillText(Math.floor(state.count).toString(), x, y); } this.animationId = requestAnimationFrame(() => this.animate()); }
    destroy() { if (this.animationId) { cancelAnimationFrame(this.animationId); } }
}
function initTabs() { const tabBtns = document.querySelectorAll('.tab-btn'); const tabPanes = document.querySelectorAll('.tab-pane'); tabBtns.forEach(btn => { btn.addEventListener('click', () => { const tabId = btn.dataset.tab; tabBtns.forEach(b => b.classList.remove('active')); btn.classList.add('active'); tabPanes.forEach(pane => { pane.classList.remove('active'); if (pane.id === `${tabId}-pane`) { pane.classList.add('active'); } }); }); }); }
function initScrollAnimations() { const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { entry.target.classList.add('visible'); } }); }, { threshold: 0.1, rootMargin: '0px 0px -50px 0px' }); document.querySelectorAll('.fade-in-up').forEach(el => { observer.observe(el); }); }
let heroNetwork = null, fmnViz = null, routingViz = null, recurrentViz = null, loopViz = null;
document.addEventListener('DOMContentLoaded', () => { const heroCanvas = document.getElementById('neuron-canvas'); if (heroCanvas) { heroNetwork = new NeuronNetwork(heroCanvas); } const fmnCanvas = document.getElementById('fmn-canvas'); if (fmnCanvas) { fmnViz = new FMNVisualization(fmnCanvas); } const routingCanvas = document.getElementById('routing-canvas'); if (routingCanvas) { routingViz = new RoutingVisualization(routingCanvas); } const recurrentCanvas = document.getElementById('recurrent-canvas'); if (recurrentCanvas) { recurrentViz = new RecurrentVisualization(recurrentCanvas); } const loopsCanvas = document.getElementById('loops-canvas'); const loopSlider = document.getElementById('loop-slider'); const loopIndicator = document.getElementById('loop-indicator'); const loopValue = document.getElementById('loop-value'); if (loopsCanvas) { loopViz = new LoopVisualization(loopsCanvas, loopSlider, loopIndicator, loopValue); } initTabs(); initScrollAnimations(); });
window.addEventListener('beforeunload', () => { if (heroNetwork) heroNetwork.destroy(); if (fmnViz) fmnViz.destroy(); if (routingViz) routingViz.destroy(); if (recurrentViz) recurrentViz.destroy(); if (loopViz) loopViz.destroy(); });
    </script>
</body>
</html>