brand: put the mark on the README and in the panel

The stamp existed as files and appeared nowhere. It now opens the README, sits
at the left of the panel's navigation bar in its compact form, and stands above
the card on the two pages that carry no navigation — sign-in and first-run setup,
where it is the only thing telling an administrator which service just asked
them for a password. The tab icon moves to the stamp's small-size variant, so
the tab, the panel and the README stop being two different identities; the
earlier envelope drawing stays in docs/assets/icon.png, unreferenced.

The panel serves its own copies under internal/web/static/ because go:embed
cannot reach outside the package; the proof sheet says which file feeds which
slot. favicon.png is regenerated from the same icon at 32x32 for browsers with
no SVG favicon support, and is declared before the SVG so those that do take
the vector.

Sign-in and setup also get a column the width of their own card. Both are a
single .card.narrow, which centres itself while the heading above it stays at
the panel's left edge — with the mark added that would have been three
alignments on a page with four elements.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-04 19:24:48 +03:00
parent 322ee6c71d
commit 09abd989a1
12 changed files with 111 additions and 16 deletions
+21 -10
View File
@@ -4,7 +4,13 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{.Title}}</title>
<link rel="icon" href="/static/favicon.png" type="image/png">
{{/* The tab icon is the stamp's small-size variant — the initials rather than
the two-line wordmark, which stops resolving below 32px (the thresholds are
recorded in docs/assets/selfpost-proof.html). The PNG is declared first and
the SVG second: a browser takes the last icon whose type it understands, so
vector wins wherever it is supported and the raster catches the rest. */}}
<link rel="icon" href="/static/favicon.png" sizes="32x32">
<link rel="icon" href="/static/favicon.svg" type="image/svg+xml">
<link rel="stylesheet" href="/static/panel.css">
{{/* Unless told otherwise, htmx injects a stylesheet element of its own into
the head for the request-indicator classes. The panel uses no
@@ -40,15 +46,20 @@
.User and get no nav. */}}
{{define "nav"}}
<nav class="nav">
{{/* The session block is first here because it is drawn first: it is the top
row of the bar (see .nav in panel.css), and putting it first in the
document keeps the tab order matching the visual one. */}}
<div class="session">
<span class="muted">{{.User}}</span>
{{if eq .Active "account"}}<span aria-current="page">{{template "icon-account"}}Account</span>{{else}}<a href="/account">{{template "icon-account"}}Account</a>{{end}}
<form class="inline" method="post" action="/logout">
<button type="submit" class="danger">{{template "icon-sign-out"}}Sign out</button>
</form>
{{/* The top row is first here because it is drawn first (see .nav in
panel.css), which keeps the tab order matching the visual one. It holds
the mark on the left and the session block on the right; the page entries
follow underneath. The mark goes to /status, the page the panel opens on —
named outright rather than as "/", which is only a redirect to it. */}}
<div class="top">
<a class="brand" href="/status"><img src="/static/logo-compact.svg" width="110" height="50" alt="SelfPost"></a>
<div class="session">
<span class="muted">{{.User}}</span>
{{if eq .Active "account"}}<span aria-current="page">{{template "icon-account"}}Account</span>{{else}}<a href="/account">{{template "icon-account"}}Account</a>{{end}}
<form class="inline" method="post" action="/logout">
<button type="submit" class="danger">{{template "icon-sign-out"}}Sign out</button>
</form>
</div>
</div>
<div class="links">
{{if eq .Active "status"}}<span aria-current="page">{{template "icon-status"}}Status</span>{{else}}<a href="/status">{{template "icon-status"}}Status</a>{{end}}
+4
View File
@@ -1,4 +1,8 @@
{{define "content"}}
{{/* The full mark, on the two pages that carry no navigation: with no bar above
it, this is the only thing telling an administrator which service just asked
them for a password. */}}
<img class="mark" src="/static/logo.svg" width="330" height="150" alt="SelfPost">
<h1>Sign in</h1>
<div class="card narrow">
{{if .SetupHint}}
+1
View File
@@ -1,4 +1,5 @@
{{define "content"}}
<img class="mark" src="/static/logo.svg" width="330" height="150" alt="SelfPost">
<h1>Create administrator</h1>
<div class="card narrow">
<p class="muted">This one-time link creates the single panel administrator.