AMBER CONSOLE

SYSTEM GUIDE

REV 1.0 · MONOCHROME PLASMA UI · INDUSTRIAL CONTROL PANEL GENRE

A design system for interfaces that look like they run machinery. Everything here is derived from the physical limits of a late-80s amber plasma display: one lit color, a character grid, 2-pixel strokes, and no time for decoration. The constraints are the design.

01

PHILOSOPHY

Six laws, each inherited from a hardware limitation rather than a style preference. Break one and the illusion collapses.

1

ONE GAS, MANY INTENSITIES

There is no phosphor in here. A monochrome plasma panel is a grid of gas gaps holding a neon–argon mixture, and the amber is neon emitting directly when the gap strikes — around 590nm, the colour neon simply is. Phosphors arrive only with colour plasma, where xenon UV excites red, green and blue stripes. So the panel can light one colour and vary how hard. Hierarchy comes from brightness, inverse video, and blink — never hue. There is no red, no green, no success color.

2

INVERSE VIDEO IS IMPORTANCE

A solid amber block with dark text is the machine speaking: live status, section headers, the active mode. Ration it — two or three per screen, no more.

3

EVERYTHING IS A BOX

Regions are drawn with rules. Controls are large bordered rectangles with the label parked top-left and empty space below — targets for a gloved finger. Borders do the layout work; elevation and shadow do not exist.

4

THE CHARACTER GRID RULES

Text sits on terminal rows. Labels are KEY:VALUE pairs, columns align, leading is tight at 1.15. Space is measured in 4px half-cells, never eyeballed.

5

CASING IS SEMANTIC

System and machine text is ALL CAPS. Operator-facing soft keys — the labels a human presses — are Title Case. That split is information, so preserve it.

6

ORNAMENT IS TYPOGRAPHIC

Emphasis is built from repeated glyphs, dashes, and colons: ✳✳ REMOTE MODE ✳✳. No icon libraries, no illustration, no imagery of any kind.


DO
  • Say STATUS:AUTO MODE — terse, declarative, no pleasantries.
  • Abbreviate like firmware: MM:SS, FRM, LAMP V.
  • Zero-pad fixed-width numbers: 0000:00, 07/23/26.
  • Signal danger with blink plus inverse video.
DO NOT
  • Write "Your presets have been completed!" — no exclamation, no second person.
  • Introduce a second hue, a gradient, or a drop shadow.
  • Use emoji or an SVG icon set. Ever.
  • Animate with fades, eases, or slides — state changes are instant redraws.
02

COLOR

Five discharge intensities over three warm blacks. Every color decision in the system is a choice of intensity, and intensity means energization: bright is live, faint is inert.

There are two palettes, and they are not a light/dark pair — they are two different pieces of hardware. Switch with data-ac-gas on the root element, or use the GAS toggle in the menu bar. Both ramps are shown below regardless of which one is active; both are held to the same contrast gate.

DATA-AC-GAS="NEON" · 24° · THE DEFAULT

A monochrome AC plasma panel. The light is neon emitting directly from the gas — no phosphor anywhere in the stack. The hue is derived, not picked: weight the Ne I visible lines by the CIE 1931 observer and the discharge sits at x=0.631 y=0.369, just outside sRGB. That maps to 19°, which is a DC neon tube; a pulsed sustain enriches the 585.2nm line and walks it up. 19–31° is the defensible band and 24° is its middle.

--AMBER-100 · #FFA86DHOT HIGHLIGHT, FOCUS
--AMBER-90 · #FF6B08PRIMARY — --ink, --fill
--AMBER-70 · #DD5800SECONDARY TEXT
--AMBER-50 · #AB4500DIM, DISABLED
--AMBER-30 · #5B2500TRACE, GHOST RULES
--SCREEN · #100600
--SCREEN-RAISED · #1B0C02
--SCREEN-WELL · #060200
--ON-FILL · #1E0C00

