Skip to content

Commit 83cb15c

Browse files
committed
[DOC] add element to top page + fix on sidebar
1 parent babf4ac commit 83cb15c

File tree

5 files changed

+179
-15
lines changed

5 files changed

+179
-15
lines changed

docs/source/_static/css/custom.css

Lines changed: 115 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,17 @@ html[data-theme="dark"] {
6767
--pytorch-yellow: #eaa700;
6868
}
6969

70+
/* ============================================
71+
Right Sidebar - On This Page spacing
72+
============================================ */
73+
.bd-toc-nav.page-toc {
74+
margin-top: 1.25rem;
75+
}
76+
77+
.pst-page-navigation-heading {
78+
margin-bottom: 0.5rem;
79+
}
80+
7081
/* ============================================
7182
Hero Section
7283
============================================ */
@@ -122,13 +133,111 @@ html[data-theme="dark"] {
122133
margin: 0;
123134
}
124135

136+
/* ============================================
137+
Stats Strip (below hero)
138+
============================================ */
139+
.stats-strip {
140+
display: flex;
141+
justify-content: center;
142+
align-items: stretch;
143+
gap: 0;
144+
margin: 0 0 2rem 0;
145+
padding: 0;
146+
border-radius: 12px;
147+
overflow: hidden;
148+
box-shadow: var(--card-shadow);
149+
border: 1px solid var(--pst-color-border);
150+
background: var(--pst-color-surface);
151+
}
152+
153+
.stat-item {
154+
flex: 1;
155+
display: flex;
156+
flex-direction: column;
157+
align-items: center;
158+
justify-content: center;
159+
padding: 1.25rem 1rem;
160+
text-align: center;
161+
position: relative;
162+
transition: background 0.2s ease;
163+
}
164+
165+
.stat-item:not(:last-child)::after {
166+
content: '';
167+
position: absolute;
168+
right: 0;
169+
top: 20%;
170+
height: 60%;
171+
width: 1px;
172+
background: var(--pst-color-border);
173+
}
174+
175+
.stat-item:hover {
176+
background: var(--pst-color-background);
177+
}
178+
179+
.stat-value {
180+
font-size: 1.75rem;
181+
font-weight: 700;
182+
color: var(--hyperactive-primary);
183+
line-height: 1.2;
184+
margin-bottom: 0.25rem;
185+
}
186+
187+
html[data-theme="dark"] .stat-value {
188+
color: var(--hyperactive-secondary);
189+
}
190+
191+
.stat-label {
192+
font-size: 0.8rem;
193+
font-weight: 500;
194+
color: var(--pst-color-text-muted);
195+
text-transform: uppercase;
196+
letter-spacing: 0.05em;
197+
}
198+
199+
.stat-icon {
200+
font-size: 1.25rem;
201+
margin-bottom: 0.5rem;
202+
opacity: 0.7;
203+
}
204+
205+
/* Responsive: stack on mobile */
206+
@media (max-width: 640px) {
207+
.stats-strip {
208+
flex-wrap: wrap;
209+
}
210+
211+
.stat-item {
212+
flex: 1 1 50%;
213+
padding: 1rem 0.75rem;
214+
}
215+
216+
.stat-item:not(:last-child)::after {
217+
display: none;
218+
}
219+
220+
.stat-item:nth-child(1),
221+
.stat-item:nth-child(2) {
222+
border-bottom: 1px solid var(--pst-color-border);
223+
}
224+
225+
.stat-item:nth-child(odd) {
226+
border-right: 1px solid var(--pst-color-border);
227+
}
228+
229+
.stat-value {
230+
font-size: 1.5rem;
231+
}
232+
}
233+
125234
/* ============================================
126235
Badge Banner (replaces Maturity Banner)
127236
============================================ */
128237
.badge-banner {
129238
text-align: center;
130-
padding: 1.25rem 1rem;
131-
margin: 1.5rem 0;
239+
padding: 1rem 1rem 1.5rem;
240+
margin: 1rem 0;
132241
}
133242

