Skip to content

feat(ui): screen refresh redesign — home, edit, settings, and window management#190

Open
ScottMorris wants to merge 35 commits intomainfrom
redesign/ui-implementation
Open

feat(ui): screen refresh redesign — home, edit, settings, and window management#190
ScottMorris wants to merge 35 commits intomainfrom
redesign/ui-implementation

Conversation

@ScottMorris
Copy link
Copy Markdown
Contributor

Summary

Full UI redesign of the Threshold desktop app across 6 phases plus iterative polish:

  • Home screen: Next alarm banner with gradient fill and single-line countdown, accent rails on alarm cards, pull-to-refresh on mobile, centred Add Alarm button with independently positioned settings gear
  • Edit screen: Side-by-side window pickers, tighter vertical spacing, scrollable form constrained to 700px, CSS class overrides for time picker sizing
  • Settings screen: Desktop nav rail with four section panels, mobile layout unchanged
  • Window management: Locked to 760×680 (resizable: false), position-only persistence via tauri-plugin-window-state, TitleBar buttons driven dynamically from Tauri capabilities
  • Accessibility: Reduced motion support on SwipeToDeleteRow, proper ARIA labels, theme-aware palette roles throughout
  • Foundation: Shared UI tokens (uiTokens.ts), alarm card style helpers, design docs and v4 mockups

Key files changed

  • NextAlarmBanner.tsx — new component, gradient banner with countdown
  • PullToRefresh.tsx — new component, mobile pull-to-refresh gesture
  • TitleBar.tsx — capability-driven minimize/maximize buttons
  • EditAlarm.tsx — layout overhaul for 760×680 window
  • Home.tsx — footer restructure, banner integration
  • Settings.tsx — desktop nav rail with section panels
  • tauri.conf.json / capabilities — window lock, permission cleanup
  • lib.rs — position-only state persistence

Test plan

  • Verify desktop window opens at 760×680 and position persists across restarts
  • Verify maximize button is hidden in TitleBar
  • Verify Home screen banner shows correct countdown and gradient style
  • Verify Add Alarm button is centred with gear to the right in footer
  • Verify Edit screen scrolls when content exceeds viewport (sound picker visible)
  • Verify Window mode pickers display side-by-side and fit within form width
  • Verify Settings nav rail works on desktop, flat list on mobile
  • Verify all screens render correctly in light and dark mode across themes
  • Verify pull-to-refresh works on mobile
  • Verify reduced motion preference disables swipe animations

🤖 Generated with Claude Code

ScottMorris and others added 30 commits March 8, 2026 12:27
**What changed**
- add temporary redesign exploration assets for screen language
- add a draft screen redesign update plan with linked mobile and desktop SVG concepts
- include sample screenshots used as baseline references for alarm copy and layout

**Why**
- start a local design-history branch so we can iterate safely
- capture decisions around theming, platform behaviour, and scope before implementation
- preserve a reviewable snapshot for comparing future refinements
**What changed**
- add `REDESIGN_JOURNEY_LOG.md` to track redesign progress
- include a reusable entry template for ongoing updates
- seed initial entries for branch setup and log introduction

**Why**
- keep a clear historical record of design decisions and updates
- provide ready-to-use presenter notes for each milestone
- support iterative local commits during the redesign journey
**What changed**
- update the redesign update plan to reflect desktop constraints:
  - borderless window with custom title bar
  - keep existing desktop bottom add button style
  - place Settings gear to the right of the desktop add button
- clarify that Material You is Android-only and not a desktop feature
- add `docs/ui/specs/` baseline specification set based on current code behaviour:
  - `README.md`
  - `ui-taxonomy.md`
  - `screen-spec-template.md`
  - `home-spec.md`
  - `edit-alarm-spec.md`
  - `settings-spec.md`
- add a journey log entry documenting this milestone and speaker script
- update `docs/ui/README.md` to include the new specs index

**Why**
- keep redesign planning aligned with the real desktop implementation
- establish a reusable specification taxonomy to make future UI rework easier
- preserve a clear, presentable change history as the redesign evolves
**What changed**
- upgrade UI taxonomy with a dedicated `Platform Concept Layer`
- update the screen spec template to include:
  - `Platform Concept Model` sections (Shared, Mobile, Desktop)
  - `Platform Mapping Matrix` for cross-platform expression
- refactor baseline screen specs (`Home`, `Edit/New Alarm`, `Settings`) to use concept-first platform modelling
- update specs README usage guidance for the new platform concept structure
- add redesign journey log entry and speaker script for this milestone

