fix(zddc-server): project landing logo links to deployment root

The project landing page at /<project> had its own hand-rolled
header with <svg class="logo"> — not the canonical app-header__logo
class, and not loading shared/logo.js. So the logo on that page was
purely decorative while every other tool's logo (in the same beta
build) was wrapped by shared/logo.js into a clickable link to
/<project>. Inconsistent and surprising — clicking the logo from
mdedit/archive/etc. takes you to project landing, but clicking the
logo on project landing did nothing.

Inline the wrap directly in the template (the page is server-
rendered, so it can't lean on shared/logo.js the way bundled tools
do):

  <a class="app-header__logo-link" href="/" title="ZDDC home">
    <svg class="app-header__logo" ...>...</svg>
  </a>

href="/" because "next up" from the project landing is the
deployment root (the project picker / landing tool).

Also rename .logo → .app-header__logo for visual consistency, and
add the matching hover/focus styles inline. The test asserts both
the wrapping anchor and the canonical class name.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
ZDDC 2026-05-10 07:46:59 -05:00
parent cf5d7c2ea6
commit 3fa2762c28
2 changed files with 29 additions and 9 deletions

View file

@ -73,10 +73,22 @@ var projectLandingTmpl = template.Must(template.New("projectLanding").Parse(`<!D
padding: 0.5rem 1rem; background: var(--bg-secondary); padding: 0.5rem 1rem; background: var(--bg-secondary);
border-bottom: 1px solid var(--border); border-bottom: 1px solid var(--border);
} }
header .logo { header .app-header__logo {
width: 26px; height: 26px; display: inline-block; vertical-align: middle; width: 26px; height: 26px; display: inline-block; vertical-align: middle;
margin-right: 0.5rem; margin-right: 0.5rem;
} }
header .app-header__logo-link {
display: inline-flex; align-items: center; text-decoration: none;
border-radius: var(--radius);
transition: opacity 0.15s, box-shadow 0.15s;
}
header .app-header__logo-link:hover .app-header__logo,
header .app-header__logo-link:focus-visible .app-header__logo {
opacity: 0.82;
}
header .app-header__logo-link:focus-visible {
outline: 2px solid var(--primary); outline-offset: 2px;
}
header .title-line { font-size: 1.05rem; font-weight: 600; } header .title-line { font-size: 1.05rem; font-weight: 600; }
header .crumb { color: var(--text-muted); font-size: 0.85rem; } header .crumb { color: var(--text-muted); font-size: 0.85rem; }
main { main {
@ -135,14 +147,16 @@ var projectLandingTmpl = template.Must(template.New("projectLanding").Parse(`<!D
<body> <body>
<header class="app-header"> <header class="app-header">
<div> <div>
<svg class="logo" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" aria-hidden="true"> <a class="app-header__logo-link" href="/" title="ZDDC home" aria-label="ZDDC home">
<rect width="64" height="64" rx="12" fill="#1e3a5f"/> <svg class="app-header__logo" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" aria-hidden="true">
<g fill="#fff"> <rect width="64" height="64" rx="12" fill="#1e3a5f"/>
<rect x="14" y="18" width="36" height="7"/> <g fill="#fff">
<polygon points="43,25 50,25 21,43 14,43"/> <rect x="14" y="18" width="36" height="7"/>
<rect x="14" y="43" width="36" height="7"/> <polygon points="43,25 50,25 21,43 14,43"/>
</g> <rect x="14" y="43" width="36" height="7"/>
</svg> </g>
</svg>
</a>
<span class="title-line">{{.Project}}</span> <span class="title-line">{{.Project}}</span>
</div> </div>
<span class="crumb">ZDDC project workspace</span> <span class="crumb">ZDDC project workspace</span>

View file

@ -69,6 +69,12 @@ func TestServeProjectLanding(t *testing.T) {
"Master Deliverables List", "Master Deliverables List",
`href="/Project-1/working"`, `href="/Project-1/working"`,
`href="/Project-1/archive/"`, `href="/Project-1/archive/"`,
// Logo wraps to the deployment root — same convention as
// shared/logo.js applies in tools (which would route here
// to /Project-1, the project landing). On the project
// landing itself, "next up" is the deployment root.
`<a class="app-header__logo-link" href="/"`,
`class="app-header__logo"`,
} { } {
if !strings.Contains(body, want) { if !strings.Contains(body, want) {
t.Errorf("body missing %q", want) t.Errorf("body missing %q", want)