DATA-AC-GAS="AMBER" · 38° · THE PHOSPHOR

The classic amber CRT phosphor (P3): a broad ~590nm band with real green content, where neon is a line spectrum with almost none. Historically this is a different display technology — but it is what most people mean by "amber terminal", it is the ramp the source design system was drawn against, and it pairs naturally with .ac-crt.

--AMBER-100 · #FFD052HOT HIGHLIGHT, FOCUS
--AMBER-90 · #FFAE1EPRIMARY — --ink, --fill
--AMBER-70 · #CD8817SECONDARY TEXT
--AMBER-50 · #8D5B10DIM, DISABLED
--AMBER-30 · #4A2F08TRACE, GHOST RULES
--SCREEN · #0D0700
--SCREEN-RAISED · #170E02
--SCREEN-WELL · #060200
--ON-FILL · #1A0E00

The --amber-* prefix names the ramp, not the hue — it is historical, and under NEON those tokens are not amber. Adding a third gas means adding one block to colors.css: five stops, three surfaces, --on-fill, and the four --gas-N triples the glow is built from.

SEMANTIC ALIASES

TOKENMAPS TOUSE
--ink / --ink-brightamber-90 / 100Body text; bright for live values and hover.
--ink-dim / --ink-faintamber-70 / 50Labels and legends; faint for disabled — and faint never glows.
--fill / --on-fillamber-90 / per paletteInverse-video surfaces and the dark text on them.
--stroke / --stroke-dimamber-90 / 50All borders, always 2px. Dim for secondary frames.
THE THREE EMPHASIS LEVELS — NO FOURTH EXISTS STATUS:AUTO MODE  PRESETS COMPLETED STATUS:AUTO MODE  PRESETS COMPLETED ✳ LAMP FAULT ✳
03

TYPE

Two bitmap faces. VT323 — a digitization of the DEC VT320 terminal ROM — carries everything at 18px and above. Silkscreen handles 8px bit labels where VT323 loses its grid. Below 18px, VT323 is unreadable: that is the floor, not a guideline.

DISPLAY · 44 / 0.1EMSHOW LOCAL - AUTO
TITLE · 30RESET FRAME COUNT
BODY · 22SHOW TIME 0000:00 (MM:SS) DATE 07/23/26
SMALL · 18SHOW INFORMATION ──────────────
MICRO · 8 SILKSCREENREMOTE START BIT · REEL UNIT READY · SYSTEM READY

CASING

ALL CAPS for machine text, Title Case for operator soft keys. SHOW LOCAL - AUTO MODE is the system reporting; Change Show is a key a human presses.

SUBSTITUTION NOTE

The source hardware used a mask-ROM face with no digital release. VT323 and Silkscreen are era-correct stand-ins. Supply a licensed bitmap face and only --font-terminal changes.

04

GLOW, BLINK, SCANLINES

The only three effects in the system. Glow marks energization, blink marks alarm, scanlines sit once on the outermost frame. There is no fourth effect, and no component anywhere in the CSS carries a transition — a control does not ease into being pressed. The one timing function in the whole framework belongs to the gas, not to the UI: see .ac-afterglow below.

The switches above default to PLASMA on, CRT off. Plasma is what this panel is; CRT simulates a different display technology, and its blanking gaps are the one thing a plasma screen conspicuously does not have. Turn it on to compare — the choice persists. .ac-afterglow rides the CRT switch, so it is off by default too.

Three screen simulations layer on top, driven from two switches — .ac-afterglow rides with .ac-crt, because persistence is a property of the same glass the scanlines are on, and a tube that scans without holding is not a tube anybody has watched. Each class still works alone if you wire it yourself: .ac-bloom (the panel — hotter glow tokens for every descendant, a soft center-weighted bleed breathing on a 9s mains cycle, and the cell mesh with its shimmer), .ac-crt (the tube — scanline texture, edge vignette, one-cell line drift per 11s, ±2% flicker, and a retrace band sweeping down every 13s) and .ac-afterglow (plasma persistence — see below). All three are tuned near the threshold of perception: if you can point at the effect, it is too strong. The motion describes energized hardware, not a UI transition — state changes stay instant — and everything stops under prefers-reduced-motion. .ac-scanlines is the static, motion-free texture for cards and print.

