Skip to content

feat(deck): rounded key tiles, larger icons, regular-weight titles with letter spacing - #585

Merged
danshapiro merged 10 commits into
mainfrom
feat/deck-visual-tweaks
Jul 30, 2026
Merged

feat(deck): rounded key tiles, larger icons, regular-weight titles with letter spacing#585
danshapiro merged 10 commits into
mainfrom
feat/deck-visual-tweaks

Conversation

@danshapiro

Copy link
Copy Markdown
Owner

Visual refinement of the Stream Deck key rendering (follow-up to #576/#580). Client-only, rendering-only — no changes to sorting, state classification, interaction, settings, or transports.

  • Key titles now render in regular-weight (400) Inter with a slight letter-spacing; the fit/truncation math accounts for the spacing so titles never overflow.
  • Tile icons (repo icons, agent pane icons, letter avatars, +N badge) are ~50% larger, with re-fitted slot layout keeping 1/2/3-icon cases centered and clear of the title banner on all key sizes.
  • Every key type (tab tiles in both styles, pager, action layer, empty keys) now renders inside a rounded rectangle with pure black outside — keys read as rounded tiles on the hardware. All borders/rings (bar-top green border, white active ring, classic status rings) follow the rounded shape.
  • ensureRoundRect guard: browsers without canvas roundRect get square corners instead of a crash.

Quality: TDD throughout; plan review passed round 1; independent delta review passed round 1 with zero blockers (reviewer re-derived all frame/ring/clip geometry); headless-Chromium probes verified letter-spacing measurement behavior and pixel-diffed the rounded clipping; 241 relevant tests + full check/lint/typecheck green. Minor deferred polish noted in review logs (1px content inset at the two largest key sizes).

danshapiro and others added 10 commits July 29, 2026 20:19
- Task 1: add ensureRoundRect guard at both real-ctx seams (roundRect is
  Baseline 2023; VirtualDeckPanel hands the renderer a real ctx in any
  browser, so an unguarded call could throw uncaught pre-Firefox 112 /
  Safari 16) and note letterSpacing needs no guard (inert expando)
- Task 2: correct the empty-kind claim (kind 'empty' was never rendered
  in the test file; the frame test introduces the first render)
- Task 3: drawRing has 8 call sites, not 7
- Record empirical Chromium verification of the trailing-inclusive
  letterSpacing measureText model and the classic-preview clip probe
  (no legible content loss) in new Load-Bearing Validation Notes
…lance in harness

- Add ctx.restore() after switch closes in renderKey (src/deck/tile-renderer.ts)
  before getImageData return. This balances the ctx.save() called by beginKeyFrame.

- Update recordingCtx test harness to track save/restore calls:
  * Count saves and restores in local counters
  * Expose getSaves() and getRestores() functions via return object
  * Pass counters through to renderTab helper

- Update 'rounded key frame' test:
  * Extract getSaves/getRestores from test results
  * Assert saves === restores (balanced) for each key kind
  * Assert saves >= 1 (save/restore actually occurred)

This prevents regressions where ctx.save/restore mismatch could silently break.

🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier)

Co-Authored-By: Amplifier <[email protected]>
- Remove dead 'captured' variable assignment in the 'every key kind paints...' test (line 278-286)
- Fix recordingCtx harness: clear both pendingArc and pendingRound after all operations (fill/clip/stroke) to prevent stale pending records from leaking into subsequent captures
- Add length assertions before .every() calls in iconLayout test to guard against vacuous passes on empty arrays

Generated with Amplifier

Co-Authored-By: Amplifier <[email protected]>
@danshapiro
danshapiro merged commit c5e9fda into main Jul 30, 2026
3 checks passed
@danshapiro
danshapiro deleted the feat/deck-visual-tweaks branch July 31, 2026 03:09
pull Bot pushed a commit to HinchK/freshell that referenced this pull request Jul 31, 2026
…erminal identity (danshapiro#584), deck visual tweaks (danshapiro#585)

Conflict resolution (crates/freshell-freshagent/src/terminal_tabs.rs,
settle_gated_create): kept BOTH sides, ordered spawn-gate acquire (D-C-R,
ours) BEFORE the PIN2 claude prespawn durable binding (theirs) — a gate
rejection must not leave a stale prespawn ledger row, so the durable write
happens only after a permit is secured.

Post-merge semantic fix: pinned FRESHELL_CODEX_MANAGED_LAUNCH=0 in
rest_locator_identity.rs::rest_created_codex_pane_binds_identity_row_and_ledger
(new in danshapiro#584, written pre-flip; exercises the plain-CLI codex path with a
sleeper fake that cannot serve an app-server sidecar).

Pre-merge analysis recorded no redundancy between the danshapiro#582 review-hardening
(d9705fd) and the remote delta; danshapiro#586 touches resume-resolve-contract.ts,
not session-contract.ts — CrashTrace work composes cleanly.

Generated with Amplifier

Co-Authored-By: Amplifier <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant