From 3e59763afd7bd6127d2abc7386eee9c89d563b19 Mon Sep 17 00:00:00 2001 From: Nathan Arthur Date: Mon, 17 Aug 2026 18:38:58 -0500 Subject: [PATCH 01/12] feat: rebuild site as a typographic, dark-only verification surface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The site's job is verification, not discovery: nearly everyone who lands here already has a reason to look Nathan up. Rebuild the home page for a 30-second skim by that reader. - Home page: positioning line, three featured projects with role/stack/ years, then a one-line "also built" tail. Newsletter moves to the footer. - Typographic layout — hairline rules and type scale, no cards, no shadows. - Dark only. Six color tokens in tailwind.config.js; every dark:/light variant pair is gone. The site already rendered dark-locked, so the light variants were dead code and knowledge.md documented a toggle that never existed. - Mono is the system stack, not a webfont. - Delete the GitHub stats section and its whole pipeline: fetch script, OAuth device flow, data/github-stats.json, services/github/. - Delete the project search, the back-to-top button, the list transitions, the hover lifts, and the per-project icons. - Drop deps: @iconify/svelte, iconify, @octokit/*, tsx, dotenv, open, and the three unused Tailwind plugins. - /uses and /audioverse inherit the new tokens; Nav is replaced by a back link on each. - Rewrite knowledge.md and WARP.md, which described a light/dark toggle and a GitHub pipeline that no longer exist. Co-Authored-By: Claude Opus 5 (1M context) --- .env-sample | 1 - .prettierignore | 3 - WARP.md | 267 +- data/.gitignore | 5 - data/github-stats.json | 11637 -------------------------- knowledge.md | 132 +- package.json | 14 +- pnpm-lock.yaml | 502 +- scripts/fetch-github-stats.ts | 101 - scripts/tsconfig.json | 14 - src/app.html | 5 +- src/components/Footer.svelte | 38 + src/components/GithubStats.svelte | 71 - src/components/Nav.svelte | 24 - src/components/ProjectList.svelte | 234 - src/components/SubscribeForm.svelte | 18 - src/routes/+layout.svelte | 32 +- src/routes/+page.svelte | 151 +- src/routes/audioverse/+page.svelte | 97 +- src/routes/uses/+page.svelte | 224 +- src/services/github/api.ts | 43 - src/services/github/colors.ts | 22 - src/services/github/types.ts | 29 - src/types/github-stats.d.ts | 6 - tailwind.config.js | 24 +- vite.config.ts | 5 - 26 files changed, 529 insertions(+), 13170 deletions(-) delete mode 100644 .env-sample delete mode 100644 data/.gitignore delete mode 100644 data/github-stats.json delete mode 100644 scripts/fetch-github-stats.ts delete mode 100644 scripts/tsconfig.json create mode 100644 src/components/Footer.svelte delete mode 100644 src/components/GithubStats.svelte delete mode 100644 src/components/Nav.svelte delete mode 100644 src/components/ProjectList.svelte delete mode 100644 src/components/SubscribeForm.svelte delete mode 100644 src/services/github/api.ts delete mode 100644 src/services/github/colors.ts delete mode 100644 src/services/github/types.ts delete mode 100644 src/types/github-stats.d.ts diff --git a/.env-sample b/.env-sample deleted file mode 100644 index 2004362..0000000 --- a/.env-sample +++ /dev/null @@ -1 +0,0 @@ -GITHUB_OAUTH_CLIENT_ID=your-client-id \ No newline at end of file diff --git a/.prettierignore b/.prettierignore index 5df8b82..ab78a95 100644 --- a/.prettierignore +++ b/.prettierignore @@ -2,6 +2,3 @@ package-lock.json pnpm-lock.yaml yarn.lock - -# Generated data -data/github-stats.json diff --git a/WARP.md b/WARP.md index 1a4af06..157c587 100644 --- a/WARP.md +++ b/WARP.md @@ -4,239 +4,100 @@ This file provides guidance to WARP (warp.dev) when working with code in this re ## Overview -Nathan Arthur's personal website built with SvelteKit as a static site generator. Features dynamic GitHub statistics integration, project showcase, and responsive design with Tailwind CSS. +Nathan Arthur's personal website: a small static SvelteKit site — a home page, a +`/uses` page, and one case study — deployed to Cloudflare Workers static assets +at nathanarthur.com. See `knowledge.md` for the design and content rules; they +are load-bearing, not decoration. ## Development Commands -### Core Development - ```bash -# Install dependencies (project uses pnpm) -pnpm install - -# Start development server (avoid in WARP to prevent blocking) -pnpm dev - -# Build static site -pnpm build - -# Preview production build locally -pnpm preview - -# Type checking -pnpm check - -# Watch mode type checking +pnpm install # project uses pnpm +pnpm dev # dev server (avoid in WARP to prevent blocking) +pnpm build # static build into ./build +pnpm preview # preview the production build +pnpm check # svelte-check pnpm check:watch +pnpm test # vitest, single run +pnpm lint # prettier --check + eslint +pnpm format # prettier --write ``` -### Testing & Quality - -```bash -# Run tests (use --run to avoid watch mode in WARP) -pnpm test - -# Run Vitest directly with no-watch -pnpm vitest --run - -# Lint code (ESLint + Prettier) -pnpm lint - -# Format code -pnpm format -``` - -### GitHub Statistics Integration - -```bash -# Install dependencies for GitHub stats fetching -pnpm prefetch-github - -# Fetch GitHub stats (requires GITHUB_OAUTH_CLIENT_ID in .env) -pnpm fetch-github -``` - -## High-Level Architecture - -### Static Site Generation - -- **SvelteKit** with `@sveltejs/adapter-static` for GitHub Pages deployment -- **Pre-rendering** enabled via `export const prerender = true` in root layout -- **Build-time data fetching** using static JSON files rather than runtime API calls - -### GitHub Integration Flow +## Architecture -1. **OAuth Device Flow**: `scripts/fetch-github-stats.ts` handles authentication -2. **Data Fetching**: Pulls user profile, repositories, and language statistics -3. **Static Generation**: Data stored in `data/github-stats.json` for build-time consumption -4. **Display**: `src/services/github/api.ts` processes static data for components +### Static site generation -### Technology Stack +- **SvelteKit 5** with `@sveltejs/adapter-static` +- Pre-rendering enabled via `export const prerender = true` in `src/routes/+layout.ts` +- No runtime data fetching except `/uses`, which loads `static/data/uses.yaml` + in the browser on mount -- **SvelteKit 5** for framework and routing -- **TypeScript** for type safety throughout -- **Tailwind CSS** with plugins for forms, typography, container queries -- **Vite** for build tooling and dev server -- **Vitest** for unit testing -- **ESLint + Prettier** for code quality +### Technology stack -## Project Structure +- SvelteKit 5, TypeScript, Tailwind CSS (no plugins), Vite, Vitest, ESLint + Prettier -### Key Directories +### Project structure ``` src/ -├── routes/ # SvelteKit file-based routing -│ ├── +layout.svelte # Root layout with dark mode support -│ ├── +layout.ts # Layout load function (prerender: true) -│ ├── +page.svelte # Home page with project showcase -│ └── uses/ # "/uses" page route -├── components/ # Reusable Svelte components -│ ├── GithubStats.svelte # GitHub statistics display -│ ├── ProjectList.svelte # Searchable project showcase -│ └── SubscribeForm.svelte -├── services/ # Business logic layer -│ └── github/ # GitHub API integration -│ ├── api.ts # Data processing from static JSON -│ ├── types.ts # TypeScript interfaces -│ └── colors.ts # Language color mapping -└── types/ # Global type definitions -``` - -### Data Flow - -1. **Build Time**: Static JSON (`data/github-stats.json`) consumed by services layer -2. **Component Layer**: `GithubStats.svelte` calls `fetchGithubStats()` from `services/github/api.ts` -3. **Data Processing**: API service calculates statistics and language percentages -4. **Rendering**: Components receive processed data for display - -## GitHub Statistics System - -### Authentication Setup - -1. Create GitHub OAuth app and get client ID -2. Copy `.env-sample` to `.env` and set `GITHUB_OAUTH_CLIENT_ID` -3. Run `pnpm prefetch-github` to install required dependencies - -### Data Fetching Process - -```bash -# Authenticate via OAuth device flow (opens browser) -pnpm fetch-github -``` - -The script: - -1. Initiates OAuth device flow authentication -2. Fetches user profile data for 'narthur' -3. Retrieves all public repositories (up to 100) -4. Collects language statistics for each repository -5. Saves complete dataset to `data/github-stats.json` - -### Data Processing - -- **Stars**: Aggregated across all repositories -- **Languages**: Byte counts summed and converted to percentages -- **Top Languages**: Shows top 5, with remainder grouped as "Other" -- **Caching**: No runtime caching needed - data is static at build time - -## Development Patterns - -### SvelteKit Conventions - -- **File Routes**: `+page.svelte` for pages, `+layout.svelte` for layouts -- **Load Functions**: `+layout.ts` with `prerender: true` for static generation -- **Component Naming**: PascalCase for `.svelte` components - -### TypeScript Guidelines - -- Avoid `any` type, prefer `unknown` or specific types -- Interface definitions in `src/types/` and `src/services/*/types.ts` -- Acceptable `any` usage in test files only - -### Styling Approach - -- **Tailwind First**: Use utility classes directly in markup -- **Avoid @apply**: Don't use `@apply` directives in Svelte ` diff --git a/src/components/GithubStats.svelte b/src/components/GithubStats.svelte deleted file mode 100644 index ffacdaa..0000000 --- a/src/components/GithubStats.svelte +++ /dev/null @@ -1,71 +0,0 @@ - - -
-

- GitHub Stats -

-
- - - {#if Object.keys(githubStats.languages).length > 0} -
-
- {#each Object.entries(githubStats.languages) as [lang, percentage]} -
- {/each} -
-
- {#each Object.entries(githubStats.languages) as [lang, percentage]} -
-
- {lang} {percentage.toFixed(1)}% -
- {/each} -
-
- {/if} -
-
diff --git a/src/components/Nav.svelte b/src/components/Nav.svelte deleted file mode 100644 index ff6cd38..0000000 --- a/src/components/Nav.svelte +++ /dev/null @@ -1,24 +0,0 @@ - - - diff --git a/src/components/ProjectList.svelte b/src/components/ProjectList.svelte deleted file mode 100644 index 2568d6c..0000000 --- a/src/components/ProjectList.svelte +++ /dev/null @@ -1,234 +0,0 @@ - - - - -
-

- Things I've Built -

-
-
- - -
-
- -
diff --git a/src/components/SubscribeForm.svelte b/src/components/SubscribeForm.svelte deleted file mode 100644 index 0cd037c..0000000 --- a/src/components/SubscribeForm.svelte +++ /dev/null @@ -1,18 +0,0 @@ -
-

- Subscribe to My Newsletter -

-

- Sign up to receive mostly-weekly productivity tips and tools, AI news, and the random thoughts - of a self-employed web developer with ADHD. -

-
-
diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index 5b9b4b8..1af28c0 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -2,29 +2,35 @@ import '../app.css'; import '@fontsource/instrument-sans/400.css'; // Regular import '@fontsource/instrument-sans/500.css'; // Medium - import '@fontsource/instrument-sans/700.css'; // Bold - import Nav from '../components/Nav.svelte'; + import Footer from '../components/Footer.svelte'; let { children } = $props(); -
-