A screen door is not a scanline, and the difference is the whole point of .ac-bloom. A cell here lights at the crossing of a row wire and a column wire, boxed in on four sides by barrier ribs that carry no discharge and emit nothing — so a lit pixel is a neon dot trapped in a square aperture, and what you see with your eye close to the glass is a fine mesh in both axes. The dark horizontal blanking gaps between raster lines belong to .ac-crt and to the tube it simulates. There is no scan in a plasma panel, so there is nothing to blank. The ribs are drawn in pure black rather than a tint, which is what makes the grid appear only where the panel is lit: over the unlit screen a black veil has nothing to take away. On top of it sits the shimmer — the sustain voltage is AC, so the gas is struck and re-struck rather than held, and a sub-pixel buzz on two detuned cycles is the visible residue of that. Both stop under prefers-reduced-motion; the mesh itself does not, because it is the shape of the hardware rather than an effect playing over it.

All three go on the outermost frame, and the frame is the whole screen — including the menu bar. A nav that floats above the simulations is a nav that is not part of the panel, so .ac-nav--sticky sits inside the frame at z-index 20 and every overlay paints above it, from 40 up. That is also why .ac-screen clips with overflow: clip rather than hidden: hidden would make the frame a scroll container, and a sticky bar inside one sticks to nothing.

GLOW — ENERGIZED 255315 --glow-text on live values, --glow-box on filled and focused elements.
NO GLOW — INERT 255315 Dim and disabled states never glow. Glow is a signal, not a texture.
BLINK — ALARM ✳✳ CHECK DOUSER ✳✳ steps(1) hard on/off, 1.1s. Never a fade — until .ac-afterglow is on, which softens the OFF edge only. The ON edge stays instant either way.

PLASMA AFTERGLOW

A gas gap that stops being driven does not go dark on the next refresh. The discharge leaves excited and metastable neon behind it, and that population keeps emitting while it relaxes and recombines — the afterglow, which is a property of the gas and not of any coating. Most of the light is gone in the first fifth of a second, then a short dim tail. .ac-afterglow is that relaxation, and it is several separate things because persistence is six separate phenomena — and only four are reachable from CSS alone.

1 · DECAY-OUT Anything that disappears drains instead of switching off — a tab panel, a closing dialog, an acknowledged alarm. Pure CSS, and the one part that carries the effect on its own. The transition is declared on the hidden state only, so hiding decays and showing snaps back instantly. Nothing here ever fades in.
2 · GHOSTING Text rewritten in place leaves the previous value behind for a beat. Watch the clock and the frame counter on the console page. This is the one part CSS cannot do — nothing in the cascade remembers the old string — so a MutationObserver in amber-console.js parks a copy at the rect it occupied.
3 · RESIDUAL PATCHES The glass never sits perfectly uniform; charge relaxes unevenly. Four overlapping pools at 3% over the amber, drifting on a 47s cycle. You do not notice it directly — you notice when it stops.
4 · THE BLINK OFF-EDGE A blinking alarm is the thing on the panel that stops being driven most often — once a second, forever — so it is the last place the decay should be missing. .ac-blink stays steps(1) by default; with persistence on, only the ON edge stays hard. Instant up, curve down.
5 · DE-ENERGIZING The commonest light-off event on a control panel is not a node disappearing, it is a lamp going out: a pressed button releasing, a tab deselecting, an interlock unchecking, the pointer leaving a control. Those never hide, so decay-out never saw them and they snapped off in one frame while everything around them relaxed. Press RUN then STOP on the console and watch the pad drain.
6 · SCROLL SMEAR Scrolling hands every cell on the panel a new value at once, which is the largest light-off event there is, and the image trails. Scaled by real scroll speed and drained when you stop. Scroll this page briskly.
BLINK — ALARM ✳ LAMP FAULT ✳ Toggle CRT in the nav and watch this one. Off, it snaps between full and 10%. On, it holds, then drains over an ~88ms window of the 1.1s cycle — deliberately near the floor of what registers as a decay at all.
EVERY BLINK SITE FOLLOWS One rule swaps the animation-name rather than the shorthand, so .ac-blink, .ac-cursor, an invalid .ac-input and an over-range .ac-meter--alarm bar all keep their own cycle length and pick up the same curve. The de-energizing rules use the same trick as decay-out: the transition is declared on the UNLIT half, so going out drains and coming on is instant.
<div class="ac-screen ac-afterglow"><span class="ac-persist"></span> … </div>

