Browse Source

footer: rebuild home footer in /work style; restyle nav; drop cookie notice

Footer (parts/footer-home.html + #dw-footer CSS):
- /work-style dark panel: address widget, full 20-link columns (+ Work link),
  .footer-end bar with small copyright, Gaegu line, and social icons.
- Social set expanded (Wikipedia/GitHub/Mastodon/Stack Exchange/Facebook/
  Bluesky/Reddit/Spotify/LinkedIn), all from the SVG sprite.
- Self-hosted Inter/Playfair Display/Gaegu (woff2), scoped to #dw-footer.

Icon sprite: bin/build-icons.mjs now merges bin/custom-icons/*.svg (Bootstrap
Icons) into icons.svg so hand-added glyphs survive the kit rebuild.

Nav: #nav offcanvas + scroll-up navbar dropdown use the footer color at 70%
opacity + blur; removed the x close button; offcanvas height 85px to match
the navbar (measured 84.6px).

Cookies: removed the notice from both footers, the cookieNotification() JS
in single.js, and the js-cookie dependency (US site, no EU requirement).
windhamdavid 1 week ago
parent
commit
997aa9e3ac

+ 16 - 1
bin/build-icons.mjs

@@ -10,7 +10,7 @@
  * The kit is the curated icon set, so the sprite is exactly the icons we use (~40, ~40 KB)
  * — replacing the 689 KB Font Awesome webfont.
  */
-import { readFileSync, writeFileSync, readdirSync } from 'node:fs';
+import { readFileSync, writeFileSync, readdirSync, existsSync } from 'node:fs';
 import { resolve } from 'node:path';
 
 const scope = 'node_modules/@awesome.me';
@@ -39,6 +39,21 @@ for (const file of readdirSync(spritesDir).filter((f) => f.endsWith('.svg'))) {
   }
 }
 
+// Custom local icons (non-FA, e.g. Bootstrap Icons) live in bin/custom-icons/*.svg.
+// Merged here so they survive a kit rebuild; filename (minus .svg) is the icon name.
+const customDir = resolve('bin/custom-icons');
+if (existsSync(customDir)) {
+  for (const file of readdirSync(customDir).filter((f) => f.endsWith('.svg'))) {
+    const name = file.replace(/\.svg$/, '');
+    if (seen.has(name)) continue; // kit wins on a name clash
+    seen.add(name);
+    const svg = readFileSync(resolve(customDir, file), 'utf8');
+    const viewBox = (svg.match(/viewBox="([^"]+)"/) || [, '0 0 16 16'])[1];
+    const inner = svg.replace(/[\s\S]*?<svg[^>]*>/, '').replace(/<\/svg>[\s\S]*/, '').trim();
+    symbols.push(`<symbol id="dw-${name}" viewBox="${viewBox}" fill="currentColor">${inner}</symbol>`);
+  }
+}
+
 symbols.sort();
 const sprite =
   '<svg xmlns="http://www.w3.org/2000/svg" style="display:none" aria-hidden="true">\n' +

+ 3 - 0
bin/custom-icons/briefcase.svg

@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-briefcase" viewBox="0 0 16 16">
+  <path d="M6.5 1A1.5 1.5 0 0 0 5 2.5V3H1.5A1.5 1.5 0 0 0 0 4.5v8A1.5 1.5 0 0 0 1.5 14h13a1.5 1.5 0 0 0 1.5-1.5v-8A1.5 1.5 0 0 0 14.5 3H11v-.5A1.5 1.5 0 0 0 9.5 1h-3zm0 1h3a.5.5 0 0 1 .5.5V3H6v-.5a.5.5 0 0 1 .5-.5zm1.886 6.914L15 7.151V12.5a.5.5 0 0 1-.5.5h-13a.5.5 0 0 1-.5-.5V7.15l6.614 1.764a1.5 1.5 0 0 0 .772 0zM1.5 4h13a.5.5 0 0 1 .5.5v1.616L8.129 7.948a.5.5 0 0 1-.258 0L1 6.116V4.5a.5.5 0 0 1 .5-.5z"/>
+</svg>

+ 3 - 0
bin/custom-icons/linkedin.svg

