This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
(() => {
|
||||
const hero = document.querySelector("[data-circuit-hero]");
|
||||
if (!hero) return;
|
||||
|
||||
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],
|
||||
];
|
||||
let run = 0;
|
||||
let timers = [];
|
||||
|
||||
const clearTimers = () => {
|
||||
timers.forEach(window.clearTimeout);
|
||||
timers = [];
|
||||
};
|
||||
|
||||
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"));
|
||||
};
|
||||
|
||||
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"));
|
||||
|
||||
if (reducedMotion) {
|
||||
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));
|
||||
});
|
||||
};
|
||||
|
||||
hero.querySelector("[data-circuit-replay]")?.addEventListener("click", start);
|
||||
start();
|
||||
})();
|
||||
@@ -41,6 +41,215 @@ h1 { max-width: 880px; margin: 0; font-size: clamp(30px, 4vw, 45px); font-style:
|
||||
.dek { max-width: 700px; margin-top: 18px; color: var(--muted); }
|
||||
.dek p { margin: 0; }
|
||||
|
||||
.circuit-hero {
|
||||
--circuit-gold: #c5a059;
|
||||
--circuit-cyan: #65f7ff;
|
||||
--circuit-pink: #ff4fd8;
|
||||
position: relative;
|
||||
width: min(100% - 40px, 1200px);
|
||||
height: clamp(620px, 78vh, 760px);
|
||||
min-height: 620px;
|
||||
margin: 34px auto;
|
||||
overflow: hidden;
|
||||
border: 1px solid var(--rule);
|
||||
background:
|
||||
linear-gradient(180deg, rgba(255,255,255,.025), transparent 14%),
|
||||
radial-gradient(circle at 28% 28%, rgba(101,247,255,.035), transparent 28%),
|
||||
#080a0a;
|
||||
isolation: isolate;
|
||||
}
|
||||
.circuit-hero::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
inset: 0;
|
||||
pointer-events: none;
|
||||
background-image:
|
||||
linear-gradient(rgba(255,255,255,.018) 1px, transparent 1px),
|
||||
linear-gradient(90deg, rgba(255,255,255,.018) 1px, transparent 1px);
|
||||
background-size: 36px 36px;
|
||||
mask-image: linear-gradient(to bottom, #000, transparent 82%);
|
||||
}
|
||||
.circuit-hero::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
z-index: 20;
|
||||
inset: 0;
|
||||
pointer-events: none;
|
||||
opacity: .1;
|
||||
background: repeating-linear-gradient(0deg, transparent 0 3px, rgba(255,255,255,.025) 3px 4px);
|
||||
}
|
||||
.circuit-hero-topline {
|
||||
position: absolute;
|
||||
z-index: 14;
|
||||
inset: 22px 28px auto;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
color: var(--dim);
|
||||
font: 500 9px var(--mono);
|
||||
letter-spacing: .14em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.circuit-hero-topline strong { color: var(--circuit-gold); font-weight: 600; }
|
||||
.circuit-brand-block {
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
top: clamp(72px, 11vh, 104px);
|
||||
left: clamp(28px, 5vw, 72px);
|
||||
width: min(610px, 64vw);
|
||||
}
|
||||
.circuit-brand-kicker {
|
||||
margin: 0 0 12px;
|
||||
color: var(--circuit-gold);
|
||||
font: 600 11px/1.2 var(--mono);
|
||||
letter-spacing: .16em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.circuit-brand-block h1 {
|
||||
max-width: none;
|
||||
margin: 0;
|
||||
font: 700 clamp(45px, 7vw, 98px)/.86 var(--serif);
|
||||
font-style: normal;
|
||||
letter-spacing: -.055em;
|
||||
text-shadow: 0 0 24px rgba(197,160,89,.05);
|
||||
}
|
||||
.circuit-dek {
|
||||
max-width: 430px;
|
||||
margin-top: 22px;
|
||||
color: var(--muted);
|
||||
font-size: clamp(15px, 1.6vw, 17px);
|
||||
}
|
||||
.circuit-dek p { margin: 0; }
|
||||
.circuit-status {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 9px;
|
||||
margin: 20px 0 0;
|
||||
border: 1px solid rgba(197,160,89,.45);
|
||||
padding: 6px 9px;
|
||||
color: var(--circuit-gold);
|
||||
background: rgba(18,18,18,.68);
|
||||
font: 500 9px var(--mono);
|
||||
letter-spacing: .08em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.circuit-status span {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
background: var(--circuit-cyan);
|
||||
box-shadow: 0 0 10px var(--circuit-cyan);
|
||||
animation: circuit-pulse 1.6s ease-in-out infinite;
|
||||
}
|
||||
.circuit-stage { position: absolute; z-index: 2; inset: 0; }
|
||||
.circuit-stage svg { display: block; width: 100%; height: 100%; }
|
||||
.circuit-stage path { fill: none; vector-effect: non-scaling-stroke; }
|
||||
.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-traces path,
|
||||
.circuit-live path { stroke: #303837; stroke-width: 2; }
|
||||
.circuit-live path {
|
||||
opacity: .34;
|
||||
stroke: var(--circuit-cyan);
|
||||
stroke-dasharray: 22 52;
|
||||
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);
|
||||
stroke-width: 1.5;
|
||||
vector-effect: non-scaling-stroke;
|
||||
}
|
||||
.circuit-vias circle:nth-child(2n) { stroke: var(--circuit-pink); }
|
||||
.circuit-node {
|
||||
position: absolute;
|
||||
z-index: 12;
|
||||
display: inline-block;
|
||||
color: var(--circuit-gold);
|
||||
font-family: var(--mono);
|
||||
font-weight: 600;
|
||||
letter-spacing: .09em;
|
||||
line-height: 1;
|
||||
text-transform: uppercase;
|
||||
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-ready { opacity: 1; transform: none; pointer-events: auto; }
|
||||
.circuit-node::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: -14px;
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
border: 1px solid currentColor;
|
||||
transform: translateY(-50%) rotate(45deg);
|
||||
opacity: .65;
|
||||
}
|
||||
.circuit-node:hover,
|
||||
.circuit-node:focus-visible { color: #b6fbff; filter: drop-shadow(0 0 8px rgba(101,247,255,.35)); outline: none; }
|
||||
.circuit-node:hover::before,
|
||||
.circuit-node:focus-visible::before { background: currentColor; box-shadow: 0 0 10px currentColor; }
|
||||
.circuit-node-main { color: var(--ink); font-size: clamp(22px, 2.7vw, 38px); font-weight: 600; }
|
||||
.circuit-node-main i { color: var(--circuit-gold); font-style: normal; animation: circuit-cursor .75s steps(1) infinite; }
|
||||
.circuit-node-sub { font-size: clamp(11px, 1.15vw, 13px); }
|
||||
.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-legend {
|
||||
position: absolute;
|
||||
z-index: 12;
|
||||
right: 24px;
|
||||
bottom: 20px;
|
||||
display: flex;
|
||||
gap: 18px;
|
||||
color: var(--dim);
|
||||
font: 500 8px var(--mono);
|
||||
letter-spacing: .1em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.circuit-legend span:first-child { color: var(--circuit-cyan); }
|
||||
.circuit-replay {
|
||||
display: none;
|
||||
position: absolute;
|
||||
z-index: 22;
|
||||
bottom: 17px;
|
||||
left: 24px;
|
||||
border: 1px solid var(--rule);
|
||||
background: rgba(8,10,10,.86);
|
||||
padding: 7px 10px;
|
||||
color: var(--muted);
|
||||
cursor: pointer;
|
||||
font: 500 8px var(--mono);
|
||||
letter-spacing: .1em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.js .circuit-replay { display: block; }
|
||||
.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); } }
|
||||
|
||||
.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; }
|
||||
.homepage-panel { min-width: 0; }
|
||||
@@ -367,6 +576,25 @@ h1 { max-width: 880px; margin: 0; font-size: clamp(30px, 4vw, 45px); font-style:
|
||||
.primary-nav { margin-top: 14px; justify-content: space-between; gap: 14px; }
|
||||
.header-meta { display: none; }
|
||||
.hero, .hero.compact { padding-block: 44px; }
|
||||
.circuit-hero { width: calc(100% - 20px); height: 760px; min-height: 760px; margin-block: 20px; }
|
||||
.circuit-hero-topline { inset: 18px 16px auto; font-size: 8px; }
|
||||
.circuit-hero-topline span:last-child { display: none; }
|
||||
.circuit-brand-block { top: 72px; left: 24px; width: 82vw; }
|
||||
.circuit-brand-block h1 { font-size: clamp(48px, 14vw, 62px); }
|
||||
.circuit-dek { max-width: 85vw; font-size: 14px; }
|
||||
.circuit-node-main { font-size: 21px; }
|
||||
.circuit-node-sub { font-size: 10px; }
|
||||
.circuit-node[data-route-node="projects"] { left: 32%; top: 42%; }
|
||||
.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="linkedin"] { left: 18%; top: 81%; }
|
||||
.circuit-node[data-route-node="twitch"] { left: 60%; top: 81%; }
|
||||
.circuit-node[data-route-node="youtube"] { left: 18%; top: 88%; }
|
||||
.circuit-node[data-route-node="kofi"] { left: 64%; top: 88%; }
|
||||
.circuit-legend { display: none; }
|
||||
.circuit-replay { left: 16px; bottom: 13px; }
|
||||
h1 { font-size: 30px; }
|
||||
.homepage-discovery-grid { grid-template-columns: 1fr; gap: 48px; }
|
||||
.featured-project-card { padding: 20px; }
|
||||
@@ -426,3 +654,9 @@ h1 { max-width: 880px; margin: 0; font-size: clamp(30px, 4vw, 45px); font-style:
|
||||
.footer-inner { align-items: flex-start; flex-direction: column; padding-block: 28px; }
|
||||
.site-footer nav { flex-wrap: wrap; }
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.circuit-status span,
|
||||
.circuit-node-main i,
|
||||
.circuit-live path.is-live { animation: none; }
|
||||
}
|
||||
|
||||
+4
-4
@@ -2,10 +2,10 @@ _model: page
|
||||
---
|
||||
title: Home
|
||||
---
|
||||
eyebrow: The Chronicle
|
||||
eyebrow: Developer / Devlog / Project Hub
|
||||
---
|
||||
summary: Things built. Lessons learned. Work still in progress.
|
||||
summary: Things built. Signals sent.
|
||||
---
|
||||
body:
|
||||
A running record of projects, experiments, technical writing, and the occasional
|
||||
idea that refused to stay hypothetical.
|
||||
Projects, experiments, technical writing, and ideas moving from signal to
|
||||
finished work.
|
||||
|
||||
+2
-1
@@ -9,9 +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=13">
|
||||
<link rel="stylesheet" href="{{ '/static/style.css'|url }}?v=14">
|
||||
<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/narration.js'|url }}?v=1" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
+76
-5
@@ -1,9 +1,80 @@
|
||||
<section class="hero">
|
||||
<div class="shell narrow">
|
||||
<p class="eyebrow">{{ this.eyebrow }}</p>
|
||||
<h1>{{ this.summary }}</h1>
|
||||
<div class="dek">{{ this.body }}</div>
|
||||
<section class="circuit-hero" aria-label="Labyricorn navigation hero" data-circuit-hero>
|
||||
<div class="circuit-hero-topline">
|
||||
<span><strong>LABYRICORN</strong> // SIGNAL ROUTER</span>
|
||||
<span>REG. NO. 004 — EST. LOCAL</span>
|
||||
</div>
|
||||
|
||||
<div class="circuit-brand-block">
|
||||
<p class="circuit-brand-kicker">{{ this.eyebrow }}</p>
|
||||
<h1>{{ this.summary }}</h1>
|
||||
<div class="circuit-dek">{{ this.body }}</div>
|
||||
<p class="circuit-status"><span aria-hidden="true"></span> network active / routes resolving</p>
|
||||
</div>
|
||||
|
||||
<div class="circuit-stage" aria-hidden="true">
|
||||
<svg viewBox="0 0 1200 720" preserveAspectRatio="none">
|
||||
<g class="circuit-ambient">
|
||||
<path d="M35 95 H185 V125 H410"/><path d="M55 150 H155 V185 H300"/>
|
||||
<path d="M300 45 V115 H455"/><path d="M465 65 H610 V100 H690"/>
|
||||
<path d="M705 55 H835 V90 H930"/><path d="M900 115 H1050 V80 H1160"/>
|
||||
<path d="M1010 230 H1140 V335 H1085"/><path d="M940 430 H1095 V465 H1165"/>
|
||||
<path d="M45 455 H170 V475 H250"/><path d="M40 585 H130 V555 H205"/>
|
||||
<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-ghost">
|
||||
<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"/>
|
||||
<path d="M36 650 H120 V610 H220"/><path d="M1080 645 H1145 V580"/>
|
||||
</g>
|
||||
<g class="circuit-live">
|
||||
<path id="route-projects" d="M70 350 H510 V180 H720 V140 H805"/>
|
||||
<path id="route-articles" class="circuit-live-alt" d="M180 390 H565 V320 H865"/>
|
||||
<path id="route-blog" d="M95 425 H470 V470 H720"/>
|
||||
<path id="route-github" class="circuit-live-alt" d="M90 505 H260 V530 H345"/>
|
||||
<path id="route-gitea" d="M190 560 H350 V585 H430"/>
|
||||
<path id="route-linkedin" class="circuit-live-alt" d="M430 610 H515 V630 H585"/>
|
||||
<path id="route-twitch" d="M610 650 H700 V655 H755"/>
|
||||
<path id="route-youtube" class="circuit-live-alt" d="M790 605 H885 V590 H930"/>
|
||||
<path id="route-kofi" d="M970 540 H1030 V515 H1060"/>
|
||||
</g>
|
||||
<g class="circuit-vias">
|
||||
<circle cx="70" cy="350" r="4"/><circle cx="805" cy="140" r="4"/>
|
||||
<circle cx="180" cy="390" r="4"/><circle cx="865" cy="320" r="4"/>
|
||||
<circle cx="95" cy="425" r="4"/><circle cx="720" cy="470" r="4"/>
|
||||
<circle cx="90" cy="505" r="3"/><circle cx="345" cy="530" r="3"/>
|
||||
<circle cx="190" cy="560" r="3"/><circle cx="430" cy="585" r="3"/>
|
||||
<circle cx="585" cy="630" r="3"/><circle cx="755" cy="655" r="3"/>
|
||||
<circle cx="930" cy="590" r="3"/><circle cx="1060" cy="515" r="3"/>
|
||||
</g>
|
||||
</svg>
|
||||
</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>
|
||||
</nav>
|
||||
|
||||
<div class="circuit-legend" aria-hidden="true"><span>◆ live packet</span><span>— Labyricorn bus</span></div>
|
||||
<button class="circuit-replay" type="button" data-circuit-replay>Replay signal sequence</button>
|
||||
</section>
|
||||
|
||||
<section class="activity-section">
|
||||
|
||||
Reference in New Issue
Block a user