{{define "layout"}} {{/* layout — every page's document: the head, the estilo bar and
. The bar is estilo's (chrome.Bar, built once per request in chrome.go), in place of the rastrillo topbar markup this file used to write out itself: that bar was 45px signed out and 51px signed in, because the Create and Import buttons were taller than it, so signing in moved the whole page. estilo's is 52px at every width, signed in or out, with the account always last in the same corner. data-theme is written into the first bytes of the response, from a cookie read server-side (chrome.Appearance). AGENTS.md: light/dark must resolve before first paint, because cell fills resolve against the theme and a late preference repaints every coloured cell. It is ABSENT for "system", and that is the mechanism, not an omission: theme.css's whole toggle is :root[data-theme="light"] and :root[data-theme="dark"], and with no attribute the browser resolves against the OS. The is built here and only here, "{part} · {part} · Sheets", so no handler can drift from the suite's separator (spec §10). <meta charset> comes first, before anything that could be read as text. The stylesheets are in the suite's fixed order: tokens, theme, brand, then estilo's base, menu and chrome, then the app's own. */}} <html lang="en" dir="ltr"{{with .Frame.Theme}} data-theme="{{.}}"{{end}}> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>{{range .Frame.TitleParts}}{{.}} · {{end}}{{.Frame.Chrome.App.Name}} {{/* First of every script: while a modal dialog is open, key and clipboard events stop at the window before any page listener hears them (static/modal.js). */}} {{iconAssets}} {{block "head" .}}{{end}} {{/* [estilo-shell] wraps every page. On the grid it is estilo-shell="fill": exactly the viewport, the bar at its 52px and the grid's
taking the rest (estilo chrome.css). That is why the grid can fill the screen without this app subtracting a bar height it would have to guess. The "main" block lets the grid page supply its own
, without rst-page's padding and max width. */}}
{{.Frame.Chrome.Labels.Skip}} {{template "estilo-bar" .Frame.Chrome}} {{block "main" .}}
{{template "content" .}}
{{end}}
{{if .Frame.Shortcuts}}{{template "shortcuts-dialog" .Frame.Keys}}{{end}} {{end}} {{/* The keyboard shortcuts, opened from the account menu's Help ("Keyboard shortcuts…"). It used to be the Help menu on the grid's menu bar, a definition list inside a dropdown; Help moved into the account menu with every other app's (spec §8.2), and a list of keys is not a menu. A native , so it sits in the top layer above the bar (spec §5.3), and it opens with the platform's invoker command, so no script is needed. The labels are this request's platform's (menu.Shortcut): ⌘Z on a Mac, Ctrl+Z elsewhere. */}} {{define "shortcuts-dialog"}}

Keyboard shortcuts

{{.undo}}
Undo your last edit
{{.bold}}
Bold
{{.italic}}
Italic
{{.cut}}
Cut
{{.copy}}
Copy
{{.paste}}
Paste
{{.filldown}}
Fill down
{{.delete}}
Clear the selected cells
{{.enter}}
Commit and move down
{{.tab}}
Commit and move right
{{.esc}}
Abandon the edit
{{end}} {{define "contrast-notice"}} {{if .}} {{/* Spec §11.1: a retained fill can be unreadable, and that is correct. We render an imported file as authored — silently correcting it would lie about the document — so the obligation that follows is to say so and leave the decision to the person. This is that, and it is deliberately a notice rather than a change to any cell. A warning (the shared chrome spec's §4): it used to say rst-callout="warn", which is no rastrillo tone, so it rendered as a neutral grey note. */}}

Imported colours below the contrast floor. These cells came from a file pairing a fill and a text colour under WCAG AA's 4.5:1: {{range $i, $ref := .}}{{if $i}}, {{end}}{{$ref}}{{end}}

They are shown exactly as the file wrote them. Changing a colour is yours to decide, not ours to do quietly.

{{end}} {{end}}