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:
@@ -5,8 +5,27 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); version
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- The project's mark is now in use rather than only on file. The README opens
|
||||||
|
with the full stamp; the panel carries the compact one at the left of its
|
||||||
|
navigation bar, linking to the status page, and the full one above the card
|
||||||
|
on the two pages that have no navigation — sign-in and first-run setup. The
|
||||||
|
browser tab icon changes with it, from the earlier envelope drawing to the
|
||||||
|
stamp's small-size variant, so the tab, the panel and the README are one
|
||||||
|
identity. The four brand files in `docs/assets/` had their wordmark converted
|
||||||
|
from live text to outlines: they were set in IBM Plex Sans, which is not
|
||||||
|
installed on the machines that render them, and the light/semibold contrast
|
||||||
|
between *Self* and *Post* — the whole of the mark — collapsed into whatever
|
||||||
|
fallback the viewer happened to have.
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
- panel: the sign-in and setup pages are now a column the width of their own
|
||||||
|
card. Both are a single narrow card, which centred itself while the heading
|
||||||
|
above it stayed at the panel's left edge; adding the mark would have made
|
||||||
|
that three alignments on a page with four elements.
|
||||||
|
|
||||||
- panel: the three monitoring pages — Deliveries, Mail queue, System log — are
|
- panel: the three monitoring pages — Deliveries, Mail queue, System log — are
|
||||||
now laid out wider (64rem against the 48rem the rest of the panel keeps).
|
now laid out wider (64rem against the 48rem the rest of the panel keeps).
|
||||||
They carry data rather than prose: the send-log's seven columns had no room
|
They carry data rather than prose: the send-log's seven columns had no room
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|