@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-linkedin" viewBox="0 0 16 16">
+  <path d="M0 1.146C0 .513.526 0 1.175 0h13.65C15.474 0 16 .513 16 1.146v13.708c0 .633-.526 1.146-1.175 1.146H1.175C.526 16 0 15.487 0 14.854V1.146zm4.943 12.248V6.169H2.542v7.225h2.401zm-1.2-8.212c.837 0 1.358-.554 1.358-1.248-.015-.709-.52-1.248-1.342-1.248-.822 0-1.359.54-1.359 1.248 0 .694.521 1.248 1.327 1.248h.016zm4.908 8.212V9.359c0-.216.016-.432.08-.586.173-.431.568-.878 1.232-.878.869 0 1.216.662 1.216 1.634v3.865h2.401V9.25c0-2.22-1.184-3.252-2.764-3.252-1.274 0-1.845.7-2.165 1.193v.025h-.016a5.54 5.54 0 0 1 .016-.025V6.169h-2.4c.03.678 0 7.225 0 7.225h2.4z"/>
+</svg>

+ 3 - 0
bin/custom-icons/spotify.svg

@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-spotify" viewBox="0 0 16 16">
+  <path d="M8 0a8 8 0 1 0 0 16A8 8 0 0 0 8 0zm3.669 11.538a.498.498 0 0 1-.686.165c-1.879-1.147-4.243-1.407-7.028-.77a.499.499 0 0 1-.222-.973c3.048-.696 5.662-.397 7.77.892a.5.5 0 0 1 .166.686zm.979-2.178a.624.624 0 0 1-.858.205c-2.15-1.321-5.428-1.704-7.972-.932a.625.625 0 0 1-.362-1.194c2.905-.881 6.517-.454 8.986 1.063a.624.624 0 0 1 .206.858zm.084-2.268C10.154 5.56 5.9 5.419 3.438 6.166a.748.748 0 1 1-.434-1.432c2.825-.857 7.523-.692 10.492 1.07a.747.747 0 1 1-.764 1.288z"/>
+</svg>

+ 4 - 0
bin/custom-icons/stack-overflow.svg

@@ -0,0 +1,4 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-stack-overflow" viewBox="0 0 16 16">
+  <path d="M12.412 14.572V10.29h1.428V16H1v-5.71h1.428v4.282h9.984z"/>
+  <path d="M3.857 13.145h7.137v-1.428H3.857v1.428zM10.254 0 9.108.852l4.26 5.727 1.146-.852L10.254 0zm-3.54 3.377 5.484 4.567.913-1.097L7.627 2.28l-.914 1.097zM4.922 6.55l6.47 3.013.603-1.294-6.47-3.013-.603 1.294zm-.925 3.344 6.985 1.469.294-1.398-6.985-1.468-.294 1.397z"/>
+</svg>

+ 3 - 0
bin/custom-icons/wikipedia.svg

@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-wikipedia" viewBox="0 0 16 16">
+  <path d="M8.835 3.003c.828-.006 2.688 0 2.688 0l.033.03v.288c0 .08-.045.12-.133.12-.433.02-.522.063-.68.29-.087.126-.258.393-.435.694l-1.52 2.843-.043.089 1.858 3.801.113.031 2.926-6.946c.102-.28.086-.478-.044-.595-.132-.114-.224-.18-.563-.195l-.275-.014a.161.161 0 0 1-.096-.035.1.1 0 0 1-.046-.084v-.289l.042-.03h3.306l.034.03v.29c0 .078-.045.117-.133.117-.433.02-.754.113-.962.281a1.64 1.64 0 0 0-.488.704s-2.691 6.16-3.612 8.208c-.353.672-.7.61-1.004-.019A224.05 224.05 0 0 1 8.044 8.81c-.623 1.285-1.475 3.026-1.898 3.81-.411.715-.75.622-1.02.019-.45-1.065-1.131-2.519-1.817-3.982-.735-1.569-1.475-3.149-1.943-4.272-.167-.4-.293-.657-.412-.759-.12-.1-.368-.16-.746-.18C.069 3.429 0 3.395 0 3.341v-.303l.034-.03c.615-.003 3.594 0 3.594 0l.034.03v.288c0 .08-.05.118-.15.118l-.375.016c-.322.013-.483.11-.483.288 0 .083.034.217.109.4.72 1.753 3.207 6.998 3.207 6.998l.091.023 1.603-3.197-.32-.71L6.24 5.095s-.213-.433-.286-.577l-.098-.196c-.387-.77-.411-.82-.865-.88-.137-.017-.208-.035-.208-.102v-.304l.041-.03h2.853l.075.024v.303c0 .069-.05.104-.15.104l-.206.03c-.523.04-.438.254-.09.946l1.057 2.163 1.17-2.332c.195-.427.155-.534.074-.633-.046-.055-.202-.144-.54-.158l-.133-.015a.159.159 0 0 1-.096-.034.099.099 0 0 1-.045-.085v-.288l.041-.03Z"/>
+</svg>