**Why**
- make mobile and desktop differences first-class documentation contracts
- preserve concept intent across future layout and styling rework
- improve implementation and review clarity by separating shared vs platform-specific behaviour
**What changed**
- add a dedicated redesign asset versioning policy section to `SCREEN_REDESIGN_UPDATE_PLAN.md`
- document decision to keep iterative SVG and redesign doc churn tracked
- add a journey log entry with presenter script for this process decision

**Why**
- preserve full redesign chronology as part of the project story
- keep design evolution auditable and reviewable over time
- avoid losing context from exploratory iterations
**What changed**
- add `docs/ui-mockups/temp-screen-redesigns/proposed-v2/` SVG set for the next redesign review pass
- update Home desktop SVG direction to reflect desktop constraints:
  - borderless custom title bar context
  - existing bottom add button style
  - Settings gear in the bottom action zone to the right of add
- update Settings mobile and desktop SVGs toward flatter list-first layouts
- repoint `SCREEN_REDESIGN_UPDATE_PLAN.md` image references from `proposed-v1` to `proposed-v2`
- add a redesign journey log entry documenting the v2 iteration and presenter script

**Why**
- align visual exploration with the latest desktop and settings direction decisions
- reduce visual noise in settings concepts before implementation begins
- preserve chronological redesign evolution with explicit versioned mockup sets
…tion

**What changed**
- add `docs/ui-mockups/temp-screen-redesigns/proposed-v3/` SVG set
- update Home desktop mockup to:
  - avoid literal screenshot replication
  - preserve bottom add button style
  - place Settings gear beside the add action zone
- lock mobile Settings concept close to current structure, without line-heavy treatment
- restore desktop Settings left-category/right-detail composition inspired by v1
- update redesign plan references and notes to `proposed-v3`
- append redesign journey log entry with v3 rationale and speaker script

**Why**
- keep inspiration and design direction separate for clearer intent
- align mockups with latest feedback while preserving visual comparison consistency
- continue chronological tracking of redesign pivots (`v1 -> v2 -> v3`)
…cisions

- produce proposed-v4/threshold-settings-mobile-v4.svg: faithful rendering of
  current Settings.tsx in deep-night dark palette, including all rows and
  developer icon button colour mapping (primary/secondary/info)
- update plan section 5: mobile Settings locked to current structure + scrolling
- replace open questions with settled decisions (pull-to-refresh, developer
  section always expanded, desktop title bar ownership, add button style,
  theming-in-mockups policy)
- add one remaining open question: Next alarm banner data source
- append journey log entry recording this review session

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
nextTrigger is already present on AlarmRecord — no new state needed.
Document the derivation pattern and mark section 12 as settled.
Add section 13 noting implementation plan as the next step.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…isions

- add proposed-v4 SVGs for all six screens: Home mobile/desktop,
  Edit mobile/desktop, Settings mobile/desktop
- wider phone shell (560px), correct TitleBar.tsx 32px bar across all
  desktop mockups, consistent deep-night dark comparison palette
- Home mobile: pull-to-refresh replaces toolbar refresh icon, Next alarm
  banner, accent rail, overflow menu only
- Home desktop: full-width ADD ALARM button matching code, Settings gear
  moves into footer zone beside add button
- Edit mobile/desktop: correct toolbar and footer patterns per platform
- Settings desktop: left nav rail concept with right detail panel,
  Material You row greyed as desktop-unavailable
- update plan section 4 image references to proposed-v4 across all screens

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- home desktop: button now centred maxWidth 400 matching code, disabled
  cards show time + label only (no "Disabled" status text)
- edit desktop: Gnome-style circular day selector buttons preserved,
  custom desktop TimePicker kept, footer Cancel/Save corrected
- add threshold-window-desktop-v4.svg: OS-level view showing app window
  floating on desktop background with wider AR, TitleBar.tsx chrome,
  window drop shadow, and OS taskbar tab with active window indicator
- update plan section 4 to include window context mockup reference

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- add threshold-edit-window-mobile-v4.svg: Window tab active, two MUI
  TimePicker fields (Start Window / End Window) stacked vertically,
  helper text explaining random ring behaviour, preview card showing
  start–end range and active days
- add threshold-edit-window-desktop-v4.svg: Window tab active, Start
  and End pickers side by side using custom desktop TimePicker.tsx,
  helper text below pickers, same footer Cancel/Save pattern
- update plan section 4 to show Fixed Time and Window mode separately
  for both mobile and desktop

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Covers 6 phases: foundation tokens, Home screen (accent rail, next alarm
banner, pull-to-refresh, desktop footer gear), Edit/New Alarm visual
refresh, Settings verification, desktop polish, and QA/accessibility pass.

