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
129 lines
5.5 KiB
HTML
129 lines
5.5 KiB
HTML
{#- ═══════════════════════════════════════════════════════
|
|
Shared fragments, in the service's own vocabulary.
|
|
|
|
Every one of these obeys the two disciplines that get broken
|
|
by reflex: nothing is enclosed in a border or a box, and every
|
|
bar is drawn at the one shared width so any two percentages in
|
|
the service compare directly.
|
|
═══════════════════════════════════════════════════════ -#}
|
|
|
|
{#- A degraded service. Teletext's failure was a page that did not
|
|
arrive, said in red where the content should have been — not a
|
|
panel with an icon and a left border. -#}
|
|
{% macro service_error(name, raw) %}
|
|
<div class="tt-err" role="alert">
|
|
<div class="tt-err-cause">{{ raw | friendly_error(name) }}</div>
|
|
{% if raw %}
|
|
<details>
|
|
<summary>Technical detail</summary>
|
|
<pre>{{ raw | redact_secrets }}</pre>
|
|
</details>
|
|
{% endif %}
|
|
</div>
|
|
{% endmacro %}
|
|
|
|
|
|
{#- THE ONE RULER. Every bar in the service is drawn here and
|
|
nowhere else, at --bar-cells wide, filled in whole cells. Pass a
|
|
percentage; the macro rounds it to cells so a bar never ends
|
|
mid-character. `tone` picks the colour by threshold. -#}
|
|
{% macro bar(pct, tone='') %}
|
|
{%- set p = [[pct | float(0), 0] | max, 100] | min -%}
|
|
{%- set cells = 20 -%}
|
|
{%- set filled = ((p / 100) * cells) | round(0, 'common') | int -%}
|
|
{%- set cls = tone if tone else ('alert' if p >= 90 else ('warn' if p >= 75 else 'ok')) -%}
|
|
<span class="tt-bar {{ cls }}" role="img"
|
|
aria-label="{{ p | round | int }} percent"><i style="width: {{ (filled / cells * 100) | round(2) }}%"></i></span>
|
|
{% endmacro %}
|
|
|
|
|
|
{#- Direction of travel. Only ever called where the backend really
|
|
carries a comparison — never to decorate a number that has no
|
|
history behind it. -#}
|
|
{% macro trend(now, reference, unit='') %}
|
|
{%- if now is not none and reference is not none and reference > 0 -%}
|
|
{%- set delta = ((now - reference) / reference) * 100 -%}
|
|
{%- if delta > 12 -%}
|
|
<span class="tt-trend up" title="Above the 7-day average">▲</span>
|
|
{%- elif delta < -12 -%}
|
|
<span class="tt-trend down" title="Below the 7-day average">▼</span>
|
|
{%- else -%}
|
|
<span class="tt-trend flat" title="At the 7-day average">▬</span>
|
|
{%- endif -%}
|
|
{%- endif -%}
|
|
{% endmacro %}
|
|
|
|
|
|
{#- Disk temperature / spin state. A spun-down disk reports no usable
|
|
temperature, so Standby replaces the reading rather than showing a
|
|
stale or zero degree value. Colour carries the state; there is no
|
|
badge shape to put it in. -#}
|
|
{% macro disk_state(dk) %}
|
|
{%- if dk.spinning == false -%}
|
|
<span class="tt-row-val off">STANDBY</span>
|
|
{%- elif dk.temp is not none -%}
|
|
<span class="tt-row-val {% if dk.temp >= 55 %}alert{% elif dk.temp >= 45 %}warn{% else %}ok{% endif %}">{{ dk.temp }}°C</span>
|
|
{%- else -%}
|
|
<span class="tt-row-val off">—</span>
|
|
{%- endif -%}
|
|
{% endmacro %}
|
|
|
|
|
|
{#- A title tile. Artwork is the only thing in this world not made of
|
|
characters, so it sits as a flat rectangle on the grid with its
|
|
label below — no frame, no rounding, no shadow. -#}
|
|
{% macro tile(title, sub, poster, badge='', action='', target='') %}
|
|
<div class="tt-tile">
|
|
{% if poster %}
|
|
<img class="tt-tile-art" src="{{ poster }}" alt="" loading="lazy">
|
|
{% else %}
|
|
<span class="tt-tile-art tt-tile-art-empty" aria-hidden="true"></span>
|
|
{% endif %}
|
|
<span class="tt-tile-t">{{ title }}</span>
|
|
{% if sub or badge %}
|
|
<span class="tt-tile-s">
|
|
{%- if badge %}<span class="tt-tile-badge">{{ badge }}</span>{% endif %}
|
|
{%- if badge and sub %} {% endif %}{{ sub }}</span>
|
|
{% endif %}
|
|
{% if action %}
|
|
<span class="tt-tile-p">
|
|
<button class="tt-btn tt-btn-sm" data-title="{{ title }}" data-target="{{ target }}"
|
|
onclick="armAdd(this)">{{ action }}</button>
|
|
</span>
|
|
{% endif %}
|
|
</div>
|
|
{% endmacro %}
|
|
|
|
|
|
{#- A disk/cache row for the phone reflow of the System table (below
|
|
560px, where a six-column table stops fitting and its horizontal
|
|
scroll would hide the bar and the temperature — the two readings
|
|
that matter most). Name, the one shared bar, and the temperature
|
|
sit on one line; device/size/free sit beneath as a sub-line. The
|
|
desktop <table> stays the table at wider widths; this is not a
|
|
replacement for it, only the reflow. -#}
|
|
{% macro disk_row(dk) %}
|
|
<div class="tt-disk-row">
|
|
<div class="tt-disk-row-top">
|
|
<span class="tt-disk-name">{{ dk.name }}</span>
|
|
{{ bar(dk.used_pct | default(0)) }}
|
|
<span class="tt-disk-pct">{{ dk.used_pct | default(0) | round | int }}%</span>
|
|
{{ disk_state(dk) }}
|
|
</div>
|
|
<div class="tt-disk-row-sub">{{ dk.device | default('—') }} · {{ dk.free | default('—') }} free of {{ dk.total | default('—') }}</div>
|
|
</div>
|
|
{% endmacro %}
|
|
|
|
|
|
{#- A list row: number, name, body, value. The index rows and every
|
|
listing in the service share this one shape. -#}
|
|
{% macro row(name, title, sub='', value='', tone='') %}
|
|
<div class="tt-row">
|
|
{% if name %}<span class="tt-row-name">{{ name }}</span>{% endif %}
|
|
<span class="tt-row-body">
|
|
<span class="tt-row-title">{{ title }}</span>
|
|
{% if sub %}<span class="tt-row-sub">{{ sub }}</span>{% endif %}
|
|
</span>
|
|
{% if value %}<span class="tt-row-val {{ tone }}">{{ value }}</span>{% endif %}
|
|
</div>
|
|
{% endmacro %}
|