2026-02-19T11-57-39_auto_memory/memories.db-shm, memory/memories.db-wal, me
This commit is contained in:
parent
63352f6df1
commit
f0a945f17a
@ -1221,3 +1221,11 @@
|
||||
{"timestamp":"2026-02-19T11:48:54.952Z","level":"info","category":"watcher","message":"File added","data":{"path":"/home/nicholai/.agents/memory/memories.db-wal"}}
|
||||
{"timestamp":"2026-02-19T11:49:03.513Z","level":"info","category":"git","message":"Auto-committed","data":{"message":"2026-02-19T11-48-59_auto_memory/memories.db-shm, memory/vectors.zvec/idmap.","filesChanged":56}}
|
||||
{"timestamp":"2026-02-19T11:49:09.301Z","level":"info","category":"watcher","message":"File changed","data":{"path":"/home/nicholai/.agents/memory/memories.db-shm"}}
|
||||
{"timestamp":"2026-02-19T11:49:14.318Z","level":"info","category":"git","message":"Auto-committed","data":{"message":"2026-02-19T11-49-14_auto_memory/memories.db-shm","filesChanged":1}}
|
||||
{"timestamp":"2026-02-19T11:52:12.012Z","level":"warn","category":"git","message":"Periodic sync failed: No git credentials found. Run `gh auth login` or set GITHUB_TOKEN secret."}
|
||||
{"timestamp":"2026-02-19T11:57:12.011Z","level":"warn","category":"git","message":"Periodic sync failed: No git credentials found. Run `gh auth login` or set GITHUB_TOKEN secret."}
|
||||
{"timestamp":"2026-02-19T11:57:30.231Z","level":"info","category":"watcher","message":"File added","data":{"path":"/home/nicholai/.agents/memory/memories.db-shm"}}
|
||||
{"timestamp":"2026-02-19T11:57:30.231Z","level":"info","category":"watcher","message":"File added","data":{"path":"/home/nicholai/.agents/memory/memories.db-wal"}}
|
||||
{"timestamp":"2026-02-19T11:57:30.246Z","level":"info","category":"watcher","message":"File changed","data":{"path":"/home/nicholai/.agents/memory/memories.db-shm"}}
|
||||
{"timestamp":"2026-02-19T11:57:30.489Z","level":"info","category":"watcher","message":"File changed","data":{"path":"/home/nicholai/.agents/memory/memories.db-shm"}}
|
||||
{"timestamp":"2026-02-19T11:57:34.868Z","level":"info","category":"watcher","message":"File changed","data":{"path":"/home/nicholai/.agents/memory/memories.db-shm"}}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
/* === Design System Globals === */
|
||||
|
||||
/* --- Dark theme (default) --- */
|
||||
:root {
|
||||
--color-bg: #08080a;
|
||||
--color-surface: #0e0e12;
|
||||
@ -13,6 +14,8 @@
|
||||
--color-accent-hover: #c0c0c8;
|
||||
--color-danger: #8a4a48;
|
||||
--color-success: #4a7a5e;
|
||||
--color-dither: #f0f0f2;
|
||||
--color-grain-opacity: 0.04;
|
||||
|
||||
--font-mono: 'IBM Plex Mono', monospace;
|
||||
|
||||
@ -28,6 +31,24 @@
|
||||
--dur: 0.2s;
|
||||
}
|
||||
|
||||
/* --- Light theme --- */
|
||||
[data-theme="light"] {
|
||||
--color-bg: #e4dfd8;
|
||||
--color-surface: #dbd5cd;
|
||||
--color-surface-raised: #d1cbc2;
|
||||
--color-border: rgba(0, 0, 0, 0.06);
|
||||
--color-border-strong: rgba(0, 0, 0, 0.12);
|
||||
--color-text: #2a2a2e;
|
||||
--color-text-bright: #0a0a0c;
|
||||
--color-text-muted: #9a968f;
|
||||
--color-accent: #6a6660;
|
||||
--color-accent-hover: #3a3832;
|
||||
--color-danger: #8a4a48;
|
||||
--color-success: #4a7a5e;
|
||||
--color-dither: #0a0a0c;
|
||||
--color-grain-opacity: 0.06;
|
||||
}
|
||||
|
||||
*, *::before, *::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
@ -42,6 +63,7 @@ body {
|
||||
line-height: 1.55;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
overflow-x: hidden;
|
||||
transition: background 0.4s var(--ease), color 0.4s var(--ease);
|
||||
}
|
||||
|
||||
/* Grain */
|
||||
@ -51,7 +73,7 @@ body::before {
|
||||
inset: 0;
|
||||
z-index: 9999;
|
||||
pointer-events: none;
|
||||
opacity: 0.04;
|
||||
opacity: var(--color-grain-opacity);
|
||||
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 512 512' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.2' numOctaves='5' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
|
||||
background-repeat: repeat;
|
||||
background-size: 256px;
|
||||
@ -99,7 +121,7 @@ code, .mono {
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.14em;
|
||||
color: var(--color-bg);
|
||||
background: var(--color-text);
|
||||
background: var(--color-text-bright);
|
||||
padding: 2px 8px 1px;
|
||||
}
|
||||
|
||||
@ -128,6 +150,23 @@ code, .mono {
|
||||
top: 50%;
|
||||
}
|
||||
|
||||
/* === 4-pointed star === */
|
||||
|
||||
.star-4 {
|
||||
display: inline-block;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
flex-shrink: 0;
|
||||
background: var(--color-text-muted);
|
||||
clip-path: polygon(
|
||||
50% 0%, 60% 35%, 100% 50%, 60% 65%,
|
||||
50% 100%, 40% 65%, 0% 50%, 40% 35%
|
||||
);
|
||||
}
|
||||
.star-4--bright {
|
||||
background: var(--color-text-bright);
|
||||
}
|
||||
|
||||
/* === Buttons === */
|
||||
|
||||
.btn {
|
||||
@ -155,7 +194,7 @@ code, .mono {
|
||||
.btn:active { opacity: 0.8; }
|
||||
|
||||
.btn-primary {
|
||||
border-color: var(--color-text);
|
||||
border-color: var(--color-text-bright);
|
||||
color: var(--color-text-bright);
|
||||
}
|
||||
.btn-primary:hover {
|
||||
@ -205,12 +244,11 @@ code, .mono {
|
||||
transition: border-color var(--dur) var(--ease);
|
||||
}
|
||||
.input::placeholder { color: var(--color-text-muted); }
|
||||
.input:focus { border-color: var(--color-text); }
|
||||
.input:focus { border-color: var(--color-text-bright); }
|
||||
|
||||
select.input {
|
||||
appearance: none;
|
||||
cursor: pointer;
|
||||
background-image: url("data:image/svg+xml,%3Csvg width='8' height='5' viewBox='0 0 8 5' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M1 1L4 4L7 1' stroke='%233e3e46' stroke-width='1' stroke-linecap='square'/%3E%3C/svg%3E");
|
||||
background-repeat: no-repeat;
|
||||
background-position: right 12px center;
|
||||
padding-right: 32px;
|
||||
@ -234,10 +272,14 @@ select.input {
|
||||
}
|
||||
.badge-accent {
|
||||
color: var(--color-text-bright);
|
||||
border-color: var(--color-text);
|
||||
border-color: var(--color-text-bright);
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
}
|
||||
|
||||
[data-theme="light"] .badge-accent {
|
||||
background: rgba(0, 0, 0, 0.04);
|
||||
}
|
||||
|
||||
/* === Card === */
|
||||
|
||||
.card {
|
||||
@ -247,7 +289,7 @@ select.input {
|
||||
padding: var(--space-lg);
|
||||
transition: border-color var(--dur) var(--ease);
|
||||
}
|
||||
.card:hover { border-color: rgba(255, 255, 255, 0.2); }
|
||||
.card:hover { border-color: var(--color-text-muted); }
|
||||
|
||||
/* === Vertical text === */
|
||||
|
||||
@ -258,7 +300,7 @@ select.input {
|
||||
font-size: 0.625rem;
|
||||
letter-spacing: 0.2em;
|
||||
text-transform: uppercase;
|
||||
color: rgba(255, 255, 255, 0.1);
|
||||
color: var(--color-border-strong);
|
||||
}
|
||||
|
||||
/* === Utilities === */
|
||||
|
||||
781
skills/signet-design/assets/index.html
Normal file
781
skills/signet-design/assets/index.html
Normal file
@ -0,0 +1,781 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" data-theme="dark">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Design Brief</title>
|
||||
<link rel="stylesheet" href="globals.css">
|
||||
<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=IBM+Plex+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
.page {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
max-width: 820px;
|
||||
margin: 0 auto;
|
||||
padding: var(--space-xl) var(--space-lg);
|
||||
}
|
||||
|
||||
/* === Theme toggle === */
|
||||
.theme-toggle {
|
||||
position: fixed;
|
||||
top: 20px;
|
||||
right: 24px;
|
||||
z-index: 100;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
cursor: pointer;
|
||||
background: none;
|
||||
border: 1px solid var(--color-border-strong);
|
||||
padding: 6px 12px;
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.5625rem;
|
||||
font-weight: 500;
|
||||
letter-spacing: 0.14em;
|
||||
text-transform: uppercase;
|
||||
color: var(--color-text-muted);
|
||||
transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease);
|
||||
}
|
||||
.theme-toggle:hover {
|
||||
color: var(--color-text);
|
||||
border-color: var(--color-text-muted);
|
||||
}
|
||||
.theme-toggle .toggle-dot {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
background: var(--color-text-muted);
|
||||
transition: background var(--dur) var(--ease);
|
||||
}
|
||||
.theme-toggle:hover .toggle-dot {
|
||||
background: var(--color-text);
|
||||
}
|
||||
|
||||
/* === Hero zone with dithered canvas === */
|
||||
.hero-zone {
|
||||
position: relative;
|
||||
min-height: 360px;
|
||||
margin-bottom: var(--space-2xl);
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.hero-canvas-wrap {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#dither-canvas {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
opacity: 0.35;
|
||||
}
|
||||
|
||||
.hero-content {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
padding-bottom: var(--space-lg);
|
||||
}
|
||||
|
||||
.hero-title {
|
||||
font-size: 3.5rem;
|
||||
letter-spacing: 0.08em;
|
||||
line-height: 0.92;
|
||||
color: var(--color-text-bright);
|
||||
text-transform: uppercase;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.hero-sub {
|
||||
font-size: 0.75rem;
|
||||
color: var(--color-text-muted);
|
||||
margin-top: var(--space-sm);
|
||||
letter-spacing: 0.03em;
|
||||
}
|
||||
|
||||
/* === Schematic decorators === */
|
||||
.schematic-circle {
|
||||
position: absolute;
|
||||
border: 1px solid var(--color-border-strong);
|
||||
border-radius: 50%;
|
||||
pointer-events: none;
|
||||
}
|
||||
.schematic-circle::before,
|
||||
.schematic-circle::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
background: var(--color-border-strong);
|
||||
}
|
||||
.schematic-circle::before {
|
||||
width: 1px;
|
||||
height: 8px;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
.schematic-circle::after {
|
||||
width: 8px;
|
||||
height: 1px;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.connector-line {
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
}
|
||||
.connector-line--v {
|
||||
width: 1px;
|
||||
background: var(--color-border);
|
||||
}
|
||||
.connector-line--h {
|
||||
height: 1px;
|
||||
background: var(--color-border);
|
||||
}
|
||||
.connector-line .dot {
|
||||
position: absolute;
|
||||
width: 3px;
|
||||
height: 3px;
|
||||
border-radius: 50%;
|
||||
background: var(--color-text-muted);
|
||||
}
|
||||
|
||||
/* Vertical sidebar text */
|
||||
.sidebar-vert {
|
||||
position: fixed;
|
||||
left: 24px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
/* Right side dithered edge bleed */
|
||||
#dither-edge {
|
||||
position: fixed;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 240px;
|
||||
height: 100vh;
|
||||
opacity: 0.18;
|
||||
z-index: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* === Sections === */
|
||||
.section {
|
||||
padding-bottom: var(--space-xl);
|
||||
margin-bottom: var(--space-xl);
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
}
|
||||
.section:last-child {
|
||||
border-bottom: none;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.section-content { margin-top: var(--space-md); }
|
||||
|
||||
.section-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--space-sm);
|
||||
}
|
||||
|
||||
/* === Swatches === */
|
||||
.swatch {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 50%;
|
||||
border: 1px solid var(--color-border-strong);
|
||||
}
|
||||
.swatch-label {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.5rem;
|
||||
color: var(--color-text-muted);
|
||||
letter-spacing: 0.08em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
/* Type specimen */
|
||||
.type-specimen {
|
||||
border-left: 1px solid var(--color-border-strong);
|
||||
padding-left: var(--space-md);
|
||||
}
|
||||
|
||||
.code-block {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.6875rem;
|
||||
color: var(--color-text-muted);
|
||||
padding: var(--space-sm) var(--space-md);
|
||||
background: var(--color-surface);
|
||||
border: 1px solid var(--color-border);
|
||||
display: block;
|
||||
letter-spacing: 0.03em;
|
||||
}
|
||||
|
||||
.tri {
|
||||
display: inline-block;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 4px solid currentColor;
|
||||
border-top: 2.5px solid transparent;
|
||||
border-bottom: 2.5px solid transparent;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* === Dither block — bold compositional element === */
|
||||
.dither-block {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
background: var(--color-surface);
|
||||
}
|
||||
.dither-block canvas {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.dither-block--hero-side {
|
||||
margin: var(--space-lg) 0;
|
||||
height: 120px;
|
||||
}
|
||||
|
||||
.dither-block--section {
|
||||
height: 80px;
|
||||
margin: var(--space-md) 0 var(--space-sm);
|
||||
}
|
||||
|
||||
.dither-block--wide {
|
||||
height: 160px;
|
||||
margin: var(--space-lg) 0;
|
||||
}
|
||||
|
||||
/* === Numbered index === */
|
||||
.num-index {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(8, 1fr);
|
||||
gap: 3px 6px;
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.625rem;
|
||||
color: var(--color-text-muted);
|
||||
letter-spacing: 0.06em;
|
||||
max-width: 240px;
|
||||
}
|
||||
.num-index span {
|
||||
text-align: right;
|
||||
padding: 2px 0;
|
||||
}
|
||||
|
||||
/* === Inline dithered section art (legacy, now bolder) === */
|
||||
.dither-inline {
|
||||
height: 80px;
|
||||
margin: var(--space-md) 0 var(--space-sm);
|
||||
opacity: 0.8;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* === Editorial asymmetric offset === */
|
||||
.offset-right {
|
||||
margin-left: auto;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
/* === Footer bar === */
|
||||
.footer-bar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-end;
|
||||
margin-top: var(--space-2xl);
|
||||
padding-top: var(--space-lg);
|
||||
border-top: 1px solid var(--color-border);
|
||||
}
|
||||
|
||||
/* === Crosshair field === */
|
||||
.crosshair-field {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
pointer-events: none;
|
||||
z-index: 0;
|
||||
}
|
||||
.crosshair-field .ch {
|
||||
position: absolute;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
}
|
||||
.crosshair-field .ch::before,
|
||||
.crosshair-field .ch::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
background: var(--color-border);
|
||||
}
|
||||
.crosshair-field .ch::before {
|
||||
width: 1px;
|
||||
height: 100%;
|
||||
left: 50%;
|
||||
}
|
||||
.crosshair-field .ch::after {
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
top: 50%;
|
||||
}
|
||||
|
||||
/* === Schematic overlay (fixed background) === */
|
||||
.schematic-overlay {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
pointer-events: none;
|
||||
z-index: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* Star symbols */
|
||||
.star-marker {
|
||||
position: absolute;
|
||||
font-size: 0.5rem;
|
||||
letter-spacing: 0.12em;
|
||||
color: var(--color-border-strong);
|
||||
font-family: var(--font-mono);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- Theme toggle -->
|
||||
<button class="theme-toggle" id="theme-toggle" aria-label="Toggle theme">
|
||||
<span class="toggle-dot"></span>
|
||||
<span class="toggle-label">Dark</span>
|
||||
</button>
|
||||
|
||||
<!-- Background layers -->
|
||||
<div class="schematic-overlay">
|
||||
<!-- Schematic circles -->
|
||||
<div class="schematic-circle" style="width: 80px; height: 80px; top: 8%; right: 12%;"></div>
|
||||
<div class="schematic-circle" style="width: 120px; height: 120px; top: 45%; left: 4%;"></div>
|
||||
<div class="schematic-circle" style="width: 50px; height: 50px; bottom: 20%; right: 25%;"></div>
|
||||
|
||||
<!-- Connector lines -->
|
||||
<div class="connector-line connector-line--v" style="left: 8%; top: 15%; height: 200px;">
|
||||
<span class="dot" style="top: 0;"></span>
|
||||
<span class="dot" style="bottom: 0;"></span>
|
||||
</div>
|
||||
<div class="connector-line connector-line--h" style="top: 32%; left: 5%; width: 140px;">
|
||||
<span class="dot" style="left: 0;"></span>
|
||||
<span class="dot" style="right: 0;"></span>
|
||||
</div>
|
||||
<div class="connector-line connector-line--v" style="right: 15%; top: 60%; height: 160px;">
|
||||
<span class="dot" style="top: 0;"></span>
|
||||
<span class="dot" style="bottom: 0;"></span>
|
||||
</div>
|
||||
|
||||
<!-- Star markers -->
|
||||
<span class="star-marker" style="top: 6%; left: 3%;">****</span>
|
||||
<span class="star-marker" style="top: 6%; right: 3%;">****</span>
|
||||
<span class="star-marker" style="bottom: 4%; left: 3%;">****</span>
|
||||
</div>
|
||||
|
||||
<div class="crosshair-field">
|
||||
<div class="ch" style="top: 10%; left: 15%;"></div>
|
||||
<div class="ch" style="top: 10%; left: 55%;"></div>
|
||||
<div class="ch" style="top: 10%; left: 85%;"></div>
|
||||
<div class="ch" style="top: 35%; left: 30%;"></div>
|
||||
<div class="ch" style="top: 35%; left: 70%;"></div>
|
||||
<div class="ch" style="top: 60%; left: 10%;"></div>
|
||||
<div class="ch" style="top: 60%; left: 50%;"></div>
|
||||
<div class="ch" style="top: 60%; left: 90%;"></div>
|
||||
<div class="ch" style="top: 85%; left: 25%;"></div>
|
||||
<div class="ch" style="top: 85%; left: 75%;"></div>
|
||||
</div>
|
||||
|
||||
<!-- Right edge dithered bleed -->
|
||||
<canvas id="dither-edge"></canvas>
|
||||
|
||||
<!-- Vertical sidebar -->
|
||||
<div class="sidebar-vert">
|
||||
<span class="vertical-text">Sys_Component_Library_v01</span>
|
||||
</div>
|
||||
|
||||
<div class="page">
|
||||
|
||||
<!-- Hero -->
|
||||
<div class="hero-zone">
|
||||
<div class="hero-canvas-wrap">
|
||||
<canvas id="dither-canvas"></canvas>
|
||||
</div>
|
||||
<div class="hero-content">
|
||||
<div class="flex items-center gap-sm" style="margin-bottom: var(--space-md);">
|
||||
<span class="label-inv">SYS</span>
|
||||
<span class="star-4"></span>
|
||||
<span class="label">Design_Brief</span>
|
||||
</div>
|
||||
<div class="hero-title">Component<br>Library</div>
|
||||
<p class="hero-sub">Core UI primitives and tokens.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Bold dither block — compositional anchor -->
|
||||
<div class="dither-block dither-block--wide">
|
||||
<canvas data-dither="glitch-wide"></canvas>
|
||||
</div>
|
||||
|
||||
<!-- Colors -->
|
||||
<div class="section">
|
||||
<div class="section-header">
|
||||
<div class="crosshair"></div>
|
||||
<span class="label">Sys_Palette</span>
|
||||
<span class="star-4" style="margin-left: auto;"></span>
|
||||
</div>
|
||||
<div class="flex gap-lg wrap section-content">
|
||||
<div class="flex flex-col gap-xs items-center">
|
||||
<div class="swatch" style="background: var(--color-bg);"></div>
|
||||
<span class="swatch-label">bg</span>
|
||||
</div>
|
||||
<div class="flex flex-col gap-xs items-center">
|
||||
<div class="swatch" style="background: var(--color-surface);"></div>
|
||||
<span class="swatch-label">srf</span>
|
||||
</div>
|
||||
<div class="flex flex-col gap-xs items-center">
|
||||
<div class="swatch" style="background: var(--color-surface-raised);"></div>
|
||||
<span class="swatch-label">rsd</span>
|
||||
</div>
|
||||
<div class="flex flex-col gap-xs items-center">
|
||||
<div class="swatch" style="background: var(--color-border-strong);"></div>
|
||||
<span class="swatch-label">brd</span>
|
||||
</div>
|
||||
<div class="flex flex-col gap-xs items-center">
|
||||
<div class="swatch" style="background: var(--color-text);"></div>
|
||||
<span class="swatch-label">txt</span>
|
||||
</div>
|
||||
<div class="flex flex-col gap-xs items-center">
|
||||
<div class="swatch" style="background: var(--color-text-muted);"></div>
|
||||
<span class="swatch-label">mtd</span>
|
||||
</div>
|
||||
<div class="flex flex-col gap-xs items-center">
|
||||
<div class="swatch" style="background: var(--color-accent);"></div>
|
||||
<span class="swatch-label">acc</span>
|
||||
</div>
|
||||
<div class="flex flex-col gap-xs items-center">
|
||||
<div class="swatch" style="background: var(--color-danger);"></div>
|
||||
<span class="swatch-label">err</span>
|
||||
</div>
|
||||
<div class="flex flex-col gap-xs items-center">
|
||||
<div class="swatch" style="background: var(--color-success);"></div>
|
||||
<span class="swatch-label">ok</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Typography -->
|
||||
<div class="section">
|
||||
<div class="section-header">
|
||||
<div class="crosshair"></div>
|
||||
<span class="label">Sys_Type</span>
|
||||
</div>
|
||||
<div class="dither-block dither-block--section">
|
||||
<canvas data-dither="band"></canvas>
|
||||
</div>
|
||||
<div class="flex flex-col gap-md section-content type-specimen">
|
||||
<h1>Heading One</h1>
|
||||
<h2>Heading Two</h2>
|
||||
<h3>Heading Three</h3>
|
||||
<p>Body text in muted color for secondary content.</p>
|
||||
<span class="code-block">monospace for code and data</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Buttons -->
|
||||
<div class="section">
|
||||
<div class="section-header">
|
||||
<div class="crosshair"></div>
|
||||
<span class="label">Sys_Buttons</span>
|
||||
<span class="star-4" style="margin-left: auto;"></span>
|
||||
<span class="star-4"></span>
|
||||
</div>
|
||||
<div class="flex gap-md wrap items-center section-content">
|
||||
<button class="btn btn-primary">Primary</button>
|
||||
<button class="btn btn-secondary">Secondary</button>
|
||||
<button class="btn btn-ghost">Ghost</button>
|
||||
<button class="btn btn-danger">Danger</button>
|
||||
<button class="btn btn-sm btn-secondary">Small</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Badges -->
|
||||
<div class="section">
|
||||
<div class="section-header">
|
||||
<div class="crosshair"></div>
|
||||
<span class="label">Sys_Badges</span>
|
||||
</div>
|
||||
<div class="flex gap-sm wrap items-center section-content">
|
||||
<span class="badge">Default</span>
|
||||
<span class="badge badge-accent">Accent</span>
|
||||
<span class="label-inv" style="margin-left: 4px;">Inverted</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Dither block between sections -->
|
||||
<div class="dither-block dither-block--section">
|
||||
<canvas data-dither="smear"></canvas>
|
||||
</div>
|
||||
|
||||
<!-- Inputs — offset right for asymmetry -->
|
||||
<div class="section">
|
||||
<div class="section-header">
|
||||
<div class="crosshair"></div>
|
||||
<span class="label">Sys_Form</span>
|
||||
</div>
|
||||
<div class="flex flex-col gap-md section-content offset-right" style="max-width: 340px;">
|
||||
<input class="input" type="text" placeholder="Text input...">
|
||||
<select class="input">
|
||||
<option>Select an option</option>
|
||||
<option>Option A</option>
|
||||
<option>Option B</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Card -->
|
||||
<div class="section">
|
||||
<div class="section-header">
|
||||
<div class="crosshair"></div>
|
||||
<span class="label">Sys_Card</span>
|
||||
</div>
|
||||
<div class="dither-block dither-block--section">
|
||||
<canvas data-dither="cloud"></canvas>
|
||||
</div>
|
||||
<div class="card section-content" style="max-width: 340px;">
|
||||
<div class="flex flex-col gap-md">
|
||||
<div class="flex items-center gap-sm">
|
||||
<h3>Card Title</h3>
|
||||
<span class="badge badge-accent">Tag</span>
|
||||
</div>
|
||||
<p>A surface container for grouped content.</p>
|
||||
<div class="flex gap-sm">
|
||||
<button class="btn btn-sm btn-primary">
|
||||
<span class="tri"></span>
|
||||
Action
|
||||
</button>
|
||||
<button class="btn btn-sm btn-ghost">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Footer with numbered index -->
|
||||
<div class="footer-bar">
|
||||
<div class="flex items-center gap-sm">
|
||||
<span class="star-4"></span>
|
||||
<span class="label">Sys_Index</span>
|
||||
</div>
|
||||
<div class="num-index">
|
||||
<span>00</span><span>01</span><span>02</span><span>03</span>
|
||||
<span>04</span><span>05</span><span>06</span><span>07</span>
|
||||
<span>08</span><span>09</span><span>10</span><span>11</span>
|
||||
<span>12</span><span>13</span><span>14</span><span>15</span>
|
||||
<span>16</span><span>17</span><span>18</span><span>19</span>
|
||||
<span>20</span><span>21</span><span>22</span><span>23</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(() => {
|
||||
// === Theme toggle ===
|
||||
const toggle = document.getElementById('theme-toggle');
|
||||
const html = document.documentElement;
|
||||
const label = toggle.querySelector('.toggle-label');
|
||||
|
||||
function setTheme(theme) {
|
||||
html.setAttribute('data-theme', theme);
|
||||
label.textContent = theme === 'dark' ? 'Dark' : 'Light';
|
||||
// Re-render all canvases
|
||||
setTimeout(renderAllDither, 60);
|
||||
}
|
||||
|
||||
toggle.addEventListener('click', () => {
|
||||
const current = html.getAttribute('data-theme') || 'dark';
|
||||
setTheme(current === 'dark' ? 'light' : 'dark');
|
||||
});
|
||||
|
||||
// === Perlin noise ===
|
||||
const PERM = new Uint8Array(512);
|
||||
for (let i = 0; i < 256; i++) PERM[i] = i;
|
||||
// Seeded shuffle for consistency
|
||||
let seed = 42;
|
||||
function seededRand() {
|
||||
seed = (seed * 16807 + 0) % 2147483647;
|
||||
return (seed - 1) / 2147483646;
|
||||
}
|
||||
for (let i = 255; i > 0; i--) {
|
||||
const j = Math.floor(seededRand() * (i + 1));
|
||||
[PERM[i], PERM[j]] = [PERM[j], PERM[i]];
|
||||
}
|
||||
for (let i = 0; i < 256; i++) PERM[i + 256] = PERM[i];
|
||||
|
||||
function fade(t) { return t * t * t * (t * (t * 6 - 15) + 10); }
|
||||
function lerp(a, b, t) { return a + t * (b - a); }
|
||||
function grad(hash, x, y) {
|
||||
const h = hash & 3;
|
||||
return (h < 2 ? x : -x) + (h === 0 || h === 3 ? y : -y);
|
||||
}
|
||||
|
||||
function noise2d(x, y) {
|
||||
const xi = Math.floor(x) & 255, yi = Math.floor(y) & 255;
|
||||
const xf = x - Math.floor(x), yf = y - Math.floor(y);
|
||||
const u = fade(xf), v = fade(yf);
|
||||
const aa = PERM[PERM[xi] + yi], ab = PERM[PERM[xi] + yi + 1];
|
||||
const ba = PERM[PERM[xi + 1] + yi], bb = PERM[PERM[xi + 1] + yi + 1];
|
||||
return lerp(
|
||||
lerp(grad(aa, xf, yf), grad(ba, xf - 1, yf), u),
|
||||
lerp(grad(ab, xf, yf - 1), grad(bb, xf - 1, yf - 1), u), v
|
||||
);
|
||||
}
|
||||
|
||||
function fbm(x, y, octaves = 4) {
|
||||
let val = 0, amp = 0.5, freq = 1;
|
||||
for (let i = 0; i < octaves; i++) {
|
||||
val += amp * noise2d(x * freq, y * freq);
|
||||
amp *= 0.5;
|
||||
freq *= 2;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
// === Bayer 4x4 ===
|
||||
const BAYER4 = [
|
||||
0, 8, 2, 10,
|
||||
12, 4, 14, 6,
|
||||
3, 11, 1, 9,
|
||||
15, 7, 13, 5,
|
||||
];
|
||||
|
||||
function getDitherColor() {
|
||||
const style = getComputedStyle(document.documentElement);
|
||||
return style.getPropertyValue('--color-dither').trim() || '#f0f0f2';
|
||||
}
|
||||
|
||||
function ditherCanvas(canvas, noiseFn, pixelSize = 4, threshold = 0.5) {
|
||||
const rect = canvas.getBoundingClientRect();
|
||||
const w = Math.floor(rect.width);
|
||||
const h = Math.floor(rect.height);
|
||||
if (w === 0 || h === 0) return;
|
||||
canvas.width = w;
|
||||
canvas.height = h;
|
||||
|
||||
const ctx = canvas.getContext('2d');
|
||||
ctx.clearRect(0, 0, w, h);
|
||||
const cols = Math.floor(w / pixelSize);
|
||||
const rows = Math.floor(h / pixelSize);
|
||||
|
||||
ctx.fillStyle = getDitherColor();
|
||||
|
||||
for (let y = 0; y < rows; y++) {
|
||||
for (let x = 0; x < cols; x++) {
|
||||
const val = noiseFn(x, y, cols, rows);
|
||||
const bayerVal = BAYER4[(y % 4) * 4 + (x % 4)] / 16;
|
||||
if (val + (bayerVal - 0.5) * 0.4 > threshold) {
|
||||
ctx.fillRect(x * pixelSize, y * pixelSize, pixelSize - 1, pixelSize - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// === Glitch/smear dither — vertical streaks like the rave poster ===
|
||||
function glitchNoise(x, y, cols, rows, offsetX = 0, offsetY = 0) {
|
||||
const nx = x / cols * 5 + offsetX;
|
||||
const ny = y / rows * 3 + offsetY;
|
||||
// Base organic shape
|
||||
const base = fbm(nx, ny, 5) * 0.5 + 0.5;
|
||||
// Vertical smear — sample noise with stretched Y
|
||||
const smearY = y / rows * 0.4;
|
||||
const smear = fbm(nx * 0.3, smearY + offsetY, 3) * 0.5 + 0.5;
|
||||
// Horizontal glitch bands
|
||||
const bandNoise = noise2d(0.1, y / rows * 20 + offsetY) * 0.5 + 0.5;
|
||||
const glitchShift = bandNoise > 0.65 ? (bandNoise - 0.65) * 8 : 0;
|
||||
const shiftedBase = fbm(nx + glitchShift, ny, 4) * 0.5 + 0.5;
|
||||
// Combine
|
||||
return shiftedBase * 0.5 + smear * 0.3 + base * 0.2;
|
||||
}
|
||||
|
||||
function renderAllDither() {
|
||||
// Hero canvas
|
||||
const heroCanvas = document.getElementById('dither-canvas');
|
||||
if (heroCanvas) {
|
||||
ditherCanvas(heroCanvas, (x, y, cols, rows) => {
|
||||
const nx = x / cols * 4;
|
||||
const ny = y / rows * 4;
|
||||
const n1 = fbm(nx + 1.3, ny + 0.7, 5);
|
||||
const n2 = fbm(nx * 1.5 + 5, ny * 1.5 + 3, 4);
|
||||
const edgeX = Math.min(x / cols, 1 - x / cols) * 2;
|
||||
const edgeY = Math.min(y / rows, 1 - y / rows) * 2;
|
||||
const edgeFade = Math.min(edgeX, edgeY);
|
||||
const combined = (n1 * 0.6 + n2 * 0.4) - edgeFade * 0.3;
|
||||
return combined * 0.5 + 0.5;
|
||||
}, 4, 0.46);
|
||||
}
|
||||
|
||||
// Right edge bleed
|
||||
const edgeCanvas = document.getElementById('dither-edge');
|
||||
if (edgeCanvas) {
|
||||
edgeCanvas.style.width = '240px';
|
||||
edgeCanvas.style.height = '100vh';
|
||||
ditherCanvas(edgeCanvas, (x, y, cols, rows) => {
|
||||
const nx = x / cols * 3;
|
||||
const ny = y / rows * 6;
|
||||
const n = fbm(nx + 8, ny + 2, 4);
|
||||
const edgeFade = x / cols;
|
||||
return (n * 0.5 + 0.5) * edgeFade;
|
||||
}, 3, 0.52);
|
||||
}
|
||||
|
||||
// Data-dither canvases
|
||||
document.querySelectorAll('[data-dither]').forEach(canvas => {
|
||||
const type = canvas.dataset.dither;
|
||||
|
||||
if (type === 'glitch-wide') {
|
||||
ditherCanvas(canvas, (x, y, cols, rows) =>
|
||||
glitchNoise(x, y, cols, rows, 0, 0)
|
||||
, 3, 0.42);
|
||||
} else if (type === 'band') {
|
||||
ditherCanvas(canvas, (x, y, cols, rows) => {
|
||||
const nx = x / cols * 8;
|
||||
const ny = y / rows * 3;
|
||||
return fbm(nx, ny + 20, 3) * 0.5 + 0.5;
|
||||
}, 3, 0.55);
|
||||
} else if (type === 'smear') {
|
||||
ditherCanvas(canvas, (x, y, cols, rows) =>
|
||||
glitchNoise(x, y, cols, rows, 15, 7)
|
||||
, 3, 0.45);
|
||||
} else if (type === 'cloud') {
|
||||
ditherCanvas(canvas, (x, y, cols, rows) => {
|
||||
const nx = x / cols * 5;
|
||||
const ny = y / rows * 3;
|
||||
const n = fbm(nx + 40, ny + 10, 4);
|
||||
const cx = (x / cols - 0.5) * 2;
|
||||
const cy = (y / rows - 0.5) * 2;
|
||||
const dist = Math.sqrt(cx * cx + cy * cy);
|
||||
return (n * 0.5 + 0.5) * (1 - dist * 0.3);
|
||||
}, 3, 0.5);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Initial render
|
||||
renderAllDither();
|
||||
|
||||
// Re-render on resize
|
||||
let resizeTimer;
|
||||
window.addEventListener('resize', () => {
|
||||
clearTimeout(resizeTimer);
|
||||
resizeTimer = setTimeout(renderAllDither, 150);
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
x
Reference in New Issue
Block a user