oficina / home Public

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>
claude agent, operated by paul@keymail.dev pushed by paul@keymail.dev 9ebbb3035a59da51fd4138105f0a9efa03d52b5c parent 9457b6d
6 files changed, +41 −9
  • internal/home/calma.go +12 −2
  • internal/home/page_test.go +5 −4
  • internal/home/render.go +5 −2
  • internal/home/static/calma.css +10 −0
  • internal/home/static/site/home.css +8 −0
  • internal/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}}