Assuming a removed node ghosts itself. The observer only sees text change; a node that stops existing has no rect left to pin a ghost to, so ghost it before you remove it — AmberConsole.afterglow(row), then row.remove(). Retune the decay with --ac-decay (105ms), --ac-decay-fast (60ms, for rewritten text and de-energizing controls) and --ac-decay-ease.

THE THREE SIMULATIONS, SIDE BY SIDE

Each tile is its own frame. Use the PLASMA and CRT switches in the nav to compare these against the live page — the difference should be almost too small to name. CRT takes the afterglow with it. Note that the switches reach the menu bar too.

FLAT — NO SIMULATION 154A The baseline. Everything still reads.
.AC-BLOOM — THE PANEL 154A Hotter glow tokens, a soft bleed, and the cell mesh. Put your eye close.
.AC-CRT — THE TUBE 154A Scanlines, vignette, drift, flicker, retrace.
.AC-AFTERGLOW — PERSISTENCE 154A Residual patches only, here — a static tile has nothing to decay.
.AC-SCANLINES — STATIC TEXTURE 154A No motion at all. For print, cards and thumbnails.
<div class="ac-screen ac-bloom ac-crt ac-afterglow"><span class="ac-mesh"></span><span class="ac-retrace"></span><span class="ac-persist"></span> … </div>

Nesting a simulation inside another one. Once per screen, on the outermost frame — the tiles above are the exception that proves it, and they are documentation, not UI.

BLOCK CURSORTITLE:HEAT class="ac-cursor"
GLYPHS — THE ONLY ICON SET ✳✳   █ ▮ ▯   ▲ ▼ ◄ ►   ┌─┐ └─┘ Typeset in the terminal font. Never an SVG, never an emoji.
05

GEOMETRY

SPACING · 4 8 12 16 24 32 48
4px half-cells of the character grid.
STROKE · 2PX ONLY
No hairlines — a 1px rule cannot exist on this panel. The one exception is .ac-badge, which is a chip rather than structure.
RADIUS · 8 PADS / 4 WELLS / 0 STRIPS
CRT-rounded corners, never pills.
06

CONTROLS

Live components from the library. Hover to brighten, press to invert, tab to see the dashed focus ring.

BUTTON — VARIANTS
Outline is default. Filled is inverse video — one primary per region. Dim is secondary. Disabled drops to faint and loses its glow. class="ac-btn" ac-btn--filled ac-btn--dim ac-btn--block [disabled] <!-- or drive it with ARIA: --> <button class="ac-btn" aria-pressed="true">

More than one filled button in a region. Inverse video means "the machine is doing this"; two of them means neither reads.

BUTTON — SIZES
class="ac-btn ac-btn--sm" ac-btn ac-btn--lg

--sm on a touch panel: it computes to about 30px tall, under the 44px hit-target floor. Use it only in dense, mouse-driven tooling.

BUTTON — TOUCH PADS (LABEL TOP-LEFT, BODY EMPTY)
Sized for a gloved finger; the active mode is the filled one. Selection is state, not decoration. class="ac-btn ac-btn--lg ac-btn--pad ac-grow"

