feat: enhance blog layout with footer and improved navigation; add SVG icons for GitHub and Bluesky

This commit is contained in:
2026-05-11 10:23:16 +10:00
parent 0834d30e9b
commit 7091b6844e
7 changed files with 150 additions and 85 deletions

View File

@@ -247,14 +247,17 @@ class StaticBlogGenerator {
'</head>',
'<body class="blog-page">',
'<nav class="quick-links" aria-label="Primary">',
' <div class="quick-links-inner">',
this.renderHeaderLinks(),
' <a class="quick-link rss-link" href="/rss.xml" aria-label="RSS feed" title="RSS feed">',
' <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M6.18 15.64a2.18 2.18 0 0 1 2.18 2.18C8.36 19.01 7.38 20 6.18 20C4.98 20 4 19.01 4 17.82a2.18 2.18 0 0 1 2.18-2.18M4 4.44A15.56 15.56 0 0 1 19.56 20h-2.83A12.73 12.73 0 0 0 4 7.27V4.44m0 5.66a9.9 9.9 0 0 1 9.9 9.9h-2.83A7.07 7.07 0 0 0 4 12.93V10.1z"/></svg>',
' RSS',
' </a>',
' <a class="quick-link rss-link" href="/rss.xml" aria-label="RSS feed" title="RSS feed">',
' <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M6.18 15.64a2.18 2.18 0 0 1 2.18 2.18C8.36 19.01 7.38 20 6.18 20C4.98 20 4 19.01 4 17.82a2.18 2.18 0 0 1 2.18-2.18M4 4.44A15.56 15.56 0 0 1 19.56 20h-2.83A12.73 12.73 0 0 0 4 7.27V4.44m0 5.66a9.9 9.9 0 0 1 9.9 9.9h-2.83A7.07 7.07 0 0 0 4 12.93V10.1z"/></svg>',
' RSS',
' </a>',
' </div>',
'</nav>',
this.renderScrollTopBar(),
bodyHtml,
this.renderFooter(),
' <script type="module" src="/scripts/blogPage.js"></script>',
'</body>',
'</html>'
@@ -274,16 +277,37 @@ class StaticBlogGenerator {
renderScrollTopBar() {
return [
'<header class="blog-scroll-topbar" data-blog-scroll-topbar>',
' <a class="blog-scroll-logo-link" href="/" aria-label="Back to main site">',
' <img src="/logos/LogoFull.svg" alt="lit.ruv.wtf" class="blog-scroll-logo" />',
' </a>',
' <nav class="blog-scroll-links" aria-label="Scrolled navigation">',
' <div class="blog-scroll-topbar-inner">',
' <a class="blog-scroll-logo-link" href="/" aria-label="Back to main site">',
' <img src="/logos/LogoFull.svg" alt="lit.ruv.wtf" class="blog-scroll-logo" />',
' </a>',
' <nav class="blog-scroll-links" aria-label="Scrolled navigation">',
this.renderHeaderLinks(),
' </nav>',
' </nav>',
' </div>',
'</header>'
].join('\n');
}
/**
* @returns {string}
*/
renderFooter() {
return [
'<footer class="blog-footer">',
' <div class="blog-footer-inner">',
' <a href="/" class="blog-footer-logo" aria-label="Back to main site">',
' <img src="/logos/LogoFull.svg" alt="lit.ruv.wtf" class="blog-footer-logo-img" />',
' </a>',
' <div class="blog-footer-links">',
this.renderHeaderLinks(),
' </div>',
` <p class="blog-footer-copy">&copy; ${new Date().getFullYear()} lit.ruv.wtf</p>`,
' </div>',
'</footer>',
].join('\n');
}
/**
* @returns {string}
*/

View File

@@ -1,10 +1,14 @@
'use strict';
const GITHUB_SVG = '<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg>';
const BLUESKY_SVG = '<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M5.202 2.857C7.954 4.922 10.913 9.11 12 11.358c1.087-2.247 4.046-6.436 6.798-8.501C20.783 1.366 24 .213 24 3.883c0 .732-.42 6.156-.667 7.037-.856 3.061-3.978 3.842-6.755 3.37 4.854.826 6.089 3.562 3.422 6.299-5.065 5.196-7.28-1.304-7.847-2.97-.104-.305-.152-.448-.153-.327 0-.121-.05.022-.153.327-.568 1.666-2.782 8.166-7.847 2.97-2.667-2.737-1.432-5.473 3.422-6.3-2.777.473-5.899-.308-6.755-3.369C.42 10.04 0 4.615 0 3.883c0-3.67 3.217-2.517 5.202-1.026"/></svg>';
/**
* @typedef {Object} NavLink
* @property {string} label
* @property {string} href
* @property {boolean} [external]
* @property {string} [svg] - Inline SVG string shown instead of label text.
*/
/** @type {NavLink[]} */
@@ -12,9 +16,9 @@ const NAV_LINKS = [
{ label: 'home', href: '/' },
{ label: 'blog', href: '/blog.html' },
{ label: 'docs', href: '/docs/' },
{ label: 'github', href: 'https://github.com/litruv', external: true },
{ label: 'bluesky', href: 'https://bsky.app/profile/lit.mates.dev', external: true },
{ label: 'materials', href: '/materials' },
{ label: 'GitHub', href: 'https://github.com/litruv', external: true, svg: GITHUB_SVG },
{ label: 'Bluesky', href: 'https://bsky.app/profile/lit.mates.dev', external: true, svg: BLUESKY_SVG },
];
/**
@@ -24,9 +28,11 @@ const NAV_LINKS = [
* @returns {string}
*/
function renderNavLinkItems(indent = ' ') {
return NAV_LINKS.map(({ label, href, external }) => {
return NAV_LINKS.map(({ label, href, external, svg }) => {
const attrs = external ? ' target="_blank" rel="noopener"' : '';
return `${indent}<a href="${href}"${attrs} class="quick-link">${label}</a>`;
const content = svg ? svg : label;
const extraClass = svg ? ' quick-link--icon' : '';
return `${indent}<a href="${href}"${attrs} class="quick-link${extraClass}" aria-label="${label}"${svg ? ` title="${label}"` : ''}>${content}</a>`;
}).join('\n');
}