Files
armandine/AGENTS.md
mifi af70682fa8
Some checks failed
ci/woodpecker/push/ci Pipeline failed
ci/woodpecker/push/build unknown status
ci/woodpecker/push/deploy unknown status
Revert to static JS site (Svelte built, but no CSR); Optimize images
2026-02-16 00:54:08 -03:00

54 lines
4.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# AGENTS.md guidance for LLM agents
This file helps LLM agents work with the Armandine codebase without introducing antipatterns.
## Stack and goals
- **Svelte 5** + **SvelteKit** with **TypeScript**. The site is a **single pre-rendered page** (no SSR, no backend).
- **adapter-static**: the app is built to static HTML/JS/CSS in `build/`. **CSR is disabled** (`csr = false` in `+layout.ts`), so no Svelte runtime or app JS is loaded in the browser. The gallery and shell (header, empty lightbox dialog) are **rendered at build time** from Svelte components and `src/lib/media.ts`. Lightbox, theme toggle, and “show video” are implemented in **`static/assets/js/script.js`** only; they bind to the pre-rendered DOM.
- **PostCSS**: nesting and CSS level 2; component-scoped `<style>` in Svelte where possible; global styles in `src/app.css`.
- **Critical CSS**: after `vite build`, `scripts/critical-css.js` runs Beasties to inline critical CSS into the built HTML.
## Structure
| What | Where |
|------|--------|
| Routes / page | `src/routes/` (`+page.svelte`, `+page.ts`, `+layout.svelte`, `+layout.ts`) |
| Components | `src/lib/components/` (e.g. `GalleryFigure.svelte`, `SiteHeader.svelte`) |
| Media data (build-time gallery) | `src/lib/media.ts` typed array; loaded in `+page.ts` and passed to the page |
| Client script (lightbox, theme) | `static/assets/js/script.js` not part of Svelte bundle; preloaded in head |
| GA init | `static/assets/js/ga-init.js` |
| Static assets (favicons, media files) | `static/assets/` (media: `desktop/`, `tablet/`, `mobile/`, `thumbnail/`, `videos/`) |
| Global CSS | `src/app.css` (imported in `+layout.svelte`) |
| Config | `svelte.config.js`, `vite.config.ts`, `tsconfig.json`, `postcss.config.js` |
## Conventions
- Use **Svelte 5** patterns (e.g. `$props()`, runes). Use **TypeScript** for `src/lib` and route logic.
- **Gallery**: Rendered at build time via `GalleryFigure` and `data.mediaItems` from `+page.ts`. Do not move gallery rendering to the client.
- **Lightbox and theme**: Implemented only in `static/assets/js/script.js` (no client-side Svelte). They rely on the pre-rendered DOM (e.g. `.gallery-item[data-name]`, `dialog.lightbox`, `#show_video`, `#theme-toggle`). The Svelte `Lightbox` component is still used at build time to output the empty `<dialog class="lightbox">`; script.js creates the inner structure (header, .lb-content, #lb-caption) on first open. Keep all runtime behavior in script.js.
- **Head**: Metadata, JSON-LD, favicons, preload of `script.js`, and GA scripts are set in `+page.svelte`s `<svelte:head>`.
- **CSS**: Prefer component-scoped `<style>` in Svelte components; use `src/app.css` only for `:root`, `body`, and shared/global rules (e.g. lightbox, which is targeted by the client script).
- **Build**: `pnpm build` = `vite build` then `node scripts/critical-css.js`. Output is `build/`. Dockerfile copies `build/` into the image.
## Build pipeline and CI
- **Local:** `pnpm dev` (dev server), `pnpm build` (production build), `pnpm preview` (serve `build/`), `pnpm check` (Svelte + TypeScript check).
- **CI (Woodpecker):** `ci` runs lint, format:check, and **check** (Svelte/TS). `build` runs `pnpm build` then `docker build` (image uses `build/`).
## Antipatterns to avoid
- **Do not** add a backend, API routes, or SSR for this static site.
- **Do not** move lightbox or theme logic into Svelte components; they stay in `static/assets/js/script.js` and attach to the pre-rendered DOM.
- **Do not** add unscoped global CSS for component-specific styles; use component `<style>` or the existing `app.css` sections.
- **Do not** introduce dynamic routes or server-dependent behavior that would break static export (adapter-static).
- **Do not** remove or bypass the Beasties critical-CSS step without replacing it with an equivalent (e.g. another inlining strategy).
## How to add features
- **New media item:** Add an entry to the `mediaItems` array in `src/lib/media.ts` (type, name, caption, alt, dimensions, loading/fetchpriority as needed). Ensure the corresponding files exist under `static/assets/media/` (desktop, tablet, mobile, thumbnail; videos in `videos/`).
- **New component:** Add a `.svelte` file under `src/lib/components/` (or a subfolder). Use component-scoped `<style>` and PostCSS will process it. Export and use in the appropriate route or parent component.
- **New page:** Add a route under `src/routes/` (e.g. `src/routes/about/+page.svelte` and `+page.ts` if needed). With `prerender = true` in the root layout, all pages are pre-rendered.
- **Change metadata or JSON-LD:** Edit the `<svelte:head>` block in `src/routes/+page.svelte` (or the relevant page). Update the `jsonLd` object and meta tags as needed.
- **Change client behavior (lightbox/theme):** Edit `static/assets/js/script.js`. Ensure the script still targets the same DOM structure (e.g. `.gallery-item`, `data-name`, `data-type`, `data-caption`, `#lightbox`, `#lb-content`, `#lb-caption`, `#lb-close`, `#show_video`, `#theme-toggle`).