Skip to content

Repository files navigation

andrea-lisi.com · v2 "Mission Console"

Personal portfolio, second iteration. One-page dark site with a technical HUD aesthetic: mono labels, corner crosshairs, a sticky status bar, an animated signal-wave canvas and a procedurally generated three.js asteroid whose faces pulse with warm colors.

Stack

  • Astro — static output, partial hydration via React islands.
  • React 19 — only for the animated islands (SignalCanvas, Asteroid).
  • three.js — the hero asteroid: displaced icosahedron, pulsing vertex-color patches, orbiting fragments and a gold dust ring, scroll-linked rotation.
  • CSStokens.css is the variable source of truth, scoped Astro <style> blocks per component. No utility-CSS framework.
  • Biome — single-binary linter + formatter, strict ruleset.
  • Vitest + Testing Library — unit tests for hooks and React islands.
  • Playwright + axe-core — end-to-end smoke + accessibility checks.
  • Netlify — deploy from netlify.toml (static dist/).
  • GitHub Actions — quality (lint + typecheck + unit), build, and E2E + a11y on push / PR.

Development

pnpm install
pnpm dev        # http://localhost:4321

Build

pnpm build      # type-check + Astro build -> dist/
pnpm preview    # serve the production build locally

Quality gates

pnpm lint       # Biome: lint + format check
pnpm lint:fix   # Biome: apply fixes
pnpm format     # Biome: format only
pnpm typecheck  # astro check (TS + .astro)
pnpm test       # Vitest unit tests (jsdom)
pnpm test:watch # Vitest watch mode
pnpm test:coverage  # coverage report (v8)
pnpm verify     # lint + typecheck + unit + build (full local CI)

End-to-end + a11y

pnpm test:e2e:install   # one-time: install Playwright browsers
pnpm test:e2e           # build + preview on :4323 + Playwright suite

The suite runs against the production build, not the dev server: on-demand compilation made the first hit from each worker time out, and the built site is what actually ships. Workers are capped at 4 because every page runs a WebGL loop and a canvas rAF loop, and one Chromium per core starves them all.

The E2E suite covers section presence, the absence of the removed sections and of the flagged copy patterns, console-error budget, island hydration (canvas + WebGL asteroid), the CV download link, the nav labels, the mobile bottom bar, a no-JavaScript render, the prefers-reduced-motion path, the /ai deep link, and a WCAG 2.1 AA axe scan on both pages.

Deploy

Netlify auto-builds from the main branch using netlify.toml. To link a fresh repo: connect the GitHub repo in the Netlify UI (no env vars required) — netlify.toml handles command, publish, and Node version.

Structure

src/
├── layouts/
│   └── layout.astro               # html shell, fonts, meta, reveal-on-scroll script
├── pages/                         # thin: each page just picks a locale
│   ├── index.astro                # /        -> <Home locale="en" />
│   ├── ai.astro                   # /ai      -> <AiPage locale="en" />
│   └── it/
│       ├── index.astro            # /it/     -> <Home locale="it" />
│       └── ai.astro               # /it/ai   -> <AiPage locale="it" />
├── i18n/
│   ├── types.ts                   # the Copy shape both locales must fill
│   ├── en.ts                      # English, the published voice
│   ├── it.ts                      # Italian, the author's original voice
│   └── index.ts                   # locales, getCopy, hrefFor
├── components/
│   ├── home-page.astro            # the whole home page, for one locale
│   ├── ai-page.astro              # the /ai deep link, for one locale
│   ├── lang-switch.astro          # EN / IT, keeps you on the same page
│   ├── rail.astro                 # fixed left rail / mobile bottom bar + scrollspy
│   ├── status-bar.astro           # sticky name + coordinates strip
│   ├── hero.astro                 # 00 · name, stat strip, buttons, canvas + asteroid
│   ├── approach.astro             # 01 · "How I work": six prose blocks
│   ├── ai-section.astro           # 02 · AI, shared by the home page and /ai
│   ├── work.astro                 # 03 · Experience timeline
│   ├── contact.astro              # 04 · CV, profiles, email
│   ├── footer.astro
│   ├── section-header.astro       # giant outlined number + H2_ + eyebrow
│   ├── analytics.astro            # GA, production only
│   └── react/                     # client islands
│       ├── signal-canvas.tsx      # 2D canvas: sine waves + rising dots
│       ├── asteroid.tsx           # three.js asteroid (desktop only)
│       └── use-reduced-motion.ts  # shared media-query hook
├── data/
│   └── ai.ts                      # AI copy, shared by the section and the page
└── styles/
    ├── tokens.css                 # CSS variables (single source of truth)
    └── global.css                 # base, section shell, keyframes, reduced motion

public/
├── andrea-lisi-cv.pdf             # CV download target (copy of D:\CV output)
├── favicon.svg
└── robots.txt

tests/
├── unit/                          # Vitest + Testing Library
└── e2e/                           # Playwright + axe

Hydration strategy

Component Directive Why
SignalCanvas client:load Full-bleed hero background, visible at once.
Asteroid client:media="(min-width: 720px)" WebGL: desktop only, never loads on mobile.

Everything else is server-rendered at build time. Scrollspy and reveal-on-scroll are plain inline scripts (no framework runtime). Reveal-on-scroll hides [data-rv] blocks until the observer fires, so <html class="no-js"> plus an inline script in <head> keeps every block visible when JavaScript never runs.

Reduced motion

Honored twice: a global @media (prefers-reduced-motion: reduce) kill-switch in global.css, and a JS check (useReducedMotion in islands, matchMedia in inline scripts) that skips the rAF loops and renders the canvas and the asteroid as single static frames.

Original design handoff

The "Mission Console" design reference (prototype HTML + notes) came from Redesign Andrea Lisi site.zip. Production code is in src/.

License

UNLICENSED — personal site. Code is shared for transparency, not for reuse.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages