7.1 KiB
Agent guide: mifi Ventures landing
This file helps LLM agents work in this repo without introducing anti-patterns. Follow the architecture and conventions below.
Purpose
- Audience: LLM agents (e.g. Cursor, Codex) making code or content changes.
- Goal: Preserve a minimal static site: SvelteKit prerender, no client-side app JS, shared theming, critical CSS inlining, and clear separation between app routes and static error pages.
Stack and architecture
- Framework: SvelteKit with adapter-static. All routes are prerendered; there is no client-side router or hydration (
csr: falseinsrc/routes/+layout.ts). - Build:
pnpm run build=vite build→node scripts/critters.mjs→node scripts/minify-static-js.mjs→node scripts/copy-410-paths.mjs. Output isdist/(static files only). - Runtime: nginx serves
dist/(mounted as/usr/share/nginx/htmlin the container). No Node at runtime. - Theming: CSS only. Light/dark follows system preference via
@media (prefers-color-scheme: dark)insrc/app.css. There is no JS theme toggle ordata-theme; do not add one unless explicitly requested. - Fonts: Local only. Inter and Fraunces are served from
static/assets/fonts/(e.g.inter-v20-latin-*.woff2,fraunces-v38-latin-*.woff2). Preloads are insrc/routes/+layout.svelte. Do not add Google Fonts or other external font URLs for the main site or error pages.
Key paths
| Path | Role |
|---|---|
src/app.css |
Single global stylesheet: CSS variables (light/dark), base styles, components. Source of truth for theme tokens. |
src/app.html |
SvelteKit HTML shell. Rarely edited. |
src/routes/+layout.svelte |
Root layout: head (meta, fonts, favicon, scripts), skip link, slot. Imports app.css. |
src/routes/+layout.ts |
Exports prerender = true, ssr = true, csr = false. Do not enable CSR. |
src/routes/+page.svelte |
Home page; composes sections from src/lib/components/. |
src/lib/data/*.ts |
Content and meta (home-meta, content, experience, engagements, json-ld). Edit here for copy or SEO. |
src/lib/seo.ts |
SEO defaults (baseUrl, theme colors, etc.) and mergeMeta(). |
static/ |
Copied as-is into dist/ by SvelteKit. Favicon, robots.txt, fonts, images, 404.html, 410.html, and assets/error-pages.css live here. |
scripts/critters.mjs |
Post-build: inlines critical CSS into every dist/*.html (including 404 and 410). Resolves stylesheet URLs relative to dist/. |
scripts/minify-static-js.mjs |
Post-build: minifies JS in dist/assets/. |
scripts/copy-410-paths.mjs |
Post-build: copies 410.html to each 410 URL path as index.html so static preview (e.g. serve dist) shows the 410 page at those URLs; nginx still returns 410 via explicit location blocks. |
nginx.conf |
Serves static files; try_files $uri $uri/ /index.html for SPA-style fallback; error_page 404 /404.html and error_page 410 /410.html for custom error pages. |
Static error pages (404, 410)
- Files:
static/404.html,static/410.html. They are standalone HTML (not Svelte). Do not convert them to Svelte routes. - Styling: Both link to one shared stylesheet:
<link rel="stylesheet" href="/assets/error-pages.css">. All error-page CSS lives instatic/assets/error-pages.css(theme variables for light/dark, local@font-facefor Inter/Fraunces, layout for.error-page). Do not duplicate theme tokens or add inline<style>in the HTML; keep a single source inerror-pages.css. - Critical CSS: The build runs Critters on all
dist/*.html. Critters inlines critical CSS from linked stylesheets (including/assets/error-pages.css) into 404.html and 410.html. So:- Do keep the
<link rel="stylesheet" href="/assets/error-pages.css">in 404.html and 410.html; Critters will inline it at build time. - Do not add error-page-only CSS in
src/app.css; the app bundle is not loaded on error pages.
- Do keep the
- Theme alignment: When changing light/dark colors or typography in
src/app.css, updatestatic/assets/error-pages.cssso 404/410 stay visually consistent (same--ep-*tokens and, if needed,@media (prefers-color-scheme: dark)). - Local fonts: Error pages use the same font paths as the main site (
/assets/fonts/...) via@font-faceinerror-pages.css. Do not use Google Fonts or other external font URLs on error pages. - Preview vs production: In preview (
serve dist), the 410 URLs (e.g./pt/,/feed/) are served by copying410.htmlto each path asindex.html(seescripts/copy-410-paths.mjs). In production, nginx returns HTTP 410 for those paths and serves the same content viaerror_page 410 /410.html. If you add or remove 410 paths, update bothnginx.confand thePATHSarray inscripts/copy-410-paths.mjs.
Anti-patterns to avoid
-
Enabling client-side rendering
Do not setcsr: trueor add a client-side router. The site is intentionally static and JS-minimal. -
Adding app JavaScript for the main shell
The only scripts are small, purposeful ones (e.g.copyright-year.js,ga-init.js,mobile-menu-helper.js) instatic/assets/js/. Do not introduce a Svelte hydration bundle or large runtime for the main pages. -
External fonts
Do not add<link>to Google Fonts (or similar) in layout or error pages. Use local fonts instatic/assets/fonts/and reference them via preload (layout) or@font-face(error-pages.css). -
Skipping Critters for new HTML
Any new.htmlinstatic/is copied todist/and must be processed by Critters (the script already runs on alldist/*.html). Do not add static HTML that bypasses the build or that uses only inline styles without a linked stylesheet (linked styles get inlined by Critters). -
Diverging error page theme
Do not change 404/410 styling in a way that ignoresstatic/assets/error-pages.cssor that duplicates theme tokens fromsrc/app.cssin ad-hoc form. Keep one error-page stylesheet and align its variables withapp.csswhen you change the main theme. -
Breaking static export
Do not add routes or behavior that require server-side rendering at request time (e.g. dynamic routes without prerender). The app is fully prerendered and served as static files. -
Scattering SEO or theme defaults
Keep SEO defaults and theme-color values insrc/lib/seo.tsand in layout/error pages that need them. Do not duplicate or hardcode them in many places.
Quick reference
- Change copy or structure (home):
src/lib/data/*.ts,src/lib/components/*.svelte,src/routes/+page.svelte. - Change global styles or theme:
src/app.css. Then syncstatic/assets/error-pages.cssif tokens or dark mode change. - Change error page copy or structure:
static/404.html,static/410.html. Style changes:static/assets/error-pages.cssonly. - Add a new static HTML page: Add it under
static/, link to/assets/error-pages.css(or a dedicated stylesheet that Critters can inline). Ensurescripts/critters.mjsruns over alldist/*.html(it already does). - Change nginx behavior:
nginx.conf(e.g. cache headers,error_page,try_files).