A row of pads without .ac-grow (or min-width:0) — the 130px min-width floor will overflow a narrow viewport.

TABS — SOFT KEYS, TITLE CASE
Arrow keys, Home and End move between them when the optional JS module is loaded. <div class="ac-tabs" role="tablist" data-ac="tabs"> <button class="ac-tab" role="tab" aria-selected="true" aria-controls="panel-1">Functions</button> </div>

Navigation between pages — that is .ac-nav. Tabs swap a region, not a screen.

INPUT + SELECT — RECESSED WELLS Invalid is blink plus inverse video. There is no red border, because there is no red. <label class="ac-field"> <span class="ac-field__label">Title:</span> <input class="ac-input" type="text"> </label> <span class="ac-select"><select class="ac-input">…</select></span>
CHECKBOX — STATUS BITS (NO CHECK GLYPH) A set bit fills solid, exactly like a hardware indicator lamp. <label class="ac-check"><input type="checkbox"><span>Spare</span></label>

A single yes/no setting the operator flips — that reads better as an .ac-toggle, which states ON or OFF in words.

RADIO — EXCLUSIVE MODES <label class="ac-radio"><input type="radio" name="mode"><span>Auto</span></label>

More than about five options — that is an .ac-select.

TOGGLE — HARD SNAP, ON/OFF READOUT The thumb jumps; it does not slide. Text state is mandatory — a switch position alone is ambiguous on a monochrome panel. The middle one is the CSS-only variant: no JavaScript at all. <button class="ac-toggle" data-ac="toggle" aria-pressed="false">…</button> <label class="ac-toggle ac-toggle--input">…<input type="checkbox">…</label>
KEYPAD — NUMERIC ENTRY FOR GLOVED HANDS
<div class="ac-keypad"><button class="ac-btn ac-keypad__key">7</button>…</div>

Any screen with a keyboard attached. This exists because there is no keyboard in a projection booth.

DIALOG — IT APPEARS; IT DOES NOT FADE IN Flat backdrop, no blur, no scale. Built on native <dialog>, so Escape and focus trapping come from the browser. <dialog class="ac-dialog"><form method="dialog"> <h2 class="ac-dialog__title">Confirm</h2> <div class="ac-dialog__body">…</div> <div class="ac-dialog__actions">…</div> </form></dialog>

Anything the operator must see machine state behind. A modal on a control surface hides the panel; use an .ac-banner instead.

07

DISPLAY

The machine's own voice: frames, strips, readouts, and the single loudest element the system permits.

STATUSBAR — INVERSE (MACHINE VOICE) AND LINE (DATA ROW)
STATUS:AUTO MODEPRESETS COMPLETED
SHOW TIME 0000:00 (MM:SS)DATE 07/23/26TIME 22:28:45
class="ac-statusbar" ac-statusbar--line role="status"

Prose. A status bar holds KEY:VALUE strings, not sentences.

PANEL — LEGEND CHIP BREAKS THE BORDER
Show Information
TRAILER:
TITLE:HEAT
<div class="ac-panel"><span class="ac-panel__title">Show Information</span>…</div>

A panel over a non---screen background, unless you also set --ac-panel-title-bg — the chip paints its own background to mask the border.

PANEL — INVERSE BAR TITLE
Frame Count
255315
class="ac-panel ac-panel--bar"
READOUT — INSTRUMENT VALUE
Lamp Volts
41.0V
Lamp Amps
154A
Frames
255315
<div class="ac-readout"> <div class="ac-readout__label">Lamp Volts</div> <div class="ac-readout__value">41.0<span class="ac-readout__unit">V</span></div> </div>

Text. A readout is for a number that changes.

BADGE — MICRO TAGS, PIXEL FACE
CH 04ArmedSpare
class="ac-badge" ac-badge--filled ac-badge--dim

