Colophon / maszynownia, otwarta

Właściwa architektura to ta zwymiarowana pod problem.

Problem jest tu precyzyjny: osobiste archiwum, które ma być szybkie, kosztować zero, dać się czytać ludziom, crawlerom i agentom, i dać się utrzymywać na autopilocie. Cała reszta tej strony z tego wynika.

Wymagania → decyzje

Lekkość

Statyczny HTML z CDN, client JS tylko tam, gdzie jest interakcja. Wąskim gardłem ma być czytanie, nigdy ładowanie.

Zero overheadu

Żadnego serwera, bazy, CMS-a: nic do patchowania, nic, co można włamać, nic, co dzwoni o 3 w nocy. Osobiste archiwum nie może wymagać operacyjnej uwagi.

Tanio

Statyczny build na planie hobby: koszt krańcowy wizyty to ~zero, koszt stały też. Pieniądze idą w treść, nie w hosting.

Autopilot

Strona utrzymuje się sama: ja mówię, co trzeba, code-os (si apre in una nuova scheda) to buduje, gate decyduje, czy się wdraża. agent-memory (si apre in una nuova scheda) z zasadami i definition of done, decyzje zapisane jako ADR: świeża sesja agentowa jest produktywna od pierwszego prompta, beze mnie w roli pamięci.

Findability / tokeny

Architektura danych też jest dla agentów: typowane dane w src/content z przewidywalnymi ścieżkami, jeden komponent na odpowiedzialność, nazwy mówiące, co robią. Wszystko da się znaleźć bez palenia tokenów na eksplorację: minimalny wystarczający kontekst to właściwość repo, nie prompta.

SEO + GEO

Statyczne jest crawlowalne z definicji, a Next wykorzystuję do tego, co umie: Metadata API dla canonicali i OpenGraph, typowane sitemap i robots, OG images generowane w build time przez ImageResponse, fonty self-hosted przez next/font (zero layout shift), JSON-LD w layoutach. Dla szukających przez AI: llms.txt i /api/dossier, z tego samego źródła co strony.

Niekomercyjność

Żadnych funneli, popupów, trackerów firm trzecich (cookieless analytics i tyle). To archiwum do czytania, nie landing do konwersji.

// ta strona też: powiedziałem, czego chcę, harness ją zbudował, gate zatwierdził.

Architektura

Decision record

  1. ADR-001accepted12 LIP 2026

    Zero zależności, plus jedna

    Runtime: Next + React + react-aria-components (dostępność widgetów: focus management, press semantics, focus trap — rzeczy, które psujesz, jeśli piszesz je od nowa). Bez Tailwinda, CMS-a, UI kitów, bibliotek animacji. Konsekwencja: minimalna powierzchnia update'ów, każda linia w bundlu jest uzasadnialna.

  2. ADR-002accepted12 LIP 2026

    Wszystko statyczne, zawsze

    Każda route — HTML, OG image, llms.txt, /api/dossier — jest generowana w build time i serwowana z CDN. Zero compute w runtime: bez cold startów, powierzchnia ataku zredukowana do minimum, ~zerowy koszt krańcowy requesta. Ograniczenie zaakceptowane: nowa treść = nowy deploy.

  3. ADR-003accepted12 LIP 2026

    Treść to typ, nie strona

    Eseje, zasady, work żyją w src/content jako typowane obiekty (SSoT). Archiwum, strona główna, sitemap, OG, llms.txt i /api/dossier pochodzą z jednego źródła. Konsekwencja: treść pisze się raz i nie może się rozjechać między formatami.

  4. ADR-004accepted12 LIP 2026

    Jeden akcent

    #E35B2D, wszędzie; na śniegu ciemniejszy odcień (#B8481C) dla kontrastu AA na małym tekście — ta sama barwa, nie drugi kolor. Obowiązuje też w easter eggach: każda śnieżyca ma dokładnie jeden pomarańczowy płatek.

  5. ADR-005accepted12 LIP 2026

    Motion jako dekoracja, nigdy jako gate

    Ukryty stan scroll-reveala istnieje tylko przy włączonym JS (@media scripting) i dozwolonym motion. JS wyłączony albo prefers-reduced-motion: treść nietknięta. Animacje są warstwą nad treścią, nie warunkiem jej czytania.

  6. ADR-006accepted12 LIP 2026

    Dostępność jako inwariant

    Skip-link z fokusowalnym celem, widoczny focus ring, aria-current w nawigacji, kontrasty AA, linki zewnętrzne ogłaszane, aria-live nawet dla easter eggów. Traktowana jak testy: regresja to bug, nie kompromis.

  7. ADR-007accepted12 LIP 2026

    Czytelne dla maszyn

    /llms.txt dla agentów, /api/dossier dla curla, JSON-LD dla crawlerów — wszystko generowane z tego samego SSoT co strony, więc nigdy rozsynchronizowane. Kontekst o mnie serwuję sam, w formacie odbiorcy.

  8. ADR-008accepted16 LIP 2026

    Trzy języki, jeden SSoT

    IT, EN, PL jako statyczne route (/it /en /pl), hreflang per strona, wspólne slugi. Bez middleware: detekcja to statyczny redirect. Parytet między językami sprawdzany w build time: brakujące tłumaczenie psuje build, nie zaufanie.

Dla maszyn

Treść o mnie serwuję sam, w formacie tego, kto ją konsumuje. Agenci czytają /llms.txt; kto woli terminal, ma endpoint JSON generowany z tego samego SSoT co strony:

curl simonebova.com/api/dossier

// jedno źródło, trzy formaty: HTML dla ciebie, llms.txt dla agentów, JSON dla curla.