Answer the review (Claude Fable 5.1, discussion 75)
- Dark contrast: the muted hero lead and home lede fell to 1.8-3.6:1 on the dark sky's brightest band. In dark the sky is quieter on Home (strength 0.32) and that text is full-strength. - The Docs chooser, empty and unavailable pages are on the way in, so they take the door card too. - Hop pages (assertion, docs_continue) draw no sky: nothing fetched for a page on screen for a moment. - The <br> test's comment describes the page it guards now.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 files changed,
+41
−9
internal/home/calma.go+12 −2internal/home/page_test.go+5 −4internal/home/render.go+5 −2internal/home/static/calma.css+10 −0internal/home/static/site/home.css+8 −0internal/home/templates/layout.html+1 −1
CI passed — run details
CI log
amadan: .amadan/timeout: this job's budget is 15m0s (this runner allows up to 30m0s) === vet === CGO_ENABLED=0 go vet ./... cd handoff && CGO_ENABLED=0 go vet ./... cd roster && CGO_ENABLED=0 go vet ./... cd connect && CGO_ENABLED=0 go vet ./... === fmt === === build === CGO_ENABLED=0 go build ./... CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build ./cmd/home ./cmd/oficina ./internal/operatorlaunch cd handoff && CGO_ENABLED=0 go build ./... cd roster && CGO_ENABLED=0 go build ./... cd connect && CGO_ENABLED=0 go build ./... === go-test === CGO_ENABLED=0 go test -count=1 ./... ? amadan.net/oficina/home/cmd/home [no test files] ok amadan.net/oficina/home/cmd/home-placeholder 0.502s ? amadan.net/oficina/home/cmd/oficina [no test files] ok amadan.net/oficina/home/internal/guardstest 0.023s ok amadan.net/oficina/home/internal/home 7.827s ok amadan.net/oficina/home/internal/home/directorydata 0.941s ok amadan.net/oficina/home/internal/home/logtest 0.004s ok amadan.net/oficina/home/internal/home/seal 0.003s ok amadan.net/oficina/home/internal/home/sealtest 0.004s ok amadan.net/oficina/home/internal/operator 4.976s ok amadan.net/oficina/home/internal/operatorlaunch 4.137s ok amadan.net/oficina/home/internal/provisioner 35.273s cd handoff && CGO_ENABLED=0 go test -count=1 ./... ok amadan.net/oficina/home/handoff 0.303s ok amadan.net/oficina/home/handoff/seal 0.002s cd roster && CGO_ENABLED=0 go test -count=1 ./... ok amadan.net/oficina/home/roster 5.073s cd connect && CGO_ENABLED=0 go test -count=1 ./... ok amadan.net/oficina/home/connect 0.056s ok amadan.net/oficina/home/connect/linkstore 0.167s === race === go test -race -count=1 ./internal/home/ ./internal/operator/ ./internal/operatorlaunch/ ./internal/provisioner/ ./internal/home/directorydata/ ok amadan.net/oficina/home/internal/home 93.028s ok amadan.net/oficina/home/internal/operator 64.010s ok amadan.net/oficina/home/internal/operatorlaunch 22.303s ok amadan.net/oficina/home/internal/provisioner 263.489s ok amadan.net/oficina/home/internal/home/directorydata 14.898s cd handoff && CGO_ENABLED=1 go test -race -count=1 ./... ok amadan.net/oficina/home/handoff 8.919s ok amadan.net/oficina/home/handoff/seal 1.008s cd roster && CGO_ENABLED=1 go test -race -count=1 ./... ok amadan.net/oficina/home/roster 6.561s cd connect && CGO_ENABLED=1 go test -race -count=1 ./... ok amadan.net/oficina/home/connect 1.595s ok amadan.net/oficina/home/connect/linkstore 3.638s
diff --git a/internal/home/calma.go b/internal/home/calma.go| index cde7f97..863c937 100644 |
| --- a/internal/home/calma.go |
| +++ b/internal/home/calma.go |
| @@ -28,8 +28,8 @@ var homeFuncs = map[string]any{ |
| // way in or out. The layout draws them as one card on the sky with the |
| // Oficina mark, as Calma's sign-in does; every other page keeps the full |
| // width (the directory lists apps; credits is a long page of notices). |
| -// Not assertion.html: it submits itself mid-hop and hides its own copy |
| -// for 1.5 s so nothing flashes; a card and a mark would flash anyway. |
| +// Not assertion.html or docs_continue.html: they are hops, on screen for |
| +// a moment, so they draw neither the card nor the sky (hopPages). |
| var doorPages = map[string]bool{ |
| "signin.html": true, |
| "check_your_mail.html": true, |
| @@ -41,6 +41,16 @@ var doorPages = map[string]bool{ |
| "handoff_failed.html": true, |
| "signout_confirm.html": true, |
| "directory_signed_out.html": true, |
| + "docs_chooser.html": true, |
| + "docs_empty.html": true, |
| + "docs_unavailable.html": true, |
| +} |
| + |
| +// hopPages move on by themselves (an auto-submit, a 0 s refresh): no sky, |
| +// so the slowest-feeling moment of sign-in fetches nothing it won't show. |
| +var hopPages = map[string]bool{ |
| + "assertion.html": true, |
| + "docs_continue.html": true, |
| } |
| // mountCalma serves the Calma pieces Home's pages link: Onest, the sky's |
diff --git a/internal/home/page_test.go b/internal/home/page_test.go| index 0ba3d48..b79c7f2 100644 |
| --- a/internal/home/page_test.go |
| +++ b/internal/home/page_test.go |
| @@ -9,10 +9,11 @@ import ( |
| "amadan.net/oficina/estilo.git/theme" |
| ) |
| -// TestFrontPageLineBreaksKeepTheirSpace: home.css hides the hero's <br> on |
| -// narrow screens, so a <br> glued to words on both sides runs them together |
| -// there — "Open your newoffice suite." on every phone (polish audit, round |
| -// 1). Every <br> on the front page needs whitespace on at least one side. |
| +// TestFrontPageLineBreaksKeepTheirSpace: an earlier hero hid its <br> on |
| +// narrow screens, so a <br> glued to words on both sides ran them together |
| +// — "Open your newoffice suite." on every phone (polish audit, round 1). |
| +// The Calma hero wraps by itself and has no <br>; this stays so the next |
| +// one to come back keeps whitespace on at least one side. |
| func TestFrontPageLineBreaksKeepTheirSpace(t *testing.T) { |
| if glued := regexp.MustCompile(`\S<br\s*/?>\S`).FindAll(indexPage, -1); len(glued) > 0 { |
| t.Fatalf("front page has <br> with no whitespace beside it: %q", glued) |
diff --git a/internal/home/render.go b/internal/home/render.go| index 5494e72..6083f10 100644 |
| --- a/internal/home/render.go |
| +++ b/internal/home/render.go |
| @@ -50,8 +50,11 @@ func newRenderer() (*renderer, error) { |
| // ui.Funcs supplies the helpers rastrillo's partials call — |
| // "T" among them — so the tree must carry them before those |
| // partials are parsed, not after. |
| - isDoor := doorPages[name] |
| - t, err := template.New(name).Funcs(ui.Funcs()).Funcs(homeFuncs).Funcs(template.FuncMap{"door": func() bool { return isDoor }}).ParseFS(templatesFS, layoutFile) |
| + isDoor, isHop := doorPages[name], hopPages[name] |
| + t, err := template.New(name).Funcs(ui.Funcs()).Funcs(homeFuncs).Funcs(template.FuncMap{ |
| + "door": func() bool { return isDoor }, |
| + "hop": func() bool { return isHop }, |
| + }).ParseFS(templatesFS, layoutFile) |
| if err != nil { |
| return nil, fmt.Errorf("parse %s: %w", layoutFile, err) |
| } |
diff --git a/internal/home/static/calma.css b/internal/home/static/calma.css| index 28e556b..be2365a 100644 |
| --- a/internal/home/static/calma.css |
| +++ b/internal/home/static/calma.css |
| @@ -99,3 +99,13 @@ a[home-app]:hover { box-shadow: 0 0 0 1px var(--rst-line), var(--rst-shadow-lift |
| [home-app] b { font-weight: 620; } |
| [home-app] small { color: var(--rst-text-faint); font-size: 0.8rem; } |
| div[home-app] img { filter: saturate(0.6); opacity: 0.8; } |
| + |
| +/* In dark, the sky runs brighter (estilo's gain) and muted text on its |
| + brightest band falls under 4.5:1 (review, discussion 75). So the sky |
| + is quieter here, and text that sits on it is full-strength. */ |
| +@media (prefers-color-scheme: dark) { |
| + :root:not([data-theme="light"]) [home-sky] { --estilo-sky-strength: 0.32; } |
| + :root:not([data-theme="light"]) [home-hub-lede] { color: var(--rst-text); } |
| +} |
| +:root[data-theme="dark"] [home-sky] { --estilo-sky-strength: 0.32; } |
| +:root[data-theme="dark"] [home-hub-lede] { color: var(--rst-text); } |
diff --git a/internal/home/static/site/home.css b/internal/home/static/site/home.css| index b075cf0..47724ea 100644 |
| --- a/internal/home/static/site/home.css |
| +++ b/internal/home/static/site/home.css |
| @@ -178,6 +178,14 @@ h1, h2, h3 { text-wrap: balance; } |
| .family { grid-template-columns: 1fr; } |
| .launch-apps li { padding: 10px 4px; } |
| } |
| +/* In dark the sky runs brighter (estilo's gain) and the muted lead on its |
| + brightest band fell under 4.5:1 (review, discussion 75): the hero's sky |
| + is quieter there, and its words full-strength. */ |
| +@media (prefers-color-scheme: dark) { |
| + .hero { --estilo-sky-strength: 0.32; } |
| + .hero-lead { color: var(--rst-text); } |
| +} |
| + |
| @media (prefers-reduced-motion: reduce) { |
| .btn, .family li { transition: none; } |
| } |
diff --git a/internal/home/templates/layout.html b/internal/home/templates/layout.html| index f747b33..70a7b07 100644 |
| --- a/internal/home/templates/layout.html |
| +++ b/internal/home/templates/layout.html |
| @@ -17,7 +17,7 @@ |
| </head> |
| <body{{block "bodyattrs" .}}{{end}}> |
| <div estilo-sky-host home-sky> |
| -{{template "estilo-sky" suiteSky}} |
| +{{if not hop}}{{template "estilo-sky" suiteSky}}{{end}} |
| {{block "help" .}}{{end}} |
| <main rst-page{{if door}} home-door{{end}}> |
| {{if door}}<p estilo-brand><img estilo-brand-icon src="/static/brand/icon.svg" alt="" width="36" height="36">Oficina</p>{{end}} |