From f83a317520fc56fb0996495d12bf86a50c1da2a7 Mon Sep 17 00:00:00 2001 From: Kevin Riehl Date: Sun, 9 Aug 2026 00:42:45 -0700 Subject: [PATCH] =?UTF-8?q?content:=20audit=20phase=204=20=E2=80=94=20lead?= =?UTF-8?q?=20with=20the=20work=20that=20differentiates?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Brand/content phase. The engineering was never the weak part of this site; the copy was. Decisions on title, bio angle, download figures and node copy were the owner's — this implements them. Identity: - jobTitle was 'Software Development - Lead Associate', an internal HR grade that means nothing to a recruiter or a search engine. Now 'Lead Software Engineer' — a faithful translation, not a promotion. - aboutMe opened with "Intermediate Software Engineer", grading himself down in his own headline, and named the most generic possible stack (React/Node/SQL/ShadCN/Docker). It now leads with the work almost nobody else has done: WebRTC telehealth, real-time gesture recognition that made chat usable for speech-impaired patients, and air-gapped deployment tooling. Those were previously buried 3-4 clicks deep in leaf nodes and appeared nowhere on the surface. - Title/description/OG/Twitter copy realigned to match. JSON-LD needed no change — it already derives from the origin node. Node copy: - The five job nodes had placeholder descriptions ('Junior developer at the start of my career.', 'Where I am now.') that are the first thing a tooltip shows. Each is now a one-line hook naming the most substantial thing from that role. - Normalised highlight punctuation: only exp-job5's bullets ended in periods. Proof of work: - `downloads` existed on ProjectNode and was used by zero nodes despite two published PyPI packages. Populated with verified lifetime figures from pypistats.org (tvdbAPI 2,277, tmdbAPI 784, checked 2026-08-09) and dated in a comment. Lifetime, deliberately, not the recent rate — 27 and 12 in the last month is not a number worth advertising. - Nothing rendered the field. NodeModal now shows it beside the status badge, and SeoContent renders it too so it's crawlable. Data integrity: - edu-degree's description said "Computer Science" while its own structured fields said Applied Science / IT-Software Development. Its label was the generic "University"; now Green River College. - calculatePlayerLevel() hardcoded '2020-10-01', duplicating exp-job1.startDate — two sources for one fact, free to drift. It now derives the earliest start from the experience nodes, via an explicit "Month YYYY" parser rather than handing a bare "October 2020" to `new Date` (not a format engines are required to accept). - Added the first tests for calculatePlayerLevel, previously the only untested export in stats.ts. 14 -> 16 tests. - Fixed the 'tool-vscod' id typo. Corrections to the audit this phase acted on: the self-hosted repos at git.tehriehldeal.com ARE publicly reachable (all three return 200 anonymously) — the earlier claim that recruiters couldn't reach them was asserted without checking. All three live project sites are up too. Verified in the production build: modal shows the new title and bio, the downloads badge renders as "↓ 2,277 downloads", figures are crawlable in the prerendered HTML, and no filler copy survives. Co-Authored-By: Claude Opus 5 (1M context) --- src/app.html | 2 +- src/lib/components/NodeModal.svelte | 23 +++++++++++++++++--- src/lib/components/SeoContent.svelte | 3 +++ src/lib/data.ts | 32 +++++++++++++++++----------- src/lib/utils/stats.test.ts | 19 ++++++++++++++++- src/lib/utils/stats.ts | 28 +++++++++++++++++++++--- src/routes/+layout.svelte | 10 ++++----- 7 files changed, 91 insertions(+), 26 deletions(-) diff --git a/src/app.html b/src/app.html index 7d708d5..caa6bce 100644 --- a/src/app.html +++ b/src/app.html @@ -4,7 +4,7 @@ - Kevin Riehl — Software Engineer (React, Node.js, TypeScript) | Portfolio + Kevin Riehl — Lead Software Engineer (React, Node.js, WebRTC) | Portfolio %sveltekit.head% diff --git a/src/lib/components/NodeModal.svelte b/src/lib/components/NodeModal.svelte index ca3873d..6777124 100644 --- a/src/lib/components/NodeModal.svelte +++ b/src/lib/components/NodeModal.svelte @@ -143,10 +143,15 @@ {/if} - - {#if node.category === 'projects' && node.status} + + {#if node.category === 'projects' && (node.status || node.downloads)}
- {node.status} + {#if node.status} + {node.status} + {/if} + {#if node.downloads} + ↓ {node.downloads} + {/if}
{/if} @@ -471,6 +476,18 @@ transform: translateY(0); } + .downloads-badge { + display: inline-block; + padding: 0.2rem 0.6rem; + border: 1px solid rgba(255, 215, 0, 0.35); + border-radius: 12px; + background: rgba(255, 215, 0, 0.08); + color: var(--color-gold); + font-size: 0.75rem; + font-weight: 600; + letter-spacing: 0.02em; + } + .project-status { margin: 0.75rem 0; } diff --git a/src/lib/components/SeoContent.svelte b/src/lib/components/SeoContent.svelte index 1f2c215..3295241 100644 --- a/src/lib/components/SeoContent.svelte +++ b/src/lib/components/SeoContent.svelte @@ -79,6 +79,9 @@ {#if project.techStack?.length}

Tech: {project.techStack.join(', ')}

{/if} + {#if project.downloads} +

{project.downloads}

+ {/if}