A personal portfolio website for a professional programmer. The site serves as a marketing tool to showcase skills, projects, and experience to potential employers, clients, and collaborators.
This project was built collaboratively with Claude Code (Anthropic's CLI agent). Below is a record of how the spec and scaffold came together.
The spec was generated through a conversational brainstorm. The process went roughly like this:
- User prompt: "I'm working on putting together a personal site and would like some assistance writing a spec sheet. What do you think would belong in a personal website? I'm a programmer by trade and looking to market myself."
- Claude proposed a structure — 4 core pages (Home, About, Projects, Contact) plus optional additions (Blog, Testimonials, Open Source contributions), along with technical considerations (responsive design, performance, SEO, accessibility, analytics).
- User made selections: Include all 6 pages (the 4 core plus Blog and Testimonials). All technical considerations looked good.
- Claude wrote the full spec into
README.md, deliberately leaving two sections open-ended: Tech Stack and Design Direction. - User filled in the blanks:
- Framework: SvelteKit (Svelte 5) — chosen specifically because the user had never used it and wanted to learn it.
- Design direction: "iOS 26 Liquid Glass" — Claude then elaborated this into a detailed design spec covering color palette, typography, navigation, component styling, and motion.
- User requested a
CLAUDE.mdto orient future sessions on the project's context, learning goals, coding conventions, and expected structure. - Both files were committed and pushed to main.
With the spec and CLAUDE.md in place, a second session handled the full scaffold:
- Plan mode: Claude read the spec and
CLAUDE.md, explored the empty repo, and produced a step-by-step implementation plan. The user reviewed and approved it. - Node.js upgrade: The
svCLI required Node 20+. Upgraded from Node 18 to Node 22 vianvm. - SvelteKit scaffold: Ran
npx sv createwith the minimal TypeScript template. - Dependencies: Installed
mdsvex,shiki,tailwindcss,@tailwindcss/vite, and@tailwindcss/typography. - Build tool config:
svelte.config.js— Added mdsvex preprocessor with a Shiki highlighter (github-dark theme), registered.mdas a page extension.vite.config.ts— Added the Tailwind CSS Vite plugin.
- Liquid Glass design system (
app.css): Defined custom design tokens via Tailwind's@themedirective (glass colors, blur values, border radii, shadows), a gradient mesh body background, and 6 reusable glass utility classes (.glass,.glass-medium,.glass-heavy,.glass-nav,.glass-button,.glass-input). - TypeScript types and data: Created interfaces for Project, Testimonial, Skill, BlogPost, and SiteConfig. Wrote placeholder data files for projects, testimonials, skills, and site constants.
- Shared components: Built
Nav.svelte(floating glass nav with mobile hamburger using$state/$derivedrunes),Footer.svelte, andGlassCard.svelte(reusable glass panel accepting Snippet children). - All 6 page routes: Home (hero + featured projects + skills), About (bio + quick info + tech stack), Projects (filterable grid with
$state/$derived), Blog listing (import.meta.globto load all posts), Blog[slug](dynamic post page), Testimonials (quote cards), Contact (form + info + availability). - Blog infrastructure: Load functions using
import.meta.globfor the listing and dynamicimport()for individual slugs. An examplehello-world.mdpost with frontmatter metadata and code blocks in Svelte, TypeScript, and CSS. - Verification: Dev server started clean, all 7 routes returned HTTP 200, Shiki syntax highlighting confirmed in blog HTML,
npm run checkpassed with 0 errors/0 warnings,npm run buildsucceeded. - Committed and pushed to main.
With the scaffold functional, a third session focused on design polish and SEO infrastructure:
- Plan mode: Claude reviewed all existing pages and components, then produced a 7-step implementation plan covering page transitions, responsive scaling, favicon, and Open Graph meta tags. The user approved it.
- Types & site config: Added
urlandogImagefields to theSiteConfiginterface and populated them insite.ts(GitHub Pages URL, placeholder OG image path). - Favicon: Created a hand-coded SVG favicon matching the glass aesthetic — a dark gradient squircle with
</>code brackets in accent blue. Removed the unused default Svelte logo fromsrc/lib/assets/. Added<meta name="theme-color">and favicon<link>toapp.html. - SEO component (
SEO.svelte): Built a reusable component rendering<svelte:head>with<title>,<meta description>,<link rel="canonical">, Open Graph tags (og:title,og:description,og:url,og:image,og:type,og:site_name), Twitter Card tags, and optionalarticle:published_time/article:tagfor blog posts. Props default fromsiteConfig. - All 7 pages updated: Replaced inline
<svelte:head>blocks with the<SEO>component and added mobile-first responsive Tailwind classes throughout — scaled headings (text-3xl sm:text-4xl md:text-5xl), responsive padding/margins, stacked CTA buttons on mobile (flex-col sm:flex-row), and blog card layout adjustments. - Component polish:
GlassCardgot responsive padding (p-4 sm:p-6).Navgotmax-w-[calc(100vw-2rem)]to prevent overflow on narrow viewports, plusslideandfadetransitions on the mobile dropdown with staggered link entry.Footergot responsive spacing. - Page transitions: Added
onNavigatein+layout.sveltewrapping navigation with the View Transitions API (document.startViewTransition()) with graceful fallback for unsupported browsers. Added glass dissolve keyframes inapp.css—::view-transition-old(root)fades out withblur(4px),::view-transition-new(root)fades in fromblur(4px). Also added atransitionshorthand to the.glassbase class for smooth hover behavior. - Verification:
svelte-checkpassed with 0 errors,npm run buildsucceeded with static output. - Committed and pushed to main.
- Hook fix: A
PreToolUsehook for ensuring README updates before commits was erroring on Windows due to$CLAUDE_PROJECT_DIRnot expanding. Fixed the path to use a relative path (.claude/hooks/pre-commit-readme.mjs).
- Blog posts: Wrote three example posts — "What I Learned Building My First SvelteKit Site" (SvelteKit/Svelte 5 lessons), "Agentic Coding: Lessons From Building Software With AI" (workflow best practices), and "Building Liquid Glass UI With Pure CSS" (deep dive into
backdrop-filterand the site's design system). - Shiki config fix: Added
markdownto the loaded languages list insvelte.config.jsand added a safe fallback so unknown languages default totextinstead of crashing the build. - Template literal fix: Avoided
${}template literals in code blocks within markdown posts, as Svelte's compiler interprets them as expressions during mdsvex processing. - Root path migration: Removed the
/PersonalSitebase path fromsvelte.config.jsand updatedsiteConfig.urltohttps://echoloquate.github.ioafter the repo was renamed to serve from root. - Committed and pushed to main.
- Nav hide-on-scroll: Added scroll-direction tracking to
Nav.svelteusing a$effectwith a passive scroll listener. The nav slides up off-screen when scrolling down (past 60px threshold) and reappears when scrolling up, with a 300ms CSS transition. Mobile menu auto-closes when the nav hides. - Blog post rewrites: Rewrote all four blog posts (
hello-world,agentic-coding-best-practices,liquid-glass-css,building-with-sveltekit) to sound less AI-generated — more casual voice, fewer perfectly parallel structures, more first-person asides, trimmed filler sections. - Nav scroll refinement: Added a 30px scroll-delta threshold so the nav doesn't flicker on small scroll changes. Increased
.glass-navbackground opacity (rgba(15, 15, 25, 0.6)) and blur (32px) so text doesn't bleed through the translucent panel. - Committed and pushed to main.
- Hero section with name, professional title, and a brief tagline
- Call to action buttons (e.g., "View My Work", "Get In Touch")
- Featured projects section (2-3 highlight cards pulled from the Projects page)
- Brief skills overview or tech stack icons
- Latest blog post preview
- Professional background and personal story
- Tech stack and skills broken out by category (languages, frameworks, tools, platforms)
- Career timeline or work experience highlights
- Soft skills and working style
- Downloadable resume/CV (PDF link)
- Professional photo/headshot
- Filterable grid or list of projects
- Each project card includes:
- Project name and description
- Technologies used (tags)
- Screenshots or demo media
- Links to live demo and source code (GitHub)
- Your role and key contributions
- Problem solved / impact summary
- 3-6 featured projects minimum
- List of blog posts with title, date, excerpt, and tags
- Individual post pages with full content
- Category or tag filtering
- Code syntax highlighting for technical posts
- Estimated read time
- Share buttons (optional)
- Quotes from colleagues, clients, or collaborators
- Name, role, and company of the person giving the testimonial
- Photo or avatar (optional)
- Displayed as a carousel, grid, or dedicated section
- Can also be embedded as a section on the Home or About page
- Contact form (name, email, subject, message)
- Direct email link as a fallback
- Links to professional profiles:
- GitHub
- Any other relevant platforms (Twitter/X, Dev.to, Stack Overflow, etc.)
- Availability status (e.g., "Open to full-time roles", "Available for freelance")
- Location / timezone info (optional)
- Mobile-first approach
- Breakpoints for mobile, tablet, and desktop
- Touch-friendly navigation and interactions
- Fast load times (target < 2s initial load)
- Optimized images (lazy loading, modern formats like WebP)
- Minimal JavaScript bundle size
- Semantic HTML5 structure
- Meta tags (title, description, Open Graph, Twitter cards)
- Sitemap and robots.txt
- Clean URL structure
- WCAG 2.1 AA compliance
- Keyboard navigable
- Proper heading hierarchy and ARIA labels
- Sufficient color contrast
- Privacy-respecting analytics (e.g., Plausible, Umami, or Google Analytics)
- Track page views, referral sources, and visitor trends
- Framework: SvelteKit (Svelte 5) — full-stack framework with file-based routing, SSR/SSG support
- Styling: Tailwind CSS — utility-first, pairs well with Svelte's scoped styles for custom glass effects
- Blog engine: mdsvex — Markdown preprocessor for Svelte, supports Svelte components inside posts
- Syntax highlighting: Shiki (built into mdsvex) for code blocks in blog posts
- Hosting: Vercel or Netlify (both have first-class SvelteKit adapter support)
- Contact form: Formspree or SvelteKit form actions with an email API (e.g., Resend)
- Analytics: Plausible or Umami (lightweight, privacy-respecting)
- Translucent, frosted glass panels (
backdrop-filter: blur()+ semi-transparent backgrounds) - Depth and layering — floating cards and surfaces with soft, diffused shadows
- Light, airy feel with vibrant gradient backgrounds that bleed through glass layers
- Generous rounded corners on all interactive surfaces
- Subtle refraction and specular highlight effects on glass edges
- Soft, muted base tones with vibrant accent colors visible through translucent layers
- Background: fluid gradient meshes (soft blues, purples, pinks, or dynamic ambient colors)
- Glass surfaces:
rgba(255, 255, 255, 0.3–0.6)with blur overlays - Text: high-contrast against glass (dark text on light glass, white text on dark glass)
- Accents: vibrant but not harsh — pulled from the gradient background
- Clean sans-serif system font stack (SF Pro style):
Inter,system-ui, or similar - Light to medium font weights on glass surfaces
- Clear hierarchy: large bold headings, lighter body text
- Translucent floating top nav bar with glass effect
- Collapses to a glass-panel hamburger menu on mobile
- Active state indicated by a brighter glass pill or subtle glow
- Cards: frosted glass panels with soft borders and hover lift animations
- Buttons: glass-style with subtle gradient fills, hover glow effects
- Inputs: translucent fields with soft inner glow on focus
- Sections: layered glass panels at varying depths over a gradient background
- Smooth, spring-based transitions (Svelte's built-in transitions and animations)
- Subtle parallax or depth shifts on scroll
- Hover states: gentle scale, glow, or blur intensity changes
- Page transitions: crossfade or slide with glass opacity shifts