added more specs and rebuilt for simpler additions
This commit is contained in:
@@ -3,83 +3,368 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Design Spec Samples Catalog</title>
|
||||
<title>Design Spec Samples Catalog | Dynamic Registry</title>
|
||||
<style>
|
||||
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;700&family=Inter:wght@400;500;700&family=JetBrains+Mono:wght@400;500&display=swap');
|
||||
|
||||
:root {
|
||||
--bg-canvas: #0d0f12;
|
||||
--bg-surface: #121417;
|
||||
--bg-elevated: #1c1f26;
|
||||
--border-color: #2b303b;
|
||||
--text-primary: #e0e6f0;
|
||||
--text-muted: #8a95a5;
|
||||
--accent-cyan: #00f0ff;
|
||||
--accent-green: #00e676;
|
||||
--accent-amber: #ffb700;
|
||||
}
|
||||
|
||||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
|
||||
body {
|
||||
background-color: #0d0f12;
|
||||
color: #e0e6f0;
|
||||
font-family: 'IBM Plex Mono', 'JetBrains Mono', monospace;
|
||||
max-width: 600px;
|
||||
margin: 80px auto;
|
||||
padding: 20px;
|
||||
background-color: var(--bg-canvas);
|
||||
color: var(--text-primary);
|
||||
font-family: 'Inter', sans-serif;
|
||||
line-height: 1.6;
|
||||
max-width: 860px;
|
||||
margin: 40px auto;
|
||||
padding: 0 20px;
|
||||
}
|
||||
h1 {
|
||||
font-size: 1.5rem;
|
||||
border-bottom: 1px solid #2b303b;
|
||||
padding-bottom: 10px;
|
||||
margin-bottom: 30px;
|
||||
|
||||
/* Header Identity */
|
||||
.catalog-header {
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
padding-bottom: 16px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
ul {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
|
||||
.catalog-title {
|
||||
font-family: 'IBM Plex Mono', monospace;
|
||||
font-size: 1.6rem;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
li {
|
||||
margin: 20px 0;
|
||||
padding: 15px;
|
||||
border: 1px solid #2b303b;
|
||||
|
||||
.status-dot {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
background-color: var(--accent-cyan);
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.catalog-meta {
|
||||
font-family: 'IBM Plex Mono', monospace;
|
||||
font-size: 0.82rem;
|
||||
color: var(--text-muted);
|
||||
margin-top: 6px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
/* Search Filter Input Bar */
|
||||
.filter-bar {
|
||||
margin-bottom: 24px;
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.search-input {
|
||||
background-color: var(--bg-surface);
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 4px;
|
||||
background-color: #121417;
|
||||
color: var(--text-primary);
|
||||
font-family: 'JetBrains Mono', monospace;
|
||||
font-size: 0.85rem;
|
||||
padding: 10px 14px;
|
||||
width: 100%;
|
||||
outline: none;
|
||||
}
|
||||
a {
|
||||
color: #ffb000;
|
||||
|
||||
.search-input:focus {
|
||||
border-color: var(--accent-cyan);
|
||||
}
|
||||
|
||||
/* Dynamic Catalog Cards List */
|
||||
.samples-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.sample-card {
|
||||
background-color: var(--bg-surface);
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 4px;
|
||||
padding: 16px;
|
||||
transition: none; /* Instant snap */
|
||||
}
|
||||
|
||||
.sample-card:hover {
|
||||
border-color: var(--accent-cyan);
|
||||
background-color: var(--bg-elevated);
|
||||
}
|
||||
|
||||
.sample-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.sample-link {
|
||||
font-family: 'IBM Plex Mono', monospace;
|
||||
font-size: 1.05rem;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
transition: none;
|
||||
}
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
|
||||
.sample-link:hover {
|
||||
color: var(--accent-cyan);
|
||||
}
|
||||
p {
|
||||
color: #8a95a5;
|
||||
font-size: 0.9rem;
|
||||
margin-top: 8px;
|
||||
margin-bottom: 0;
|
||||
line-height: 1.5;
|
||||
|
||||
.badge {
|
||||
font-family: 'IBM Plex Mono', monospace;
|
||||
font-size: 0.72rem;
|
||||
padding: 2px 6px;
|
||||
border-radius: 2px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.badge-html { background-color: rgba(0, 240, 255, 0.15); color: var(--accent-cyan); }
|
||||
.badge-md { background-color: rgba(255, 183, 0, 0.15); color: var(--accent-amber); }
|
||||
|
||||
.sample-filename {
|
||||
font-family: 'JetBrains Mono', monospace;
|
||||
font-size: 0.78rem;
|
||||
color: var(--text-muted);
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.sample-desc {
|
||||
font-size: 0.88rem;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
/* Footer */
|
||||
.catalog-footer {
|
||||
margin-top: 40px;
|
||||
padding-top: 16px;
|
||||
border-top: 1px solid var(--border-color);
|
||||
font-family: 'IBM Plex Mono', monospace;
|
||||
font-size: 0.78rem;
|
||||
color: var(--text-muted);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Design Spec Samples</h1>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="homepage.html">Sample 1: Developer Homepage (Terminal/Minimalist Spec)</a>
|
||||
<p>
|
||||
A premium, dark-mode native developer homepage modeled after modern, high-density terminal setups and IDEs. Adheres strictly to the guidelines: no glassmorphism, no rounded blobs, and pure solid color layouts.
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<a href="split-panel.html">Sample 2: Split Panel Layout (ASCII Animation & Scrollable Tiles)</a>
|
||||
<p>
|
||||
A dashboard/panel layout with a sticky site nav header, a left panel featuring an animated terminal ASCII character, and a right panel containing a scrollable feed of developer project cards.
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<a href="companion.html">Sample 3: Companion Layout (Interactive Daemon & Ultra-Minimal Cards)</a>
|
||||
<p>
|
||||
A 50/50 vertical split layout page where the left column contains content cards and the right column houses a persistent, reactive ASCII companion. Employs ultra-minimal borders and discrete state updates.
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<a href="document-flow.html">Sample 4: Document Flow Layout (Scroll-Tracker Daemon & Seamless Document Stream)</a>
|
||||
<p>
|
||||
A continuous document reading flow that removes 4-sided bounding boxes and master-detail click affordances. Features a fixed left pane with an IntersectionObserver scroll-tracker daemon.
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<a href="portfolio.html">Sample 5: River Rooks Portfolio (Single-Page Landing Page)</a>
|
||||
<p>
|
||||
A temporary, single-column digital business card and landing page conforming strictly to portfolio-spec.md. Features a 65ch centered flow, 8x8px active status dot, terminal stdout block, active stack tags, and piped link footer.
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<header class="catalog-header">
|
||||
<h1 class="catalog-title">
|
||||
<span class="status-dot"></span>
|
||||
DESIGN SPEC SAMPLES CATALOG
|
||||
</h1>
|
||||
<div class="catalog-meta">
|
||||
<span>PATH: /samples/</span>
|
||||
<span id="file-counter">SCANNING DIRECTORY...</span>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- Filter Input -->
|
||||
<div class="filter-bar">
|
||||
<input type="text" id="search-box" class="search-input" placeholder="Search samples by name, keyword, or filename... ($ grep -i)" oninput="filterSamples()">
|
||||
</div>
|
||||
|
||||
<!-- Dynamic Catalog Container -->
|
||||
<main id="samples-container" class="samples-list">
|
||||
<!-- Rendered dynamically by JavaScript -->
|
||||
</main>
|
||||
|
||||
<footer class="catalog-footer">
|
||||
<div>Unified Design Language Compliant</div>
|
||||
<div>POSIX / Terminal Minimalist Spec</div>
|
||||
</footer>
|
||||
|
||||
<script>
|
||||
// Known files catalog with fallback metadata definitions
|
||||
const knownFiles = [
|
||||
{
|
||||
file: 'unified-design-specification.md',
|
||||
title: 'Unified Design Specification (Master Brief)',
|
||||
type: 'md',
|
||||
desc: 'The master specification uniting Homelab Services Directory, Technical Blog/Notes, and Resume/Portfolio into a dark slate (#0d0f12), dual-typography (IBM Plex Mono + Inter), instant snap interaction language.'
|
||||
},
|
||||
{
|
||||
file: 'sample-dashboard.html',
|
||||
title: 'Sample 8: Terminal Workspace Dashboard (3-Tile Split)',
|
||||
type: 'html',
|
||||
desc: 'A 3-tile modal editor workspace layout (Neovim/Tmux style) featuring live homelab services, resume bio, article log stream, and interactive vim command bar.'
|
||||
},
|
||||
{
|
||||
file: 'sample-command-center.html',
|
||||
title: 'Sample 9: Command Center (Zed/Ghostty Tabbed Utility)',
|
||||
type: 'html',
|
||||
desc: 'A tabbed single-pane utility layout inspired by Zed Editor and Ghostty. Features keyboard navigation hotkeys [1], [2], [3] for Services, Blog, and Resume tabs.'
|
||||
},
|
||||
{
|
||||
file: 'sample-dual-pane-explorer.html',
|
||||
title: 'Sample 10: Dual-Pane Tree Explorer (Helix File Tree)',
|
||||
type: 'html',
|
||||
desc: 'A split-screen file-tree explorer featuring a left tree sidebar, document view container, and an interactive ASCII daemon mascot (sys-daemon) reacting to item selection.'
|
||||
},
|
||||
{
|
||||
file: 'homepage.html',
|
||||
title: 'Sample 1: Developer Homepage (Terminal Minimalist Spec)',
|
||||
type: 'html',
|
||||
desc: 'A dark-mode native developer homepage modeled after modern, high-density terminal setups and IDEs. Adheres strictly to zero glassmorphism and solid color layouts.'
|
||||
},
|
||||
{
|
||||
file: 'split-panel.html',
|
||||
title: 'Sample 2: Split Panel Layout (ASCII Animation & Scrollable Tiles)',
|
||||
type: 'html',
|
||||
desc: 'A dashboard layout with a sticky site nav header, left panel with animated terminal ASCII character, and right panel with scrollable developer project cards.'
|
||||
},
|
||||
{
|
||||
file: 'companion.html',
|
||||
title: 'Sample 3: Companion Layout (Interactive Daemon & Minimal Cards)',
|
||||
type: 'html',
|
||||
desc: 'A 50/50 vertical split layout with content cards on the left and a persistent, reactive ASCII companion on the right with discrete state updates.'
|
||||
},
|
||||
{
|
||||
file: 'document-flow.html',
|
||||
title: 'Sample 4: Document Flow Layout (Scroll-Tracker Daemon)',
|
||||
type: 'html',
|
||||
desc: 'A continuous document reading flow removing 4-sided bounding boxes, featuring a left pane with an IntersectionObserver scroll-tracker daemon.'
|
||||
},
|
||||
{
|
||||
file: 'portfolio.html',
|
||||
title: 'Sample 5: River Rooks Portfolio (Single-Page Business Card)',
|
||||
type: 'html',
|
||||
desc: 'A single-column digital business card landing page conforming to portfolio-spec.md with terminal stdout block, active stack tags, and piped footer.'
|
||||
},
|
||||
{
|
||||
file: 'homelab.html',
|
||||
title: 'Sample 6: Homelab Lander & Infrastructure Directory',
|
||||
type: 'html',
|
||||
desc: 'A public-facing lander for self-hosted homelab infrastructure featuring category filters, service cards, telemetry, and ASCII network topology routing map.'
|
||||
},
|
||||
{
|
||||
file: 'public-services.html',
|
||||
title: 'Sample 7: Public Services & Applications Portal',
|
||||
type: 'html',
|
||||
desc: 'A quick-access launcher portal for self-hosted web tools (Git forge, CyberChef, Stirling PDF, media) with search, filters, and access level badges.'
|
||||
},
|
||||
{
|
||||
file: 'design-specification.md',
|
||||
title: 'Design Specification (Primary Technical Brief)',
|
||||
type: 'md',
|
||||
desc: 'Primary specification document detailing technical web architecture guidelines, typography rules, color palette, and global anti-pattern constraints.'
|
||||
},
|
||||
{
|
||||
file: 'portfolio-spec.md',
|
||||
title: 'Portfolio Specification (Landing Page Brief)',
|
||||
type: 'md',
|
||||
desc: 'Specification sheet for the single-page under-construction portfolio card layout.'
|
||||
},
|
||||
{
|
||||
file: 'sample3-spec-sheet.md',
|
||||
title: 'Sample 3 Specification (Companion Layout Brief)',
|
||||
type: 'md',
|
||||
desc: 'Specification sheet detailing the split-screen ASCII companion interaction suppression policy.'
|
||||
}
|
||||
];
|
||||
|
||||
let allItems = [];
|
||||
|
||||
async function initCatalog() {
|
||||
allItems = [...knownFiles];
|
||||
|
||||
// Attempt dynamic discovery via fetch directory listing if web server supports autoindex
|
||||
try {
|
||||
const response = await fetch('./');
|
||||
if (response.ok) {
|
||||
const htmlText = await textResponse(response);
|
||||
const parser = new DOMParser();
|
||||
const doc = parser.parseFromString(htmlText, 'text/html');
|
||||
const links = Array.from(doc.querySelectorAll('a'))
|
||||
.map(a => a.getAttribute('href'))
|
||||
.filter(href => href && (href.endsWith('.html') || href.endsWith('.md')) && href !== 'index.html');
|
||||
|
||||
// Merge dynamically discovered files if any are missing from knownFiles
|
||||
links.forEach(href => {
|
||||
const cleanName = href.replace('./', '');
|
||||
if (!allItems.some(item => item.file === cleanName)) {
|
||||
const isHtml = cleanName.endsWith('.html');
|
||||
allItems.push({
|
||||
file: cleanName,
|
||||
title: cleanName,
|
||||
type: isHtml ? 'html' : 'md',
|
||||
desc: `Dynamically discovered ${isHtml ? 'HTML sample' : 'Markdown specification'} file.`
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
console.log('Directory autoindex fetch skipped, rendering fallback manifest.');
|
||||
}
|
||||
|
||||
renderCatalog(allItems);
|
||||
}
|
||||
|
||||
async function textResponse(res) {
|
||||
return await res.text();
|
||||
}
|
||||
|
||||
function renderCatalog(items) {
|
||||
const container = document.getElementById('samples-container');
|
||||
const counter = document.getElementById('file-counter');
|
||||
|
||||
counter.innerText = `${items.length} FILES INDEXED`;
|
||||
container.innerHTML = '';
|
||||
|
||||
if (items.length === 0) {
|
||||
container.innerHTML = `<div style="color: var(--text-muted); font-family: monospace;">No matching sample files found.</div>`;
|
||||
return;
|
||||
}
|
||||
|
||||
items.forEach(item => {
|
||||
const card = document.createElement('div');
|
||||
card.className = 'sample-card';
|
||||
|
||||
const badgeClass = item.type === 'html' ? 'badge-html' : 'badge-md';
|
||||
const badgeLabel = item.type === 'html' ? 'HTML SAMPLE' : 'MARKDOWN SPEC';
|
||||
|
||||
card.innerHTML = `
|
||||
<div class="sample-header">
|
||||
<a href="${item.file}" class="sample-link">${item.title}</a>
|
||||
<span class="badge ${badgeClass}">${badgeLabel}</span>
|
||||
</div>
|
||||
<div class="sample-filename">file:///samples/${item.file}</div>
|
||||
<div class="sample-desc">${item.desc}</div>
|
||||
`;
|
||||
|
||||
container.appendChild(card);
|
||||
});
|
||||
}
|
||||
|
||||
function filterSamples() {
|
||||
const query = document.getElementById('search-box').value.toLowerCase().trim();
|
||||
const filtered = allItems.filter(item =>
|
||||
item.title.toLowerCase().includes(query) ||
|
||||
item.file.toLowerCase().includes(query) ||
|
||||
item.desc.toLowerCase().includes(query)
|
||||
);
|
||||
renderCatalog(filtered);
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', initCatalog);
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user