/* Night Grid — dark neon HUD style for dashboards.
Guide: https://claude.ai/artifact/AT2mCxMkeLFzkife1rAuLk
Fonts:
Random glitch: */
: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-soft: #C3C8D1; /* secondary body text */
--ng-dim: #8A93A3; /* labels */
--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;
--ng-speed: 120ms;
}
body {
margin: 0;
background: var(--ng-void);
color: var(--ng-text);
font: 500 18px/1.5 var(--ng-font-ui);
}
a { color: var(--ng-cyan); }
a:hover { color: var(--ng-yellow); }
h1, h2, h3 { font-weight: 700; text-transform: uppercase; line-height: 1.1; }
h1 { color: var(--ng-yellow); }
/* Mono machine-style label: "CPU LOAD", "01 // COLOR" */
.ng-label {
font: 600 12px/1.4 var(--ng-font-data);
letter-spacing: 0.15em;
text-transform: uppercase;
color: var(--ng-dim);
}
.ng-data { font-family: var(--ng-font-data); font-variant-numeric: tabular-nums; }
/* Panel with one clipped top-right corner */
.ng-panel {
background: var(--ng-panel);
border: 1px solid var(--ng-line);
padding: 20px 24px;
clip-path: polygon(0 0, calc(100% - var(--ng-cut)) 0, 100% var(--ng-cut), 100% 100%, 0 100%);
}
/* Buttons: one primary (yellow) per view */
.ng-btn {
min-height: 48px;
padding: 0 28px;
border: 1px solid var(--ng-line);
background: transparent;
color: var(--ng-dim);
font: 700 18px var(--ng-font-ui);
letter-spacing: 0.08em;
text-transform: uppercase;
cursor: pointer;
transition: filter var(--ng-speed) linear;
}
.ng-btn:hover { filter: brightness(1.2); }
.ng-btn:focus-visible { outline: 2px solid var(--ng-yellow); outline-offset: 3px; }
.ng-btn--primary {
background: var(--ng-yellow);
color: var(--ng-void);
border: 0;
clip-path: polygon(0 0, calc(100% - 12px) 0, 100% 12px, 100% 100%, 0 100%);
}
.ng-btn--info { color: var(--ng-cyan); border-color: var(--ng-cyan); }
.ng-btn--danger { color: var(--ng-red-txt); border-color: var(--ng-red); }
/* Tags */
.ng-tag {
display: inline-block;
padding: 4px 10px;
border: 1px solid var(--ng-line);
color: var(--ng-dim);
font: 600 12px var(--ng-font-data);
letter-spacing: 0.12em;
text-transform: uppercase;
}
.ng-tag--priority { background: var(--ng-yellow); color: var(--ng-void); border-color: var(--ng-yellow); }
.ng-tag--live { color: var(--ng-cyan); border-color: var(--ng-cyan); }
.ng-tag--ok { color: var(--ng-green); border-color: var(--ng-green); }
.ng-tag--breach { background: var(--ng-red); color: #fff; border-color: var(--ng-red); }
/* Segmented meter:
…10×
*/
.ng-meter { display: flex; gap: 3px; }
.ng-meter > i { flex: 1; height: 6px; background: var(--ng-raise); }
.ng-meter > i.on { background: var(--ng-cyan); }
.ng-meter--danger > i.on { background: var(--ng-red); }
/* Alert banner */
.ng-alert {
background: rgb(255 0 60 / 0.08);
border: 1px solid var(--ng-red);
padding: 20px 24px;
}
.ng-alert .ng-label { color: var(--ng-red-txt); }
/* Input: yellow underline on focus */
.ng-input {
min-height: 48px;
padding: 0 16px;
background: var(--ng-void);
color: var(--ng-text);
border: 1px solid var(--ng-line);
font: 16px var(--ng-font-data);
}
.ng-input:focus { outline: none; border-bottom: 2px solid var(--ng-yellow); }
.ng-input[aria-invalid="true"] { border-bottom: 2px solid var(--ng-red); }
/* Glow: the single most important value only */
.ng-glow { text-shadow: 0 0 12px rgb(252 238 10 / 0.6); }
/* --- Diagonal structure --- */
/* Multi-notch panel: cut top-left, step in the top edge, cut bottom-right */
.ng-panel--notched {
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%);
padding-top: 28px;
}
/* Heading underline: thick bar that steps down diagonally into a hairline */
.ng-rule { position: relative; padding-bottom: 16px; }
.ng-rule::after {
content: "";
position: absolute;
left: 0;
bottom: 0;
width: 100%;
height: 8px;
background: var(--ng-rule, var(--ng-yellow));
clip-path: polygon(0 0, 72px 0, 78px 5px, 100% 5px, 100% 6px, 76px 6px, 70px 8px, 0 8px);
}
/* Stepped edge band along the bottom of a section */
.ng-edge { position: relative; padding-bottom: 40px; }
.ng-edge::after {
content: "";
position: absolute;
left: 0;
right: 0;
bottom: 0;
height: 14px;
background: var(--ng-edge, var(--ng-line));
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%);
}
.ng-edge--hot { --ng-edge: var(--ng-yellow); }
/* --- Glitch --- */
/* .ng-glitch marks candidates; night-grid.js adds .is-glitching to one at random every 6–14s */
.ng-glitch.is-glitching { animation: ng-glitch 360ms steps(1, end); }
@keyframes ng-glitch {
20% { transform: translateX(-3px) skewX(-12deg); text-shadow: 2px 0 var(--ng-red), -2px 0 var(--ng-cyan); 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 var(--ng-red), 2px 0 var(--ng-cyan); clip-path: inset(30% 0 35% 0); }
80% { transform: none; text-shadow: 1px 0 var(--ng-red), -1px 0 var(--ng-cyan); }
}
/* --- Fold / unfold ---
Title
…content…
Corner chip shows » pointing down (unfold) when closed, up (fold) when open. */
.ng-fold {
position: relative;
background: var(--ng-panel);
border: 1px solid var(--ng-line);
}
.ng-fold > summary {
list-style: none;
cursor: pointer;
min-height: 44px;
padding: 10px 64px 10px 24px;
display: flex;
align-items: center;
font: 700 24px/1.1 var(--ng-font-ui);
text-transform: uppercase;
}
.ng-fold > summary::-webkit-details-marker { display: none; }
.ng-fold > summary:focus-visible { outline: 2px solid var(--ng-yellow); outline-offset: -2px; }
.ng-fold > summary::before {
content: "";
position: absolute;
top: 0;
right: 0;
width: 44px;
height: 44px;
background: var(--ng-yellow);
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: var(--ng-void);
font: 700 24px/1 var(--ng-font-data);
transform: rotate(90deg);
transition: transform var(--ng-speed) steps(2);
}
.ng-fold[open] > summary::after { transform: rotate(-90deg); }
.ng-fold > :not(summary) { margin: 0; padding: 0 24px 20px; }
/* Scanline overlay: add class to */
.ng-scanlines::after {
content: "";
position: fixed;
inset: 0;
pointer-events: none;
background: repeating-linear-gradient(0deg, rgb(255 255 255 / 0.025) 0 1px, transparent 1px 3px);
}
@media (prefers-reduced-motion: reduce) {
.ng-scanlines::after { display: none; }
* { transition: none !important; animation: none !important; }
}