Tighten stack overlap; fix folder top tabs; replace paper with rack.

Cards and trace use negative-margin overlap; folder tabs stay above bodies; new server-rack variant.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-05-20 22:50:45 -04:00
co-authored by Cursor
parent 531acf6969
commit 17338fc3b4
14 changed files with 342 additions and 188 deletions
+31
View File
@@ -0,0 +1,31 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Levkin — Stack Rack</title>
<link rel="icon" href="/favicon.svg" type="image/svg+xml" />
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="./rack.css" />
</head>
<body>
<nav class="nav"><a href="/">← options</a><a href="/stack-trace/">trace</a><span id="depth">U0</span></nav>
<div class="rack-frame">
<div class="rack-label">LEV-RACK-01</div>
<main class="mount">
<div class="scroll-section" data-layer="0"><article class="unit u0"><header class="unit-head"><span class="led on"></span><span class="uid">U0</span><span class="svc">foundation</span></header><div class="unit-body"><strong>Levkin</strong><p>Software dev · CA · 15+ yrs · new work open</p></div></article></div>
<div class="scroll-section" data-layer="1"><article class="unit u1"><header class="unit-head"><span class="led on"></span><span class="uid">U1</span><span class="svc">application</span></header><div class="unit-body"><strong>custom_software</strong><p>TS · Python · .NET</p></div></article></div>
<div class="scroll-section" data-layer="2"><article class="unit u2"><header class="unit-head"><span class="led on"></span><span class="uid">U2</span><span class="svc">automation</span><a href="https://auto.levkin.ca">auto↗</a></header><div class="unit-body"><strong>pipeline_cluster</strong><p>n8n · CI/CD · LLM hooks</p></div></article></div>
<div class="scroll-section" data-layer="3"><article class="unit u3"><header class="unit-head"><span class="led on"></span><span class="uid">U3</span><span class="svc">enterprise</span><a href="https://caseware.levkin.ca">caseware↗</a></header><div class="unit-body"><strong>caseware_module</strong><p>MNP · JazzIt · 8h→2m</p></div></article></div>
<div class="scroll-section" data-layer="4"><article class="unit u4"><header class="unit-head"><span class="led blink"></span><span class="uid">U4</span><span class="svc">quality</span><a href="https://iliadobkin.com">iliadobkin↗</a></header><div class="unit-body"><strong>sdet_suite</strong><p>traces · Playwright · CI</p></div></article></div>
<div class="scroll-section" data-layer="5"><article class="unit u5"><header class="unit-head"><span class="led"></span><span class="uid">U5</span><span class="svc">ops</span><a href="https://jobs.levkin.ca">jobs↗</a></header><div class="unit-body"><strong>job_ops</strong><p>auth · internal</p></div></article></div>
<div class="scroll-section scroll-section--final" data-layer="6"><article class="unit u6"><header class="unit-head"><span class="led on"></span><span class="uid">U6</span><span class="svc">interface</span></header><div class="unit-body"><strong>engage()</strong><p><a href="https://cal.levkin.ca/ilia/consult">book_consult</a> · <a href="mailto:hello@levkine.ca">mail</a></p></div></article></div>
<div class="stop"></div>
</main>
</div>
<footer class="foot"><span>// rack EOT</span><a href="https://git.levkin.ca">git.levkin.ca</a></footer>
<script src="./rack.js" type="module"></script>
</body>
</html>
+128
View File
@@ -0,0 +1,128 @@
:root {
--nav: 2.5rem;
--stick: 0.5rem;
--step: 1.7rem;
--scroll-tick: 26vh;
--overlap: 22vh;
--rack: #12141a;
--mono: 'IBM Plex Mono', monospace;
}
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: var(--mono);
background: #08090c;
color: #9ca3af;
font-size: 0.75rem;
}
.nav {
position: fixed; top: 0; left: 0; right: 0; z-index: 200;
display: flex; gap: 1rem; padding: 0.5rem 1rem; font-size: 0.62rem;
background: rgba(8,9,12,0.95); border-bottom: 1px solid #1e2430;
}
.nav a { color: #5a6478; text-decoration: none; }
.nav a:hover { color: #4ade80; }
#depth { margin-left: auto; color: #4ade80; font-weight: 600; }
.rack-frame {
max-width: 540px;
margin: 0 auto;
padding: calc(var(--nav) + 0.75rem) 0.75rem 0;
border-left: 4px solid #2a3040;
border-right: 4px solid #2a3040;
background: linear-gradient(90deg, #0c0e14 0%, var(--rack) 8%, var(--rack) 92%, #0c0e14 100%);
min-height: 100vh;
box-shadow: inset 0 0 40px rgba(0,0,0,0.5);
}
.rack-label {
font-size: 0.55rem;
letter-spacing: 0.2em;
color: #3a4458;
padding: 0 0.5rem 0.75rem;
border-bottom: 1px dashed #2a3040;
margin-bottom: 0.5rem;
}
.mount { padding: 0 0.35rem; }
.scroll-section { height: var(--scroll-tick); position: relative; }
.scroll-section--final { height: 16vh; min-height: 160px; }
.stop { height: 1px; margin-bottom: 2rem; }
.unit {
position: sticky;
margin-bottom: calc(-1 * var(--overlap));
border: 1px solid #2a3448;
background: #161a22;
border-radius: 2px;
overflow: hidden;
box-shadow: 0 4px 0 #0a0c10, inset 0 1px 0 rgba(255,255,255,0.04);
}
.unit-head {
display: flex;
align-items: center;
gap: 0.5rem;
padding: 0.35rem 0.65rem;
background: #1a2030;
border-bottom: 1px solid #2a3448;
font-size: 0.62rem;
position: relative;
z-index: 20;
}
.led {
width: 6px;
height: 6px;
border-radius: 50%;
background: #3a4458;
flex-shrink: 0;
}
.led.on { background: #4ade80; box-shadow: 0 0 6px #4ade80; }
.led.blink { background: #fbbf24; animation: blink 1.2s ease infinite; }
@keyframes blink {
50% { opacity: 0.35; }
}
.uid { color: #6b7280; font-weight: 600; min-width: 1.5rem; }
.svc { color: #9ca3af; text-transform: uppercase; letter-spacing: 0.08em; flex: 1; }
.unit-head a {
color: #60a5fa;
text-decoration: none;
font-size: 0.58rem;
}
.unit-body {
padding: 0.55rem 0.65rem 0.65rem;
position: relative;
z-index: 1;
}
.unit-body strong { color: #e5e7eb; font-weight: 500; display: block; margin-bottom: 0.15rem; }
.unit-body p { color: #6b7280; font-size: 0.68rem; }
.unit-body a { color: #60a5fa; text-decoration: none; }
.unit-body a:hover { text-decoration: underline; }
.u0 { top: calc(var(--nav) + var(--stick)); z-index: 1; }
.u1 { top: calc(var(--nav) + var(--stick) + var(--step)); z-index: 2; }
.u2 { top: calc(var(--nav) + var(--stick) + var(--step) * 2); z-index: 3; }
.u3 { top: calc(var(--nav) + var(--stick) + var(--step) * 3); z-index: 4; }
.u4 { top: calc(var(--nav) + var(--stick) + var(--step) * 4); z-index: 5; }
.u5 { top: calc(var(--nav) + var(--stick) + var(--step) * 5); z-index: 6; }
.u6 {
top: calc(var(--nav) + var(--stick) + var(--step) * 6);
z-index: 7;
margin-bottom: 0;
}
.foot {
display: flex; justify-content: space-between; max-width: 540px; margin: 0 auto;
padding: 1rem 1.25rem 2rem; font-size: 0.58rem; color: #3a4458;
}
.foot a { color: #3a4458; text-decoration: none; }
+15
View File
@@ -0,0 +1,15 @@
const sections = document.querySelectorAll('.scroll-section');
const depthEl = document.getElementById('depth');
const mid = () => window.innerHeight * 0.42;
function tick() {
let a = 0;
sections.forEach((s) => {
const r = s.getBoundingClientRect();
if (r.top <= mid() && r.bottom > mid()) a = +s.dataset.layer;
});
depthEl.textContent = `U${a}`;
}
window.addEventListener('scroll', tick, { passive: true });
tick();