Night Grid cyberpunk style guide
Spec, stylesheet, glitch script, Claude Code skill and the design canvas source. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
commit
94832d861b
8 files changed
+845
No files matched your search
@@ -0,0 +1,145 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Night Grid sample dashboard</title>
|
||||
<script src="./support.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<x-dc>
|
||||
<helmet>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Rajdhani:wght@500;600;700&family=JetBrains+Mono:wght@400;600&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
body{margin:0;background:#050508}
|
||||
a{color:#02D7F2}a:hover{color:#FCEE0A}
|
||||
</style>
|
||||
</helmet>
|
||||
<div style="min-height: 100vh; background: #050508; color: #E6E8EC; font-family: 'Rajdhani', sans-serif; font-size: 18px; line-height: 1.5">
|
||||
<div style="display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 16px; padding: 16px 24px; border-bottom: 1px solid #2A2F3A">
|
||||
<div style="display: flex; align-items: center; gap: 16px; flex-wrap: wrap">
|
||||
<span style="background: #FCEE0A; color: #050508; padding: 4px 12px; font-size: 22px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase">Homelab</span>
|
||||
<span style="font-family: 'JetBrains Mono', monospace; font-size: 13px; letter-spacing: 0.12em; color: #8A93A3">SYS.MONITOR // SAMPLE DATA</span>
|
||||
</div>
|
||||
<nav aria-label="Sections" style="display: flex; flex-wrap: wrap; gap: 4px">
|
||||
<a href="#" style="min-height: 44px; display: inline-flex; align-items: center; padding: 0 16px; color: #FCEE0A; text-decoration: none; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; border-bottom: 2px solid #FCEE0A">Overview</a>
|
||||
<a href="#" style="min-height: 44px; display: inline-flex; align-items: center; padding: 0 16px; color: #8A93A3; text-decoration: none; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase">Nodes</a>
|
||||
<a href="#" style="min-height: 44px; display: inline-flex; align-items: center; padding: 0 16px; color: #8A93A3; text-decoration: none; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase">Network</a>
|
||||
<a href="#" style="min-height: 44px; display: inline-flex; align-items: center; padding: 0 16px; color: #8A93A3; text-decoration: none; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase">Logs</a>
|
||||
</nav>
|
||||
<span style="font-family: 'JetBrains Mono', monospace; font-size: 13px; color: #02D7F2">● LIVE 22:41:07</span>
|
||||
</div>
|
||||
|
||||
<div style="max-width: 1360px; margin: 0 auto; padding: 32px 24px 64px; display: flex; flex-direction: column; gap: 24px">
|
||||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 16px">
|
||||
<sc-for list="{{stats}}" as="s" hint-placeholder-count="4">
|
||||
<div style="background: #0E1016; border: 1px solid #2A2F3A; padding: 20px 24px; display: flex; flex-direction: column; gap: 8px; clip-path: polygon(0 0, calc(100% - 16px) 0, 100% 16px, 100% 100%, 0 100%)">
|
||||
<div style="font-family: 'JetBrains Mono', monospace; font-size: 12px; letter-spacing: 0.15em; color: #8A93A3">{{s.label}}</div>
|
||||
<div style="font-family: 'JetBrains Mono', monospace; font-size: 40px; font-weight: 600; line-height: 1.1; color: {{s.color}}">{{s.value}}<span style="font-size: 18px; color: #8A93A3">{{s.unit}}</span></div>
|
||||
<div style="display: flex; gap: 3px">
|
||||
<sc-for list="{{s.segs}}" as="g" hint-placeholder-count="10"><div style="flex: 1; height: 6px; background: {{g}}"></div></sc-for>
|
||||
</div>
|
||||
<div style="font-family: 'JetBrains Mono', monospace; font-size: 12px; color: {{s.noteColor}}">{{s.note}}</div>
|
||||
</div>
|
||||
</sc-for>
|
||||
</div>
|
||||
|
||||
<div style="display: flex; flex-wrap: wrap; gap: 16px">
|
||||
<div style="flex: 999 1 560px; min-width: 0; background: #0E1016; border: 1px solid #2A2F3A; padding: 24px; display: flex; flex-direction: column; gap: 16px; clip-path: polygon(0 0, calc(100% - 24px) 0, 100% 24px, 100% 100%, 0 100%)">
|
||||
<div style="display: flex; justify-content: space-between; align-items: baseline; flex-wrap: wrap; gap: 8px">
|
||||
<h2 style="margin: 0; font-size: 24px; font-weight: 700; text-transform: uppercase">Network throughput</h2>
|
||||
<div style="display: flex; gap: 16px; font-family: 'JetBrains Mono', monospace; font-size: 12px; color: #8A93A3">
|
||||
<span><span style="display: inline-block; width: 10px; height: 10px; background: #02D7F2; margin-right: 6px"></span>RX</span>
|
||||
<span><span style="display: inline-block; width: 10px; height: 10px; background: #FCEE0A; margin-right: 6px"></span>TX</span>
|
||||
</div>
|
||||
</div>
|
||||
<div role="img" aria-label="Bar chart of received and transmitted traffic over the last 12 hours, sample data" style="display: flex; align-items: flex-end; gap: 6px; height: 220px; border-bottom: 1px solid #2A2F3A; background: repeating-linear-gradient(0deg, #1C2029 0px, #1C2029 1px, transparent 1px, transparent 55px)">
|
||||
<sc-for list="{{bars}}" as="b" hint-placeholder-count="12">
|
||||
<div style="flex: 1; display: flex; align-items: flex-end; gap: 2px; height: 100%">
|
||||
<div style="flex: 1; height: {{b.rx}}; background: #02D7F2"></div>
|
||||
<div style="flex: 1; height: {{b.tx}}; background: #FCEE0A"></div>
|
||||
</div>
|
||||
</sc-for>
|
||||
</div>
|
||||
<div style="display: flex; justify-content: space-between; font-family: 'JetBrains Mono', monospace; font-size: 12px; color: #8A93A3"><span>-12H</span><span>-6H</span><span>NOW</span></div>
|
||||
</div>
|
||||
|
||||
<div style="flex: 1 1 320px; min-width: 0; background: #0E1016; border: 1px solid #2A2F3A; padding: 24px; display: flex; flex-direction: column; gap: 16px">
|
||||
<h2 style="margin: 0; font-size: 24px; font-weight: 700; text-transform: uppercase">Nodes</h2>
|
||||
<sc-for list="{{nodes}}" as="n" hint-placeholder-count="4">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; gap: 12px; padding: 10px 0; border-bottom: 1px solid #1C2029">
|
||||
<div style="display: flex; flex-direction: column">
|
||||
<span style="font-weight: 700; text-transform: uppercase">{{n.name}}</span>
|
||||
<span style="font-family: 'JetBrains Mono', monospace; font-size: 12px; color: #8A93A3">{{n.ip}}</span>
|
||||
</div>
|
||||
<span style="font-family: 'JetBrains Mono', monospace; font-size: 12px; letter-spacing: 0.12em; padding: 4px 10px; border: 1px solid {{n.color}}; color: {{n.color}}">{{n.status}}</span>
|
||||
</div>
|
||||
</sc-for>
|
||||
<button type="button" style="min-height: 48px; background: #FCEE0A; color: #050508; border: 0; font-family: 'Rajdhani', sans-serif; font-size: 18px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; cursor: pointer; clip-path: polygon(0 0, calc(100% - 12px) 0, 100% 12px, 100% 100%, 0 100%)">Run diagnostics</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="background: #0E1016; border: 1px solid #2A2F3A; padding: 24px; display: flex; flex-direction: column; gap: 12px">
|
||||
<div style="display: flex; align-items: center; gap: 12px">
|
||||
<h2 style="margin: 0; font-size: 24px; font-weight: 700; text-transform: uppercase">Event log</h2>
|
||||
<div style="flex: 1; height: 2px; background: #FCEE0A; max-width: 120px"></div><div style="width: 8px; height: 2px; background: #FCEE0A"></div><div style="width: 4px; height: 2px; background: #FCEE0A"></div>
|
||||
</div>
|
||||
<div style="overflow-x: auto">
|
||||
<table style="width: 100%; min-width: 640px; border-collapse: collapse; font-family: 'JetBrains Mono', monospace; font-size: 14px">
|
||||
<thead>
|
||||
<tr style="text-align: left; color: #8A93A3; font-size: 12px; letter-spacing: 0.15em">
|
||||
<th style="padding: 8px 12px 8px 0; font-weight: 400; border-bottom: 1px solid #2A2F3A">TIME</th>
|
||||
<th style="padding: 8px 12px; font-weight: 400; border-bottom: 1px solid #2A2F3A">LEVEL</th>
|
||||
<th style="padding: 8px 12px; font-weight: 400; border-bottom: 1px solid #2A2F3A">SOURCE</th>
|
||||
<th style="padding: 8px 12px; font-weight: 400; border-bottom: 1px solid #2A2F3A">MESSAGE</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<sc-for list="{{logs}}" as="l" hint-placeholder-count="5">
|
||||
<tr>
|
||||
<td style="padding: 10px 12px 10px 0; color: #8A93A3; border-bottom: 1px solid #1C2029; white-space: nowrap">{{l.t}}</td>
|
||||
<td style="padding: 10px 12px; color: {{l.color}}; border-bottom: 1px solid #1C2029; font-weight: 600">{{l.level}}</td>
|
||||
<td style="padding: 10px 12px; color: #C3C8D1; border-bottom: 1px solid #1C2029">{{l.src}}</td>
|
||||
<td style="padding: 10px 12px; color: #E6E8EC; border-bottom: 1px solid #1C2029">{{l.msg}}</td>
|
||||
</tr>
|
||||
</sc-for>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</x-dc>
|
||||
<script type="text/x-dc" data-dc-script data-props='{"$preview":{"width":1440,"height":1100}}'>
|
||||
class Component extends DCLogic {
|
||||
renderVals() {
|
||||
const meter = (n, on) => Array.from({ length: 10 }, (_, i) => (i < n ? on : '#1C2029'));
|
||||
const rx = [30, 42, 38, 55, 61, 48, 72, 66, 80, 58, 64, 88];
|
||||
const tx = [12, 18, 15, 22, 30, 20, 35, 28, 41, 26, 33, 46];
|
||||
return {
|
||||
stats: [
|
||||
{ label: 'CPU LOAD', value: '42', unit: '%', color: '#E6E8EC', segs: meter(4, '#02D7F2'), note: 'NOMINAL', noteColor: '#00FF9F' },
|
||||
{ label: 'MEMORY', value: '27.1', unit: 'GB', color: '#E6E8EC', segs: meter(7, '#02D7F2'), note: '68% OF 40 GB', noteColor: '#8A93A3' },
|
||||
{ label: 'DISK /DEV/NVME0', value: '94', unit: '%', color: '#FF3B5C', segs: meter(9, '#FF003C'), note: '▲ ALERT // THRESHOLD 90%', noteColor: '#FF3B5C' },
|
||||
{ label: 'UPTIME', value: '18', unit: 'D', color: '#FCEE0A', segs: meter(10, '#FCEE0A'), note: 'SINCE 2026-10-13', noteColor: '#8A93A3' }
|
||||
],
|
||||
bars: rx.map((r, i) => ({ rx: r + '%', tx: tx[i] + '%' })),
|
||||
nodes: [
|
||||
{ name: 'desktop', ip: '10.0.0.10', status: 'ONLINE', color: '#00FF9F' },
|
||||
{ name: 'nas-01', ip: '10.0.0.20', status: 'WARN', color: '#FF3B5C' },
|
||||
{ name: 'pi-dns', ip: '10.0.0.53', status: 'ONLINE', color: '#00FF9F' },
|
||||
{ name: 'laptop', ip: '10.0.0.31', status: 'IDLE', color: '#8A93A3' }
|
||||
],
|
||||
logs: [
|
||||
{ t: '22:41:07', level: 'INFO', color: '#02D7F2', src: 'pi-dns', msg: 'Blocklist refreshed' },
|
||||
{ t: '22:38:52', level: 'ALERT', color: '#FF3B5C', src: 'nas-01', msg: 'Disk usage crossed 90%' },
|
||||
{ t: '22:30:00', level: 'OK', color: '#00FF9F', src: 'desktop', msg: 'Nightly backup complete' },
|
||||
{ t: '22:12:44', level: 'INFO', color: '#02D7F2', src: 'laptop', msg: 'Entered sleep' },
|
||||
{ t: '21:58:19', level: 'ACTION', color: '#FCEE0A', src: 'desktop', msg: 'Updates ready to install' }
|
||||
]
|
||||
};
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,316 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Night Grid style guide</title>
|
||||
<script src="./support.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<x-dc>
|
||||
<helmet>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Rajdhani:wght@500;600;700&family=JetBrains+Mono:wght@400;600&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
body{margin:0;background:#050508}
|
||||
a{color:#02D7F2}a:hover{color:#FCEE0A}
|
||||
.is-glitching{animation:ng-glitch 360ms steps(1,end)}
|
||||
@keyframes ng-glitch{20%{transform:translateX(-3px) skewX(-12deg);text-shadow:2px 0 #FF003C,-2px 0 #02D7F2;clip-path:inset(10% 0 55% 0)}40%{transform:translateX(3px) skewX(8deg);clip-path:inset(60% 0 8% 0)}60%{transform:translateX(-1px);text-shadow:-2px 0 #FF003C,2px 0 #02D7F2;clip-path:inset(30% 0 35% 0)}80%{transform:none;text-shadow:1px 0 #FF003C,-1px 0 #02D7F2}}
|
||||
.ng-fold>summary{list-style:none;cursor:pointer}
|
||||
.ng-fold>summary::-webkit-details-marker{display:none}
|
||||
.ng-fold>summary:focus-visible{outline:2px solid #FCEE0A;outline-offset:-2px}
|
||||
.ng-fold>summary::before{content:"";position:absolute;top:0;right:0;width:44px;height:44px;background:#FCEE0A;clip-path:polygon(0 0,100% 0,100% 100%,12px 100%,0 calc(100% - 12px))}
|
||||
.ng-fold>summary::after{content:"»";position:absolute;top:0;right:0;width:44px;height:44px;display:grid;place-items:center;color:#050508;font:700 24px/1 'JetBrains Mono',monospace;transform:rotate(90deg);transition:transform 120ms steps(2)}
|
||||
.ng-fold[open]>summary::after{transform:rotate(-90deg)}
|
||||
@media (prefers-reduced-motion:reduce){.is-glitching{animation:none}.ng-fold>summary::after{transition:none}}
|
||||
</style>
|
||||
</helmet>
|
||||
<div style="position: relative; min-height: 100vh; background: #050508; color: #E6E8EC; font-family: 'Rajdhani', sans-serif; font-size: 18px; line-height: 1.5; overflow: hidden">
|
||||
<sc-if value="{{scanlines}}" hint-placeholder-val="{{ true }}">
|
||||
<div aria-hidden="true" style="position: absolute; inset: 0; pointer-events: none; background: repeating-linear-gradient(0deg, rgba(255,255,255,0.025) 0px, rgba(255,255,255,0.025) 1px, transparent 1px, transparent 3px); z-index: 2"></div>
|
||||
</sc-if>
|
||||
<div style="max-width: 1200px; margin: 0 auto; padding: 64px 24px 96px; display: flex; flex-direction: column; gap: 96px; position: relative; z-index: 1">
|
||||
|
||||
<header style="display: flex; flex-direction: column; gap: 20px; border-bottom: 1px solid #2A2F3A; padding-bottom: 48px">
|
||||
<div style="display: flex; gap: 16px; align-items: center; flex-wrap: wrap; font-family: 'JetBrains Mono', monospace; font-size: 13px; letter-spacing: 0.12em; color: #8A93A3">
|
||||
<span style="background: #FCEE0A; color: #050508; padding: 4px 10px; font-weight: 600">SYS.STYLE</span>
|
||||
<span>REV 1.0 // 2026-10-31</span>
|
||||
<span style="color: #02D7F2">STATUS: ONLINE</span>
|
||||
</div>
|
||||
<h1 class="{{g0}}" style="margin: 0; font-size: clamp(56px, 9vw, 120px); line-height: 0.9; font-weight: 700; letter-spacing: -0.01em; text-transform: uppercase; color: #FCEE0A">Night Grid</h1>
|
||||
<p style="margin: 0; max-width: 680px; font-size: 22px; color: #C3C8D1">A visual language for dashboards and tools: dark streets, neon signal, hard edges. Inspired by the HUD look of near-future noir games, built to stay readable at 3 a.m.</p>
|
||||
</header>
|
||||
|
||||
<section style="display: flex; flex-direction: column; gap: 32px">
|
||||
<h2 style="margin: 0; font-size: 14px; font-family: 'JetBrains Mono', monospace; letter-spacing: 0.2em; color: #FF003C; font-weight: 600">01 // PRINCIPLES</h2>
|
||||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 16px">
|
||||
<div style="background: #0E1016; border: 1px solid #2A2F3A; padding: 24px; clip-path: polygon(0 0, calc(100% - 16px) 0, 100% 16px, 100% 100%, 0 100%)">
|
||||
<div class="{{g1}}" style="font-size: 26px; font-weight: 700; text-transform: uppercase; color: #FCEE0A">Signal over noise</div>
|
||||
<p style="margin: 8px 0 0; color: #C3C8D1">The city is dark so the data can glow. 70% of any screen is near-black void.</p>
|
||||
</div>
|
||||
<div style="background: #0E1016; border: 1px solid #2A2F3A; padding: 24px; clip-path: polygon(0 0, calc(100% - 16px) 0, 100% 16px, 100% 100%, 0 100%)">
|
||||
<div class="{{g2}}" style="font-size: 26px; font-weight: 700; text-transform: uppercase; color: #FCEE0A">Hard edges</div>
|
||||
<p style="margin: 8px 0 0; color: #C3C8D1">No rounded corners. Panels get one 45° clipped corner and 1px hairlines.</p>
|
||||
</div>
|
||||
<div style="background: #0E1016; border: 1px solid #2A2F3A; padding: 24px; clip-path: polygon(0 0, calc(100% - 16px) 0, 100% 16px, 100% 100%, 0 100%)">
|
||||
<div class="{{g3}}" style="font-size: 26px; font-weight: 700; text-transform: uppercase; color: #FCEE0A">Color is meaning</div>
|
||||
<p style="margin: 8px 0 0; color: #C3C8D1">Yellow = act or focus. Cyan = info and live data. Red = danger. Never decorative.</p>
|
||||
</div>
|
||||
<div style="background: #0E1016; border: 1px solid #2A2F3A; padding: 24px; clip-path: polygon(0 0, calc(100% - 16px) 0, 100% 16px, 100% 100%, 0 100%)">
|
||||
<div class="{{g4}}" style="font-size: 26px; font-weight: 700; text-transform: uppercase; color: #FCEE0A">Diegetic data</div>
|
||||
<p style="margin: 8px 0 0; color: #C3C8D1">Labels read like machine output: uppercase mono, IDs, timestamps, // separators.</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section style="display: flex; flex-direction: column; gap: 32px">
|
||||
<h2 style="margin: 0; font-size: 14px; font-family: 'JetBrains Mono', monospace; letter-spacing: 0.2em; color: #FF003C; font-weight: 600">02 // COLOR</h2>
|
||||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 16px">
|
||||
<sc-for list="{{colors}}" as="c" hint-placeholder-count="9">
|
||||
<div style="display: flex; flex-direction: column; border: 1px solid #2A2F3A; background: #0E1016">
|
||||
<div style="height: 96px; background: {{c.hex}}; border-bottom: 1px solid #2A2F3A"></div>
|
||||
<div style="padding: 14px 16px; display: flex; flex-direction: column; gap: 2px">
|
||||
<div style="font-size: 20px; font-weight: 700; text-transform: uppercase">{{c.name}}</div>
|
||||
<div style="font-family: 'JetBrains Mono', monospace; font-size: 13px; color: #02D7F2">{{c.hex}} · {{c.token}}</div>
|
||||
<div style="font-size: 15px; color: #8A93A3">{{c.role}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</sc-for>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; gap: 10px">
|
||||
<div style="font-family: 'JetBrains Mono', monospace; font-size: 13px; letter-spacing: 0.12em; color: #8A93A3">SCREEN BUDGET</div>
|
||||
<div style="display: flex; height: 28px; border: 1px solid #2A2F3A">
|
||||
<div style="flex: 70; background: #050508"></div>
|
||||
<div style="flex: 15; background: #0E1016; border-left: 1px solid #2A2F3A"></div>
|
||||
<div style="flex: 8; background: #FCEE0A"></div>
|
||||
<div style="flex: 4; background: #02D7F2"></div>
|
||||
<div style="flex: 3; background: #FF003C"></div>
|
||||
</div>
|
||||
<div style="display: flex; flex-wrap: wrap; gap: 8px 24px; font-family: 'JetBrains Mono', monospace; font-size: 13px; color: #C3C8D1">
|
||||
<span>VOID 70%</span><span>PANEL 15%</span><span style="color: #FCEE0A">YELLOW 8%</span><span style="color: #02D7F2">CYAN 4%</span><span style="color: #FF3B5C">RED 3%</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section style="display: flex; flex-direction: column; gap: 32px">
|
||||
<h2 style="margin: 0; font-size: 14px; font-family: 'JetBrains Mono', monospace; letter-spacing: 0.2em; color: #FF003C; font-weight: 600">03 // TYPE</h2>
|
||||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 24px">
|
||||
<div style="border: 1px solid #2A2F3A; padding: 28px; display: flex; flex-direction: column; gap: 12px">
|
||||
<div style="font-family: 'JetBrains Mono', monospace; font-size: 13px; color: #8A93A3; letter-spacing: 0.12em">DISPLAY + UI — RAJDHANI 500/600/700</div>
|
||||
<div style="font-size: 72px; font-weight: 700; line-height: 1; text-transform: uppercase; color: #FCEE0A">Wake up</div>
|
||||
<div style="font-size: 32px; font-weight: 600; text-transform: uppercase">Section heading 32</div>
|
||||
<div style="font-size: 18px; font-weight: 500; color: #C3C8D1">Body 18/1.5. Condensed, squared shapes; uppercase for headings and buttons, sentence case for anything longer than a line.</div>
|
||||
</div>
|
||||
<div style="border: 1px solid #2A2F3A; padding: 28px; display: flex; flex-direction: column; gap: 12px">
|
||||
<div style="font-family: 'JetBrains Mono', monospace; font-size: 13px; color: #8A93A3; letter-spacing: 0.12em">DATA + LABELS — JETBRAINS MONO 400/600</div>
|
||||
<div style="font-family: 'JetBrains Mono', monospace; font-size: 56px; font-weight: 600; line-height: 1; color: #02D7F2">98.6<span style="font-size: 24px; color: #8A93A3">%</span></div>
|
||||
<div style="font-family: 'JetBrains Mono', monospace; font-size: 13px; letter-spacing: 0.15em; color: #8A93A3">LABEL 13 · +0.15EM · UPPERCASE</div>
|
||||
<div style="font-family: 'JetBrains Mono', monospace; font-size: 14px; color: #C3C8D1">[22:41:07] node-03 > sync complete</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="display: flex; flex-wrap: wrap; gap: 8px 32px; font-family: 'JetBrains Mono', monospace; font-size: 13px; color: #8A93A3">
|
||||
<span>SCALE 13 · 15 · 18 · 24 · 32 · 48 · 72 · 120</span><span>TABULAR NUMBERS FOR ALL METRICS</span>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section style="display: flex; flex-direction: column; gap: 32px">
|
||||
<h2 style="margin: 0; font-size: 14px; font-family: 'JetBrains Mono', monospace; letter-spacing: 0.2em; color: #FF003C; font-weight: 600">04 // SHAPE + LINE</h2>
|
||||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 24px">
|
||||
<div style="display: flex; flex-direction: column; gap: 12px">
|
||||
<div style="height: 140px; background: #0E1016; border: 1px solid #2A2F3A; clip-path: polygon(0 0, calc(100% - 20px) 0, 100% 20px, 100% 100%, 0 100%)"></div>
|
||||
<div style="font-weight: 700; text-transform: uppercase">Clipped panel</div>
|
||||
<div style="font-size: 15px; color: #8A93A3">Top-right cut, 16px (cards) or 24px (sections). One cut per shape.</div>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; gap: 12px">
|
||||
<div style="height: 140px; position: relative; background: #0E1016">
|
||||
<div style="position: absolute; top: 0; left: 0; width: 18px; height: 18px; border-top: 2px solid #FCEE0A; border-left: 2px solid #FCEE0A"></div>
|
||||
<div style="position: absolute; top: 0; right: 0; width: 18px; height: 18px; border-top: 2px solid #FCEE0A; border-right: 2px solid #FCEE0A"></div>
|
||||
<div style="position: absolute; bottom: 0; left: 0; width: 18px; height: 18px; border-bottom: 2px solid #FCEE0A; border-left: 2px solid #FCEE0A"></div>
|
||||
<div style="position: absolute; bottom: 0; right: 0; width: 18px; height: 18px; border-bottom: 2px solid #FCEE0A; border-right: 2px solid #FCEE0A"></div>
|
||||
</div>
|
||||
<div style="font-weight: 700; text-transform: uppercase">Target brackets</div>
|
||||
<div style="font-size: 15px; color: #8A93A3">Marks focus or selection. Yellow only, 2px.</div>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; gap: 12px">
|
||||
<div style="height: 140px; background: #0E1016; display: flex; flex-direction: column; justify-content: center; gap: 18px; padding: 0 20px">
|
||||
<div style="height: 1px; background: #2A2F3A"></div>
|
||||
<div style="height: 1px; background: #02D7F2"></div>
|
||||
<div style="display: flex; gap: 4px"><div style="flex: 1; height: 2px; background: #FCEE0A"></div><div style="width: 8px; height: 2px; background: #FCEE0A"></div><div style="width: 4px; height: 2px; background: #FCEE0A"></div></div>
|
||||
</div>
|
||||
<div style="font-weight: 700; text-transform: uppercase">Hairlines</div>
|
||||
<div style="font-size: 15px; color: #8A93A3">1px #2A2F3A dividers; cyan for live; broken yellow dash as a header tail.</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 24px">
|
||||
<div style="display: flex; flex-direction: column; gap: 12px">
|
||||
<div style="height: 140px; background: #0E1016; display: flex; flex-direction: column; justify-content: center; padding: 0 20px">
|
||||
<div style="position: relative; padding-bottom: 16px; font-size: 24px; font-weight: 700; text-transform: uppercase">Network
|
||||
<div aria-hidden="true" style="position: absolute; left: 0; bottom: 0; width: 100%; height: 8px; background: #FCEE0A; clip-path: polygon(0 0, 72px 0, 78px 5px, 100% 5px, 100% 6px, 76px 6px, 70px 8px, 0 8px)"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="font-weight: 700; text-transform: uppercase">Stepped rule <span style="font-family: 'JetBrains Mono', monospace; font-size: 13px; font-weight: 400; color: #02D7F2">.ng-rule</span></div>
|
||||
<div style="font-size: 15px; color: #8A93A3">Under headings: a thick bar that steps down at 45° into a hairline.</div>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; gap: 12px">
|
||||
<div style="height: 140px; position: relative; background: #0E1016">
|
||||
<div aria-hidden="true" style="position: absolute; left: 0; right: 0; bottom: 0; height: 14px; background: #FCEE0A; clip-path: polygon(0 100%, 0 0, 22% 0, calc(22% + 14px) 100%, 52% 100%, calc(52% + 7px) 50%, 70% 50%, calc(70% + 7px) 100%, 90% 100%, calc(90% + 14px) 0, 100% 0, 100% 100%)"></div>
|
||||
</div>
|
||||
<div style="font-weight: 700; text-transform: uppercase">Edge band <span style="font-family: 'JetBrains Mono', monospace; font-size: 13px; font-weight: 400; color: #02D7F2">.ng-edge</span></div>
|
||||
<div style="font-size: 15px; color: #8A93A3">Stepped band along a section's bottom. Line grey by default, yellow with --hot.</div>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; gap: 12px">
|
||||
<div style="height: 140px; background: #0E1016; border: 1px solid #2A2F3A; clip-path: polygon(0 16px, 16px 0, 55% 0, calc(55% + 12px) 12px, 100% 12px, 100% calc(100% - 12px), calc(100% - 12px) 100%, 0 100%)"></div>
|
||||
<div style="font-weight: 700; text-transform: uppercase">Notched panel <span style="font-family: 'JetBrains Mono', monospace; font-size: 13px; font-weight: 400; color: #02D7F2">.ng-panel--notched</span></div>
|
||||
<div style="font-size: 15px; color: #8A93A3">Several cuts for a hero panel. One or two diagonal pieces per screen.</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section style="display: flex; flex-direction: column; gap: 32px">
|
||||
<h2 style="margin: 0; font-size: 14px; font-family: 'JetBrains Mono', monospace; letter-spacing: 0.2em; color: #FF003C; font-weight: 600">05 // COMPONENTS</h2>
|
||||
<div style="display: flex; flex-wrap: wrap; gap: 16px; align-items: center">
|
||||
<button type="button" style="min-height: 48px; padding: 0 28px; background: #FCEE0A; color: #050508; border: 0; font-family: 'Rajdhani', sans-serif; font-size: 18px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; cursor: pointer; clip-path: polygon(0 0, calc(100% - 12px) 0, 100% 12px, 100% 100%, 0 100%)">Execute</button>
|
||||
<button type="button" style="min-height: 48px; padding: 0 28px; background: transparent; color: #02D7F2; border: 1px solid #02D7F2; font-family: 'Rajdhani', sans-serif; font-size: 18px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; cursor: pointer">Scan</button>
|
||||
<button type="button" style="min-height: 48px; padding: 0 28px; background: transparent; color: #FF3B5C; border: 1px solid #FF003C; font-family: 'Rajdhani', sans-serif; font-size: 18px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; cursor: pointer">Abort</button>
|
||||
<button type="button" style="min-height: 48px; padding: 0 20px; background: transparent; color: #8A93A3; border: 1px solid #2A2F3A; font-family: 'Rajdhani', sans-serif; font-size: 18px; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; cursor: pointer">Cancel</button>
|
||||
</div>
|
||||
<div style="display: flex; flex-wrap: wrap; gap: 10px; font-family: 'JetBrains Mono', monospace; font-size: 12px; letter-spacing: 0.12em">
|
||||
<span style="padding: 4px 10px; background: #FCEE0A; color: #050508; font-weight: 600">PRIORITY</span>
|
||||
<span style="padding: 4px 10px; border: 1px solid #02D7F2; color: #02D7F2">LIVE</span>
|
||||
<span style="padding: 4px 10px; border: 1px solid #00FF9F; color: #00FF9F">NOMINAL</span>
|
||||
<span style="padding: 4px 10px; background: #FF003C; color: #FFFFFF; font-weight: 600">BREACH</span>
|
||||
<span style="padding: 4px 10px; border: 1px solid #2A2F3A; color: #8A93A3">IDLE</span>
|
||||
</div>
|
||||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 16px">
|
||||
<div style="background: #0E1016; border: 1px solid #2A2F3A; padding: 20px 24px; display: flex; flex-direction: column; gap: 8px; clip-path: polygon(0 0, calc(100% - 16px) 0, 100% 16px, 100% 100%, 0 100%)">
|
||||
<div style="font-family: 'JetBrains Mono', monospace; font-size: 12px; letter-spacing: 0.15em; color: #8A93A3">STAT TILE // CPU LOAD</div>
|
||||
<div style="font-family: 'JetBrains Mono', monospace; font-size: 44px; font-weight: 600; color: #E6E8EC; line-height: 1.1">42<span style="font-size: 20px; color: #8A93A3">%</span></div>
|
||||
<div style="display: flex; gap: 3px">
|
||||
<div style="flex: 1; height: 6px; background: #02D7F2"></div><div style="flex: 1; height: 6px; background: #02D7F2"></div><div style="flex: 1; height: 6px; background: #02D7F2"></div><div style="flex: 1; height: 6px; background: #02D7F2"></div><div style="flex: 1; height: 6px; background: #1C2029"></div><div style="flex: 1; height: 6px; background: #1C2029"></div><div style="flex: 1; height: 6px; background: #1C2029"></div><div style="flex: 1; height: 6px; background: #1C2029"></div><div style="flex: 1; height: 6px; background: #1C2029"></div><div style="flex: 1; height: 6px; background: #1C2029"></div>
|
||||
</div>
|
||||
<div style="font-family: 'JetBrains Mono', monospace; font-size: 12px; color: #00FF9F">▲ SEGMENTED METER · 10 STEPS</div>
|
||||
</div>
|
||||
<div style="background: rgba(255,0,60,0.08); border: 1px solid #FF003C; padding: 20px 24px; display: flex; flex-direction: column; gap: 6px">
|
||||
<div style="display: flex; align-items: center; gap: 10px; font-family: 'JetBrains Mono', monospace; font-size: 12px; letter-spacing: 0.15em; color: #FF3B5C; font-weight: 600">
|
||||
<svg aria-hidden="true" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square"><path d="M12 3 2 21h20L12 3z"></path><path d="M12 10v5"></path><path d="M12 18v.5"></path></svg>
|
||||
ALERT // ICE BREACH
|
||||
</div>
|
||||
<div style="font-size: 22px; font-weight: 700; text-transform: uppercase">Disk /dev/nvme0 at 94%</div>
|
||||
<div style="font-size: 15px; color: #C3C8D1">Alerts state the thing, the number and the time. Red border, 8% red fill.</div>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; gap: 8px">
|
||||
<label for="ng-input" style="font-family: 'JetBrains Mono', monospace; font-size: 12px; letter-spacing: 0.15em; color: #8A93A3">INPUT // HOST</label>
|
||||
<input id="ng-input" type="text" value="night-city.local" style="min-height: 48px; padding: 0 16px; background: #050508; color: #E6E8EC; border: 1px solid #2A2F3A; border-bottom: 2px solid #FCEE0A; font-family: 'JetBrains Mono', monospace; font-size: 16px; outline: none">
|
||||
<div style="font-size: 15px; color: #8A93A3">Focus = yellow underline. Errors swap it to red with a mono message.</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 16px; align-items: start">
|
||||
<details class="ng-fold" open="" style="position: relative; background: #0E1016; border: 1px solid #2A2F3A">
|
||||
<summary style="min-height: 44px; padding: 10px 64px 10px 24px; display: flex; align-items: center; font-size: 24px; font-weight: 700; line-height: 1.1; text-transform: uppercase">Fold panel · open</summary>
|
||||
<p style="margin: 0; padding: 0 24px 20px; color: #C3C8D1">Corner chip » points up: click to fold. Native <details>, works with the keyboard, no script.</p>
|
||||
</details>
|
||||
<details class="ng-fold" style="position: relative; background: #0E1016; border: 1px solid #2A2F3A">
|
||||
<summary style="min-height: 44px; padding: 10px 64px 10px 24px; display: flex; align-items: center; font-size: 24px; font-weight: 700; line-height: 1.1; text-transform: uppercase">Fold panel · folded</summary>
|
||||
<p style="margin: 0; padding: 0 24px 20px; color: #C3C8D1">Folded, the chip points down: click to unfold.</p>
|
||||
</details>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section style="display: flex; flex-direction: column; gap: 32px">
|
||||
<h2 style="margin: 0; font-size: 14px; font-family: 'JetBrains Mono', monospace; letter-spacing: 0.2em; color: #FF003C; font-weight: 600">06 // CHARTS + MOTION</h2>
|
||||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 24px">
|
||||
<ul style="margin: 0; padding: 0 0 0 20px; display: flex; flex-direction: column; gap: 10px; color: #C3C8D1">
|
||||
<li>Series 1 cyan, series 2 yellow, threshold/alert red. Max three series per chart.</li>
|
||||
<li>Gridlines #1C2029, axis labels mono 12px #8A93A3. No chart backgrounds.</li>
|
||||
<li>Bars squared, 2px gaps. Lines 2px, no smoothing: the data is jagged, show it.</li>
|
||||
<li>Glow only on the single most important value: <span style="font-family: 'JetBrains Mono', monospace">text-shadow 0 0 12px</span> at 60%.</li>
|
||||
</ul>
|
||||
<ul style="margin: 0; padding: 0 0 0 20px; display: flex; flex-direction: column; gap: 10px; color: #C3C8D1">
|
||||
<li>Motion is fast and stepped: 120ms, <span style="font-family: 'JetBrains Mono', monospace">steps(4)</span> or linear. No bounces.</li>
|
||||
<li>Glitch (skew, RGB split, slices, 360ms) on state change, plus one random marked heading every 6–14s. Watch this page's title and principles.</li>
|
||||
<li>Numbers tick up when they change; panels wipe in left to right.</li>
|
||||
<li>Scanlines at 2.5% white, toggleable, off under <span style="font-family: 'JetBrains Mono', monospace">prefers-reduced-motion</span>.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section style="display: flex; flex-direction: column; gap: 32px">
|
||||
<h2 style="margin: 0; font-size: 14px; font-family: 'JetBrains Mono', monospace; letter-spacing: 0.2em; color: #FF003C; font-weight: 600">07 // TOKENS</h2>
|
||||
<pre style="margin: 0; padding: 24px; background: #0E1016; border: 1px solid #2A2F3A; overflow-x: auto; font-family: 'JetBrains Mono', monospace; font-size: 14px; line-height: 1.7; color: #C3C8D1">:root {
|
||||
--ng-void: #050508; /* page ground */
|
||||
--ng-panel: #0E1016; /* cards, panels */
|
||||
--ng-raise: #1C2029; /* tracks, grid, hover */
|
||||
--ng-line: #2A2F3A; /* 1px borders */
|
||||
--ng-text: #E6E8EC;
|
||||
--ng-dim: #8A93A3; /* labels, 6.5:1 on void */
|
||||
--ng-yellow: #FCEE0A; /* action, focus */
|
||||
--ng-cyan: #02D7F2; /* info, live data */
|
||||
--ng-red: #FF003C; /* danger fill/border */
|
||||
--ng-red-txt: #FF3B5C; /* danger text */
|
||||
--ng-green: #00FF9F; /* ok */
|
||||
--ng-font-ui: 'Rajdhani', sans-serif;
|
||||
--ng-font-data: 'JetBrains Mono', monospace;
|
||||
--ng-cut: 16px; /* clip-path corner */
|
||||
}</pre>
|
||||
</section>
|
||||
|
||||
<section style="display: flex; flex-direction: column; gap: 32px">
|
||||
<h2 style="margin: 0; font-size: 14px; font-family: 'JetBrains Mono', monospace; letter-spacing: 0.2em; color: #FF003C; font-weight: 600">08 // DO + DON'T</h2>
|
||||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 24px">
|
||||
<div style="border-top: 2px solid #00FF9F; padding-top: 16px; display: flex; flex-direction: column; gap: 8px; color: #C3C8D1">
|
||||
<div style="font-family: 'JetBrains Mono', monospace; font-size: 13px; letter-spacing: 0.15em; color: #00FF9F">DO</div>
|
||||
<div>One yellow call to action per view.</div>
|
||||
<div>Pair every color state with a label or icon.</div>
|
||||
<div>Keep body text sentence case and ≥16px.</div>
|
||||
<div>Let empty void separate groups before adding lines.</div>
|
||||
</div>
|
||||
<div style="border-top: 2px solid #FF003C; padding-top: 16px; display: flex; flex-direction: column; gap: 8px; color: #C3C8D1">
|
||||
<div style="font-family: 'JetBrains Mono', monospace; font-size: 13px; letter-spacing: 0.15em; color: #FF3B5C">DON'T</div>
|
||||
<div>Use rounded corners, soft shadows or gradients.</div>
|
||||
<div>Put yellow text on cyan or red (it vibrates).</div>
|
||||
<div>Glow everything: if all of it shines, nothing does.</div>
|
||||
<div>Copy game logos, fonts or UI assets: inspired by, never lifted.</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</x-dc>
|
||||
<script type="text/x-dc" data-dc-script data-props='{"scanlines":{"editor":"boolean","default":true},"$preview":{"width":1440,"height":3600}}'>
|
||||
class Component extends DCLogic {
|
||||
componentDidMount() {
|
||||
if (matchMedia('(prefers-reduced-motion: reduce)').matches) return;
|
||||
const next = () => { this.timer = setTimeout(tick, 6000 + Math.random() * 8000); };
|
||||
const tick = () => {
|
||||
this.setState({ glitch: Math.floor(Math.random() * 5) });
|
||||
this.clear = setTimeout(() => this.setState({ glitch: -1 }), 400);
|
||||
next();
|
||||
};
|
||||
next();
|
||||
}
|
||||
componentWillUnmount() {
|
||||
clearTimeout(this.timer);
|
||||
clearTimeout(this.clear);
|
||||
}
|
||||
renderVals() {
|
||||
const g = (i) => (this.state && this.state.glitch === i ? 'is-glitching' : '');
|
||||
return {
|
||||
g0: g(0), g1: g(1), g2: g(2), g3: g(3), g4: g(4),
|
||||
scanlines: this.props.scanlines ?? true,
|
||||
colors: [
|
||||
{ name: 'Void', hex: '#050508', token: '--ng-void', role: 'Page ground. Almost black, slightly blue.' },
|
||||
{ name: 'Panel', hex: '#0E1016', token: '--ng-panel', role: 'Cards and panels.' },
|
||||
{ name: 'Raise', hex: '#1C2029', token: '--ng-raise', role: 'Meter tracks, gridlines, hover.' },
|
||||
{ name: 'Line', hex: '#2A2F3A', token: '--ng-line', role: '1px borders and dividers.' },
|
||||
{ name: 'Yellow', hex: '#FCEE0A', token: '--ng-yellow', role: 'Action, focus, headline. Primary.' },
|
||||
{ name: 'Cyan', hex: '#02D7F2', token: '--ng-cyan', role: 'Info, links, live data series.' },
|
||||
{ name: 'Red', hex: '#FF003C', token: '--ng-red', role: 'Danger, alerts, thresholds.' },
|
||||
{ name: 'Green', hex: '#00FF9F', token: '--ng-green', role: 'Nominal, success. Use sparingly.' },
|
||||
{ name: 'Text', hex: '#E6E8EC', token: '--ng-text', role: 'Primary text. Never pure white.' }
|
||||
]
|
||||
};
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1 @@
|
||||
{"v":3,"createdOnFiles":{"v":1,"at":"2026-10-31T12:00:00Z"},"title":"Night Grid Style Guide","launch":{"view":"canvas"},"pages":[],"boards":{"Main.dc.html":{"x":0,"y":0,"w":1440,"h":3600,"title":"Style guide","expand":"fill","is_interactive":true},"Dashboard.dc.html":{"x":1520,"y":0,"w":1440,"h":1100,"title":"Sample dashboard","expand":"fill"}},"order":["Main.dc.html","Dashboard.dc.html"],"notes":{},"designSystems":[]}
|
||||
Reference in new issue
Block a user