Files
Joshua KingandClaude Opus 5 d9ed1898b9 Add the Extrudex Design System v3 bundle
Tokens (light + dark, neumorphism, 54/54 WCAG AA contrast pairs), the
self-hosted JetBrains Mono fonts, and interactive mockups of every screen
across three iterations. Iteration 3 is final: phone, tablet and desktop
tiers, device preview, and "empty spool weight" terminology. The build
scripts regenerate the screens byte-identically from source.

Implementation is tracked in Maestro feature UI Refresh - V3.0
(224b72a1-8d84-4970-97ea-5dafa4d8ea3b).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-19 11:31:50 -04:00

9.9 KiB
Raw Permalink Blame History

Extrudex Soft UI (Design System v3) proposal: summary

2026-09-18. This is a proposal only. Nothing was changed in the Extrudex repository (still clean at dev 321ce0d) or in CTXD. Nothing was deleted.

What I built and where it is

Everything is in ~/Design/extrudex-v3/.

File What it is
00-understanding.md Step 1: every field on each existing screen, every stored printer field, the v2.0 palette, and how CTXD differs from the code
design-system-v3.css Step 2: the token set. v2.0 base kept, dark and light themes, neumorphism tokens (surfaces, raised and inset pairs, 4 intensity levels, radius scale), state tokens, reference components
design-system-v3.md Step 2: every changed or added token with its reason, the state matrix, the dark-mode approach, 2 alternative palettes, and contrast tables for both themes (54/54 pass, plus 9 more pairs)
fonts/ JetBrains Mono 400/500/700/800 woff2 (the same @fontsource 5.3.0 files the app ships) + OFL license
screens/01-dashboard.html New standalone Dashboard: stock tiles, running low (net + gross, tare unknown shown), net kg by material, recent prints with weight source and upper-bound duration marks, compact printer strip
screens/02-filament.html Inventory: working search and filters, table/cards toggle, the 5-part name, net remaining vs tare (+ source) vs gross, Edit, Delete with a confirmation dialog
screens/03-spool-form.html Add/Edit spool with a scenario switcher: 409 conflict, 400 field errors, tare unknown, add new, plus a control-state specimen
screens/04-printers.html Printers: stored fields only, a "dev today / dev + feature branch" data toggle, the MQTT dropped state (A1), and a Future, not built section
source/ Build inputs (build.py makes each screen self-contained with base64 fonts) and checks/table.py, which regenerates the contrast table

Every screen has a Light/Dark toggle (also ?theme=light or ?theme=dark in the URL), has no network dependencies, and was checked at 1440 px and 390 px in headless Chrome.

