The tab's icon follows light and dark mode (#64)

The logo on the page switched with the mode (#63), but the tab's icon
was always favicon.png, the light logo. web/favicon-dark.png is
logo-dark.svg at 128px, served beside it, and the theme script points
the icon link at whichever matches data-mode, so it follows the theme
the account chose, not only the system. The sign-in page, with no
account, picks by the system's with two media-bound links.
/favicon.ico, which a browser asks for on its own, stays the light one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-28 18:12:11 +00:00
parent f9c9c2b7cc
commit d8db785681
9 changed files with 22 additions and 6 deletions

View File

@@ -71,6 +71,7 @@ pub fn router(state: WebState) -> Router {
.route("/logo-dark.svg", get(logo_dark))
.route("/favicon.ico", get(favicon))
.route("/favicon.png", get(favicon))
.route("/favicon-dark.png", get(favicon_dark))
.route("/apple-touch-icon.png", get(touch_icon))
.route("/app.js", get(app_js))
.route("/app.css", get(app_css))
@@ -589,6 +590,14 @@ async fn favicon() -> impl IntoResponse {
)
}
/// web/logo-dark.svg at 128px, the tab's icon while the page is dark.
async fn favicon_dark() -> impl IntoResponse {
(
[(header::CONTENT_TYPE, "image/png"), (header::CACHE_CONTROL, "max-age=86400")],
include_bytes!("../web/favicon-dark.png").as_slice(),
)
}
/// web/logo.svg at 180px, for an iPhone's home screen. It is opaque edge to edge, as iOS paints
/// a transparent icon's background black and cuts its own corners.
async fn touch_icon() -> impl IntoResponse {