wop commited on
Commit
9149c92
·
verified ·
1 Parent(s): 47271a3

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +295 -174
index.html CHANGED
@@ -4,17 +4,13 @@
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
  <title>CompactAI Papers</title>
7
-
8
  <link rel="preconnect" href="https://fonts.googleapis.com">
9
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
10
  <link href="https://fonts.googleapis.com/css2?family=Geist:wght@300..700&family=Geist+Mono:wght@400;500&display=swap" rel="stylesheet">
11
-
12
- <link rel="stylesheet" href="everywhere.css">
13
  </head>
14
  <body>
15
-
16
  <a href="#mainContent" class="skip-link">Skip to papers</a>
17
-
18
  <div class="sr-only" aria-live="polite" aria-atomic="true" id="announcer"></div>
19
 
20
  <header class="site-header">
@@ -22,16 +18,39 @@
22
  <h1 class="site-title">Compact<span class="gold">AI</span> Papers</h1>
23
  <p class="site-subtitle">Research &amp; ideas from the community</p>
24
  <div class="header-divider"></div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  </div>
26
  </header>
27
 
28
  <main class="container" id="mainContent" aria-label="Papers collection">
29
  <h2 class="section-label">Papers</h2>
30
  <ul class="papers-grid" id="papersGrid" role="list"></ul>
 
31
  </main>
32
 
33
  <section class="papermaker-callout" aria-label="Papermaker role">
34
- <p>Have an idea worth writing up? If a mod spots it and likes it, you might earn the <span class="role-name">@Papermaker</span> role &mdash; a nod that you helped push CompactAI forward.</p>
 
 
35
  </section>
36
 
37
  <footer class="site-footer">
@@ -42,229 +61,331 @@
42
 
43
  <script>
