Skip to content

Commit eaffd0e

Browse files
committed
docs: update Bootstrap documentation with latest changes
- Update HTML documentation files with Bootstrap styling improvements - Add JavaScript search functionality - Enhance CSS styling for better user experience
1 parent fbf2eb4 commit eaffd0e

File tree

7 files changed

+346
-82
lines changed

7 files changed

+346
-82
lines changed

docs/api-reference.html

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
<body>
1919

2020
<!-- Navigation -->
21-
<nav class="navbar navbar-expand-lg navbar-light bg-white sticky-top">
21+
<nav class="navbar navbar-expand-md navbar-light sticky-top dense-nav">
2222
<div class="container">
2323
<a class="navbar-brand" href="index.html">
2424
<i class="fas fa-chart-line me-2"></i>StatClean
@@ -28,8 +28,8 @@
2828
<span class="navbar-toggler-icon"></span>
2929
</button>
3030

31-
<div class="collapse navbar-collapse" id="navbarNav">
32-
<ul class="navbar-nav">
31+
<div class="collapse navbar-collapse w-100" id="navbarNav">
32+
<ul class="navbar-nav me-auto">
3333
<li class="nav-item">
3434
<a class="nav-link" href="index.html">Home</a>
3535
</li>
@@ -46,8 +46,15 @@
4646
<a class="nav-link active" href="api-reference.html">API</a>
4747
</li>
4848
</ul>
49-
50-
<div class="d-flex ms-auto">
49+
50+
<div class="d-flex ms-auto align-items-center search-container">
51+
<input id="docSearch" class="form-control form-control-sm" type="search" placeholder="Search docs…" aria-label="Search" />
52+
<div id="searchResults" class="search-results"></div>
53+
</div>
54+
<div class="d-flex ms-2 align-items-center">
55+
<button class="btn btn-outline-secondary me-2" id="themeToggle" title="Toggle theme">
56+
<i class="fas fa-moon"></i>
57+
</button>
5158
<a href="https://github.com/SubaashNair/StatClean" class="btn btn-outline-primary">
5259
<i class="fab fa-github"></i>
5360
<span>GitHub</span>
@@ -61,10 +68,10 @@
6168
</div>
6269
</nav>
6370

64-
<div class="container-fluid">
71+
<div class="container">
6572
<div class="row">
6673
<!-- Sidebar Navigation -->
67-
<div class="col-lg-3 sidebar">
74+
<div class="col-lg-3 col-xl-2 sidebar">
6875
<nav class="nav flex-column scrollspy-nav">
6976
<a class="nav-link active" href="#initialization">StatClean Class</a>
7077
<a class="nav-link" href="#detection">Detection Methods</a>
@@ -79,7 +86,7 @@
7986
</div>
8087

8188
<!-- Main Content -->
82-
<div class="col-lg-9 content-area">
89+
<div class="col-lg-9 col-xl-10 content-area">
8390
<h1><i class="fas fa-book me-3"></i>API Reference</h1>
8491
<p class="lead">Complete reference documentation for all StatClean classes, methods, and functions.</p>
8592

@@ -726,6 +733,7 @@ <h5><i class="fas fa-info-circle me-2"></i>Key Properties</h5>
726733

727734
<!-- Bootstrap JS -->
728735
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
736+
<script src="assets/js/search.js"></script>
729737
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-core.min.js"></script>
730738
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/plugins/autoloader/prism-autoloader.min.js"></script>
731739

@@ -749,6 +757,18 @@ <h5><i class="fas fa-info-circle me-2"></i>Key Properties</h5>
749757
}
750758
});
751759
});
760+
761+
// Theme toggle
762+
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
763+
const stored = localStorage.getItem('bs-theme') || (prefersDark ? 'dark' : 'light');
764+
document.documentElement.setAttribute('data-bs-theme', stored);
765+
document.getElementById('themeToggle')?.addEventListener('click', () => {
766+
const current = document.documentElement.getAttribute('data-bs-theme') === 'dark' ? 'light' : 'dark';
767+
document.documentElement.setAttribute('data-bs-theme', current);
768+
localStorage.setItem('bs-theme', current);
769+
const icon = document.querySelector('#themeToggle i');
770+
if (icon) icon.className = current === 'dark' ? 'fas fa-sun' : 'fas fa-moon';
771+
});
752772
</script>
753773
</body>
754774
</html>

docs/assets/css/style.css

Lines changed: 68 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020
body {
2121
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
2222
line-height: 1.6;
23-
color: var(--gray-800);
23+
color: var(--bs-body-color);
24+
background-color: var(--bs-body-bg);
2425
}
2526

2627
/* Navigation */
@@ -31,33 +32,23 @@ body {
3132
}
3233

3334
.navbar {
34-
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
35-
background: white !important;
35+
box-shadow: 0 1px 2px rgba(0,0,0,0.05);
3636
padding: 0.5rem 0;
3737
}
3838

