|
7 | 7 | <meta name="description" content="Train, run, and serve ML models in your Go application. 245 tok/s on Gemma 3 1B — 20% faster than Ollama. Pure Go, zero CGo."> |
8 | 8 | <meta name="theme-color" content="#8B5CF6"> |
9 | 9 | <link rel="icon" href="zerfoo.svg" type="image/svg+xml"> |
| 10 | +<script>(function(){var t=localStorage.getItem('theme');if(t)document.documentElement.classList.add(t)})()</script> |
10 | 11 | <style> |
11 | 12 | *,*::before,*::after{box-sizing:border-box;margin:0;padding:0} |
12 | 13 | :root{ |
13 | 14 | --purple:#8B5CF6;--blue:#3B82F6;--cyan:#06B6D4; |
14 | 15 | --bg:#0B0F1A;--bg2:#111827;--bg3:#1F2937; |
15 | 16 | --fg:#F9FAFB;--fg2:#D1D5DB;--fg3:#9CA3AF; |
| 17 | + --border:rgba(255,255,255,.06);--border-hover:rgba(139,92,246,.3);--border-hover-blue:rgba(59,130,246,.3);--border-hover-cyan:rgba(6,182,212,.3); |
| 18 | + --nav-bg:rgba(11,15,26,.85); |
| 19 | + --gh-btn-hover:#374151; |
| 20 | + --bar-muted:var(--bg3); |
| 21 | + --bench-note-bg:var(--bg); |
| 22 | + --purple-subtle:rgba(139,92,246,.12);--purple-code:rgba(139,92,246,.1);--purple-glow:rgba(139,92,246,.3);--purple-glow-hover:rgba(139,92,246,.45);--purple-tag:rgba(139,92,246,.15); |
| 23 | + --syn-kw:#C084FC;--syn-fn:#60A5FA;--syn-str:#34D399;--syn-cmt:#6B7280;--syn-type:#F472B6;--syn-num:#FBBF24; |
16 | 24 | --grad:linear-gradient(135deg,var(--purple),var(--blue),var(--cyan)); |
17 | 25 | --mono:'SFMono-Regular',Consolas,'Liberation Mono',Menlo,monospace; |
18 | 26 | --sans:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif; |
19 | 27 | --max:1120px; |
20 | 28 | } |
| 29 | +@media(prefers-color-scheme:light){ |
| 30 | + :root:not(.dark){ |
| 31 | + --purple:#7C3AED;--blue:#2563EB;--cyan:#0891B2; |
| 32 | + --bg:#FFFFFF;--bg2:#F3F4F6;--bg3:#E5E7EB; |
| 33 | + --fg:#111827;--fg2:#374151;--fg3:#6B7280; |
| 34 | + --border:rgba(0,0,0,.08);--border-hover:rgba(124,58,237,.2);--border-hover-blue:rgba(37,99,235,.2);--border-hover-cyan:rgba(8,145,178,.2); |
| 35 | + --nav-bg:rgba(255,255,255,.85); |
| 36 | + --gh-btn-hover:#D1D5DB; |
| 37 | + --bar-muted:var(--bg3); |
| 38 | + --bench-note-bg:var(--bg2); |
| 39 | + --purple-subtle:rgba(124,58,237,.08);--purple-code:rgba(124,58,237,.08);--purple-glow:rgba(124,58,237,.2);--purple-glow-hover:rgba(124,58,237,.3);--purple-tag:rgba(124,58,237,.1); |
| 40 | + --syn-kw:#7C3AED;--syn-fn:#2563EB;--syn-str:#059669;--syn-cmt:#9CA3AF;--syn-type:#DB2777;--syn-num:#D97706; |
| 41 | + } |
| 42 | +} |
| 43 | +:root.light{ |
| 44 | + --purple:#7C3AED;--blue:#2563EB;--cyan:#0891B2; |
| 45 | + --bg:#FFFFFF;--bg2:#F3F4F6;--bg3:#E5E7EB; |
| 46 | + --fg:#111827;--fg2:#374151;--fg3:#6B7280; |
| 47 | + --border:rgba(0,0,0,.08);--border-hover:rgba(124,58,237,.2);--border-hover-blue:rgba(37,99,235,.2);--border-hover-cyan:rgba(8,145,178,.2); |
| 48 | + --nav-bg:rgba(255,255,255,.85); |
| 49 | + --gh-btn-hover:#D1D5DB; |
| 50 | + --bar-muted:var(--bg3); |
| 51 | + --bench-note-bg:var(--bg2); |
| 52 | + --purple-subtle:rgba(124,58,237,.08);--purple-code:rgba(124,58,237,.08);--purple-glow:rgba(124,58,237,.2);--purple-glow-hover:rgba(124,58,237,.3);--purple-tag:rgba(124,58,237,.1); |
| 53 | + --syn-kw:#7C3AED;--syn-fn:#2563EB;--syn-str:#059669;--syn-cmt:#9CA3AF;--syn-type:#DB2777;--syn-num:#D97706; |
| 54 | +} |
21 | 55 | html{scroll-behavior:smooth;font-size:16px} |
22 | 56 | body{background:var(--bg);color:var(--fg);font-family:var(--sans);line-height:1.6;-webkit-font-smoothing:antialiased} |
23 | 57 | a{color:var(--blue);text-decoration:none;transition:color .15s} |
|
30 | 64 | @media(max-width:768px){section{padding:56px 0}} |
31 | 65 |
|
32 | 66 | /* Nav */ |
33 | | -nav{position:sticky;top:0;z-index:100;background:rgba(11,15,26,.85);backdrop-filter:blur(12px);border-bottom:1px solid rgba(255,255,255,.06)} |
| 67 | +nav{position:sticky;top:0;z-index:100;background:var(--nav-bg);backdrop-filter:blur(12px);border-bottom:1px solid var(--border)} |
34 | 68 | nav .wrap{display:flex;align-items:center;justify-content:space-between;height:64px} |
35 | 69 | nav .logo{display:flex;align-items:center;gap:10px;font-weight:700;font-size:1.125rem;color:var(--fg)} |
36 | 70 | nav .logo img{width:32px;height:32px} |
37 | 71 | nav .links{display:flex;gap:24px;font-size:.875rem;align-items:center} |
38 | 72 | nav .links a{color:var(--fg2)} |
39 | 73 | nav .links a:hover{color:var(--fg)} |
40 | 74 | .gh-btn{display:inline-flex;align-items:center;gap:6px;padding:6px 14px;border-radius:6px;background:var(--bg3);color:var(--fg)!important;font-size:.8125rem;font-weight:500;transition:background .15s} |
41 | | -.gh-btn:hover{background:#374151} |
| 75 | +.gh-btn:hover{background:var(--gh-btn-hover)} |
42 | 76 | .gh-btn svg{width:16px;height:16px;fill:currentColor} |
43 | 77 |
|
| 78 | +.theme-toggle{background:none;border:none;color:var(--fg2);cursor:pointer;padding:4px;display:flex;align-items:center;transition:color .15s} |
| 79 | +.theme-toggle:hover{color:var(--fg)} |
| 80 | +.theme-toggle svg{width:18px;height:18px} |
| 81 | +.theme-toggle .icon-sun{display:none} |
| 82 | +.light .theme-toggle .icon-sun,.dark .theme-toggle .icon-sun{display:block} |
| 83 | +.light .theme-toggle .icon-moon,.dark .theme-toggle .icon-moon{display:none} |
| 84 | +@media(prefers-color-scheme:light){ |
| 85 | + :root:not(.dark) .theme-toggle .icon-sun{display:block} |
| 86 | + :root:not(.dark) .theme-toggle .icon-moon{display:none} |
| 87 | +} |
| 88 | + |
44 | 89 | /* Mobile nav */ |
45 | 90 | .nav-toggle{display:none;background:none;border:none;color:var(--fg);cursor:pointer;padding:4px} |
46 | 91 | @media(max-width:640px){ |
47 | 92 | .nav-toggle{display:block} |
48 | | - nav .links{display:none;position:absolute;top:64px;left:0;right:0;flex-direction:column;background:var(--bg2);padding:16px 24px;gap:16px;border-bottom:1px solid rgba(255,255,255,.06)} |
| 93 | + nav .links{display:none;position:absolute;top:64px;left:0;right:0;flex-direction:column;background:var(--bg2);padding:16px 24px;gap:16px;border-bottom:1px solid var(--border)} |
49 | 94 | nav .links.open{display:flex} |
50 | 95 | } |
51 | 96 |
|
|
63 | 108 | .hero .actions{display:flex;justify-content:center;gap:12px;flex-wrap:wrap} |
64 | 109 | .btn{display:inline-flex;align-items:center;gap:8px;padding:12px 28px;border-radius:8px;font-weight:600;font-size:.9375rem;transition:transform .15s,box-shadow .15s} |
65 | 110 | .btn:hover{transform:translateY(-1px)} |
66 | | -.btn-primary{background:var(--grad);color:#fff;box-shadow:0 4px 24px rgba(139,92,246,.3)} |
67 | | -.btn-primary:hover{box-shadow:0 6px 32px rgba(139,92,246,.45);color:#fff} |
| 111 | +.btn-primary{background:var(--grad);color:#fff;box-shadow:0 4px 24px var(--purple-glow)} |
| 112 | +.btn-primary:hover{box-shadow:0 6px 32px var(--purple-glow-hover);color:#fff} |
68 | 113 | .btn-secondary{background:var(--bg3);color:var(--fg)} |
69 | | -.btn-secondary:hover{background:#374151;color:var(--fg)} |
| 114 | +.btn-secondary:hover{background:var(--gh-btn-hover);color:var(--fg)} |
70 | 115 |
|
71 | 116 | /* Install bar */ |
72 | 117 | .install{display:flex;justify-content:center;margin-top:32px} |
73 | | -.install-bar{display:inline-flex;align-items:center;gap:12px;background:var(--bg2);border:1px solid rgba(255,255,255,.08);border-radius:8px;padding:10px 20px;font-family:var(--mono);font-size:.875rem;color:var(--fg2)} |
| 118 | +.install-bar{display:inline-flex;align-items:center;gap:12px;background:var(--bg2);border:1px solid var(--border);border-radius:8px;padding:10px 20px;font-family:var(--mono);font-size:.875rem;color:var(--fg2)} |
74 | 119 | .install-bar .dollar{color:var(--fg3);user-select:none} |
75 | 120 | .install-bar button{background:none;border:none;color:var(--fg3);cursor:pointer;padding:4px;transition:color .15s} |
76 | 121 | .install-bar button:hover{color:var(--fg)} |
|
79 | 124 | .code-section{background:var(--bg2)} |
80 | 125 | .code-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(340px,1fr));gap:24px} |
81 | 126 | @media(max-width:480px){.code-grid{grid-template-columns:1fr}} |
82 | | -.code-card{background:var(--bg);border:1px solid rgba(255,255,255,.06);border-radius:12px;overflow:hidden} |
83 | | -.code-card .card-head{padding:16px 20px;border-bottom:1px solid rgba(255,255,255,.06);display:flex;align-items:center;gap:8px} |
| 127 | +.code-card{background:var(--bg);border:1px solid var(--border);border-radius:12px;overflow:hidden} |
| 128 | +.code-card .card-head{padding:16px 20px;border-bottom:1px solid var(--border);display:flex;align-items:center;gap:8px} |
84 | 129 | .code-card .card-head .dot{width:8px;height:8px;border-radius:50%} |
85 | 130 | .code-card .card-head .dot:nth-child(1){background:#EF4444} |
86 | 131 | .code-card .card-head .dot:nth-child(2){background:#EAB308} |
87 | 132 | .code-card .card-head .dot:nth-child(3){background:#22C55E} |
88 | 133 | .code-card .card-head span:last-child{margin-left:8px;font-size:.75rem;color:var(--fg3);font-family:var(--mono)} |
89 | 134 | pre{margin:0;padding:20px;overflow-x:auto;font-family:var(--mono);font-size:.8125rem;line-height:1.7;color:var(--fg2)} |
90 | | -pre .kw{color:#C084FC} |
91 | | -pre .fn{color:#60A5FA} |
92 | | -pre .str{color:#34D399} |
93 | | -pre .cmt{color:#6B7280} |
94 | | -pre .type{color:#F472B6} |
95 | | -pre .num{color:#FBBF24} |
| 135 | +pre .kw{color:var(--syn-kw)} |
| 136 | +pre .fn{color:var(--syn-fn)} |
| 137 | +pre .str{color:var(--syn-str)} |
| 138 | +pre .cmt{color:var(--syn-cmt)} |
| 139 | +pre .type{color:var(--syn-type)} |
| 140 | +pre .num{color:var(--syn-num)} |
96 | 141 |
|
97 | 142 | /* Features */ |
98 | 143 | .features{background:var(--bg)} |
99 | 144 | .section-head{text-align:center;margin-bottom:56px} |
100 | 145 | .section-head h2{font-size:clamp(1.5rem,3.5vw,2.25rem);font-weight:700;margin-bottom:12px} |
101 | 146 | .section-head p{color:var(--fg2);max-width:560px;margin:0 auto;font-size:1.0625rem} |
102 | 147 | .feat-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:20px} |
103 | | -.feat{background:var(--bg2);border:1px solid rgba(255,255,255,.06);border-radius:12px;padding:28px 24px;transition:border-color .2s} |
104 | | -.feat:hover{border-color:rgba(139,92,246,.3)} |
105 | | -.feat .icon{width:40px;height:40px;border-radius:10px;background:rgba(139,92,246,.12);display:flex;align-items:center;justify-content:center;margin-bottom:16px;font-size:1.25rem} |
| 148 | +.feat{background:var(--bg2);border:1px solid var(--border);border-radius:12px;padding:28px 24px;transition:border-color .2s} |
| 149 | +.feat:hover{border-color:var(--border-hover)} |
| 150 | +.feat .icon{width:40px;height:40px;border-radius:10px;background:var(--purple-subtle);display:flex;align-items:center;justify-content:center;margin-bottom:16px;font-size:1.25rem} |
106 | 151 | .feat h3{font-size:1.0625rem;font-weight:600;margin-bottom:8px} |
107 | 152 | .feat p{color:var(--fg3);font-size:.875rem;line-height:1.6} |
108 | | -.feat code{background:rgba(139,92,246,.1);padding:2px 6px;border-radius:4px;font-size:.8125rem;font-family:var(--mono)} |
| 153 | +.feat code{background:var(--purple-code);padding:2px 6px;border-radius:4px;font-size:.8125rem;font-family:var(--mono)} |
109 | 154 |
|
110 | 155 | /* Benchmarks */ |
111 | 156 | .bench{background:var(--bg2)} |
112 | 157 | .bench-table{width:100%;border-collapse:collapse;margin-top:8px;font-size:.875rem} |
113 | | -.bench-table th,.bench-table td{text-align:left;padding:12px 16px;border-bottom:1px solid rgba(255,255,255,.06)} |
| 158 | +.bench-table th,.bench-table td{text-align:left;padding:12px 16px;border-bottom:1px solid var(--border)} |
114 | 159 | .bench-table th{color:var(--fg3);font-weight:500;font-size:.75rem;text-transform:uppercase;letter-spacing:.05em} |
115 | 160 | .bench-table td{color:var(--fg2)} |
116 | 161 | .bench-table .highlight{color:var(--fg);font-weight:600} |
117 | 162 | .bench-bar{display:flex;align-items:center;gap:12px} |
118 | 163 | .bench-bar .bar{height:8px;border-radius:4px;background:var(--grad)} |
119 | 164 | .bench-bar .val{font-size:.8125rem;font-weight:600;color:var(--fg);min-width:72px} |
120 | | -.bench-note{margin-top:24px;padding:16px 20px;background:var(--bg);border-radius:8px;font-size:.8125rem;color:var(--fg3);border-left:3px solid var(--purple)} |
| 165 | +.bench-note{margin-top:24px;padding:16px 20px;background:var(--bench-note-bg);border-radius:8px;font-size:.8125rem;color:var(--fg3);border-left:3px solid var(--purple)} |
121 | 166 |
|
122 | 167 | /* Models */ |
123 | 168 | .models{background:var(--bg)} |
124 | 169 | .model-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:12px} |
125 | | -.model-card{background:var(--bg2);border:1px solid rgba(255,255,255,.06);border-radius:10px;padding:20px 16px;text-align:center;transition:border-color .2s} |
126 | | -.model-card:hover{border-color:rgba(59,130,246,.3)} |
| 170 | +.model-card{background:var(--bg2);border:1px solid var(--border);border-radius:10px;padding:20px 16px;text-align:center;transition:border-color .2s} |
| 171 | +.model-card:hover{border-color:var(--border-hover-blue)} |
127 | 172 | .model-card .name{font-weight:600;font-size:.9375rem;margin-bottom:4px} |
128 | 173 | .model-card .status{font-size:.75rem;color:var(--fg3)} |
129 | 174 | .model-card .status.prod{color:#34D399} |
130 | 175 |
|
131 | 176 | /* Blog */ |
132 | 177 | .blog{background:var(--bg2)} |
133 | 178 | .blog-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:20px} |
134 | | -.blog-card{display:block;background:var(--bg);border:1px solid rgba(255,255,255,.06);border-radius:12px;padding:28px 24px;transition:border-color .2s,transform .2s} |
135 | | -.blog-card:hover{border-color:rgba(59,130,246,.3);transform:translateY(-2px)} |
136 | | -.blog-card .tag{display:inline-block;font-size:.6875rem;font-weight:600;text-transform:uppercase;letter-spacing:.05em;padding:3px 8px;border-radius:4px;background:rgba(139,92,246,.15);color:var(--purple);margin-bottom:12px} |
| 179 | +.blog-card{display:block;background:var(--bg);border:1px solid var(--border);border-radius:12px;padding:28px 24px;transition:border-color .2s,transform .2s} |
| 180 | +.blog-card:hover{border-color:var(--border-hover-blue);transform:translateY(-2px)} |
| 181 | +.blog-card .tag{display:inline-block;font-size:.6875rem;font-weight:600;text-transform:uppercase;letter-spacing:.05em;padding:3px 8px;border-radius:4px;background:var(--purple-tag);color:var(--purple);margin-bottom:12px} |
137 | 182 | .blog-card h3{font-size:1rem;font-weight:600;margin-bottom:8px;color:var(--fg)} |
138 | 183 | .blog-card p{color:var(--fg3);font-size:.8125rem;line-height:1.6} |
139 | 184 |
|
140 | 185 | /* Ecosystem */ |
141 | 186 | .eco{background:var(--bg)} |
142 | 187 | .eco-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:16px} |
143 | | -@media(max-width:768px){.eco-grid{grid-template-columns:1fr}} |
144 | | -.eco-card{display:block;background:var(--bg2);border:1px solid rgba(255,255,255,.06);border-radius:10px;padding:24px 20px;transition:border-color .2s} |
145 | | -.eco-card:hover{border-color:rgba(6,182,212,.3)} |
| 188 | +@media(max-width:768px){.eco-grid{grid-template-columns:1fr}.feat-grid{grid-template-columns:repeat(auto-fit,minmax(240px,1fr))}} |
| 189 | +.eco-card{display:block;background:var(--bg2);border:1px solid var(--border);border-radius:10px;padding:24px 20px;transition:border-color .2s} |
| 190 | +.eco-card:hover{border-color:var(--border-hover-cyan)} |
146 | 191 | .eco-card .mod{font-family:var(--mono);font-size:.8125rem;color:var(--cyan);margin-bottom:8px} |
147 | 192 | .eco-card h3{font-size:.9375rem;font-weight:600;margin-bottom:6px;color:var(--fg)} |
148 | 193 | .eco-card p{color:var(--fg3);font-size:.8125rem;line-height:1.5} |
149 | 194 |
|
150 | 195 | /* Footer */ |
151 | | -footer{border-top:1px solid rgba(255,255,255,.06);padding:40px 0} |
| 196 | +footer{border-top:1px solid var(--border);padding:40px 0} |
152 | 197 | footer .wrap{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:16px} |
153 | 198 | footer .left{display:flex;align-items:center;gap:8px;font-size:.8125rem;color:var(--fg3)} |
154 | 199 | footer .left img{width:20px;height:20px;opacity:.5} |
155 | 200 | footer .right{display:flex;gap:20px;font-size:.8125rem} |
156 | 201 | footer .right a{color:var(--fg3)} |
157 | 202 | footer .right a:hover{color:var(--fg)} |
| 203 | + |
| 204 | +/* Mobile responsive */ |
| 205 | +@media(max-width:640px){ |
| 206 | + .wrap{padding:0 16px} |
| 207 | + .hero h1{font-size:1.75rem} |
| 208 | + .hero .sub{font-size:.9375rem} |
| 209 | + .hero .stats{gap:20px} |
| 210 | + .hero .stat .num{font-size:1.25rem} |
| 211 | + .hero .actions{flex-direction:column;align-items:center} |
| 212 | + .btn{width:100%;max-width:320px;justify-content:center} |
| 213 | + .install-bar{font-size:.75rem;padding:8px 14px;gap:8px;max-width:100%;overflow-x:auto} |
| 214 | + .section-head{margin-bottom:36px} |
| 215 | + .section-head h2{font-size:1.375rem} |
| 216 | + .section-head p{font-size:.9375rem} |
| 217 | + .feat-grid{grid-template-columns:1fr} |
| 218 | + .code-grid{grid-template-columns:1fr} |
| 219 | + pre{font-size:.75rem;padding:14px} |
| 220 | + .bench-table{font-size:.75rem} |
| 221 | + .bench-table th,.bench-table td{padding:8px 10px} |
| 222 | + .bench-bar .val{font-size:.75rem;min-width:56px} |
| 223 | + .model-grid{grid-template-columns:repeat(2,1fr)} |
| 224 | + .blog-grid{grid-template-columns:1fr} |
| 225 | + footer .wrap{flex-direction:column;text-align:center} |
| 226 | + footer .left{flex-direction:column} |
| 227 | + footer .right{justify-content:center} |
| 228 | +} |
158 | 229 | </style> |
159 | 230 | </head> |
160 | 231 | <body> |
|
172 | 243 | <a href="#models">Models</a> |
173 | 244 | <a href="#blog">Blog</a> |
174 | 245 | <a href="https://pkg.go.dev/github.com/zerfoo/zerfoo" target="_blank">Docs</a> |
| 246 | + <button class="theme-toggle" onclick="toggleTheme()" aria-label="Toggle theme"> |
| 247 | + <svg class="icon-moon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 12.79A9 9 0 1111.21 3 7 7 0 0021 12.79z"/></svg> |
| 248 | + <svg class="icon-sun" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="5"/><path d="M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42"/></svg> |
| 249 | + </button> |
175 | 250 | <a href="https://github.com/zerfoo/zerfoo" target="_blank" class="gh-btn"> |
176 | 251 | <svg viewBox="0 0 16 16"><path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"/></svg> |
177 | 252 | GitHub |
@@ -550,5 +625,20 @@ <h2 style="font-size:clamp(1.5rem,3.5vw,2.25rem);font-weight:700;margin-bottom:1 |
550 | 625 | </div> |
551 | 626 | </footer> |
552 | 627 |
|
| 628 | +<script> |
| 629 | +function toggleTheme(){ |
| 630 | + var r=document.documentElement; |
| 631 | + var isDark=r.classList.contains('dark'); |
| 632 | + var isLight=r.classList.contains('light'); |
| 633 | + if(isDark){r.classList.remove('dark');r.classList.add('light');localStorage.setItem('theme','light')} |
| 634 | + else if(isLight){r.classList.remove('light');r.classList.add('dark');localStorage.setItem('theme','dark')} |
| 635 | + else{ |
| 636 | + // No manual override yet — toggle from system default |
| 637 | + var sysLight=window.matchMedia('(prefers-color-scheme:light)').matches; |
| 638 | + if(sysLight){r.classList.add('dark');localStorage.setItem('theme','dark')} |
| 639 | + else{r.classList.add('light');localStorage.setItem('theme','light')} |
| 640 | + } |
| 641 | +} |
| 642 | +</script> |
553 | 643 | </body> |
554 | 644 | </html> |
0 commit comments