134243
.badge-items {
@@ -141,17 +250,14 @@ html[data-theme="dark"] {
141250

142251
.badge-items a {
143252
display: inline-block;
144-
transition: transform 0.2s ease, opacity 0.2s ease;
145-
}
146-
147-
.badge-items a:hover {
148-
transform: translateY(-2px);
149-
opacity: 0.9;
253+
line-height: 0;
150254
}
151255

152256
.badge-items img {
153-
height: 20px;
257+
height: 28px;
154258
vertical-align: middle;
259+
border-radius: 0 !important;
260+
image-rendering: crisp-edges;
155261
}
156262

157263
/* Legacy Maturity Banner (kept for backwards compatibility) */

docs/source/_static/images/badges/generate_badges.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,14 +73,15 @@ def create_badge_svg(label: str, value: str, color: str, label_width: int = None
7373
return svg
7474

7575

76-
def create_simple_badge_svg(text: str, color: str, width: int = None) -> str:
76+
def create_simple_badge_svg(text: str, color: str, width: int = None, font_size: int = 11) -> str:
7777
"""
7878
Create a simple single-section SVG badge.
7979
8080
Args:
8181
text: Badge text
8282
color: Background color
8383
width: Override calculated width
84+
font_size: Font size in pixels
8485
8586
Returns:
8687
SVG string
@@ -89,11 +90,12 @@ def create_simple_badge_svg(text: str, color: str, width: int = None) -> str:
8990
padding = 16
9091
w = width or int(len(text) * char_width + padding * 2)
9192
height = 20
93+
text_y = 14 if font_size >= 11 else 13.5
9294

9395
svg = f'''<svg xmlns="http://www.w3.org/2000/svg" width="{w}" height="{height}">
9496
<title>{text}</title>
9597
<rect width="{w}" height="{height}" fill="{color}"/>
96-
<text x="{w/2}" y="14" fill="#fff" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11" text-anchor="middle" font-weight="600">{text}</text>
98+
<text x="{w/2}" y="{text_y}" fill="#fff" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="{font_size}" text-anchor="middle" font-weight="600">{text}</text>
9799
</svg>'''
98100

99101
return svg
@@ -163,7 +165,7 @@ def main():
163165
"version.svg": create_badge_svg("version", f"v{version}", COLORS["primary"]),
164166
"python.svg": create_badge_svg("python", python_range, COLORS["primary"]),
165167
"license.svg": create_badge_svg("license", license_name, COLORS["primary"]),
166-
"sponsor.svg": create_simple_badge_svg("GC.OS Sponsored", COLORS["sponsor"], width=110),
168+
"sponsor.svg": create_simple_badge_svg("GC.OS Sponsored", COLORS["sponsor"], width=105, font_size=10),
167169
}
168170

169171
# Write badges
Lines changed: 3 additions & 3 deletions
Loading

docs/source/conf.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,10 +385,46 @@ def adds(pth):
385385
else:
386386
_py_versions_inline = "3.10+"
387387

388+
389+
# -- Count algorithms and integrations dynamically ----------------------------
390+
def count_from_all_list(module_path: str) -> int:
391+
"""Count items in __all__ list of a Python module file."""
392+
import ast
393+
394+
file_path = Path(__file__).parent.parent.parent / "src" / module_path
395+
if not file_path.exists():
396+
return 0
397+
398+
try:
399+
tree = ast.parse(file_path.read_text())
400+
for node in ast.walk(tree):
401+
if isinstance(node, ast.Assign):
402+
for target in node.targets:
403+
if isinstance(target, ast.Name) and target.id == "__all__":
404+
if isinstance(node.value, ast.List):
405+
return len(node.value.elts)
406+
except Exception:
407+
pass
408+
return 0
409+
410+
411+
# Count algorithms from opt/__init__.py
412+
_n_algorithms = count_from_all_list("hyperactive/opt/__init__.py")
413+
414+
# Count integrations from experiment/integrations/__init__.py
415+
_n_integrations = count_from_all_list("hyperactive/experiment/integrations/__init__.py")
416+
417+
# Backends are conceptual (GFO, Optuna, sklearn) - hardcoded
418+
_n_backends = 3
419+
420+
388421
rst_epilog = f"""
389422
.. |version| replace:: {PYPROJECT_METADATA["version"]}
390423
.. |min_python| replace:: {PYPROJECT_METADATA["min_python"]}
391424
.. |python_versions_list| replace:: {_py_versions_inline}
392425
.. |python_version_range| replace:: {_py_version_range}
393426
.. |current_year| replace:: {current_year}
427+
.. |n_algorithms| replace:: {_n_algorithms}
428+
.. |n_backends| replace:: {_n_backends}
429+
.. |n_integrations| replace:: {_n_integrations}
394430
"""

docs/source/index.rst

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,26 @@
99
</div>
1010
</div>
1111

12+
<!-- Stats are auto-counted in conf.py: n_algorithms, n_backends, n_integrations -->
13+
<div class="stats-strip">
14+
<div class="stat-item">
15+
<div class="stat-value" id="stat-algorithms">31</div>
16+
<div class="stat-label">Algorithms</div>
17+
</div>
18+
<div class="stat-item">
19+
<div class="stat-value" id="stat-backends">3</div>
20+
<div class="stat-label">Backends</div>
21+
</div>
22+
<div class="stat-item">
23+
<div class="stat-value" id="stat-integrations">5</div>
24+
<div class="stat-label">Integrations</div>
25+
</div>
26+
<div class="stat-item">
27+
<div class="stat-value">1</div>
28+
<div class="stat-label">Unified API</div>
29+
</div>
30+
</div>
31+
1232

1333
Hyperactive provides a collection of optimization algorithms, accessible through a unified
1434
experiment-based interface that separates optimization problems from algorithms. The library

0 commit comments

Comments
 (0)