· Raymond Arias · Frontend · 3 min read
How I Built a 100/100 Lighthouse Portfolio with Astro and Design Systems
A technical breakdown of how I achieved perfect Lighthouse scores by combining Astro's performance with a custom design system — no templates, no bloat, just intentional craft.

Most developer portfolios look the same.
They’re built on templates. They load heavy JavaScript. They have generic gradients, identical card grids, and motion that serves no purpose. And when you run Lighthouse, they score 60-70 on performance, 80 on accessibility, and maybe 90 on SEO if you’re lucky.
I decided to build mine differently.
The Problem with Template Portfolios
I’ve seen hundreds of portfolios. They all share the same DNA:
- A hero with a gradient blob
- Three equal feature cards
- A project grid with hover effects that do nothing
- A footer with social links
- And somewhere, buried in the code, 200KB of unused JavaScript
The problem isn’t that they’re ugly. The problem is that they’re lazy. They communicate “I used a template” instead of “I think about craft.”
For a Senior Product Designer & Frontend Developer, that’s not acceptable.
The Decision: Astro + Custom Design System
I chose two things deliberately:
Astro because it ships zero JavaScript by default. No hydration unless you need it. No bundle bloat. Just HTML, CSS, and the content you actually need.
A custom Design System because I refuse to let Tailwind defaults dictate my visual identity. Every color, every weight, every spacing value is intentional. Not borrowed. Not templated.
The Design System: v1.1
Before writing a single line of component code, I defined the system:
Colors
| Token | Hex | Usage |
|---|---|---|
| Black | #000000 | Backgrounds (70%) |
| White | #FFFFFF | Text (20%) |
| Gold | #D4AF37 | Accents (10%) |
| Grays | #1a1a1a, #666666, #A0A0A0 | Secondary surfaces |
The 70/20/10 proportion isn’t arbitrary. It’s editorial. It communicates restraint. It says “I know what matters.”
Typography
- Family: Inter (self-hosted,
font-display: swap) - Weights: 400 (body), 500 (labels), 600 (headings), 700 (emphasis), 800 (hero mobile), 900 (hero desktop)
- Letter-spacing:
-0.03emfor display,-0.02emfor headings,0for body
No serif defaults. No Inter-as-everything. Just one family, multiple weights, clear hierarchy.
Spacing
Base unit: 8px. Every vertical rhythm is a multiple of 8. Section padding, component gaps, page margins — all predictable. No arbitrary py-[47px] values.
Motion
- Durations: 150ms (fast), 200ms (base), 300ms (slow)
- Max 4px movement on hover
prefers-reduced-motionrespected everywhere- No infinite loops. No parallax. No scroll-hijack.
Motion supports comprehension. It doesn’t decorate.
Implementation in Astro
The system lives in three places:
1. tailwind.config.js
Every token is mapped to Tailwind utilities:
colors: {
'brand-gold': '#D4AF37',
'brand-gold-hover': '#E5C04A',
'brand-black': '#000000',
'brand-gray-dark': '#1a1a1a',
// ...
},
fontWeight: {
black: '800',
heavy: '900',
},
letterSpacing: {
tighter: '-0.03em',
'tight-2': '-0.02em',
},2. src/assets/styles/tailwind.css
CSS variables for runtime access:
:root {
--color-accent: #D4AF37;
--font-weight-heavy: 900;
--duration-base: 200ms;
/* 53 variables total */
}3. Components
Every component uses tokens. No hardcoded values. No text-blue-500. No py-12 without reason.
<!-- Hero title -->
<h1 class="text-5xl md:text-6xl font-black md:font-heavy leading-tighter tracking-tighter">
Raymond Arias
</h1>The Result: 100/100 Lighthouse
After implementation, I ran Lighthouse on the production build:
| Category | Score |
|---|---|
| Performance | 99/100 |
| Accessibility | 100/100 |
| Best Practices | 100/100 |
| SEO | 100/100 |
Zero failing audits across all categories.
What made the difference:
- No unused JavaScript: Astro ships HTML by default. Only interactive components hydrate.
- Self-hosted fonts: No Google Fonts blocking render.
font-display: swapeliminates FOIT. - Semantic HTML: Proper heading hierarchy,
aria-labelwhere needed, focus states on every interactive element. - Contrast ratios: Every text combination passes WCAG AA. Gold on black: 7.5:1. White on black: 21:1.
- No layout shift: Images have explicit dimensions. Fonts load with swap. No CLS.
What This Communicates
A 100/100 Lighthouse score isn’t just a number. It’s evidence.
It says:
- I care about performance, not just aesthetics.
- I understand accessibility, not as an afterthought, but as a foundation.
- I think about SEO at the component level, not just meta tags.
- I build systems, not pages.
For a hiring manager scanning portfolios, that’s the difference between “another developer” and “someone who thinks like a product designer.”
The Portfolio
You can see the result live at raymondarias.dev.
It’s not perfect. Some projects are paused. Some images are pending. But it’s honest. It’s curated. And it scores 100/100 on the metrics that matter.
If you’re building a portfolio and want to talk about Astro, design systems, or how to communicate seniority through craft — let’s connect.