+ 3 - 10
css/styles.scss

@@ -129,25 +129,18 @@ $enable-negative-margins: true;
   z-index: 1045; // above .navbar.fixed-top (1030)
   display: flex;
   flex-direction: column;
-  height: 100px;
+  height: 85px;              // match the scroll-up navbar dropdown (~84.6px)
   visibility: hidden;
   transform: translateY(-100%);
   transition: transform 0.3s ease-in-out, visibility 0.3s;
   overflow-y: auto;
+  background: rgba(72, 76, 87, 0.7); // footer color (#484c57), translucent
+  backdrop-filter: blur(6px);
 }
 .dw-offcanvas:target {
   visibility: visible;
   transform: none;
 }
-.dw-offcanvas-close {
-  position: absolute;
-  top: 0.25rem;
-  right: 0.75rem;
-  font-size: 1.75rem;
-  line-height: 1;
-  color: inherit;
-  text-decoration: none;
-}
 .dw-offcanvas-backdrop {
   display: none;
   position: fixed;

BIN
fonts/Inter-Regular.woff2


BIN
fonts/Inter-SemiBold.woff2


BIN
fonts/gaegu-v15-latin-300.woff2


BIN
fonts/playfair-display-v20-latin-700.woff2


BIN
fonts/playfair-display-v20-latin-900.woff2


File diff suppressed because it is too large
+ 2 - 0
icons.svg


+ 2 - 28
js/single.js

@@ -67,31 +67,5 @@ $('#commentform').validate({
 	errorElement: 'div',
 	errorPlacement: function(error, element) {
 		element.before(error);
-	} 
-});
-
-/*============================================
-		    EU GDPR cookie notification
-==============================================*/
-
-$( document ).ready( function() {
-	cookieNotification();
-});
-var hideCookieNotification = function() {
-	$( '.js-cookie-notification' ).delay(5000).fadeOut( "slow" );
-	Cookies.set('EU-GDPR-Cookie', 'true', { expires: 365 });
-};
-var cookieNotification = function() {
-	var setCookieNotification = function() {	
-	  $( '.js-cookie-notification' ).fadeOut( "slow" );
-	  Cookies.set('EU-GDPR-Cookie', 'true', { expires: 365 });
-	return false;
-};
-	if ( Cookies.get('EU-GDPR-Cookie') === 'true' ) {
-		console.log('EU GDPR cookie notification set');
-	} else {
-		console.log('EU GDPR cookie notification not set');
-		$('.js-cookie-notification').css({ 'display' : 'block'});
-		$('.js-cookie-notification').find('.js-cookie-notification-hide').click( setCookieNotification );
-	};					
-}
+	}
+});

File diff suppressed because it is too large
+ 0 - 0
js/v4-script.min.js


+ 0 - 2
js/v4-script.min.js.LICENSE.txt

@@ -46,5 +46,3 @@
  * Copyright (c) 2022 Jörn Zaefferer
  * Released under the MIT license
  */
-
-/*! js-cookie v3.0.8 | MIT */

+ 0 - 12
package-lock.json

@@ -13,7 +13,6 @@
         "jquery": "^3.6.1",
         "jquery-lazyload": "^1.9.7",
         "jquery-validation": "^1.19.5",
-        "js-cookie": "^3.0.8",
         "svg-morpheus": "^0.3.0"
       },
       "devDependencies": {
@@ -18705,12 +18704,6 @@
         "jquery": "^1.7 || ^2.0 || ^3.1"
       }
     },
-    "node_modules/js-cookie": {
-      "version": "3.0.8",
-      "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.8.tgz",
-      "integrity": "sha512-yeJd4aNAdYZQjaon2bpD/Gb0B/omw7HQOsynXXcOiWVCacbBcPlgn8S/d1X6blFSaHao7ozqtW7NZW19xpCtIw==",
-      "license": "MIT"
-    },
     "node_modules/js-library-detector": {
       "version": "6.7.0",
       "resolved": "https://registry.npmjs.org/js-library-detector/-/js-library-detector-6.7.0.tgz",
@@ -40848,11 +40841,6 @@
       "integrity": "sha512-X2SmnPq1mRiDecVYL8edWx+yTBZDyC8ohWXFhXdtqFHgU9Wd4KHkvcbCoIZ0JaSaumzS8s2gXSkP8F7ivg/8ZQ==",
       "requires": {}
     },