Decisions that go against DECISIONS.MD or the v2.0 rules

  1. Styling: "tokens verbatim… do not edit a token to suit a component." v3 changes the values of a few v2.0 semantic tokens (--surface-raised, --shadow-raised, --focus-ring, --radius-sm, --radius-md, --text-on-accent in light). This isn't editing a token to suit a component. It's a proposed new version of the design system, and each change has a reason in the .md. It still needs your call: adopting it means updating the guide at pages.ccl first and then copying it verbatim into theme.css, as the rule intends.
  2. v2.0 brand rules "0 radius" and "flat shadows" are overturned. Soft UI can't exist without them. --radius-none stays for tables and code.
  3. Primary buttons changed color, dark theme (#8f7ae0 → #a99af0), because v2.0's ink-on-accent is 4.32:1 and fails AA. That's a brand-color shift on the most visible control.
  4. CONTEXT scope: "printer status pages… deliberately out until daily use." The Printers screen was designed because you asked for it. Note that a printers view already exists on dev, embedded in Floor.

Things I followed even where the code has moved past the docs:

  • Weight source is shown with 4 values (typed, sliced, recalled, unknown). DECISIONS.MD lists 3. The schema adds sliced and says recalled is no longer written.
  • Tare origin: the code (resolveTare in types.ts) falls back to a brand tare, labeled as a guess. DECISIONS.MD says tare comes "from spool_type, never from brand". The mockups never show a brand-derived tare.

Open questions

  1. Adopt or reject the two brand-rule changes (radius, shadows) and the lighter primary-button violet? Everything else depends on this.
  2. Floor → Dashboard + Printers. The proposal splits today's Floor into a stock-first Dashboard and a separate Printers page. Is that the direction, or should Floor stay as one page restyled?
  3. Weight source in GET /api/prints. It's stored but not served, so the Dashboard needs a small API change. OK to add it?
  4. recalled vs sliced. Should DECISIONS.MD be updated to say sliced exists and recalled is legacy? That's a CTXD edit, which I didn't make.
  5. Brand-tare fallback. Code and DECISIONS.MD disagree. Which one is right?
  6. Serial display. I masked the middle of serials (01P09A••••••4821). Show in full, masked, or hidden?
  7. "Tare unknown only" filter is new on the Filament page (it helps work down the "weigh it yourself" list). Keep it?
  8. The 409 "reapply my change" button assumes the client can diff the fields you changed against the new version. Today the form only shows the server's message. Do you want that behavior, or just "reload"?
  9. Alternative palettes A (warm graphite) and B (slate/teal) are in the .md. Do you want either mocked up?
  10. CTXD is out of date (Dashboard.tsx, no auth, Bambu only, the design system URL). Should someone refresh CONTEXT.MD? I made no CTXD edits.

Proposed Maestro tasks (titles only, smallest first; not created)

  1. Add weight_source to the GET /api/prints response
  2. Add v3 warning and info status tokens to theme.css
  3. Add the --border-control token and apply it to buttons, inputs and selects
  4. Replace the v2.0 focus ring with the v3 2px offset outline
  5. Fix primary-button text contrast (4.32:1 → 6.14:1)
  6. Show a weight-source chip on each print row
  7. Show an upper-bound mark on durations with connection gaps
  8. Show "gaps not counted" on prints with null connection_gaps
  9. Show tare, tare source and gross weight on the Filament table and cards
  10. Show "tare unknown" (never 0) wherever gross weight is derived
  11. Add the "Tare unknown only" filter to Filament
  12. Map spool 400 messages to their fields in SpoolForm
  13. Add the 5-part name preview to SpoolForm
  14. Add the net/tare/gross scale diagram to SpoolForm
  15. Replace the SpoolForm 409 footer text with a conflict panel and reload actions
  16. Add a light theme with a stored per-browser toggle
  17. Add the neumorphism shadow and radius tokens (after the brand decision)
  18. Restyle buttons, inputs and chips with the v3 state matrix
  19. Split Floor into a stock-first Dashboard and a Printers page
  20. Render the connection-lost state on printer cards (after the printer-connections feature merges)
  21. Publish Design System v3 to pages.ccl and re-sync theme.css verbatim

Iteration 2 (2026-09-18): navigation, data display and interaction

Everything is in iteration-2/. Iteration 1 above is unchanged, for comparison.

File What it is
iteration-2/00-ux-review.md 12 findings from iteration 1, the navigation model, flows ranked by frequency, interaction patterns, data-display rules, accessibility notes, 5 new questions, 18 more task titles
iteration-2/screens/index.html Start here. Flow map plus 8 guided flows that deep-link into each state
iteration-2/screens/01-dashboard.html "Needs you" queue first, then stock tiles, recent prints by day, printers and running low. Everything clickable
iteration-2/screens/02-filament.html Saved views with counts, Stock/Weights columns, grouping, sortable headers, row ⋯ menu, weigh session
iteration-2/screens/03-prints.html New. Needs attention (inline suggestions, grams, batch) · All · Running · Archived
iteration-2/screens/04-printers.html Urgency order, jump strip, holder fill + Load, stale "last known" state, dev/feature toggle
iteration-2/source/ data.js (one shared model), app.js (shell, palette, panel, toasts), components.css, pages, build.py

What's shared across every page: the spool/print/load panel (deep-linked, Esc/back closes, j/k steps), the ⌘K palette, nav badges for work waiting, toasts after each save, a freshness indicator with an offline state, and a phone tab bar with a floating Add button.

Corrected from iteration 1: it showed AMS "slot" positions, which the database doesn't store. Iteration 2 shows holder fill ("3 / 4") instead.

Verified: every page and panel state loads with no console errors in headless Chrome, at 1440 px and 390 px, in both themes. There are no network requests, and no new colors (the v3 contrast table still applies).


Iteration 3 (2026-09-18): remaining screens, tablet and phone

Everything is in iteration-3/. Iterations 1 and 2 are unchanged.

  • Start here: iteration-3/screens/index.html (flow map, 14 flows) and iteration-3/screens/devices.html (every screen in live phone 390 × 844, tablet 820 × 1180 and 1180 × 820 frames).
  • New screens: 05 Lists · 06 Labels · 07 Access · 08 System · 09 Scan: holder · 10 Scan: spool, plus Add/Edit printer, Manage holders and Remove printer panels on Printers.
  • Your answers from iteration-2/00-ux-review.md, applied: Change spool (with real grams-returned wording), lightest-first weigh sessions with location, Filament badge for unverified tares, and load/attribute palette commands.
  • Responsive: three tiers (phone < 700, tablet 700–1180 with a compact rail, desktop). Spec in iteration-3/00-changes.md §4.
  • Findings: list names are case-sensitive in the schema; audit log, low-filament report and machine tokens have APIs but no screens on dev.
  • Verified: all 12 pages and 18 panel/palette states load with no console errors; checked at 390, 820 and 1180 px and desktop, in both themes. No network requests, no new colors.

Terminology update (2026-09-18): iteration 3's UI now says "empty spool weight" everywhere it said "tare" (verified: no rendered text, tooltip, label or placeholder contains "tare"). Code and API names (tare_grams etc.) are unchanged. See iteration-3/00-changes.md §1b. Open item: GLOSSARY.MD in CTXD still uses "Tare".