Fix the finish review's 8 material findings on the teletext redesign
Applies the fix round from the finish-reviewer's disposition on commit
4b19cbd, in one batch:
- System's disk table is unreadable below 560px: horizontal-scrolling a
6-column table hid the usage bar and the temperature, the two
readings that matter most (discipline 3 — one shared ruler — was
unauditable as a result). Added a disk_row() macro and a phone-only
.tt-disk-rows reflow (name + full 20-cell bar + temp on one line,
device/free/total beneath), CSS-toggled against the existing table
at the same breakpoint.
- Contrast failure on the highest-severity state: white text on the
red .tt-field.crit/.tt-toast.error/.tt-btn.armed reversals measured
4.0:1, under the 4.5:1 floor. Switched to black text (5.25:1),
matching the black-on-yellow .warn pattern already in use — and
fixed a second instance of the same bug: .tt-field.crit had no
.tt-field-meta override, unlike .warn.
- Two type families where the direction contract names one blocky
monospace: unified on a single self-hosted face (Space Mono, one
weight, no bold) for both body and the double-height row.
- FIRST VIEWPORT proportion: an unpromised 6-item Just Added grid was
competing with NOW SHOWING for the fold instead of the contract's
"lower two-thirds in double-height cyan." Cut to a fixed 3-item,
fixed-3-column row, which also fixes the orphaned-tile grid defect
as a side effect (a fixed count can't leave a lone tile beside empty
tracks).
- Three flat mid-grey fills contradicted discipline 1 (no in-between
tone): .tt-tile-art, .tt-btn:disabled, and .tt-err pre all painted a
solid --ink-dimmer background. Centralized the dither .tt-tile-art
already used correctly into a shared --dither-mid generator and
applied it to all three.
- Google Fonts dependency on a LAN-only home server: a dropped webfont
request was a silent identity change, not a graceful fallback.
Self-hosted Space Mono under static/fonts/ via @font-face; dropped
the <link> tags from _shell.html and login.html.
- Deliberately deferred: "pages differ in stock" (discipline 5) still
fires on only one band service-wide. Every other finding was a
bounded fix to existing code; this one asks for a new mechanism (an
aggregate status band on P100) rather than a correction, so it's
flagged for a follow-up rather than rushed into this batch.
Recaptured desktop.png, mobile.png, desktop-system.png and
mobile-system.png (the four files the reviewer's findings cited)
through the same true-390px iframe method as the prior round, and
returned them for the fix round's verdict pass.
Known follow-up: DESIGN.md's typography section (written by the
documenter before this batch) still names the old two-family pairing
and needs a re-run now that the font system changed under it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NBw1QodG8ZMYHrGeQfqyDS
This commit is contained in:
parent
4b19cbdfb2
commit
bc7779e590
9 changed files with 155 additions and 28 deletions
|
|
@ -29,6 +29,23 @@
|
|||
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
|
||||
|
|
@ -67,18 +84,28 @@
|
|||
--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. Emphasis comes from colour and
|
||||
from doubling the height, never from a weight ramp and
|
||||
never from a third size. */
|
||||
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: 'Chivo Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
||||
--font-dh: 'DotGothic16', 'Chivo Mono', ui-monospace, Menlo, monospace;
|
||||
--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
|
||||
|
|
|
|||
|
|
@ -95,7 +95,15 @@
|
|||
}
|
||||
/* A page carrying critical state gets a heavier field than a quiet
|
||||
one (discipline 5) — the band goes red and doubles in height. */
|
||||
.tt-field.crit { background: var(--alert); color: var(--tt-white); }
|
||||
.tt-field.crit {
|
||||
background: var(--alert);
|
||||
/* Black, not white: white-on-red measures 4.0:1 here, under the
|
||||
4.5:1 floor for 15px uppercase text. Black-on-red clears 5.25:1
|
||||
and is the correct teletext reversal — every other coloured band
|
||||
(.warn, a hover row) already reverses to black. */
|
||||
color: var(--tt-black);
|
||||
}
|
||||
.tt-field.crit .tt-field-meta { color: var(--tt-black); }
|
||||
.tt-field.warn { background: var(--voice); color: var(--tt-black); }
|
||||
.tt-field.warn .tt-field-meta { color: var(--tt-black); }
|
||||
|
||||
|
|
@ -273,6 +281,41 @@ a.tt-row:focus-visible .tt-row-sub { color: var(--tt-black); }
|
|||
.tt-table tbody tr:hover th,
|
||||
.tt-table tbody tr:hover td { background: var(--field); color: var(--tt-white); }
|
||||
|
||||
/* ── Disk rows (System, phone reflow of the table above) ──
|
||||
Below 560px a six-column table stops fitting; scrolling it
|
||||
horizontally hides the bar and the temperature, the two
|
||||
readings that matter most here. This is the other rendering
|
||||
of the same disk data, shown only below that width — see the
|
||||
media query at the bottom of this file for the swap. */
|
||||
.tt-disk-rows { display: none; flex-direction: column; }
|
||||
.tt-disk-row { padding: 0.4em 1ch; }
|
||||
.tt-disk-row-top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.4em 1ch;
|
||||
}
|
||||
.tt-disk-name {
|
||||
flex: 0 0 auto;
|
||||
min-width: 5ch;
|
||||
color: var(--ink);
|
||||
letter-spacing: 0.16em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.tt-disk-pct {
|
||||
flex: 0 0 auto;
|
||||
color: var(--live);
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
.tt-disk-row-sub {
|
||||
margin-top: 0.15em;
|
||||
color: var(--ink-dim);
|
||||
}
|
||||
.tt-disk-row:hover { background: var(--field); }
|
||||
.tt-disk-row:hover .tt-disk-name,
|
||||
.tt-disk-row:hover .tt-disk-pct,
|
||||
.tt-disk-row:hover .tt-disk-row-sub { color: var(--tt-white); }
|
||||
|
||||
/* ── Tiles (library / discover) ─────────────────────────
|
||||
Artwork is the one thing in this world that is not made of
|
||||
characters, so it is treated as an inserted transmission: a
|
||||
|
|
@ -284,21 +327,28 @@ a.tt-row:focus-visible .tt-row-sub { color: var(--tt-black); }
|
|||
grid-template-columns: repeat(auto-fill, minmax(min(12.5ch, 100%), 1fr));
|
||||
padding: 0 1ch;
|
||||
}
|
||||
/* P100's Just Added: a fixed row, not a viewport-dependent auto-fill.
|
||||
Paired with a fixed item count (see home()), this guarantees a full
|
||||
row every time rather than leaving a lone tile beside empty tracks —
|
||||
and it keeps this block compact, so NOW SHOWING above it can hold the
|
||||
lower two-thirds of the first viewport the direction contract names. */
|
||||
.tt-tiles-row {
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
}
|
||||
@media (max-width: 560px) {
|
||||
.tt-tiles-row { grid-template-columns: repeat(1, 1fr); }
|
||||
}
|
||||
.tt-tile { display: flex; flex-direction: column; min-width: 0; }
|
||||
.tt-tile-art {
|
||||
display: block;
|
||||
width: 100%;
|
||||
aspect-ratio: 2 / 3;
|
||||
object-fit: cover;
|
||||
background: var(--ink-dimmer);
|
||||
}
|
||||
/* No artwork came back. A dithered field, not a fake poster. */
|
||||
.tt-tile-art-empty {
|
||||
background-image: repeating-linear-gradient(
|
||||
45deg,
|
||||
var(--ink-dimmer) 0 1px,
|
||||
var(--tt-black) 1px calc(var(--dither-size) * 2)
|
||||
);
|
||||
/* Covers the box while a real poster is still loading, and IS the
|
||||
fallback for a poster that never arrives — dithered, per
|
||||
discipline 1, never a flat mid-grey panel. */
|
||||
background-color: var(--tt-black);
|
||||
background-image: var(--dither-mid);
|
||||
}
|
||||
.tt-tile-t {
|
||||
margin-top: 0.4em;
|
||||
|
|
@ -330,8 +380,13 @@ a.tt-row:focus-visible .tt-row-sub { color: var(--tt-black); }
|
|||
cursor: pointer;
|
||||
}
|
||||
.tt-btn:hover:not(:disabled) { background: var(--live); }
|
||||
.tt-btn:disabled { background: var(--ink-dimmer); color: var(--ink-dim); cursor: default; }
|
||||
.tt-btn.armed { background: var(--alert); color: var(--tt-white); }
|
||||
.tt-btn:disabled {
|
||||
background-color: var(--tt-black);
|
||||
background-image: var(--dither-mid);
|
||||
color: var(--ink-dim);
|
||||
cursor: default;
|
||||
}
|
||||
.tt-btn.armed { background: var(--alert); color: var(--tt-black); }
|
||||
.tt-btn.done { background: transparent; color: var(--ok); cursor: default; }
|
||||
.tt-btn-quiet {
|
||||
background: transparent;
|
||||
|
|
@ -398,7 +453,8 @@ a.tt-row:focus-visible .tt-row-sub { color: var(--tt-black); }
|
|||
.tt-err pre {
|
||||
margin: 0.3em 0 0;
|
||||
padding: 0.5em 1ch;
|
||||
background: var(--ink-dimmer);
|
||||
background-color: var(--tt-black);
|
||||
background-image: var(--dither-mid);
|
||||
color: var(--ink);
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
|
|
@ -539,6 +595,11 @@ a.tt-row:focus-visible .tt-row-sub { color: var(--tt-black); }
|
|||
.tt-row-val { margin-left: auto; white-space: normal; }
|
||||
.tt-head-name { letter-spacing: 0.12em; }
|
||||
.tt-head-clock { margin-left: 0; flex-basis: 100%; }
|
||||
|
||||
/* The System disk table swaps for its row reflow here — see the
|
||||
"Disk rows" block above. */
|
||||
.tt-table-scroll { display: none; }
|
||||
.tt-disk-rows { display: flex; }
|
||||
}
|
||||
|
||||
/* ── Search ─────────────────────────────────────────────
|
||||
|
|
@ -615,7 +676,10 @@ a.tt-row:focus-visible .tt-row-sub { color: var(--tt-black); }
|
|||
pointer-events: none;
|
||||
}
|
||||
.tt-toast.show { opacity: 1; transform: translateY(0); }
|
||||
.tt-toast.error { background: var(--alert); color: var(--tt-white); }
|
||||
.tt-toast.error {
|
||||
background: var(--alert);
|
||||
color: var(--tt-black); /* same contrast fix as .tt-field.crit */
|
||||
}
|
||||
|
||||
/* ── Sign-in ────────────────────────────────────────────
|
||||
The one page with no navigation, so it centres its single
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue