prime8dev

prime8dev
git clone https://git.prime8.dev/prime8dev.git
Log | Files | Refs | README | LICENSE

commit fb30598c33df76ef8127530eaaab5a2bc22aec19
parent 8dd71ece75be32545e418126a4252d3298e90a61
Author: Damian Myrda <damian@prime8.dev>
Date:   Sat, 17 Jan 2026 00:01:38 -0600

Update content

Diffstat:
Mweb/blogs/building-my-portfolio.md | 11++++-------
Mweb/config/about.json | 2+-
Mweb/src/components/pages/Experience.astro | 9+++++++--
Mweb/src/scripts/ui/state.ts | 24+++++++++++++++++++++---
4 files changed, 33 insertions(+), 13 deletions(-)

diff --git a/web/blogs/building-my-portfolio.md b/web/blogs/building-my-portfolio.md @@ -11,13 +11,11 @@ tags: - Portfolio --- -I've always been drawn to terminal interfaces. There's something satisfying about the simplicity and efficiency of a well-designed TUI. So when it came time to build my portfolio, I knew I wanted to capture that aesthetic—monospace fonts, keyboard navigation, and a dark color scheme that feels like home. +I've always been drawn to terminal interfaces. There's something satisfying about the simplicity and efficiency of a well-designed TUI. So when it came time to build my portfolio, I knew I wanted to capture that aesthetic. Keyboard navigation and dark color scheme that feels like home. ## The Stack -This site is built with **Astro** for server-side rendering. At build/request time, READMEs are fetched directly from my GitLab and GitHub repositories—no CORS issues, no stale content. The markdown is parsed with **marked** and rendered with custom styling to match the terminal aesthetic. - -**WakaTime integration** pulls my coding stats in real-time, showing weekly activity breakdowns and total hours coded. It's a nice way to show I'm actually writing code, not just talking about it. +This site is built with **Astro** for server-side rendering. At build/request time, READMEs are fetched directly from my GitLab and GitHub repositories: no stale content. **Wakatime integration** pulls my coding stats in real-time, showing weekly activity breakdowns and total hours coded. It's a nice way to show I'm actually writing code, not just talking about it. ## Design Decisions @@ -26,7 +24,6 @@ A few key choices drove the design: - **Keyboard-first navigation** – Number keys (`1-4`) switch tabs instantly. Arrow keys navigate lists and timelines. `Tab` cycles through sections. `Enter` opens blog posts, `Escape` closes them. It feels like using a real terminal application. - **List-detail pattern** – Projects and experience use a sidebar list with detail views, similar to email clients or file managers. The experience page features a timeline visualization that's navigable with arrow keys. - **Live data everywhere** – WakaTime stats update on every page load. Project READMEs are fetched fresh from git repositories. No static snapshots that go stale. -- **Lightbox for images** – Experience photos open in a full-screen lightbox with keyboard navigation (arrow keys to cycle, escape to close). ## The Color Palette @@ -38,11 +35,11 @@ The palette is inspired by classic terminal emulators: - Links: `#5fafff` (light blue) - Cyan, magenta, red for semantic colors -JetBrains Mono is the font throughout—it's readable and has great character distinction. +JetBrains Mono is the font throughout. It's readable and has great character distinction. ## Conclusion -Building this portfolio was a chance to combine two things I love: terminal aesthetics and modern web development. The result is something that feels personal—a site that reflects how I actually work, not just what I've worked on. +Building this portfolio was a chance to combine two things I love: terminal aesthetics and modern web development. The result is something that feels personal: a site that reflects how I actually work, not just what I've worked on. If you're thinking about building your own portfolio, my advice is simple: make it yours. Pick a style that resonates with you, add the features you'd actually want to use, and don't be afraid to over-engineer the parts you find interesting. That's where the best learning happens. diff --git a/web/config/about.json b/web/config/about.json @@ -1,7 +1,7 @@ { "name": "Damian Myrda", "handle": "moncheeta", - "bio": "Passionate about low-level systems programming, TUI/CLI tooling, and UNIX philosophy", + "bio": "Passionate about low-level systems programming, TUI/CLI tooling, and UNIX philosophy. Always learning like Curious George 🐒", "location": "Chicago, IL", "profession": "Software Engineer", "profession_short": "SWE", diff --git a/web/src/components/pages/Experience.astro b/web/src/components/pages/Experience.astro @@ -1,6 +1,7 @@ --- import rawExperience from "../../../config/experience.json"; import type Experience from "../../lib/types/experience"; +import currentJob from "../../lib/utils/job"; import { MONTH_NAMES } from "../../constants/calendar"; import { calculateMonths } from "../../lib/utils/period"; import { getTagClass } from "../../lib/utils/tags"; @@ -9,6 +10,10 @@ const experience = (rawExperience as Experience[]).sort((a, b) => a.startDate.localeCompare(b.startDate), ); +const currentRoleIndex = currentJob + ? experience.findIndex((exp) => exp.id === currentJob.id) + : 0; + const dates = experience.map((exp) => { const [year, month] = exp.startDate.split("-").map(Number); return new Date(year, month - 1, 1); @@ -88,7 +93,7 @@ while (current <= timelineEnd) { return ( <div - class={`timeline-segment ${originalIndex === 0 ? "selected" : ""}`} + class={`timeline-segment ${originalIndex === currentRoleIndex ? "selected" : ""}`} style={`left: ${leftPercent}%; width: ${widthPercent}%;`} data-index={originalIndex} data-id={exp.id} @@ -120,7 +125,7 @@ while (current <= timelineEnd) { return ( <div - class={`exp-card ${index !== 0 ? "hidden" : ""}`} + class={`exp-card ${index !== currentRoleIndex ? "hidden" : ""}`} data-for={index} > <div class="exp-card-header"> diff --git a/web/src/scripts/ui/state.ts b/web/src/scripts/ui/state.ts @@ -2,10 +2,11 @@ import { openBlogPost } from "./blog"; import { updateDetailView, updateExperienceDetail } from "./detail"; export let currentTab = "about"; + export const selectedIndex: Record<string, number> = { - experience: 0, - projects: 0, - blog: 0, + experience: getInitialExperienceIndex(), + projects: getInitialProjectsIndex(), + blog: getInitialBlogIndex(), }; export let currentBlogId: string | null = null; @@ -55,6 +56,23 @@ export function setCurrentTab(tab: string): void { currentTab = tab; } +function getInitialExperienceIndex(): number { + const selected = document.querySelector( + "#experience .timeline-segment.selected", + ); + return selected ? parseInt(selected.getAttribute("data-index") || "0") : 0; +} + +function getInitialProjectsIndex(): number { + const selected = document.querySelector("#projects .list-item.selected"); + return selected ? parseInt(selected.getAttribute("data-index") || "0") : 0; +} + +function getInitialBlogIndex(): number { + const selected = document.querySelector("#blog .blog-list-item.selected"); + return selected ? parseInt(selected.getAttribute("data-index") || "0") : 0; +} + export function setCurrentBlogId(id: string | null): void { currentBlogId = id; }