|
151 | 151 | .contact-value a:hover { border-bottom-color: var(--accent); } |
152 | 152 | .contact-note { font-size: 0.85rem; color: var(--text-muted); line-height: 1.7; margin-top: 1.5rem; } |
153 | 153 |
|
| 154 | + /* Visitor counter */ |
| 155 | + .visitor-counter { margin-top: 1.5rem; padding-top: 1.25rem; border-top: 1px solid var(--border-light); } |
| 156 | + .visitor-counter .about-sidebar-label { margin-bottom: 0.5rem; } |
| 157 | + .visitor-count-text { font-family: var(--serif); font-size: 0.88rem; color: var(--text-mid); line-height: 1.6; } |
| 158 | + .visitor-count-text .count-number { font-weight: 600; color: var(--accent); font-variant-numeric: tabular-nums; } |
| 159 | + .visitor-count-text.loading { color: var(--text-light); font-size: 0.82rem; font-family: var(--sans); } |
| 160 | + |
154 | 161 | /* Footer */ |
155 | 162 | footer { max-width: 1400px; margin: 3rem auto 0; padding: 1.5rem 3rem 3rem; border-top: 1px solid var(--border); text-align: center; font-size: 0.78rem; color: var(--text-light); } |
156 | 163 |
|
@@ -353,6 +360,10 @@ <h2>${sec.title}</h2> |
353 | 360 | <div class="about-sidebar-label">Interests</div> |
354 | 361 | <div class="about-sidebar-item">${D.about.interests}</div> |
355 | 362 | </div> |
| 363 | + <div class="visitor-counter"> |
| 364 | + <div class="about-sidebar-label">👋</div> |
| 365 | + <div class="visitor-count-text loading" id="visitor-count">counting...</div> |
| 366 | + </div> |
356 | 367 | </div> |
357 | 368 | </div>`; |
358 | 369 |
|
@@ -439,6 +450,39 @@ <h2>${sec.title}</h2> |
439 | 450 | overview.classList.add('has-active'); |
440 | 451 | activeDrawer = index; |
441 | 452 | } |
| 453 | + |
| 454 | +// ── Visitor counter (GoatCounter) ── |
| 455 | +// Replace YOURSITE with your GoatCounter site code after signup at https://www.goatcounter.com |
| 456 | +const GC_SITE = 'adityaputatunda'; // e.g. 'aditya-putatunda' |
| 457 | + |
| 458 | +function ordinal(n) { |
| 459 | + const s = ['th','st','nd','rd']; |
| 460 | + const v = n % 100; |
| 461 | + return n.toLocaleString() + (s[(v - 20) % 10] || s[v] || s[0]); |
| 462 | +} |
| 463 | + |
| 464 | +function fetchVisitorCount() { |
| 465 | + const el = document.getElementById('visitor-count'); |
| 466 | + if (!el) return; |
| 467 | + fetch(`https://${GC_SITE}.goatcounter.com/counter/${encodeURIComponent('/')}.json`) |
| 468 | + .then(r => r.json()) |
| 469 | + .then(data => { |
| 470 | + const count = parseInt(data.count_unique || data.count, 10); |
| 471 | + if (isNaN(count)) throw new Error('bad count'); |
| 472 | + el.textContent = `You're the ${ordinal(count)} visitor. Thanks for stopping by.`; |
| 473 | + el.classList.remove('loading'); |
| 474 | + }) |
| 475 | + .catch(() => { |
| 476 | + el.textContent = 'Counter not yet configured.'; |
| 477 | + }); |
| 478 | +} |
| 479 | + |
| 480 | +// Fetch on load + when About tab is shown |
| 481 | +fetchVisitorCount(); |
442 | 482 | </script> |
| 483 | + |
| 484 | +<!-- GoatCounter tracking — replace YOURSITE --> |
| 485 | +<script data-goatcounter="https://adityaputatunda.goatcounter.com/count" |
| 486 | + async src="//gc.zgo.at/count.js"></script> |
443 | 487 | </body> |
444 | 488 | </html> |
0 commit comments