← back to Linenwallpaper
corner-nav: install fleet-ready two-hamburger accordion nav (manifest-driven, brand palette, clean-URL aware) (TK-10318)
fb89df32a9722e8423564f7d64460bb87e1b366d · 2026-08-08 07:52:44 -0700 · Steve Abrams
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Files touched
M public/care.htmlA public/corner-nav-accordion.jsA public/corner-nav.manifest.jsonM public/history.htmlM public/index.htmlM public/sourcing.htmlM public/trade.htmlM public/vocabulary.html
Diff
commit fb89df32a9722e8423564f7d64460bb87e1b366d
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Sat Aug 8 07:52:44 2026 -0700
corner-nav: install fleet-ready two-hamburger accordion nav (manifest-driven, brand palette, clean-URL aware) (TK-10318)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
public/care.html | 6 +-
public/corner-nav-accordion.js | 322 ++++++++++++++++++++++++++++++++++++++++
public/corner-nav.manifest.json | 27 ++++
public/history.html | 6 +-
public/index.html | 4 +
public/sourcing.html | 6 +-
public/trade.html | 6 +-
public/vocabulary.html | 6 +-
8 files changed, 378 insertions(+), 5 deletions(-)
diff --git a/public/care.html b/public/care.html
index 363ed0e..bfb7e10 100644
--- a/public/care.html
+++ b/public/care.html
@@ -55,4 +55,8 @@ nav.foot a{margin-right:22px;text-decoration:none}
<a href="/trade">Trade</a>
<a href="/about">About</a>
</nav>
-</div></body></html>
\ No newline at end of file
+</div>
+ <!-- fleet corner-nav (corner-nav-fanout.js) -->
+ <style>:root{--cnav-drawer-bg:#1a1714;--cnav-burger-bg:rgba(26,23,20,.92);--cnav-fg:#f0e9dc;--cnav-muted:#a89b85;--cnav-accent:#9B7B4F;--cnav-line:#3a3228;--cnav-sec-line:#2a241c;}</style>
+ <script src="/corner-nav-accordion.js" defer></script>
+</body></html>
\ No newline at end of file
diff --git a/public/corner-nav-accordion.js b/public/corner-nav-accordion.js
new file mode 100644
index 0000000..0445f94
--- /dev/null
+++ b/public/corner-nav-accordion.js
@@ -0,0 +1,322 @@
+/* corner-nav-accordion.js — FLEET-READY two-hamburger corner navigation.
+ Generalized from the CRCP build (commercialrealestate/public/corner-nav.js, live on
+ crcp.agentabrams.com). This is a DISTINCT component from _shared/corner-nav.js (the
+ Gucci top-right-pill + left-account nav) — do NOT confuse the two.
+
+ Drop-in on ANY site: <script src="/corner-nav-accordion.js" defer></script>
+
+ • TOP-LEFT ☰ → the whole site, grouped into collapsed accordion sections
+ (current page's group carries a gold "you-are-here" dot + its link
+ highlighted; per-section count badges). All sections start COLLAPSED.
+ • TOP-RIGHT ▤ → "On this page" jump links auto-built from the page's own headings,
+ plus the full site menu below.
+ Overlay + Esc + click-out to close. Reserves header padding. Folds legacy top-tabs
+ into the hamburgers while leaving page controls (inputs/buttons/selects) intact.
+
+ WHAT MAKES IT FLEET-READY (vs the CRCP original's hardcoded 26-page GROUPS array):
+ ─────────────────────────────────────────────────────────────────────────────────
+ The site map is now PER-SITE DATA, resolved in this priority order:
+ (a) window.CORNER_NAV_CONFIG — an inline object set before this script (no fetch, fastest)
+ (b) /corner-nav.manifest.json — a tiny per-site JSON this component fetches (RECOMMENDED)
+ (c) auto-discovery — a flat "This site" section built from the page's own
+ header/footer/nav <a> links (last-resort fallback so the
+ menu is never empty even with zero config).
+ Also:
+ • CLEAN-URL aware — normalizes current path + every href, so "/about", "/about.html" and
+ "about" all match. Emits hrefs exactly as the manifest authored them.
+ • PALETTE via CSS custom properties with hard fallbacks — inherits each site's theme when
+ the site defines the vars, else uses the CRCP dark/gold default. Override any of:
+ --cnav-drawer-bg --cnav-fg --cnav-muted --cnav-accent --cnav-line
+ --cnav-burger-bg --cnav-overlay
+ • Idempotent, self-contained, a11y-friendly.
+
+ MANIFEST / CONFIG SHAPE (both use the same object):
+ { "site": "Cork Wallcovering", // optional; shown as the ☰ drawer subtitle
+ "groups": [
+ { "title": "Explore", "items": [ ["/", "🏠 Home"], ["/about", "About"] ] },
+ { "title": "Reference", "items": [ ["/care", "Care"], ["/vocabulary", "Vocabulary"] ] }
+ ] }
+ Each item is [href, label]. Label may include an emoji/glyph. Href may be clean or .html.
+*/
+(function () {
+ if (window.__cornerNav) return; window.__cornerNav = true;
+
+ // ── path helpers (clean-URL aware) ───────────────────────────────────────────────────
+ function norm(p) {
+ if (!p) return '';
+ try { if (/^https?:/i.test(p)) p = new URL(p, location.href).pathname; } catch (e) {}
+ p = p.split('#')[0].split('?')[0];
+ p = p.replace(/\.html?$/i, '');
+ p = p.replace(/^\/+/, '').replace(/\/+$/, '');
+ if (p === 'index') p = '';
+ return p.toLowerCase();
+ }
+ var CUR = norm(location.pathname);
+
+ // ── default palette (CRCP dark/gold) — every value is a CSS-var-with-fallback ─────────
+ var C = {
+ burgerBg: 'var(--cnav-burger-bg, rgba(20,25,37,.92))',
+ fg: 'var(--cnav-fg, #e6e8ec)',
+ line: 'var(--cnav-line, #232a38)',
+ accent: 'var(--cnav-accent, #C8A24B)',
+ muted: 'var(--cnav-muted, #8A93A2)',
+ drawerBg: 'var(--cnav-drawer-bg, #11161f)',
+ secLine: 'var(--cnav-sec-line, #1b212c)',
+ overlay: 'var(--cnav-overlay, rgba(0,0,0,.5))'
+ };
+
+ // ── styles (scoped under .cnav*, driven by the vars above) ────────────────────────────
+ var css = '' +
+ '.cnav-burger{position:fixed;top:10px;z-index:9998;display:flex;align-items:center;gap:6px;' +
+ 'background:' + C.burgerBg + ';color:' + C.fg + ';border:1px solid rgba(255,255,255,.14);' +
+ 'border-radius:10px;padding:8px 11px;font-size:15px;line-height:1;cursor:pointer;' +
+ 'box-shadow:0 2px 10px rgba(0,0,0,.35);backdrop-filter:blur(3px);}' +
+ '.cnav-burger:hover{border-color:' + C.accent + ';color:' + C.accent + ';}' +
+ '.cnav-burger.left{left:10px;} .cnav-burger.right{right:10px;}' +
+ '.cnav-burger .lbl{font-size:12px;letter-spacing:.3px;} @media(max-width:640px){.cnav-burger .lbl{display:none;}}' +
+ '.cnav-ov{position:fixed;inset:0;background:' + C.overlay + ';z-index:9998;opacity:0;pointer-events:none;transition:opacity .18s;}' +
+ '.cnav-ov.on{opacity:1;pointer-events:auto;}' +
+ '.cnav-drawer{position:fixed;top:0;bottom:0;width:min(330px,88vw);background:' + C.drawerBg + ';color:' + C.fg + ';z-index:9999;' +
+ 'box-shadow:0 0 40px rgba(0,0,0,.5);display:flex;flex-direction:column;transition:transform .2s ease;' +
+ 'font:14px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif;}' +
+ '.cnav-drawer.left{left:0;border-right:1px solid ' + C.line + ';transform:translateX(-104%);}' +
+ '.cnav-drawer.right{right:0;border-left:1px solid ' + C.line + ';transform:translateX(104%);}' +
+ '.cnav-drawer.on{transform:translateX(0);}' +
+ '.cnav-hd{display:flex;align-items:center;justify-content:space-between;padding:14px 16px;border-bottom:1px solid ' + C.line + ';' +
+ 'font-size:12px;text-transform:uppercase;letter-spacing:.7px;color:' + C.accent + ';}' +
+ '.cnav-hd .sub{display:block;color:' + C.muted + ';font-size:10.5px;letter-spacing:.3px;text-transform:none;margin-top:2px;}' +
+ '.cnav-hd button{background:none;border:0;color:' + C.muted + ';font-size:20px;cursor:pointer;line-height:1;}' +
+ '.cnav-hd button:hover{color:' + C.fg + ';}' +
+ '.cnav-body{overflow-y:auto;padding:6px 0 24px;flex:1;}' +
+ '.cnav-sec{border-bottom:1px solid ' + C.secLine + ';}' +
+ '.cnav-sec>h4{margin:0;padding:12px 16px;font-size:12.5px;font-weight:700;letter-spacing:.3px;color:' + C.fg + ';' +
+ 'cursor:pointer;user-select:none;display:flex;align-items:center;justify-content:space-between;gap:8px;}' +
+ '.cnav-sec>h4:hover{color:#fff;background:rgba(255,255,255,.02);}' +
+ '.cnav-sec>h4 .lt{display:flex;align-items:center;gap:8px;min-width:0;}' +
+ '.cnav-sec>h4 .rt{display:flex;align-items:center;gap:9px;color:' + C.muted + ';}' +
+ '.cnav-sec>h4 .cnt{font-size:11px;font-variant-numeric:tabular-nums;background:' + C.secLine + ';border:1px solid ' + C.line + ';border-radius:9px;padding:0 7px;line-height:17px;}' +
+ '.cnav-sec>h4 .car{color:' + C.accent + ';transition:transform .15s;font-size:11px;}' +
+ '.cnav-sec.collapsed>h4 .car{transform:rotate(-90deg);}' +
+ '.cnav-sec.collapsed .cnav-list{display:none;}' +
+ '.cnav-sec.cur-sec>h4{color:#fff;} .cnav-sec.cur-sec .cnt{border-color:' + C.accent + ';color:' + C.accent + ';}' +
+ '.cnav-sec .curdot{width:7px;height:7px;border-radius:50%;background:' + C.accent + ';box-shadow:0 0 6px rgba(200,162,75,.55);flex:0 0 7px;}' +
+ '.cnav-list{padding:2px 0 8px;}' +
+ '.cnav-list a{display:block;padding:8px 16px 8px 22px;color:' + C.fg + ';opacity:.86;text-decoration:none;font-size:13.5px;border-left:2px solid transparent;}' +
+ '.cnav-list a:hover{background:rgba(200,162,75,.08);color:#fff;opacity:1;}' +
+ '.cnav-list a.cur{color:' + C.accent + ';opacity:1;border-left-color:' + C.accent + ';background:rgba(200,162,75,.10);font-weight:600;}' +
+ '.cnav-empty{padding:14px 16px;color:' + C.muted + ';font-size:13px;}';
+ var st = document.createElement('style'); st.textContent = css; document.head.appendChild(st);
+
+ function el(tag, cls, html) { var e = document.createElement(tag); if (cls) e.className = cls; if (html != null) e.innerHTML = html; return e; }
+
+ // ── overlay ───────────────────────────────────────────────────────────────────────
+ var ov = el('div', 'cnav-ov'); document.body.appendChild(ov);
+ function closeAll() {
+ document.querySelectorAll('.cnav-drawer.on').forEach(function (d) { d.classList.remove('on'); });
+ ov.classList.remove('on');
+ document.querySelectorAll('.cnav-burger').forEach(function (b) { b.setAttribute('aria-expanded', 'false'); });
+ }
+ ov.addEventListener('click', closeAll);
+ document.addEventListener('keydown', function (e) { if (e.key === 'Escape') closeAll(); });
+
+ // ── a collapsible accordion section (always starts COLLAPSED) ────────────────────────
+ function section(title, opts) {
+ opts = opts || {};
+ var sec = el('div', 'cnav-sec collapsed' + (opts.current ? ' cur-sec' : ''));
+ var dot = opts.current ? '<span class="curdot" title="you are here"></span>' : '';
+ var cnt = (opts.count != null) ? '<span class="cnt">' + opts.count + '</span>' : '';
+ var h = el('h4', null, '<span class="lt">' + dot + '<span>' + title + '</span></span>' +
+ '<span class="rt">' + cnt + '<span class="car">▾</span></span>');
+ var list = el('div', 'cnav-list');
+ h.addEventListener('click', function () { sec.classList.toggle('collapsed'); });
+ sec.appendChild(h); sec.appendChild(list); sec._list = list;
+ return sec;
+ }
+
+ function drawer(side, title, sub) {
+ var d = el('div', 'cnav-drawer ' + side);
+ var hd = el('div', 'cnav-hd', '<span>' + title + (sub ? '<span class="sub">' + sub + '</span>' : '') + '</span>');
+ var x = el('button', null, '✕'); x.setAttribute('aria-label', 'Close'); x.addEventListener('click', closeAll);
+ hd.appendChild(x);
+ var body = el('div', 'cnav-body');
+ d.appendChild(hd); d.appendChild(body); document.body.appendChild(d); d._body = body;
+ return d;
+ }
+
+ // ── PER-SITE NAV RESOLUTION ──────────────────────────────────────────────────────────
+ var GROUPS = null, SITE_LABEL = null;
+
+ function ingest(cfg) {
+ if (!cfg) return false;
+ var groups = Array.isArray(cfg) ? cfg : cfg.groups;
+ if (!groups || !groups.length) return false;
+ GROUPS = groups.map(function (g) {
+ return { title: g.title || 'Menu',
+ items: (g.items || []).filter(function (it) { return it && it[0]; }) };
+ }).filter(function (g) { return g.items.length; });
+ if (!GROUPS.length) { GROUPS = null; return false; }
+ SITE_LABEL = (Array.isArray(cfg) ? null : cfg.site) || null;
+ return true;
+ }
+
+ // (c) auto-discovery fallback — one flat "This site" section from the page's own links.
+ function autoDiscover() {
+ var seen = {}, items = [];
+ document.querySelectorAll('header a[href], footer a[href], nav a[href], .nav a[href]').forEach(function (a) {
+ if (a.closest('.cnav-drawer')) return;
+ var href = a.getAttribute('href') || '';
+ if (/^(mailto:|tel:|javascript:)/i.test(href)) return;
+ if (href.charAt(0) === '#') return;
+ if (/^https?:/i.test(href)) { try { if (new URL(href, location.href).host !== location.host) return; } catch (e) { return; } }
+ var key = norm(href);
+ if (key in seen) return; seen[key] = 1;
+ var label = (a.textContent || '').replace(/\s+/g, ' ').trim().slice(0, 40) || (key || 'Home');
+ items.push([href || '/', label]);
+ });
+ if (!items.length) return false;
+ GROUPS = [{ title: 'This site', items: items }];
+ return true;
+ }
+
+ function groupsTotal() { return GROUPS.reduce(function (n, g) { return n + g.items.length; }, 0); }
+
+ // ── LEFT drawer + RIGHT drawer are (re)built once GROUPS resolve ──────────────────────
+ var left = drawer('left', 'Navigate', 'the whole site');
+ var right = drawer('right', 'On this page', 'jump to a section');
+
+ function buildLeft() {
+ left._body.innerHTML = '';
+ var sub = left.querySelector('.cnav-hd .sub'); if (sub && SITE_LABEL) sub.textContent = SITE_LABEL;
+ GROUPS.forEach(function (g) {
+ var hasCur = g.items.some(function (it) { return norm(it[0]) === CUR; });
+ var sec = section(g.title, { count: g.items.length, current: hasCur });
+ g.items.forEach(function (it) {
+ var a = el('a', norm(it[0]) === CUR ? 'cur' : '', it[1]);
+ a.href = it[0]; a.addEventListener('click', closeAll); sec._list.appendChild(a);
+ });
+ left._body.appendChild(sec);
+ });
+ }
+
+ function slug(s) { return s.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)/g, '').slice(0, 40) || 'sec'; }
+ function buildOnThisPage() {
+ right._body.innerHTML = '';
+ var jump = section('Sections on this page', { current: true });
+ var nodes = Array.prototype.slice.call(document.querySelectorAll('main h2, section > h2, h2.sec, .panel > h3, section > h3'));
+ var seen = {}, count = 0;
+ nodes.forEach(function (n) {
+ if (n.closest('.cnav-drawer')) return;
+ if (!n.offsetParent && n.offsetHeight === 0) return;
+ var txt = (n.textContent || '').replace(/\s+/g, ' ').trim();
+ txt = txt.replace(/^[▸▾▿▶◀⌄˅▼>\s]+/, '');
+ if (!txt) return; txt = txt.slice(0, 46);
+ if (!n.id) { var s = slug(txt), u = s, i = 2; while (document.getElementById(u)) { u = s + '-' + (i++); } n.id = u; }
+ if (seen[n.id]) return; seen[n.id] = 1;
+ var a = el('a', '', txt); a.href = '#' + n.id; a.addEventListener('click', closeAll);
+ jump._list.appendChild(a); count++;
+ });
+ if (count) { jump.querySelector('.rt').insertAdjacentHTML('afterbegin', '<span class="cnt">' + count + '</span>'); right._body.appendChild(jump); }
+ else { right._body.appendChild(el('div', 'cnav-empty', 'No jump-to sections on this page. Use the ☰ menu (top-left) to go to another page.')); }
+ var nav = section('Go to another page', { count: groupsTotal() });
+ GROUPS.forEach(function (g) {
+ g.items.forEach(function (it) {
+ var a = el('a', norm(it[0]) === CUR ? 'cur' : '', it[1]);
+ a.href = it[0]; a.addEventListener('click', closeAll); nav._list.appendChild(a);
+ });
+ });
+ right._body.appendChild(nav);
+ }
+
+ // ── the two hamburgers ──────────────────────────────────────────────────────────────
+ function burger(side, glyph, label, onOpen) {
+ var b = el('button', 'cnav-burger ' + side, glyph + ' <span class="lbl">' + label + '</span>');
+ b.setAttribute('aria-label', label); b.setAttribute('aria-expanded', 'false');
+ var target = side === 'left' ? left : right;
+ b.addEventListener('click', function (e) {
+ e.stopPropagation();
+ if (!GROUPS) return; // nav not resolved yet
+ var open = target.classList.contains('on'); closeAll();
+ if (!open) { if (onOpen) onOpen(); target.classList.add('on'); ov.classList.add('on'); b.setAttribute('aria-expanded', 'true'); }
+ });
+ document.body.appendChild(b); return b;
+ }
+ burger('left', '☰', 'Menu', null);
+ burger('right', '▤', 'Sections', buildOnThisPage);
+
+ // Reserve corner space on the top bar so its title / controls clear the burgers.
+ function reserve() {
+ var bar = document.querySelector('header'); if (!bar) return;
+ var cs = getComputedStyle(bar);
+ bar.style.paddingLeft = Math.max(parseInt(cs.paddingLeft, 10) || 0, 104) + 'px';
+ bar.style.paddingRight = Math.max(parseInt(cs.paddingRight, 10) || 0, 120) + 'px';
+ }
+ // Fold old horizontal top-tabs into the hamburgers: hide inter-page nav LINKS in the header
+ // (every destination lives in the ☰ menu) but LEAVE page controls (sliders, buttons, selects)
+ // and the brand/logo home link.
+ function hideTopTabs() {
+ document.querySelectorAll('header a[href], .topnav a[href], nav.nav a[href], .nav a[href]').forEach(function (a) {
+ if (a.closest('.cnav-drawer')) return;
+ if (a.classList.contains('ns-brand') || a.classList.contains('logo')) return;
+ var href = a.getAttribute('href') || '';
+ if (/\.html([?#].*)?$/i.test(href) || href === '/' || href.charAt(0) === '#' ||
+ (/^\/[a-z0-9\-]+$/i.test(href) && !/^\/(products?|sample|cart|api)\b/i.test(href))) a.style.display = 'none';
+ });
+ ['.topnav', 'nav.nav', 'header .nav'].forEach(function (sel) {
+ document.querySelectorAll(sel).forEach(function (w) {
+ var hasVisibleControl = Array.prototype.some.call(w.children, function (c) {
+ if (c.tagName === 'A') return c.style.display !== 'none';
+ return c.offsetParent !== null || /INPUT|BUTTON|SELECT|SPAN|LABEL/.test(c.tagName);
+ });
+ if (!hasVisibleControl) w.style.display = 'none';
+ });
+ });
+ }
+ // Some fleet sites carry OTHER fixed top-corner controls (e.g. dw-fleet-nav's
+ // brand-switcher trigger, top-right). Nudge our burger clear of any pre-existing
+ // fixed control sharing its corner+row so the two never stack. Idempotent & re-runnable.
+ function avoidCollisions() {
+ var vw = window.innerWidth;
+ ['left', 'right'].forEach(function (side) {
+ var burger = document.querySelector('.cnav-burger.' + side); if (!burger) return;
+ burger.style[side] = '10px'; // reset before re-measuring (so resize recomputes cleanly)
+ var br = burger.getBoundingClientRect();
+ var need = 0;
+ document.querySelectorAll('body *').forEach(function (e) {
+ if (!e.getBoundingClientRect) return;
+ if (e.closest('.cnav-burger') || e.closest('.cnav-drawer') || (e.classList && e.classList.contains('cnav-ov'))) return;
+ var cs = getComputedStyle(e);
+ if (cs.position !== 'fixed' || cs.display === 'none' || cs.visibility === 'hidden' || parseFloat(cs.opacity) === 0) return;
+ var r = e.getBoundingClientRect();
+ if (r.width < 8 || r.height < 8) return;
+ if (r.top > br.bottom + 6 || r.bottom < br.top - 6) return; // different row — ignore
+ if (side === 'right') { if ((vw - r.right) < 220 && r.left < vw - 10) { var s = vw - r.left; if (s > need) need = s; } }
+ else { if (r.left < 220 && r.right > 10) { if (r.right > need) need = r.right; } }
+ });
+ if (need > 0) burger.style[side] = (need + 8) + 'px';
+ });
+ }
+ function apply() { reserve(); hideTopTabs(); avoidCollisions(); }
+ var _rt; window.addEventListener('resize', function () { clearTimeout(_rt); _rt = setTimeout(avoidCollisions, 150); });
+
+ // ── resolve the nav, then wire everything ────────────────────────────────────────────
+ function ready(fn) { if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', fn); else fn(); }
+ function finish() { buildLeft(); apply(); }
+
+ // (a) inline config wins immediately (no fetch)
+ if (ingest(window.CORNER_NAV_CONFIG)) {
+ ready(finish);
+ } else {
+ // (b) fetch the per-site manifest, then (c) auto-discover on any failure
+ var url = (window.CORNER_NAV_MANIFEST || '/corner-nav.manifest.json');
+ fetch(url, { credentials: 'same-origin' })
+ .then(function (r) { return r.ok ? r.json() : null; })
+ .then(function (j) { ingest(j); })
+ .catch(function () { /* fall through to auto-discover below */ })
+ .finally(function () {
+ ready(function () {
+ if (!GROUPS && !autoDiscover()) GROUPS = [{ title: 'This site', items: [['/', 'Home']] }];
+ finish();
+ });
+ });
+ }
+})();
diff --git a/public/corner-nav.manifest.json b/public/corner-nav.manifest.json
new file mode 100644
index 0000000..bc1bc21
--- /dev/null
+++ b/public/corner-nav.manifest.json
@@ -0,0 +1,27 @@
+{
+ "site": "Linen Wallpaper",
+ "groups": [
+ {
+ "title": "Browse",
+ "items": [
+ ["/", "■ Shop Linen"]
+ ]
+ },
+ {
+ "title": "The Material",
+ "items": [
+ ["/history", "📜 History"],
+ ["/sourcing", "🌿 Sourcing"],
+ ["/care", "🧽 Care & Cleaning"],
+ ["/vocabulary", "📖 Vocabulary"]
+ ]
+ },
+ {
+ "title": "Work With Us",
+ "items": [
+ ["/trade", "🤝 Trade Program"],
+ ["/about", "ℹ️ About"]
+ ]
+ }
+ ]
+}
diff --git a/public/history.html b/public/history.html
index f02220b..2ebcfe3 100644
--- a/public/history.html
+++ b/public/history.html
@@ -49,4 +49,8 @@ nav.foot a{margin-right:22px;text-decoration:none}
<a href="/trade">Trade</a>
<a href="/about">About</a>
</nav>
-</div></body></html>
\ No newline at end of file
+</div>
+ <!-- fleet corner-nav (corner-nav-fanout.js) -->
+ <style>:root{--cnav-drawer-bg:#1a1714;--cnav-burger-bg:rgba(26,23,20,.92);--cnav-fg:#f0e9dc;--cnav-muted:#a89b85;--cnav-accent:#9B7B4F;--cnav-line:#3a3228;--cnav-sec-line:#2a241c;}</style>
+ <script src="/corner-nav-accordion.js" defer></script>
+</body></html>
\ No newline at end of file
diff --git a/public/index.html b/public/index.html
index ae4164c..dbc4a9d 100644
--- a/public/index.html
+++ b/public/index.html
@@ -1775,5 +1775,9 @@ async function renderRailSections(){
<script src="/dw-header.js" defer></script>
<!-- DW network ad slot -->
<script src="https://ads.agentabrams.com/embed.js" data-slot="footer-strip"></script>
+
+ <!-- fleet corner-nav (corner-nav-fanout.js) -->
+ <style>:root{--cnav-drawer-bg:#1a1714;--cnav-burger-bg:rgba(26,23,20,.92);--cnav-fg:#f0e9dc;--cnav-muted:#a89b85;--cnav-accent:#9B7B4F;--cnav-line:#3a3228;--cnav-sec-line:#2a241c;}</style>
+ <script src="/corner-nav-accordion.js" defer></script>
</body>
</html>
diff --git a/public/sourcing.html b/public/sourcing.html
index ba463e1..704e1d9 100644
--- a/public/sourcing.html
+++ b/public/sourcing.html
@@ -59,4 +59,8 @@ nav.foot a{margin-right:22px;text-decoration:none}
<a href="/trade">Trade</a>
<a href="/about">About</a>
</nav>
-</div></body></html>
\ No newline at end of file
+</div>
+ <!-- fleet corner-nav (corner-nav-fanout.js) -->
+ <style>:root{--cnav-drawer-bg:#1a1714;--cnav-burger-bg:rgba(26,23,20,.92);--cnav-fg:#f0e9dc;--cnav-muted:#a89b85;--cnav-accent:#9B7B4F;--cnav-line:#3a3228;--cnav-sec-line:#2a241c;}</style>
+ <script src="/corner-nav-accordion.js" defer></script>
+</body></html>
\ No newline at end of file
diff --git a/public/trade.html b/public/trade.html
index 7c8d620..e684a5f 100644
--- a/public/trade.html
+++ b/public/trade.html
@@ -63,4 +63,8 @@ nav.foot a{margin-right:22px;text-decoration:none}
<a href="/trade">Trade</a>
<a href="/about">About</a>
</nav>
-</div></body></html>
\ No newline at end of file
+</div>
+ <!-- fleet corner-nav (corner-nav-fanout.js) -->
+ <style>:root{--cnav-drawer-bg:#1a1714;--cnav-burger-bg:rgba(26,23,20,.92);--cnav-fg:#f0e9dc;--cnav-muted:#a89b85;--cnav-accent:#9B7B4F;--cnav-line:#3a3228;--cnav-sec-line:#2a241c;}</style>
+ <script src="/corner-nav-accordion.js" defer></script>
+</body></html>
\ No newline at end of file
diff --git a/public/vocabulary.html b/public/vocabulary.html
index 4da3ef8..0411a5d 100644
--- a/public/vocabulary.html
+++ b/public/vocabulary.html
@@ -46,4 +46,8 @@ nav.foot a{margin-right:22px;text-decoration:none}
<a href="/trade">Trade</a>
<a href="/about">About</a>
</nav>
-</div></body></html>
\ No newline at end of file
+</div>
+ <!-- fleet corner-nav (corner-nav-fanout.js) -->
+ <style>:root{--cnav-drawer-bg:#1a1714;--cnav-burger-bg:rgba(26,23,20,.92);--cnav-fg:#f0e9dc;--cnav-muted:#a89b85;--cnav-accent:#9B7B4F;--cnav-line:#3a3228;--cnav-sec-line:#2a241c;}</style>
+ <script src="/corner-nav-accordion.js" defer></script>
+</body></html>
\ No newline at end of file
← 2aa6b1b Revert AdSense: DW sister sites stay ad-free (Steve policy 2
·
back to Linenwallpaper
·
viewer standard: add per-field on/off menu (Fields ▾) to pro c565a51 →