#63 use gf1 gl0w logo in header/footer lockup (#118)
Patch
.forge/issues/d105f27f-f406-4fc7-a286-c331e45e2f5c/issue.md+21 −0--- /dev/null+++ b/.forge/issues/d105f27f-f406-4fc7-a286-c331e45e2f5c/issue.md@@ -0,0 +1,21 @@1+---2+id: d105f27f-f406-4fc7-a286-c331e45e2f5c3+title: Use the gf1 gl0w logo in the header/footer lockup4+state: open5+labels:6+- area:render7+assignees: []8+milestone: null9+created: 2026-10-28T10:49:07.368617004Z10+updated: null11+---12+## Problem13+14+The #70 lockup still renders the gl0w brand as a monospace text placeholder (`gl0w` in a bordered box). The real gl0w mark is now available at `~/src/code/gf1/website/assets/logo.svg` (inverted-triangle G, `currentColor`).15+16+## Fix17+18+- Vendor the exact SVG as `static/gl0w.svg` and emit it in `dist/gl0w.svg`.19+- Inline the mark in the header lockup and footer brand so `currentColor` follows the dark/light theme and hover states.20+- Keep the hu13 diamond-hub logo and the `hu13 — a gl0w project` tagline.21+- Add a regression test for the gf1 viewBox/path geometry, the absence of the text placeholder, and the emitted asset.
src/build.rs+2 −0--- a/src/build.rs+++ b/src/build.rs@@ -1379,6 +1379,8 @@ pub const HEADERS_FILE: &str = "\13791379 fn write_favicon_and_manifest(out: &Path) -> Result<(), String> {13801380 let logo = include_str!("../static/logo.svg");13811381 std::fs::write(out.join("logo.svg"), logo).map_err(|e| format!("hu13: write logo.svg: {e}"))?;1382+ let gl0w = include_str!("../static/gl0w.svg");1383+ std::fs::write(out.join("gl0w.svg"), gl0w).map_err(|e| format!("hu13: write gl0w.svg: {e}"))?;13821384 let icon = include_str!("../static/favicon.svg");13831385 std::fs::write(out.join("favicon.svg"), icon)13841386 .map_err(|e| format!("hu13: write favicon.svg: {e}"))?;
src/layout.rs+5 −3--- a/src/layout.rs+++ b/src/layout.rs@@ -329,7 +329,8 @@ pub fn provenance_footer(branch: Option<&str>, short_sha: Option<&str>) -> Strin329329 }330330 }331331 format!(332- "<footer class=\"site-footer\"><div class=\"wrap\"><div class=\"footer-brand\"><a class=\"gl0w-mark\" href=\"https://gl0w.world\" rel=\"noopener\">gl0w</a><span class=\"footer-tag\">hu13 — a gl0w project</span></div><p class=\"footer-links\"><a href=\"https://gl0w.world\" rel=\"noopener\">gl0w.world</a><a href=\"/agents.html\">agents</a><a href=\"/new-issue.html\">submit</a></p><p class=\"muted footer-provenance\">{line}</p></div></footer>"332+ "<footer class=\"site-footer\"><div class=\"wrap\"><div class=\"footer-brand\"><a class=\"gl0w-mark\" href=\"https://gl0w.world\" rel=\"noopener\" aria-label=\"gl0w\">{gl0w}</a><span class=\"footer-tag\">hu13 — a gl0w project</span></div><p class=\"footer-links\"><a href=\"https://gl0w.world\" rel=\"noopener\">gl0w.world</a><a href=\"/agents.html\">agents</a><a href=\"/new-issue.html\">submit</a></p><p class=\"muted footer-provenance\">{line}</p></div></footer>",333+ gl0w = crate::logo::GL0W_SVG333334 )334335 }335336 @@ -425,11 +426,12 @@ fn page_site_inner(425426 <html lang=\"en\">\n\426427 <head>\n{head}</head>\n\427428 <body>\n\428-<header class=\"site-header\"><div class=\"wrap header-bar\"><a class=\"brand-lockup\" href=\"/\" aria-label=\"hu13 by gl0w — home\"><span class=\"gl0w-mark\" aria-hidden=\"true\">gl0w</span><span class=\"lockup-slash\" aria-hidden=\"true\">/</span><img class=\"site-logo\" src=\"/logo.svg\" alt=\"hu13 logo\" width=\"84\" height=\"28\"></a><span class=\"sep\" aria-hidden=\"true\">•</span><nav class=\"site-nav nav-scroll\" aria-label=\"Site\"><div class=\"nav-scroll-row\">{nav_active}</div></nav></div></header>\n\429+<header class=\"site-header\"><div class=\"wrap header-bar\"><a class=\"brand-lockup\" href=\"/\" aria-label=\"hu13 by gl0w — home\"><span class=\"gl0w-mark\" aria-hidden=\"true\">{gl0w}</span><span class=\"lockup-slash\" aria-hidden=\"true\">/</span><img class=\"site-logo\" src=\"/logo.svg\" alt=\"hu13 logo\" width=\"84\" height=\"28\"></a><span class=\"sep\" aria-hidden=\"true\">•</span><nav class=\"site-nav nav-scroll\" aria-label=\"Site\"><div class=\"nav-scroll-row\">{nav_active}</div></nav></div></header>\n\429430 <main class=\"wrap\">\n{body}\n</main>\n\430431 {footer}\n\431432 </body>\n\432-</html>\n"433+</html>\n",434+ gl0w = crate::logo::GL0W_SVG433435 )434436 }435437
src/logo.rs+8 −3--- a/src/logo.rs+++ b/src/logo.rs@@ -8,9 +8,10 @@88 //! the text banner lives in `static/ascii.txt` (owner block-art, 12 lines,99 //! stripped from `static/logo-ansi.txt`).1010 //!11-//! [`ASCII_ART`], [`LOGO_ANSI_RAW`], [`LOGO_SVG`], [`FAVICON_SVG`] and12-//! [`WORDMARK_SVG`] re-expose those static files for later issues (navbar13-//! #16, favicon #17, wiki README #19, agents page) with no build step.11+//! [`ASCII_ART`], [`LOGO_ANSI_RAW`], [`LOGO_SVG`], [`GL0W_SVG`],12+//! [`FAVICON_SVG`] and [`WORDMARK_SVG`] re-expose those static files for13+//! later issues (navbar #16, favicon #17, wiki README #19, agents page)14+//! with no build step.1415 //!1516 //! [`ascii_pre`] renders the banner as an escaped `<pre>` block (see1617 //! [`crate::layout::esc`]): the art itself is block glyphs plus spaces so@@ -43,6 +44,10 @@ pub const LOGO_ANSI_RAW: &str = include_str!("../static/logo-ansi.txt");4344 /// Header lockup, byte-for-byte `static/logo.svg` (mark + hu13 as <path>).4445 pub const LOGO_SVG: &str = include_str!("../static/logo.svg");4546 47+/// gl0w mark, byte-for-byte `static/gl0w.svg` (from the gf1 brand source).48+/// Inlined into the header/footer so `currentColor` follows the site theme.49+pub const GL0W_SVG: &str = include_str!("../static/gl0w.svg");50+4651 #[allow(dead_code)]4752 /// Simplified 16px favicon variant, byte-for-byte `static/favicon.svg`4853 /// (mark only, no letters — documented choice for small-size legibility).
static/gl0w.svg+4 −0--- /dev/null+++ b/static/gl0w.svg@@ -0,0 +1,4 @@1+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 357 306" role="img" aria-label="gl0w functional laboratories — inverted triangle G">2+ <!-- traced from raster master: uniform 30u weight, sheared cuts, single gap upper-right -->3+ <path fill="currentColor" d="M2,2 L355,2 L320,62 L283,63 L304,29 L52,29 L179,250 L252,120 L138,120 L154,91 L303,91 L179,305 Z"/>4+</svg>
static/style.css+3 −3--- a/static/style.css+++ b/static/style.css@@ -188,9 +188,9 @@ footer.site-footer .footer-provenance{margin:0;font-size:var(--fs-sm);text-align188188 .site-header .wrap.header-bar{display:flex;flex-wrap:nowrap;align-items:center;gap:.5rem .75rem}189189 .brand-lockup{display:inline-flex;align-items:center;gap:.5rem;flex:none;color:var(--fg);text-decoration:none;min-height:40px}190190 .brand-lockup:visited{color:var(--fg)}191-.gl0w-mark{font:600 .8rem/1 ui-monospace,SFMono-Regular,Menlo,monospace;letter-spacing:.18em;192- text-transform:lowercase;color:var(--cyan);border:1px solid var(--border);padding:.35rem .45rem}193-.brand-lockup:hover .gl0w-mark{color:var(--blue);border-color:var(--blue)}191+.gl0w-mark{display:inline-flex;align-items:center;color:var(--cyan);line-height:0;flex:none}192+.gl0w-mark svg{display:block;height:1.3rem;width:auto}193+.brand-lockup:hover .gl0w-mark,.footer-brand .gl0w-mark:hover{color:var(--blue)}194194 .lockup-slash{color:var(--border);font-weight:400}195195 .site-logo{display:block;width:auto;height:1.75rem;flex:none}196196 .hu13-word{font-weight:700;color:var(--blue)}
tests/brand.rs+24 −3--- a/tests/brand.rs+++ b/tests/brand.rs@@ -58,8 +58,20 @@ fn header_and_footer_carry_gl0w_branding() {5858 for page in ["index.html", "agents.html", "issues/index.html"] {5959 let html = std::fs::read_to_string(out.join(page)).expect(page);6060 assert!(61- html.contains("<span class=\"gl0w-mark\""),62- "{page}: gl0w mark in header"61+ html.contains("<span class=\"gl0w-mark\" aria-hidden=\"true\"><svg"),62+ "{page}: gl0w logo mark in header"63+ );64+ assert!(65+ html.contains("viewBox=\"0 0 357 306\"") && html.contains("M2,2 L355,2"),66+ "{page}: gf1 gl0w mark geometry"67+ );68+ assert!(69+ !html.contains("<span class=\"gl0w-mark\" aria-hidden=\"true\">gl0w</span>"),70+ "{page}: text placeholder replaced by logo"71+ );72+ assert!(73+ html.contains("<a class=\"gl0w-mark\" href=\"https://gl0w.world\" rel=\"noopener\" aria-label=\"gl0w\">"),74+ "{page}: footer logo links gl0w.world"6375 );6476 assert!(6577 html.contains("hu13 — a gl0w project"),@@ -105,9 +117,19 @@ fn social_card_and_meta_present() {105117 106118 #[test]107119 fn logo_has_no_baked_background() {120+ let out = build();108121 let logo =109122 std::fs::read_to_string(PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("static/logo.svg"))110123 .unwrap();124+ let gl0w =125+ std::fs::read_to_string(PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("static/gl0w.svg"))126+ .unwrap();127+ assert!(128+ gl0w.contains("viewBox=\"0 0 357 306\"") && gl0w.contains("fill=\"currentColor\""),129+ "vendored gf1 gl0w mark"130+ );131+ let built = std::fs::read_to_string(out.join("gl0w.svg")).unwrap();132+ assert_eq!(built, gl0w, "build emits the same gl0w logo");111133 assert!(!logo.contains("fill=\"#1a1b26\""), "no dark slab");112134 assert!(113135 logo.contains("@media (prefers-color-scheme:light)"),114--
Comments (0)
No comments yet.
Reviews (0)
No reviews yet.