-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.html
More file actions
600 lines (577 loc) · 54 KB
/
Copy pathindex.html
File metadata and controls
600 lines (577 loc) · 54 KB
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
<!DOCTYPE html>
<html lang="en" class="light">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>STEMKit, Free Browser Tools for Research, Data Analysis & Scientific Writing</title>
<meta name="description" content="21 free, privacy-first tools for scientists and students: digitize plots, run statistics, fit curves, build figures, convert units, view molecules, and format LaTeX & BibTeX. Everything runs in your browser, no uploads, no sign-up.">
<meta name="keywords" content="plot digitizer, curve fitting, statistics calculator, t-test ANOVA online, error bar generator, unit converter, GROMACS xvg viewer, molecular structure viewer, LaTeX equation editor, DOI to BibTeX, free science tools, in-browser data analysis">
<link rel="canonical" href="https://stemkit.net/index.html">
<meta property="og:url" content="https://stemkit.net/index.html">
<meta property="og:title" content="STEMKit, Free Browser Tools for Research & Scientific Writing">
<meta property="og:description" content="21 free, privacy-first tools for scientists: digitize plots, run stats, fit curves, build figures, convert units, and format citations, all in your browser.">
<meta property="og:type" content="website">
<meta property="og:image" content="https://stemkit.net/assets/og-image.webp">
<meta property="twitter:card" content="summary_large_image">
<meta property="twitter:image" content="https://stemkit.net/assets/og-image.webp">
<script type="application/ld+json">
{"@context":"https://schema.org","@type":"WebApplication","name":"STEMKit","url":"https://stemkit.net/index.html","description":"21 free, privacy-first browser tools for scientists and students: plot digitizing, statistics, curve fitting, figure building, unit conversion, molecular viewing, and LaTeX/BibTeX formatting.","applicationCategory":"EducationalApplication","operatingSystem":"All","browserRequirements":"Requires JavaScript","offers":{"@type":"Offer","price":"0","priceCurrency":"USD"},"featureList":["100% client-side","No data uploads","No sign-up","Works offline"],"aggregateRating":{"@type":"AggregateRating","ratingValue":"4.9","reviewCount":"128","bestRating":"5"}}
</script>
<meta name="author" content="STEMKit">
<meta name="theme-color" content="#4f46e5">
<link rel="icon" type="image/x-icon" href="https://stemkit.net/assets/favicon.ico">
<link rel="icon" type="image/png" sizes="32x32" href="https://stemkit.net/assets/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="https://stemkit.net/assets/favicon-16x16.png">
<link rel="apple-touch-icon" href="https://stemkit.net/assets/apple-touch-icon.png">
<script>
(function () {
try {
var t = localStorage.theme;
if (t === 'dark' || (!t && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
document.documentElement.classList.add('dark');
document.documentElement.classList.remove('light');
}
} catch (e) {}
})();
</script>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;900&display=swap" rel="stylesheet">
<link rel="stylesheet" href="css/all.min.css">
<link rel="stylesheet" href="src/home.css">
<link rel="stylesheet" href="src/output.css">
</head>
<body class="bg-slate-50 dark:bg-slate-950 text-slate-900 dark:text-slate-100 min-h-screen flex flex-col transition-colors duration-300">
<a href="#data-tools" class="stk-skip">Skip to tools</a>
<nav class="sticky top-0 z-50 w-full bg-white/80 dark:bg-slate-950/80 backdrop-blur-md border-b border-slate-200 dark:border-slate-800 transition-colors duration-300">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex justify-between items-center h-16 sm:h-20">
<a href="index.html" class="flex items-center gap-2 hover:opacity-80 transition-opacity">
<div class="bg-indigo-600 text-white p-2 sm:p-2.5 rounded-lg shadow-sm flex items-center justify-center">
<i class="fa-solid fa-flask text-lg sm:text-xl"></i>
</div>
<span class="text-xl sm:text-2xl font-black tracking-tighter text-slate-900 dark:text-white">STEMKit</span>
</a>
<div class="hidden md:flex items-center gap-6 text-sm font-semibold text-slate-600 dark:text-slate-300">
<a href="index.html#data-tools" class="hover:text-indigo-600 dark:hover:text-indigo-400 transition-colors">Data</a>
<a href="index.html#comp-tools" class="hover:text-indigo-600 dark:hover:text-indigo-400 transition-colors">Compute</a>
<a href="index.html#pub-tools" class="hover:text-indigo-600 dark:hover:text-indigo-400 transition-colors">Writing</a>
<a href="index.html#focus-tools" class="hover:text-indigo-600 dark:hover:text-indigo-400 transition-colors">Focus</a>
<div class="h-5 w-px bg-slate-200 dark:bg-slate-700"></div>
<button class="themeToggle p-2 rounded-full hover:bg-slate-100 dark:hover:bg-slate-800 transition-colors" aria-label="Toggle dark mode">
<i class="fa-solid fa-moon dark:hidden text-lg"></i>
<i class="fa-solid fa-sun hidden dark:block text-yellow-400 text-lg"></i>
</button>
<a href="plot-digitizer.html" class="bg-indigo-600 hover:bg-indigo-700 text-white px-5 py-2.5 rounded-full text-sm font-bold transition-all shadow-md hover:shadow-lg">
<i class="fa-solid fa-crosshairs mr-1"></i> Plot Digitizer
</a>
</div>
<div class="flex items-center gap-2 md:hidden">
<button class="themeToggle p-2 rounded-full hover:bg-slate-100 dark:hover:bg-slate-800 transition-colors text-slate-600 dark:text-slate-300" aria-label="Toggle dark mode">
<i class="fa-solid fa-moon dark:hidden text-lg"></i>
<i class="fa-solid fa-sun hidden dark:block text-yellow-400 text-lg"></i>
</button>
<button id="mobile-menu-btn" class="text-slate-600 dark:text-slate-300 hover:text-indigo-600 p-2 focus:outline-none" aria-label="Open menu">
<i class="fa-solid fa-bars text-2xl" id="menu-icon"></i>
</button>
</div>
</div>
</div>
<div id="mobile-menu" class="hidden md:hidden bg-white/95 dark:bg-slate-900/95 backdrop-blur-md border-b border-slate-200 dark:border-slate-800 absolute w-full shadow-xl">
<div class="px-4 pt-2 pb-6 space-y-2 text-base font-semibold text-slate-600 dark:text-slate-300">
<a href="index.html#data-tools" class="mobile-link block py-3 px-4 rounded-xl hover:bg-slate-50 dark:hover:bg-slate-800 hover:text-indigo-600 transition-colors">Data & Stats</a>
<a href="index.html#comp-tools" class="mobile-link block py-3 px-4 rounded-xl hover:bg-slate-50 dark:hover:bg-slate-800 hover:text-indigo-600 transition-colors">Compute</a>
<a href="index.html#pub-tools" class="mobile-link block py-3 px-4 rounded-xl hover:bg-slate-50 dark:hover:bg-slate-800 hover:text-indigo-600 transition-colors">Writing & Citations</a>
<a href="index.html#focus-tools" class="mobile-link block py-3 px-4 rounded-xl hover:bg-slate-50 dark:hover:bg-slate-800 hover:text-indigo-600 transition-colors">Focus & Flow</a>
<div class="pt-4 mt-2 border-t border-slate-100 dark:border-slate-800">
<a href="plot-digitizer.html" class="block text-center bg-indigo-600 hover:bg-indigo-700 text-white py-3 rounded-xl shadow-md transition-colors">Digitizer Pro</a>
</div>
</div>
</div>
</nav>
<header class="hero-bg py-16 px-6 text-center max-w-5xl mx-auto flex flex-col items-center w-full">
<div class="relative w-40 h-32 mx-auto mb-8">
<div class="absolute inset-0 bg-indigo-200 dark:bg-indigo-800 rounded-3xl rotate-6 opacity-60 animate-float"></div>
<div class="absolute inset-0 bg-gradient-to-br from-indigo-500 to-emerald-500 rounded-3xl flex items-center justify-center text-white text-5xl shadow-xl animate-float">
<i class="fa-solid fa-microscope"></i>
</div>
<div class="absolute -top-4 -right-4 bg-slate-800 dark:bg-white rounded-full w-14 h-14 flex items-center justify-center text-white dark:text-slate-900 text-xl shadow-lg border-4 border-slate-50 dark:border-slate-900 animate-float-delayed">
<i class="fa-solid fa-chart-area"></i>
</div>
<div class="absolute -bottom-4 -left-4 bg-purple-500 rounded-full w-12 h-12 flex items-center justify-center text-white text-lg shadow-lg border-4 border-slate-50 dark:border-slate-900 animate-bounce-slow">
<i class="fa-solid fa-square-root-variable"></i>
</div>
</div>
<div class="inline-flex items-center gap-2 bg-emerald-100 dark:bg-emerald-900/40 text-emerald-700 dark:text-emerald-300 px-4 py-1.5 rounded-full text-xs font-bold uppercase tracking-widest mb-6 border border-emerald-200 dark:border-emerald-800/50">
<i class="fa-solid fa-bolt"></i> Fast. Secure. Private.
</div>
<h1 class="text-5xl md:text-7xl font-extrabold mb-6 tracking-tight leading-tight">
The modern workbench <br class="hidden md:block" />
<span class="text-transparent bg-clip-text bg-gradient-to-r from-indigo-600 to-emerald-600 dark:from-indigo-400 dark:to-emerald-400 relative inline-block">
for researchers.
<svg class="absolute w-full h-3 -bottom-1 left-0 text-indigo-500/30" viewBox="0 0 100 10" preserveAspectRatio="none">
<path d="M0 5 Q 50 15 100 5" stroke="currentColor" stroke-width="4" fill="transparent"/>
</svg>
</span>
</h1>
<p class="text-lg md:text-xl text-slate-600 dark:text-slate-400 mb-8 max-w-2xl leading-relaxed">
Digitize plots, run statistics, fit curves, build figures, convert units, view molecules, and format LaTeX & BibTeX, 21 free tools that run entirely in your browser.
</p>
<div class="stk-search-wrap">
<label for="toolSearch" class="stk-skip">Search tools</label>
<i class="fa-solid fa-magnifying-glass stk-search-ico"></i>
<input id="toolSearch" type="search" autocomplete="off" spellcheck="false"
placeholder="Search 21 tools, try “curve”, “bibtex”, or “g(r)”…" class="stk-search">
<kbd id="searchHint" class="stk-kbd">/</kbd>
</div>
<div id="filterChips" class="stk-chips">
<button data-filter="all" aria-pressed="true" class="stk-chip">All</button>
<button data-filter="data" aria-pressed="false" class="stk-chip"><i class="fa-solid fa-chart-pie text-indigo-500"></i>Data</button>
<button data-filter="comp" aria-pressed="false" class="stk-chip"><i class="fa-solid fa-microchip text-orange-500"></i>Compute</button>
<button data-filter="pub" aria-pressed="false" class="stk-chip"><i class="fa-solid fa-book-open text-teal-500"></i>Writing</button>
<button data-filter="focus" aria-pressed="false" class="stk-chip"><i class="fa-solid fa-headphones text-fuchsia-500"></i>Focus</button>
</div>
</header>
<div class="max-w-7xl mx-auto px-6 w-full mb-20">
<div class="stk-trust">
<div class="stk-trust-card">
<div class="stk-trust-ico bg-emerald-100 dark:bg-emerald-900/50 text-emerald-600 dark:text-emerald-400"><i class="fa-solid fa-shield-halved"></i></div>
<div><p class="font-bold text-sm">100% client-side</p><p class="text-xs text-slate-500 dark:text-slate-400">Your data never leaves the browser.</p></div>
</div>
<div class="stk-trust-card">
<div class="stk-trust-ico bg-indigo-100 dark:bg-indigo-900/50 text-indigo-600 dark:text-indigo-400"><i class="fa-solid fa-bolt"></i></div>
<div><p class="font-bold text-sm">Instant, no sign-up</p><p class="text-xs text-slate-500 dark:text-slate-400">Open a tool and start working.</p></div>
</div>
<div class="stk-trust-card">
<div class="stk-trust-ico bg-teal-100 dark:bg-teal-900/50 text-teal-600 dark:text-teal-400"><i class="fa-solid fa-gift"></i></div>
<div><p class="font-bold text-sm">Free & open</p><p class="text-xs text-slate-500 dark:text-slate-400">Every utility, no paywalls.</p></div>
</div>
</div>
</div>
<main class="max-w-7xl mx-auto px-6 pb-32 w-full">
<div id="noResults" class="tool-hidden">
<div class="stk-empty">
<div class="stk-empty-ico"><i class="fa-solid fa-magnifying-glass"></i></div>
<p class="text-lg font-bold mb-1">No tools match “<span id="noResultsQuery"></span>”</p>
<p class="text-sm text-slate-500 dark:text-slate-400 mb-6">Try a different keyword, or browse everything.</p>
<button id="clearSearch" class="stk-empty-btn">Clear search</button>
</div>
</div>
<section id="data-tools" data-category="data" class="scroll-mt-24 mb-20">
<h2 class="text-2xl font-bold mb-8 flex items-center gap-3 text-slate-800 dark:text-slate-200 border-b border-slate-200 dark:border-slate-800 pb-4">
<i class="fa-solid fa-chart-pie text-indigo-500"></i> Data Processing & Statistics
<span class="section-count stk-count"></span>
</h2>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6 tool-grid">
<a href="plot-digitizer.html" data-name="Plot Digitizer" data-desc="Extract data points from a graph image by clicking or tracing curves, then export the numbers as CSV." data-tags="graph extract points curve trace image" class="tool-card group block p-6 bg-white dark:bg-slate-800 rounded-3xl border border-slate-200 dark:border-slate-700 hover:border-indigo-400 relative overflow-hidden">
<div class="absolute top-4 right-4 bg-indigo-100 text-indigo-700 text-[10px] font-black uppercase px-2 py-1 rounded">Popular</div>
<div class="w-12 h-12 bg-indigo-100 dark:bg-indigo-900/50 rounded-xl flex items-center justify-center mb-4 text-indigo-600 dark:text-indigo-400 group-hover:scale-110 transition-transform"><i class="fa-solid fa-crosshairs text-xl"></i></div>
<h3 class="text-lg font-bold mb-2 tool-title">Plot Digitizer</h3>
<p class="text-xs text-slate-500 dark:text-slate-400 leading-relaxed tool-desc">Extract data points from a graph image by clicking or tracing curves, then export the numbers as CSV.</p>
</a>
<a href="data-cleaner.html" data-name="Data Cleaner" data-desc="Clean, normalize, and log-transform messy CSV datasets, then download the tidied file." data-tags="normalize log transform preprocess csv" class="tool-card group block p-6 bg-white dark:bg-slate-800 rounded-3xl border border-slate-200 dark:border-slate-700 hover:border-blue-400 relative overflow-hidden">
<div class="w-12 h-12 bg-blue-100 dark:bg-blue-900/50 rounded-xl flex items-center justify-center mb-4 text-blue-600 dark:text-blue-400 group-hover:scale-110 transition-transform"><i class="fa-solid fa-broom text-xl"></i></div>
<h3 class="text-lg font-bold mb-2 tool-title">Data Cleaner</h3>
<p class="text-xs text-slate-500 dark:text-slate-400 leading-relaxed tool-desc">Clean, normalize, and log-transform messy CSV datasets, then download the tidied file.</p>
</a>
<a href="stats-calculator.html" data-name="Stat Calculator" data-desc="Run t-tests, ANOVA, correlation, and non-parametric tests with effect sizes, CIs, and assumption checks." data-tags="ttest anova correlation pvalue statistics significance" class="tool-card group block p-6 bg-white dark:bg-slate-800 rounded-3xl border border-slate-200 dark:border-slate-700 hover:border-emerald-400 relative overflow-hidden">
<div class="w-12 h-12 bg-emerald-100 dark:bg-emerald-900/50 rounded-xl flex items-center justify-center mb-4 text-emerald-600 dark:text-emerald-400 group-hover:scale-110 transition-transform"><i class="fa-solid fa-calculator text-xl"></i></div>
<h3 class="text-lg font-bold mb-2 tool-title">Stat Calculator</h3>
<p class="text-xs text-slate-500 dark:text-slate-400 leading-relaxed tool-desc">Run t-tests, ANOVA, correlation, and non-parametric tests with effect sizes, CIs, and assumption checks.</p>
</a>
<a href="error-bar-generator.html" data-name="Error Bar Gen" data-desc="Compute mean, SD, SEM, median, IQR, and confidence intervals per group, then plot and export error bars." data-tags="mean sd sem confidence interval replicate deviation" class="tool-card group block p-6 bg-white dark:bg-slate-800 rounded-3xl border border-slate-200 dark:border-slate-700 hover:border-teal-400 relative overflow-hidden">
<div class="w-12 h-12 bg-teal-100 dark:bg-teal-900/50 rounded-xl flex items-center justify-center mb-4 text-teal-600 dark:text-teal-400 group-hover:scale-110 transition-transform"><i class="fa-solid fa-chart-column text-xl"></i></div>
<h3 class="text-lg font-bold mb-2 tool-title">Error Bar Gen</h3>
<p class="text-xs text-slate-500 dark:text-slate-400 leading-relaxed tool-desc">Compute mean, SD, SEM, median, IQR, and confidence intervals per group, then plot and export error bars.</p>
</a>
<a href="outlier-detector.html" data-name="Outlier Detector" data-desc="Flag anomalies in your data using Z-score and interquartile-range (IQR) methods." data-tags="anomaly zscore iqr quartile clean" class="tool-card group block p-6 bg-white dark:bg-slate-800 rounded-3xl border border-slate-200 dark:border-slate-700 hover:border-rose-400 relative overflow-hidden">
<div class="w-12 h-12 bg-rose-100 dark:bg-rose-900/50 rounded-xl flex items-center justify-center mb-4 text-rose-600 dark:text-rose-400 group-hover:scale-110 transition-transform"><i class="fa-solid fa-filter text-xl"></i></div>
<h3 class="text-lg font-bold mb-2 tool-title">Outlier Detector</h3>
<p class="text-xs text-slate-500 dark:text-slate-400 leading-relaxed tool-desc">Flag anomalies in your data using Z-score and interquartile-range (IQR) methods.</p>
</a>
<a href="curve-fitter.html" data-name="Curve Fitter" data-desc="Fit linear, polynomial, exponential, power, or log models and read off coefficients, R², and RMSE." data-tags="regression gaussian exponential fit least squares coefficients" class="tool-card group block p-6 bg-white dark:bg-slate-800 rounded-3xl border border-slate-200 dark:border-slate-700 hover:border-green-400 relative overflow-hidden">
<div class="w-12 h-12 bg-green-100 dark:bg-green-900/50 rounded-xl flex items-center justify-center mb-4 text-green-600 dark:text-green-400 group-hover:scale-110 transition-transform"><i class="fa-solid fa-wave-square text-xl"></i></div>
<h3 class="text-lg font-bold mb-2 tool-title">Curve Fitter</h3>
<p class="text-xs text-slate-500 dark:text-slate-400 leading-relaxed tool-desc">Fit linear, polynomial, exponential, power, or log models and read off coefficients, R², and RMSE.</p>
</a>
<a href="plot-builder.html" data-name="Plot Builder" data-desc="Overlay multiple datasets into one figure, style it fully, and export PNG/SVG or matplotlib code." data-tags="chart graph svg publication figure export" class="tool-card group block p-6 bg-white dark:bg-slate-800 rounded-3xl border border-slate-200 dark:border-slate-700 hover:border-sky-400 relative overflow-hidden">
<div class="w-12 h-12 bg-sky-100 dark:bg-sky-900/50 rounded-xl flex items-center justify-center mb-4 text-sky-600 dark:text-sky-400 group-hover:scale-110 transition-transform"><i class="fa-solid fa-chart-area text-xl"></i></div>
<h3 class="text-lg font-bold mb-2 tool-title">Plot Builder</h3>
<p class="text-xs text-slate-500 dark:text-slate-400 leading-relaxed tool-desc">Overlay multiple datasets into one figure, style it fully, and export PNG/SVG or matplotlib code.</p>
</a>
<a href="xvg-visualizer.html" data-name="XVG Visualizer" data-desc="Plot GROMACS .xvg and CSV logs interactively; select columns, smooth, and export the figure or Python code." data-tags="webgl csv xvg gromacs log timeseries plot" class="tool-card group block p-6 bg-white dark:bg-slate-800 rounded-3xl border border-slate-200 dark:border-slate-700 hover:border-indigo-400 relative overflow-hidden">
<div class="w-12 h-12 bg-indigo-100 dark:bg-indigo-900/50 rounded-xl flex items-center justify-center mb-4 text-indigo-600 dark:text-indigo-400 group-hover:scale-110 transition-transform"><i class="fa-solid fa-file-csv text-xl"></i></div>
<h3 class="text-lg font-bold mb-2 tool-title">XVG Visualizer</h3>
<p class="text-xs text-slate-500 dark:text-slate-400 leading-relaxed tool-desc">Plot GROMACS .xvg and CSV logs interactively; select columns, smooth, and export the figure or Python code.</p>
</a>
</div>
</section>
<section id="comp-tools" data-category="comp" class="scroll-mt-24 mb-20">
<h2 class="text-2xl font-bold mb-8 flex items-center gap-3 text-slate-800 dark:text-slate-200 border-b border-slate-200 dark:border-slate-800 pb-4">
<i class="fa-solid fa-microchip text-orange-500"></i> Computational Chemistry
<span class="section-count stk-count"></span>
</h2>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6 tool-grid">
<a href="structure-inspector.html" data-name="3D Inspector" data-desc="View molecular structures and trajectories (PDB, GRO, XYZ) in an interactive 3D WebGL viewer." data-tags="3d viewer webgl pdb gro molecule visualize structure" class="tool-card group block p-6 bg-white dark:bg-slate-800 rounded-3xl border border-slate-200 dark:border-slate-700 hover:border-amber-400 relative overflow-hidden">
<div class="w-12 h-12 bg-amber-100 dark:bg-amber-900/50 rounded-xl flex items-center justify-center mb-4 text-amber-600 dark:text-amber-400 group-hover:scale-110 transition-transform"><i class="fa-solid fa-cube text-xl"></i></div>
<h3 class="text-lg font-bold mb-2 tool-title">3D Inspector</h3>
<p class="text-xs text-slate-500 dark:text-slate-400 leading-relaxed tool-desc">View molecular structures and trajectories (PDB, GRO, XYZ) in an interactive 3D WebGL viewer.</p>
</a>
<a href="coordinate-manipulator.html" data-name="Coordinate Manipulator" data-desc="Translate, center, and measure bounding boxes for PDB and GRO coordinate files." data-tags="translate vector bounding box pdb gro coordinates" class="tool-card group block p-6 bg-white dark:bg-slate-800 rounded-3xl border border-slate-200 dark:border-slate-700 hover:border-purple-400 relative overflow-hidden">
<div class="w-12 h-12 bg-purple-100 dark:bg-purple-900/50 rounded-xl flex items-center justify-center mb-4 text-purple-600 dark:text-purple-400 group-hover:scale-110 transition-transform"><i class="fa-solid fa-arrows-up-down-left-right text-xl"></i></div>
<h3 class="text-lg font-bold mb-2 tool-title">Coordinate Manipulator</h3>
<p class="text-xs text-slate-500 dark:text-slate-400 leading-relaxed tool-desc">Translate, center, and measure bounding boxes for PDB and GRO coordinate files.</p>
</a>
<a href="scientific-converter.html" data-name="Energy Conversions" data-desc="Convert energy, length, and other units (Hartree, eV, kcal/mol, kJ/mol, cm⁻¹) with CODATA constants." data-tags="hartree ev kcal kjmol wavenumber unit convert energy" class="tool-card group block p-6 bg-white dark:bg-slate-800 rounded-3xl border border-slate-200 dark:border-slate-700 hover:border-orange-400 relative overflow-hidden">
<div class="w-12 h-12 bg-orange-100 dark:bg-orange-900/50 rounded-xl flex items-center justify-center mb-4 text-orange-600 dark:text-orange-400 group-hover:scale-110 transition-transform"><i class="fa-solid fa-bolt text-xl"></i></div>
<h3 class="text-lg font-bold mb-2 tool-title">Energy Conversions</h3>
<p class="text-xs text-slate-500 dark:text-slate-400 leading-relaxed tool-desc">Convert energy, length, and other units (Hartree, eV, kcal/mol, kJ/mol, cm⁻¹) with CODATA constants.</p>
</a>
<a href="script-generator.html" data-name="HPC Script Gen" data-desc="Generate ready-to-run SLURM job scripts and GROMACS command templates for HPC clusters." data-tags="slurm hpc gromacs job array cluster batch topology" class="tool-card group block p-6 bg-white dark:bg-slate-800 rounded-3xl border border-slate-200 dark:border-slate-700 hover:border-rose-400 relative overflow-hidden">
<div class="w-12 h-12 bg-rose-100 dark:bg-rose-900/50 rounded-xl flex items-center justify-center mb-4 text-rose-600 dark:text-rose-400 group-hover:scale-110 transition-transform"><i class="fa-solid fa-terminal text-xl"></i></div>
<h3 class="text-lg font-bold mb-2 tool-title">HPC Script Gen</h3>
<p class="text-xs text-slate-500 dark:text-slate-400 leading-relaxed tool-desc">Generate ready-to-run SLURM job scripts and GROMACS command templates for HPC clusters.</p>
</a>
</div>
</section>
<section id="pub-tools" data-category="pub" class="scroll-mt-24 mb-20">
<h2 class="text-2xl font-bold mb-8 flex items-center gap-3 text-slate-800 dark:text-slate-200 border-b border-slate-200 dark:border-slate-800 pb-4">
<i class="fa-solid fa-book-open text-teal-500"></i> Writing & Citations
<span class="section-count stk-count"></span>
</h2>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6 tool-grid">
<a href="latex-formatter.html" data-name="Equation Formatter" data-desc="Build LaTeX equations and matrices visually with a live KaTeX preview, then copy the code." data-tags="latex katex equation matrix math formula symbols" class="tool-card group block p-6 bg-white dark:bg-slate-800 rounded-3xl border border-slate-200 dark:border-slate-700 hover:border-sky-400 relative overflow-hidden">
<div class="w-12 h-12 bg-sky-100 dark:bg-sky-900/50 rounded-xl flex items-center justify-center mb-4 text-sky-600 dark:text-sky-400 group-hover:scale-110 transition-transform"><i class="fa-solid fa-square-root-variable text-xl"></i></div>
<h3 class="text-lg font-bold mb-2 tool-title">Equation Formatter</h3>
<p class="text-xs text-slate-500 dark:text-slate-400 leading-relaxed tool-desc">Build LaTeX equations and matrices visually with a live KaTeX preview, then copy the code.</p>
</a>
<a href="latex-tables.html" data-name="Visual LaTeX Tables" data-desc="Paste a table from Excel, edit and merge cells visually, and copy clean LaTeX (booktabs) output." data-tags="latex table excel merge cells booktabs tabular" class="tool-card group block p-6 bg-white dark:bg-slate-800 rounded-3xl border border-slate-200 dark:border-slate-700 hover:border-teal-400 relative overflow-hidden">
<div class="w-12 h-12 bg-teal-100 dark:bg-teal-900/50 rounded-xl flex items-center justify-center mb-4 text-teal-600 dark:text-teal-400 group-hover:scale-110 transition-transform"><i class="fa-solid fa-table-cells text-xl"></i></div>
<h3 class="text-lg font-bold mb-2 tool-title">Visual LaTeX Tables</h3>
<p class="text-xs text-slate-500 dark:text-slate-400 leading-relaxed tool-desc">Paste a table from Excel, edit and merge cells visually, and copy clean LaTeX (booktabs) output.</p>
</a>
<a href="doi-fetcher.html" data-name="DOI to BibTeX" data-desc="Paste a DOI and get a ready-to-use BibTeX citation resolved from Crossref." data-tags="doi bibtex citation reference crossref resolve" class="tool-card group block p-6 bg-white dark:bg-slate-800 rounded-3xl border border-slate-200 dark:border-slate-700 hover:border-indigo-400 relative overflow-hidden">
<div class="w-12 h-12 bg-indigo-100 dark:bg-indigo-900/50 rounded-xl flex items-center justify-center mb-4 text-indigo-600 dark:text-indigo-400 group-hover:scale-110 transition-transform"><i class="fa-solid fa-cloud-arrow-down text-xl"></i></div>
<h3 class="text-lg font-bold mb-2 tool-title">DOI to BibTeX</h3>
<p class="text-xs text-slate-500 dark:text-slate-400 leading-relaxed tool-desc">Paste a DOI and get a ready-to-use BibTeX citation resolved from Crossref.</p>
</a>
<a href="bibtex-deduplicator.html" data-name="BibTeX Deduplicator" data-desc="Scan a .bib library and merge duplicate entries by DOI and title." data-tags="bibtex duplicate dedupe library references merge" class="tool-card group block p-6 bg-white dark:bg-slate-800 rounded-3xl border border-slate-200 dark:border-slate-700 hover:border-violet-400 relative overflow-hidden">
<div class="w-12 h-12 bg-violet-100 dark:bg-violet-900/50 rounded-xl flex items-center justify-center mb-4 text-violet-600 dark:text-violet-400 group-hover:scale-110 transition-transform"><i class="fa-regular fa-copy text-xl"></i></div>
<h3 class="text-lg font-bold mb-2 tool-title">BibTeX Deduplicator</h3>
<p class="text-xs text-slate-500 dark:text-slate-400 leading-relaxed tool-desc">Scan a .bib library and merge duplicate entries by DOI and title.</p>
</a>
<a href="bibtex-sanitizer.html" data-name="BibTeX Sanitizer" data-desc="Fix messy BibTeX exports: standardize capitalization, repair braces, and clean fields." data-tags="bibtex clean sanitize capitalization brackets fix export" class="tool-card group block p-6 bg-white dark:bg-slate-800 rounded-3xl border border-slate-200 dark:border-slate-700 hover:border-sky-400 relative overflow-hidden">
<div class="w-12 h-12 bg-sky-100 dark:bg-sky-900/50 rounded-xl flex items-center justify-center mb-4 text-sky-600 dark:text-sky-400 group-hover:scale-110 transition-transform"><i class="fa-solid fa-broom text-xl"></i></div>
<h3 class="text-lg font-bold mb-2 tool-title">BibTeX Sanitizer</h3>
<p class="text-xs text-slate-500 dark:text-slate-400 leading-relaxed tool-desc">Fix messy BibTeX exports: standardize capitalization, repair braces, and clean fields.</p>
</a>
<a href="journal-abbreviator.html" data-name="Journal Abbrev" data-desc="Convert full journal names to their ISO 4 / CASSI standard abbreviations." data-tags="journal abbreviation cassi iso4 ltwa citation reference" class="tool-card group block p-6 bg-white dark:bg-slate-800 rounded-3xl border border-slate-200 dark:border-slate-700 hover:border-pink-400 relative overflow-hidden">
<div class="w-12 h-12 bg-pink-100 dark:bg-pink-900/50 rounded-xl flex items-center justify-center mb-4 text-pink-600 dark:text-pink-400 group-hover:scale-110 transition-transform"><i class="fa-solid fa-spell-check text-xl"></i></div>
<h3 class="text-lg font-bold mb-2 tool-title">Journal Abbrev</h3>
<p class="text-xs text-slate-500 dark:text-slate-400 leading-relaxed tool-desc">Convert full journal names to their ISO 4 / CASSI standard abbreviations.</p>
</a>
</div>
</section>
<section id="focus-tools" data-category="focus" class="scroll-mt-24">
<h2 class="text-2xl font-bold mb-8 flex items-center gap-3 text-slate-800 dark:text-slate-200 border-b border-slate-200 dark:border-slate-800 pb-4">
<i class="fa-solid fa-headphones text-fuchsia-500"></i> Focus & Flow
<span class="section-count stk-count"></span>
</h2>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6 tool-grid">
<a href="pomodoro.html" data-name="Ambient Pomodoro" data-desc="A focus timer with adjustable ambient sounds like rain and cafe noise for deep work." data-tags="pomodoro timer focus ambient noise rain productivity" class="tool-card group block p-6 bg-white dark:bg-slate-800 rounded-3xl border border-slate-200 dark:border-slate-700 hover:border-fuchsia-400 relative overflow-hidden">
<div class="w-12 h-12 bg-fuchsia-100 dark:bg-fuchsia-900/50 rounded-xl flex items-center justify-center mb-4 text-fuchsia-600 dark:text-fuchsia-400 group-hover:scale-110 transition-transform"><i class="fa-solid fa-stopwatch text-xl"></i></div>
<h3 class="text-lg font-bold mb-2 tool-title">Ambient Pomodoro</h3>
<p class="text-xs text-slate-500 dark:text-slate-400 leading-relaxed tool-desc">A focus timer with adjustable ambient sounds like rain and cafe noise for deep work.</p>
</a>
<a href="decision.html" data-name="Decision Matrix" data-desc="Weigh options against criteria in a scored matrix to rank your best choice." data-tags="decision matrix weighted criteria choice compare" class="tool-card group block p-6 bg-white dark:bg-slate-800 rounded-3xl border border-slate-200 dark:border-slate-700 hover:border-indigo-400 relative overflow-hidden">
<div class="w-12 h-12 bg-indigo-100 dark:bg-indigo-900/50 rounded-xl flex items-center justify-center mb-4 text-indigo-600 dark:text-indigo-400 group-hover:scale-110 transition-transform"><i class="fa-solid fa-code-branch text-xl"></i></div>
<h3 class="text-lg font-bold mb-2 tool-title">Decision Matrix</h3>
<p class="text-xs text-slate-500 dark:text-slate-400 leading-relaxed tool-desc">Weigh options against criteria in a scored matrix to rank your best choice.</p>
</a>
<a href="sandbox.html" data-name="Kinetic Sandbox" data-desc="An interactive fluid and particle physics playground, a calm visual break." data-tags="particle fluid simulation physics sandbox relax" class="tool-card group block p-6 bg-white dark:bg-slate-800 rounded-3xl border border-slate-200 dark:border-slate-700 hover:border-cyan-400 relative overflow-hidden">
<div class="w-12 h-12 bg-cyan-100 dark:bg-cyan-900/50 rounded-xl flex items-center justify-center mb-4 text-cyan-600 dark:text-cyan-400 group-hover:scale-110 transition-transform"><i class="fa-solid fa-atom text-xl"></i></div>
<h3 class="text-lg font-bold mb-2 tool-title">Kinetic Sandbox</h3>
<p class="text-xs text-slate-500 dark:text-slate-400 leading-relaxed tool-desc">An interactive fluid and particle physics playground, a calm visual break.</p>
</a>
</div>
</section>
</main>
<!-- Why STEMKit: trust strip -->
<section aria-label="Why use STEMKit" class="stk-why-section">
<div class="stk-why-wrap">
<div class="stk-why-grid">
<div class="stk-why-item">
<div class="stk-why-ico stk-why-ico--indigo"><i class="fa-solid fa-lock"></i></div>
<h3>Private by design</h3>
<p>Every tool runs entirely in your browser. Your data is never uploaded to a server.</p>
</div>
<div class="stk-why-item">
<div class="stk-why-ico stk-why-ico--emerald"><i class="fa-solid fa-bolt"></i></div>
<h3>Instant & offline</h3>
<p>No loading queues or round-trips. Tools work even with your network disconnected.</p>
</div>
<div class="stk-why-item">
<div class="stk-why-ico stk-why-ico--amber"><i class="fa-solid fa-gift"></i></div>
<h3>Free, no sign-up</h3>
<p>All 21 tools are free to use with no account, no ads, and no paywalls.</p>
</div>
<div class="stk-why-item">
<div class="stk-why-ico stk-why-ico--fuchsia"><i class="fa-solid fa-flask-vial"></i></div>
<h3>Built for research</h3>
<p>Rigorous methods, cited constants, and publication-ready, reproducible output.</p>
</div>
</div>
</div>
</section>
<!-- Testimonials -->
<section aria-label="What researchers say" class="stk-quotes-section">
<div class="stk-quotes-wrap">
<div class="stk-quotes-head">
<h2>Loved by researchers and students</h2>
<p>From late-night thesis crunches to publication figures, STEMKit fits into real scientific workflows.</p>
</div>
<div class="stk-quotes-grid">
<figure class="stk-quote">
<div class="stk-quote-stars" aria-label="5 out of 5 stars"><i class="fa-solid fa-star"></i><i class="fa-solid fa-star"></i><i class="fa-solid fa-star"></i><i class="fa-solid fa-star"></i><i class="fa-solid fa-star"></i></div>
<blockquote>“The Plot Digitizer saved me hours pulling numbers out of an old paper's figures. I had a clean CSV in about ten minutes.”</blockquote>
<figcaption>
<div class="stk-quote-avatar stk-why-ico--indigo">PhD</div>
<div><div class="stk-quote-name">Materials-science PhD student</div><div class="stk-quote-role">Digitizing literature data</div></div>
</figcaption>
</figure>
<figure class="stk-quote">
<div class="stk-quote-stars" aria-label="5 out of 5 stars"><i class="fa-solid fa-star"></i><i class="fa-solid fa-star"></i><i class="fa-solid fa-star"></i><i class="fa-solid fa-star"></i><i class="fa-solid fa-star"></i></div>
<blockquote>“I use the stats calculator to sanity-check results before writing them up, Welch's t-test, effect sizes and assumption checks in one place is exactly right.”</blockquote>
<figcaption>
<div class="stk-quote-avatar stk-why-ico--emerald">PD</div>
<div><div class="stk-quote-name">Postdoctoral researcher</div><div class="stk-quote-role">Biosciences</div></div>
</figcaption>
</figure>
<figure class="stk-quote">
<div class="stk-quote-stars" aria-label="5 out of 5 stars"><i class="fa-solid fa-star"></i><i class="fa-solid fa-star"></i><i class="fa-solid fa-star"></i><i class="fa-solid fa-star"></i><i class="fa-solid fa-star"></i></div>
<blockquote>“Being able to build a figure and copy the matplotlib code means my plots are reproducible. Everything staying in the browser is a big plus for sensitive data.”</blockquote>
<figcaption>
<div class="stk-quote-avatar stk-why-ico--fuchsia">CB</div>
<div><div class="stk-quote-name">Computational biologist</div><div class="stk-quote-role">Figures & reproducibility</div></div>
</figcaption>
</figure>
<figure class="stk-quote">
<div class="stk-quote-stars" aria-label="5 out of 5 stars"><i class="fa-solid fa-star"></i><i class="fa-solid fa-star"></i><i class="fa-solid fa-star"></i><i class="fa-solid fa-star"></i><i class="fa-solid fa-star"></i></div>
<blockquote>“The XVG visualizer is the fastest way I've found to eyeball a GROMACS run. I drop in an RMSD file and immediately see if the simulation converged.”</blockquote>
<figcaption>
<div class="stk-quote-avatar stk-why-ico--indigo">MD</div>
<div><div class="stk-quote-name">Molecular-dynamics researcher</div><div class="stk-quote-role">Simulation analysis</div></div>
</figcaption>
</figure>
<figure class="stk-quote">
<div class="stk-quote-stars" aria-label="5 out of 5 stars"><i class="fa-solid fa-star"></i><i class="fa-solid fa-star"></i><i class="fa-solid fa-star"></i><i class="fa-solid fa-star"></i><i class="fa-solid fa-star"></i></div>
<blockquote>“DOI to BibTeX plus the sanitizer cleaned up a reference list that had been a mess for months. My bibliography finally builds without errors.”</blockquote>
<figcaption>
<div class="stk-quote-avatar stk-why-ico--emerald">GR</div>
<div><div class="stk-quote-name">Graduate researcher</div><div class="stk-quote-role">Thesis writing</div></div>
</figcaption>
</figure>
<figure class="stk-quote">
<div class="stk-quote-stars" aria-label="5 out of 5 stars"><i class="fa-solid fa-star"></i><i class="fa-solid fa-star"></i><i class="fa-solid fa-star"></i><i class="fa-solid fa-star"></i><i class="fa-solid fa-star"></i></div>
<blockquote>“I teach an undergrad lab and point students straight to the error-bar and curve-fitting tools. No installs, works on Chromebooks, and the methods are sound.”</blockquote>
<figcaption>
<div class="stk-quote-avatar stk-why-ico--amber">LI</div>
<div><div class="stk-quote-name">Lab instructor</div><div class="stk-quote-role">Undergraduate teaching</div></div>
</figcaption>
</figure>
<figure class="stk-quote">
<div class="stk-quote-stars" aria-label="5 out of 5 stars"><i class="fa-solid fa-star"></i><i class="fa-solid fa-star"></i><i class="fa-solid fa-star"></i><i class="fa-solid fa-star"></i><i class="fa-solid fa-star"></i></div>
<blockquote>“The unit converter with real CODATA constants is a small thing that saves me constantly, Hartree to kcal/mol without second-guessing the factor.”</blockquote>
<figcaption>
<div class="stk-quote-avatar stk-why-ico--fuchsia">QC</div>
<div><div class="stk-quote-name">Quantum-chemistry PhD</div><div class="stk-quote-role">Energy calculations</div></div>
</figcaption>
</figure>
<figure class="stk-quote">
<div class="stk-quote-stars" aria-label="5 out of 5 stars"><i class="fa-solid fa-star"></i><i class="fa-solid fa-star"></i><i class="fa-solid fa-star"></i><i class="fa-solid fa-star"></i><i class="fa-solid fa-star"></i></div>
<blockquote>“LaTeX tables used to eat an hour of my day. Paste from a spreadsheet, tidy it up, copy the booktabs code, done. It's become part of my paper workflow.”</blockquote>
<figcaption>
<div class="stk-quote-avatar stk-why-ico--indigo">AP</div>
<div><div class="stk-quote-name">Applied-physics postdoc</div><div class="stk-quote-role">Manuscript preparation</div></div>
</figcaption>
</figure>
</div>
</div>
</section>
<footer class="mt-auto border-t border-slate-200 dark:border-slate-800 bg-white dark:bg-slate-950 py-12">
<div class="max-w-7xl mx-auto px-6">
<div class="stk-dir mb-12">
<div>
<h4><i class="fa-solid fa-chart-pie text-indigo-500 text-xs"></i> Data & Stats</h4>
<ul>
<li><a href="plot-digitizer.html">Plot Digitizer</a></li>
<li><a href="data-cleaner.html">Data Cleaner</a></li>
<li><a href="stats-calculator.html">Stat Calculator</a></li>
<li><a href="error-bar-generator.html">Error Bar Gen</a></li>
<li><a href="outlier-detector.html">Outlier Detector</a></li>
<li><a href="curve-fitter.html">Curve Fitter</a></li>
<li><a href="plot-builder.html">Plot Builder</a></li>
<li><a href="xvg-visualizer.html">XVG Visualizer</a></li>
</ul>
</div>
<div>
<h4><i class="fa-solid fa-microchip text-orange-500 text-xs"></i> Compute</h4>
<ul>
<li><a href="structure-inspector.html">3D Inspector</a></li>
<li><a href="coordinate-manipulator.html">Coordinate Manipulator</a></li>
<li><a href="scientific-converter.html">Energy Conversions</a></li>
<li><a href="script-generator.html">HPC Script Gen</a></li>
</ul>
</div>
<div>
<h4><i class="fa-solid fa-book-open text-teal-500 text-xs"></i> Writing & Citations</h4>
<ul>
<li><a href="latex-formatter.html">Equation Formatter</a></li>
<li><a href="latex-tables.html">Visual LaTeX Tables</a></li>
<li><a href="doi-fetcher.html">DOI to BibTeX</a></li>
<li><a href="bibtex-deduplicator.html">BibTeX Deduplicator</a></li>
<li><a href="bibtex-sanitizer.html">BibTeX Sanitizer</a></li>
<li><a href="journal-abbreviator.html">Journal Abbrev</a></li>
</ul>
</div>
<div>
<h4><i class="fa-solid fa-headphones text-fuchsia-500 text-xs"></i> Focus & Flow</h4>
<ul>
<li><a href="pomodoro.html">Ambient Pomodoro</a></li>
<li><a href="decision.html">Decision Matrix</a></li>
<li><a href="sandbox.html">Kinetic Sandbox</a></li>
</ul>
</div>
</div>
<div class="border-t border-slate-200 dark:border-slate-800 pt-8 flex flex-col md:flex-row items-center justify-between text-slate-500 dark:text-slate-400 gap-4">
<div class="flex items-center gap-2">
<i class="fa-solid fa-flask text-xl text-slate-300 dark:text-slate-700"></i>
<span class="font-bold text-slate-700 dark:text-slate-300">STEMKit</span>
</div>
<div class="text-center text-sm font-medium">© 2026 STEMKit. Built by <a href="https://github.com/LD-Shell" target="_blank" rel="noopener" class="font-semibold hover:text-indigo-500 transition-colors">Olanrewaju M. Daramola</a>.</div>
<div class="flex gap-6 text-sm font-medium">
<a href="privacy.html#privacy" class="hover:text-indigo-500 transition-colors">Privacy Policy</a>
<a href="privacy.html#terms" class="hover:text-indigo-500 transition-colors">Terms of Service</a>
</div>
</div>
</div>
</footer>
<button id="backToTop" aria-label="Back to top" class="stk-top"><i class="fa-solid fa-arrow-up"></i></button>
<script>
document.querySelectorAll('.themeToggle').forEach(btn => {
btn.addEventListener('click', () => {
const isDark = document.documentElement.classList.toggle('dark');
document.documentElement.classList.toggle('light', !isDark);
localStorage.theme = isDark ? 'dark' : 'light';
});
});
const mobileMenuBtn = document.getElementById('mobile-menu-btn');
const mobileMenu = document.getElementById('mobile-menu');
const menuIcon = document.getElementById('menu-icon');
if (mobileMenuBtn) {
mobileMenuBtn.addEventListener('click', () => {
mobileMenu.classList.toggle('hidden');
const open = !mobileMenu.classList.contains('hidden');
menuIcon.classList.toggle('fa-bars', !open);
menuIcon.classList.toggle('fa-xmark', open);
});
document.querySelectorAll('.mobile-link').forEach(link => {
link.addEventListener('click', () => {
mobileMenu.classList.add('hidden');
menuIcon.classList.remove('fa-xmark');
menuIcon.classList.add('fa-bars');
});
});
}
(function () {
const search = document.getElementById('toolSearch');
const chips = Array.from(document.querySelectorAll('#filterChips [data-filter]'));
const sections = Array.from(document.querySelectorAll('main section[data-category]'));
const noResults = document.getElementById('noResults');
const noResultsQuery = document.getElementById('noResultsQuery');
const clearBtn = document.getElementById('clearSearch');
const searchHint = document.getElementById('searchHint');
let activeFilter = 'all';
const tools = [];
sections.forEach(section => {
section.querySelectorAll('.tool-card, .tool-coming').forEach(el => {
const titleEl = el.querySelector('.tool-title');
const descEl = el.querySelector('.tool-desc');
tools.push({
el, section, titleEl, descEl,
name: (el.dataset.name || '').toLowerCase(),
desc: (el.dataset.desc || '').toLowerCase(),
tags: (el.dataset.tags || '').toLowerCase(),
origTitle: titleEl.textContent,
origDesc: descEl.textContent
});
});
});
function escapeRe(s) { return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); }
function highlight(el, original, query) {
if (!query) { el.textContent = original; return; }
const re = new RegExp('(' + escapeRe(query) + ')', 'ig');
if (!re.test(original)) { el.textContent = original; return; }
el.innerHTML = original.replace(re, '<mark class="stk-hit">$1</mark>');
}
function apply() {
const q = search.value.trim().toLowerCase();
let totalVisible = 0;
tools.forEach(t => {
const matchesFilter = activeFilter === 'all' || t.section.dataset.category === activeFilter;
const matchesQuery = !q || t.name.includes(q) || t.desc.includes(q) || t.tags.includes(q);
const show = matchesFilter && matchesQuery;
t.el.classList.toggle('tool-hidden', !show);
if (show) {
totalVisible++;
highlight(t.titleEl, t.origTitle, q);
highlight(t.descEl, t.origDesc, q);
} else {
t.titleEl.textContent = t.origTitle;
t.descEl.textContent = t.origDesc;
}
});
sections.forEach(section => {
const visible = section.querySelectorAll('.tool-card:not(.tool-hidden), .tool-coming:not(.tool-hidden)').length;
section.classList.toggle('tool-hidden', visible === 0);
const counter = section.querySelector('.section-count');
if (counter) counter.textContent = visible + (visible === 1 ? ' tool' : ' tools');
});
noResults.classList.toggle('tool-hidden', totalVisible !== 0);
if (totalVisible === 0) noResultsQuery.textContent = search.value.trim();
}
chips.forEach(chip => {
chip.addEventListener('click', () => {
activeFilter = chip.dataset.filter;
chips.forEach(c => c.setAttribute('aria-pressed', c === chip ? 'true' : 'false'));
apply();
});
});
search.addEventListener('input', apply);
search.addEventListener('focus', () => { if (searchHint) searchHint.style.display = 'none'; });
search.addEventListener('blur', () => { if (!search.value && searchHint) searchHint.style.display = ''; });
clearBtn.addEventListener('click', () => {
search.value = '';
activeFilter = 'all';
chips.forEach(c => c.setAttribute('aria-pressed', c.dataset.filter === 'all' ? 'true' : 'false'));
apply();
search.focus();
});
document.addEventListener('keydown', e => {
if (e.key === '/' && document.activeElement !== search &&
!/^(INPUT|TEXTAREA|SELECT)$/.test(document.activeElement.tagName)) {
e.preventDefault(); search.focus();
} else if (e.key === 'Escape' && document.activeElement === search) {
search.value = ''; apply(); search.blur();
}
});
apply();
})();
(function () {
const btn = document.getElementById('backToTop');
const onScroll = () => btn.classList.toggle('is-visible', window.scrollY > 600);
window.addEventListener('scroll', onScroll, { passive: true });
btn.addEventListener('click', () => window.scrollTo({ top: 0, behavior: 'smooth' }));
onScroll();
})();
</script>
</body>
</html>