-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscript.js
More file actions
134 lines (123 loc) · 11.7 KB
/
Copy pathscript.js
File metadata and controls
134 lines (123 loc) · 11.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
const pages = window.StraddieTipLoopPages || [
{ id: "home", label: "Home", href: "index.html" },
{ id: "streams", label: "Streams", href: "streams.html" },
{ id: "loop", label: "Loop", href: "loop.html" },
{ id: "microfactory", label: "Microfactory", href: "microfactory.html" },
{ id: "governance", label: "Governance", href: "governance.html" },
{ id: "ecosystem", label: "Ecosystem", href: "ecosystem.html" },
{ id: "forms", label: "Forms", href: "forms.html" },
{ id: "sources", label: "Sources", href: "sources.html" }
];
const pageId = document.body.dataset.page || "home";
function icon(kind) {
const icons = {
streams: '<svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M4 7h16"/><path d="M4 12h16"/><path d="M4 17h16"/><circle cx="7" cy="7" r="2"/><circle cx="13" cy="12" r="2"/><circle cx="18" cy="17" r="2"/></svg>',
loop: '<svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M7 7h8a4 4 0 0 1 0 8H9"/><path d="m7 7 3-3"/><path d="M7 7l3 3"/><path d="m17 15-3-3"/><path d="m17 15-3 3"/></svg>',
robot: '<svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="5" y="8" width="14" height="10" rx="2"/><path d="M12 8V4"/><circle cx="9" cy="13" r="1"/><circle cx="15" cy="13" r="1"/><path d="M9 17h6"/><path d="M3 12h2"/><path d="M19 12h2"/></svg>',
ledger: '<svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M6 4h12v16H6z"/><path d="M9 8h6"/><path d="M9 12h6"/><path d="M9 16h3"/></svg>',
network: '<svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="6" cy="12" r="3"/><circle cx="18" cy="6" r="3"/><circle cx="18" cy="18" r="3"/><path d="m8.6 10.6 6.8-3.2"/><path d="m8.6 13.4 6.8 3.2"/></svg>',
clipboard: '<svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M9 4h6a2 2 0 0 1 2 2v1H7V6a2 2 0 0 1 2-2z"/><path d="M7 6H5v15h14V6h-2"/><path d="M8 12h8"/><path d="M8 16h6"/></svg>',
plastic: '<svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M9 3h6l1 4v13H8V7z"/><path d="M9 7h6"/><path d="M10 12h4"/><path d="M10 16h4"/></svg>',
metal: '<svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M4 17h16"/><path d="M6 17 9 7h6l3 10"/><path d="M8 13h8"/><path d="M10 7V4h4v3"/></svg>',
cardboard: '<svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M4 8 12 4l8 4v9l-8 4-8-4z"/><path d="M4 8l8 4 8-4"/><path d="M12 12v9"/></svg>',
glass: '<svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M9 3h6l-1 7v8l2 2H8l2-2v-8z"/><path d="M9.5 9h5"/><path d="M10 15h4"/></svg>',
circuit: '<svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="5" y="5" width="14" height="14" rx="2"/><path d="M9 9h6v6H9z"/><path d="M3 9h2"/><path d="M3 15h2"/><path d="M19 9h2"/><path d="M19 15h2"/><path d="M9 3v2"/><path d="M15 3v2"/><path d="M9 19v2"/><path d="M15 19v2"/></svg>',
timber: '<svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M4 8h16v8H4z"/><path d="M7 8v8"/><path d="M12 8v8"/><path d="M17 8v8"/></svg>',
handover: '<svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M4 14h5l2 2h4l5-5"/><path d="M4 18h12"/><path d="M15 6h5v5"/><path d="M14 12 20 6"/></svg>',
bench: '<svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M4 10h16"/><path d="M6 10v9"/><path d="M18 10v9"/><path d="M7 6h10v4H7z"/></svg>',
lock: '<svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="5" y="11" width="14" height="9" rx="2"/><path d="M8 11V8a4 4 0 0 1 8 0v3"/><path d="M12 15v2"/></svg>',
ai: '<svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3v18"/><path d="M5 8a4 4 0 0 1 7-2"/><path d="M19 8a4 4 0 0 0-7-2"/><path d="M5 16a4 4 0 0 0 7 2"/><path d="M19 16a4 4 0 0 1-7 2"/><path d="M8 12h8"/></svg>',
printer: '<svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M6 5h12v5H6z"/><path d="M5 14h14v6H5z"/><path d="M9 10v4"/><path d="M15 10v4"/><path d="M9 17h6"/></svg>',
hour: '<svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="8"/><path d="M12 7v5l3 2"/><path d="M4 20h16"/></svg>',
shield: '<svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3 5 6v5c0 5 3 8 7 10 4-2 7-5 7-10V6z"/><path d="m9 12 2 2 4-5"/></svg>',
shed: '<svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M3 21V9l9-6 9 6v12"/><path d="M7 21v-8h10v8"/><path d="M9 16h6"/></svg>',
sandworm: '<svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M4 16c3-7 13-7 16 0"/><path d="M6 16c2 4 10 4 12 0"/><path d="M8 12h8"/><path d="M10 8h4"/></svg>',
sand: '<svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19h16"/><path d="M6 17 12 5l6 12"/><path d="M9 15h6"/><path d="M11 11h2"/></svg>',
energy: '<svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M13 2 5 13h6l-1 9 9-12h-6z"/></svg>',
map: '<svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="m4 6 5-2 6 2 5-2v14l-5 2-6-2-5 2z"/><path d="M9 4v14"/><path d="M15 6v14"/></svg>',
trust: '<svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M7 11l5 5 5-5"/><path d="M5 7l7-4 7 4v6c0 4-3 7-7 8-4-1-7-4-7-8z"/></svg>',
screen: '<svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="4" y="5" width="16" height="11" rx="2"/><path d="M8 21h8"/><path d="M12 16v5"/></svg>',
grant: '<svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M6 4h12v16H6z"/><path d="M9 8h6"/><path d="M9 12h6"/><path d="m9 17 2 1 4-4"/></svg>',
legal: '<svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3v18"/><path d="M5 7h14"/><path d="M6 7l-3 6h6z"/><path d="M18 7l-3 6h6z"/><path d="M8 21h8"/></svg>',
source: '<svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M6 4h9l3 3v13H6z"/><path d="M14 4v4h4"/><path d="M8 12h8"/><path d="M8 16h6"/></svg>'
};
return icons[kind] || icons.streams;
}
function renderHeader() {
const header = document.querySelector("[data-site-header]");
if (!header) return;
header.className = "site-header";
header.innerHTML = `
<a class="skip-link" href="#main">Skip to content</a>
<nav class="nav" aria-label="Main navigation">
<a class="brand-mark" href="index.html" aria-label="Straddie Tip Loop Lab home">
<span>Straddie</span>
<span>Tip Loop Lab</span>
</a>
<button class="nav-toggle" type="button" aria-label="Open menu" aria-expanded="false">
<span></span><span></span><span></span>
</button>
<div class="nav-links">
${pages.map((page) => `<a href="${page.href}" ${page.id === pageId ? 'aria-current="page"' : ""}>${page.label}</a>`).join("")}
</div>
</nav>
`;
const toggle = header.querySelector(".nav-toggle");
toggle.addEventListener("click", () => {
const isOpen = document.body.classList.toggle("nav-open");
toggle.setAttribute("aria-expanded", String(isOpen));
toggle.setAttribute("aria-label", isOpen ? "Close menu" : "Open menu");
});
}
function renderFooter() {
const footer = document.querySelector("[data-site-footer]");
if (!footer) return;
const index = Math.max(0, pages.findIndex((page) => page.id === pageId));
const previous = pages[(index - 1 + pages.length) % pages.length];
const next = pages[(index + 1) % pages.length];
footer.className = "site-footer";
footer.innerHTML = `
<nav class="sequence-nav" aria-label="Previous and next pages">
<a href="${previous.href}"><span>Previous</span><strong>${previous.label}</strong></a>
<a href="${next.href}"><span>Next</span><strong>${next.label}</strong></a>
</nav>
<div class="footer-inner">
<p>Straddie Tip Loop Lab is a public Strange But True family prototype. It is a proposal and learning map, not an approval claim.</p>
<div class="footer-links">
<a href="https://auraofintelligence.github.io/straddie-tip-loop-lab/">Live site</a>
<a href="https://github.com/auraofintelligence/straddie-tip-loop-lab">Source repo</a>
<a href="https://auraofintelligence.github.io/straddie-makerspace-lab/tip-loop.html">Maker-space seed page</a>
<a href="LICENCE.md">Licence</a>
</div>
</div>
`;
}
function setupBackToTop() {
const button = document.createElement("button");
button.className = "back-to-top";
button.type = "button";
button.setAttribute("aria-label", "Back to top");
button.title = "Back to top";
button.innerHTML = '<svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="m6 15 6-6 6 6"/></svg>';
document.body.append(button);
button.addEventListener("click", () => window.scrollTo({ top: 0, behavior: "smooth" }));
const update = () => button.classList.toggle("is-visible", window.scrollY > 500);
update();
window.addEventListener("scroll", update, { passive: true });
}
function setupExternalLinks() {
document.querySelectorAll('a[href^="http://"], a[href^="https://"]').forEach((link) => {
link.target = "_blank";
const rel = new Set((link.getAttribute("rel") || "").split(/\s+/).filter(Boolean));
rel.add("noopener");
rel.add("noreferrer");
link.setAttribute("rel", [...rel].join(" "));
});
}
renderHeader();
renderFooter();
setupBackToTop();
setupExternalLinks();
document.querySelectorAll("[data-icon]").forEach((node) => {
node.innerHTML = icon(node.dataset.icon);
});