projview 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,551 @@
1
+ /* ---- projview: soft dark + a little cartoonish (catppuccin-mocha-ish) ---- */
2
+
3
+ :root {
4
+ --base: #1e1e2e;
5
+ --mantle: #181825;
6
+ --crust: #11111b;
7
+ --surface0: #2a2b3c;
8
+ --surface1: #393a4d;
9
+ --surface2: #494b63;
10
+ --text: #cdd6f4;
11
+ --subtext: #a6adc8;
12
+ --overlay: #6c7086;
13
+ --lavender: #b4befe;
14
+ --mauve: #cba6f7;
15
+ --peach: #fab387;
16
+ --green: #a6e3a1;
17
+ --blue: #89b4fa;
18
+ --pink: #f5c2e7;
19
+ --red: #f38ba8;
20
+
21
+ --radius: 16px;
22
+ --radius-sm: 10px;
23
+ --font: "SF Pro Rounded", ui-rounded, "Nunito", "Quicksand", system-ui, -apple-system, sans-serif;
24
+ --mono: "JetBrains Mono", "Fira Code", ui-monospace, SFMono-Regular, Menlo, monospace;
25
+ --shadow: 0 6px 20px rgba(0, 0, 0, 0.35);
26
+ --shadow-sm: 0 3px 10px rgba(0, 0, 0, 0.28);
27
+ }
28
+
29
+ * { box-sizing: border-box; }
30
+
31
+ html, body {
32
+ margin: 0;
33
+ height: 100%;
34
+ background: var(--base);
35
+ color: var(--text);
36
+ font-family: var(--font);
37
+ font-size: 15px;
38
+ line-height: 1.6;
39
+ }
40
+
41
+ body {
42
+ display: flex;
43
+ overflow: hidden;
44
+ }
45
+
46
+ /* ---------------- sidebar ---------------- */
47
+
48
+ #sidebar {
49
+ width: 300px;
50
+ flex: 0 0 300px;
51
+ height: 100vh;
52
+ background: var(--mantle);
53
+ border-right: 2px solid var(--surface0);
54
+ display: flex;
55
+ flex-direction: column;
56
+ }
57
+
58
+ #brand {
59
+ display: flex;
60
+ align-items: center;
61
+ gap: 12px;
62
+ padding: 18px 16px;
63
+ border-bottom: 2px solid var(--surface0);
64
+ }
65
+
66
+ #brand .logo {
67
+ font-size: 28px;
68
+ filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.4));
69
+ }
70
+
71
+ .brand-text { display: flex; flex-direction: column; line-height: 1.2; }
72
+ .brand-text strong { font-size: 17px; color: var(--lavender); letter-spacing: 0.2px; }
73
+
74
+ #live-status {
75
+ display: inline-flex;
76
+ align-items: center;
77
+ gap: 6px;
78
+ color: var(--green);
79
+ font-size: 12px;
80
+ font-weight: 600;
81
+ }
82
+ #live-status .dot {
83
+ width: 8px; height: 8px; border-radius: 50%;
84
+ background: var(--green);
85
+ box-shadow: 0 0 8px var(--green);
86
+ transition: background 0.2s, box-shadow 0.2s;
87
+ }
88
+ #live-status.off { color: var(--overlay); }
89
+ #live-status .dot.off { background: var(--overlay); box-shadow: none; }
90
+ #live-status.pulse .dot { animation: blip 0.6s ease; }
91
+ @keyframes blip {
92
+ 0% { transform: scale(1); }
93
+ 40% { transform: scale(2.2); }
94
+ 100% { transform: scale(1); }
95
+ }
96
+
97
+ .open-palette {
98
+ display: flex;
99
+ align-items: center;
100
+ gap: 8px;
101
+ width: calc(100% - 24px);
102
+ margin: 12px;
103
+ padding: 8px 10px;
104
+ border: 2px solid var(--surface0);
105
+ border-radius: var(--radius-sm);
106
+ background: var(--base);
107
+ color: var(--overlay);
108
+ font-family: inherit;
109
+ font-size: 13px;
110
+ cursor: pointer;
111
+ transition: border-color 0.15s ease, color 0.15s ease;
112
+ }
113
+ .open-palette:hover { border-color: var(--mauve); color: var(--subtext); }
114
+ .open-palette .op-ico { font-size: 12px; }
115
+ .open-palette .op-text { flex: 1; text-align: left; }
116
+ .open-palette kbd, .palette kbd {
117
+ font-family: var(--mono);
118
+ font-size: 10px;
119
+ background: var(--surface0);
120
+ color: var(--subtext);
121
+ border-radius: 5px;
122
+ padding: 2px 5px;
123
+ }
124
+
125
+ .tree {
126
+ flex: 1;
127
+ overflow-y: auto;
128
+ padding: 4px 8px 10px;
129
+ }
130
+
131
+ #side-foot {
132
+ padding: 10px 16px;
133
+ border-top: 2px solid var(--surface0);
134
+ color: var(--overlay);
135
+ font-size: 11px;
136
+ }
137
+
138
+ /* tree rows */
139
+ .row {
140
+ display: flex;
141
+ align-items: center;
142
+ gap: 7px;
143
+ width: 100%;
144
+ padding: 5px 8px;
145
+ margin: 1px 0;
146
+ border: none;
147
+ border-radius: 8px;
148
+ background: transparent;
149
+ color: var(--subtext);
150
+ font-family: inherit;
151
+ font-size: 13px;
152
+ text-align: left;
153
+ cursor: pointer;
154
+ transition: background 0.13s ease, color 0.13s ease;
155
+ }
156
+ .row:hover { background: var(--surface0); color: var(--text); }
157
+ .row .twist { flex: 0 0 12px; color: var(--overlay); font-size: 9px; text-align: center; }
158
+ .row .ico { flex: 0 0 15px; height: 15px; display: inline-flex; align-items: center; }
159
+ .row .ico svg { width: 15px; height: 15px; }
160
+ .row.dir .ico { color: var(--subtext); }
161
+ .row .ico-md { color: var(--overlay); }
162
+ .row .ico-mmd { color: var(--mauve); }
163
+ .row .label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
164
+ .row.dir .label { font-weight: 600; color: var(--text); }
165
+
166
+ .row.file.active {
167
+ background: linear-gradient(90deg, var(--mauve), var(--lavender));
168
+ color: var(--crust);
169
+ font-weight: 700;
170
+ box-shadow: var(--shadow-sm);
171
+ }
172
+ .row.file.active .ico { color: var(--crust); }
173
+
174
+ /* nested indentation with guide lines */
175
+ .children {
176
+ margin-left: 15px;
177
+ border-left: 1px solid var(--surface0);
178
+ padding-left: 3px;
179
+ }
180
+
181
+ /* ---------------- viewer ---------------- */
182
+
183
+ #viewer {
184
+ flex: 1;
185
+ height: 100vh;
186
+ overflow-y: auto;
187
+ position: relative;
188
+ }
189
+
190
+ #breadcrumb {
191
+ position: sticky;
192
+ top: 0;
193
+ z-index: 5;
194
+ display: flex;
195
+ align-items: center;
196
+ flex-wrap: wrap;
197
+ gap: 3px;
198
+ padding: 12px 40px;
199
+ background: rgba(30, 30, 46, 0.92);
200
+ backdrop-filter: blur(6px);
201
+ -webkit-backdrop-filter: blur(6px);
202
+ border-bottom: 1px solid var(--surface0);
203
+ font-size: 12.5px;
204
+ }
205
+ .crumb { background: none; border: none; font: inherit; color: var(--subtext); padding: 2px 5px; border-radius: 6px; }
206
+ .crumb.root { color: var(--overlay); }
207
+ .crumb.dir { cursor: pointer; }
208
+ .crumb.dir:hover { color: var(--lavender); background: var(--surface0); }
209
+ .crumb.current { color: var(--lavender); font-weight: 700; }
210
+ .crumb-sep { color: var(--overlay); opacity: 0.55; }
211
+
212
+ #content { max-width: 880px; margin: 0 auto; padding: 30px 48px 90px; }
213
+
214
+ .empty-state {
215
+ display: flex;
216
+ flex-direction: column;
217
+ align-items: center;
218
+ justify-content: center;
219
+ height: 70vh;
220
+ color: var(--overlay);
221
+ gap: 10px;
222
+ text-align: center;
223
+ }
224
+ .empty-emoji { font-size: 56px; }
225
+ .empty-state .muted { font-size: 13px; opacity: 0.8; }
226
+
227
+ /* ---------------- markdown ---------------- */
228
+
229
+ .markdown-body h1, .markdown-body h2, .markdown-body h3,
230
+ .markdown-body h4, .markdown-body h5, .markdown-body h6 {
231
+ color: var(--lavender);
232
+ line-height: 1.3;
233
+ margin: 1.6em 0 0.6em;
234
+ scroll-margin-top: 56px; /* clear the sticky breadcrumb when an #anchor jumps here */
235
+ }
236
+ .markdown-body h1 { font-size: 2em; border-bottom: 2px solid var(--surface0); padding-bottom: 0.3em; }
237
+ .markdown-body h2 { font-size: 1.5em; border-bottom: 1px solid var(--surface0); padding-bottom: 0.25em; }
238
+ .markdown-body h3 { font-size: 1.25em; color: var(--mauve); }
239
+
240
+ .markdown-body a { color: var(--blue); text-decoration: none; border-bottom: 1px dashed var(--blue); }
241
+ .markdown-body a:hover { color: var(--pink); border-bottom-color: var(--pink); }
242
+
243
+ .markdown-body p, .markdown-body li { color: var(--text); }
244
+ .markdown-body strong { color: var(--peach); }
245
+
246
+ .markdown-body code {
247
+ font-family: var(--mono);
248
+ font-size: 0.88em;
249
+ background: var(--surface0);
250
+ padding: 2px 6px;
251
+ border-radius: 6px;
252
+ color: var(--peach);
253
+ }
254
+
255
+ .markdown-body pre,
256
+ .markdown-body pre.hljs {
257
+ background: var(--crust) !important;
258
+ border: 2px solid var(--surface0);
259
+ border-radius: var(--radius);
260
+ padding: 16px 18px;
261
+ overflow-x: auto;
262
+ box-shadow: var(--shadow-sm);
263
+ }
264
+ .markdown-body pre code { background: none; padding: 0; color: inherit; font-size: 0.86em; }
265
+
266
+ .markdown-body blockquote {
267
+ margin: 1em 0;
268
+ padding: 4px 18px;
269
+ border-left: 4px solid var(--mauve);
270
+ background: var(--mantle);
271
+ border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
272
+ color: var(--subtext);
273
+ }
274
+
275
+ .markdown-body table {
276
+ border-collapse: collapse;
277
+ width: 100%;
278
+ margin: 1em 0;
279
+ border-radius: var(--radius-sm);
280
+ overflow: hidden;
281
+ box-shadow: var(--shadow-sm);
282
+ }
283
+ .markdown-body th, .markdown-body td {
284
+ border: 1px solid var(--surface0);
285
+ padding: 9px 14px;
286
+ }
287
+ .markdown-body th { background: var(--surface0); color: var(--lavender); }
288
+ .markdown-body tr:nth-child(even) td { background: var(--mantle); }
289
+
290
+ .markdown-body hr { border: none; border-top: 2px dashed var(--surface1); margin: 2em 0; }
291
+
292
+ .markdown-body img { max-width: 100%; border-radius: var(--radius-sm); }
293
+
294
+ .markdown-body ul, .markdown-body ol { padding-left: 1.5em; }
295
+
296
+ /* mermaid card */
297
+ .mermaid {
298
+ display: flex;
299
+ justify-content: center;
300
+ background: var(--mantle);
301
+ border: 2px solid var(--surface0);
302
+ border-radius: var(--radius);
303
+ padding: 22px;
304
+ margin: 1.4em 0;
305
+ box-shadow: var(--shadow-sm);
306
+ }
307
+ .mermaid svg { max-width: 100%; height: auto; }
308
+ .mermaid.rendered { cursor: zoom-in; }
309
+ .mermaid.mermaid-error { display: block; border-color: var(--red); background: rgba(243, 139, 168, 0.06); }
310
+ .diagram-error { color: var(--red); width: 100%; text-align: left; }
311
+ .diagram-error .err-msg {
312
+ margin: 8px 0;
313
+ background: var(--crust) !important;
314
+ border: 1px solid var(--red);
315
+ color: var(--red);
316
+ font-size: 0.82em;
317
+ white-space: pre-wrap;
318
+ }
319
+ .diagram-error details { margin-top: 6px; color: var(--subtext); font-size: 0.85em; }
320
+ .diagram-error summary { cursor: pointer; }
321
+ .diagram-error details pre { margin-top: 6px; }
322
+
323
+ /* ---------------- right-side TOC ---------------- */
324
+
325
+ #toc {
326
+ flex: 0 0 240px;
327
+ width: 240px;
328
+ height: 100vh;
329
+ background: var(--mantle);
330
+ border-left: 2px solid var(--surface0);
331
+ display: flex;
332
+ flex-direction: column;
333
+ overflow: hidden;
334
+ }
335
+ .toc-head {
336
+ display: flex;
337
+ align-items: center;
338
+ justify-content: space-between;
339
+ padding: 16px 14px 10px;
340
+ font-size: 11px;
341
+ text-transform: uppercase;
342
+ letter-spacing: 0.08em;
343
+ color: var(--overlay);
344
+ font-weight: 700;
345
+ }
346
+ #toc-collapse {
347
+ background: none; border: none; color: var(--overlay);
348
+ cursor: pointer; font-size: 14px; padding: 2px 7px; border-radius: 6px; line-height: 1;
349
+ }
350
+ #toc-collapse:hover { background: var(--surface0); color: var(--text); }
351
+
352
+ #toc-list { flex: 1; overflow-y: auto; padding: 0 8px 16px; }
353
+ .toc-item {
354
+ display: block;
355
+ width: 100%;
356
+ text-align: left;
357
+ background: none;
358
+ border: none;
359
+ border-left: 2px solid transparent;
360
+ color: var(--subtext);
361
+ font: inherit;
362
+ font-size: 12.5px;
363
+ line-height: 1.35;
364
+ padding: 5px 8px;
365
+ border-radius: 0 6px 6px 0;
366
+ cursor: pointer;
367
+ overflow: hidden;
368
+ text-overflow: ellipsis;
369
+ white-space: nowrap;
370
+ transition: color 0.12s, background 0.12s, border-color 0.12s;
371
+ }
372
+ .toc-item:hover { color: var(--text); background: var(--surface0); }
373
+ .toc-item.lvl-h1 { font-weight: 700; color: var(--text); }
374
+ .toc-item.lvl-h2 { padding-left: 18px; }
375
+ .toc-item.lvl-h3 { padding-left: 30px; font-size: 12px; }
376
+ .toc-item.active { color: var(--lavender); border-left-color: var(--mauve); background: var(--surface0); }
377
+
378
+ #toc-reopen {
379
+ position: fixed;
380
+ top: 14px; right: 14px;
381
+ z-index: 20;
382
+ display: none;
383
+ width: 34px; height: 34px;
384
+ border-radius: 9px;
385
+ border: 2px solid var(--surface0);
386
+ background: var(--mantle);
387
+ color: var(--subtext);
388
+ cursor: pointer;
389
+ font-size: 15px;
390
+ }
391
+ #toc-reopen:hover { color: var(--lavender); border-color: var(--mauve); }
392
+
393
+ body.toc-collapsed #toc { display: none; }
394
+ body.toc-collapsed #toc-reopen { display: block; }
395
+ body.toc-empty #toc { display: none; }
396
+ body.toc-empty #toc-reopen { display: none; }
397
+
398
+ /* ---------------- search palette (cmd+K) ---------------- */
399
+
400
+ .palette {
401
+ position: fixed;
402
+ inset: 0;
403
+ z-index: 70;
404
+ display: flex;
405
+ justify-content: center;
406
+ align-items: flex-start;
407
+ padding-top: 12vh;
408
+ background: rgba(17, 17, 27, 0.55);
409
+ backdrop-filter: blur(3px);
410
+ -webkit-backdrop-filter: blur(3px);
411
+ }
412
+ .palette[hidden] { display: none; }
413
+ .palette-box {
414
+ width: min(640px, 92vw);
415
+ max-height: 70vh;
416
+ display: flex;
417
+ flex-direction: column;
418
+ background: var(--mantle);
419
+ border: 2px solid var(--surface1);
420
+ border-radius: var(--radius);
421
+ box-shadow: var(--shadow);
422
+ overflow: hidden;
423
+ }
424
+ #palette-input {
425
+ padding: 16px 18px;
426
+ border: none;
427
+ border-bottom: 2px solid var(--surface0);
428
+ background: transparent;
429
+ color: var(--text);
430
+ font-family: inherit;
431
+ font-size: 16px;
432
+ outline: none;
433
+ }
434
+ #palette-input::placeholder { color: var(--overlay); }
435
+ .palette-results { overflow-y: auto; padding: 6px; }
436
+ .palette-hint { padding: 22px; text-align: center; color: var(--overlay); font-size: 13px; }
437
+ .pg-head {
438
+ padding: 8px 10px 4px;
439
+ font-size: 10px;
440
+ text-transform: uppercase;
441
+ letter-spacing: 0.08em;
442
+ color: var(--overlay);
443
+ font-weight: 700;
444
+ }
445
+ .presult { padding: 7px 10px; border-radius: var(--radius-sm); cursor: pointer; }
446
+ .presult.sel { background: var(--surface0); }
447
+ .pr-main { display: flex; align-items: center; gap: 8px; }
448
+ .pr-ico { flex: 0 0 15px; height: 15px; color: var(--overlay); display: inline-flex; align-items: center; }
449
+ .pr-ico svg { width: 15px; height: 15px; }
450
+ .presult.sel .pr-ico { color: var(--mauve); }
451
+ .pr-name { color: var(--text); font-size: 14px; font-weight: 600; }
452
+ .pr-badge { color: var(--peach); font-size: 11px; font-family: var(--mono); }
453
+ .pr-path {
454
+ margin-left: auto;
455
+ color: var(--overlay);
456
+ font-size: 11px;
457
+ font-family: var(--mono);
458
+ overflow: hidden;
459
+ text-overflow: ellipsis;
460
+ white-space: nowrap;
461
+ max-width: 45%;
462
+ }
463
+ .snip {
464
+ margin: 3px 0 0 23px;
465
+ font-family: var(--mono);
466
+ font-size: 11.5px;
467
+ color: var(--subtext);
468
+ white-space: nowrap;
469
+ overflow: hidden;
470
+ text-overflow: ellipsis;
471
+ }
472
+ .snip-ln { color: var(--overlay); margin-right: 8px; }
473
+ .palette mark { background: transparent; color: var(--peach); font-weight: 700; padding: 0; }
474
+ .palette-foot {
475
+ display: flex;
476
+ gap: 16px;
477
+ padding: 8px 14px;
478
+ border-top: 2px solid var(--surface0);
479
+ color: var(--overlay);
480
+ font-size: 11px;
481
+ }
482
+
483
+ /* in-content highlight when opening a search hit */
484
+ mark.search-hit {
485
+ background: var(--peach);
486
+ color: var(--crust);
487
+ border-radius: 3px;
488
+ padding: 0 2px;
489
+ animation: hitflash 0.45s ease;
490
+ }
491
+ @keyframes hitflash { from { background: var(--green); } to { background: var(--peach); } }
492
+
493
+ /* ---------------- toast ---------------- */
494
+
495
+ .toast {
496
+ position: fixed;
497
+ bottom: 22px;
498
+ left: 50%;
499
+ transform: translateX(-50%) translateY(12px);
500
+ z-index: 50;
501
+ background: var(--surface1);
502
+ color: var(--text);
503
+ border: 2px solid var(--surface2);
504
+ border-radius: var(--radius-sm);
505
+ padding: 10px 16px;
506
+ font-size: 13px;
507
+ box-shadow: var(--shadow);
508
+ opacity: 0;
509
+ pointer-events: none;
510
+ transition: opacity 0.2s ease, transform 0.2s ease;
511
+ }
512
+ .toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }
513
+
514
+ /* ---------------- mermaid zoom overlay ---------------- */
515
+
516
+ .zoom-overlay {
517
+ position: fixed;
518
+ inset: 0;
519
+ z-index: 60;
520
+ display: flex;
521
+ align-items: center;
522
+ justify-content: center;
523
+ overflow: hidden;
524
+ background: rgba(17, 17, 27, 0.93);
525
+ }
526
+ .zoom-overlay[hidden] { display: none; }
527
+ .zoom-hint {
528
+ position: fixed;
529
+ top: 16px; left: 50%;
530
+ transform: translateX(-50%);
531
+ color: var(--overlay);
532
+ font-size: 12px;
533
+ background: var(--mantle);
534
+ padding: 6px 12px;
535
+ border-radius: 8px;
536
+ border: 1px solid var(--surface0);
537
+ }
538
+ .zoom-inner {
539
+ cursor: grab;
540
+ transform-origin: center center;
541
+ will-change: transform;
542
+ touch-action: none;
543
+ }
544
+ .zoom-inner:active { cursor: grabbing; }
545
+ .zoom-inner svg { max-width: 86vw; max-height: 82vh; }
546
+
547
+ /* scrollbars */
548
+ ::-webkit-scrollbar { width: 11px; height: 11px; }
549
+ ::-webkit-scrollbar-thumb { background: var(--surface1); border-radius: 20px; border: 2px solid var(--mantle); }
550
+ ::-webkit-scrollbar-thumb:hover { background: var(--surface2); }
551
+ ::-webkit-scrollbar-track { background: transparent; }
@@ -0,0 +1,15 @@
1
+ /* transient bottom toast for non-blocking notices */
2
+
3
+ import { $ } from './dom.js';
4
+
5
+ const toastEl = $('toast');
6
+ let toastTimer;
7
+
8
+ export function toast(msg) {
9
+ toastEl.textContent = msg;
10
+ toastEl.hidden = false;
11
+ void toastEl.offsetWidth; // reflow so the transition replays on rapid repeats
12
+ toastEl.classList.add('show');
13
+ clearTimeout(toastTimer);
14
+ toastTimer = setTimeout(() => toastEl.classList.remove('show'), 2600);
15
+ }
package/public/toc.js ADDED
@@ -0,0 +1,51 @@
1
+ /* right-side table of contents (h1-h3) + scroll-spy + collapse */
2
+
3
+ import { $ } from './dom.js';
4
+ import { scrollToFragment } from './viewer.js';
5
+
6
+ const contentEl = $('content');
7
+ const viewerEl = $('viewer');
8
+ const tocListEl = $('toc-list');
9
+
10
+ let tocEntries = []; // [{ id, el, link }]
11
+
12
+ export function buildToc() {
13
+ const headings = [...contentEl.querySelectorAll('h1, h2, h3')].filter((h) => h.id);
14
+ tocEntries = [];
15
+ if (!headings.length) {
16
+ document.body.classList.add('toc-empty');
17
+ tocListEl.replaceChildren();
18
+ return;
19
+ }
20
+ document.body.classList.remove('toc-empty');
21
+ const frag = document.createDocumentFragment();
22
+ for (const h of headings) {
23
+ const link = document.createElement('button');
24
+ link.className = `toc-item lvl-${h.tagName.toLowerCase()}`;
25
+ link.textContent = h.textContent;
26
+ link.addEventListener('click', () => scrollToFragment(h.id));
27
+ frag.appendChild(link);
28
+ tocEntries.push({ id: h.id, el: h, link });
29
+ }
30
+ tocListEl.replaceChildren(frag);
31
+ updateScrollSpy();
32
+ }
33
+
34
+ function updateScrollSpy() {
35
+ if (!tocEntries.length) return;
36
+ const top = viewerEl.scrollTop + 90;
37
+ let current = tocEntries[0];
38
+ for (const entry of tocEntries) {
39
+ if (entry.el.offsetTop <= top) current = entry; else break;
40
+ }
41
+ for (const entry of tocEntries) entry.link.classList.toggle('active', entry === current);
42
+ }
43
+
44
+ let spyRaf = 0;
45
+ viewerEl.addEventListener('scroll', () => {
46
+ if (spyRaf) return;
47
+ spyRaf = requestAnimationFrame(() => { spyRaf = 0; updateScrollSpy(); });
48
+ });
49
+
50
+ $('toc-collapse').addEventListener('click', () => document.body.classList.add('toc-collapsed'));
51
+ $('toc-reopen').addEventListener('click', () => document.body.classList.remove('toc-collapsed'));