Stage 1 of 8
Source change
Facts live as JSON and Markdown in src/content; components only render them. A change is one edit in one place.
src/content/**/*.{json,md}A static site, checked on the Mac and uploaded to Cloudflare. Follow a change through it.
Stage 1 of 8
Facts live as JSON and Markdown in src/content; components only render them. A change is one edit in one place.
src/content/**/*.{json,md}Stage 2 of 8
Builds the site, then a Playwright suite runs against the output.
npm testStage 3 of 8
Playwright prints the designed and ATS CV pages to PDF from the same content.
npm run cvStage 4 of 8
Type-checks components and content schemas, then pre-renders every page.
astro check && astro buildStage 5 of 8
HTML, CSS, small scripts, self-hosted fonts, PDFs, search.json, sitemap and _redirects. No server code.
dist/Stage 6 of 8
A direct upload from the Mac. Preview uploads add an X-Robots-Tag noindex header and a Disallow robots.txt.
npx wrangler pages deploy dist --project-name=anis-portfolio --branch=previewStage 7 of 8
Serves the static files from Cloudflare’s edge and applies the /work/* → /portfolio/* redirects.
*.pages.dev · HTTPSStage 8 of 8
The theme is set before paint, the search index loads on first open, and the terminal runs entirely in the page.
theme · search.json · terminalBuild time · on the Mac
Run time
src/content, validated by schemas in src/content.config.ts. A malformed entry fails the build./search.json, the terminal's dataset and both CVs.npm run build runs astro check (types and content schemas) before building.npm test builds, serves dist/ locally and runs a Playwright suite: internal links and anchors, console errors, overflow at 360px and tablet widths, axe WCAG A/AA in both themes, theme, search, filters, constellation, terminal, mobile menu, reduced motion, CV PDF text, and a guard against confidential names in public files.preview branch with PUBLIC_NOINDEX=true, plus an X-Robots-Tag: noindex header and a Disallow robots.txt added to the upload./work/* links redirect to /portfolio/* via public/_redirects.