Add hit counter service and expand frontend content sections
- New hit-counter FastAPI service (Prometheus metrics, SQLite storage), wired into Caddy (hits.carloselugo.com) and docker-compose - Scrape hit-counter in Prometheus every 5m - Add articles, about, contact, experience, and expertise sections to the frontend, with per-article hit tracking Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
export function renderAbout() {
|
||||
return `
|
||||
<hr class="hr" />
|
||||
<section class="about" id="about">
|
||||
<div class="container about-inner">
|
||||
<div class="about-photo reveal" id="about-photo">
|
||||
<img src="/images/profile_rev2.png" alt="Carlos Lugo" onerror="this.parentElement.classList.add('about-photo--empty'); this.remove();" />
|
||||
</div>
|
||||
<div class="about-copy reveal">
|
||||
<span class="section-kicker">About</span>
|
||||
<h2 class="about-title">From the field to the dashboard.</h2>
|
||||
<p class="about-p">
|
||||
I'm Carlos Lugo, based in Puerto Rico. My career started operating ISP, MAN, and MPLS networks
|
||||
on the ground, and over two decades it's grown into leading capacity planning, technology
|
||||
architecture, and now network intelligence for one of the region's largest operators.
|
||||
</p>
|
||||
<p class="about-p">
|
||||
Today I build the analytics platforms and AI-driven models that guide infrastructure decisions
|
||||
at scale — and I take on select consulting engagements for teams who need that same translation
|
||||
from telemetry to strategy.
|
||||
</p>
|
||||
<div class="about-tags">
|
||||
<span class="tag tag-neutral">Cisco IOS-XR</span>
|
||||
<span class="tag tag-neutral">Juniper JunOS</span>
|
||||
<span class="tag tag-neutral">Kafka / ClickHouse</span>
|
||||
<span class="tag tag-neutral">Python / Flask</span>
|
||||
<span class="tag tag-neutral">Fortigate / Palo Alto</span>
|
||||
</div>
|
||||
<p class="about-meta">
|
||||
A.S. Instrumentation Technology, UPR Bayamón · Former Cisco CCNP · Spanish (native), English (professional)
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<hr class="hr" />
|
||||
|
||||
<style>
|
||||
.about { padding: 64px 0; }
|
||||
.about-inner {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
|
||||
gap: 48px;
|
||||
align-items: center;
|
||||
}
|
||||
.about-photo {
|
||||
width: 100%;
|
||||
max-width: 340px;
|
||||
aspect-ratio: 1 / 1;
|
||||
border-radius: 50%;
|
||||
overflow: hidden;
|
||||
background: var(--bg-card);
|
||||
}
|
||||
.about-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
|
||||
.about-photo--empty {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: 2px dashed var(--border-strong);
|
||||
}
|
||||
.about-photo--empty::after {
|
||||
content: 'CL';
|
||||
font-family: var(--font-sans);
|
||||
font-weight: 800;
|
||||
font-size: 3rem;
|
||||
color: var(--accent);
|
||||
}
|
||||
.about-title { font-size: 2rem; margin-bottom: 20px; }
|
||||
.about-p { font-size: 1rem; line-height: 1.7; color: var(--muted-2); max-width: 56ch; margin-bottom: 16px; }
|
||||
.about-tags { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 24px; }
|
||||
.about-meta { font-size: 0.8rem; color: var(--muted); margin-top: 24px; }
|
||||
@media (max-width: 780px) {
|
||||
.about-inner { grid-template-columns: 1fr; }
|
||||
.about-photo { max-width: 220px; margin: 0 auto; }
|
||||
}
|
||||
</style>
|
||||
`
|
||||
}
|
||||
Reference in New Issue
Block a user