44
  var PAPERS = [
45
- {
46
- "id": "trueact-md",
47
- "title": "TrueACT: A Different Kind of Neuron",
48
- "date": "2026-05",
49
- "author": "CompactAI",
50
- "tags": [
51
- "architecture",
52
- "neurons",
53
- "math",
54
- "experimental"
55
- ],
56
- "proved": false,
57
- "featured": true
58
- },
59
- {
60
- "id": "STM_paper-md",
61
- "title": "STM and the Circle Thing",
62
- "date": "2026-05",
63
- "author": "Dragonoid",
64
- "tags": [
65
- "training",
66
- "experimental"
67
- ],
68
- "proved": true,
69
- "featured": false,
70
- "proof_script_content": "import torch\nimport torch.nn as nn\nimport torch.optim as optim\nimport random\nimport numpy as np\n\n# STM (Subtractive Training Method) - Definitive Proof\n# Fix: Added Mastery Floor to prevent premature hard-task removal.\n\nN_EASY, N_HARD = 1000, 250\nMASTERY_THRESHOLD = 0.15\nEPOCHS = 25\n\ndef generate_math(difficulty=\"easy\"):\n if difficulty == \"easy\":\n a, b = random.randint(0, 9), random.randint(0, 9)\n else:\n a, b = random.randint(10, 99), random.randint(10, 99)\n return f\"{a}+{b}={a+b}\", difficulty\n\ntrain_raw = [generate_math(\"easy\") for _ in range(N_EASY)] + [generate_math(\"hard\") for _ in range(N_HARD)]\ntest_easy = [generate_math(\"easy\") for _ in range(200)]\ntest_hard = [generate_math(\"hard\") for _ in range(200)]\n\nchars = list(\"0123456789+=\") + [\"<PAD>\"]\nchar2idx = {c: i for i, c in enumerate(chars)}\nPAD_IDX, EQ_IDX = char2idx[\"<PAD>\"], char2idx[\"=\"]\n\ndef encode(data_list):\n max_l = max(len(d[0]) for d in data_list)\n X, Y = [], []\n for text, _ in data_list:\n enc = [char2idx[c] for c in text] + [PAD_IDX] * (max_l - len(text) + 1)\n X.append(enc[:-1]); Y.append(enc[1:])\n return torch.tensor(X), torch.tensor(Y)\n\nclass STM_Model(nn.Module):\n def __init__(self, vocab_size, hidden_size=128):\n super().__init__()\n self.embedding = nn.Embedding(vocab_size, hidden_size)\n self.rnn = nn.GRU(hidden_size, hidden_size, batch_first=True)\n self.fc = nn.Linear(hidden_size, vocab_size)\n def forward(self, x):\n out, _ = self.rnn(self.embedding(x))\n return self.fc(out)\n\nmodel = STM_Model(len(chars))\noptimizer = optim.Adam(model.parameters(), lr=0.003)\ncriterion = nn.CrossEntropyLoss(ignore_index=PAD_IDX, reduction='none')\n\ndef eval_acc(model, data_list):\n model.eval()\n X, Y = encode(data_list)\n with torch.no_grad():\n out = model(X).argmax(dim=-1)\n correct = 0\n for i in range(len(data_list)):\n eq_pos = (X[i] == EQ_IDX).nonzero(as_tuple=True)[0].item()\n pred = out[i, eq_pos:eq_pos+4]\n target = Y[i, eq_pos:eq_pos+4]\n mask = (target != PAD_IDX)\n if torch.equal(pred[mask], target[mask]): correct += 1\n return correct / len(data_list)\n\ndef get_metrics(model, data_list):\n model.eval()\n X, Y = encode(data_list)\n with torch.no_grad():\n out = model(X).view(-1, len(chars))\n loss = criterion(out, Y.view(-1)).view(X.size(0), X.size(1))\n ans_mask = ((X == EQ_IDX).cumsum(1) - (X == EQ_IDX).float()) * (Y != PAD_IDX).float()\n return ((loss * ans_mask).sum(1) / (ans_mask.sum(1) + 1e-8)).numpy()\n\ncurrent_dataset = list(train_raw)\nprev_losses = get_metrics(model, current_dataset)\ntotal_tokens = 0\ninitial_tokens = len(train_raw) * 12\n\nprint(f\"{'Epoch':<5} | {'Pool(E/H)':<10} | {'Acc(E/H)':<12} | {'Efficiency'}\")\nprint(\"-\" * 50)\n\nfor epoch in range(1, EPOCHS + 1):\n model.train()\n X, Y = encode(current_dataset)\n total_tokens += X.numel()\n indices = np.random.permutation(len(current_dataset))\n for i in range(0, len(current_dataset), 64):\n idx = indices[i:i+64]\n optimizer.zero_grad()\n loss = nn.CrossEntropyLoss(ignore_index=PAD_IDX)(model(X[idx]).view(-1, len(chars)), Y[idx].view(-1))\n loss.backward(); optimizer.step()\n\n curr_losses = get_metrics(model, current_dataset)\n drops = prev_losses - curr_losses\n drop_cutoff = drops.mean() + (drops.std() * 0.5)\n\n keep_indices = []\n for i in range(len(current_dataset)):\n # STM Rule: Drop if (Breakthrough AND mastered) OR (Near-perfect)\n if (drops[i] > drop_cutoff and curr_losses[i] < 0.5) or curr_losses[i] < MASTERY_THRESHOLD:\n pass\n else:\n keep_indices.append(i)\n\n e_rem = sum(1 for _, l in current_dataset if l == \"easy\")\n h_rem = sum(1 for _, l in current_dataset if l == \"hard\")\n acc_e = eval_acc(model, test_easy)\n acc_h = eval_acc(model, test_hard)\n efficiency = (initial_tokens * epoch) / total_tokens\n\n print(f\"{epoch:<5} | {e_rem:>4}/{h_rem:<4} | {acc_e:>5.1%}/{acc_h:<5.1%} | {efficiency:.2f}x\")\n\n if not keep_indices: break\n current_dataset = [current_dataset[i] for i in keep_indices]\n prev_losses = curr_losses[keep_indices]\n\nprint(\"\\nSTM proof complete. The theory works — now with the Mastery Floor fix.\")\n"
71
- },
72
- {
73
- "id": "apollonian_gasket-md",
74
- "title": "Token Embeddings Inside an Integer Apollonian Gasket",
75
- "date": "2026-05",
76
- "author": "Mage",
77
- "tags": [
78
- "embeddings",
79
- "geometry",
80
- "number-theory",
81
- "experimental"
82
- ],
83
- "proved": false,
84
- "featured": false
85
- },
86
- {
87
- "id": "overta_hypothesis-md",
88
- "title": "The Overta Hypothesis: Knowledge-Free Foundation Models",
89
- "date": "2026-05",
90
- "author": "Amy",
91
- "tags": [
92
- "training",
93
- "alignment",
94
- "reasoning",
95
- "experimental"
96
- ],
97
- "proved": false,
98
- "featured": false
99
- },
100
- {
101
- "id": "attention_experiment-md",
102
- "title": "An Experiment With Attention",
103
- "date": "2026-05",
104
- "author": "wop",
105
- "tags": [
106
- "attention",
107
- "benchmark",
108
- "experimental"
109
- ],
110
- "proved": false,
111
- "featured": false
112
- },
113
- {
114
- "id": "sparrow_fant-md",
115
- "title": "Sparrow, FANT, and the Weird Stuff That Works",
116
- "date": "2026-05",
117
- "author": "Crownelius",
118
- "tags": [
119
- "math",
120
- "small-models",
121
- "experimental"
122
- ],
123
- "proved": false,
124
- "featured": false
125
- }
126
- ];
127
  (function() {
128
  var grid = document.getElementById('papersGrid');
 
 
 
 
 
 
 
 
129
 
130
- // Announce messages to screen readers via aria-live region
131
  function announce(msg) {
132
  var el = document.getElementById('announcer');
133
  if (el) {
134
  el.textContent = '';
135
- // Force re-announce by clearing then setting
136
  setTimeout(function() { el.textContent = msg; }, 50);
137
  }
138
  }
139
 
140
- if (PAPERS.length === 0) {
141
- grid.innerHTML = '<li class="empty-state" role="listitem"><p>No papers yet.</p></li>';
142
- return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
143
  }
144
- PAPERS.forEach(function(paper, i) {
145
- grid.appendChild(createCard(paper, i));
146
- });
147
 
148
  function createCard(paper, index) {
149
  var li = document.createElement('li');
150
  li.setAttribute('role', 'listitem');
151
 
152
- var card = document.createElement('div');
153
  card.className = 'paper-card' + (paper.featured ? ' featured' : '');
154
  card.style.animationDelay = (index * 80) + 'ms';
155
- card.setAttribute('tabindex', '0');
156
- card.setAttribute('role', 'button');
157
  card.setAttribute('aria-label', 'Read paper: ' + paper.title);
158
- if (paper.date) {
159
- card.setAttribute('aria-describedby', 'meta-' + paper.id);
160
- }
161
-
162
- var tagsHtml = '';
163
- if (paper.tags && paper.tags.length) {
164
- tagsHtml = paper.tags.map(function(t) {
165
- return '<span class="card-tag">' + escapeHtml(t) + '</span>';
166
- }).join(' ');
167
- }
168
 
169
  card.innerHTML =
170
  '<h3 class="card-title">' + escapeHtml(paper.title) + '</h3>' +
171
  (paper.author ? '<div class="card-author">' + escapeHtml(paper.author) + '</div>' : '') +
172
  '<div class="card-meta" id="meta-' + paper.id + '">' +
173
  (paper.date ? '<span>' + escapeHtml(paper.date) + '</span>' : '') +
174
- tagsHtml +
175
- (paper.proved ? '<span class="card-proved" aria-label="Theory proven">&check; PROVED</span>' : '') +
 
 
176
  '</div>' +
177
  '<span class="card-arrow" aria-hidden="true">&rarr;</span>';
178
 
179
- // Tilt effect
180
- card.addEventListener('mousemove', function(e) {
181
- if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
182
- var rect = card.getBoundingClientRect();
183
- var x = e.clientX - rect.left;
184
- var y = e.clientY - rect.top;
185
- card.style.setProperty('--mx', x + 'px');
186
- card.style.setProperty('--my', y + 'px');
187
- });
188
-
189
- card.addEventListener('mouseleave', function() {
190
- card.style.removeProperty('--mx');
191
- card.style.removeProperty('--my');
192
- });
193
-
194
- // Click handler
195
- card.addEventListener('click', function() {
196
- openPaper(paper, card);
197
- });
198
-
199
- // Keyboard handler: Enter or Space to activate
200
- card.addEventListener('keydown', function(e) {
201
- if (e.key === 'Enter' || e.key === ' ') {
202
- e.preventDefault();
203
- openPaper(paper, card);
204
- }
205
  });
206
 
207
  li.appendChild(card);
208
  return li;
209
  }
210
 
211
- function openPaper(paper, triggerEl) {
212
- var previousFocus = triggerEl || document.activeElement;
213
 
214
- var overlay = document.createElement('div');
215
- overlay.className = 'paper-overlay';
216
- overlay.setAttribute('role', 'dialog');
217
- overlay.setAttribute('aria-modal', 'true');
218
- overlay.setAttribute('aria-label', 'Paper: ' + paper.title);
219
 
220
- var view = document.createElement('div');
221
- view.className = 'paper-view';
222
- view.setAttribute('role', 'document');
223
- view.innerHTML =
224
- '<button class="paper-view-close" aria-label="Close paper viewer">&times;</button>' +
225
- '<iframe class="paper-view-frame" title="' + escapeHtml(paper.title) + '" src="Papers/' + paper.id + '.html"></iframe>';
226
 
227
- overlay.appendChild(view);
228
- document.body.appendChild(overlay);
229
- document.body.style.overflow = 'hidden';
 
 
230
 
231
- var closeBtn = view.querySelector('.paper-view-close');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
232
 
233
- closeBtn.focus();
 
 
234
 
235
- var close = function() {
236
- overlay.style.opacity = '0';
237
- overlay.style.transition = 'opacity 0.2s ease';
238
- setTimeout(function() {
239
- overlay.remove();
240
- document.body.style.overflow = '';
241
- if (previousFocus && typeof previousFocus.focus === 'function') {
242
- previousFocus.focus();
243
- }
244
- announce('Paper viewer closed.');
245
- }, 200);
246
- };
247
 
248
  closeBtn.addEventListener('click', close);
249
 
250
- overlay.addEventListener('click', function(e) {
251
- if (e.target === overlay) close();
 
 
 
 
 
 
 
 
 
 
 
 
 
252
  });
 
253
  document.addEventListener('keydown', function handler(e) {
 
 
 
 
254
  if (e.key === 'Escape') {
255
  close();
256
  document.removeEventListener('keydown', handler);
257
  }
 
 
 
 
 
 
 
 
 
 
 
 
258
  });
 
 
259
  }
260
 
261
- function escapeHtml(str) {
262
- var div = document.createElement('div');
263
- div.appendChild(document.createTextNode(str));
264
- return div.innerHTML;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
265
  }
266
  })();
