arr-summary/static/css/base.css
Barely Removable 517559a460
All checks were successful
Deploy / deploy (push) Successful in 24s
Give Activity a genuine ninth colour: --tt-orange
Requested directly: "can we make activity orange". The locked eight
palette had already run out at six legible text colours (Watch's blue
was the last one, and it's already a contrast exception); a dithered
swatch alone read as unfinished, and dithering the word itself
rendered as illegible static — tried and reverted this session.

--tt-orange (#ff8000) is defined in base.css right after the locked
eight, clearly marked as a deliberate, acknowledged one-off exception
to "eight colours, no ninth" rather than a secretly-smuggled-in tint.
Same flat text+swatch treatment as every other fastext key. Updated
CLAUDE.md's discipline 1 and DESIGN.md's Locked Eight Rule to name the
exception explicitly, so it reads as a documented decision next time
someone audits the palette, not a bug.
2026-08-30 09:52:19 -07:00

186 lines
8.7 KiB
CSS

/* ═══════════════════════════════════════════════════════
MEDIA CENTRE — "Page 100"
A broadcast information service, not a dashboard. The world
is teletext (Ceefax, and the cable guide channel that did the
same job in America): a locked eight-colour palette on pure
black, one blocky monospace at exactly two heights, a strict
character-cell grid, and grouping carried by colour fields and
row weight — never by a border, never by a box.
Five disciplines this world is held to. Breaking one is a
regression, not a variation:
1. NO IN-BETWEEN TONE. There are eight colours. A mid-grey is
an ordered dither of two of them (--dither-*), never a
ninth colour smuggled into the palette.
2. NO ENCLOSURE. Nothing is ever surrounded by a border or a
box. Grouping is a coloured field row, indentation, and
weight. This is the exact reflex the old design was built
on and the main thing this world refuses.
3. ONE RULER. Every bar, meter and percentage on every page
shares one scale (--bar-cells), so 60% on the array and
60% on an indexer are the same width and compare directly.
4. EVERY READING CARRIES ITS DIRECTION. A value shows where
it is heading, so a disk becoming a problem is visible
before it is one.
5. PAGES DIFFER IN STOCK. A page holding critical state is
set heavier than a quiet one. Uniform texture across seven
pages is a failure.
═══════════════════════════════════════════════════════ */
/* Self-hosted, deliberately: this app runs on a LAN-only home server
behind a filtered/offline-capable network, where a Google Fonts
request can simply fail. A dropped @font-face request means every
character on the page silently falls back to whatever monospace the
OS ships — a different world by accident, not a variation of this
one. One weight only (400): there is no bold in this system. */
@font-face {
font-family: 'Space Mono';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('../fonts/SpaceMono-Regular.woff2') format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6,
U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
:root {
/* ── The locked eight ──────────────────────────────────
Teletext had exactly these, at full saturation, and the
product's semantics were already the same semantics:
green runs, yellow works, red is off air. Do not soften
them; the emissive-on-black scene is what they are for. */
--tt-black: #000000;
--tt-red: #ff0000;
--tt-green: #00ff00;
--tt-yellow: #ffff00;
--tt-blue: #0000ff;
--tt-magenta: #ff00ff;
--tt-cyan: #00ffff;
--tt-white: #ffffff;
/* A deliberate, acknowledged ninth: the fastext nav has eight
destinations and only five of the locked eight read as legible
text on black once red/green/yellow/cyan/magenta/blue are already
spoken for (Activity ran out — a dithered swatch alone read as
unfinished, and dithering the word itself was tried and found
illegible). Not "one of the eight" — used nowhere else. */
--tt-orange: #ff8000;
/* ── Roles ─────────────────────────────────────────────
Each colour means one thing across all nine pages. */
--ink: var(--tt-white); /* body text */
--voice: var(--tt-yellow); /* the service speaking: mastheads, page numbers */
--live: var(--tt-cyan); /* live values, now showing */
--ok: var(--tt-green); /* running, healthy, available */
--alert: var(--tt-red); /* off air, failed, danger */
--pending: var(--tt-magenta); /* requested, waiting on a human */
--field: var(--tt-blue); /* the only "background" colour — header fields */
/* ── Dither ────────────────────────────────────────────
The only legal way to make a tone that isn't one of the
eight. A checkerboard of the colour against black at cell
scale, exactly how a 16-colour screen faked a gradient.
Used for inactive bar cells and secondary text grounds. */
--dither-size: 2px;
/* --ink-dim is the ONLY dimmed value allowed to carry text: at 58% it
clears 4.5:1 on black. --ink-dimmer is for graphics only — bar
troughs, the dither field, the separator — because at 30% it does
not, and secondary text set in it was failing contrast outright. */
--ink-dim: color-mix(in srgb, var(--tt-white) 58%, var(--tt-black));
--ink-dimmer: color-mix(in srgb, var(--tt-white) 30%, var(--tt-black));
/* The one legal way to fill an area with a mid-tone: every "flat
grey panel" in the codebase (a disabled button, an unloaded poster,
a code block behind an error detail) draws from this generator
rather than declaring --ink-dimmer as a solid background. A solid
fill of a dimmed token is still a ninth colour by another name. */
--dither-mid: repeating-linear-gradient(45deg,
var(--ink-dimmer) 0 1px, var(--tt-black) 1px calc(var(--dither-size) * 2));
/* ── Type: one face, exactly two heights ───────────────
Teletext's entire scale — ONE family, not one for body and a
different one for the double-height row. Emphasis comes from
colour and from doubling the height, never from a weight ramp
(this face loads a single weight, 400, on purpose — there is
no bold anywhere to reach for) and never from a third size. */
--fs: 0.9375rem; /* 15px — the single body size */
--fs2: 1.875rem; /* 30px — double height, the only other size */
--lh: 1.45;
--row: calc(var(--fs) * var(--lh)); /* one character row */
--cell: 1ch;
--font: 'Space Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
--font-dh: var(--font);
/* ── Measure ───────────────────────────────────────────
A teletext page was 40 columns. A screen this wide gets
double that, so density survives without the grid dying. */
--page-cols: 92ch;
--gutter: 1.5rem;
/* ── The one ruler (discipline 3) ──────────────────────
Every bar on every page is this many cells wide, so any
two percentages anywhere in the service are comparable. */
--bar-cells: 20;
--bar-cell-w: 0.62em;
--tap: 44px;
}
*, *::before, *::after { box-sizing: border-box; }
html { background: var(--tt-black); }
body {
margin: 0;
background: var(--tt-black);
color: var(--ink);
font-family: var(--font);
font-size: var(--fs);
line-height: var(--lh);
font-variant-numeric: tabular-nums;
/* Teletext never anti-aliased into a soft grey edge. Keep the
letterforms crisp rather than letting the browser blend them
toward tones the palette does not contain. */
-webkit-font-smoothing: antialiased;
text-rendering: optimizeSpeed;
}
/* Phosphor bloom. Applied only where the world is speaking loudly —
double-height rows and status glyphs — because bloom under a dense
table of figures costs more legibility than it buys character. */
.bloom {
text-shadow: 0 0 0.4em color-mix(in srgb, currentColor 55%, transparent);
}
a { color: var(--live); text-decoration: none; }
a:hover { color: var(--tt-black); background: var(--live); }
/* Focus is a reversed cell, the way a teletext menu row selected
itself. No outline ring — a ring is an enclosure. */
:focus-visible {
outline: none;
background: var(--voice);
color: var(--tt-black);
}
::selection { background: var(--live); color: var(--tt-black); }
/* Browser furniture, themed to the palette rather than left at the
defaults that belong to no design system. */
* { scrollbar-color: var(--ink-dimmer) var(--tt-black); scrollbar-width: thin; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: var(--tt-black); }
::-webkit-scrollbar-thumb { background: var(--ink-dimmer); }
::-webkit-scrollbar-thumb:hover { background: var(--ink-dim); }
::-webkit-scrollbar-corner { background: var(--tt-black); }
input { caret-color: var(--voice); }
.visually-hidden {
position: absolute; width: 1px; height: 1px;
padding: 0; margin: -1px; overflow: hidden;
clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}