PAGES 0.3 - INTERAKTIONER OG BYGGESTATUS

Samme renderere bruges i Pages-editoren og CLI. Komponenten beskrives som
{type: "source", body: {...}} i en .page eller .site-element. Egne .site-type
filer kan erstatte standardfelterne; nye standardtyper er altid tilgængelige.

MODEL
interactionMode: "test" (standard) eller "live".
breadcrumbs: false skjuler brødkrummer på alle sider.
search: true eksporterer search.json. En search-komponent uden src har også
et indlejret indeks og læsbare links uden JavaScript. folder afgrænser siderne.
reactions: {feed, endpoint, storageKey, eventType} er fælles reaktionsindstillinger.
GUI'en viser dataforbindelser, modtagere og browserlagernavne i et eget overblik.

REAKTIONER
contentId er en stabil nøgle, uafhængig af URL. eventType og actions skal passe
med modtagerens tilladte værdier. En action har id, label og icon; up/down har
SVG-ikoner. policy er unlimited, once eller daily; limit er dagskvoten.
animation kan være none; duration angives i millisekunder. Reduceret bevægelse
slår animationen fra. feed, interval, endpoint, transport og storageKey kan
angives pr. komponent. Eksempler bruger test og fixture (tal pr. action).

Localhost og preview sender aldrig produktionsreaktioner. Testdata gemmes i
storageKey + '.test'. Lagerformatet er version 2. Lagerfejl stopper ikke den
åbne side. storage-events opdaterer andre faner; klikhistorik er lokal og er
ikke dokumentation for personidentitet. To samtidige writes fra flere faner
kan stadig konkurrere: browserlager er ikke en transaktionsdatabase.

GET sender type, subject, action, r og eventId. eventId er et UUID, og r er
samme id. POST kan sende JSON til en særskilt modtager. Modtageren skal selv
implementere POST. Loggerens eksisterende pixel bruger GET.
Ventende events genforsøges med samme id ved genåbning/aktiv fane og under
polling. Højst 50 pr. komponent pr. runde og mindst 30 sekunder mellem forsøg.
Et vellykket HTTP-kald er ikke bevis på optælling.

OFFENTLIG JSON OG AFSTEMNING
{ "updated_at":"2026-10-31T12:00:00Z",
  "counts":{"indlaeg":{"eksempel":{"up":12,"down":3}}},
  "acceptedIds":["UUID"], "rejectedIds":["UUID"] }

Visningen lægger egne ventende events oven i offentlig optælling. Kun præcise
acceptedIds/rejectedIds fjerner de pågældende lokale events. updated_at alene
fjerner ingen. Loggeren beholder kvitteringer 30 dage; klienten udløber ventende
events efter samme periode. Gamle offentlige snapshots forkastes. Ukendte tal
vises som ukendte; hentefejl bevarer sidst kendte tal. Sletning af browserlager
trækker ikke allerede sendte events tilbage. Loggeren deduplikerer eventId og
kan håndhæve kvoter pr. pseudonym besøgsnøgle. Cookies/IP/browser kan ikke give
en sikker personkvote. UTC er dagsgrænsen i både klient og cruncher.

DATA OG SØGNING
source/chart: src, field (punktsepareret feltsti), mode (fetch eller build),
fallback, interval, timeout, schema og version. Build-mode indlejrer den lokale
JSON-kilde; fetch-mode henter fra det publicerede site eller eksplicit endpoint.
source har format text/date og itemField til lister. chart har style bar/line
og caption; en datatabel følger grafen. Der udføres ingen tekst som JavaScript.
search: src (valgfrit), folder (sitets indbyggede indeks), param (URL-navnerum).
Kategorier, tekst og sortering bevares i URL. Eksternt indeks er en liste eller
{documents:[...]}, med title, url, summary/text, tags, category og date.

BILLEDER OG NAVIGATION
media/post: hoverSrc og imageLink giver billedskift på hover og tastaturfokus.
På touch følger linket sin normale navigation; essentiel tekst må ikke kræve
hover. gallery har images med src, alt, caption og credit. Forstørrelse bruger
browserdialog, Escape og fokusretur. tabs/accordion har id, heading og items
med label/text. Faner har piletaster, Home/End og hash-links. Uden JavaScript
vises almindelige details-afsnit. local-reset sletter kun angivet lagernavn.

FORMULAR
inputs kan bruge text, email, textarea, number, date, select og checkbox.
Select options kan være en liste eller tekst adskilt af |. required bruger
browserens validering. test: yes og scenario: success/error simulerer lokalt.
Modellen skal være live, og test skal være slået fra, før der sendes rigtige
data. ajax: yes bruger POST/FormData til action, med 10 sekunders timeout.
Et eksternt endpoint kræver passende CORS. Standardformular uden ajax bruger
browserens almindelige afsendelse. Formularserveren validerer altid selv input.

FORMATER
Artikel, note, event, location, canvas, record, medier, Regnemodel, Shade og
Skilt bruger Pages' fælles renderere. Planche og To Do har publiceringsvisninger:
Planche viser rumlig komposition og en læseliste; To Do viser kolonner og kort.
De medfører ikke hele deres redigeringsprogram på det offentlige site.
Canvas og Planche har flytning, zoomknapper og tastatur. Planche-afspilning,
rotation, interaktiv redigering og fuld To Do-arbejdsgang er ikke med.
Ikke alle Ele-plugins er offentlige renderere. Formatbeslutninger og konkrete
eksempler er dokumenteret i hjemmesidens vedligeholdelse/formatkatalog.json.

BYGGEFEJL
CLI skriver en tydelig fejl til stderr, returnerer exit 1 og skriver status
ved siden af outputmappen. Se cli/README.txt. GUI viser fejl med stor rød ramme,
role=alert, fokus og en markør for afbrudte builds ved genåbning. En watchdog
advarer ved over 90 sekunder uden fremdrift, hvis browsertråden stadig svarer.
En fuldstændigt blokeret eller lukket browser kan ikke tegne en besked, før den
svarer igen. CLI-overvågningen kører i den særskilte lokale previewserver.

KONTROL
pages.test.mjs, interactions.test.mjs og cli/cli.test.mjs indgår i Linux-release.
Andre operativsystemer krydskompileres og kræver stadig native accepttest.


Pages 0.3.2: site-wide reaction snapshot
Set model.reactions.feed to the site's public JSON URL (e.g. /reactions.json).
Every document, including pages without reaction widgets, fetches it exactly
once. No reaction polling, visibility refresh or click-triggered feed fetch.
window.elePages.reactions.ready resolves after the attempt; .data exposes the
shared snapshot to other counters. Failure leaves totals unknown until the next
page load. All widgets share updates; reset preserves public totals.
Pending events are reconciled only by acceptedIds/rejectedIds and retried once
after the snapshot arrives. A new click sends its own event immediately.
Legacy widget feeds: one distinct URL is fetched once; multiple different URLs
produce a visible configuration error. A site-level feed takes precedence.
Use a root-relative or absolute URL for a shared external feed.