-    "js-cookie": {
-      "version": "3.0.8",
-      "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.8.tgz",
-      "integrity": "sha512-yeJd4aNAdYZQjaon2bpD/Gb0B/omw7HQOsynXXcOiWVCacbBcPlgn8S/d1X6blFSaHao7ozqtW7NZW19xpCtIw=="
-    },
     "js-library-detector": {
       "version": "6.7.0",
       "resolved": "https://registry.npmjs.org/js-library-detector/-/js-library-detector-6.7.0.tgz",

+ 0 - 1
package.json

@@ -43,7 +43,6 @@
     "jquery": "^3.6.1",
     "jquery-lazyload": "^1.9.7",
     "jquery-validation": "^1.19.5",
-    "js-cookie": "^3.0.8",
     "svg-morpheus": "^0.3.0"
   }
 }

+ 71 - 44
parts/footer-home.html

@@ -1,54 +1,81 @@
 <!-- wp:html -->
-<div class="container-fluid footer footer-home dark">
+<div id="dw-footer" class="container-fluid footer-home dw-footer">
 	<div class="container">
 		<div class="row">
-			<div class="col-md-4">
-				<ul style="float:left;margin-right:10px;">
-					<li><a href="/about"><svg class="dw-icon" aria-hidden="true" focusable="false"><use href="#dw-file-lines"></use></svg> About</a></li>
-					<li><a href="/desk/archive" title="Archive"><svg class="dw-icon" aria-hidden="true" focusable="false"><use href="#dw-box-archive"></use></svg> Archive</a></li>
-					<li><a href="/studio/music/"><svg class="dw-icon" aria-hidden="true" focusable="false"><use href="#dw-microphone"></use></svg> Audio</a></li>
-					<li><a href="https://davidwindham.com/rtc"><svg class="dw-icon" aria-hidden="true" focusable="false"><use href="#dw-comment"></use></svg> Chat</a></li>
-					<li><a href="http://chess.davidwindham.com"><span class="chess-html">&#9814;</span> Chess</a></li>
-					<li><a href="http://code.davidawindham.com"><svg class="dw-icon" aria-hidden="true" focusable="false"><use href="#dw-code"></use></svg> Code</a></li>
-					<li><a href="/contact"><svg class="dw-icon" aria-hidden="true" focusable="false"><use href="#dw-envelope"></use></svg> Contact</a></li>
-				</ul>
-				<ul style="float:left;margin-right:10px;">
-					<li><a href="/desk"><svg class="dw-icon" aria-hidden="true" focusable="false"><use href="#dw-pen-to-square"></use></svg> Desk</a></li>
-					<li><a href="/mail/" title="Newsletter"><svg class="dw-icon" aria-hidden="true" focusable="false"><use href="#dw-paper-plane"></use></svg> Email</a></li>
-					<li><a href="/contact/guests" title="Guestbook"><svg class="dw-icon" aria-hidden="true" focusable="false"><use href="#dw-pen-to-square"></use></svg> Guests</a></li>
-					<li><a href="/"><svg class="dw-icon" aria-hidden="true" focusable="false"><use href="#dw-house"></use></svg> Home</a></li>
-					<li><a href="/studio/art/" title="Art"><svg class="dw-icon" aria-hidden="true" focusable="false"><use href="#dw-paintbrush"></use></svg> Paint</a></li>
-					<li><a href="/pay"><svg class="dw-icon" aria-hidden="true" focusable="false"><use href="#dw-credit-card"></use></svg> Pay</a></li>
-				</ul>
-				<ul style="float:left;margin-right:10px;">
-					<li><a href="http://photo.davidwindham.com" title="Photo"><svg class="dw-icon" aria-hidden="true" focusable="false"><use href="#dw-camera-retro"></use></svg> Photo</a></li>
-					<li><a href="http://radio.davidawindham.com"><svg class="dw-icon" aria-hidden="true" focusable="false"><use href="#dw-microphone"></use></svg> Radio</a></li>
-					<li><a href="/shop"><svg class="dw-icon" aria-hidden="true" focusable="false"><use href="#dw-credit-card"></use></svg> Shop</a></li>
-					<li><a href="/about/analytics/" title="analytics"><svg class="dw-icon" aria-hidden="true" focusable="false"><use href="#dw-gauge"></use></svg> Stats</a></li>
-					<li><a href="/studio"><svg class="dw-icon" aria-hidden="true" focusable="false"><use href="#dw-flask"></use></svg> Studio</a></li>
-					<li><a href="/til/" title="Today I Learned"><svg class="dw-icon" aria-hidden="true" focusable="false"><use href="#dw-book"></use></svg> TIL</a></li>
-				</ul>
+			<div class="col-lg-5 col-md-6">
+				<div class="br-widget">
+					<h5>David Windham</h5>
+					<address class="mt-3">
+						<a href="https://www.google.com/maps/place/David+A.+Windham/@34.1765211,-82.2053464,283m/data=!3m1!1e3!4m15!1m8!3m7!1s0x88f801f9e630a345:0xe922490e1a1e4b7!2s102+Glenridge+Cir,+Greenwood,+SC+29646!3b1!8m2!3d34.1765755!4d-82.2046031!16s%2Fg%2F11c2bblj4m!3m5!1s0x88f801f9e8809783:0x5c848caa89afc24b!8m2!3d34.176529!4d-82.204683!16s%2Fg%2F11c1vh_2d0">102 Glenridge Circle</a><br />
+						<a href="https://www.google.com/maps/place/David+A.+Windham/@34.1765211,-82.2053464,283m/data=!3m1!1e3!4m15!1m8!3m7!1s0x88f801f9e630a345:0xe922490e1a1e4b7!2s102+Glenridge+Cir,+Greenwood,+SC+29646!3b1!8m2!3d34.1765755!4d-82.2046031!16s%2Fg%2F11c2bblj4m!3m5!1s0x88f801f9e8809783:0x5c848caa89afc24b!8m2!3d34.176529!4d-82.204683!16s%2Fg%2F11c1vh_2d0">Greenwood, South Carolina USA</a><br />
+						<a href="mailto:david@davidawindham.com">david@davidawindham.com</a><br />
+						<a href="tel:8037123283">+1-803-712-3283</a>
+					</address>
+				</div>
 			</div>
