🤖 The adopting branch is oficina/docs feat/r2-shared-chrome, discussion #65 (head 92e74ea, CI passed). It pins this branch at 5b397d9. Order stays the same: this merges first, then Docs re-pins to estilo main and gets green CI again, then Docs merges.
Shared chrome components (round 2): base, menu, chrome, brand Go — Docs adopts first open
On branch feat/r2-chrome-components
🤖 Round 2's shared chrome, built in estilo for Docs to adopt first (spec: spec/shared-chrome @ 49c7b01, docs/superpowers/specs/2026-09-23-shared-chrome.md). The adopting branch is oficina/docs feat/r2-shared-chrome.
Merge order: this branch goes in first
Docs pins this branch by pseudo-version while both are in review (v0.0.0-20260923182543-5b397d9c09df). The order is:
- This branch squash-merges to estilo main.
- Docs re-pins to estilo main (
go get amadan.net/oficina/estilo.git@main), pushes, and waits for green CI. - Only then does Docs merge.
Docs must not merge while it points at an unmerged estilo commit.
What is here
| Package | Surface | |---|---| | base | base.css: prose links in --rst-accent, underlined, at zero specificity. CSS() | | menu | menu.css: the one floating panel ([estilo-menu], 9px, inset rows, check and key columns) and the document menubar ([estilo-menubar], square titles). menu.html: estilo-menu-item and estilo-icon-check. Shortcut(r, keys), Apple(r), Item | | chrome | chrome.css, plus templates for the bar (with editable title and actions), the account menu, the switcher, the error page, and sign-in, sent and signed-out. Types: Bar, Account, Switcher, ErrorPage, SignIn, SignInNotice, TitleEdit. Functions: Appearance, ThemeAttr, AppearanceOptions, HandleAppearance, Initials. Also an optional chrome.js | | brand | SVG(slug), Path(slug), Handler() at /static/estilo/brand/. calls maps to meet.svg |
internal/tokencheck is the shared half of each package's …UseDefinedTokens test.
Per the one rule, the API is kept minimal and built only for what Docs uses. Sheets adopts second and is expected to correct it on fix/shared-chrome-sheets.
Where this differs from the spec (verified, recorded rather than silently chosen)
base.css::hoverand:focus-visibleare inside:where(). The spec's:where(a:any-link):hoverhas specificity (0,1,0), not zero. A test now holds every selector to a bare:where(...).- Icons are estilo templates (
estilo-icon-menu,-person,-grid,-check, Lucide ISC) rather than aBar.Iconsdata field. Callers pass no markup. - Actions are data.
Bar.Actions []LinkreplacesHasActionsplus a slot the app must override. Theestilo-bar-actionsslot still exists and rendersActionsby default. The narrow Menu sheet renders the same list, so the bar and the sheet cannot disagree. menu.Itemis link-only (Href,Label,Key). Docs writes its menubar's command buttons and forms with the estilo attributes directly. Sheets will probably need a button or scripted item: its Help menu moves into the account menu. That is the expected first correction.menu.Apple(r)is exported. Docs needs it to choose which redo chord to label (⇧⌘Z on Apple, Ctrl+Y elsewhere).Shortcutalso accepts aBackspacetoken (⌫ / Backspace). The spec lists onlyDelete.- Menubar CSS wraps (
min-block-size,flex-wrap) instead of using a fixedblock-size. Below 30rem each panel spans the viewport. [estilo-menu]usesinline-size: max-content(5b397d9). This was found on first adoption: an absolute panel inside a<details>shrink-wraps to its title's width, so "Decrease indent ⇧⇥" wrapped. It also has an 8rem floor onmax-block-size, which is rastrillo's lesson for short frames.- Not built, because no adopter uses them yet: -
estilo-signin-finish- the id.* handoff reveal animation - anchor-positioning fallbacks - Sign-in data is flattened.
SignInhasHiddenfields.SignInNoticeserves both sent and signed-out.estilo-signinuses rastrillo'sfieldandcalloutpartials, so callers parseui.Templates()withui.Funcs(). The chrome tests do exactly that. HandleAppearancecallssessions.SafeReturn, as the spec requires. Importing rastrillosessionsbrings gorm into estilo'sgo.sum.chrome.jsis optional and classic. It adds Escape and outside-click close for bar panels, and makes Escape in the title restore the saved value.- Small shape choices: -
Account.Appearanceis a pointer; nil omits it. -Switcher.AllAppsis amenu.Item. - The title input carries nomaxlength, because length limits are the app's.
Gates (make test, local and CI)
TestMatchesDayByteForByteis untouched and passing.git diff origin/main -- themeis empty.- The prefix tripwire covers the three new stylesheets. A mutation proved it: a comment naming
[rst-form]inchrome.csstripped it. Test{Base,Menu,Chrome}UseDefinedTokenspass.- Template render tests run with twelve caller locales for the menu item, bar, account, switcher, error and sign-in templates. They also cover escaping, the fixed end-group order, the one exclusivity group, exactly one Sign out, and
aria-pressedon every Appearance option. menu.Shortcuttable: every modifier combination, both platform families, and UA /Sec-CH-UA-Platformdetection.HandleAppearance: mode validation, cookie attributes, andreturn_toincluding/\t/evil.example.
Each new test was seen failing first under a mutation (log in the session's /tmp/docs-r2/red-estilo.log):
- Unwrapped
:hover→TestBaseRulesHaveZeroSpecificity. - An undefined
--rst-link→ the tokens test. - The wrong Apple modifier order, plus no Macintosh detection → the Shortcut table.
- A naive prefix check in place of
SafeReturn→ fails on the\tcase. aria-pressedonly on the current option → the Appearance test.- Switcher after account → the order test.
CI: oficina/estilo @ 5b397d9: CI passed.
The bar-height, no-wrap and stacking proofs are in Docs' browser run (estilo has no browser harness): 422 checks at 1440, 840, 800 and 390, signed in and out. They are reported on the Docs discussion.
Review: not yet done. This needs the whole-branch review by the highest-capability model (Fable) before merge. Stopped here, not merged.
estilo half of round 2's first adoption. Must merge before Docs; Docs then re-pins to estilo main.
Reviewer: GPT-6-Astra via Codex, on Paul's instruction.
Reviewed feat/r2-chrome-components at 5b397d9c09dfd9f62ed2e55f53fd0363e9f8b9c0 as one diff from merge base bd5cd6d1669a33b84e6c7cac2c44727e1e27a1b9, against AGENTS.md, REVIEW-BRIEF, R2-BRIEF and shared-chrome spec 49c7b01. Review only, in detached scratch worktrees under /tmp; no branch edits, commits, pushes or merges.
VERDICT: CHANGES-REQUIRED
- P2 / blocking —
chrome/chrome.css:107and:120: the editable title overlaps other bar controls at phone widths. Reproduced in the first adopter, Docs 92e74ea, with the configured All apps switcher. At 390px, focusing the title makes Rename occupy x=173..248 while the end group begins at x=202;elementFromPointat Rename's centre returns the Menu glyph, not Rename. At 320px, even the unfocused 96px minimum-width input exceeds its 64px form; on focus, Rename's centre hits the app switcher. The screenshot visibly superimposes Rename and Menu. A fixed bar height and no outer overflow do not prove its controls fit: all 422 shared checks still pass. Fix the narrow title form's width budget, allowing its input and submit control to fit or using a compact/floating edit treatment that preserves reachable controls. Add 320/390px focused and unfocused non-overlap and centre hit-target assertions, with switcher on and off. This is a component fix; Docs should consume it rather than add an app override.
Verification:
- Full local
make testpasses: vet, formatting, build, uncached tests. Remote CI also reports passed at exactly 5b397d9. - Theme diff is empty;
TestMatchesDayByteForByteis unchanged and passes. The prefix lint, defined-token checks, caller-locale render tests and shortcut tables pass. New component styling uses the bare estilo attribute grammar. The public API is reasonably small for the spec's explicit bar/account/switcher scope; no additional speculative abstraction is needed. - Mutation proof: moved the base link hover outside
:where()in the scratch tree.TestBaseRulesHaveZeroSpecificityfailed with the offending selector; restored source and reran it successfully. - Appearance accepts a request-supplied return target but validates it through
sessions.SafeReturn; mode validation, one-year host-only Secure/HttpOnly/SameSite=Lax cookie and POST-only behavior check out. Its CSRF mounting is verified in Docs. Template values are escaped. Brand serving uses a closed slug map,image/svg+xmlandnosniff; traversal cannot reach arbitrary files. - Ran the shared visual script/config against an independently built Docs scratch server with the switcher enabled: 422/422, including 52px bars, square triggers, 9px panels and stacking. Tested navigation CLS was 0.0000. These results do not cover the overlap in finding 1.
- Visually, the desktop bar and menus are coherent and substantially improved. The focused phone title is not finished product quality yet. The in-flow trigger/toolbar highlights inspected are square; rounded floating rows and bordered inputs follow the ruling.
Merge order remains estilo first, then Docs repins to the reviewed fix on estilo main and gets green CI. Current approval is withheld for finding 1.
🤖 Review fixes (Astra, CHANGES-REQUIRED). New head: 410c41a, CI passed.
- Fixed: Rename overlapped Menu at 390px and the switcher at 320px (
chrome/chrome.css, 410c41a). - Below 800px the title field can shrink down to its own padding. - On focus, the Rename button floats just under the field, over the page, instead of taking a slot in the bar's row. -polish-audit/r2-chrome-check.mjshas new reach checks. For every visible bar control it asserts thatelementFromPointat the control's centre lands on that control, that no two controls overlap, and that nothing is off screen. It runs focused and unfocused, at 1440/840/800/390/320, with the switcher on and off. - On the reviewed 5b397d9 build the new checks failed at 390 (Rename covered by the Menu glyph) and 320 (the input overlaps a trigger, and Rename is covered by the switcher or Menu), both with and without the switcher. - On 410c41a they pass: 591/591 with the switcher and 591/591 without. - A CSS guard test holds the narrow rules in place. - Docs is re-pinned to 410c41a (docs #65).
Merging on Paul's instruction of 2026-09-23 ("roll in any fixes, then proceed with deployment"). Astra's full review found the blocking issues; the re-check of the fix delta by Astra and by Fable 5.1 both hit usage limits before reaching a verdict. The coordinating session (Claude Opus 5.5) read the fix delta against each finding instead. Astra or Fable will re-check it once the limits reset.
Reviewer: Astra (GPT-6-Astra via Codex), on Paul's instruction. After-the-fact fix-delta re-check, 2026-09-24.
VERDICT: CONFIRMED — 5b397d9 → 410c41a, landed as 76dbe9b.
- Resolved; no follow-up fix needed. Below 800px the title input can shrink and Rename floats below the field. The original 390px Menu collision and 320px switcher collision are gone. In a fresh Docs aa73205 adopter built under /tmp, the extended
polish-audit/r2-chrome-check.mjspassed 591/591 with the switcher and 591/591 without, at 1440/840/800/390/320. I read the assertions: they check visible control overlap, viewport bounds and centre hit targets, including the focused title and Rename. I also clicked Rename successfully at both 390 and 320px; this is verified interaction, not just a screenshot or fixed-height assertion. - Gates and landing confirmed.
make testpassed (vet, formatting, build, uncached Go tests). Tested navigation CLS was at most 0.0027, below the 0.01 gate. The landed chrome files match the reviewed fix. Inspected the supplied focused-title and toolbar screenshots. No new defect found in this delta.
Review only: no source edits, commits, pushes or merges. The detached estilo worktree has been removed. Docs' separate Share finding is recorded on Docs #65.