Anything the operator must read at a glance — 8px is a label, not a message.

TABLE — THE DATA GRID THIS GENRE LIVES ON
TIMECODEDESCRIPTIONFRAMESTATE
22:28:41E-114DOUSER NOT CONFIRMED255315ACTIVE
22:14:02W-062LAMP CURRENT LOW 148A234880CLEARED
21:58:37W-041REEL UNIT SLACK212104CLEARED
class="ac-table ac-table--zebra ac-table--dense" <td class="ac-table__num"> <tr class="ac-table__row--active ac-blink">

A fixed set of named readings — that is .ac-list.

LIST — KEYED LOG WITH LEADER DOTS
Lamp Hours
1284
Reel
04 / 06
Format
70MM
<dl class="ac-list"><div class="ac-list__item"> <dt class="ac-list__key">Reel</dt><span class="ac-list__fill"></span> <dd class="ac-list__value">04 / 06</dd></div></dl>

Sortable or multi-column data. That is a table.

METER — STEPPED BARGRAPH, NEVER A SMOOTH FILL
050100
<div class="ac-meter__track" style="--ac-meter-value: 72"> <div class="ac-meter__bar"></div></div>

A single precise reading. A number the operator can write down beats a bar they have to estimate — use an .ac-readout.

SPINNER — A CHARACTER, NOT A CIRCLE
LOADING PRESET BANK
steps(4), 0.8s
<span class="ac-spinner" role="status" aria-label="Working"></span>

Anything whose duration you know. A machine that can measure progress should show an .ac-meter; a spinner admits it cannot.

BANNER — ONE PER SCREEN, THE LOUDEST ELEMENT
Remote Mode
✳✳ glyphs are added by the component. Blink is reserved for a live, unacknowledged condition — and it is always paired with inverse video and the glyphs, so it still reads as an alarm when blink is switched off. <div class="ac-banner ac-banner--filled ac-blink" role="alert">Lamp Fault</div>

Two banners on one screen. The second one makes the first one furniture.

PANEL — DIM FRAME (RECEDES)
Interlocks SECONDARY REGION — READ-ONLY INSTRUMENTATION
class="ac-panel ac-panel--dim"
08

SCREEN ANATOMY

How a full console screen assembles. Title and soft keys on top; the operating column left, instrumentation right; destructive or exiting actions bottom-right, far from RUN.

ZONECONTENTSRULES
HEADERWordmark, page title (ALL CAPS, underlined), Title Case tabs right.One display-size line only.
LEFT COLUMNLegend panel with input wells, status strips, motion pads, banner.Reading order top to bottom is the operator's workflow.
RIGHT COLUMNBit-field checkboxes in a dim panel, bar panels with readouts.Read-only instrumentation; dim frames so it recedes.
FOOTER ROWMode changes left, exit and destructive actions bottom-right.Never adjacent to a motion control.
FRAME.ac-crt, .ac-bloom and/or .ac-afterglow on the outermost element, plus one companion child per simulation: .ac-mesh for bloom, .ac-retrace for CRT, .ac-persist for afterglow. The nav goes inside it.Once per screen, never nested. All three should be operator-toggleable — the demos put afterglow on the CRT switch.
<div class="ac-screen ac-bloom ac-crt ac-afterglow" data-ac-screen> <span class="ac-mesh"></span> <span class="ac-retrace"></span> <span class="ac-persist"></span> <nav class="ac-nav ac-nav--sticky">…</nav> <div class="ac-screen__body"> <div class="ac-grid ac-grid--console ac-grow"> <div class="ac-stack">…operate…</div> <div class="ac-stack">…instrument…</div> </div> </div> </div>

See the assembled reference screen: ORION-70 PROJECTION CONSOLE.

Confirm

THE BACKDROP IS FLAT BLACK AT 72%. NO BLUR, NO SCALE, NO FADE — A REDRAWN SCREEN HAS NO IN-BETWEEN FRAMES.