Includes file change summary, per-phase acceptance checks, and 4 open
questions to resolve before execution begins.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- produce IMPLEMENTATION_PLAN.md: 6-phase engineering plan with
  file-level change sets and acceptance checks per phase
- settle all open questions: accent rail colour, NextAlarmBanner
  background, PullToRefresh spinner, desktop Settings nav rail
- upgrade phase 4 desktop Settings to full nav rail + detail panel
  layout (left rail: background.default surface; right panel:
  background.paper surface; both with 14px border-radius card language)
- set desktop window target size to 760 × 680 in phase 1 plan
- update journey log with this session's decisions and rationale

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- number all entries 01–14 for easy reference
- restore chronological order (v4 full set, desktop corrections, Window
  mode mockups were out of sequence)
- add three missing entries: #9 NextAlarmBanner data source confirmed,
  #11 desktop v4 corrections + OS window context view, #12 Window alarm
  mode mockups for Edit screen

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Move all screen-refresh-2026 artefacts out of temp-screen-redesigns/
into docs/ui/redesigns/screen-refresh-2026/ with calmer filenames:

- IMPLEMENTATION_PLAN.md → plan.md
- SCREEN_REDESIGN_UPDATE_PLAN.md → design-decisions.md
- REDESIGN_JOURNEY_LOG.md → journey-log.md
- AGENT_PROMPT.md → agent-prompt.md
- proposed-v4/ → mockups/v4/
- proposed-v1/v2/v3 and exploration assets → mockups/archive/

Update all internal path references across plan.md, design-decisions.md,
and agent-prompt.md. Add implementation log requirement to agent prompt.
Log entry 15 added to journey-log.md.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Change desktop window from 450×800 to 760×680
- Create uiTokens.ts with card, banner, and footer constants
- Create alarmCardStyles.ts with reusable sx helpers for alarm cards
- Create implementation-log.md for tracking redesign progress

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…-refresh

- Add left accent rail to AlarmItem (primary.main for enabled, action.disabled for disabled)
- Create NextAlarmBanner component showing countdown to next alarm
- Create PullToRefresh component for mobile with reduced-motion support
- Remove toolbar refresh icon on mobile (replaced by pull-to-refresh)
- Move desktop Settings gear from top-right to footer beside Add Alarm button
- Reduce desktop container mt from 8 to 0 (RootLayout provides 32px)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Apply borderRadius from UI tokens to time picker containers
- Theme label TextField with rounded corners
- Theme sound picker Paper with divider border and background.paper
- Fix DaySelector hardcoded rgba border with theme-aware divider colour

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Replace single-column desktop Settings with two-column layout
- Left nav rail (220px) with Appearance, Alarm Settings, General, Developer
- Right detail panel renders only the active section content
- Active nav item highlighted with primary.main background
- Material You toggle visible on desktop with "Android only" label and disabled state
- Mobile Settings layout completely unchanged
- Preserve licence header

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Simplify redundant mt ternary in Home.tsx desktop container
- Verified footer clearance (pb: 10 = 80px clears 56px footer)
- Verified NextAlarmBanner inside scrollable container
- Verified Settings gear and Add button don't overlap in footer flex layout

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Skip slide-off animation and call delete immediately when reduced motion preferred
- Use instant transition for snap-back instead of spring animation
- Verified touch targets (FAB 56px, Switch 38px), contrast ratios, and
  gesture orthogonality (PullToRefresh vertical vs SwipeToDelete horizontal)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
After swiping an alarm card and releasing (snap-back), isDrag.current
stayed true, preventing subsequent taps from firing onClick to edit
the alarm. Now reset to false after the snap-back animation completes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Set resizable: false in tauri.conf.json (maximizable was already false)
- Restrict window-state plugin to StateFlags::POSITION so the persisted
  state file can never override the configured window dimensions

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…abilities

- Query isMaximizable/isMinimizable from Tauri on mount; conditionally render
  buttons in all three platform control variants (Mac, Windows, Linux)
- Restore isMaximized tracking and toggleMaximize wiring (was commented out)
- Context menu items likewise gated on capability flags
- Add WindowMaximizeIcon and WindowRestoreIcon imports (now actually used)
- Remove allow-maximize, allow-unmaximize, allow-toggle-maximize from
  default.json (maximizable: false in config; permissions no longer needed)
- Remove allow-set-size from desktop.json (window-state plugin no longer
  restores size since StateFlags::POSITION change)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
