Astro design system reference
Overview
This page documents the design system implemented across the site. The CSS custom properties, components, and layout patterns shown here are the source of truth; the page renders and explains what is already in production.
It is intended as a personal reference and may later be shared with interviewers or hiring managers as a portfolio artifact.
The component lab provides an interactive environment for developing and testing components in isolation, with live previews and accessibility testing.
Design Principles
Typography
Headings use var(--font-headers); body copy usesvar(--font-copy); monospace elements usevar(--font-mono).
Visual scale
inline code.Token usage
| Token | Mobile | Desktop | Line height |
|---|---|---|---|
--type-size-h1 | 32 px | 64 px | --line-height-h1 |
--type-size-h2 | 26 px | 45 px | --line-height-h2 |
--type-size-h3 | 22 px | 32 px | --line-height-h3 |
--type-size-h4 | 18 px | 24 px | --line-height-h4 |
--type-size-h5 | 16 px | 19 px | --line-height-h5 |
--type-size-large | 18 px | 22 px | --line-height-body |
--type-size-body | 16 px | 18 px | --line-height-body |
--type-size-small | 13 px | 15 px | --line-height-body |
Content samples
Blockquotes use a left border and slightly larger text. This is how a pull quote or emphasized statement appears.
/* Example token usage */
.card {
padding: var(--space-component);
background: var(--color-card-bg);
border-radius: var(--radius-lg);
}Color Tokens
The default theme is dark. A light theme is applied via[data-theme="light"] or system preference.
Core palette
--bg-mainPage backgroundDark: #0b1020 / Light: #f8fafc--bg-surfaceCards, header, code blocksDark: #111a2e / Light: #ffffff--bg-surface-elevatedElevated surfaces, hover statesDark: #18243a / Light: #e8eef7--text-primaryHeadings, primary textDark: #f8fafc / Light: #0f172a--text-secondaryBody text, descriptionsDark: #cbd5e1 / Light: #334155--text-mutedMeta, captions, labelsDark: #94a3b8 / Light: #475569--brand-primaryLinks, actions, focusDark: #5ea8ff / Light: #005fcc--brand-accentLink hover, success statesDark: #38d9a9 / Light: #007a5a--brand-highlightHighlights, marksDark: #ffb86b / Light: #a14b00--border-mainCard borders, dividersDark: #26344d / Light: #cbd5e1--border-mutedHeader border, subtle separatorsDark: #1a2638 / Light: #e2e8f0--border-controlForm input bordersDark: #52627a / Light: #64748bSemantic roles
| Token | Usage | Source |
|---|---|---|
--color-link | Default links | --brand-primary |
--color-link-hover | Hovered links | --brand-accent |
--color-action | Buttons, CTAs | --brand-primary |
--color-action-hover | Button hover | #3d8ee0 |
--color-focus | Focus outlines | --color-link |
--color-success | Success states | --brand-accent |
--color-card-bg | Card backgrounds | --bg-surface |
--color-card-bg-elevated | Elevated card backgrounds | --bg-surface-elevated |
--color-card-border | Card borders | --border-main |
Spacing Scale
Spacing is derived from the fluid rhythm token var(--rhythm)(≈ 26 px on mobile, ≈ 33 px on desktop).
--space-xscalc(var(--rhythm) * 0.5)13 px → 17 px--space-smcalc(var(--rhythm) * 0.75)20 px → 25 px--space-mdvar(--rhythm)26 px → 33 px--space-lgcalc(var(--rhythm) * 1.5)40 px → 50 px--space-xlcalc(var(--rhythm) * 2)53 px → 66 px--space-sectioncalc(var(--rhythm) * 2.5)66 px → 83 px--space-layoutcalc(var(--rhythm) * 3)79 px → 99 pxLayout Rails
Reading width and page width are intentionally separate. Prose stays narrow for readability, while pages and wide components can use more viewport space.
Components
Navigation
PaginationNav
src/components/PaginationNav.astro
Content
Card
src/components/Card.astro
Designing with tokens
How CSS custom properties shape typography, spacing, color, and layout across the site.
TagFilterBar
src/components/TagFilterBar.astro
Callout
src/styles/components.css
Interaction
Button
src/styles/components.css
ThemeToggle
src/components/ThemeToggle.astro
Integrations
ShareStrip
src/components/ShareStrip.astro
Search UI
src/pages/search.astro, src/styles/pagefind.css
Pagefind injects its markup at runtime; the site restyles it with project tokens. The internals are not rebuilt here.
Contact form fields
src/pages/contact.astro
Content Patterns
Article intro
A large lede paragraph uses var(--type-size-large) to set up an article or section.
Metadata row
Tag list
Accessibility Notes
- Skip link — keyboard users can jump to main content.
- Focus states — visible dashed outline with offset.
- Touch targets — minimum 44px for buttons and icon links.
- Color contrast — palettes are chosen for both dark and light modes.
- Semantic HTML — native elements before ARIA.
- Reduced motion — transitions and animations respect user preference.
Known Gaps & Follow-ups
| Item | Note |
|---|---|
| Header height | Measured at runtime by JavaScript; the CSS fallback is 4.5rem. |
| Pagefind search UI | Third-party markup restyled by src/styles/pagefind.css. |
| Portfolio case-study grid | Page-local 1.6fr / 0.8fr sizing in src/pages/portfolio.astro. |
| Homepage role text | One-off letter-spacing on the homepage hero role; not tokenized. |
| Page-specific animations | Scroll-driven header behavior and card entrance motion are scoped to specific pages. |
Implementation Notes
- This page widens the default content rail to
--layout-rail-widewhile keeping prose paragraphs at the readable--layout-rail-prosemeasure. --header-heightis measured and set by JavaScript; the CSS fallback is4.5rem.- Pagefind search UI is third-party markup restyled by
src/styles/pagefind.css. - Some page-specific styles use local sizing not yet captured by shared tokens.
- This page is intentionally omitted from the main navigation and uses
noindex, followmetadata.