fix(theme): switch navbar and home logos through pure css

Extend theme-aware logo switching to the home page hero logo, which previously never changed with the active color scheme, and keep the navbar logo switching in the same CSS-only mechanism.

Replace the header template synchronization script with theme CSS background images so logos render correctly at first paint, work with JavaScript disabled, and avoid WebKit replaced-element repaint behavior. Hide the upstream images as layout placeholders and use selectors that outrank Gitea's navbar hover styles.

Add an AGENTS.md guide documenting repository scope, theme and template constraints, verification expectations, and the manual deployment flow.
This commit is contained in:
cole-maxwell1
2026-09-07 21:57:59 -05:00
parent 8dc216d4e9
commit b21d961929
5 changed files with 119 additions and 31 deletions
+29
View File
@@ -0,0 +1,29 @@
# Repository Guide
## Scope
- This repository is a static overlay copied into Gitea's custom path; it has no local build, lint, or automated test toolchain.
- Target Gitea 1.27.x. Treat upstream theme variables and template structure as version-coupled behavior.
## Themes
- `theme-codecraftsmen-light.css` and `theme-codecraftsmen-dark.css` intentionally import Gitea-provided `theme-gitea-*.css` files that are absent from this repository.
- Keep custom themes as overrides of upstream themes so newly added Gitea defaults continue to apply.
- `theme-codecraftsmen-auto.css` selects the custom light and dark themes with `prefers-color-scheme`; verify changes in all three theme modes.
- Keep font and image URLs relative to `public/assets/css/` (`../fonts/...` and `../img/...`) because Gitea serves these files below `/assets/`.
- Preserve `gitea-theme-meta-info`, including both display name and color scheme, so Gitea can discover each theme correctly.
- Do not add overrides under `templates/base/` for branding. Replace the upstream navbar and home page logo images through theme CSS so Gitea template upgrades remain intact.
## Templates
- `templates/custom/header.tmpl` injects Plausible analytics. Every external or inline script must use `nonce="{{ctx.CspScriptNonce}}"` or Gitea's CSP will block it.
## Verification And Deployment
- There is no standalone local renderer. Validate on the target Gitea release across anonymous, authenticated, and administrator pages in light, dark, and auto modes.
- For Gitea upgrades, compare both custom palettes against the built-in light and dark themes from the exact target release before testing.
- Deployment is not automated here. After review, synchronize `public/` and `templates/` to `ansible/roles/gitea/files/theme` in the separate homelab repository.
## Assets
- The bundled fonts and logos are project-supplied and do not grant redistribution rights; do not publish or replace them without confirming the applicable licenses.
@@ -1,11 +1,53 @@
@import "./theme-codecraftsmen-light.css" (prefers-color-scheme: light);
@import "./theme-codecraftsmen-dark.css" (prefers-color-scheme: dark);
html[data-theme="codecraftsmen-auto"] #navbar #navbar-logo {
background-position: center;
background-repeat: no-repeat;
background-size: 60px 30px;
}
html[data-theme="codecraftsmen-auto"] #navbar #navbar-logo img {
visibility: hidden;
width: 60px;
height: 30px;
}
html[data-theme="codecraftsmen-auto"] .page-content.home img.logo {
display: none;
}
html[data-theme="codecraftsmen-auto"] .page-content.home .center:has(> img.logo)::before {
content: "";
display: block;
width: 220px;
height: 220px;
margin: 0 auto;
background-position: center;
background-repeat: no-repeat;
background-size: contain;
}
@media (prefers-color-scheme: light) {
html[data-theme="codecraftsmen-auto"] #navbar #navbar-logo {
background-image: url("../img/logo-light-no-slogan.svg");
}
html[data-theme="codecraftsmen-auto"] .page-content.home .center:has(> img.logo)::before {
background-image: url("../img/logo-light.svg");
}
}
@media (prefers-color-scheme: dark) {
html[data-theme="codecraftsmen-auto"] #navbar #navbar-logo {
background-image: url("../img/logo-dark-no-slogan.svg");
}
html[data-theme="codecraftsmen-auto"] .page-content.home .center:has(> img.logo)::before {
background-image: url("../img/logo-dark.svg");
}
}
gitea-theme-meta-info {
--theme-display-name: "CodeCraftsmen Auto";
--theme-color-scheme: "auto";
@@ -293,11 +293,35 @@ gitea-theme-meta-info {
--cc-font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
}
html[data-theme="codecraftsmen-dark"] #navbar #navbar-logo {
background-image: url("../img/logo-dark-no-slogan.svg");
background-position: center;
background-repeat: no-repeat;
background-size: 60px 30px;
}
html[data-theme="codecraftsmen-dark"] #navbar #navbar-logo img {
visibility: hidden;
width: 60px;
height: 30px;
}
html[data-theme="codecraftsmen-dark"] .page-content.home img.logo {
display: none;
}
html[data-theme="codecraftsmen-dark"] .page-content.home .center:has(> img.logo)::before {
content: "";
display: block;
width: 220px;
height: 220px;
margin: 0 auto;
background-image: url("../img/logo-dark.svg");
background-position: center;
background-repeat: no-repeat;
background-size: contain;
}
body,
input,
textarea,
@@ -269,11 +269,35 @@ gitea-theme-meta-info {
--cc-font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
}
html[data-theme="codecraftsmen-light"] #navbar #navbar-logo {
background-image: url("../img/logo-light-no-slogan.svg");
background-position: center;
background-repeat: no-repeat;
background-size: 60px 30px;
}
html[data-theme="codecraftsmen-light"] #navbar #navbar-logo img {
visibility: hidden;
width: 60px;
height: 30px;
}
html[data-theme="codecraftsmen-light"] .page-content.home img.logo {
display: none;
}
html[data-theme="codecraftsmen-light"] .page-content.home .center:has(> img.logo)::before {
content: "";
display: block;
width: 220px;
height: 220px;
margin: 0 auto;
background-image: url("../img/logo-light.svg");
background-position: center;
background-repeat: no-repeat;
background-size: contain;
}
body,
input,
textarea,
-31
View File
@@ -4,34 +4,3 @@
window.plausible=window.plausible||function(){(plausible.q=plausible.q||[]).push(arguments)},plausible.init=plausible.init||function(i){plausible.o=i||{}};
plausible.init()
</script>
<script nonce="{{ctx.CspScriptNonce}}">
(() => {
const darkMode = window.matchMedia("(prefers-color-scheme: dark)");
const updateNavbarLogo = () => {
const logo = document.querySelector("#navbar-logo img");
const theme = document.documentElement.dataset.theme;
if (!logo) return false;
if (!theme?.startsWith("codecraftsmen-")) return true;
const dark = theme === "codecraftsmen-dark" || (theme === "codecraftsmen-auto" && darkMode.matches);
const src = `${window.config.assetUrlPrefix}/img/logo-${dark ? "dark" : "light"}-no-slogan.svg`;
if (logo.getAttribute("src") !== src) logo.setAttribute("src", src);
return true;
};
const navbarObserver = new MutationObserver(() => {
if (updateNavbarLogo()) navbarObserver.disconnect();
});
navbarObserver.observe(document.documentElement, {childList: true, subtree: true});
document.addEventListener("DOMContentLoaded", () => {
updateNavbarLogo();
navbarObserver.disconnect();
}, {once: true});
darkMode.addEventListener("change", updateNavbarLogo);
window.addEventListener("pageshow", updateNavbarLogo);
document.addEventListener("visibilitychange", () => {
if (!document.hidden) updateNavbarLogo();
});
})();
</script>