Version 4 of the personal portfolio for Valentina Ramírez, Full Stack developer focused on backend and AI, and founder of Lúmina W. It is a bilingual Astro site, deployed on Vercel, with a serverless quote-delivery function.
Last updated: 2026-10-06
- Local development
- Stack
- Architecture
- Routes and internationalization
- Design system
- SEO, discovery and accessibility
- Testing and quality
- Delivery flow
- Deployment
- Repository documentation
- License
- Contact
- Node
22.x, pinned in.nvmrc - npm
git clone git@github.com:wavival/wavival.dev.git
cd wavival.dev
nvm use
npm ci
cp .env.example .env
npm run devThe development server runs at http://localhost:4321.
The Umami values are optional. Analytics and Core Web Vitals reporting are emitted only when both are set. BREVO_API_KEY is required in Vercel for quote delivery and must remain server-only.
| Variable | Read by | Required | Purpose |
|---|---|---|---|
PUBLIC_UMAMI_SRC |
Build (Layout.astro) |
Optional, both Umami variables or none | Umami script URL. |
PUBLIC_UMAMI_ID |
Build (Layout.astro) |
Optional, both Umami variables or none | Umami website ID. |
BREVO_API_KEY |
Runtime (api/quote.ts) |
Required in Vercel for quotes | Brevo transactional email key. Server-only, never PUBLIC_. |
QUOTE_ALLOWED_HOSTS |
Runtime (api/quote.ts) |
Optional | Extra hosts (comma-separated) allowed to post quotes, for example a staging domain. |
Set the variables in the Vercel project settings, not in the repository. The PUBLIC_ ones are read at build time, so a change needs a new deployment. wavival.dev@luminaw.co must be a verified sender in Brevo. See .env.example for the local template.
| Command | Purpose |
|---|---|
npm run dev |
Starts Astro with HMR on port 4321. |
npm run build |
Builds the static site into dist/. |
npm run preview |
Serves the production build locally. |
npm run check |
Runs Astro diagnostics and type checks. |
npm run lint |
Runs ESLint. |
npm run lint:fix |
Runs ESLint and applies the safe fixes. |
npm run format |
Formats the repository with Prettier. |
npm run format:check |
Checks Prettier formatting. |
npm test |
Runs Playwright against a production preview on port 4329. |
npm run test:ui |
Opens the Playwright UI runner. |
npm run test:install |
Installs the Chromium build Playwright needs. |
npm run commitlint |
Checks a commit message against the Conventional Commits rules. |
npm run lhci |
Runs Lighthouse CI against dist/. Build first. |
npm run links |
Checks built links in dist/. Build first. |
npm run csp:check |
Validates CSP hashes after a build. |
npm run css:check |
Ensures component CSS classes survive the production build. |
npm run security-txt:check |
Fails when security.txt has expired; warns in its last 60 days. |
| Layer | Choice |
|---|---|
| Framework | Astro 7, static pages plus one Vercel Function for quote delivery. |
| Styling | Tailwind CSS 4, CSS custom properties. |
| Components | Astro, organized with atomic design. |
| Client scripts | Vanilla TypeScript. |
| Internationalization | Spanish at root and English under /en/. |
| SEO | @astrojs/sitemap, Open Graph, Twitter Card, JSON-LD and llms.txt. |
| Analytics | Umami and web-vitals, enabled only with both public Umami variables. |
| Testing | Playwright, Lighthouse CI, linkinator, ESLint and Prettier. |
| Hosting | Vercel with Microfrontends. |
The site is statically rendered with Astro 7. Tailwind CSS 4 (through @tailwindcss/vite) supplies utility classes while CSS custom properties carry the design tokens. Client behavior is limited to vanilla TypeScript for navigation, theme state, quote submission, and optional web-vitals reporting. The Vercel Function at api/quote.ts sends quote requests through Brevo to wavival.dev@luminaw.co.
src/
├── components/ atoms, molecules and organisms
├── data/ projects, stack, GitHub build-time data and view models
├── i18n/ copy, slug map, localized routes and accessibility helpers
├── layouts/ Layout.astro, the shared document shell and metadata owner
├── pages/ Spanish routes and the English mirror under en/ (quote: cotizar.astro and en/quote/)
├── scripts/ navigation, theme, disclosure and optional RUM behavior
├── utils/ pure helpers (bento grid spans)
└── styles/ global CSS, design tokens and component classes
api/ quote.ts, the only Vercel Function
public/ brand, fonts, UI icons, images, CVs, crawler and AI-discovery files
scripts/ build-time validation scripts
tests/ Playwright browser and unit-style specs
docs/ SEO, i18n, accessibility, performance, security, engineering, release, brand, commercial and roadmap guides
.github/workflows/ CI, PR checks, auto-merge into dev, branch cleanup and release
.husky/ pre-commit (lint-staged) and commit-msg (commitlint) hooks
assets/ README-only visual assets
Root configuration: astro.config.mjs, eslint.config.mjs,
tsconfig.json, playwright.config.ts, lighthouserc.json, commitlint.config.cjs,
.prettierrc, .prettierignore, .nvmrc, vercel.json and microfrontends.json.
Layout.astro owns the shared head, canonical URL, hreflang tags, Open Graph and Twitter metadata, JSON-LD, theme pre-paint logic, navigation loader, navigation, footer, and skip link. Project content is defined in src/data/projects.ts (six projects, each an ecosystem split into parts); projectView.ts adapts it for localized rendering and projectSeo.ts builds the page title and JSON-LD.
Spanish is the default locale at the root. English is mirrored below /en/.
| Spanish | English |
|---|---|
/ |
/en/ |
/proyectos/ |
/en/projects/ |
/servicios/ |
/en/services/ |
/cotizar/ |
/en/quote/ |
/sobre-mi/ |
/en/about/ |
/contacto/ |
/en/contact/ |
/herramientas/ |
/en/uses/ |
/privacidad/ |
/en/privacy/ |
Each of the six projects has one page at /proyectos/[slug]/ and /en/projects/[slug]/; its parts (app, landing, docs...) are sections of that page, reachable by hash (#landing). Former slugs redirect permanently (see docs/seo.md). src/i18n/utils.ts is the source of truth for language pairs, localized routes, alternate URLs, active navigation, and CV links. Update its slug map whenever a page or slug changes.
The Vercel Microfrontends contract reserves /nullbreach and /nullbreach/:path* for the independent NullBreach project. This portfolio owns all remaining paths.
Version 4 uses the @wavival | Design System v4:
- One-column editorial composition at the full container width.
- Raleway 800 for display typography and Poppins for body copy.
- One accessible blue signal for interactive elements.
- 1px rules instead of shadowed cards.
- Static content with native
<details>disclosures, no scroll-reveal behavior. - Atomic components in
src/components/atoms,molecules, andorganisms. - Dark theme by default, controlled with the
.darkclass and persisted inlocalStorage.
Tokens live in src/styles/tokens.css; component classes live in src/styles/utilities.css. Use the token names and complete literal component class names to preserve Tailwind output.
Full detail: docs/seo.md and docs/i18n.md.
Every route receives a shared metadata baseline from Layout.astro:
- Canonical URLs and reciprocal
es,en, andx-defaulthreflang alternates. - Locale-specific default Open Graph cards:
og-card-es.webpandog-card-en.webp, both 1200x630 WebP. Case studies use their own cards. - Open Graph, Twitter Card, structured data, sitemap, and robots metadata.
Person,Organization, andWebSiteJSON-LD on all pages, plus page-specific structured data where applicable.public/llms.txtandpublic/llms-full.txtfor AI discovery.- Umami and Core Web Vitals reporting only when
PUBLIC_UMAMI_SRCandPUBLIC_UMAMI_IDare both configured.
Full detail: docs/accessibility.md. Related: docs/performance.md and docs/security.md.
Accessibility behavior includes a visible skip link, localized state labels, a keyboard-safe mobile menu, native disclosures, 44px icon control targets, explicit image dimensions, and a single visible <h1> per route. The automated suite checks desktop and mobile rendering, routes, SEO, i18n, theme behavior, project filters, and design regressions.
Run the complete browser suite after building:
npm run build
npm testHusky runs lint-staged (ESLint and Prettier on staged files) before each commit and Commitlint on each commit message; commit-msg also runs ~/.claude/git-hooks/commit-msg when that executable exists on the developer machine. See docs/engineering.md.
The CI workflow, on pushes and pull requests to dev, stg and main, runs the dependency audit (scripts/check-audit.mjs, which accepts only the advisories it lists with a reason), formatting, linting, Astro checks, the production build, CSP hash validation, component CSS validation, the security.txt expiry check, Lighthouse, and internal-link checks. The Commit lint workflow runs on every push, Secret scan (Gitleaks) on every push and on pull requests, CodeQL on pushes and pull requests to dev, stg and main and weekly, Dependabot opens weekly update pull requests to dev, and pull requests additionally validate the title and the allowed base branch.
feature/*, fix/*, chore/* -> dev -> stg -> main
mainis production,stgis staging, anddevis the integration branch.- Work branches target
devthrough pull requests. - Promotions are only
devtostgandstgtomain, always with merge commits.stgtomainis merged only by the owner. Because each promotion merge commit lands only on the base branch, a direct head can show as behind; the only allowed alternative head is a branch whose tree is identical todev(orstg), which keeps the base-branch check passing. auto-merge-dev.ymlenables auto-merge on every non-draft PR intodevfrom afeature/,fix/orchore/branch (merge commit, source branch deleted), and the merge waits for the required checks.delete-merged-branches.ymldeletes, every 12 hours or on demand withdry_run, the branches of PRs merged intodev.release.ymlis run by hand to tag and publish a version, seedocs/RELEASING.md.- Conventional Commit messages follow
type(scope): message. - Automated checks include commit title and message validation, quality, Playwright, Lighthouse, internal links, Gitleaks, and pull-request base validation.
- Vercel configuration, redirects, security headers, and cache policies live in
vercel.json.
Vercel builds the project with npm run build, installs dependencies with npm ci, serves dist/, and deploys api/quote.ts as the quote-delivery function. Set BREVO_API_KEY in Vercel and verify wavival.dev@luminaw.co as a Brevo sender. The site is available at https://www.wavival.dev.
microfrontends.json defines the Vercel path-ownership contract. vercel.json defines redirects, immutable asset caches, and production security headers. When editing inline scripts, run npm run build && npm run csp:check and update the CSP hash only when required by the check.
| Document | Scope |
|---|---|
| README.md | Repository overview, local setup, architecture, delivery and documentation map. |
| CLAUDE.md | Claude Code project guide: imports AGENTS.md and links to the documentation set. |
| AGENTS.md | Operational rules for agents: scope, documentation sources, delivery flow and verification. |
| DESIGN.md | @wavival Design System v4 tokens, type scale, component classes, composition, and accessibility rules. |
| COMPONENTS.md | Component and layout contracts, props, and usage details. |
| CHANGELOG.md | Versioned project history following Keep a Changelog and SemVer. |
| docs/seo.md | SEO, indexing, structured data and AI-assistant discovery (GEO). |
| docs/i18n.md | Spanish and English: page map, copy locations and rules. |
| docs/accessibility.md | Accessibility guarantees, component behavior, checks and checklist. |
| docs/performance.md | Performance decisions, caching, measuring and checklist. |
| docs/security.md | Headers, CSP, the quote function, OWASP Top 10 coverage, data, supply chain and checklist. |
| docs/engineering.md | Engineering practices: branches, commits, code, checks, CI and documentation. |
| docs/RELEASING.md | How a version is chosen, tagged and released with the Release workflow. |
| docs/brand.md | Living personal-brand positioning, voice, visual rules, product relationship, and content boundaries. |
| docs/commercial.md | Living commercial offer, ideal client, permitted claims, CTAs, and content risks. |
| docs/ROADMAP.md | Pending work, decisions that need the owner, and known gaps. |
| public/cv_valentina_ramirez_es.pdf | Spanish downloadable CV. |
| public/cv_valentina_ramirez_en.pdf | English downloadable CV. |
| public/llms.txt | Public AI-discovery index. |
| public/llms-full.txt | Public long-form AI-discovery companion. |
| public/robots.txt | Public crawler directives and sitemap location. |
| public/.well-known/security.txt | Public RFC 9116 security contact. |
| SECURITY.md | Private vulnerability-reporting policy for the repository and deployed site. |
| vercel.json | Redirects, immutable asset caches and production security headers. |
| microfrontends.json | Vercel Microfrontends path-ownership contract (NullBreach). |
| .env.example | Local environment-variable template. |
| LICENSE | MIT license. |
MIT. See LICENSE.
Thanks for getting here. Let's build great things.