267
  </script>
268
-
269
  </body>
270
  </html>
 
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
  <title>CompactAI Papers</title>
 
7
  <link rel="preconnect" href="https://fonts.googleapis.com">
8
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
9
  <link href="https://fonts.googleapis.com/css2?family=Geist:wght@300..700&family=Geist+Mono:wght@400;500&display=swap" rel="stylesheet">
10
+ <link rel="stylesheet" href="everything.css">
 
11
  </head>
12
  <body>
 
13
  <a href="#mainContent" class="skip-link">Skip to papers</a>
 
14
  <div class="sr-only" aria-live="polite" aria-atomic="true" id="announcer"></div>
15
 
16
  <header class="site-header">
 
18
  <h1 class="site-title">Compact<span class="gold">AI</span> Papers</h1>
19
  <p class="site-subtitle">Research &amp; ideas from the community</p>
20
  <div class="header-divider"></div>
21
+
22
+ <div class="toolbar" aria-label="Paper tools">
23
+ <label class="toolbar-search">
24
+ <span class="sr-only">Search papers</span>
25
+ <input id="paperSearch" type="search" placeholder="Search title, author, tags" autocomplete="off">
26
+ </label>
27
+ <label class="toolbar-select">
28
+ <span class="sr-only">Sort papers</span>
29
+ <select id="paperSort">
30
+ <option value="featured">Featured first</option>
31
+ <option value="newest">Newest first</option>
32
+ <option value="title">Title A to Z</option>
33
+ <option value="author">Author A to Z</option>
34
+ </select>
35
+ </label>
36
+ <button class="toolbar-chip is-active" type="button" data-filter="all">All</button>
37
+ <button class="toolbar-chip" type="button" data-filter="proved">Proved</button>
38
+ <button class="toolbar-chip" type="button" data-filter="featured">Featured</button>
39
+ <button class="toolbar-reset" type="button" id="resetFilters">Reset</button>
40
+ </div>
41
  </div>