-		</div>
-		<div class="row mt-5">
-			<div class="col-md-4">
-				<ul class="social">
-					<li><a href="https://bsky.app/profile/davidwindham.com" class="twitter" rel="me"><svg class="dw-icon dw-icon-2x" role="img" aria-label="Bluesky"><use href="#dw-bluesky"></use></svg></a></li>
-					<li><a href="https://www.facebook.com/davidawindham" class="facebook"><svg class="dw-icon dw-icon-2x" role="img" aria-label="Facebook"><use href="#dw-facebook"></use></svg></a></li>
-          <li><a href="https://www.reddit.com/user/windhamdavid" class="reddit"><svg class="dw-icon dw-icon-2x" role="img" aria-label="Reddit"><use href="#dw-reddit"></use></svg></a></li>
-					<li><a href="https://github.com/windhamdavid" class="github" rel="me"><svg class="dw-icon dw-icon-2x" role="img" aria-label="GitHub"><use href="#dw-github"></use></svg></a></li>
-				</ul>
-			</div>
-			<div class="col-md-3 offset-sm-5">
-				<p class="small dim right">&copy; 2004-2026<br />
-				<p class="small dim right"><a href="/sitemap"><svg class="dw-icon" aria-hidden="true" focusable="false"><use href="#dw-sitemap"></use></svg> Sitemap</a><br />
-				<span class="small dull right">This website uses cookies</span></p>
+			<div class="col-lg-6 col-md-6 offset-lg-1 mt-5 mt-md-0">
+				<div class="br-widget">
+					<div class="row">
+						<div class="col-4">
+							<ul class="footer-links">
+								<li><a href="/about"><svg class="dw-icon" aria-hidden="true" focusable="false"><use href="#dw-file-lines"></use></svg> About</a></li>
+								<li><a href="/desk/archive" title="Archive"><svg class="dw-icon" aria-hidden="true" focusable="false"><use href="#dw-box-archive"></use></svg> Archive</a></li>
+								<li><a href="/studio/music/"><svg class="dw-icon" aria-hidden="true" focusable="false"><use href="#dw-microphone"></use></svg> Audio</a></li>
+								<li><a href="https://davidwindham.com/rtc"><svg class="dw-icon" aria-hidden="true" focusable="false"><use href="#dw-comment"></use></svg> Chat</a></li>
+								<li><a href="http://chess.davidwindham.com"><span class="chess-html">&#9814;</span> Chess</a></li>
+								<li><a href="http://code.davidawindham.com"><svg class="dw-icon" aria-hidden="true" focusable="false"><use href="#dw-code"></use></svg> Code</a></li>
+								<li><a href="/contact"><svg class="dw-icon" aria-hidden="true" focusable="false"><use href="#dw-envelope"></use></svg> Contact</a></li>
+							</ul>
+						</div>
+						<div class="col-4">
+							<ul class="footer-links">
+								<li><a href="/desk"><svg class="dw-icon" aria-hidden="true" focusable="false"><use href="#dw-pen-to-square"></use></svg> Desk</a></li>
+								<li><a href="/mail/" title="Newsletter"><svg class="dw-icon" aria-hidden="true" focusable="false"><use href="#dw-paper-plane"></use></svg> Email</a></li>
+								<li><a href="/contact/guests" title="Guestbook"><svg class="dw-icon" aria-hidden="true" focusable="false"><use href="#dw-pen-to-square"></use></svg> Guests</a></li>
+								<li><a href="/"><svg class="dw-icon" aria-hidden="true" focusable="false"><use href="#dw-house"></use></svg> Home</a></li>
+								<li><a href="/studio/art/" title="Art"><svg class="dw-icon" aria-hidden="true" focusable="false"><use href="#dw-paintbrush"></use></svg> Paint</a></li>
+								<li><a href="/pay"><svg class="dw-icon" aria-hidden="true" focusable="false"><use href="#dw-credit-card"></use></svg> Pay</a></li>
+								<li><a href="http://photo.davidwindham.com" title="Photo"><svg class="dw-icon" aria-hidden="true" focusable="false"><use href="#dw-camera-retro"></use></svg> Photo</a></li>
+							</ul>
+						</div>
+						<div class="col-4">
+							<ul class="footer-links">
+								<li><a href="http://radio.davidawindham.com"><svg class="dw-icon" aria-hidden="true" focusable="false"><use href="#dw-microphone"></use></svg> Radio</a></li>
+								<li><a href="/shop"><svg class="dw-icon" aria-hidden="true" focusable="false"><use href="#dw-credit-card"></use></svg> Shop</a></li>
+								<li><a href="/sitemap"><svg class="dw-icon" aria-hidden="true" focusable="false"><use href="#dw-sitemap"></use></svg> Sitemap</a></li>
+								<li><a href="/about/analytics/" title="analytics"><svg class="dw-icon" aria-hidden="true" focusable="false"><use href="#dw-gauge"></use></svg> Stats</a></li>
+								<li><a href="/studio"><svg class="dw-icon" aria-hidden="true" focusable="false"><use href="#dw-flask"></use></svg> Studio</a></li>
+								<li><a href="/til/" title="Today I Learned"><svg class="dw-icon" aria-hidden="true" focusable="false"><use href="#dw-book"></use></svg> TIL</a></li>
+								<li><a href="/work"><svg class="dw-icon" aria-hidden="true" focusable="false"><use href="#dw-briefcase"></use></svg> Work</a></li>
+							</ul>
+						</div>
+					</div>
+				</div>
 			</div>
 		</div>
 	</div>
