Colophon / the engine room, open

The right architecture is the one sized to the problem.

The problem here is precise: a personal archive that must be fast, cost zero, be readable by humans, crawlers and agents, and let itself be maintained on autopilot. Everything else on this page follows from that.

Requirements → decisions

Lightweight

Static HTML served from a CDN, client JS only where there's interaction. The bottleneck must be the reading, never the loading.

Zero overhead

No server, no database, no CMS: nothing to patch, nothing that gets breached, nothing that calls at 3am. A personal archive must not demand operational attention.

Cheap

Static build on a hobby plan: the marginal cost of a visit is ~zero, and so is the fixed cost. The money goes into the content, not the hosting.

Autopilot

The site maintains itself: I say what's needed, code-os (si apre in una nuova scheda) builds it, the gate decides whether it ships. agent-memory (si apre in una nuova scheda) holds the rules and the definition of done, decisions are recorded as ADRs: a fresh agentic session is productive at the first prompt, without me acting as its memory.

Findability / tokens

The data architecture is for agents too: typed data in src/content with predictable paths, one component per responsibility, names that say what they do. Anything is findable without burning tokens on exploration: minimum sufficient context is a property of the repo, not of the prompt.

SEO + GEO

Static is crawlable by definition, and I use Next for what it's good at: Metadata API for canonicals and OpenGraph, typed sitemap and robots, OG images generated at build time with ImageResponse, self-hosted fonts via next/font (zero layout shift), JSON-LD in the layouts. For AI-mediated search: llms.txt and /api/dossier, from the same source as the pages.

Non-commercial

No funnels, no popups, no third-party trackers (cookieless analytics and that's it). It's an archive to read, not a landing page to convert.

// this page too: I said what I wanted, the harness built it, the gate approved it.

Architecture

Decision record

  1. ADR-001accepted12 JUL 2026

    Zero dependencies, plus one

    Runtime: Next + React + react-aria-components (widget accessibility: focus management, press semantics, focus traps — things you get wrong if you rewrite them). No Tailwind, CMS, UI kits, animation libraries. Consequence: minimal update surface, every line in the bundle is justifiable.

  2. ADR-002accepted12 JUL 2026

    Everything static, always

    Every route — HTML, OG images, llms.txt, /api/dossier — is generated at build time and served from a CDN. No runtime compute: no cold starts, attack surface reduced to a minimum, ~zero marginal cost per request. The constraint is accepted: new content = new deploy.

  3. ADR-003accepted12 JUL 2026

    Content is a type, not a page

    Essays, principles, work live in src/content as typed objects (SSoT). Archive, homepage, sitemap, OG, llms.txt and /api/dossier all derive from the same source. Consequence: a piece of content is written once and cannot diverge across formats.

  4. ADR-004accepted12 JUL 2026

    One accent

    #E35B2D, everywhere; on the snow section a darker shade (#B8481C) for AA contrast on small text — same hue, not a second color. It holds in the easter eggs too: every snowfall has exactly one orange flake.

  5. ADR-005accepted12 JUL 2026

    Motion as decoration, never as a gate

    The hidden state of the scroll reveal exists only with JS enabled (@media scripting) and motion allowed. JS off or prefers-reduced-motion: content intact. Animations are a layer above the content, not a precondition for reading it.

  6. ADR-006accepted12 JUL 2026

    Accessibility as an invariant

    Skip link with a focusable target, visible focus ring, aria-current on navigation, AA contrast, external links announced, aria-live even for the easter eggs. Treated like tests: a regression is a bug, not a trade-off.

  7. ADR-007accepted12 JUL 2026

    Machine-readable

    /llms.txt for agents, /api/dossier for curl, JSON-LD for crawlers — all generated from the same SSoT as the pages, so never out of sync. I serve the context about me myself, in the format of whoever consumes it.

  8. ADR-008accepted16 JUL 2026

    Three languages, one SSoT

    IT, EN, PL as static routes (/it /en /pl), per-page hreflang, shared slugs. No middleware: detection is a static redirect. Cross-language parity is asserted at build time: a missing translation breaks the build, not the trust.

For the machines

I serve the content about me myself, in the format of whoever consumes it. Agents read /llms.txt; if you prefer the terminal, there's a JSON endpoint generated from the same SSoT as the pages:

curl simonebova.com/api/dossier

// same source, three formats: HTML for you, llms.txt for agents, JSON for curl.