Move 6 guide pages from Guides/ to ToolsnToys/ root; fix back-links. Add edu-toys.html (museum-style iframe exhibit for 4 legacy edu toy pages). Add 4 edu toy artifacts, dendritic curio, docker-cheatsheet-enhanced. Wire foss-tools, guides, edu-toys, and dendritic hrefs in toolsntoys.html. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
829 lines
24 KiB
HTML
829 lines
24 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>TOOLS N TOYS // FIELD UNIT SP-07</title>
|
|
<!-- Sixtyfour, Share Tech Mono, Rambla -->
|
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
<link href="https://fonts.googleapis.com/css2?family=Sixtyfour&family=Share+Tech+Mono&family=Rambla:ital,wght@0,400;0,700;1,400;1,700&family=Noto+Emoji&display=swap" rel="stylesheet">
|
|
<style>
|
|
:root {
|
|
--bg-deep: #030812;
|
|
--bg-mid: #060f1a;
|
|
--bg-surface: #081524;
|
|
--bg-panel: #0d1e32;
|
|
--text-main: #c8d8e8;
|
|
--text-muted: #3a5570;
|
|
--phosphor: #00ff41;
|
|
--neon-green: #32dc8c;
|
|
--neon-green-dim: #229966;
|
|
--fire-amber: #e8943a;
|
|
--fire-amber-dim: #b06020;
|
|
--toucan: #ffcf40;
|
|
--fire-coral: #d4654a;
|
|
--neon-teal: #2ac4b3;
|
|
--orchid: #c558d9;
|
|
--border-neon: rgba(50,220,140,0.3);
|
|
--border-amber: rgba(232,148,58,0.4);
|
|
--campfire-glow: #e8943a; /* adapted amber glow */
|
|
}
|
|
|
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
|
|
body {
|
|
background: var(--bg-deep);
|
|
color: var(--text-main);
|
|
font-family: 'Rambla', sans-serif;
|
|
min-height: 100vh;
|
|
overflow-x: hidden;
|
|
position: relative;
|
|
}
|
|
|
|
/* Night atmosphere bg */
|
|
body::before {
|
|
content: '';
|
|
position: fixed;
|
|
inset: 0;
|
|
background:
|
|
radial-gradient(ellipse 60% 50% at 50% 80%, rgba(232,148,58,0.05) 0%, transparent 70%),
|
|
radial-gradient(ellipse 100% 60% at 20% 0%, rgba(3,8,18,0.9) 0%, transparent 60%),
|
|
radial-gradient(ellipse 100% 60% at 80% 0%, rgba(3,8,18,0.9) 0%, transparent 60%),
|
|
repeating-linear-gradient(
|
|
0deg,
|
|
transparent,
|
|
transparent 2px,
|
|
rgba(0,0,0,0.12) 2px,
|
|
rgba(0,0,0,0.12) 4px
|
|
);
|
|
pointer-events: none;
|
|
z-index: 0;
|
|
}
|
|
|
|
/* Scanline effect */
|
|
body::after {
|
|
content: '';
|
|
position: fixed;
|
|
inset: 0;
|
|
background: repeating-linear-gradient(
|
|
to bottom,
|
|
transparent 0px,
|
|
transparent 3px,
|
|
rgba(0,0,0,0.15) 3px,
|
|
rgba(0,0,0,0.15) 4px
|
|
);
|
|
pointer-events: none;
|
|
z-index: 1000;
|
|
animation: scanline 15s linear infinite;
|
|
}
|
|
|
|
@keyframes scanline {
|
|
0% { background-position: 0 0; }
|
|
100% { background-position: 0 400px; }
|
|
}
|
|
|
|
/* Noise texture overlay */
|
|
.noise {
|
|
position: fixed;
|
|
inset: 0;
|
|
opacity: 0.04;
|
|
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)'/%3E%3C/svg%3E");
|
|
pointer-events: none;
|
|
z-index: 999;
|
|
}
|
|
|
|
.app {
|
|
position: relative;
|
|
z-index: 1;
|
|
max-width: 1100px;
|
|
margin: 0 auto;
|
|
padding: 2rem 1.5rem;
|
|
}
|
|
|
|
/* ===== HEADER ===== */
|
|
.header {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
justify-content: space-between;
|
|
margin-bottom: 2rem;
|
|
padding-bottom: 1rem;
|
|
border-bottom: 1px solid var(--border-neon);
|
|
position: relative;
|
|
}
|
|
|
|
.header::after {
|
|
content: '';
|
|
position: absolute;
|
|
bottom: -1px;
|
|
left: 0;
|
|
width: 40%;
|
|
height: 1px;
|
|
background: var(--neon-green);
|
|
box-shadow: 0 0 10px var(--neon-green);
|
|
animation: headerGlow 4s ease-in-out infinite alternate;
|
|
}
|
|
|
|
@keyframes headerGlow {
|
|
from { opacity: 0.4; width: 25%; }
|
|
to { opacity: 1; width: 55%; }
|
|
}
|
|
|
|
.unit-tag {
|
|
font-family: 'Share Tech Mono', monospace;
|
|
font-size: 0.9rem;
|
|
color: var(--fire-amber);
|
|
letter-spacing: 0.25em;
|
|
text-transform: uppercase;
|
|
margin-bottom: 0.4rem;
|
|
}
|
|
|
|
.title {
|
|
font-family: 'Sixtyfour', cursive;
|
|
font-size: 1.8rem;
|
|
font-weight: 400;
|
|
color: var(--neon-green);
|
|
text-shadow: 0 0 8px var(--neon-green), 0 0 20px rgba(50,220,140,0.6);
|
|
line-height: 1.2;
|
|
margin-bottom: 0.5rem;
|
|
}
|
|
|
|
.subtitle {
|
|
font-family: 'Share Tech Mono', monospace;
|
|
font-size: 0.9rem;
|
|
color: var(--text-muted);
|
|
letter-spacing: 0.2em;
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
.status-badge {
|
|
font-family: 'Share Tech Mono', monospace;
|
|
font-size: 1rem;
|
|
padding: 0.25rem 0.8rem;
|
|
border: 1px solid var(--neon-green);
|
|
color: var(--neon-green);
|
|
letter-spacing: 0.15em;
|
|
text-shadow: 0 0 8px var(--neon-green);
|
|
box-shadow: inset 0 0 10px rgba(50,220,140,0.15), 0 0 8px rgba(50,220,140,0.2);
|
|
animation: badgePulse 2.5s ease-in-out infinite;
|
|
}
|
|
|
|
@keyframes badgePulse {
|
|
0%, 100% { opacity: 0.8; box-shadow: inset 0 0 8px rgba(50,220,140,0.1); }
|
|
50% { opacity: 1; box-shadow: inset 0 0 16px rgba(50,220,140,0.3), 0 0 12px rgba(50,220,140,0.4); }
|
|
}
|
|
|
|
.header-right {
|
|
text-align: right;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.5rem;
|
|
align-items: flex-end;
|
|
}
|
|
|
|
.coord {
|
|
font-family: 'Share Tech Mono', monospace;
|
|
font-size: 0.9rem;
|
|
color: var(--text-muted);
|
|
letter-spacing: 0.1em;
|
|
}
|
|
|
|
/* ===== STAT BAR ===== */
|
|
.stats-bar {
|
|
display: grid;
|
|
grid-template-columns: repeat(4, 1fr);
|
|
gap: 0.75rem;
|
|
margin-bottom: 2rem;
|
|
}
|
|
|
|
.stat-card {
|
|
background: var(--bg-panel);
|
|
border: 1px solid var(--border-neon);
|
|
padding: 0.85rem 1.1rem;
|
|
position: relative;
|
|
clip-path: polygon(0 0, calc(100% - 12px) 0, 100% 12px, 100% 100%, 0 100%);
|
|
box-shadow: 0 0 15px rgba(0,0,0,0.3), inset 0 0 15px rgba(50,220,140,0.05);
|
|
}
|
|
|
|
.stat-card::before {
|
|
content: '';
|
|
position: absolute;
|
|
top: 0; right: 0;
|
|
width: 0; height: 0;
|
|
border-style: solid;
|
|
border-width: 0 12px 12px 0;
|
|
border-color: transparent var(--bg-deep) transparent transparent;
|
|
}
|
|
|
|
.stat-label {
|
|
font-family: 'Share Tech Mono', monospace;
|
|
font-size: 0.85rem;
|
|
color: var(--text-muted);
|
|
letter-spacing: 0.18em;
|
|
margin-bottom: 0.4rem;
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
.stat-value {
|
|
font-family: 'Sixtyfour', cursive;
|
|
font-size: 0.9rem;
|
|
color: var(--fire-amber);
|
|
text-shadow: 0 0 10px rgba(232,148,58,0.5);
|
|
margin-bottom: 0.2rem;
|
|
}
|
|
|
|
.stat-sub {
|
|
font-family: 'Share Tech Mono', monospace;
|
|
font-size: 0.85rem;
|
|
color: var(--text-muted);
|
|
}
|
|
|
|
.stat-bar-track {
|
|
height: 3px;
|
|
background: rgba(255,255,255,0.05);
|
|
margin-top: 0.6rem;
|
|
position: relative;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.stat-bar-fill {
|
|
height: 100%;
|
|
background: var(--neon-green);
|
|
box-shadow: 0 0 6px var(--neon-green);
|
|
}
|
|
|
|
/* ===== MAIN LAYOUT ===== */
|
|
.main-grid {
|
|
display: grid;
|
|
grid-template-columns: 240px 1fr;
|
|
gap: 1.5rem;
|
|
}
|
|
|
|
/* ===== SIDEBAR ===== */
|
|
.panel {
|
|
background: var(--bg-panel);
|
|
border: 1px solid var(--border-neon);
|
|
margin-bottom: 1.5rem;
|
|
box-shadow: 0 0 15px rgba(0,0,0,0.4);
|
|
}
|
|
|
|
.panel-header {
|
|
font-family: 'Share Tech Mono', monospace;
|
|
font-size: 1rem;
|
|
letter-spacing: 0.2em;
|
|
color: var(--fire-amber);
|
|
padding: 0.6rem 0.8rem;
|
|
border-bottom: 1px solid rgba(232,148,58,0.2);
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
}
|
|
|
|
.panel-header::before { content: '//'; color: var(--text-muted); }
|
|
|
|
.panel-body { padding: 0.8rem; }
|
|
|
|
.category-list { display: flex; flex-direction: column; gap: 0.4rem; }
|
|
|
|
.cat-item {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding: 0.5rem 0.7rem;
|
|
cursor: pointer;
|
|
font-size: 0.9rem;
|
|
color: var(--text-main);
|
|
transition: all 150ms;
|
|
border: 1px solid transparent;
|
|
position: relative;
|
|
}
|
|
|
|
.cat-item:hover, .cat-item.active {
|
|
background: rgba(50,220,140,0.08);
|
|
border-color: rgba(50,220,140,0.3);
|
|
color: var(--neon-green);
|
|
}
|
|
|
|
.cat-item.active::before {
|
|
content: '';
|
|
position: absolute;
|
|
left: 0; top: 0; bottom: 0;
|
|
width: 2px;
|
|
background: var(--neon-green);
|
|
box-shadow: 0 0 8px var(--neon-green);
|
|
}
|
|
|
|
.cat-count {
|
|
font-family: 'Share Tech Mono', monospace;
|
|
font-size: 0.85rem;
|
|
color: var(--text-muted);
|
|
background: rgba(0,0,0,0.3);
|
|
padding: 1px 6px;
|
|
}
|
|
|
|
.status-line {
|
|
font-family: 'Share Tech Mono', monospace;
|
|
font-size: 0.8rem;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
margin-bottom: 0.4rem;
|
|
}
|
|
|
|
/* ===== ITEM GRID ===== */
|
|
.item-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
|
|
gap: 1rem;
|
|
}
|
|
|
|
.item-card {
|
|
background: var(--bg-panel);
|
|
border: 1px solid rgba(50,220,140,0.15);
|
|
position: relative;
|
|
transition: all 200ms ease;
|
|
overflow: hidden;
|
|
clip-path: polygon(0 0, calc(100% - 10px) 0, 100% 10px, 100% 100%, 10px 100%, 0 calc(100% - 10px));
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.item-card:hover {
|
|
border-color: rgba(50,220,140,0.5);
|
|
background: var(--bg-surface);
|
|
box-shadow: 0 8px 32px rgba(0,0,0,0.5), 0 0 15px rgba(50,220,140,0.1);
|
|
}
|
|
|
|
.item-card.legendary { border-color: rgba(255,207,64,0.3); }
|
|
.item-card.legendary:hover { border-color: var(--toucan); box-shadow: 0 0 20px rgba(255,207,64,0.15); }
|
|
.item-card.rare { border-color: rgba(42,196,179,0.3); }
|
|
.item-card.rare:hover { border-color: var(--neon-teal); }
|
|
.item-card.uncommon { border-color: rgba(50,220,140,0.3); }
|
|
.item-card.damaged { border-color: rgba(212,101,74,0.3); }
|
|
.item-card.unique {
|
|
border-color: rgba(197,88,217,0.3);
|
|
animation: uniquePulse 3s infinite alternate;
|
|
}
|
|
|
|
@keyframes uniquePulse {
|
|
from { border-color: rgba(197,88,217,0.2); }
|
|
to { border-color: rgba(197,88,217,0.6); box-shadow: 0 0 12px rgba(197,88,217,0.2); }
|
|
}
|
|
|
|
.item-card::before {
|
|
content: '';
|
|
position: absolute;
|
|
top: 0; right: 0;
|
|
width: 0; height: 0;
|
|
border-style: solid;
|
|
border-width: 0 10px 10px 0;
|
|
border-color: transparent var(--bg-deep) transparent transparent;
|
|
}
|
|
|
|
.item-img-zone {
|
|
height: 100px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
background: rgba(0,0,0,0.4);
|
|
font-size: 2.8rem;
|
|
font-family: 'Noto Emoji', sans-serif;
|
|
border-bottom: 1px solid rgba(255,255,255,0.05);
|
|
position: relative;
|
|
color: var(--text-muted);
|
|
}
|
|
|
|
.item-card.legendary .item-img-zone { color: var(--toucan); text-shadow: 0 0 12px rgba(255,207,64,0.5); }
|
|
.item-card.rare .item-img-zone { color: var(--neon-teal); text-shadow: 0 0 12px rgba(42,196,179,0.5); }
|
|
.item-card.uncommon .item-img-zone { color: var(--neon-green);text-shadow: 0 0 12px rgba(50,220,140,0.5); }
|
|
.item-card.damaged .item-img-zone { color: var(--fire-coral);text-shadow: 0 0 12px rgba(212,101,74,0.5); }
|
|
.item-card.unique .item-img-zone { color: var(--orchid); text-shadow: 0 0 12px rgba(197,88,217,0.5); }
|
|
|
|
.item-body { padding: 1rem; flex: 1; display: flex; flex-direction: column; }
|
|
|
|
.item-name {
|
|
font-family: 'Rambla', sans-serif;
|
|
font-weight: 700;
|
|
font-size: 1rem;
|
|
color: var(--text-main);
|
|
margin-bottom: 0.3rem;
|
|
letter-spacing: 0.02em;
|
|
}
|
|
|
|
.item-meta {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
font-family: 'Share Tech Mono', monospace;
|
|
font-size: 0.9rem;
|
|
color: var(--text-muted);
|
|
margin-bottom: 0.8rem;
|
|
}
|
|
|
|
.item-desc {
|
|
font-family: 'Rambla', sans-serif;
|
|
font-size: 0.9rem;
|
|
line-height: 1.4;
|
|
color: var(--text-main);
|
|
margin-bottom: 1rem;
|
|
flex: 1;
|
|
}
|
|
|
|
.condition-track {
|
|
height: 3px;
|
|
background: rgba(255,255,255,0.05);
|
|
margin-bottom: 1rem;
|
|
}
|
|
|
|
.condition-fill { height: 100%; box-shadow: 0 0 4px var(--neon-green); }
|
|
|
|
.rarity-pip {
|
|
position: absolute;
|
|
top: 0.6rem;
|
|
left: 0.6rem;
|
|
width: 6px;
|
|
height: 6px;
|
|
border-radius: 50%;
|
|
}
|
|
|
|
.pip-legendary { background: var(--toucan); box-shadow: 0 0 8px var(--toucan); animation: legendaryPip 2s infinite; }
|
|
.pip-rare { background: var(--neon-teal); box-shadow: 0 0 6px var(--neon-teal); }
|
|
.pip-uncommon { background: var(--neon-green); }
|
|
.pip-damaged { background: var(--fire-coral); }
|
|
.pip-unique { background: var(--orchid); box-shadow: 0 0 8px var(--orchid); }
|
|
|
|
@keyframes legendaryPip {
|
|
0%, 100% { transform: scale(1); opacity: 0.8; }
|
|
50% { transform: scale(1.4); opacity: 1; }
|
|
}
|
|
|
|
.visit-btn {
|
|
font-family: 'Share Tech Mono', monospace;
|
|
font-size: 1rem;
|
|
padding: 0.6rem;
|
|
text-align: center;
|
|
background: transparent;
|
|
border: 1px solid var(--fire-amber);
|
|
color: var(--fire-amber);
|
|
text-decoration: none;
|
|
transition: all 150ms;
|
|
letter-spacing: 0.15em;
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
.visit-btn:hover {
|
|
background: rgba(232,148,58,0.1);
|
|
box-shadow: 0 0 15px rgba(232,148,58,0.3);
|
|
text-shadow: 0 0 8px var(--fire-amber);
|
|
}
|
|
|
|
/* Back Link */
|
|
.back-link {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
font-family: 'Share Tech Mono', monospace;
|
|
color: var(--text-muted);
|
|
text-decoration: none;
|
|
margin-bottom: 1.5rem;
|
|
transition: color 150ms;
|
|
letter-spacing: 0.1em;
|
|
}
|
|
.back-link:hover { color: var(--neon-green); }
|
|
|
|
/* Canvas and FX */
|
|
#embers {
|
|
position: fixed;
|
|
inset: 0;
|
|
pointer-events: none;
|
|
z-index: 3;
|
|
}
|
|
|
|
.campfire-glow {
|
|
position: fixed;
|
|
bottom: -100px;
|
|
left: 50%;
|
|
transform: translateX(-50%);
|
|
width: 600px;
|
|
height: 400px;
|
|
background: radial-gradient(ellipse at center bottom, rgba(232,148,58,0.12) 0%, transparent 70%);
|
|
pointer-events: none;
|
|
z-index: 0;
|
|
animation: glowPulse 4s ease-in-out infinite;
|
|
}
|
|
|
|
@keyframes glowPulse {
|
|
0%, 100% { opacity: 0.5; }
|
|
50% { opacity: 0.9; transform: translateX(-50%) scale(1.05); }
|
|
}
|
|
|
|
::-webkit-scrollbar { width: 4px; }
|
|
::-webkit-scrollbar-track { background: var(--bg-deep); }
|
|
::-webkit-scrollbar-thumb { background: var(--text-muted); }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
|
|
<div class="noise"></div>
|
|
<div class="campfire-glow"></div>
|
|
<canvas id="embers"></canvas>
|
|
|
|
<div class="app">
|
|
|
|
<a href="../index.html" class="back-link" target="_top">← SPACE</a>
|
|
|
|
<header class="header">
|
|
<div class="header-left">
|
|
<div class="unit-tag">▶ FIELD UNIT SP-07 // TOOLS N TOYS</div>
|
|
<h1 class="title">TOOLS N TOYS</h1>
|
|
<div class="subtitle">ORCHESTRATION & UTILITY HUB</div>
|
|
</div>
|
|
<div class="header-right">
|
|
<div class="status-badge">● LOCAL_ACTIVE</div>
|
|
<div class="coord">SECTOR: HUB-07</div>
|
|
<div class="coord">SYNC: REALTIME</div>
|
|
</div>
|
|
</header>
|
|
|
|
<div class="stats-bar">
|
|
<div class="stat-card">
|
|
<div class="stat-label">SECTIONS</div>
|
|
<div class="stat-value">5</div>
|
|
<div class="stat-sub">ACTIVE MODULES</div>
|
|
<div class="stat-bar-track"><div class="stat-bar-fill" style="width:100%"></div></div>
|
|
</div>
|
|
<div class="stat-card">
|
|
<div class="stat-label">TOOLS</div>
|
|
<div class="stat-value">57</div>
|
|
<div class="stat-sub">COLLECTED ITEMS</div>
|
|
<div class="stat-bar-track"><div class="stat-bar-fill" style="width:85%"></div></div>
|
|
</div>
|
|
<div class="stat-card">
|
|
<div class="stat-label">GUIDES</div>
|
|
<div class="stat-value">6</div>
|
|
<div class="stat-sub">FIELD MANUALS</div>
|
|
<div class="stat-bar-track"><div class="stat-bar-fill" style="width:60%"></div></div>
|
|
</div>
|
|
<div class="stat-card">
|
|
<div class="stat-label">EDU TOYS</div>
|
|
<div class="stat-value">4</div>
|
|
<div class="stat-sub">LEGACY ARTIFACTS</div>
|
|
<div class="stat-bar-track"><div class="stat-bar-fill" style="width:40%; background:var(--fire-coral); box-shadow:0 0 6px var(--fire-coral);"></div></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="main-grid">
|
|
<aside class="sidebar">
|
|
<div class="panel">
|
|
<div class="panel-header">SECTIONS</div>
|
|
<div class="panel-body">
|
|
<div class="category-list">
|
|
<div class="cat-item active">
|
|
<span>ALL</span>
|
|
<span class="cat-count">5</span>
|
|
</div>
|
|
<div class="cat-item">
|
|
<span>JL'S TOOLS</span>
|
|
<span class="cat-count">5</span>
|
|
</div>
|
|
<div class="cat-item">
|
|
<span>FOSS ARSENAL</span>
|
|
<span class="cat-count">50+</span>
|
|
</div>
|
|
<div class="cat-item">
|
|
<span>FIELD MANUALS</span>
|
|
<span class="cat-count">6</span>
|
|
</div>
|
|
<div class="cat-item">
|
|
<span>EDU TOYS</span>
|
|
<span class="cat-count">4</span>
|
|
</div>
|
|
<div class="cat-item">
|
|
<span>CURIO</span>
|
|
<span class="cat-count">1</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="panel">
|
|
<div class="panel-header">FIELD STATUS</div>
|
|
<div class="panel-body">
|
|
<div class="status-line">
|
|
<span style="color:var(--text-muted)">CONNECTIVITY</span>
|
|
<span style="color:var(--neon-green)">LOCAL</span>
|
|
</div>
|
|
<div class="status-line">
|
|
<span style="color:var(--text-muted)">LAST SYNC</span>
|
|
<span style="color:var(--fire-amber)">NOW</span>
|
|
</div>
|
|
<div class="status-line" style="margin-top:0.8rem">
|
|
<span style="color:var(--text-muted)">THREAT LEVEL</span>
|
|
<span style="color:var(--neon-green-dim)">MINIMAL</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</aside>
|
|
|
|
<main class="item-grid">
|
|
<!-- JL'S TOOLS -->
|
|
<div class="item-card legendary">
|
|
<div class="rarity-pip pip-legendary"></div>
|
|
<div class="item-img-zone">🔧</div>
|
|
<div class="item-body">
|
|
<div class="item-name">JL'S TOOLS</div>
|
|
<div class="item-meta">
|
|
<span>5 ITEMS</span>
|
|
<span style="color:var(--toucan)">LEGENDARY</span>
|
|
</div>
|
|
<p class="item-desc">early solutions to very niche problems</p>
|
|
<div class="condition-track"><div class="condition-fill" style="width:98%; background:var(--neon-green)"></div></div>
|
|
<a href="jl-early-tools.html" class="visit-btn">VISIT</a>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- FOSS ARSENAL -->
|
|
<div class="item-card rare">
|
|
<div class="rarity-pip pip-rare"></div>
|
|
<div class="item-img-zone">🛡</div>
|
|
<div class="item-body">
|
|
<div class="item-name">FOSS ARSENAL</div>
|
|
<div class="item-meta">
|
|
<span>50+ ITEMS</span>
|
|
<span style="color:var(--neon-teal)">RARE</span>
|
|
</div>
|
|
<p class="item-desc">Free and open weapons for builders, makers, and tinkerers.</p>
|
|
<div class="condition-track"><div class="condition-fill" style="width:85%; background:var(--neon-teal)"></div></div>
|
|
<a href="foss-tools.html" class="visit-btn">VISIT</a>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- FIELD MANUALS -->
|
|
<div class="item-card uncommon">
|
|
<div class="rarity-pip pip-uncommon"></div>
|
|
<div class="item-img-zone">📋</div>
|
|
<div class="item-body">
|
|
<div class="item-name">FIELD MANUALS</div>
|
|
<div class="item-meta">
|
|
<span>6 ITEMS</span>
|
|
<span style="color:var(--neon-green)">UNCOMMON</span>
|
|
</div>
|
|
<p class="item-desc">Step-by-step guides for Linux, Docker, AppImage, and streaming.</p>
|
|
<div class="condition-track"><div class="condition-fill" style="width:92%; background:var(--neon-green)"></div></div>
|
|
<a href="guides.html" class="visit-btn">VISIT</a>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- EDU TOYS -->
|
|
<div class="item-card damaged">
|
|
<div class="rarity-pip pip-damaged"></div>
|
|
<div class="item-img-zone">🧪</div>
|
|
<div class="item-body">
|
|
<div class="item-name">EDU TOYS</div>
|
|
<div class="item-meta">
|
|
<span>4 ITEMS</span>
|
|
<span style="color:var(--fire-coral)">DAMAGED</span>
|
|
</div>
|
|
<p class="item-desc">Artifacts from an early course prototype. Janky but preserved.</p>
|
|
<div class="condition-track"><div class="condition-fill" style="width:35%; background:var(--fire-coral)"></div></div>
|
|
<a href="edu-toys.html" class="visit-btn">VISIT</a>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- UNIQUE CURIO -->
|
|
<div class="item-card unique">
|
|
<div class="rarity-pip pip-unique"></div>
|
|
<div class="item-img-zone">🕸</div>
|
|
<div class="item-body">
|
|
<div class="item-name">DENDRITIC CURIO</div>
|
|
<div class="item-meta">
|
|
<span>1 ITEM</span>
|
|
<span style="color:var(--orchid)">UNIQUE</span>
|
|
</div>
|
|
<p class="item-desc">An early Sonnet 4 experiment. A curiosity from the beginning of the agentic age.</p>
|
|
<div class="condition-track"><div class="condition-fill" style="width:100%; background:var(--orchid)"></div></div>
|
|
<a href="dendritic_links_network_v23.html" class="visit-btn">VISIT</a>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
/* === EMBER PARTICLE SYSTEM (Night Sky Adaptation) === */
|
|
const canvas = document.getElementById('embers');
|
|
const ctx = canvas.getContext('2d');
|
|
|
|
function resize() {
|
|
canvas.width = window.innerWidth;
|
|
canvas.height = window.innerHeight;
|
|
}
|
|
resize();
|
|
window.addEventListener('resize', resize);
|
|
|
|
const EMBER_COUNT = 60;
|
|
const embers = [];
|
|
|
|
const mouse = { x: -9999, y: -9999 };
|
|
window.addEventListener('mousemove', ev => { mouse.x = ev.clientX; mouse.y = ev.clientY; });
|
|
|
|
const ZONES = [
|
|
{ r: 40, strength: 0.012 },
|
|
{ r: 90, strength: 0.004 },
|
|
{ r: 130, strength: 0.001 },
|
|
];
|
|
|
|
const COLORS = [
|
|
{ r: 232, g: 148, b: 58 }, // fire-amber
|
|
{ r: 212, g: 101, b: 74 }, // fire-coral
|
|
{ r: 255, g: 207, b: 64 }, // toucan
|
|
{ r: 197, g: 88, b: 217 }, // orchid
|
|
];
|
|
|
|
function randomEmber() {
|
|
const col = COLORS[Math.floor(Math.random() * COLORS.length)];
|
|
return {
|
|
x: Math.random() * canvas.width,
|
|
y: canvas.height + 10,
|
|
vx: (Math.random() - 0.5) * 0.8,
|
|
vy: -(0.4 + Math.random() * 1.2),
|
|
life: 0,
|
|
maxLife: 200 + Math.random() * 300,
|
|
size: 1 + Math.random() * 2,
|
|
r: col.r, g: col.g, b: col.b,
|
|
wobble: Math.random() * Math.PI * 2,
|
|
wobbleSpeed: 0.02 + Math.random() * 0.02,
|
|
trail: [],
|
|
};
|
|
}
|
|
|
|
for (let i = 0; i < EMBER_COUNT; i++) {
|
|
const e = randomEmber();
|
|
e.y = Math.random() * canvas.height;
|
|
e.life = Math.random() * e.maxLife;
|
|
embers.push(e);
|
|
}
|
|
|
|
function drawEmber(e) {
|
|
const progress = e.life / e.maxLife;
|
|
const alpha = progress < 0.1 ? progress / 0.1 : progress > 0.8 ? (1 - progress) / 0.2 : 1;
|
|
if (alpha <= 0) return;
|
|
|
|
const gAlpha = alpha * 0.38; // Dimmed as per mandate
|
|
|
|
const glow = ctx.createRadialGradient(e.x, e.y, 0, e.x, e.y, e.size * 5);
|
|
glow.addColorStop(0, `rgba(${e.r},${e.g},${e.b},${gAlpha})`);
|
|
glow.addColorStop(1, `rgba(${e.r},${e.g},${e.b},0)`);
|
|
ctx.beginPath();
|
|
ctx.arc(e.x, e.y, e.size * 5, 0, Math.PI * 2);
|
|
ctx.fillStyle = glow;
|
|
ctx.fill();
|
|
|
|
// core pixel
|
|
ctx.fillStyle = `rgba(${e.r},${e.g},${e.b},${Math.min(0.65, gAlpha * 1.4)})`;
|
|
const ps = Math.max(1, Math.round(e.size));
|
|
ctx.fillRect(Math.round(e.x) - ps, Math.round(e.y) - ps, ps * 2, ps * 2);
|
|
|
|
for (let t = 0; t < e.trail.length; t++) {
|
|
const pt = e.trail[t];
|
|
const ta = (t / e.trail.length) * gAlpha * 0.3;
|
|
ctx.fillStyle = `rgba(${e.r},${e.g},${e.b},${ta})`;
|
|
ctx.fillRect(Math.round(pt.x), Math.round(pt.y), 2, 2);
|
|
}
|
|
}
|
|
|
|
function tick() {
|
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
for (const e of embers) {
|
|
if (e.life % 6 === 0) {
|
|
e.trail.push({ x: e.x, y: e.y });
|
|
if (e.trail.length > 5) e.trail.shift();
|
|
}
|
|
const dx = mouse.x - e.x, dy = mouse.y - e.y, d = Math.sqrt(dx*dx+dy*dy);
|
|
if (d < ZONES[2].r) {
|
|
let s = 0;
|
|
for(const z of ZONES) if(d < z.r) { s = z.strength; break; }
|
|
e.vx += (dx/d)*s; e.vy += (dy/d)*s;
|
|
e.vx *= 0.98; e.vy *= 0.98;
|
|
}
|
|
e.wobble += e.wobbleSpeed;
|
|
e.x += e.vx + Math.sin(e.wobble) * 0.3;
|
|
e.y += e.vy;
|
|
e.life++;
|
|
if (e.life >= e.maxLife || e.y < -20) Object.assign(e, randomEmber());
|
|
drawEmber(e);
|
|
}
|
|
requestAnimationFrame(tick);
|
|
}
|
|
tick();
|
|
|
|
// Simple category switching logic
|
|
const catItems = document.querySelectorAll('.cat-item');
|
|
catItems.forEach(item => {
|
|
item.addEventListener('click', () => {
|
|
catItems.forEach(c => c.classList.remove('active'));
|
|
item.classList.add('active');
|
|
});
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|