42
  </header>
43
 
44
  <main class="container" id="mainContent" aria-label="Papers collection">
45
  <h2 class="section-label">Papers</h2>
46
  <ul class="papers-grid" id="papersGrid" role="list"></ul>
47
+ <p class="collection-status" id="collectionStatus" aria-live="polite"></p>
48
  </main>
49
 
50
  <section class="papermaker-callout" aria-label="Papermaker role">
51
+ <div class="container">
52
+ <p>Have an idea worth writing up? If a mod spots it and likes it, you might earn the <span class="role-name">@Papermaker</span> role &mdash; a nod that you helped push CompactAI forward.</p>
53
+ </div>
54
  </section>
55
 
56
  <footer class="site-footer">
 
61
 
62
  <script>
63
  var PAPERS = [
64
+ {
65
+ id: "trueact-md",
66
+ title: "TrueACT: A Different Kind of Neuron",
67
+ date: "2026-05",
68
+ author: "CompactAI",
69
+ tags: ["architecture", "neurons", "math", "experimental"],
70
+ proved: false,
71
+ featured: true
72
+ },
73
+ {
74
+ id: "STM_paper-md",
75
+ title: "STM and the Circle Thing",
76
+ date: "2026-05",
77
+ author: "Dragonoid",
78
+ tags: ["training", "experimental"],
79
+ proved: true,
80
+ featured: false,
81
+ proof_script_content: "import torch\nimport torch.nn as nn\nimport torch.optim as optim\nimport random\nimport numpy as np\n\n# STM (Subtractive Training Method) - Definitive Proof\n# Fix: Added Mastery Floor to prevent premature hard-task removal.\n\nN_EASY, N_HARD = 1000, 250\nMASTERY_THRESHOLD = 0.15\nEPOCHS = 25\n\ndef generate_math(difficulty=\"easy\"):\n if difficulty == \"easy\":\n a, b = random.randint(0, 9), random.randint(0, 9)\n else:\n a, b = random.randint(10, 99), random.randint(10, 99)\n return f\"{a}+{b}={a+b}\", difficulty\n\ntrain_raw = [generate_math(\"easy\") for _ in range(N_EASY)] + [generate_math(\"hard\") for _ in range(N_HARD)]\ntest_easy = [generate_math(\"easy\") for _ in range(200)]\ntest_hard = [generate_math(\"hard\") for _ in range(200)]\n\nchars = list(\"0123456789+=\") + [\"<PAD>\"]\nchar2idx = {c: i for i, c in enumerate(chars)}\nPAD_IDX, EQ_IDX = char2idx[\"<PAD>\"], char2idx[\"=\"]\n\ndef encode(data_list):\n max_l = max(len(d[0]) for d in data_list)\n X, Y = [], []\n for text, _ in data_list:\n enc = [char2idx[c] for c in text] + [PAD_IDX] * (max_l - len(text) + 1)\n X.append(enc[:-1]); Y.append(enc[1:])\n return torch.tensor(X), torch.tensor(Y)\n\nclass STM_Model(nn.Module):\n def __init__(self, vocab_size, hidden_size=128):\n super().__init__()\n self.embedding = nn.Embedding(vocab_size, hidden_size)\n self.rnn = nn.GRU(hidden_size, hidden_size, batch_first=True)\n self.fc = nn.Linear(hidden_size, vocab_size)\n def forward(self, x):\n out, _ = self.rnn(self.embedding(x))\n return self.fc(out)\n\nmodel = STM_Model(len(chars))\noptimizer = optim.Adam(model.parameters(), lr=0.003)\ncriterion = nn.CrossEntropyLoss(ignore_index=PAD_IDX, reduction='none')\n\ndef eval_acc(model, data_list):\n model.eval()\n X, Y = encode(data_list)\n with torch.no_grad():\n out = model(X).argmax(dim=-1)\n correct = 0\n for i in range(len(data_list)):\n eq_pos = (X[i] == EQ_IDX).nonzero(as_tuple=True)[0].item()\n pred = out[i, eq_pos:eq_pos+4]\n target = Y[i, eq_pos:eq_pos+4]\n mask = (target != PAD_IDX)\n if torch.equal(pred[mask], target[mask]): correct += 1\n return correct / len(data_list)\n\ndef get_metrics(model, data_list):\n model.eval()\n X, Y = encode(data_list)\n with torch.no_grad():\n out = model(X).view(-1, len(chars))\n loss = criterion(out, Y.view(-1)).view(X.size(0), X.size(1))\n ans_mask = ((X == EQ_IDX).cumsum(1) - (X == EQ_IDX).float()) * (Y != PAD_IDX).float()\n return ((loss * ans_mask).sum(1) / (ans_mask.sum(1) + 1e-8)).numpy()\n\ncurrent_dataset = list(train_raw)\nprev_losses = get_metrics(model, current_dataset)\ntotal_tokens = 0\ninitial_tokens = len(train_raw) * 12\n\nprint(f\"{'Epoch':<5} | {'Pool(E/H)':<10} | {'Acc(E/H)':<12} | {'Efficiency'}\")\nprint(\"-\" * 50)\n\nfor epoch in range(1, EPOCHS + 1):\n model.train()\n X, Y = encode(current_dataset)\n total_tokens += X.numel()\n indices = np.random.permutation(len(current_dataset))\n for i in range(0, len(current_dataset), 64):\n idx = indices[i:i+64]\n optimizer.zero_grad()\n loss = nn.CrossEntropyLoss(ignore_index=PAD_IDX)(model(X[idx]).view(-1, len(chars)), Y[idx].view(-1))\n loss.backward(); optimizer.step()\n\n curr_losses = get_metrics(model, current_dataset)\n drops = prev_losses - curr_losses\n drop_cutoff = drops.mean() + (drops.std() * 0.5)\n\n keep_indices = []\n for i in range(len(current_dataset)):\n if (drops[i] > drop_cutoff and curr_losses[i] < 0.5) or curr_losses[i] < MASTERY_THRESHOLD:\n pass\n else:\n keep_indices.append(i)\n\n e_rem = sum(1 for _, l in current_dataset if l == \"easy\")\n h_rem = sum(1 for _, l in current_dataset if l == \"hard\")\n acc_e = eval_acc(model, test_easy)\n acc_h = eval_acc(model, test_hard)\n efficiency = (initial_tokens * epoch) / total_tokens\n\n print(f\"{epoch:<5} | {e_rem:>4}/{h_rem:<4} | {acc_e:>5.1%}/{acc_h:<5.1%} | {efficiency:.2f}x\")\n\n if not keep_indices: break\n current_dataset = [current_dataset[i] for i in keep_indices]\n prev_losses = curr_losses[keep_indices]\n\nprint(\"\\nSTM proof complete. The theory works — now with the Mastery Floor fix.\")"
82
+ },
83
+ {
84
+ id: "apollonian_gasket-md",
85
+ title: "Token Embeddings Inside an Integer Apollonian Gasket",
86
+ date: "2026-05",
87
+ author: "Mage",
88
+ tags: ["embeddings", "geometry", "number-theory", "experimental"],
89
+ proved: false,
90
+ featured: false
91
+ },
92
+ {
93
+ id: "overta_hypothesis-md",
94
+ title: "The Overta Hypothesis: Knowledge-Free Foundation Models",
95
+ date: "2026-05",
96
+ author: "Amy",
97
+ tags: ["training", "alignment", "reasoning", "experimental"],
98
+ proved: false,
99
+ featured: false
100
+ },
101
+ {
102
+ id: "attention_experiment-md",
103
+ title: "An Experiment With Attention",
104
+ date: "2026-05",
105
+ author: "wop",
106
+ tags: ["attention", "benchmark", "experimental"],
107
+ proved: false,
108
+ featured: false
109
+ },
110
+ {
111
+ id: "sparrow_fant-md",
112
+ title: "Sparrow, FANT, and the Weird Stuff That Works",
113
+ date: "2026-05",
114
+ author: "Crownelius",
115
+ tags: ["math", "small-models", "experimental"],
116
+ proved: false,
117
+ featured: false
118
+ }
119
+ ];
120
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
121
  (function() {
122
  var grid = document.getElementById('papersGrid');
123
+ var searchInput = document.getElementById('paperSearch');
124
+ var sortSelect = document.getElementById('paperSort');
125
+ var resetButton = document.getElementById('resetFilters');
126
+ var filterButtons = document.querySelectorAll('[data-filter]');
127
+ var collectionStatus = document.getElementById('collectionStatus');
128
+ var currentFilter = 'all';
129
+ var viewerContainer = null;
130
+ var modalState = null;
131
 
 
132
  function announce(msg) {
133
  var el = document.getElementById('announcer');
134
  if (el) {
135
  el.textContent = '';
 
136
  setTimeout(function() { el.textContent = msg; }, 50);
137
  }
138
  }
139
 
140
+ function escapeHtml(str) {
141
+ var div = document.createElement('div');
142
+ div.appendChild(document.createTextNode(str));
143
+ return div.innerHTML;
144
+ }
145
+
146
+ function getPaperById(paperId) {
147
+ for (var i = 0; i < PAPERS.length; i++) {
148
+ if (PAPERS[i].id === paperId) return PAPERS[i];
149
+ }
150
+ return null;
151
+ }
152
+
153
+ function matchesFilter(paper) {
154
+ if (currentFilter === 'proved' && !paper.proved) return false;
155
+ if (currentFilter === 'featured' && !paper.featured) return false;
156
+ return true;
157
+ }
158
+
159
+ function matchesSearch(paper, query) {
160
+ if (!query) return true;
161
+ return [paper.title, paper.author, paper.date, (paper.tags || []).join(' ')].join(' ').toLowerCase().indexOf(query) !== -1;
162
+ }
163
+
164
+ function sortPapers(items) {
165
+ var sorted = items.slice();
166
+ var sortValue = sortSelect.value;
167
+ sorted.sort(function(a, b) {
168
+ if (sortValue === 'title') return a.title.localeCompare(b.title);
169
+ if (sortValue === 'author') return (a.author || '').localeCompare(b.author || '');
170
+ if (sortValue === 'newest') return (b.date || '').localeCompare(a.date || '');
171
+ if (b.featured !== a.featured) return (b.featured ? 1 : 0) - (a.featured ? 1 : 0);
172
+ return 0;
173
+ });
174
+ return sorted;
175
+ }
176
+
177
+ function renderGrid() {
178
+ var query = searchInput.value.trim().toLowerCase();
179
+ var visible = sortPapers(PAPERS.filter(function(paper) {
180
+ return matchesFilter(paper) && matchesSearch(paper, query);
181
+ }));
182
+
183
+ grid.innerHTML = '';
184
+
185
+ if (visible.length === 0) {
186
+ grid.innerHTML = '<li class="empty-state" role="listitem"><p>No papers match these filters.</p><button type="button" id="clearEmptyState">Clear filters</button></li>';
187
+ document.getElementById('clearEmptyState').addEventListener('click', resetFilters);
188
+ collectionStatus.textContent = '0 papers shown.';
189
+ return;
190
+ }
191
+
192
+ visible.forEach(function(paper, index) {
193
+ grid.appendChild(createCard(paper, index));
194
+ });
195
+
196
+ collectionStatus.textContent = visible.length + ' papers shown.';
197
+ }
198
+
199
+ function setFilter(nextFilter) {
200
+ currentFilter = nextFilter;
201
+ filterButtons.forEach(function(button) {
202
+ button.classList.toggle('is-active', button.getAttribute('data-filter') === nextFilter);
203
+ });
204
+ renderGrid();
205
+ }
206
+
207
+ function resetFilters() {
208
+ currentFilter = 'all';
209
+ searchInput.value = '';
210
+ sortSelect.value = 'featured';
211
+ filterButtons.forEach(function(button) {
212
+ button.classList.toggle('is-active', button.getAttribute('data-filter') === 'all');
213
+ });
214
+ renderGrid();
215
+ announce('Filters cleared.');
216
+ }
217
+
218
+ function syncUrl(paperId) {
219
+ var url = new URL(window.location.href);
220
+ if (paperId) {
221
+ url.searchParams.set('paper', paperId);
222
+ } else {
223
+ url.searchParams.delete('paper');
224
+ }
225
+ window.history.pushState({ paper: paperId }, '', url.toString());
226
  }
 
 
 
227
 
228
  function createCard(paper, index) {
229
  var li = document.createElement('li');
230
  li.setAttribute('role', 'listitem');
231
 
232
+ var card = document.createElement('a');
233
  card.className = 'paper-card' + (paper.featured ? ' featured' : '');
234
  card.style.animationDelay = (index * 80) + 'ms';
235
+ card.href = '#paper-' + paper.id;
 
236
  card.setAttribute('aria-label', 'Read paper: ' + paper.title);
 
 
 
 
 
 
 
 
 
 
237
 
238
  card.innerHTML =
239
  '<h3 class="card-title">' + escapeHtml(paper.title) + '</h3>' +
240
  (paper.author ? '<div class="card-author">' + escapeHtml(paper.author) + '</div>' : '') +
241
  '<div class="card-meta" id="meta-' + paper.id + '">' +
242
  (paper.date ? '<span>' + escapeHtml(paper.date) + '</span>' : '') +
243
+ ((paper.tags || []).map(function(tag) {
244
+ return '<span class="card-tag">' + escapeHtml(tag) + '</span>';
245
+ }).join(' ')) +
246
+ (paper.proved ? '<span class="card-proved">&check; PROVED</span>' : '') +
247
  '</div>' +
248
  '<span class="card-arrow" aria-hidden="true">&rarr;</span>';
249
 
250
+ card.addEventListener('click', function(e) {
251
+ e.preventDefault();
252
+ openPaper(paper, card, true);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
253
  });
254
 
255
  li.appendChild(card);
256
  return li;
257
  }
258
 
259
+ function openPaper(paper, triggerEl, pushState) {
260
+ closeViewer(false);
261
 
262
+ modalState = {
263
+ previousFocus: triggerEl || document.activeElement,
264
+ paper: paper
265
+ };
 
266
 
267
+ if (pushState !== false) syncUrl(paper.id);
 
 
 
 
 
268
 
269
+ viewerContainer = document.createElement('div');
270
+ viewerContainer.className = 'paper-overlay';
271
+ viewerContainer.setAttribute('role', 'dialog');
272
+ viewerContainer.setAttribute('aria-modal', 'true');
273
+ viewerContainer.setAttribute('aria-labelledby', 'paperDialogTitle');
274
 
275
+ viewerContainer.innerHTML =
276
+ '<div class="paper-view" role="document">' +
277
+ '<button class="paper-view-close" type="button" aria-label="Close paper viewer">&times;</button>' +
278
+ '<div class="paper-page">' +
279
+ '<div class="paper-page-shell">' +
280
+ '<h2 id="paperDialogTitle" class="paper-page-title">' + escapeHtml(paper.title) + '</h2>' +
281
+ '<div class="paper-page-meta">' + escapeHtml(paper.author || 'CompactAI') + (paper.date ? ' · ' + escapeHtml(paper.date) : '') + '</div>' +
282
+ '<div class="paper-page-actions">' +
283
+ '<a class="paper-view-link" href="Papers/' + escapeHtml(paper.id) + '.html" target="_blank" rel="noopener">Open in new tab</a>' +
284
+ '<button class="paper-view-link" type="button" data-action="copy">Copy link</button>' +
285
+ '</div>' +
286
+ '<iframe class="paper-view-frame" title="' + escapeHtml(paper.title) + '" src="Papers/' + paper.id + '.html"></iframe>' +
287
+ '</div>' +
288
+ '</div>' +
289
+ '</div>';
290
 
291
+ document.body.appendChild(viewerContainer);
292
+ document.body.style.overflow = 'hidden';
293
+ document.querySelector('main').setAttribute('inert', '');
294
 
295
+ var closeBtn = viewerContainer.querySelector('.paper-view-close');
296
+ var copyBtn = viewerContainer.querySelector('[data-action="copy"]');
297
+ var iframe = viewerContainer.querySelector('.paper-view-frame');
298
+
299
+ function close() {
300
+ closeViewer(true);
301
+ }
 
 
 
 
 
302
 
303
  closeBtn.addEventListener('click', close);
304
 
305
+ copyBtn.addEventListener('click', function() {
306
+ var link = window.location.origin + window.location.pathname + '?paper=' + encodeURIComponent(paper.id);
307
+ if (navigator.clipboard && navigator.clipboard.writeText) {
308
+ navigator.clipboard.writeText(link).then(function() {
309
+ announce('Paper link copied.');
310
+ });
311
+ }
312
+ });
313
+
314
+ viewerContainer.addEventListener('click', function(e) {
315
+ if (e.target === viewerContainer) close();
316
+ });
317
+
318
+ iframe.addEventListener('load', function() {
319
+ announce('Opened paper viewer: ' + paper.title);
320
  });
321
+
322
  document.addEventListener('keydown', function handler(e) {
323
+ if (!viewerContainer) {
324
+ document.removeEventListener('keydown', handler);
325
+ return;
326
+ }
327
  if (e.key === 'Escape') {
328
  close();
329
  document.removeEventListener('keydown', handler);
330
  }
331
+ if (e.key === 'Tab') {
332
+ var focusable = viewerContainer.querySelectorAll('button, a, iframe');
333
+ var first = focusable[0];
334
+ var last = focusable[focusable.length - 1];
335
+ if (e.shiftKey && document.activeElement === first) {
336
+ last.focus();
337
+ e.preventDefault();
338
+ } else if (!e.shiftKey && document.activeElement === last) {
339
+ first.focus();
340
+ e.preventDefault();
341
+ }
342
+ }
343
  });
344
+
345
+ closeBtn.focus();
346
  }
347
 
348
+ function closeViewer(syncHistory) {
349
+ if (!viewerContainer) return;
350
+ var previousFocus = modalState && modalState.previousFocus;
351
+ viewerContainer.remove();
352
+ viewerContainer = null;
353
+ modalState = null;
354
+ document.body.style.overflow = '';
355
+ document.querySelector('main').removeAttribute('inert');
356
+ if (syncHistory !== false) syncUrl(null);
357
+ if (previousFocus && typeof previousFocus.focus === 'function') previousFocus.focus();
358
+ announce('Paper viewer closed.');
359
+ }
360
+
361
+ searchInput.addEventListener('input', renderGrid);
362
+ sortSelect.addEventListener('change', renderGrid);
363
+ resetButton.addEventListener('click', resetFilters);
364
+ filterButtons.forEach(function(button) {
365
+ button.addEventListener('click', function() {
366
+ setFilter(button.getAttribute('data-filter'));
367
+ });
368
+ });
369
+
370
+ window.addEventListener('popstate', function() {
371
+ var params = new URLSearchParams(window.location.search);
372
+ var paperId = params.get('paper');
373
+ if (!paperId) {
374
+ closeViewer(false);
375
+ return;
376
+ }
377
+ var paper = getPaperById(paperId);
378
+ if (paper) openPaper(paper, null, false);
379
+ });
380
+
381
+ renderGrid();
382
+
383
+ var initialPaperId = new URLSearchParams(window.location.search).get('paper');
384
+ if (initialPaperId) {
385
+ var initialPaper = getPaperById(initialPaperId);
386
+ if (initialPaper) openPaper(initialPaper, null, false);
387
  }
388
  })();
389
  </script>
 
390
  </body>
391
  </html>