-	<div class="cookie-notification js-cookie-notification">
-		<p>By using this website, you agree to the use of<br />cookies and the <a href="/privacy/">privacy policy</a>.</p>
-		<button class="btn btn-default" type="submit"><a href="#" class="js-cookie-notification-hide">Agree and dismiss</a></button>
+	<div class="footer-end">
+		<div class="container">
+			<div class="row align-items-end">
+				<div class="col-md-6 text-md-start">
+					<small class="copyright">&copy; 2004-2026</small>
+				</div>
+				<div class="col-md-6 text-md-end">
+					<p class="gaegu mb-n1">I'm not really active on some of these:</p>
+					<ul class="footer-links footer-social">
+						<li><a href="https://en.wikipedia.org/wiki/User:Windhamdavid" class="wikipedia" rel="me"><svg class="dw-icon dw-icon-2x" role="img" aria-label="Wikipedia"><use href="#dw-wikipedia"></use></svg></a></li>
+						<li><a href="https://github.com/windhamdavid" class="github" rel="me"><svg class="dw-icon dw-icon-2x" role="img" aria-label="GitHub"><use href="#dw-github"></use></svg></a></li>
+						<li><a href="https://mastodon.social/@windhamdavid" class="mastodon" rel="me"><svg class="dw-icon dw-icon-2x" role="img" aria-label="Mastodon"><use href="#dw-mastodon"></use></svg></a></li>
+						<li><a href="https://stackexchange.com/users/521983/david-windham" class="stackoverflow"><svg class="dw-icon dw-icon-2x" role="img" aria-label="Stack Exchange"><use href="#dw-stack-overflow"></use></svg></a></li>
+						<li><a href="https://www.facebook.com/davidawindham" class="facebook"><svg class="dw-icon dw-icon-2x" role="img" aria-label="Facebook"><use href="#dw-facebook"></use></svg></a></li>
+						<li><a href="https://bsky.app/profile/davidwindham.com" class="twitter" rel="me"><svg class="dw-icon dw-icon-2x" role="img" aria-label="Bluesky"><use href="#dw-bluesky"></use></svg></a></li>
+						<li><a href="https://www.reddit.com/user/windhamdavid" class="reddit"><svg class="dw-icon dw-icon-2x" role="img" aria-label="Reddit"><use href="#dw-reddit"></use></svg></a></li>
+						<li><a href="https://open.spotify.com/user/windhamdavid" class="spotify" rel="me"><svg class="dw-icon dw-icon-2x" role="img" aria-label="Spotify"><use href="#dw-spotify"></use></svg></a></li>
+						<li><a href="https://www.linkedin.com/in/windhamdavid" class="linkedin" rel="me"><svg class="dw-icon dw-icon-2x" role="img" aria-label="LinkedIn"><use href="#dw-linkedin"></use></svg></a></li>
+					</ul>
+				</div>
+			</div>
+		</div>
 	</div>
 </div>
 <!-- /wp:html -->

