Files
CyberpunkStyleGuide/canvas/Main.dc.html
T
bgrollemanandClaude Opus 5.5 94832d861b 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>
2026-11-01 09:21:37 +01:00

317 lines
25 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!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&amp;family=JetBrains+Mono:wght@400;600&amp;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 &gt; 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 &lt;details&gt;, 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>