39-
.navbar .container {
40-
max-width: 1140px;
41-
padding-left: 1rem;
42-
padding-right: 1rem;
43-
}
39+
.navbar .container { padding-left: 1rem; padding-right: 1rem; }
4440

4541
.nav-link {
4642
font-weight: 500;
47-
color: var(--gray-600) !important;
48-
transition: color 0.3s ease;
43+
color: var(--bs-secondary-color) !important;
44+
transition: color 0.2s ease;
4945
padding: 0.5rem 0.75rem !important;
5046
margin: 0 0.25rem;
5147
}
5248

53-
.nav-link:hover {
54-
color: var(--primary-color) !important;
55-
}
49+
.nav-link:hover { color: var(--bs-emphasis-color) !important; }
5650

57-
.nav-link.active {
58-
color: var(--primary-color) !important;
59-
font-weight: 600;
60-
}
51+
.nav-link.active { color: var(--bs-emphasis-color) !important; font-weight: 600; }
6152

6253
/* Navigation buttons */
6354
.navbar .btn {
@@ -75,18 +66,22 @@ body {
7566
}
7667

7768
/* Ensure proper spacing between nav items and buttons */
78-
.navbar-nav {
79-
margin-right: auto;
80-
}
69+
.navbar-nav { margin-right: auto; }
8170

8271
.navbar .d-flex {
8372
gap: 0.5rem;
8473
}
8574

75+
/* Make navbar toggler more visible */
76+
.navbar-toggler {
77+
border-color: var(--gray-300);
78+
}
79+
.navbar-toggler:focus { box-shadow: none; }
80+
8681
/* Hero Section */
8782
.hero-section {
8883
background: linear-gradient(135deg, var(--primary-color) 0%, var(--secondary-color) 100%);
89-
color: white;
84+
color: #fff;
9085
padding: 4rem 0;
9186
}
9287

@@ -113,7 +108,7 @@ body {
113108
.feature-card {
114109
border: none;
115110
border-radius: 12px;
116-
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.07);
111+
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.06);
117112
transition: transform 0.3s ease, box-shadow 0.3s ease;
118113
height: 100%;
119114
}
@@ -136,7 +131,7 @@ body {
136131

137132
/* Code Blocks */
138133
.code-container {
139-
background: var(--gray-100);
134+
background: var(--bs-tertiary-bg, #f7f7f9);
140135
border-radius: 8px;
141136
padding: 1.5rem;
142137
margin: 1rem 0;
@@ -191,6 +186,10 @@ pre code {
191186
border-color: var(--primary-color);
192187
}
193188

189+
/* Contextual backgrounds honoring color modes */
190+
.bg-body { background-color: var(--bs-body-bg) !important; }
191+
.bg-body-tertiary { background-color: var(--bs-tertiary-bg) !important; }
192+
194193
/* Tables */
195194
.table {
196195
border-radius: 8px;
@@ -211,10 +210,11 @@ pre code {
211210

212211
/* Flow Chart */
213212
.flow-chart {
214-
background: white;
213+
background: var(--bs-body-bg);
215214
border-radius: 12px;
216215
padding: 2rem;
217216
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
217+
border: 1px solid var(--bs-border-color);
218218
margin: 2rem 0;
219219
}
220220

@@ -245,8 +245,8 @@ pre code {
245245

246246
/* Footer */
247247
.footer {
248-
background-color: var(--gray-800);
249-
color: white;
248+
background-color: var(--bs-dark);
249+
color: var(--bs-light);
250250
padding: 3rem 0;
251251
margin-top: 4rem;
252252
}
@@ -258,17 +258,15 @@ pre code {
258258
}
259259

260260
.footer a {
261-
color: var(--gray-300);
261+
color: var(--bs-secondary-color);
262262
text-decoration: none;
263263
transition: color 0.3s ease;
264264
}
265265

266-
.footer a:hover {
267-
color: white;
268-
}
266+
.footer a:hover { color: var(--bs-light); }
269267

270268
/* Responsive */
271-
@media (max-width: 768px) {
269+
@media (max-width: 991.98px) {
272270
.hero-section h1 {
273271
font-size: 2.5rem;
274272
}
@@ -280,13 +278,22 @@ pre code {
280278
.feature-card {
281279
margin-bottom: 1rem;
282280
}
281+
282+
/* Stack nav buttons full width on collapse for better tap targets */
283+
.navbar .d-flex {
284+
width: 100%;
285+
gap: 0.5rem;
286+
margin-top: 0.5rem;
287+
}
288+
.navbar .btn { width: 100%; }
283289
}
284290

285291
/* Sidebar Navigation */
286292
.sidebar {
287-
background-color: var(--gray-100);
293+
background-color: var(--bs-body-bg);
288294
min-height: calc(100vh - 76px);
289-
padding: 2rem 0;
295+
padding: 1.25rem 0;
296+
border-right: 1px solid var(--bs-border-color);
290297
}
291298

292299
.sidebar .nav-link {
@@ -345,15 +352,32 @@ pre code {
345352
position: sticky;
346353
top: 100px;
347354
}
355+
/* Unify card spacing */
356+
.card { border-radius: 12px; }
357+
.card .card-header { font-weight: 600; }
358+
359+
/* Consistent section spacing */
360+
section { scroll-margin-top: 90px; }
361+
348362

349363
.scrollspy-nav .nav-link {
350-
font-size: 0.9rem;
351-
padding: 0.5rem 1rem;
364+
font-size: 0.95rem;
365+
padding: 0.5rem 1.25rem;
366+
}
367+
368+
/* Sidebar width refinement for large screens */
369+
@media (min-width: 1200px) {
370+
.sidebar { max-width: 260px; }
371+
}
372+
373+
@media (min-width: 1400px) {
374+
.sidebar { max-width: 240px; }
352375
}
353376

354377
/* Search */
355378
.search-container {
356379
position: relative;
380+
max-width: 340px;
357381
}
358382

359383
.search-results {
@@ -380,6 +404,15 @@ pre code {
380404
background-color: var(--gray-100);
381405
}
382406

407+
/* Dense layout helpers */
408+
.dense-nav .navbar-brand { font-size: 1.25rem; }
409+
.dense-nav .nav-link { padding: 0.35rem 0.6rem !important; }
410+
.dense-nav .btn { padding: 0.25rem 0.6rem; font-size: 0.85rem; }
411+
412+
@media (min-width: 992px) {
413+
.sidebar { position: sticky; top: 88px; }
414+
}
415+
383416
/* Syntax Highlighting */
384417
.highlight .k { color: #66d9ef; } /* Keywords */
385418
.highlight .s { color: #a6e22e; } /* Strings */

docs/assets/js/search.js

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// Lightweight client-side search for StatClean docs
2+
(() => {
3+
const index = [
4+
{ title: 'Home', url: 'index.html', keywords: 'statclean overview quick start features methods api examples' },
5+
{ title: 'Installation', url: 'installation.html', keywords: 'install pip requirements development verification compatibility docker ide setup' },
6+
{ title: 'Examples', url: 'examples.html', keywords: 'examples quick start statistical testing multivariate transformations method chaining visualization real dataset advanced' },
7+
{ title: 'Methods', url: 'statistical-methods.html', keywords: 'statistical methods iqr z-score modified z-score mahalanobis grubbs dixon transformation selection' },
8+
{ title: 'API Reference', url: 'api-reference.html', keywords: 'api class detection removal winsorize analysis transformation utils visualization' }
9+
]
10+
11+
function createResultItem(entry, query) {
12+
const div = document.createElement('div')
13+
div.className = 'search-result-item'
14+
div.innerHTML = `<strong>${entry.title}</strong><div class="small text-muted">${entry.url.replace('.html','')}</div>`
15+
div.addEventListener('mousedown', (e) => { // mousedown so blur doesn't fire first
16+
e.preventDefault()
17+
window.location.href = entry.url + (query ? `#${encodeURIComponent(query)}` : '')
18+
})
19+
return div
20+
}
21+
22+
function searchDocs(query) {
23+
const q = query.trim().toLowerCase()
24+
if (!q) return []
25+
return index
26+
.map(e => ({
27+
entry: e,
28+
score: (e.title.toLowerCase().includes(q) ? 2 : 0) + (e.keywords.includes(q) ? 1 : 0)
29+
}))
30+
.filter(x => x.score > 0)
31+
.sort((a,b) => b.score - a.score)
32+
.slice(0, 8)
33+
.map(x => x.entry)
34+
}
35+
36+
function wireSearch(inputId = 'docSearch', resultsId = 'searchResults') {
37+
const input = document.getElementById(inputId)
38+
const results = document.getElementById(resultsId)
39+
if (!input || !results) return
40+
41+
function render() {
42+
const hits = searchDocs(input.value)
43+
results.innerHTML = ''
44+
if (hits.length === 0) { results.style.display = 'none'; return }
45+
hits.forEach(h => results.appendChild(createResultItem(h, input.value)))
46+
results.style.display = 'block'
47+
}
48+
49+
input.addEventListener('input', render)
50+
input.addEventListener('focus', render)
51+
input.addEventListener('blur', () => setTimeout(() => (results.style.display = 'none'), 150))
52+
input.addEventListener('keydown', (e) => {
53+
if (e.key === 'Enter') {
54+
const first = results.querySelector('.search-result-item')
55+
if (first) first.dispatchEvent(new Event('mousedown'))
56+
}
57+
if (e.key === 'Escape') { results.style.display = 'none' }
58+
})
59+
}
60+
61+
document.addEventListener('DOMContentLoaded', () => wireSearch())
62+
})()
63+
64+

0 commit comments

Comments
 (0)