+ 0 - 4
parts/footer.html

@@ -12,9 +12,5 @@
 			</div>
 		</div>
 	</div>
-	<div class="cookie-notification js-cookie-notification">
-		<p>By using this website, you agree to the use of<br />cookies and the <a href="/privacy/">privacy policy</a>.</p>
-		<button class="btn btn-default" type="submit"><a href="#" class="js-cookie-notification-hide">Agree and dismiss</a></button>
-	</div>
 </div>
 <!-- /wp:html -->

+ 0 - 1
parts/header.html

@@ -9,7 +9,6 @@
 	</div>
 </header>
 <div class="dw-offcanvas text-bg-blue" tabindex="-1" id="nav" aria-labelledby="navLabel">
-  <a href="#" class="dw-offcanvas-close" aria-label="Close menu">&times;</a>
   <nav class="d-flex justify-content-center" role="navigation">
     <ul class="nav list-group list-group-horizontal pt-3 fs-5">
       <li class="list-group-item"><a href="/about">About</a></li>

+ 0 - 3
src/main.js

@@ -12,9 +12,6 @@ window.$ = window.jQuery = $;
 // Bootstrap JS retired: offcanvas → CSS :target, carousels/tabs/tooltips → native
 // per-page vanilla JS. The bootstrap npm package stays for the SCSS subset only.
 
-import Cookies from 'js-cookie';
-window.Cookies = Cookies;
-
 import 'jquery-validation'; // → $.fn.validate  (comment forms: about, single)
 import 'jquery-lazyload'; // → $.fn.lazyload  (desk)
 

+ 146 - 12
style.css

@@ -95,16 +95,6 @@ body.contact {
 	}
 }
 
-.cookie-notification {
-	display: none;
-	padding:30px;
-	position: fixed;
-	bottom: 10px;
-	left: 10px;
-	background-color: #fff;
-	opacity: 0.8;
-	border-radius: 15px;
-}
 /*============================================
 		Typography
 ==============================================*/
@@ -551,7 +541,7 @@ h4.spread {
   -ms-transform: translate3d(0, 100%, 0);
   -o-transform: translate3d(0, 100%, 0);
   transform: translate3d(0, 100%, 0);
-  background-color: rgba(237, 237, 237, 0.7);
+  background-color: rgba(72, 76, 87, 0.7);
 }
 #nav {
   width: 100%;
@@ -711,6 +701,149 @@ ul.social a.facebook span:hover {
 	color: #3B5998;
 }
 
