TUI design polish: bordered titles, status pills, dense controls, hatched empty states#10
Merged
Merged
Conversation
…ls, dense controls Tier 1 of the Posting design port (both apps are Textual, so the patterns port as CSS): - Panel titles move into the border (border_title, right-aligned); panels rest at 40%-alpha borders and brighten to full $primary + bold title on focus-within. Evidence's files panel carries the run scoreboard in its border title. - New palette.pill()/status_pill() render status cells as text on a same-hue muted swatch (the tokyo-night text-*/*-muted pairs), replacing hand-picked green/red literals across run/manifest/evidence/upload. - Inputs and buttons flatten to one row; focused inputs show a wide $primary left edge with padding swapped so text never shifts. - Thin 1-cell scrollbars tinted $primary, muted-bold DataTable headers, and render.py detail panes moved onto the palette hexes. Verified with a headless Pilot tour (screenshots of every tab, modals, and a synthetic-event run); 209 tests pass. Co-Authored-By: Claude Fable 5 <[email protected]>
…st panels
A .panel tagged .empty hides its DataTable/RichLog and shows a hatched,
centered .empty-hint placeholder instead (Posting's empty-state idiom),
with the relevant keybind accented in the hint:
- Run: both panels hatch until a run starts ("ctrl+r executes the
manifest"); cleared by _start_run and by the run_start event so the
synthetic-event test path behaves the same; reset_state restores them.
- Evidence: runs panel hatches when no runs exist, files panel when the
selected run produced no files.
- Upload: the log panel hatches until an upload starts.
- Manifest: the entries panel hatches with a message that adapts to
"no manifest loaded" vs "manifest is empty".
Verified with the headless Pilot screenshot tour; 209 tests pass.
Co-Authored-By: Claude Fable 5 <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
A visual-design pass on the TUI, porting the design language of Posting (also a Textual app, so its patterns port as CSS + small widget tweaks). No behavior changes — layout, keybindings, and the api facade surface are untouched.
Panels — titles moved into the border frame (
border_title, right-aligned). Panels rest at a 40%-alpha border and brighten to full$primary+ bold title on:focus-within, so the active pane is always obvious, and every panel gained a content row. The Evidence files panel carries the selected run's scoreboard in its border title (run-id ✓ 4 ✗ 2).Status pills — new
palette.pill()/status_pill()helpers render statuses as readable text on a same-hue muted swatch (the exacttext-*/*-mutedpairs Textual derives for tokyo-night). Run statuses, manifest ✓/⚠ cells, upload preflight, and nonzero exit codes all route through them — replacing the hand-picked"green"/"red"literals that were duplicated across six screens.Dense controls — inputs and buttons flatten to one row (Button's tall borders zeroed in every state). A focused input shows a
wide $primaryleft edge with padding swapped so text never shifts. Top bars realigned for the new heights; modals got denser for free.Chrome — thin 1-cell scrollbars tinted
$primary(brighten on hover/focus), muted-bold DataTable headers, andrender.pydetail panes moved onto the Tokyo Night palette hexes so contract/entry views match the rest of the app.Hatched empty states — a
.paneltagged.emptyswaps its table/log for a hatched, centered placeholder with the relevant keybind accented: Run before a run, Evidence with no runs / no files, Upload before an upload, Manifest when empty or unloaded. Cleared automatically when content arrives (the run console also clears on therun_startevent so the synthetic-event test path behaves identically).Verification
Notes for review
-primary,-error) are flattened; a futurevariant="success"button would regain tall borders.STATUS_TONEcovers all eight runner statuses; unknown words fall back to muted text rather than crashing.docs/demo/tui.gifstill shows the old design and needs regenerating (left out to keep this reviewable).🤖 Generated with Claude Code