A modern, anti-reflow portal showcasing an interdisciplinary creative practice across design, development, and graphic design disciplines. Built with Svelte + TypeScript and a carefully crafted design system rooted in architectural narratives.
shared-boundary grid-based layout with 1px gaps for visual cohesion--ring-primary and --ring-outline for consistent focus states across all interactive elementssrc/
├── routes/ # Page layouts (home, developer, designer, graphic)
├── lib/
│ ├── components/ # Reusable UI blocks (PortalLayout)
│ ├── data/ # TOML-based content loaders (CV, site metadata)
│ ├── state/ # Reactive stores (language toggle)
│ ├── styles/ # Global design tokens and component styles
│ └── types/ # TypeScript interfaces (CV, Site)
└── static/ # Assets and generated CV files
Content is stored in TOML format for maintainability:
cv.en.toml / cv.es.toml — Professional experience, education, skillssite.en.toml / site.es.toml — Navigation, metadata, descriptive contentThe loaders (cv-loader.ts, site-loader.ts) parse and type these files at build/render time.
# Install dependencies
pnpm install
# Start development server with HMR
pnpm run dev
# Open in browser
pnpm run dev -- --open
# Build static site
pnpm run build
# Preview production build locally
pnpm run preview
This project is configured as a fully static site using @sveltejs/adapter-static, making it perfect for Cloudflare Pages. No server-side rendering or server-side dependencies needed.
Create a Cloudflare Pages project:
mainpnpm install && pnpm run buildbuildAutomatic Deployment (GitHub integrated):
main triggers automatic build and deploymentWithout GitHub integration, you can deploy directly using Cloudflare's CLI:
# Install Wrangler CLI globally
npm install -g wrangler
# Or use it with pnpm
# pnpm add -D wrangler
# Build the project (generates ./build directory)
pnpm run build
# Deploy directly to Cloudflare Pages
wrangler pages deploy build
# Build and preview locally
pnpm run build
pnpm run preview
main and deploy automaticallysvelte.config.js — SvelteKit configuration with @sveltejs/adapter-staticwrangler.toml — Optional Wrangler CLI configuration for manual deployments.github/workflows/deploy.yml — Optional GitHub Actions CI/CD for automatic deployments.env.example — Template for environment variables (if needed)This portfolio includes comprehensive SEO implementations:
src/routes/+layout.server.ts — Global SEO data loadersrc/routes/*/+layout.server.ts — Page-specific SEO metadatasrc/routes/sitemap.xml/+server.ts — Dynamic sitemap generationstatic/manifest.json — PWA manifest with app metadatastatic/robots.txt — Search engine crawler directivesAll domain URLs are centralized in src/lib/config.ts. To change your domain:
// src/lib/config.ts
export const SITE_URL = 'https://your-new-domain.com'; // ← Update this
export const SITE_NAME = 'Your Site Name';
export const SITE_DESCRIPTION = 'Your description';
Then rebuild:
pnpm run build # ← Automatically generates all static files with new domain
This single change automatically updates everything:
robots.txt — Auto-generated with sitemap URLsitemap.xml — Auto-generated with all routesmanifest.json — Auto-generated with app metadataNo manual updates needed! See DOMAIN_CONFIG.md for detailed information.
Optional configuration via .env.local (see .env.example):
VITE_ANALYTICS_ID — Analytics tracking IDVITE_SITE_URL — Custom domain URLVITE_API_URL — External API endpointpnpm store prune
pnpm install
build directory is specified as output directory (not .svelte-kit)rm -rf .svelte-kit build
pnpm install
pnpm run build
# Clear node_modules and reinstall
rm -rf node_modules .pnpm-store pnpm-lock.yaml
pnpm install
pnpm dev --open
# Rebuild and preview
rm -rf build
pnpm run build
pnpm run preview
Design Philosophy: Structure as narrative. Every grid intersection, every gap, every color choice tells a story about the work and the maker.