+/*============================================
+		Footer — home (ported from /work)
+==============================================*/
+
+/* fonts scoped to the home footer for now (Inter / Playfair Display / Gaegu) */
+@font-face {
+	font-family: 'Inter';
+	font-style: normal;
+	font-weight: 400;
+	font-display: swap;
+	src: url('fonts/Inter-Regular.woff2') format('woff2');
+}
+@font-face {
+	font-family: 'Inter';
+	font-style: normal;
+	font-weight: 600;
+	font-display: swap;
+	src: url('fonts/Inter-SemiBold.woff2') format('woff2');
+}
+@font-face {
+	font-family: 'Playfair Display';
+	font-style: normal;
+	font-weight: 700;
+	font-display: swap;
+	src: url('fonts/playfair-display-v20-latin-700.woff2') format('woff2');
+}
+@font-face {
+	font-family: 'Playfair Display';
+	font-style: normal;
+	font-weight: 900;
+	font-display: swap;
+	src: url('fonts/playfair-display-v20-latin-900.woff2') format('woff2');
+}
+@font-face {
+	font-family: 'Gaegu';
+	font-style: normal;
+	font-weight: 300;
+	font-display: swap;
+	src: url('fonts/gaegu-v15-latin-300.woff2') format('woff2');
+}
+
+#dw-footer {
+	background-color: #484c57;
+	color: #dadada;
+	font-family: 'Inter', sans-serif;
+	margin: 6rem 0 0;
+	padding: 4rem 0;
+}
+#dw-footer h5 {
+	font-family: 'Playfair Display', serif;
+	font-weight: 900;
+	line-height: 1.2;
+	margin: 0;
+}
+#dw-footer address {
+	font-style: normal;
+	line-height: 1.9;
+}
+#dw-footer a {
+	position: relative;
+	color: #dadada;
+	fill: #dadada;
+	text-decoration: none;
+}
+#dw-footer a:hover {
+	color: #25c2a0;
+	fill: #25c2a0;
+}
+#dw-footer .br-widget {
+	margin: 4rem 0 0;
+}
+#dw-footer .br-widget:first-child {
+	margin-top: 0;
+}
+#dw-footer ul.footer-links {
+	list-style: none;
+	margin: 0;
+	padding: 0;
+}
+#dw-footer ul.footer-links li {
+	margin: 0 0 .35rem;
+	padding: 0 0 .35rem;
+}
+#dw-footer ul.footer-links li:last-child {
+	margin-bottom: 0;
+}
+/* sliding underline on hover (left-to-right) */
+#dw-footer .br-widget a:before,
+#dw-footer .footer-end a:before {
+	content: '';
+	position: absolute;
+	bottom: 0;
+	right: 0;
+	height: 1px;
+	width: 0;
+	background: currentColor;
+	transition: width 0.5s cubic-bezier(0.785, 0.135, 0.15, 0.86) 0s;
+}
+#dw-footer .br-widget a:hover:before,
+#dw-footer .footer-end a:hover:before {
+	left: 0;
+	right: initial;
+	width: 100%;
+}
+#dw-footer .footer-end {
+	margin-top: 4rem;
+	padding-top: 2rem;
+}
+#dw-footer .footer-end .copyright {
+	font-size: 12px;
+	color: #9a9ea8;
+}
+#dw-footer .footer-end .gaegu {
+	font-family: 'Gaegu', serif;
+	font-weight: 300;
+	margin-bottom: 0;
+}
+#dw-footer ul.footer-social {
+	list-style: none;
+	display: flex;
+	gap: 16px;
+	justify-content: flex-end;
+	margin: .5rem 0 0;
+	padding: 0;
+}
+#dw-footer ul.footer-social li {
+	margin: 0;
+	padding: 0;
+}
+#dw-footer ul.footer-social .dw-icon-2x {
+	width: 22px;
+	height: 22px;
+}
+@media (max-width: 767.98px) {
+	#dw-footer .footer-end .gaegu,
+	#dw-footer ul.footer-social {
+		justify-content: flex-start;
+	}
+	#dw-footer .footer-end .col-md-6.text-md-end {
+		text-align: left;
+	}
+}
+
 /*============================================
 		Intro
 ==============================================*/
@@ -2317,7 +2450,8 @@ ul.bookmarks {
   font-weight:600;
 }
 .navbar.visible {
-  background:#383838b3;
+  background: rgba(72, 76, 87, 0.7); /* footer color (#484c57), translucent */
+  backdrop-filter: blur(6px);
 }
 .offcanvas {
   background: #2b2e35d7;

File diff suppressed because it is too large
+ 0 - 0
v4-style.min.css


Some files were not shown because too many files changed in this diff