oficina / estilo Public

Clone
git clone https://amadan.net/oficina/estilo

Plain git — no account needed to clone.

Download

Download this file

1# Shared save status
2
3Status: revision 2 approved by Claude Fable 5.1 (claude-fable-5-1), 2026-09-07.
4Implementation and consumer adoption require branch review. Full initial and
5revised verdicts are recorded in Amadan Estilo discussion 1.
6User instruction: extract reusable components and maintain consistent suite UI/UX
7through Estilo during the overnight implementation run.
8
9## Concrete consumers
10
11Docs at 499d200 has a polite live region in views/show.html with two localized
12messages (retrying, failed), styled as a fixed notice. Its editor sets data-state;
13successful routine saves deliberately have no visible message.
14
15Slides slice-2-editor at a863fb6 has a status line in templates/editor.html and
16editor.css. editor-entry.js updates its text and data-state. It displays saved,
17saving, offline and error messages from the app's catalog. Existing session
18owns unfinished editor work; adoption will use an isolated branch after its
19current revision and be coordinated before merging.
20
21## Primitive
22
23Build the first shared component in Estilo, consumed by Docs first; Slides is
24the second adoption that validates/corrects the interface (AGENTS.md).
25
26Package savestatus exports an embedded html/template definition plus CSS.
27Data is a struct with localized text for Saved, Saving, Retrying, Failed and
28an optional localized accessible label. Missing text means that state stays
29visually silent. No English default or authored product copy lives here.
30The initial state is validated to a closed set, including idle. Unknown states
31are silent and never represented as saved.
32
33Markup uses estilo-save-status and estilo-save-message attributes, role=status,
34aria-live=polite, aria-atomic=true. Messages are ordinary template-escaped strings.
35The component is non-interactive. State changes are reflected by a small shared
36JavaScript function updating textContent in the already-present live region;
37it never injects HTML. Without script, the initial status text is visible.
38
39Slides maps saved/saving directly. Its offline state maps to retrying and retains
40the existing localized offline text. Its sticky dropped-batch case continues
41showing that same offline text, never saved; no new failed message is invented.
42Slide-load errors remain an app-owned element separate from save status, using
43the existing localized error text. The adopter must not claim a successful save
44clears a load error, or a successful load clears a dropped batch.
45
46Two placements are needed by the existing consumers: inline and floating.
47CSS inherits rastrillo tokens, wraps long text, respects 320px reflow and uses
48words plus weight for failure emphasis; it changes no theme value. App code
49continues to own save lifecycle, sticky failure, retry and recovery semantics.
50The floating failure retains Docs' negative background/foreground tone tokens.
51Inline placement retains Slides' minimum inline size of 8ch to avoid jitter.
52Both variants disappear for print via the component's own print rule.
53
54Silent status is an empty rendered live region: never display:none, visibility:
55hidden, hidden, or aria-hidden. Empty floating state has no padding/background/
56shadow, but the element remains present before a subsequent text mutation. This
57keeps the region in the accessibility tree before its first failure announcement.
58
59Do not ship a new all-green appearance for Docs routine saves, and do not
60change failure/retry wording. Do not infer save state from HTTP activity alone.
61
62## Integration
63
64Both app adopters import the same Estilo package revision and serve its CSS/JS
65through their existing embedded asset route. Their templates use the shared
66markup. Remove the replaced app-local status styling and DOM-writing functions.
67Retain an app-specific selector only where needed during the same migration;
68remove duplicate status DOM. No dynamic CDN imports, new framework, or bundler.
69
70Delivery is one same-origin ES module URL exposed in the editor's data attribute.
71The bundle loads it with dynamic import of that URL (kept external to bundling)
72and calls its exported mount function. The element holds template-escaped
73data-text-saved/saving/retrying/failed values; the module reads those once.
74Both apps' existing static routes serve the embedded module and CSS. Module-load
75failure must leave existing error/retry indication operational through a minimal
76app fallback or a pre-editor failure state; it must never silently run an editor
77whose persistence failure cannot be shown. The implementation review must verify
78this delivery/failure path in the actual bundle, not only the helper's unit test.
79
80## Verification
81
82Test HTML escaping, invalid state handling, missing labels/messages, role/live
83region and scriptless initial state. Exercise state transitions on a real DOM
84and prove failure wording is not replaced by stale save completion through app
85tests. Run Estilo theme/token-prefix tests unchanged and each consumer's gates.
86Verify both variants at 320px and keyboard/screen-reader semantics. Review full
87library and consumer diffs with Fable before CI/merge/deploy.
88Exercise repeated saving/offline/failed transitions; the live region remains in
89the DOM/accessibility tree while silent. Check Slides' sticky failure never
90returns to saved after a dropped batch; check load-error independence. Measure
91320px using Docs' longest existing failed text and widest available locale.
92
93No extraction is called complete until two apps consume it and their old
94duplicate implementation is removed. Until then it is an in-progress primitive.
95
96Fable review 1: claude-fable-5-1, /tmp/oficina-overnight-review/estilo.json.
97All seven findings accepted above: exact Slides mapping, persistent live region,
98explicit JS delivery, print, inline width, negative tone, pinned Slides revision.
99
100## Implementation evidence
101
102The floating notice uses pointer-events:none so it cannot block the editor.
103The full local make test gate passes. Mutation checks reject treating an unknown
104state as saved and replacing textContent with innerHTML.
105
106## Private module transport
107
108Estilo remains private. Use module path amadan.net/oficina/estilo.git,
109GOPRIVATE=amadan.net and authenticated Git transport. Go documents the VCS
110suffix as the supported way to resolve a private repository without public
111go-import metadata. A fresh direct download of5f712c7 via that path resolved
112the exact repository and commit. No public visibility change or local replace
113is part of the shipping dependency. Both first consumers adopt the qualified
114module path; no existing consumer pin was found.
115