|
||||||
|
|
||||||
# SelfPost
|
# SelfPost
|
||||||
|
|
||||||
Self-hosted outbound SMTP relay with a web control panel, shipped as a single
|
Self-hosted outbound SMTP relay with a web control panel, shipped as a single
|
||||||
|
|||||||
@@ -98,6 +98,7 @@ func (s *Server) handleLogin(w http.ResponseWriter, r *http.Request) {
|
|||||||
// a failing form.
|
// a failing form.
|
||||||
s.render(w, http.StatusOK, "login", map[string]any{
|
s.render(w, http.StatusOK, "login", map[string]any{
|
||||||
"Title": "SelfPost — Sign in",
|
"Title": "SelfPost — Sign in",
|
||||||
|
"Active": "login",
|
||||||
"SetupHint": true,
|
"SetupHint": true,
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
@@ -115,9 +116,13 @@ func (s *Server) handleLogin(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) renderLogin(w http.ResponseWriter, status int, formErr string) {
|
func (s *Server) renderLogin(w http.ResponseWriter, status int, formErr string) {
|
||||||
|
// Active names the page for the layout even though no navigation is drawn
|
||||||
|
// here: it is what puts page-login on <main>, which the stylesheet uses to
|
||||||
|
// give the signed-out pages a column the width of their own card.
|
||||||
s.render(w, status, "login", map[string]any{
|
s.render(w, status, "login", map[string]any{
|
||||||
"Title": "SelfPost — Sign in",
|
"Title": "SelfPost — Sign in",
|
||||||
"Error": formErr,
|
"Active": "login",
|
||||||
|
"Error": formErr,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,9 +42,10 @@ func (s *Server) handleSetup(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
func (s *Server) renderSetupForm(w http.ResponseWriter, status int, token, formErr string) {
|
func (s *Server) renderSetupForm(w http.ResponseWriter, status int, token, formErr string) {
|
||||||
s.render(w, status, "setup", map[string]any{
|
s.render(w, status, "setup", map[string]any{
|
||||||
"Title": "SelfPost — Create administrator",
|
"Title": "SelfPost — Create administrator",
|
||||||
"Token": token,
|
"Active": "setup",
|
||||||
"Error": formErr,
|
"Token": token,
|
||||||
|
"Error": formErr,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 1.6 KiB |
@@ -0,0 +1,8 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64" role="img" aria-label="SelfPost">
|
||||||
|
<!-- SelfPost · https://codeberg.org/mix/selfpost · AGPL-3.0
|
||||||
|
Wordmark set in IBM Plex Sans (OFL) and converted to outlines: the
|
||||||
|
file needs no font installed to render as drawn. -->
|
||||||
|
<path d="M7.80 5.00 L13.00 5.00 A2.8 2.8 0 0 0 18.60 5.00 L23.80 5.00 A2.8 2.8 0 0 0 29.40 5.00 L34.60 5.00 A2.8 2.8 0 0 0 40.20 5.00 L45.40 5.00 A2.8 2.8 0 0 0 51.00 5.00 L56.20 5.00 A2.8 2.8 0 0 0 59.00 7.80 L59.00 13.00 A2.8 2.8 0 0 0 59.00 18.60 L59.00 23.80 A2.8 2.8 0 0 0 59.00 29.40 L59.00 34.60 A2.8 2.8 0 0 0 59.00 40.20 L59.00 45.40 A2.8 2.8 0 0 0 59.00 51.00 L59.00 56.20 A2.8 2.8 0 0 0 56.20 59.00 L51.00 59.00 A2.8 2.8 0 0 0 45.40 59.00 L40.20 59.00 A2.8 2.8 0 0 0 34.60 59.00 L29.40 59.00 A2.8 2.8 0 0 0 23.80 59.00 L18.60 59.00 A2.8 2.8 0 0 0 13.00 59.00 L7.80 59.00 A2.8 2.8 0 0 0 5.00 56.20 L5.00 51.00 A2.8 2.8 0 0 0 5.00 45.40 L5.00 40.20 A2.8 2.8 0 0 0 5.00 34.60 L5.00 29.40 A2.8 2.8 0 0 0 5.00 23.80 L5.00 18.60 A2.8 2.8 0 0 0 5.00 13.00 L5.00 7.80 A2.8 2.8 0 0 0 7.80 5.00 Z" fill="#F3EDE1" stroke="#12161C" stroke-width="0.8" stroke-linejoin="round" />
|
||||||
|
<rect x="11" y="11" width="42" height="42" fill="#7A3B2E" />
|
||||||
|
<path d="M24.71 43.31Q22.47 43.31 21.01 42.47Q19.56 41.62 18.54 40.3L19.27 39.72Q20.23 40.97 21.49 41.71Q22.76 42.45 24.73 42.45Q26.99 42.45 28.23 41.39Q29.46 40.32 29.46 38.32Q29.46 36.94 28.94 36.15Q28.42 35.36 27.51 34.94Q26.6 34.52 25.49 34.29L23.74 33.95Q21.95 33.61 20.92 32.93Q19.9 32.24 19.44 31.29Q18.99 30.34 18.99 29.22Q18.99 27.63 19.69 26.59Q20.39 25.55 21.66 25.05Q22.94 24.54 24.63 24.54Q26.66 24.54 28.01 25.24Q29.36 25.94 30.14 27.11L29.41 27.66Q28.63 26.54 27.46 25.97Q26.29 25.4 24.58 25.4Q22.42 25.4 21.18 26.33Q19.95 27.27 19.95 29.19Q19.95 30.47 20.48 31.23Q21.01 32 21.92 32.42Q22.83 32.83 23.95 33.07L25.69 33.41Q27.54 33.74 28.57 34.46Q29.59 35.17 30 36.15Q30.4 37.12 30.4 38.24Q30.4 39.91 29.71 41.02Q29.02 42.14 27.73 42.73Q26.45 43.31 24.71 43.31Z M36.45 43H33.01V24.85H41.18Q42.87 24.85 44.06 25.55Q45.26 26.26 45.91 27.52Q46.56 28.78 46.56 30.47Q46.56 32.16 45.91 33.42Q45.26 34.68 44.06 35.38Q42.87 36.08 41.18 36.08H36.45ZM36.45 27.84V33.12H40.87Q41.54 33.12 42.01 32.87Q42.48 32.63 42.74 32.17Q43 31.72 43 31.07V29.87Q43 29.19 42.74 28.75Q42.48 28.31 42.01 28.08Q41.54 27.84 40.87 27.84Z" fill="#F6EDE2" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.3 KiB |
@@ -0,0 +1,8 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 220 100" width="220" height="100" role="img" aria-label="SelfPost">
|
||||||
|
<!-- SelfPost · https://codeberg.org/mix/selfpost · AGPL-3.0
|
||||||
|
Wordmark set in IBM Plex Sans (OFL) and converted to outlines: the
|
||||||
|
file needs no font installed to render as drawn. -->
|
||||||
|
<path d="M10.20 8.00 L12.83 8.00 A2.2 2.2 0 0 0 17.23 8.00 L19.87 8.00 A2.2 2.2 0 0 0 24.27 8.00 L26.90 8.00 A2.2 2.2 0 0 0 31.30 8.00 L33.94 8.00 A2.2 2.2 0 0 0 38.34 8.00 L40.97 8.00 A2.2 2.2 0 0 0 45.37 8.00 L48.01 8.00 A2.2 2.2 0 0 0 52.41 8.00 L55.04 8.00 A2.2 2.2 0 0 0 59.44 8.00 L62.08 8.00 A2.2 2.2 0 0 0 66.48 8.00 L69.11 8.00 A2.2 2.2 0 0 0 73.51 8.00 L76.14 8.00 A2.2 2.2 0 0 0 80.54 8.00 L83.18 8.00 A2.2 2.2 0 0 0 87.58 8.00 L90.21 8.00 A2.2 2.2 0 0 0 94.61 8.00 L97.25 8.00 A2.2 2.2 0 0 0 101.65 8.00 L104.28 8.00 A2.2 2.2 0 0 0 108.68 8.00 L111.32 8.00 A2.2 2.2 0 0 0 115.72 8.00 L118.35 8.00 A2.2 2.2 0 0 0 122.75 8.00 L125.39 8.00 A2.2 2.2 0 0 0 129.79 8.00 L132.42 8.00 A2.2 2.2 0 0 0 136.82 8.00 L139.46 8.00 A2.2 2.2 0 0 0 143.86 8.00 L146.49 8.00 A2.2 2.2 0 0 0 150.89 8.00 L153.52 8.00 A2.2 2.2 0 0 0 157.92 8.00 L160.56 8.00 A2.2 2.2 0 0 0 164.96 8.00 L167.59 8.00 A2.2 2.2 0 0 0 171.99 8.00 L174.63 8.00 A2.2 2.2 0 0 0 179.03 8.00 L181.66 8.00 A2.2 2.2 0 0 0 186.06 8.00 L188.70 8.00 A2.2 2.2 0 0 0 193.10 8.00 L195.73 8.00 A2.2 2.2 0 0 0 200.13 8.00 L202.77 8.00 A2.2 2.2 0 0 0 207.17 8.00 L209.80 8.00 A2.2 2.2 0 0 0 212.00 10.20 L212.00 12.80 A2.2 2.2 0 0 0 212.00 17.20 L212.00 19.80 A2.2 2.2 0 0 0 212.00 24.20 L212.00 26.80 A2.2 2.2 0 0 0 212.00 31.20 L212.00 33.80 A2.2 2.2 0 0 0 212.00 38.20 L212.00 40.80 A2.2 2.2 0 0 0 212.00 45.20 L212.00 47.80 A2.2 2.2 0 0 0 212.00 52.20 L212.00 54.80 A2.2 2.2 0 0 0 212.00 59.20 L212.00 61.80 A2.2 2.2 0 0 0 212.00 66.20 L212.00 68.80 A2.2 2.2 0 0 0 212.00 73.20 L212.00 75.80 A2.2 2.2 0 0 0 212.00 80.20 L212.00 82.80 A2.2 2.2 0 0 0 212.00 87.20 L212.00 89.80 A2.2 2.2 0 0 0 209.80 92.00 L207.17 92.00 A2.2 2.2 0 0 0 202.77 92.00 L200.13 92.00 A2.2 2.2 0 0 0 195.73 92.00 L193.10 92.00 A2.2 2.2 0 0 0 188.70 92.00 L186.06 92.00 A2.2 2.2 0 0 0 181.66 92.00 L179.03 92.00 A2.2 2.2 0 0 0 174.63 92.00 L171.99 92.00 A2.2 2.2 0 0 0 167.59 92.00 L164.96 92.00 A2.2 2.2 0 0 0 160.56 92.00 L157.92 92.00 A2.2 2.2 0 0 0 153.52 92.00 L150.89 92.00 A2.2 2.2 0 0 0 146.49 92.00 L143.86 92.00 A2.2 2.2 0 0 0 139.46 92.00 L136.82 92.00 A2.2 2.2 0 0 0 132.42 92.00 L129.79 92.00 A2.2 2.2 0 0 0 125.39 92.00 L122.75 92.00 A2.2 2.2 0 0 0 118.35 92.00 L115.72 92.00 A2.2 2.2 0 0 0 111.32 92.00 L108.68 92.00 A2.2 2.2 0 0 0 104.28 92.00 L101.65 92.00 A2.2 2.2 0 0 0 97.25 92.00 L94.61 92.00 A2.2 2.2 0 0 0 90.21 92.00 L87.58 92.00 A2.2 2.2 0 0 0 83.18 92.00 L80.54 92.00 A2.2 2.2 0 0 0 76.14 92.00 L73.51 92.00 A2.2 2.2 0 0 0 69.11 92.00 L66.48 92.00 A2.2 2.2 0 0 0 62.08 92.00 L59.44 92.00 A2.2 2.2 0 0 0 55.04 92.00 L52.41 92.00 A2.2 2.2 0 0 0 48.01 92.00 L45.37 92.00 A2.2 2.2 0 0 0 40.97 92.00 L38.34 92.00 A2.2 2.2 0 0 0 33.94 92.00 L31.30 92.00 A2.2 2.2 0 0 0 26.90 92.00 L24.27 92.00 A2.2 2.2 0 0 0 19.87 92.00 L17.23 92.00 A2.2 2.2 0 0 0 12.83 92.00 L10.20 92.00 A2.2 2.2 0 0 0 8.00 89.80 L8.00 87.20 A2.2 2.2 0 0 0 8.00 82.80 L8.00 80.20 A2.2 2.2 0 0 0 8.00 75.80 L8.00 73.20 A2.2 2.2 0 0 0 8.00 68.80 L8.00 66.20 A2.2 2.2 0 0 0 8.00 61.80 L8.00 59.20 A2.2 2.2 0 0 0 8.00 54.80 L8.00 52.20 A2.2 2.2 0 0 0 8.00 47.80 L8.00 45.20 A2.2 2.2 0 0 0 8.00 40.80 L8.00 38.20 A2.2 2.2 0 0 0 8.00 33.80 L8.00 31.20 A2.2 2.2 0 0 0 8.00 26.80 L8.00 24.20 A2.2 2.2 0 0 0 8.00 19.80 L8.00 17.20 A2.2 2.2 0 0 0 8.00 12.80 L8.00 10.20 A2.2 2.2 0 0 0 10.20 8.00 Z" fill="#F3EDE1" stroke="#12161C" stroke-width="0.7" stroke-linejoin="round" />
|
||||||
|
<rect x="15" y="15" width="190" height="70" fill="#7A3B2E" />
|
||||||
|
<path d="M61.06 66.41Q58.14 66.41 56.23 65.3Q54.33 64.2 53 62.46L53.96 61.72Q55.21 63.35 56.86 64.32Q58.51 65.29 61.1 65.29Q64.05 65.29 65.67 63.89Q67.28 62.5 67.28 59.88Q67.28 58.08 66.6 57.04Q65.92 56 64.73 55.46Q63.54 54.92 62.08 54.61L59.8 54.17Q57.46 53.73 56.12 52.83Q54.77 51.92 54.18 50.68Q53.58 49.44 53.58 47.98Q53.58 45.91 54.5 44.55Q55.42 43.19 57.08 42.52Q58.75 41.86 60.96 41.86Q63.61 41.86 65.38 42.78Q67.15 43.7 68.17 45.23L67.22 45.94Q66.2 44.48 64.67 43.73Q63.14 42.98 60.89 42.98Q58.07 42.98 56.46 44.21Q54.84 45.43 54.84 47.95Q54.84 49.61 55.54 50.61Q56.23 51.62 57.42 52.16Q58.61 52.71 60.08 53.01L62.35 53.45Q64.77 53.9 66.11 54.83Q67.45 55.77 67.98 57.04Q68.51 58.32 68.51 59.78Q68.51 61.95 67.61 63.42Q66.71 64.88 65.02 65.64Q63.34 66.41 61.06 66.41Z M78.56 66.41Q76.28 66.41 74.64 65.35Q72.99 64.3 72.09 62.29Q71.18 60.29 71.18 57.36Q71.18 54.44 72.07 52.42Q72.95 50.39 74.57 49.36Q76.18 48.32 78.46 48.32Q80.57 48.32 82.17 49.37Q83.76 50.43 84.67 52.35Q85.57 54.27 85.57 56.89V57.43H72.44V58.35Q72.44 61.51 74.06 63.43Q75.67 65.35 78.6 65.35Q80.64 65.35 82.08 64.35Q83.53 63.35 84.27 61.41L85.19 61.92Q84.44 63.96 82.74 65.18Q81.04 66.41 78.56 66.41ZM78.46 49.34Q76.56 49.34 75.21 50.21Q73.87 51.07 73.16 52.66Q72.44 54.24 72.44 56.34V56.48H84.27V56.28Q84.27 54.17 83.54 52.62Q82.81 51.07 81.5 50.21Q80.19 49.34 78.46 49.34Z M93.72 66H91.17Q90.42 66 90.06 65.63Q89.7 65.25 89.7 64.57V40.84H90.89V64.95H93.72Z M97.92 66V49.78H94.83V48.73H97.92V42.57Q97.92 41.76 98.33 41.3Q98.74 40.84 99.59 40.84H102.99V41.89H99.11V48.73H102.99V49.78H99.11V66Z M109.88 66H105.39V42.27H116.07Q118.28 42.27 119.84 43.19Q121.41 44.1 122.26 45.75Q123.11 47.4 123.11 49.61Q123.11 51.82 122.26 53.47Q121.41 55.12 119.84 56.04Q118.28 56.96 116.07 56.96H109.88ZM109.88 46.18V53.08H115.66Q116.55 53.08 117.16 52.76Q117.77 52.43 118.11 51.84Q118.45 51.24 118.45 50.39V48.83Q118.45 47.95 118.11 47.37Q117.77 46.79 117.16 46.48Q116.55 46.18 115.66 46.18Z M132.75 66.41Q130.24 66.41 128.38 65.27Q126.53 64.13 125.53 62.04Q124.53 59.95 124.53 57.09Q124.53 54.24 125.53 52.18Q126.53 50.12 128.38 48.98Q130.24 47.84 132.75 47.84Q135.3 47.84 137.16 48.98Q139.01 50.12 140.01 52.18Q141.02 54.24 141.02 57.09Q141.02 59.95 140.01 62.04Q139.01 64.13 137.16 65.27Q135.3 66.41 132.75 66.41ZM132.75 62.91Q134.49 62.91 135.47 61.83Q136.46 60.76 136.46 58.76V55.46Q136.46 53.45 135.47 52.4Q134.49 51.35 132.75 51.35Q131.09 51.35 130.08 52.4Q129.08 53.45 129.08 55.46V58.76Q129.08 60.76 130.08 61.83Q131.09 62.91 132.75 62.91Z M149.47 66.41Q146.92 66.41 145.19 65.54Q143.45 64.67 142.13 63.14L144.78 60.56Q145.77 61.68 146.94 62.33Q148.11 62.97 149.64 62.97Q151.21 62.97 151.9 62.43Q152.6 61.89 152.6 60.93Q152.6 60.15 152.11 59.69Q151.61 59.23 150.42 59.06L148.66 58.83Q146.75 58.59 145.43 57.94Q144.1 57.3 143.42 56.17Q142.74 55.05 142.74 53.45Q142.74 50.87 144.59 49.36Q146.45 47.84 149.47 47.84Q151.21 47.84 152.45 48.17Q153.69 48.49 154.64 49.12Q155.59 49.75 156.41 50.63L153.86 53.18Q153.08 52.37 151.99 51.82Q150.9 51.28 149.61 51.28Q148.25 51.28 147.58 51.77Q146.92 52.26 146.92 53.11Q146.92 54 147.45 54.46Q147.98 54.92 149.23 55.12L151.04 55.36Q153.96 55.77 155.37 57.08Q156.78 58.38 156.78 60.59Q156.78 62.29 155.88 63.62Q154.98 64.95 153.33 65.68Q151.68 66.41 149.47 66.41Z M168.09 66H164.97Q162.72 66 161.55 64.83Q160.38 63.65 160.38 61.48V51.69H157.76V48.25H159.12Q160.1 48.25 160.46 47.79Q160.82 47.33 160.82 46.42V43.39H164.73V48.25H168.37V51.69H164.73V62.53H168.09Z" fill="#F6EDE2" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 7.1 KiB |
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 13 KiB |
@@ -17,6 +17,13 @@ body {
|
|||||||
}
|
}
|
||||||
main { max-width: 42rem; margin: 0 auto; }
|
main { max-width: 42rem; margin: 0 auto; }
|
||||||
h1 { font-size: 1.4rem; margin: 0 0 1rem; }
|
h1 { font-size: 1.4rem; margin: 0 0 1rem; }
|
||||||
|
/* The full mark, on the two pages that have no navigation bar to carry the
|
||||||
|
compact one. It takes the column's width so its edges line up with the card
|
||||||
|
below it, capped at that column's own 24rem; height stays automatic because
|
||||||
|
the stamp's proportions are part of the mark and it is never scaled unevenly.
|
||||||
|
The subtitle stops resolving below 280px, which a 320px viewport still clears
|
||||||
|
once the body's padding is taken off. */
|
||||||
|
.mark { display: block; width: 100%; max-width: 24rem; height: auto; margin-bottom: 1.4rem; }
|
||||||
.card {
|
.card {
|
||||||
background: #fff; border: 1px solid #e2e5e9; border-radius: 10px;
|
background: #fff; border: 1px solid #e2e5e9; border-radius: 10px;
|
||||||
padding: 1.5rem; margin: 0 auto;
|
padding: 1.5rem; margin: 0 auto;
|
||||||
@@ -58,6 +65,13 @@ main { max-width: 48rem; }
|
|||||||
every second line. They get a wider measure; every other page keeps the narrow
|
every second line. They get a wider measure; every other page keeps the narrow
|
||||||
one. The class comes from the layout, which stamps the page name onto <main>. */
|
one. The class comes from the layout, which stamps the page name onto <main>. */
|
||||||
main.page-deliveries, main.page-mail_queue, main.page-system_log { max-width: 64rem; }
|
main.page-deliveries, main.page-mail_queue, main.page-system_log { max-width: 64rem; }
|
||||||
|
/* The signed-out pages are a single card and nothing else, and .card.narrow
|
||||||
|
centres itself inside whatever holds it — so at the panel's usual width the
|
||||||
|
card floated in the middle while the mark and the heading stayed at the far
|
||||||
|
left, three alignments on a page with four elements. Narrowing the column to
|
||||||
|
the card's own width makes the three line up and puts the block as a whole in
|
||||||
|
the middle of the page. */
|
||||||
|
main.page-login, main.page-setup { max-width: 24rem; }
|
||||||
.card + .card { margin-top: 1.2rem; }
|
.card + .card { margin-top: 1.2rem; }
|
||||||
.flash { background: #ecfdf3; border: 1px solid #abefc6; color: #067647; padding: 0.7rem 1rem; border-radius: 8px; margin-bottom: 1.2rem; }
|
.flash { background: #ecfdf3; border: 1px solid #abefc6; color: #067647; padding: 0.7rem 1rem; border-radius: 8px; margin-bottom: 1.2rem; }
|
||||||
@media (prefers-color-scheme: dark) { .flash { background: #0d2818 !important; border-color: #1a5336 !important; color: #75d99b !important; } }
|
@media (prefers-color-scheme: dark) { .flash { background: #0d2818 !important; border-color: #1a5336 !important; color: #75d99b !important; } }
|
||||||
@@ -149,9 +163,21 @@ details form { margin-top: 0.6rem; }
|
|||||||
}
|
}
|
||||||
@media (prefers-color-scheme: dark) { .nav { border-color: #2b3138 !important; } }
|
@media (prefers-color-scheme: dark) { .nav { border-color: #2b3138 !important; } }
|
||||||
.nav .links, .nav .session { display: flex; flex-wrap: wrap; gap: 0.2rem 0.9rem; align-items: center; }
|
.nav .links, .nav .session { display: flex; flex-wrap: wrap; gap: 0.2rem 0.9rem; align-items: center; }
|
||||||
/* Pushed to the far edge so the two rows read as two blocks rather than as one
|
/* The top row: mark at one edge, session block at the other. Splitting them to
|
||||||
|
the edges is what makes the two rows read as two blocks rather than as one
|
||||||
ragged list that happened to wrap. */
|
ragged list that happened to wrap. */
|
||||||
|
.nav .top { display: flex; align-items: center; justify-content: space-between; gap: 0.9rem; }
|
||||||
.nav .session { justify-content: flex-end; }
|
.nav .session { justify-content: flex-end; }
|
||||||
|
/* The mark is a link, but not one of the bar's entries: it takes none of the
|
||||||
|
padding and rounding the entry rule below applies, so its own edge lines up
|
||||||
|
with the page rather than sitting half a step inside it. The stamp carries
|
||||||
|
about 4px of field inside the file at this size, which is what puts it level
|
||||||
|
with the icons of the row underneath. */
|
||||||
|
.nav .brand { padding: 0; }
|
||||||
|
/* width/height are on the element too, so the row reserves the space before the
|
||||||
|
SVG has loaded; these keep the ratio if the box is ever squeezed. The stamp's
|
||||||
|
proportions are part of the mark — it is never scaled unevenly. */
|
||||||
|
.nav .brand img { display: block; width: 110px; height: auto; }
|
||||||
/* Each entry pairs an icon with its label, so the entry itself is a flex row
|
/* Each entry pairs an icon with its label, so the entry itself is a flex row
|
||||||
rather than a run of text — that is also why the bar centres its items
|
rather than a run of text — that is also why the bar centres its items
|
||||||
instead of aligning them on the text baseline. Account is included: it is a
|
instead of aligning them on the text baseline. Account is included: it is a
|
||||||
|
|||||||
@@ -4,7 +4,13 @@
|
|||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<title>{{.Title}}</title>
|
<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">
|
<link rel="stylesheet" href="/static/panel.css">
|
||||||
{{/* Unless told otherwise, htmx injects a stylesheet element of its own into
|
{{/* Unless told otherwise, htmx injects a stylesheet element of its own into
|
||||||
the head for the request-indicator classes. The panel uses no
|
the head for the request-indicator classes. The panel uses no
|
||||||
@@ -40,15 +46,20 @@
|
|||||||
.User and get no nav. */}}
|
.User and get no nav. */}}
|
||||||
{{define "nav"}}
|
{{define "nav"}}
|
||||||
<nav class="nav">
|
<nav class="nav">
|
||||||
{{/* The session block is first here because it is drawn first: it is the top
|
{{/* The top row is first here because it is drawn first (see .nav in
|
||||||
row of the bar (see .nav in panel.css), and putting it first in the
|
panel.css), which keeps the tab order matching the visual one. It holds
|
||||||
document keeps the tab order matching the visual one. */}}
|
the mark on the left and the session block on the right; the page entries
|
||||||
<div class="session">
|
follow underneath. The mark goes to /status, the page the panel opens on —
|
||||||
<span class="muted">{{.User}}</span>
|
named outright rather than as "/", which is only a redirect to it. */}}
|
||||||
{{if eq .Active "account"}}<span aria-current="page">{{template "icon-account"}}Account</span>{{else}}<a href="/account">{{template "icon-account"}}Account</a>{{end}}
|
<div class="top">
|
||||||
<form class="inline" method="post" action="/logout">
|
<a class="brand" href="/status"><img src="/static/logo-compact.svg" width="110" height="50" alt="SelfPost"></a>
|
||||||
<button type="submit" class="danger">{{template "icon-sign-out"}}Sign out</button>
|
<div class="session">
|
||||||
</form>
|
<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>
|
||||||
<div class="links">
|
<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}}
|
{{if eq .Active "status"}}<span aria-current="page">{{template "icon-status"}}Status</span>{{else}}<a href="/status">{{template "icon-status"}}Status</a>{{end}}
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
{{define "content"}}
|
{{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>
|
<h1>Sign in</h1>
|
||||||
<div class="card narrow">
|
<div class="card narrow">
|
||||||
{{if .SetupHint}}
|
{{if .SetupHint}}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
{{define "content"}}
|
{{define "content"}}
|
||||||
|
<img class="mark" src="/static/logo.svg" width="330" height="150" alt="SelfPost">
|
||||||
<h1>Create administrator</h1>
|
<h1>Create administrator</h1>
|
||||||
<div class="card narrow">
|
<div class="card narrow">
|
||||||
<p class="muted">This one-time link creates the single panel administrator.
|
<p class="muted">This one-time link creates the single panel administrator.
|
||||||
|
|||||||
Reference in New Issue
Block a user