diff --git a/assets/style.css b/assets/style.css
index 5c67914..ad67c8b 100644
--- a/assets/style.css
+++ b/assets/style.css
@@ -1,64 +1,59 @@
:root {
- --bg: #0f1720;
- --card: #0b1220;
- --muted: #93a3b5;
- --accent: #7dd3fc;
- --accent-2: #60a5fa;
- --glass: rgba(255, 255, 255, 0.03);
- --radius: 12px;
- --max-width: 980px;
- --hf-left: #ff6a00; /* orange */
- --hf-right: #8b5cf6; /* purple */
- --bg-dark: #071126;
+ --bg: #0a0a0a;
+ --card: #1a1a1a;
+ --muted: #a3a3a3;
+ --accent: #007aff;
+ --accent-2: #0056b3;
+ --radius: 8px;
+ --max-width: 900px;
+}
+
+[data-theme="light"] {
+ --bg: #ffffff;
+ --card: #f0f0f0;
+ --muted: #555555;
+ --accent: #007aff;
+ --accent-2: #0056b3;
}
* {
box-sizing: border-box;
}
-html,
-body,
-#content {
+html {
height: 100%;
}
body {
margin: 0;
- font-family: Inter, ui-sans-serif, system-ui, -apple-system, "Segoe UI",
- Roboto, "Helvetica Neue", Arial;
- background: linear-gradient(180deg, #071126 0%, #071b2a 100%);
- color: #e6eef6;
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
+ background: var(--bg);
+ color: var(--muted);
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
font-size: 16px;
- line-height: 1.6;
- /* Improve mobile scrolling performance */
- -webkit-overflow-scrolling: touch;
- /* Prevent font size adjustment on orientation change */
- -webkit-text-size-adjust: 100%;
- -ms-text-size-adjust: 100%;
+ line-height: 1.7;
+ position: relative;
+ min-height: 100vh;
+ padding-bottom: 150px; /* Footer height */
}
.site {
display: flex;
- min-height: 100vh;
}
-/* Mobile-first responsive site layout */
@media (max-width: 900px) {
.site {
flex-direction: column;
}
}
-/* Top navigation */
-/* --- Original & Base Styles --- */
.topnav {
- background: linear-gradient(90deg, var(--hf-left), var(--hf-right));
+ background: var(--bg);
+ border-bottom: 1px solid var(--card);
color: #fff;
- padding: 12px 20px;
+ padding: 16px 24px;
position: sticky;
top: 0;
z-index: 60;
- box-shadow: 0 6px 24px rgba(11, 17, 40, 0.5);
}
.topnav-inner {
max-width: 1200px;
@@ -68,49 +63,75 @@ body {
justify-content: space-between;
}
.topnav .brand {
- color: #fff;
+ color: var(--muted);
text-decoration: none;
- font-weight: 700;
- font-size: 1.05rem;
+ font-weight: 600;
+ font-size: 1.1rem;
display: flex;
align-items: center;
gap: 10px;
}
.nav-links {
display: flex;
- gap: 18px;
+ gap: 24px;
}
.nav-links a {
- color: rgba(255, 255, 255, 0.95);
+ color: var(--muted);
text-decoration: none;
- padding: 8px 10px;
- border-radius: 8px;
- transition: background 0.18s ease;
+ padding: 8px 0;
+ transition: color 0.2s ease;
+ position: relative;
}
.nav-links a:hover {
- background: rgba(255, 255, 255, 0.06);
+ color: var(--accent);
}
+
+.nav-links a::after {
+ content: '';
+ position: absolute;
+ width: 0;
+ height: 2px;
+ bottom: 0;
+ left: 0;
+ background-color: var(--accent);
+ transition: width 0.3s ease;
+}
+
+.nav-links a:hover::after {
+ width: 100%;
+}
+
.nav-actions {
display: flex;
align-items: center;
- gap: 12px;
+ gap: 16px;
}
.nav-btn {
background: transparent;
border: 0;
- color: #fff;
- font-size: 2.05rem;
+ color: var(--muted);
+ font-size: 1.5rem;
cursor: pointer;
padding: 0;
display: flex;
align-items: center;
+ transition: color 0.2s ease;
+}
+
+.nav-btn:hover {
+ color: var(--accent);
}
.nav-cta {
- background: #021025;
+ background: var(--accent);
color: #fff;
- padding: 8px 12px;
- border-radius: 10px;
+ padding: 10px 16px;
+ border-radius: var(--radius);
text-decoration: none;
+ transition: background-color 0.2s ease;
+}
+
+.nav-cta:hover {
+ background: var(--accent-2);
}
#hamburger {
@@ -132,30 +153,25 @@ body {
display: none;
}
}
-/* Sidebar */
.sidebar {
- width: 300px;
- background: linear-gradient(
- 180deg,
- rgba(255, 255, 255, 0.02),
- rgba(255, 255, 255, 0.01)
- );
- border-right: 1px solid rgba(255, 255, 255, 0.03);
- padding: 20px;
+ width: 280px;
+ background: var(--bg);
+ border-right: 1px solid var(--card);
+ padding: 24px;
display: flex;
flex-direction: column;
- gap: 16px;
- transition: width 0.35s cubic-bezier(0.2, 0.9, 0.2, 1), transform 0.35s ease;
+ gap: 20px;
position: sticky;
- top: 0;
- height: 100vh;
+ top: 65px; /* Match navbar height */
+ height: calc(100vh - 65px);
overflow: auto;
}
.sidebar.collapsed {
- width: 70px;
+ width: 0;
+ padding: 24px 0;
+ overflow: hidden;
}
-/* Mobile sidebar adjustments */
@media (max-width: 900px) {
.sidebar {
position: fixed;
@@ -164,13 +180,7 @@ body {
top: 0;
height: 100vh;
transform: translateX(-100%);
- background: linear-gradient(
- 180deg,
- rgba(11, 18, 32, 0.98),
- rgba(11, 18, 32, 0.95)
- );
- backdrop-filter: blur(10px);
- -webkit-backdrop-filter: blur(10px);
+ background: var(--bg);
transition: transform 0.3s ease;
}
@@ -183,9 +193,9 @@ body {
}
}
.brand a {
- font-weight: 700;
+ font-weight: 600;
font-size: 18px;
- color: var(--accent);
+ color: var(--muted);
text-decoration: none;
}
@@ -194,30 +204,26 @@ body {
}
.search-wrapper input {
width: 100%;
- padding: 10px 36px 10px 12px;
- background: linear-gradient(
- 180deg,
- rgba(255, 255, 255, 0.02),
- rgba(255, 255, 255, 0.01)
- );
- border: 1px solid rgba(255, 255, 255, 0.04);
+ padding: 12px 40px 12px 16px;
+ background: var(--card);
+ border: 1px solid var(--card);
color: var(--muted);
- border-radius: 8px;
+ border-radius: var(--radius);
outline: none;
- transition: box-shadow 0.2s ease, transform 0.12s ease;
+ transition: border-color 0.2s ease, box-shadow 0.2s ease;
}
.search-wrapper input:focus {
- box-shadow: 0 6px 20px rgba(96, 165, 250, 0.12);
- transform: translateY(-1px);
+ border-color: var(--accent);
+ box-shadow: 0 0 0 3px rgba(0, 122, 255, 0.3);
}
.search-ico {
position: absolute;
- right: 10px;
- top: 8px;
+ right: 12px;
+ top: 50%;
+ transform: translateY(-50%);
width: 20px;
height: 20px;
fill: var(--muted);
- opacity: 0.7;
}
.toc {
@@ -230,62 +236,57 @@ body {
padding: 0;
display: flex;
flex-direction: column;
- gap: 6px;
+ gap: 8px;
}
.toc-item a {
display: block;
- padding: 8px 10px;
- color: rgba(255, 255, 255, 0.85);
+ padding: 10px 12px;
+ color: var(--muted);
text-decoration: none;
- border-radius: 8px;
- transition: background 0.15s ease, color 0.15s ease,
- transform 0.18s cubic-bezier(0.2, 0.9, 0.2, 1);
+ border-radius: var(--radius);
+ transition: background 0.2s ease, color 0.2s ease;
}
.toc-item a:hover {
- background: rgba(125, 211, 252, 0.06);
+ background: var(--card);
color: var(--accent);
- transform: translateX(4px);
}
.toc-item.toc-h1 a {
- font-weight: 700;
+ font-weight: 600;
}
.toc-item.toc-h2 a {
- padding-left: 14px;
+ padding-left: 24px;
}
.toc-item.toc-h3 a {
- padding-left: 26px;
- font-size: 0.95em;
+ padding-left: 36px;
+ font-size: 0.9em;
}
.toc-item.dim a {
- opacity: 0.45;
- transform: none;
+ opacity: 0.5;
}
.toc-item a.active {
- background: linear-gradient(90deg, var(--hf-left), var(--hf-right));
- color: #021025;
- font-weight: 700;
- transform: translateX(2px) scale(1.01);
+ background: var(--accent);
+ color: #fff;
+ font-weight: 600;
}
.toc-empty {
color: var(--muted);
font-style: italic;
+ padding: 12px;
}
-/* Hide Button Styles*/
.toc-toggle {
- border: 0;
- background: linear-gradient(135deg, var(--accent-orange), var(--accent-purple));
- padding: 0.7rem 1rem;
- border-radius: var(--radius-pill);
- color: var(--on-accent);
- text-decoration: none;
+ border: 1px solid var(--card);
+ background: var(--card);
+ padding: 10px;
+ border-radius: var(--radius);
+ color: var(--muted);
cursor: pointer;
- box-shadow: var(--soft-shadow);
+ transition: background 0.2s ease, color 0.2s ease;
}
.toc-toggle:hover {
- transform: translateY(-3px);
- transition: all 1s ease;
+ background: var(--bg);
+ color: var(--accent);
}
.sidebar-footer {
display: flex;
@@ -294,1048 +295,213 @@ body {
}
.sidebar-footer .btn {
display: inline-block;
- padding: 8px 12px;
- background: rgba(255, 255, 255, 0.03);
- color: var(--accent-2);
- border-radius: 8px;
+ padding: 10px 14px;
+ background: var(--card);
+ color: var(--muted);
+ border-radius: var(--radius);
text-decoration: none;
+ transition: background 0.2s ease, color 0.2s ease;
+}
+
+.sidebar-footer .btn:hover {
+ background: var(--bg);
+ color: var(--accent);
}
-/* Content */
.content {
- flex: 1;
- padding: 20px;
+ padding: 48px;
display: flex;
justify-content: center;
}
.content-inner {
width: 100%;
max-width: var(--max-width);
- background: linear-gradient(180deg, rgba(255, 255, 255, 0.01), transparent);
- padding: 24px;
- border-radius: 16px;
- box-shadow: 0 10px 40px rgba(2, 6, 23, 0.6);
- transition: box-shadow 0.36s ease, transform 0.36s ease;
-}
-.content-inner:hover {
- box-shadow: 0 18px 60px rgba(2, 6, 23, 0.7);
- transform: translateY(-2px);
-}
-
-/* Desktop specific styles */
-@media (min-width: 901px) {
- .content {
- padding: 36px 48px;
- }
-
- .content-inner {
- padding: 36px;
- }
-}
-
-/* Decorative background gradient blob */
-.bg-decor {
- position: absolute;
- left: 50%;
- top: 4%;
- width: 720px;
- height: 420px;
- transform: translateX(-50%);
- background: radial-gradient(
- circle at 20% 30%,
- rgba(125, 211, 252, 0.06),
- transparent 25%
- ),
- radial-gradient(
- circle at 80% 70%,
- rgba(96, 165, 250, 0.05),
- transparent 30%
- );
- filter: blur(20px);
- pointer-events: none;
- z-index: 0;
-}
-.content-inner {
- position: relative;
- z-index: 2;
}
@media (max-width: 900px) {
- .bg-decor {
- display: none;
+ .content {
+ padding: 24px;
}
}
-/* Animations */
-.fade-in {
- animation: fadeIn 0.6s ease both;
-}
-@keyframes fadeIn {
- from {
- opacity: 0;
- transform: translateY(8px);
- }
- to {
- opacity: 1;
- transform: none;
- }
-}
-@keyframes slideInLeft {
- from {
- opacity: 0;
- transform: translateX(-8px);
- }
- to {
- opacity: 1;
- transform: none;
- }
-}
-.toc-item {
- animation: slideInLeft 0.36s ease both;
+#article h1, #article h2, #article h3 {
+ color: var(--muted);
}
-/* Article styles */
#article h1 {
- font-size: 28px;
+ font-size: 36px;
margin-top: 0;
+ margin-bottom: 24px;
+ font-weight: 700;
}
#article h2 {
- margin-top: 28px;
+ font-size: 28px;
+ margin-top: 48px;
+ margin-bottom: 20px;
+ font-weight: 600;
+ border-bottom: 1px solid var(--card);
+ padding-bottom: 8px;
+}
+#article h3 {
+ font-size: 22px;
+ margin-top: 36px;
+ margin-bottom: 16px;
+ font-weight: 600;
}
#article p {
color: var(--muted);
line-height: 1.7;
+ font-size: 17px;
+ margin-bottom: 20px;
}
#article table {
width: 100%;
border-collapse: collapse;
+ margin: 32px 0;
}
#article table th,
#article table td {
- border: 1px solid rgba(255, 255, 255, 0.04);
- padding: 8px;
+ border: 1px solid var(--card);
+ padding: 12px;
color: var(--muted);
+ text-align: left;
+}
+#article table th {
+ color: var(--muted);
+ background: var(--card);
}
#article a {
color: var(--accent);
text-decoration: none;
+ border-bottom: 1px solid transparent;
+ transition: border-color 0.2s ease;
+}
+
+#article a:hover {
+ border-bottom-color: var(--accent);
}
-/* Code blocks */
pre {
- border-radius: 12px;
+ border-radius: var(--radius);
overflow: auto;
- padding: 16px;
- background: #010617;
- box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.02);
+ padding: 20px;
+ background: var(--card);
+ border: 1px solid var(--card);
}
code {
- font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, "Roboto Mono",
- "Courier New", monospace;
- font-size: 0.95em;
+ font-family: "SF Mono", "Fira Code", "Fira Mono", "Roboto Mono", monospace;
+ font-size: 0.9em;
+ background: var(--card);
+ padding: 4px 6px;
+ border-radius: 4px;
+}
+
+pre code {
+ background: transparent;
+ padding: 0;
+ border-radius: 0;
}
-/* Heading anchors */
.heading-anchor {
- margin-left: 8px;
- opacity: 0;
- transform: translateY(-2px);
- transition: opacity 0.12s ease, transform 0.12s ease;
+ margin-left: 12px;
+ opacity: 0.5;
+ transition: opacity 0.2s ease;
color: var(--muted);
text-decoration: none;
+ font-weight: 400;
}
#article h1:hover .heading-anchor,
#article h2:hover .heading-anchor,
#article h3:hover .heading-anchor {
opacity: 1;
- transform: none;
}
-/* Mark highlight for search */
mark {
- background: linear-gradient(
- 90deg,
- rgba(125, 211, 252, 0.16),
- rgba(96, 165, 250, 0.12)
- );
+ background: rgba(0, 122, 255, 0.3);
padding: 2px 4px;
border-radius: 4px;
-}
-
-/* Responsive Design - Mobile First Approach */
-
-/* Small mobile devices (320px - 480px) */
-@media (max-width: 480px) {
- .topnav {
- padding: 8px 12px !important;
- }
-
- .topnav-inner {
- padding: 0 4px !important;
- }
-
- .brand {
- font-size: 0.9rem !important;
- }
-
- .nav-cta {
- padding: 6px 8px !important;
- font-size: 0.85rem !important;
- }
-
- #nav-search-btn {
- display: none !important;
- }
-
- .sidebar {
- width: 280px !important;
- padding: 16px !important;
- }
-
- .content {
- padding: 12px !important;
- }
-
- .content-inner {
- padding: 16px !important;
- border-radius: 12px !important;
- }
-
- #article h1 {
- font-size: 22px !important;
- line-height: 1.3 !important;
- }
-
- #article h2 {
- font-size: 18px !important;
- margin-top: 20px !important;
- }
-
- #article h3 {
- font-size: 16px !important;
- }
-
- #article p {
- font-size: 14px !important;
- line-height: 1.6 !important;
- }
-
- pre {
- padding: 12px !important;
- font-size: 12px !important;
- overflow-x: auto !important;
- }
-
- .toc-item a {
- padding: 6px 8px;
- font-size: 14px;
- }
-
- .search-wrapper input {
- padding: 8px 32px 8px 10px;
- font-size: 14px;
- }
-}
-
-/* Large mobile devices and small tablets (481px - 768px) */
-@media (max-width: 768px) {
- .nav-links {
- display: none !important;
- }
-
- #hamburger {
- display: block !important;
- }
-
- .sidebar {
- width: 300px !important;
- padding: 18px !important;
- }
-
- .content {
- padding: 16px !important;
- }
-
- .content-inner {
- padding: 20px !important;
- }
-
- #article h1 {
- font-size: 24px !important;
- }
-
- #article h2 {
- font-size: 20px !important;
- }
-
- #article p {
- font-size: 15px !important;
- }
-
- .toc-item a {
- padding: 7px 9px !important;
- }
-}
-
-/* Tablets and small desktops (769px - 900px) */
-@media (max-width: 900px) {
- .sidebar {
- position: fixed;
- z-index: 30;
- left: 0;
- top: 0;
- height: 100vh;
- transform: translateX(-8px);
- background: linear-gradient(
- 180deg,
- rgba(11, 18, 32, 0.95),
- rgba(11, 18, 32, 0.98)
- );
- transition: transform 0.28s cubic-bezier(0.2, 0.9, 0.2, 1);
- backdrop-filter: blur(10px);
- -webkit-backdrop-filter: blur(10px);
- }
-
- .sidebar.collapsed {
- transform: translateX(-100%);
- }
-
- .sidebar:not(.collapsed) {
- transform: translateX(0);
- }
-
- .content {
- padding: 20px;
- width: 100%;
- }
-
- .sidebar.collapsed + .content {
- padding-left: 20px;
- }
-
- .topnav-inner {
- padding: 0 8px;
- }
-
- .nav-links {
- display: none;
- }
-
- .bg-decor {
- display: none;
- }
-}
-
-/* Medium screens (901px - 1200px) */
-@media (min-width: 901px) and (max-width: 1200px) {
- .sidebar {
- width: 280px;
- }
-
- .content {
- padding: 32px 36px;
- }
-
- .content-inner {
- padding: 32px;
- }
-}
-
-/* Logo blob animation */
-.logo-blob {
- display: inline-block;
- vertical-align: middle;
- width: 12px;
- height: 12px;
- margin-right: 8px;
- border-radius: 50%;
- background: radial-gradient(circle at 30% 30%, #7dd3fc, #60a5fa);
- box-shadow: 0 6px 18px rgba(96, 165, 250, 0.12);
- animation: blob 3.6s infinite ease-in-out;
-}
-@keyframes blob {
- 0% {
- transform: translateY(0) scale(1);
- }
- 50% {
- transform: translateY(-3px) scale(1.06);
- }
- 100% {
- transform: translateY(0) scale(1);
- }
-}
-
-/* Mobile-friendly touch targets and interaction improvements */
-@media (max-width: 768px) {
- /* Increase touch target sizes for better mobile interaction */
- .nav-btn {
- padding: 12px;
- font-size: 1.8rem;
- }
-
- .toc-item a {
- min-height: 44px;
- display: flex;
- align-items: center;
- }
-
- .nav-links a {
- min-height: 44px;
- display: flex;
- align-items: center;
- }
-
- /* Improve button sizing */
- .nav-cta {
- min-height: 44px;
- display: flex;
- align-items: center;
- justify-content: center;
- }
-
- /* Better table handling on mobile */
- #article table {
- display: block;
- overflow-x: auto;
- white-space: nowrap;
- }
-
- #article table th,
- #article table td {
- padding: 12px 8px;
- min-width: 120px;
- }
-
- /* Improve code block readability */
- pre {
- font-size: 13px;
- line-height: 1.4;
- white-space: pre;
- overflow-x: auto;
- -webkit-overflow-scrolling: touch;
- }
-
- /* Better link spacing */
- #article a {
- padding: 2px 0;
- display: inline-block;
- }
-
- /* Improved search input */
- .search-wrapper input {
- height: 44px;
- -webkit-appearance: none;
- appearance: none;
- }
-
- /* Better spacing for content */
- #article {
- word-wrap: break-word;
- overflow-wrap: break-word;
- }
-
- #article img {
- max-width: 100%;
- height: auto;
- display: block;
- margin: 16px auto;
- }
-}
-
-/* Landscape orientation adjustments for mobile */
-@media (max-width: 768px) and (orientation: landscape) {
- .sidebar {
- width: 260px;
- }
-
- .content {
- padding: 12px;
- }
-
- .content-inner {
- padding: 20px;
- }
-}
-
-/* High DPI displays - ensure crisp text and elements */
-@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
- .logo-blob {
- border-radius: 50%;
- background-size: contain;
- }
-}
-
-/* Dark mode improvements for mobile */
-@media (max-width: 768px) and (prefers-color-scheme: dark) {
- .sidebar {
- background: linear-gradient(
- 180deg,
- rgba(7, 17, 38, 0.98),
- rgba(7, 17, 38, 0.95)
- );
- }
-
- .content-inner {
- background: linear-gradient(
- 180deg,
- rgba(255, 255, 255, 0.015),
- transparent
- );
- }
-}
-
-/* subtle header shadow */
-.content-inner {
- transition: box-shadow 0.36s ease, transform 0.36s ease;
-}
-.content-inner:hover {
- box-shadow: 0 18px 60px rgba(2, 6, 23, 0.7);
- transform: translateY(-2px);
-}
-
-.error-panel {
- background: linear-gradient(
- 180deg,
- rgba(255, 255, 255, 0.02),
- rgba(255, 255, 255, 0.01)
- );
- padding: 18px;
- border-radius: 12px;
color: var(--muted);
}
-/* Mobile Performance and Accessibility Improvements */
-/* CRITICAL MOBILE FIXES - High Priority */
-@media (max-width: 900px) {
- /* Fix main layout for mobile */
- .site {
- flex-direction: column !important;
- }
-
- /* Sidebar mobile behavior */
- .sidebar {
- position: fixed !important;
- z-index: 1000 !important;
- left: 0 !important;
- top: 0 !important;
- height: 100vh !important;
- width: 280px !important;
- transform: translateX(-100%) !important;
- background: linear-gradient(
- 180deg,
- rgba(11, 18, 32, 0.98),
- rgba(11, 18, 32, 0.95)
- ) !important;
- backdrop-filter: blur(10px) !important;
- -webkit-backdrop-filter: blur(10px) !important;
- transition: transform 0.3s ease !important;
- padding: 16px !important;
- }
-
- .sidebar:not(.collapsed) {
- transform: translateX(0) !important;
- }
-
- .sidebar.collapsed {
- transform: translateX(-100%) !important;
- }
-
- /* Content mobile adjustments */
- .content {
- padding: 16px !important;
- width: 100% !important;
- flex: 1 !important;
- }
-
- .content-inner {
- padding: 20px !important;
- border-radius: 12px !important;
- max-width: 100% !important;
- }
-
- /* Navigation mobile fixes */
- .topnav {
- padding: 8px 16px !important;
- position: sticky !important;
- top: 0 !important;
- z-index: 999 !important;
- }
-
- .topnav-inner {
- padding: 0 !important;
- }
-
- .nav-links {
- display: none !important;
- }
-
- #hamburger {
- display: block !important;
- }
-
- /* Typography mobile adjustments */
- #article h1 {
- font-size: 24px !important;
- line-height: 1.3 !important;
- }
-
- #article h2 {
- font-size: 20px !important;
- margin-top: 24px !important;
- }
-
- #article h3 {
- font-size: 18px !important;
- }
-
- #article p {
- font-size: 15px !important;
- line-height: 1.6 !important;
- color: #cbd5e1 !important;
- }
-
- /* Code blocks mobile */
- pre {
- padding: 16px !important;
- font-size: 13px !important;
- overflow-x: auto !important;
- -webkit-overflow-scrolling: touch !important;
- }
-
- /* Tables mobile handling */
- #article table {
- display: block !important;
- overflow-x: auto !important;
- white-space: nowrap !important;
- -webkit-overflow-scrolling: touch !important;
- }
-
- /* Touch targets */
- .toc-item a {
- min-height: 44px !important;
- display: flex !important;
- align-items: center !important;
- padding: 8px 12px !important;
- }
-
- .nav-btn {
- padding: 12px !important;
- font-size: 1.5rem !important;
- }
-
- .nav-cta {
- min-height: 44px !important;
- display: flex !important;
- align-items: center !important;
- justify-content: center !important;
- padding: 8px 12px !important;
- }
-}
-
-@media (max-width: 480px) {
- .sidebar {
- width: 260px !important;
- padding: 12px !important;
- }
-
- .content {
- padding: 12px !important;
- }
-
- .content-inner {
- padding: 16px !important;
- }
-
- .topnav {
- padding: 6px 12px !important;
- }
-
- .brand {
- font-size: 0.9rem !important;
- }
-
- .nav-cta {
- padding: 6px 8px !important;
- font-size: 0.85rem !important;
- }
-
- #nav-search-btn {
- display: none !important;
- }
-
- #article h1 {
- font-size: 20px !important;
- }
-
- #article h2 {
- font-size: 18px !important;
- }
-
- #article p {
- font-size: 14px !important;
- }
-
- pre {
- padding: 12px !important;
- font-size: 12px !important;
- }
+.site-footer {
+ padding: 12px 12px;
+ border-top: 1px solid var(--card);
+ margin-top: 10px;
+ text-align: center;
+ color: var(--muted);
}
-/* Mobile overlay for sidebar */
-@media (max-width: 900px) {
- .sidebar:not(.collapsed)::before {
- content: "";
- position: fixed;
- top: 0;
- left: 0;
- right: 0;
+.site-footer-projects {
+ position: absolute;
bottom: 0;
- background: rgba(0, 0, 0, 0.5);
- z-index: -1;
- backdrop-filter: blur(2px);
- -webkit-backdrop-filter: blur(2px);
- }
-}
-
-/* Reduce motion for users who prefer it */
-@media (prefers-reduced-motion: reduce) {
- .logo-blob,
- .content-inner,
- .sidebar,
- .toc-item a,
- .nav-links a {
- animation: none;
- transition: none;
- }
-
- .blob,
- .float,
- .shine {
- animation: none;
- }
-}
-
-/* Improve focus indicators for keyboard navigation */
-@media (max-width: 768px) {
- .nav-btn:focus,
- .toc-item a:focus,
- .nav-links a:focus,
- .nav-cta:focus,
- .search-wrapper input:focus {
- outline: 2px solid var(--accent);
- outline-offset: 2px;
- }
-
- /* Ensure minimum contrast for better readability */
- #article p {
- color: #cbd5e1;
- font-size: 15px;
- line-height: 1.7;
- }
-
- /* Better focus management for sidebar */
- .sidebar:focus-within {
- z-index: 40;
- }
-
- /* Improve button spacing on mobile */
- .nav-actions {
- gap: 8px;
- }
-
- /* Better handling of long content */
- .content-inner {
- overflow-wrap: break-word;
- word-wrap: break-word;
- hyphens: auto;
- -webkit-hyphens: auto;
- -ms-hyphens: auto;
- }
-}
-
-/* Ultra-wide mobile screens (large phones in landscape) */
-@media (max-width: 926px) and (orientation: landscape) {
- .sidebar {
- width: 240px;
- }
-
- .topnav {
- padding: 6px 16px;
- }
-}
-
-/* Very small screens optimization */
-@media (max-width: 360px) {
- .brand {
- font-size: 0.85rem;
- }
-
- .nav-cta {
- padding: 5px 6px;
- font-size: 0.8rem;
- }
-
- .sidebar {
- width: 260px;
- padding: 12px;
- }
-
- .content {
- padding: 8px;
- }
-
- .content-inner {
- padding: 16px;
- }
-
- #article h1 {
- font-size: 20px;
- }
-
- #article h2 {
- font-size: 17px;
- }
-
- #article p {
- font-size: 14px;
- }
-}
-
-/* Mobile-responsive footer styles */
-@media (max-width: 768px) {
- .site-footer {
- padding: 24px 0 16px;
- margin-top: 32px;
- }
-
- .footer-inner {
- grid-template-columns: 1fr;
- gap: 24px;
- padding: 0 16px;
+ width: 100%;
+ padding: 48px 24px;
+ border-top: 1px solid var(--card);
text-align: center;
- }
-
- .footer-brand {
- justify-content: center;
- margin-bottom: 8px;
- }
-
- .footer-brand .logo-blob {
- width: 2em;
- height: 2em;
- }
-
- .footer-col h4 {
- font-size: 1.1rem;
- margin-bottom: 12px;
- }
-
- .footer-links {
- align-items: center;
- gap: 12px;
- }
-
- .footer-socials {
- align-items: center;
- gap: 12px;
- }
+ color: var(--muted);
+}
- .footer-socials a {
+.footer-inner {
+ max-width: 1200px;
+ margin: 0 auto;
display: flex;
+ flex-direction: column;
align-items: center;
- justify-content: center;
- gap: 6px;
- }
-
- .footer-bottom {
- padding: 12px 16px 0;
- font-size: 0.9rem;
- }
-}
-
-@media (max-width: 480px) {
- .footer-inner {
- padding: 0 12px;
- gap: 20px;
- }
-
- .footer-col h4 {
- font-size: 1rem;
- }
-
- .footer-title {
- font-size: 1.1rem;
- }
-
- .footer-desc {
- font-size: 0.9rem;
- }
-
- .footer-links a,
- .footer-socials a {
- font-size: 0.9rem;
- }
-}
-
-[data-theme="light"] {
- --bg: #f8fafc;
- --card: #ffffff;
- --muted: #475569;
- --accent: #2563eb;
- --accent-2: #3b82f6;
- --glass: rgba(0, 0, 0, 0.03);
- --bg-dark: #e2e8f0;
-}
-
-[data-theme="light"] body {
- background: linear-gradient(180deg, #f1f5f9 0%, #e2e8f0 100%);
- color: #1e293b;
-}
-
-[data-theme="light"] .topnav {
- background: linear-gradient(90deg, #f97316, #a855f7);
- box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
-}
-
-[data-theme="light"] .sidebar {
- background: linear-gradient(180deg, rgba(255, 255, 255, 0.98), rgba(255, 255, 255, 0.95));
- border-right: 1px solid rgba(0, 0, 0, 0.08);
-}
-
-[data-theme="light"] .search-wrapper input {
- background: rgba(0, 0, 0, 0.03);
- border: 1px solid rgba(0, 0, 0, 0.08);
- color: #1e293b;
-}
-
-[data-theme="light"] .search-wrapper input::placeholder {
- color: #94a3b8;
-}
-
-[data-theme="light"] .search-wrapper input:focus {
- box-shadow: 0 2px 12px rgba(37, 99, 235, 0.15);
- border-color: #3b82f6;
-}
-
-[data-theme="light"] .search-ico {
- fill: #64748b;
-}
-
-[data-theme="light"] .toc-item a {
- color: #475569;
-}
-
-[data-theme="light"] .toc-item a:hover {
- background: rgba(37, 99, 235, 0.08);
- color: #2563eb;
-}
-
-[data-theme="light"] .toc-item a.active {
- background: linear-gradient(90deg, #f97316, #a855f7);
- color: #ffffff;
-}
-
-[data-theme="light"] .content {
- background: linear-gradient(135deg, rgba(249, 115, 22, 0.05), rgba(168, 85, 247, 0.05));
-}
-
-[data-theme="light"] .content-inner {
- background: rgba(255, 255, 255, 0.7);
- backdrop-filter: blur(10px);
- box-shadow: 0 4px 24px rgba(0, 0, 0, 0.08);
-}
-
-[data-theme="light"] .content-inner:hover {
- box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12);
-}
-
-[data-theme="light"] #article h1,
-[data-theme="light"] #article h2,
-[data-theme="light"] #article h3 {
- color: #0f172a;
-}
-
-[data-theme="light"] #article p,
-[data-theme="light"] #article li {
- color: #475569;
-}
-
-[data-theme="light"] #article a {
- color: #2563eb;
-}
-
-[data-theme="light"] #article a:hover {
- color: #1d4ed8;
-}
-
-[data-theme="light"] #article code {
- background: rgba(168, 85, 247, 0.08);
- color: #7c3aed;
+ gap: 24px;
}
-[data-theme="light"] pre {
- background: #1e293b;
- box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
+.footer-links {
+ display: flex;
+ gap: 24px;
}
-[data-theme="light"] #article table th,
-[data-theme="light"] #article table td {
- border: 1px solid rgba(0, 0, 0, 0.08);
- background: rgba(0, 0, 0, 0.02);
- color: #475569;
+.footer-links a {
+ color: var(--muted);
+ text-decoration: none;
+ transition: color 0.2s ease;
}
-[data-theme="light"] #article table th {
- background: rgba(168, 85, 247, 0.08);
- color: #7c3aed;
+.footer-links a:hover {
+ color: var(--accent);
}
-[data-theme="light"] mark {
- background: rgba(249, 115, 22, 0.2);
- color: #1e293b;
+.footer-bottom {
+ margin-top: 24px;
+ font-size: 0.9em;
}
-[data-theme="light"] .heading-anchor {
- color: #94a3b8;
+[data-theme='light'] .nav-links a:hover {
+ color: var(--accent);
}
-[data-theme="light"] .sidebar-footer .btn {
- background: rgba(0, 0, 0, 0.04);
- color: #3b82f6;
+[data-theme='light'] .nav-btn:hover {
+ color: var(--accent);
}
-[data-theme="light"] .toc-toggle {
- color: #64748b;
+[data-theme='light'] .brand a {
+ color: var(--muted);
}
-[data-theme="light"] .site-footer {
- background: linear-gradient(135deg, rgba(248, 250, 252, 0.96), rgba(226, 232, 240, 0.92));
- box-shadow: 0 -2px 12px rgba(0, 0, 0, 0.08);
- color: #1e293b;
+[data-theme='light'] .toc-item a:hover {
+ color: var(--accent);
}
-[data-theme="light"] .footer-col h4 {
- color: #f97316;
+[data-theme='light'] .toc-toggle:hover {
+ color: var(--accent);
}
-[data-theme="light"] .footer-desc,
-[data-theme="light"] .footer-links a,
-[data-theme="light"] .footer-socials a {
- color: #475569;
+[data-theme='light'] .sidebar-footer .btn:hover {
+ color: var(--accent);
}
-[data-theme="light"] .footer-links a:hover,
-[data-theme="light"] .footer-socials a:hover {
- color: #f97316;
+[data-theme='light'] #article h1, [data-theme='light'] #article h2, [data-theme='light'] #article h3 {
+ color: #000;
}
-[data-theme="light"] .footer-bottom {
- color: #64748b;
- border-top: 1px solid rgba(0, 0, 0, 0.06);
+[data-theme='light'] mark {
+ color: #000;
}
-@media (max-width: 900px) {
- [data-theme="light"] .sidebar {
- background: linear-gradient(180deg, rgba(248, 250, 252, 0.98), rgba(248, 250, 252, 0.95));
- }
-}
+[data-theme='light'] .footer-links a:hover {
+ color: var(--accent);
+}
\ No newline at end of file
diff --git a/hacktoberfest2025%20guide.html b/hacktoberfest2025%20guide.html
new file mode 100644
index 0000000..f48020b
--- /dev/null
+++ b/hacktoberfest2025%20guide.html
@@ -0,0 +1,119 @@
+
+
+
+
+
+
+ Hacktoberfest 2025 — Beginner’s Guide
+
+
+
+
+
+
+
+
+
+
+
+
+
+
What is Hacktoberfest?
+
Hacktoberfest is a month-long celebration of open-source software run by DigitalOcean. It is a great way to get started with open source and contribute to projects you care about.
+
+
+
+
+
+
🎁 Rewards
+
Participants who complete the challenge can choose to receive a limited edition Hacktoberfest t-shirt or have a tree planted in their name.
+
+
+
+
+
+
📂 Finding Beginner-Friendly Repositories
+
Many projects on GitHub and GitLab welcome new contributors. Look for issues with labels like good first issue , beginner , or hacktoberfest .
+
+
+
+
+
+
🚀 How to Participate
+
+ Register for Hacktoberfest on the official website.
+ Find a project that interests you and that is participating in Hacktoberfest.
+ Make a meaningful contribution to the project. This can be a code contribution, a documentation update, or something else.
+ Open a pull request with your contribution.
+ Once you have four pull requests merged, you have completed the challenge!
+
+
+
+
+
+
+
💡 Tips for Beginners
+
+ Don't be afraid to ask for help.
+ Start with small contributions and work your way up.
+ Be respectful of the project's maintainers and community.
+ Have fun!
+
+
+
+
+
+
+
+
+
diff --git a/index.html b/index.html
index 2b7082d..036bdf1 100644
--- a/index.html
+++ b/index.html
@@ -24,816 +24,51 @@
+
+
+
+
+
-
-
-
-
-
+
- Loading README.md…
+ Loading…
@@ -901,13 +102,12 @@
Loading README.md…
padding: 18px;
max-width: 720px;
margin: 18px auto;
- background: #081226;
- border-radius: 10px;
- color: #9fb1c7;
+ background: #1a1a1a;
+ border-radius: 8px;
+ color: #a3a3a3;
"
>
- JavaScript is required to render this site preview. Open
-
README.md directly to view the content.
+ JavaScript is required to render this site. Please enable it to continue.
@@ -927,12 +127,8 @@ Loading README.md…
headerIds: true,
mangle: false,
highlight: function (code, lang) {
- try {
- return hljs.highlightAuto(code, lang ? [lang] : undefined)
- .value;
- } catch (e) {
- return hljs.highlightAuto(code).value;
- }
+ const language = hljs.getLanguage(lang) ? lang : 'plaintext';
+ return hljs.highlight(code, { language }).value;
},
});
@@ -940,35 +136,29 @@ Loading README.md…
const article = document.getElementById("article");
article.innerHTML = html;
- // Add anchors to headings and small animated anchor links
+ // Add anchors to headings
document
.querySelectorAll(
"#article h1, #article h2, #article h3, #article h4, #article h5, #article h6"
)
.forEach((h) => {
- const id =
- h.id ||
- h.textContent
- .trim()
- .toLowerCase()
- .replace(/[^a-z0-9]+/g, "-");
+ const id = h.id || h.textContent.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-");
h.id = id;
const a = document.createElement("a");
a.className = "heading-anchor";
a.href = "#" + id;
a.title = "Link to " + h.textContent.trim();
- a.innerHTML = "¶";
+ a.innerHTML = "#";
h.appendChild(a);
});
buildTOC();
initSearch(md);
initActiveObserver();
- hljs.highlightAll();
} catch (err) {
document.getElementById("article").innerHTML =
- 'Unable to load README ' +
- err.message +
+ '
';
}
}
@@ -993,7 +183,7 @@
Loading README.md…
li.className = "toc-item toc-" + h.tagName.toLowerCase();
const a = document.createElement("a");
a.href = "#" + h.id;
- a.textContent = h.textContent.trim();
+ a.textContent = h.textContent.trim().replace(/#$/, '');
a.addEventListener("click", (e) => {
e.preventDefault();
const target = document.getElementById(h.id);
@@ -1006,26 +196,12 @@
Loading README.md…
});
toc.appendChild(list);
-
- // Add small animated reveal for TOC items
- const tocLinks = Array.from(document.querySelectorAll(".toc-item"));
- tocLinks.forEach((li, i) => {
- li.style.opacity = 0;
- li.style.transform = "translateX(-6px)";
- setTimeout(() => {
- li.style.transition =
- "opacity .36s ease, transform .36s cubic-bezier(.2,.9,.2,1)";
- li.style.opacity = 1;
- li.style.transform = "none";
- }, 120 + i * 40);
- });
}
- // Search: client-side simple search across headings and content
+ // Search: client-side simple search
function initSearch(mdText) {
const input = document.getElementById("search");
const toc = document.getElementById("toc");
- const content = document.getElementById("article");
let searchTimeout;
input.addEventListener("input", () => {
@@ -1034,22 +210,17 @@
Loading README.md…
const q = input.value.trim().toLowerCase();
const items = Array.from(document.querySelectorAll(".toc-item"));
- // Clear previous highlights
document.querySelectorAll("#article mark").forEach((m) => {
m.outerHTML = m.innerHTML;
});
if (!q) {
items.forEach((i) => i.classList.remove("dim"));
- document
- .querySelectorAll("#article mark")
- .forEach((m) => (m.outerHTML = m.innerHTML));
return;
}
- // Highlight matches in article text
const regex = new RegExp(
- "(" + q.replace(/[.*+?^${}()|[\]\\]/g, "\\$&") + ")",
+ "(" + q.replace(/[.*+?^${}()|[\\]/g, "\\$&") + ")",
"ig"
);
const walker = document.createTreeWalker(
@@ -1060,28 +231,23 @@
Loading README.md…
while (walker.nextNode()) textNodes.push(walker.currentNode);
textNodes.forEach((node) => {
- if (
- !node.parentElement.matches("code, pre, a, .heading-anchor")
- ) {
- const v = node.nodeValue;
- if (v.match(regex)) {
- const span = document.createElement("span");
- span.innerHTML = v.replace(regex, "
$1 ");
- node.parentNode.replaceChild(span, node);
- }
+ if (node.parentElement.matches("code, pre, a, .heading-anchor")) return;
+ const v = node.nodeValue;
+ if (v.match(regex)) {
+ const span = document.createElement("span");
+ span.innerHTML = v.replace(regex, "
$1 ");
+ node.parentNode.replaceChild(span, node);
}
});
- // Dim non-matching TOC items
items.forEach((i) => {
const text = i.textContent.toLowerCase();
if (text.includes(q)) i.classList.remove("dim");
else i.classList.add("dim");
});
- }, 300); // Debounce search for better performance
+ }, 200);
});
- // Allow pressing Enter to focus first match
input.addEventListener("keydown", (e) => {
if (e.key === "Enter") {
const first = document.querySelector(".toc-item:not(.dim) a");
@@ -1090,11 +256,10 @@
Loading README.md…
});
}
- // Highlight active heading via IntersectionObserver
+ // Highlight active heading
function initActiveObserver() {
const options = {
- root: null,
- rootMargin: "0px 0px -60% 0px",
+ rootMargin: "0px 0px -80% 0px",
threshold: 0,
};
const obs = new IntersectionObserver((entries) => {
@@ -1117,109 +282,12 @@
Loading README.md…
.forEach((h) => obs.observe(h));
}
- // TOC toggle for small screens
- document.getElementById("toc-toggle").addEventListener("click", (e) => {
- const sidebar = document.getElementById("sidebar");
- const showBtn = document.getElementById("show-sidebar-btn");
- const expanded = sidebar.classList.toggle("collapsed");
- e.target.textContent = expanded ? "Show" : "Hide";
- e.target.setAttribute("aria-expanded", String(!expanded));
-
- // Show/hide the arrow button
- if (expanded) {
- showBtn.classList.add("visible");
- } else {
- showBtn.classList.remove("visible");
- }
- });
-
- // Show sidebar button functionality
- document.getElementById("show-sidebar-btn").addEventListener("click", () => {
- const sidebar = document.getElementById("sidebar");
- const showBtn = document.getElementById("show-sidebar-btn");
- const tocToggle = document.getElementById("toc-toggle");
-
- sidebar.classList.remove("collapsed");
- showBtn.classList.remove("visible");
- tocToggle.textContent = "Hide";
- tocToggle.setAttribute("aria-expanded", "true");
- });
-
- // Navbar interactions: focus search and toggle sidebar
- document
- .getElementById("nav-search-btn")
- .addEventListener("click", () => {
- const s = document.getElementById("search");
- if (s) {
- s.focus();
- s.scrollIntoView({ behavior: "smooth", block: "center" });
- }
- });
+ // Sidebar toggle
document.getElementById("hamburger").addEventListener("click", () => {
- const sidebar = document.getElementById("sidebar");
- const showBtn = document.getElementById("show-sidebar-btn");
- const tocToggle = document.getElementById("toc-toggle");
- const expanded = sidebar.classList.toggle("collapsed");
-
- // Update show button visibility
- if (expanded) {
- showBtn.classList.add("visible");
- } else {
- showBtn.classList.remove("visible");
- }
-
- // Update TOC toggle text
- tocToggle.textContent = expanded ? "Show" : "Hide";
- tocToggle.setAttribute("aria-expanded", String(!expanded));
+ document.getElementById("sidebar").classList.toggle("collapsed");
});
- // Auto-collapse sidebar on mobile and handle window resize
- function handleSidebarResponsiveness() {
- const sidebar = document.getElementById("sidebar");
- const showBtn = document.getElementById("show-sidebar-btn");
- const tocToggle = document.getElementById("toc-toggle");
- const isMobile = window.innerWidth <= 900;
-
- if (isMobile) {
- sidebar.classList.add("collapsed");
- showBtn.classList.add("visible");
- tocToggle.textContent = "Show";
- tocToggle.setAttribute("aria-expanded", "false");
- } else {
- sidebar.classList.remove("collapsed");
- showBtn.classList.remove("visible");
- tocToggle.textContent = "Hide";
- tocToggle.setAttribute("aria-expanded", "true");
- }
- }
-
- // Initial check and window resize listener
- handleSidebarResponsiveness();
- window.addEventListener("resize", handleSidebarResponsiveness);
-
- // Close sidebar when clicking outside on mobile
- document.addEventListener("click", (e) => {
- const sidebar = document.getElementById("sidebar");
- const hamburger = document.getElementById("hamburger");
- const showBtn = document.getElementById("show-sidebar-btn");
- const tocToggle = document.getElementById("toc-toggle");
- const isMobile = window.innerWidth <= 900;
-
- if (
- isMobile &&
- !sidebar.contains(e.target) &&
- !hamburger.contains(e.target) &&
- !showBtn.contains(e.target) &&
- !sidebar.classList.contains("collapsed")
- ) {
- sidebar.classList.add("collapsed");
- showBtn.classList.add("visible");
- tocToggle.textContent = "Show";
- tocToggle.setAttribute("aria-expanded", "false");
- }
- });
-
- // keyboard shortcut: press '/' to focus search
+ // keyboard shortcut: '/' to search
document.addEventListener("keydown", (e) => {
if (
e.key === "/" &&
@@ -1231,330 +299,53 @@
Loading README.md…
}
});
- // Track the currently loaded markdown file
- let currentMarkdownFile = "README.md";
-
- // Handle brand/logo click to return to README
- document.querySelectorAll(".brand").forEach((brand) => {
- brand.addEventListener("click", (e) => {
- if (brand.tagName === "A") {
- e.preventDefault();
- loadMarkdownFile("README.md");
- }
- });
- });
-
- // Smooth scroll for nav links
- document.querySelectorAll(".nav-links a").forEach((link) => {
- link.addEventListener("click", (e) => {
- const href = link.getAttribute("href");
-
- // If link has target _blank or points to projects.html, let browser handle it
- if (link.target === '_blank' || href === 'projects.html') {
- return; // Don't intercept new-tab or projects page
- }
-
- // Allow fully qualified external links to work normally
- if (href.startsWith("http://") || href.startsWith("https://")) {
- return; // External link
- }
-
- // Only intercept internal hash navigation (href begins with '#')
- if (!href.startsWith('#')) {
- return; // Not a hash link we manage
- }
-
- e.preventDefault();
-
- // For internal hash links, check if we need to reload README first
- const id = href.slice(1);
-
- // If we're not on README, load it first, then scroll to the section
- if (currentMarkdownFile !== "README.md") {
- loadMarkdownFile("README.md", id);
- return;
- }
-
- // Otherwise, just scroll to the section
- let element = document.getElementById(id);
-
- // If element not found, try to find it by searching through headings
- if (!element) {
- const headings = document.querySelectorAll(
- "#article h1, #article h2, #article h3, #article h4, #article h5, #article h6"
- );
- for (const heading of headings) {
- const headingText = heading.textContent.trim().toLowerCase();
- const cleanId = headingText
- .replace(/[^a-z0-9]+/g, "-")
- .replace(/^-+|-+$/g, "");
- if (cleanId === id || heading.id === id) {
- element = heading;
- heading.id = id; // Ensure the ID is set correctly
- break;
- }
- }
- }
-
- if (element) {
- element.scrollIntoView({ behavior: "smooth", block: "start" });
- setTimeout(() => {
- history.pushState(null, "", "#" + id);
- element.classList.add("highlight-section");
- setTimeout(
- () => element.classList.remove("highlight-section"),
- 1000
- );
- }, 100);
- } else {
- console.warn("Element not found for ID:", id);
- // Fallback: just update the URL
- history.pushState(null, "", "#" + id);
- }
- });
- });
-
- // Function to load any markdown file
- async function loadMarkdownFile(filename, scrollToId = null) {
- try {
- const res = await fetch(filename);
- if (!res.ok) throw new Error(`${filename} not found`);
- const md = await res.text();
-
- // Configure marked and highlight
- marked.setOptions({
- headerIds: true,
- mangle: false,
- highlight: function (code, lang) {
- try {
- return hljs.highlightAuto(code, lang ? [lang] : undefined)
- .value;
- } catch (e) {
- return hljs.highlightAuto(code).value;
- }
- },
- });
-
- const html = marked.parse(md);
- const article = document.getElementById("article");
- article.innerHTML = html;
-
- // Add anchors to headings
- document
- .querySelectorAll(
- "#article h1, #article h2, #article h3, #article h4, #article h5, #article h6"
- )
- .forEach((h) => {
- const id =
- h.id ||
- h.textContent
- .trim()
- .toLowerCase()
- .replace(/[^a-z0-9]+/g, "-");
- h.id = id;
- const a = document.createElement("a");
- a.className = "heading-anchor";
- a.href = "#" + id;
- a.title = "Link to " + h.textContent.trim();
- a.innerHTML = "¶";
- h.appendChild(a);
- });
-
- // Update current file tracker
- currentMarkdownFile = filename;
-
- // Scroll to specific section if requested, otherwise scroll to top
- if (scrollToId) {
- setTimeout(() => {
- const element = document.getElementById(scrollToId);
- if (element) {
- element.scrollIntoView({ behavior: "smooth", block: "start" });
- history.pushState(null, "", "#" + scrollToId);
- element.classList.add("highlight-section");
- setTimeout(() => element.classList.remove("highlight-section"), 1000);
- }
- }, 100);
- } else {
- window.scrollTo({ top: 0, behavior: "smooth" });
- }
-
- buildTOC();
- initSearch(md);
- initActiveObserver();
- hljs.highlightAll();
-
- // Update URL
- if (!scrollToId) {
- history.pushState(null, "", filename === "README.md" ? "./" : `?file=${filename}`);
- }
- } catch (err) {
- document.getElementById("article").innerHTML =
- `
`;
- }
- }
-
- // Enhanced renderReadme function
- async function renderReadme() {
- try {
- const res = await fetch("README.md");
- if (!res.ok) throw new Error("README.md not found");
- const md = await res.text();
-
- // Configure marked and highlight
- marked.setOptions({
- headerIds: true,
- mangle: false,
- highlight: function (code, lang) {
- try {
- return hljs.highlightAuto(code, lang ? [lang] : undefined)
- .value;
- } catch (e) {
- return hljs.highlightAuto(code).value;
- }
- },
- });
-
- const html = marked.parse(md);
- const article = document.getElementById("article");
- article.innerHTML = html;
-
- // Add anchors to headings and small animated anchor links
- document
- .querySelectorAll(
- "#article h1, #article h2, #article h3, #article h4, #article h5, #article h6"
- )
- .forEach((h) => {
- const id =
- h.id ||
- h.textContent
- .trim()
- .toLowerCase()
- .replace(/[^a-z0-9]+/g, "-");
- h.id = id;
- const a = document.createElement("a");
- a.className = "heading-anchor";
- a.href = "#" + id;
- a.title = "Link to " + h.textContent.trim();
- a.innerHTML = "¶";
- h.appendChild(a);
- });
-
- buildTOC();
- initSearch(md);
- initActiveObserver();
- hljs.highlightAll();
- } catch (err) {
- document.getElementById("article").innerHTML =
- '
';
- }
- }
-
- // If visiting index.html with a hash (e.g., index.html#resources), remember it
- const initialHash = window.location.hash ? window.location.hash.slice(1) : null;
-
- // Render README and, if there was an initial hash, scroll to that section after render
- renderReadme().then(() => {
- if (initialHash) {
- // If the article is already rendered, try to find the element and scroll to it
- const el = document.getElementById(initialHash);
- if (el) {
- setTimeout(() => {
- el.scrollIntoView({ behavior: 'smooth', block: 'start' });
- history.replaceState(null, '', '#' + initialHash);
- el.classList.add('highlight-section');
- setTimeout(() => el.classList.remove('highlight-section'), 1000);
- }, 120);
- } else {
- // If element not found, ensure loadMarkdownFile handles it by reloading README and passing id
- loadMarkdownFile('README.md', initialHash);
- }
- }
- });
-
// Theme toggle
const themeToggle = document.getElementById('theme-toggle');
const html = document.documentElement;
const savedTheme = localStorage.getItem('theme') || 'dark';
html.setAttribute('data-theme', savedTheme);
- themeToggle.textContent = savedTheme === 'dark' ? '🌙' : '☀️';
+ themeToggle.innerHTML = savedTheme === 'dark' ?
+ '
' :
+ '
';
themeToggle.addEventListener('click', () => {
const current = html.getAttribute('data-theme');
const next = current === 'dark' ? 'light' : 'dark';
html.setAttribute('data-theme', next);
localStorage.setItem('theme', next);
- themeToggle.textContent = next === 'dark' ? '🌙' : '☀️';
+ themeToggle.innerHTML = next === 'dark' ?
+ '
' :
+ '
';
+ });
+
+ renderReadme();
+
+ // Smooth scrolling for nav links
+ document.querySelectorAll('.nav-links a[href^="#"]').forEach(anchor => {
+ anchor.addEventListener('click', function (e) {
+ e.preventDefault();
+
+ document.querySelector(this.getAttribute('href')).scrollIntoView({
+ behavior: 'smooth'
+ });
+ });
});
-