This commit is contained in:
+118
-26
@@ -4,45 +4,137 @@
|
||||
|
||||
const reducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
||||
const sequence = [
|
||||
["projects", 180], ["articles", 320], ["blog", 460],
|
||||
["github", 820], ["gitea", 930], ["linkedin", 1040],
|
||||
["twitch", 1150], ["youtube", 1260], ["kofi", 1370],
|
||||
{ name: "projects", travel: 620, character: 62 },
|
||||
{ name: "articles", travel: 600, character: 58 },
|
||||
{ name: "blog", travel: 560, character: 72 },
|
||||
{ name: "github", travel: 380, character: 46 },
|
||||
{ name: "gitea", travel: 360, character: 48 },
|
||||
{ name: "linkedin", travel: 360, character: 42 },
|
||||
{ name: "twitch", travel: 340, character: 46 },
|
||||
{ name: "youtube", travel: 360, character: 42 },
|
||||
{ name: "kofi", travel: 320, character: 50 },
|
||||
];
|
||||
let run = 0;
|
||||
let timers = [];
|
||||
|
||||
const clearTimers = () => {
|
||||
timers.forEach(window.clearTimeout);
|
||||
timers = [];
|
||||
let runToken = 0;
|
||||
const sleep = (milliseconds) => new Promise((resolve) => window.setTimeout(resolve, milliseconds));
|
||||
|
||||
const reset = () => {
|
||||
hero.classList.remove("is-glitching");
|
||||
hero.querySelectorAll(".circuit-node").forEach((node) => {
|
||||
node.classList.remove("is-revealing", "is-ready");
|
||||
node.querySelector("[data-route-output]").textContent = "";
|
||||
const cursor = node.querySelector("i");
|
||||
if (cursor) cursor.hidden = false;
|
||||
});
|
||||
hero.querySelectorAll(".circuit-live path").forEach((path) => {
|
||||
path.style.opacity = "0";
|
||||
path.style.strokeDashoffset = "0";
|
||||
});
|
||||
};
|
||||
|
||||
const revealAll = () => {
|
||||
hero.querySelectorAll(".circuit-node").forEach((node) => node.classList.add("is-ready"));
|
||||
hero.querySelectorAll(".circuit-live path").forEach((path) => path.classList.add("is-live"));
|
||||
hero.querySelectorAll(".circuit-node").forEach((node) => {
|
||||
node.querySelector("[data-route-output]").textContent = node.dataset.routeText;
|
||||
const cursor = node.querySelector("i");
|
||||
if (cursor) cursor.hidden = true;
|
||||
node.classList.add("is-revealing", "is-ready");
|
||||
});
|
||||
hero.querySelectorAll(".circuit-live path").forEach((path) => {
|
||||
path.style.opacity = ".34";
|
||||
});
|
||||
};
|
||||
|
||||
const start = () => {
|
||||
run += 1;
|
||||
const token = run;
|
||||
clearTimers();
|
||||
hero.classList.remove("is-glitching");
|
||||
hero.querySelectorAll(".circuit-node").forEach((node) => node.classList.remove("is-ready"));
|
||||
hero.querySelectorAll(".circuit-live path").forEach((path) => path.classList.remove("is-live"));
|
||||
const animatePath = (path, duration, token) => {
|
||||
const length = path.getTotalLength();
|
||||
path.style.strokeDasharray = `30 ${Math.max(40, length)}`;
|
||||
path.style.strokeDashoffset = "30";
|
||||
path.style.opacity = "1";
|
||||
|
||||
return new Promise((resolve) => {
|
||||
const started = performance.now();
|
||||
const frame = (now) => {
|
||||
if (token !== runToken) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
const progress = Math.min(1, (now - started) / duration);
|
||||
const eased = 1 - Math.pow(1 - progress, 3);
|
||||
path.style.strokeDashoffset = String(30 - (length + 55) * eased);
|
||||
if (progress < 1) {
|
||||
requestAnimationFrame(frame);
|
||||
} else {
|
||||
path.style.opacity = ".34";
|
||||
resolve();
|
||||
}
|
||||
};
|
||||
requestAnimationFrame(frame);
|
||||
});
|
||||
};
|
||||
|
||||
const typeRoute = async (node, characterDelay, token) => {
|
||||
const output = node.querySelector("[data-route-output]");
|
||||
node.classList.add("is-revealing");
|
||||
for (const character of node.dataset.routeText) {
|
||||
if (token !== runToken) return;
|
||||
output.textContent += character;
|
||||
await sleep(characterDelay);
|
||||
}
|
||||
const cursor = node.querySelector("i");
|
||||
if (cursor) cursor.hidden = true;
|
||||
node.classList.add("is-ready");
|
||||
};
|
||||
|
||||
const animateAmbientPackets = () => {
|
||||
if (reducedMotion) return;
|
||||
hero.querySelectorAll(".circuit-ambient-packets path").forEach((packet, index) => {
|
||||
const length = packet.getTotalLength();
|
||||
packet.style.strokeDasharray = `16 ${Math.max(30, length)}`;
|
||||
packet.animate(
|
||||
[
|
||||
{ strokeDashoffset: "20", opacity: .06 },
|
||||
{ opacity: .2, offset: .18 },
|
||||
{ opacity: .2, offset: .82 },
|
||||
{ strokeDashoffset: String(-(length + 25)), opacity: .05 },
|
||||
],
|
||||
{ duration: 3300 + (index % 5) * 620, delay: index * 210, iterations: Infinity, easing: "linear" },
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
const runSequence = async () => {
|
||||
runToken += 1;
|
||||
const token = runToken;
|
||||
|
||||
if (reducedMotion) {
|
||||
reset();
|
||||
revealAll();
|
||||
return;
|
||||
}
|
||||
|
||||
sequence.forEach(([name, delay]) => {
|
||||
timers.push(window.setTimeout(() => {
|
||||
if (token !== run) return;
|
||||
hero.querySelector(`[data-route-node="${name}"]`)?.classList.add("is-ready");
|
||||
hero.querySelector(`#route-${name}`)?.classList.add("is-live");
|
||||
}, delay));
|
||||
});
|
||||
while (token === runToken) {
|
||||
reset();
|
||||
await sleep(280);
|
||||
|
||||
for (const item of sequence) {
|
||||
if (token !== runToken) return;
|
||||
const node = hero.querySelector(`[data-route-node="${item.name}"]`);
|
||||
const path = hero.querySelector(`#route-${item.name}`);
|
||||
await animatePath(path, item.travel, token);
|
||||
await typeRoute(node, item.character, token);
|
||||
await sleep(55);
|
||||
}
|
||||
|
||||
await sleep(3000);
|
||||
if (token !== runToken) return;
|
||||
hero.classList.add("is-glitching");
|
||||
await sleep(430);
|
||||
if (token !== runToken) return;
|
||||
reset();
|
||||
await sleep(180);
|
||||
}
|
||||
};
|
||||
|
||||
hero.querySelector("[data-circuit-replay]")?.addEventListener("click", start);
|
||||
start();
|
||||
hero.querySelector("[data-circuit-replay]")?.addEventListener("click", runSequence);
|
||||
animateAmbientPackets();
|
||||
runSequence();
|
||||
})();
|
||||
|
||||
+94
-23
@@ -96,7 +96,7 @@ h1 { max-width: 880px; margin: 0; font-size: clamp(30px, 4vw, 45px); font-style:
|
||||
z-index: 10;
|
||||
top: clamp(72px, 11vh, 104px);
|
||||
left: clamp(28px, 5vw, 72px);
|
||||
width: min(610px, 64vw);
|
||||
width: min(640px, 64vw);
|
||||
}
|
||||
.circuit-brand-kicker {
|
||||
margin: 0 0 12px;
|
||||
@@ -108,14 +108,20 @@ h1 { max-width: 880px; margin: 0; font-size: clamp(30px, 4vw, 45px); font-style:
|
||||
.circuit-brand-block h1 {
|
||||
max-width: none;
|
||||
margin: 0;
|
||||
font: 700 clamp(45px, 7vw, 98px)/.86 var(--serif);
|
||||
font: 700 clamp(45px, 7vw, 98px)/.86 Georgia, "Times New Roman", serif;
|
||||
font-style: normal;
|
||||
letter-spacing: -.055em;
|
||||
text-shadow: 0 0 24px rgba(197,160,89,.05);
|
||||
}
|
||||
.circuit-dek {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
display: inline-block;
|
||||
max-width: 430px;
|
||||
margin-top: 22px;
|
||||
padding-right: 8px;
|
||||
background: rgba(7,8,8,.94);
|
||||
box-shadow: 10px 0 16px rgba(7,8,8,.98);
|
||||
color: var(--muted);
|
||||
font-size: clamp(15px, 1.6vw, 17px);
|
||||
}
|
||||
@@ -147,25 +153,32 @@ h1 { max-width: 880px; margin: 0; font-size: clamp(30px, 4vw, 45px); font-style:
|
||||
.circuit-ambient path { stroke: #1d2221; stroke-width: 1; opacity: .72; }
|
||||
.circuit-ambient path:nth-child(3n+1) { stroke: rgba(101,247,255,.22); }
|
||||
.circuit-ambient path:nth-child(3n+2) { stroke: rgba(255,79,216,.16); }
|
||||
.circuit-ghost path { stroke: #020303; stroke-width: 8; opacity: .9; }
|
||||
.circuit-ambient-packets path {
|
||||
stroke: rgba(101,247,255,.38);
|
||||
stroke-width: 1;
|
||||
stroke-linecap: square;
|
||||
opacity: .18;
|
||||
filter: drop-shadow(0 0 2px rgba(101,247,255,.22));
|
||||
}
|
||||
.circuit-ambient-packets path.circuit-live-alt { stroke: rgba(255,79,216,.3); filter: drop-shadow(0 0 2px rgba(255,79,216,.18)); }
|
||||
.circuit-ambient-packets path.circuit-live-gold { stroke: rgba(197,160,89,.3); filter: drop-shadow(0 0 2px rgba(197,160,89,.16)); }
|
||||
.circuit-ghost path { stroke: rgba(197,160,89,.08); stroke-width: 4; filter: blur(4px); }
|
||||
.circuit-base path,
|
||||
.circuit-traces path,
|
||||
.circuit-live path { stroke: #303837; stroke-width: 2; }
|
||||
.circuit-live path { stroke: #282b2a; stroke-width: 1.35; }
|
||||
.circuit-live path {
|
||||
opacity: .34;
|
||||
opacity: 0;
|
||||
stroke: var(--circuit-cyan);
|
||||
stroke-dasharray: 22 52;
|
||||
stroke-width: 1.55;
|
||||
stroke-linecap: square;
|
||||
stroke-dasharray: 30 9999;
|
||||
filter: drop-shadow(0 0 5px rgba(101,247,255,.36));
|
||||
transition: opacity .35s ease;
|
||||
}
|
||||
.circuit-live path.circuit-live-alt {
|
||||
stroke: var(--circuit-pink);
|
||||
filter: drop-shadow(0 0 5px rgba(255,79,216,.3));
|
||||
}
|
||||
.js .circuit-live path { opacity: 0; }
|
||||
.js .circuit-live path.is-live {
|
||||
opacity: .82;
|
||||
animation: circuit-packet 1.65s linear infinite;
|
||||
}
|
||||
.circuit-vias circle {
|
||||
fill: #090b0b;
|
||||
stroke: var(--circuit-cyan);
|
||||
@@ -186,7 +199,15 @@ h1 { max-width: 880px; margin: 0; font-size: clamp(30px, 4vw, 45px); font-style:
|
||||
transition: opacity .28s ease, transform .28s ease, color .2s ease, filter .2s ease;
|
||||
}
|
||||
.js .circuit-node { opacity: .22; transform: translateY(3px); pointer-events: none; }
|
||||
.js .circuit-node.is-revealing,
|
||||
.js .circuit-node.is-ready { opacity: 1; transform: none; pointer-events: auto; }
|
||||
.circuit-node > span,
|
||||
.circuit-node > i {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
background: rgba(7,8,8,.95);
|
||||
box-shadow: 0 0 0 5px rgba(7,8,8,.95);
|
||||
}
|
||||
.circuit-node::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
@@ -208,12 +229,12 @@ h1 { max-width: 880px; margin: 0; font-size: clamp(30px, 4vw, 45px); font-style:
|
||||
.circuit-node[data-route-node="projects"] { left: 67%; top: 27%; }
|
||||
.circuit-node[data-route-node="articles"] { left: 72%; top: 47%; }
|
||||
.circuit-node[data-route-node="blog"] { left: 61%; top: 68%; }
|
||||
.circuit-node[data-route-node="github"] { left: 27%; top: 73%; }
|
||||
.circuit-node[data-route-node="gitea"] { left: 36%; top: 81%; }
|
||||
.circuit-node[data-route-node="linkedin"] { left: 49%; top: 87%; }
|
||||
.circuit-node[data-route-node="twitch"] { left: 63%; top: 91%; }
|
||||
.circuit-node[data-route-node="youtube"] { left: 77%; top: 83%; }
|
||||
.circuit-node[data-route-node="kofi"] { left: 88%; top: 72%; }
|
||||
.circuit-node[data-route-node="github"] { left: 22%; top: 62%; }
|
||||
.circuit-node[data-route-node="gitea"] { left: 28%; top: 72%; }
|
||||
.circuit-node[data-route-node="linkedin"] { left: 42%; top: 82%; }
|
||||
.circuit-node[data-route-node="twitch"] { left: 58%; top: 86%; }
|
||||
.circuit-node[data-route-node="youtube"] { left: 74%; top: 80%; }
|
||||
.circuit-node[data-route-node="kofi"] { left: 84%; top: 72%; }
|
||||
.circuit-legend {
|
||||
position: absolute;
|
||||
z-index: 12;
|
||||
@@ -246,9 +267,45 @@ h1 { max-width: 880px; margin: 0; font-size: clamp(30px, 4vw, 45px); font-style:
|
||||
.circuit-replay:hover,
|
||||
.circuit-replay:focus-visible { border-color: var(--circuit-cyan); color: var(--circuit-cyan); }
|
||||
|
||||
@keyframes circuit-packet { to { stroke-dashoffset: -74; } }
|
||||
@keyframes circuit-cursor { 50% { opacity: 0; } }
|
||||
@keyframes circuit-pulse { 50% { opacity: .35; transform: scale(.8); } }
|
||||
@keyframes circuit-hero-glitch {
|
||||
0% { transform: translate(0); filter: none; }
|
||||
18% { transform: translate(3px,-1px); filter: contrast(1.25) saturate(1.3); }
|
||||
34% { transform: translate(-5px,1px); }
|
||||
52% { transform: translate(2px,0); clip-path: inset(0 0 38% 0); }
|
||||
70% { transform: translate(-2px,1px); clip-path: inset(35% 0 0); }
|
||||
86% { transform: translate(4px,-1px); filter: contrast(1.4) saturate(1.5); }
|
||||
100% { transform: translate(0); filter: brightness(.18); }
|
||||
}
|
||||
@keyframes circuit-node-glitch {
|
||||
0%, 100% { transform: translate(0); }
|
||||
25% { transform: translate(7px,-1px); }
|
||||
50% { transform: translate(-6px,1px); }
|
||||
75% { transform: translate(3px,0); }
|
||||
}
|
||||
@keyframes circuit-stage-glitch {
|
||||
0%, 100% { transform: translate(0); }
|
||||
30% { transform: translate(-6px,0); }
|
||||
55% { transform: translate(8px,1px); }
|
||||
80% { transform: translate(-3px,-1px); }
|
||||
}
|
||||
@keyframes circuit-scan-tear {
|
||||
0% { transform: translateY(0); }
|
||||
33% { transform: translateY(-8px); }
|
||||
66% { transform: translateY(11px); }
|
||||
100% { transform: translateY(0); }
|
||||
}
|
||||
.circuit-hero.is-glitching { animation: circuit-hero-glitch .42s steps(2,end) both; }
|
||||
.circuit-hero.is-glitching .circuit-node {
|
||||
animation: circuit-node-glitch .42s steps(2,end) both;
|
||||
text-shadow: 4px 0 rgba(101,247,255,.8), -4px 0 rgba(255,79,216,.65);
|
||||
}
|
||||
.circuit-hero.is-glitching .circuit-stage {
|
||||
animation: circuit-stage-glitch .42s steps(2,end) both;
|
||||
filter: drop-shadow(5px 0 rgba(101,247,255,.45)) drop-shadow(-5px 0 rgba(255,79,216,.35));
|
||||
}
|
||||
.circuit-hero.is-glitching::after { opacity: .85; animation: circuit-scan-tear .42s steps(3,end) both; }
|
||||
|
||||
.activity-section { min-height: 370px; padding: 48px 0 72px; }
|
||||
.homepage-discovery-grid { display: grid; grid-template-columns: minmax(0, 1.65fr) minmax(290px, 1fr); gap: 36px; align-items: start; }
|
||||
@@ -568,6 +625,21 @@ h1 { max-width: 880px; margin: 0; font-size: clamp(30px, 4vw, 45px); font-style:
|
||||
.footer-inner { min-height: 105px; display: flex; justify-content: space-between; align-items: center; gap: 24px; }
|
||||
.site-footer nav { display: flex; gap: 22px; }
|
||||
|
||||
@media (max-width: 860px) and (min-width: 721px) {
|
||||
.circuit-hero { height: 720px; min-height: 720px; }
|
||||
.circuit-brand-block { width: 72vw; }
|
||||
.circuit-node[data-route-node="projects"] { left: 58%; top: 36%; }
|
||||
.circuit-node[data-route-node="articles"] { left: 61%; top: 49%; }
|
||||
.circuit-node[data-route-node="blog"] { left: 55%; top: 61%; }
|
||||
.circuit-node[data-route-node="github"] { left: 20%; top: 72%; }
|
||||
.circuit-node[data-route-node="gitea"] { left: 38%; top: 76%; }
|
||||
.circuit-node[data-route-node="linkedin"] { left: 57%; top: 73%; }
|
||||
.circuit-node[data-route-node="twitch"] { left: 20%; top: 83%; }
|
||||
.circuit-node[data-route-node="youtube"] { left: 42%; top: 87%; }
|
||||
.circuit-node[data-route-node="kofi"] { left: 70%; top: 84%; }
|
||||
.circuit-legend { display: none; }
|
||||
}
|
||||
|
||||
@media (max-width: 720px) {
|
||||
.shell { width: min(100% - 28px, 1100px); }
|
||||
.narrow { margin-inline: auto; }
|
||||
@@ -588,11 +660,11 @@ h1 { max-width: 880px; margin: 0; font-size: clamp(30px, 4vw, 45px); font-style:
|
||||
.circuit-node[data-route-node="articles"] { left: 38%; top: 53%; }
|
||||
.circuit-node[data-route-node="blog"] { left: 28%; top: 64%; }
|
||||
.circuit-node[data-route-node="github"] { left: 18%; top: 74%; }
|
||||
.circuit-node[data-route-node="gitea"] { left: 56%; top: 74%; }
|
||||
.circuit-node[data-route-node="gitea"] { left: 53%; top: 74%; }
|
||||
.circuit-node[data-route-node="linkedin"] { left: 18%; top: 81%; }
|
||||
.circuit-node[data-route-node="twitch"] { left: 60%; top: 81%; }
|
||||
.circuit-node[data-route-node="twitch"] { left: 56%; top: 81%; }
|
||||
.circuit-node[data-route-node="youtube"] { left: 18%; top: 88%; }
|
||||
.circuit-node[data-route-node="kofi"] { left: 64%; top: 88%; }
|
||||
.circuit-node[data-route-node="kofi"] { left: 60%; top: 88%; }
|
||||
.circuit-legend { display: none; }
|
||||
.circuit-replay { left: 16px; bottom: 13px; }
|
||||
h1 { font-size: 30px; }
|
||||
@@ -657,6 +729,5 @@ h1 { max-width: 880px; margin: 0; font-size: clamp(30px, 4vw, 45px); font-style:
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.circuit-status span,
|
||||
.circuit-node-main i,
|
||||
.circuit-live path.is-live { animation: none; }
|
||||
.circuit-node-main i { animation: none; }
|
||||
}
|
||||
|
||||
+2
-2
@@ -9,10 +9,10 @@
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&family=Inter:wght@400;500&family=Playfair+Display:ital,wght@0,600;0,700;1,500;1,600&display=swap" rel="stylesheet">
|
||||
<link rel="icon" href="{{ '/static/favicon.svg'|url }}" type="image/svg+xml">
|
||||
<link rel="stylesheet" href="{{ '/static/style.css'|url }}?v=14">
|
||||
<link rel="stylesheet" href="{{ '/static/style.css'|url }}?v=15">
|
||||
<script src="{{ '/static/tags.js'|url }}?v=1" defer></script>
|
||||
<script src="{{ '/static/activity.js'|url }}?v=1" defer></script>
|
||||
<script src="{{ '/static/hero-circuit.js'|url }}?v=1" defer></script>
|
||||
<script src="{{ '/static/hero-circuit.js'|url }}?v=2" defer></script>
|
||||
<script src="{{ '/static/narration.js'|url }}?v=1" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
+30
-10
@@ -6,7 +6,7 @@
|
||||
|
||||
<div class="circuit-brand-block">
|
||||
<p class="circuit-brand-kicker">{{ this.eyebrow }}</p>
|
||||
<h1>{{ this.summary }}</h1>
|
||||
<h1>{{ this.summary|replace(' Signals', '<br>Signals')|safe }}</h1>
|
||||
<div class="circuit-dek">{{ this.body }}</div>
|
||||
<p class="circuit-status"><span aria-hidden="true"></span> network active / routes resolving</p>
|
||||
</div>
|
||||
@@ -22,6 +22,15 @@
|
||||
<path d="M250 670 H390 V690 H520"/><path d="M535 680 H770 V700"/>
|
||||
<path d="M805 685 H930 V665 H1035"/><path d="M1035 690 H1165"/>
|
||||
</g>
|
||||
<g class="circuit-ambient-packets">
|
||||
<path d="M35 95 H185 V125 H410"/><path class="circuit-live-alt" d="M55 150 H155 V185 H300"/>
|
||||
<path class="circuit-live-gold" d="M300 45 V115 H455"/><path class="circuit-live-alt" d="M465 65 H610 V100 H690"/>
|
||||
<path d="M705 55 H835 V90 H930"/><path class="circuit-live-gold" d="M900 115 H1050 V80 H1160"/>
|
||||
<path d="M1010 230 H1140 V335 H1085"/><path class="circuit-live-alt" d="M940 430 H1095 V465 H1165"/>
|
||||
<path d="M45 455 H170 V475 H250"/><path class="circuit-live-gold" d="M40 585 H130 V555 H205"/>
|
||||
<path class="circuit-live-alt" d="M250 670 H390 V690 H520"/><path d="M535 680 H770 V700"/>
|
||||
<path class="circuit-live-gold" d="M805 685 H930 V665 H1035"/><path d="M1035 690 H1165"/>
|
||||
</g>
|
||||
<g class="circuit-ghost">
|
||||
<path d="M70 350 H510 V180 H720 V140 H805"/>
|
||||
<path d="M180 390 H565 V320 H865"/>
|
||||
@@ -33,6 +42,17 @@
|
||||
<path d="M790 605 H885 V590 H930"/>
|
||||
<path d="M970 540 H1030 V515 H1060"/>
|
||||
</g>
|
||||
<g class="circuit-base">
|
||||
<path d="M70 350 H510 V180 H720 V140 H805"/>
|
||||
<path d="M180 390 H565 V320 H865"/>
|
||||
<path d="M95 425 H470 V470 H720"/>
|
||||
<path d="M90 505 H260 V530 H345"/>
|
||||
<path d="M190 560 H350 V585 H430"/>
|
||||
<path d="M430 610 H515 V630 H585"/>
|
||||
<path d="M610 650 H700 V655 H755"/>
|
||||
<path d="M790 605 H885 V590 H930"/>
|
||||
<path d="M970 540 H1030 V515 H1060"/>
|
||||
</g>
|
||||
<g class="circuit-traces">
|
||||
<path d="M45 200 H260 V255 H390"/><path d="M110 240 H185 V300 H410"/>
|
||||
<path d="M975 180 H1125 V285 H1080"/><path d="M955 375 H1110 V410 H1160"/>
|
||||
@@ -62,15 +82,15 @@
|
||||
</div>
|
||||
|
||||
<nav class="circuit-routes" aria-label="Signal routes">
|
||||
<a class="circuit-node circuit-node-main" data-route-node="projects" href="{{ '/projects'|url }}"><span>Projects</span><i aria-hidden="true">_</i></a>
|
||||
<a class="circuit-node circuit-node-main" data-route-node="articles" href="{{ '/articles'|url }}"><span>Articles</span><i aria-hidden="true">_</i></a>
|
||||
<a class="circuit-node circuit-node-main" data-route-node="blog" href="{{ '/blog'|url }}"><span>Blog</span><i aria-hidden="true">_</i></a>
|
||||
<a class="circuit-node circuit-node-sub" data-route-node="github" href="https://github.com/Labyricorn" rel="me">GitHub</a>
|
||||
<a class="circuit-node circuit-node-sub" data-route-node="gitea" href="https://git.labyricorn.com/">Gitea</a>
|
||||
<a class="circuit-node circuit-node-sub" data-route-node="linkedin" href="https://www.linkedin.com/in/christopher-chambers-694b7a86/">LinkedIn</a>
|
||||
<a class="circuit-node circuit-node-sub" data-route-node="twitch" href="https://www.twitch.tv/labyricorn">Twitch</a>
|
||||
<a class="circuit-node circuit-node-sub" data-route-node="youtube" href="https://www.youtube.com/@labyricorn">YouTube</a>
|
||||
<a class="circuit-node circuit-node-sub" data-route-node="kofi" href="https://ko-fi.com/labyricorn">Ko-fi</a>
|
||||
<a class="circuit-node circuit-node-main" data-route-node="projects" data-route-text="PROJECTS" href="{{ '/projects'|url }}" aria-label="Projects"><span data-route-output>Projects</span><i aria-hidden="true">_</i></a>
|
||||
<a class="circuit-node circuit-node-main" data-route-node="articles" data-route-text="ARTICLES" href="{{ '/articles'|url }}" aria-label="Articles"><span data-route-output>Articles</span><i aria-hidden="true">_</i></a>
|
||||
<a class="circuit-node circuit-node-main" data-route-node="blog" data-route-text="BLOG" href="{{ '/blog'|url }}" aria-label="Blog"><span data-route-output>Blog</span><i aria-hidden="true">_</i></a>
|
||||
<a class="circuit-node circuit-node-sub" data-route-node="github" data-route-text="GITHUB" href="https://github.com/Labyricorn" aria-label="GitHub" rel="me"><span data-route-output>GitHub</span></a>
|
||||
<a class="circuit-node circuit-node-sub" data-route-node="gitea" data-route-text="GITEA" href="https://git.labyricorn.com/" aria-label="Gitea"><span data-route-output>Gitea</span></a>
|
||||
<a class="circuit-node circuit-node-sub" data-route-node="linkedin" data-route-text="LINKEDIN" href="https://www.linkedin.com/in/christopher-chambers-694b7a86/" aria-label="LinkedIn"><span data-route-output>LinkedIn</span></a>
|
||||
<a class="circuit-node circuit-node-sub" data-route-node="twitch" data-route-text="TWITCH" href="https://www.twitch.tv/labyricorn" aria-label="Twitch"><span data-route-output>Twitch</span></a>
|
||||
<a class="circuit-node circuit-node-sub" data-route-node="youtube" data-route-text="YOUTUBE" href="https://www.youtube.com/@labyricorn" aria-label="YouTube"><span data-route-output>YouTube</span></a>
|
||||
<a class="circuit-node circuit-node-sub" data-route-node="kofi" data-route-text="KO-FI" href="https://ko-fi.com/labyricorn" aria-label="Ko-fi"><span data-route-output>Ko-fi</span></a>
|
||||
</nav>
|
||||
|
||||
<div class="circuit-legend" aria-hidden="true"><span>◆ live packet</span><span>— Labyricorn bus</span></div>
|
||||
|
||||
Reference in New Issue
Block a user