From c36cc944378ab8dcd920f487e7c9b1ac799e0dc6 Mon Sep 17 00:00:00 2001 From: lerko96 Date: Thu, 16 Apr 2026 18:03:33 -0400 Subject: [PATCH] feat(ui): add timeline component; complete terminal-noir design system MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - introduce Timeline component with scroll-in animation and type-colored spine dots (career/edu/cert/project/homelab) - swap terminal-noir palette for macOS Classic dark/light with matching timeline color tokens in globals.css - add light mode overrides, cursor blink keyframe, font-size 14px base - update Widget header: prefix/name split, bracket badge, no divider rule - align archive and homelab page headers to ❯ prompt style - convert all font-sans prose in homelab/archive to font-mono - rename widget titles to namespaced paths (homelab/network, etc.) - skills label: uppercase tracking → plain text-sm; remove row borders --- src/app/archive/page.tsx | 19 ++++------ src/app/globals.css | 53 +++++++++++++++++++++------ src/app/homelab/page.tsx | 41 ++++++++++----------- src/components/Skills.tsx | 10 +++--- src/components/Widget.tsx | 24 ++++++------- src/data/timeline.ts | 75 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 158 insertions(+), 64 deletions(-) create mode 100644 src/data/timeline.ts diff --git a/src/app/archive/page.tsx b/src/app/archive/page.tsx index 13e5848b..0692efde 100644 --- a/src/app/archive/page.tsx +++ b/src/app/archive/page.tsx @@ -11,22 +11,17 @@ export default function ArchivePage() { return ( <>
-
- - archive - - -

- Earlier Work -

-

+

+ + tyler/projects/archive +

+

Experiments, browser extensions, and bootcamp projects. Kept here for context — not representative of current work.

- +
{archiveProjects.map((project) => (
-

+

{project.description}

diff --git a/src/app/globals.css b/src/app/globals.css index ad6ef9a6..f0c7b66f 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -3,17 +3,24 @@ @variant dark (&:where(.dark, .dark *)); @theme { - /* Terminal-Noir palette */ - --color-bg: #0a0a0a; - --color-surface: #111111; - --color-surface-raised: #1a1a1a; - --color-border: #2a2a2a; - --color-border-bright: #444444; - --color-text: #e8e8e8; - --color-text-label: #666666; - --color-text-dim: #444444; - --color-accent-green: #00cc44; - --color-accent-red: #cc2200; + /* macOS Classic Dark (default) */ + --color-bg: #131313; + --color-surface: #1e1d1e; + --color-surface-raised: #272727; + --color-border: #3a3a3a; + --color-border-bright: #404040; + --color-text: #caccca; + --color-text-label: #9e9e9e; + --color-text-dim: #8f8f8f; + --color-accent-green: #62ba46; + --color-accent-red: #c74028; + + /* Timeline type colors — dark */ + --color-timeline-career: #62ba46; + --color-timeline-education: #c28b12; + --color-timeline-cert: #c75828; + --color-timeline-project: #c72855; + --color-timeline-homelab: #e1d797; /* Typography */ --font-mono: "Source Code Pro", ui-monospace, monospace; @@ -34,11 +41,15 @@ /* Base */ html { scroll-behavior: smooth; + font-size: 14px; background-color: var(--color-bg); color: var(--color-text); font-family: var(--font-mono); } +@keyframes blink { 50% { opacity: 0; } } +.animate-cursor { animation: blink 1s step-start infinite; } + @layer base { * { box-sizing: border-box; @@ -47,6 +58,26 @@ html { } } +/* macOS Classic Light overrides */ +:root:not(.dark) { + --color-bg: #ffffff; + --color-surface: #f9f9f9; + --color-surface-raised: #f7f7f7; + --color-border: #e0e0e0; + --color-border-bright: #d2d2d2; + --color-text: #000000; + --color-text-label: #505050; + --color-text-dim: #929292; + --color-accent-green: #036a07; + --color-accent-red: #d21f07; + + --color-timeline-career: #036a07; + --color-timeline-education: #0433ff; + --color-timeline-cert: #957931; + --color-timeline-project: #6f42c1; + --color-timeline-homelab: #0000a2; +} + /* Default transitions — linear, fast */ a, button { diff --git a/src/app/homelab/page.tsx b/src/app/homelab/page.tsx index a9fc0443..beb3e0ea 100644 --- a/src/app/homelab/page.tsx +++ b/src/app/homelab/page.tsx @@ -81,16 +81,11 @@ export default function HomelabPage() { <> {/* Header */}
-
- - lerkolabs - - -

- Home Infrastructure Lab -

-

+

+ + homelab +

+

Personal infrastructure environment for learning, self-hosting, and operational practice. Running 24/7 on production-grade hardware with real network segmentation, SSO, monitoring, and IaC-style documentation. @@ -98,7 +93,7 @@ export default function HomelabPage() {

{/* At a Glance */} - +
{glanceStats.map(({ label, value }) => (
@@ -151,7 +146,7 @@ export default function HomelabPage() { {v.subnet} - {v.purpose} + {v.purpose} ))} @@ -161,7 +156,7 @@ export default function HomelabPage() { {/* Services */} @@ -187,7 +182,7 @@ export default function HomelabPage() {

{svc.name}

-

+

{svc.description}

@@ -202,7 +197,7 @@ export default function HomelabPage() { {/* ADRs */}

{adr.title}

-

+

decision: {adr.decision}

-

+

why: {adr.why}

@@ -228,16 +223,16 @@ export default function HomelabPage() {
{/* GitHub CTA */} -
-

lerkolabs on GitHub

-

- Full documentation: VLAN maps, runbooks, service registry, config exports, and setup guides. +

+

homelab/docs → github.com/lerko96/homelab-wip

+

+ VLAN maps, runbooks, service registry, config exports, and setup guides.

↗ github.com/lerko96/homelab-wip diff --git a/src/components/Skills.tsx b/src/components/Skills.tsx index 6e535d4a..02cf6b25 100644 --- a/src/components/Skills.tsx +++ b/src/components/Skills.tsx @@ -27,16 +27,14 @@ const totalCount = skillGroups.reduce((n, g) => n + g.skills.length, 0); export default function Skills() { return ( - +
- {skillGroups.map(({ label, skills }, i) => ( + {skillGroups.map(({ label, skills }) => (
- + {label} diff --git a/src/components/Widget.tsx b/src/components/Widget.tsx index 6ec63db8..2a2faf6f 100644 --- a/src/components/Widget.tsx +++ b/src/components/Widget.tsx @@ -15,22 +15,22 @@ export default function Widget({ className, children, }: WidgetProps) { + const slashIdx = title.lastIndexOf("/"); + const prefix = slashIdx >= 0 ? title.slice(0, slashIdx + 1) : null; + const name = slashIdx >= 0 ? title.slice(slashIdx + 1) : title; + return ( -
- - {title} - - {meta && ( - - {meta} - +
+ {prefix && ( + {prefix} )} - {children} diff --git a/src/data/timeline.ts b/src/data/timeline.ts new file mode 100644 index 00000000..36717525 --- /dev/null +++ b/src/data/timeline.ts @@ -0,0 +1,75 @@ +export type TimelineType = 'career' | 'cert' | 'project' | 'homelab' | 'education' + +export interface TimelineEntry { + date: string + title: string + type: TimelineType + description: string + tags?: string[] +} + +export const timeline: TimelineEntry[] = [ + { + date: '2026', + title: 'CompTIA Network+ — in progress', + type: 'cert', + description: 'Studying for Network+ to formalize networking knowledge built through the homelab.', + tags: ['networking', 'certification'], + }, + { + date: '2025', + title: 'Portfolio Site v2', + type: 'project', + description: 'Next.js 16 static site, self-hosted in a DMZ LXC behind Nginx, deployed via Gitea Actions CI.', + tags: ['next.js', 'tailwind', 'self-hosted'], + }, + { + date: '2024', + title: 'CompTIA A+', + type: 'cert', + description: 'Earned A+ certification, formalizing hardware and OS fundamentals.', + tags: ['certification'], + }, + { + date: '2024', + title: 'Project Helm', + type: 'project', + description: 'Full-stack task and project management tool built in Go + React.', + tags: ['go', 'react', 'typescript'], + }, + { + date: 'ongoing', + title: 'Homelab — Proxmox Cluster', + type: 'homelab', + description: '8-VLAN segmented network, Proxmox VMs/LXCs, SSO via Authentik, full monitoring stack (Grafana + Prometheus + Loki).', + tags: ['proxmox', 'networking', 'monitoring', 'sso'], + }, + { + date: '2023-10', + title: 'SOC Analyst I — Fortress SRM', + type: 'career', + description: 'Threat monitoring, incident triage, and client-facing security operations in a managed SOC.', + tags: ['soc', 'security'], + }, + { + date: '2023-03', + title: 'Config Tech II — MCPc', + type: 'career', + description: 'Promoted to Config Tech II. Led imaging workflows and expanded into scripting for endpoint provisioning.', + tags: ['sysadmin', 'scripting'], + }, + { + date: '2022-07', + title: 'Config Tech I — MCPc', + type: 'career', + description: 'Hardware configuration, OS imaging, and deployment at scale for enterprise clients.', + tags: ['sysadmin', 'hardware'], + }, + { + date: '2021', + title: 'We Can Code IT — Java Bootcamp', + type: 'education', + description: '9-month intensive bootcamp covering Java, OOP, SQL, REST APIs, and Agile development practices.', + tags: ['java', 'sql', 'agile'], + }, +]