win.unmaximize() in App.tsx showWindow was a legacy guard against the
window-state plugin restoring a maximized state. Now that the plugin is
restricted to StateFlags::POSITION, the window can never be restored as
maximized, making the call dead code — and it was hitting a permission
error since allow-unmaximize was removed from capabilities.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…esizable windows

- App.tsx: only call win.center() when outerPosition is (0,0) so the
  window-state plugin's restored position is not overwritten on every launch
- TitleBar: gate maximize button on isMaximizable && isResizable — isMaximizable()
  returns true on some platforms even when maximizable:false in config, but
  isResizable() reliably reflects the resizable:false setting

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ScottMorris and others added 5 commits March 8, 2026 19:46
…acing

- Window mode: desktop pickers now side by side (flex row) instead of
  stacked vertically, matching the v4 mockup
- Reduced vertical spacing throughout (Stack spacing 3→2, margins 3→2)
- Removed Paper p:3 desktop padding that added unnecessary inset
- Widened desktop container to use full window width (px:4)
- All fields now visible without scrolling in the 760×680 window

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Set desktop form max-width to 700px (matching v4 mockup) instead of
  full-width stretch
- Remove height: 100% from Container so content overflows and scrolls
  naturally, making the Sound picker accessible below the fixed footer

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove intermediate flexGrow wrapper Box that prevented scroll overflow
- Scale side-by-side window pickers to 85% so they centre within each
  flex half without overflowing
- Sound picker now accessible via scroll below the fixed footer

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove flex column from outer scroll Box (was preventing overflow)
- Replace transform: scale(0.85) on window pickers with direct CSS
  overrides on picker class names — eliminates phantom padding from
  transform not reducing layout size
- Sound picker now scrollable past the fixed footer

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… layout

Update NextAlarmBanner with horizontal gradient fill and single-line
"Next alarm in Xh Ym · Scheduled: TIME" format matching v4 mockup.
Centre the Add Alarm button independently of the settings gear in the
footer. Add top padding so the banner isn't flush against the TitleBar.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@ScottMorris
Copy link
Copy Markdown
Contributor Author

@codex review

@ScottMorris ScottMorris added enhancement New feature or request documentation Improvements or additions to documentation desktop Desktop platform ui User interface tauri Tauri platform or plugin-specific work labels Mar 11, 2026
Copy link
Copy Markdown
Contributor Author

@ScottMorris ScottMorris left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Quick review pass completed.

  • Build check passes (pnpm -C apps/threshold build).
  • Please remove debug logging from apps/threshold/src/screens/Home.tsx ([DELETE_DEBUG] in handleDelete) before merge.
  • Please add the required source header ((c) Copyright 2026 Liminal HQ, Scott Morris + SPDX-License-Identifier: Apache-2.0 OR MIT) to touched source files that currently do not include it, per AGENTS.md.
  • Minor behaviour note: NextAlarmBanner computes Date.now() once per render, so countdown text can go stale without another state change; consider a minute tick if live countdown is expected.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1badfadf0c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +84 to +85
touchAction: 'pan-x',
overflowY: 'auto',
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Use vertical pan touch-action for pull-to-refresh list

On mobile Home, this wrapper is the scroll container (overflowY: 'auto') but touchAction: 'pan-x' disables native vertical panning, so once the alarm list is taller than the viewport users cannot scroll down to reach lower alarms. This makes part of the primary list inaccessible in a common scenario (many alarms). Use a touch-action that permits vertical scrolling and keep the pull-to-refresh threshold logic in JS.

Useful? React with 👍 / 👎.

Comment on lines +17 to +18
const now = Date.now();
const nextAlarm = alarms
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Refresh next-alarm countdown while Home stays open

The countdown is derived from Date.now() during render but there is no interval/ticking state, so the banner text becomes stale if the user leaves Home open (for example, after 10 minutes it still shows the original "in Xh Ym" value until another state change rerenders). Since this UI is presented as a live countdown, it should be recomputed periodically.

Useful? React with 👍 / 👎.

@@ -0,0 +1,60 @@
import React from 'react';
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Add required licence header to new TypeScript files

The repo guideline in /workspace/threshold/AGENTS.md ("Licence and Copyright") requires each source file to begin with the summary/copyright/SPDX header, but this new file starts directly with imports. That introduces a compliance regression in this commit (and the same pattern appears in other newly added TS files), so the required header block should be added at the top.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

desktop Desktop platform documentation Improvements or additions to documentation enhancement New feature or request tauri Tauri platform or plugin-specific work ui User interface

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant