Skip to content

[wip]feat/app UI refresh#233

Draft
swedishfrenchpress wants to merge 153 commits intomainfrom
feat/app-ui-refresh
Draft

[wip]feat/app UI refresh#233
swedishfrenchpress wants to merge 153 commits intomainfrom
feat/app-ui-refresh

Conversation

@swedishfrenchpress
Copy link
Copy Markdown
Collaborator

@swedishfrenchpress swedishfrenchpress commented Mar 23, 2026

WIP: App-wide UI refresh and design system standardization

This is a large draft PR focused on deep UI consistency and design system work across the app.

It combines and builds on top of two existing WIP PRs:

!OBS: The two PR referenced above are now out of date. This new branch introduces significant changes to the onboarding and withdraw screen.

From there this branch goes much further, working toward a unified design system with reusable components and consistent patterns across the entire app. The goal is to standardize typography, spacing, buttons, icons, empty states, toggles, section headers, row components, and nav bars so that every screen feels like it belongs to the same app.

Still actively working through this. Screens being touched include settings and all sub-screens (mints, mint details, webhooks, basket names, fiat currency, language, security & privacy, tips), the withdraw flow, add items, and the onboarding mint selection.

Key areas of work:

  • Building and enforcing a shared component library (rows, buttons, section headers, empty states, checkboxes, radio buttons, toggles)
  • Removing one-off custom styling in favor of component reuse
  • Standardizing typography sizes, weights, and colors across all screens
  • Consistent spacing and padding
  • Fixing light mode and dark mode across the board
  • Hero card treatment for key features (auto-withdraw, default mint, lightning mint)

This is a WIP, expect rough edges. Feedback welcome on direction.

swedishfrenchpress and others added 30 commits March 19, 2026 23:59
…iable hit testing, adjust row padding to maintain visual alignment
…e is off

The screen title showed "Auto-Withdraw" everywhere — renamed to "Withdraw"
in the nav bar and hero section across all locales (en/es/pt). Destination
and Trigger Settings sections were always visible even with the toggle off;
they are now fully hidden when disabled and smoothly animate in/out when
the toggle changes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… mode

The disabled state used a 20% opacity background color compounded with
0.5 alpha on the view, resulting in ~10% visibility. Fixed at the
component level so all screens using Widget.Button.Primary.Green benefit:

- Disabled bg now uses color_bg_tertiary (theme-aware solid color)
- Added text color selector with proper disabled state via color_text_tertiary
- Removed redundant alpha hacks from XML layouts and Kotlin code
- Removed inconsistent textStyle="bold" overrides on withdraw buttons

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Both withdraw layouts had an explicit color_bg_surface background on the
ScrollView, creating a visible seam against the nav bar. Other settings
screens (Security, Language, Currency) inherit color_bg_white from the
root with no ScrollView background override. Removed the override so
both withdraw screens match.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… spacing

The section headers (DESTINATION, TRIGGER SETTINGS, etc.) were using
inline styling with sans-serif (regular) and 0.03 letter spacing instead
of the shared Text.SectionHeader style used across 8+ other screens.
Refactored all 4 headers to use the shared style (sans-serif-medium,
0.05 letter spacing).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Both rows used the same lightning bolt icon. Auto-Withdraw now uses a
Material Design autorenew icon to convey automatic/repeating behavior,
and Withdraw Now uses the down arrow icon consistent with withdraw line
items in the activity screen.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ermark

Dialed back the gradient to barely-there warmth — light mode goes from
pure white to a ~3% orange tint, dark mode shifts subtly from default
surface to a faint ember tone. Removed the orange border stroke that
added to the warning-banner feel.

Added an oversized 120dp lightning bolt at the bottom-right corner at 6%
opacity as a brand watermark, clipped by the card edges.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Restructured layout so the bolt sits outside the padded content layer in
its own FrameLayout, flush against the card edges with -30dp margins and
clipped by the CardView corner radius. Added -15deg counter-clockwise
rotation, a vertical fade-out overlay (theme-aware, transparent to card
bg color), and bumped opacity from 6% to 12% for better visibility.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ation on toggle

Renamed hero card title from "Withdraw" to "Auto-Withdraw" across all
locales. Added a LightningStrikeView that plays an orange lightning bolt
animation when the Auto-Withdraw toggle is switched on — forked bolt
path with amber glow, no screen flash, 400ms duration, auto-removes
after completion.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Reduced to a single bolt, added smooth fade-in/hold/fade-out timing
(550ms), lowered overall opacity to 70%, thinned stroke widths and glow
radii for a subtler effect. Removed the lightning bolt icon from the
Lightning Address input label.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Removed clock icon from recent activity empty state, made history card,
auto-withdraw toggle card, and withdraw now card backgrounds transparent
so they blend seamlessly in both themes — matching the borderless
appearance already seen in light mode.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The mint profile icon wasn't reliably loading, showing a fallback
bitcoin icon instead. Removed the icon container entirely for a cleaner
layout — mint items now show just name, URL, balance, and chevron.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Removed gray card backgrounds from invoice and address components (both
XML and programmatic setCardBackgroundColor). Removed lightning bolt and
envelope icons from section headers. Fixed SEND TO and CASHU TOKEN
headers to use shared Text.SectionHeader style. Applied hero gradient to
the balance card. Made cashu input and token result cards transparent.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Simplified Lightning Invoice and Address sections to match the
Auto-Withdraw screen's clean pattern (label, input, helper text).
Replaced QR scan icon with a Scan Invoice secondary button. Renamed
SEND TO header to DESTINATION. Removed lightning bolt icon from mint
name. Added real-time fiat balance below the BTC amount using
BitcoinPriceWorker. Removed address helper text.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Fixed cashu tab spacing to match destination section by removing extra
marginTop. Renamed "Amount (sats)" to "Amount" across all locales.
Fixed scan icon on Scan Invoice button — switched from drawableStart
(ignored by MaterialButton) to app:icon with textStart gravity.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replaced the custom segment toggle (bg_input_pill container, 14sp medium
text, bg_segment_tab_selected) with the same implementation used on the
payment request screen (bg_button_secondary_pill container, 18sp bold
text, bg_button_primary_green selected state, 42dp height, 125dp min
width). Both screens now use identical toggle styling.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ling

Updated history item icons to match the Activity screen — up arrow in
gray circle with green checkmark badge overlay for completed entries.
Removed redundant "Sent" badge. Fixed badge clipping with clipChildren.
Changed Withdraw Now icon from orange to gray to match. Centered share
icon vertically with text content for cashu token entries.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Updated history item text to match the Withdraw screen's row styles
instead of the Activity screen's styles. Amount now uses 17sp medium
(matching row titles like "Withdraw Now"), detail lines use 14sp
secondary (matching row descriptions). This makes Recent Activity feel
typographically unified with the rest of the Withdraw screen.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Inner circle was 40dp while Auto-Withdraw and Withdraw Now rows use
44dp. Expanded inner circle to 44dp and outer container to 50dp so the
green checkmark badge can still overflow the edge cleanly.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Removed elevation shadow from both withdraw screen title bars and
replaced inline 20sp title styling with shared Text.Title style (17sp)
to match Security & Privacy and other screens. Fixed centering with
textAlignment. Updated mint selection bottom sheet fonts to match
withdraw screen typography — mint name uses medium 17sp, URL uses 14sp
secondary, balance uses medium instead of bold.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Switched to explicit MaterialButton with app:strokeColor/strokeWidth for
visible border, since the style's android:background was being ignored.
Added insetTop/insetBottom="0dp" to match Continue button's 52dp height.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Removed gray background (color_bg_surface on root and ScrollView),
removed title bar elevation/divider, replaced inline 20sp title with
Text.Title style, updated TO label to use Text.SectionHeader, made card
backgrounds transparent, matched button width to other screens (40dp
margin), removed word "actual" from fee note text across all locales.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The history section header and card were appearing statically while
other elements above them had a staggered reveal. Added both to the
entrance animation sequence at 250ms and 300ms delays, continuing the
top-to-bottom stagger pattern.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Hero card switches between orange/amber gradient (inactive) and green
gradient (active) when Auto-Withdraw is toggled, including the
lightning bolt watermark tint. Instant swap with no flicker. Replaced
blue accent color on the percentage slider and See All button with
Numo orange to match the app's brand palette.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Icon is now gray/neutral when off (matching Withdraw Now style) and
switches to green when toggled on. Changes in sync with the hero card
gradient transition.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- WithdrawLightningActivityTest: update tab color assertion to match
  branch change from color_text_primary to color_bg_white
- PaymentWebhookDispatcherTest: switch from runTest to runBlocking
  with Dispatchers.IO — runTest's TestCoroutineScheduler conflicts
  with MockWebServer's real I/O, causing UncaughtExceptionsBeforeTest

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@codecov
Copy link
Copy Markdown

codecov bot commented Mar 29, 2026

Welcome to Codecov 🎉

Once you merge this PR into your default branch, you're all set! Codecov will compare coverage reports and display results in all future pull requests.

Thanks for integrating Codecov - We've got you covered ☂️

swedishfrenchpress and others added 26 commits April 6, 2026 12:05
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…upgrade BouncyCastle, add DiffUtil to adapters

Replace all hardcoded hex colors in 26 XML layouts and 3 Kotlin custom views
(LightningStrikeView, NfcPaymentAnimationView, ThemeManager) with @color/
resource references for proper dark mode and theming support. Add 6 new
drawable-night variants for buttons, keypad, and input fields. Add DiffUtil
to 6 RecyclerView adapters for smoother list updates. Upgrade BouncyCastle
from jdk15on:1.70 to jdk18on:1.80 for security. Align version catalog with
actual AGP 9.1.0 and Kotlin 2.2.10.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The bottom sheet theme (Theme.Numo.BottomSheet) and its widget style
hardcoded #0A2540 (numo navy) for both the navigation bar and sheet
background. This looked jarring in dark mode where the activity
background is #0B1215 but the bottom sheet nav bar was navy.

Extract to color resources (color_bottom_sheet_bg, color_bottom_sheet_nav_bar)
with dark mode overrides that match dark_windowBackground. Also fix
MintSelectionBottomSheet and AddMintBottomSheet which hardcoded the
same navy color programmatically.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace two incompatible dialog systems (BottomSheetDialogFragment with
Light parent + color hacks, and DialogHelper using AlertDialog with
programmatic window positioning) with one consistent architecture.

- Change Theme.Numo.BottomSheet parent to DayNight for automatic dark
  mode support — no more color_bottom_sheet_bg/nav_bar hack colors
- Create ConfirmationBottomSheet and InputBottomSheet as proper
  BottomSheetDialogFragment subclasses
- Simplify DialogHelper to thin delegation layer (337 → 77 lines)
- Remove bg_bottom_sheet_dark.xml, Theme.Numo.BottomFloatingDialog,
  Theme.Numo.BottomSheetDialog, and all programmatic window gravity /
  decorView padding / blur animation code
- All bottom sheets now: full-width, 20dp top corners, surface color
  background, consistent in both light and dark mode

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ntrol

MaterialButton has default Material Design elevation that creates
visible shadows when a white button sits on a white background. Add
stateListAnimator="@null" and elevation="0dp" to 7 buttons across
5 layouts that were missing these attributes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…radle for AGP 9.1.0

Snapshot basketQuantities before mutation so DiffUtil detects the quantity
change and rebinds the ViewHolder, preventing stale UI and incorrect
basket quantities. Also upgrade Gradle wrapper to 9.3.1 and migrate
build config for AGP 9.x compatibility (embedded Kotlin, parcelize plugin).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…rawables

Fix 3 critical undefined color references (color_button_primary_green_text,
dark_surfaceColor, selector_lightning_mint) that would cause crashes. Introduce
primitive color layer and deduplicate tokens (#FFFFFF x10 → @color/white, etc.).
Add 53 missing dark mode color overrides for full DayNight coverage. Replace
hardcoded hex values with @color/ references across 55 drawables and ~1,489
hardcoded dimensions with @dimen/ tokens across 89 layouts. Apply existing
Text.* styles to 35 layouts (52 replacements). Delete 77 unused/duplicate
drawables and consolidate similar ones via tinting.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Finish applying the spacing scale from dimens.xml to all layout files:
- 28dp section gaps → @dimen/section_gap (13 files)
- 4dp → @dimen/space_xs, 6dp/10dp → nearest scale value (65+ occurrences)
- 20dp screen margins → @dimen/margin_screen_horizontal
- 40dp padding → @dimen/space_3xl or @dimen/space_2xl
- Fix row heights in about screen (60dp → @dimen/settings_item_height)
- Fix top bar padding in item list (4dp → @dimen/space_xs)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
These directories (.claude/skills, .kiro/skills, .roo/skills, etc.)
are local AI coding tool configuration and should never be committed.
Files remain on disk — only removed from git tracking.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…okens, standardized components

- Redesign payment failure screen: neutral background with contained red error
  indicator instead of full-screen red. Rewrites error copy to be specific and
  reassuring ("Payment not received", "No funds were transferred").
- Extract reusable dialog button styles (Confirm, Cancel, Destructive) and
  dialog typography styles (DialogTitle, DialogSubtitle) into styles.xml.
- Tokenize hardcoded corner radii: add radius_button (28dp) and row_subtitle_gap
  (2dp) to dimens.xml, replace 18 hardcoded instances across 13 layout files.
- Standardize all back button touch targets from 36dp to 48dp (icon_size_large)
  across 14 settings/detail screens.
- Fix non-uniform currency swap icon scaling on POS screen.
- Add brand-tinted section headers using navy color token.
- Improve empty state copy to teach the interface, not just acknowledge emptiness.
- Rewrite NFC error messages for merchant-friendly language (all 3 locales).
- Eliminate last hardcoded hex color in layouts.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Consolidate off-scale text sizes: 12sp → 11sp/13sp, 20sp → 18sp/22sp
  across 23 files to align with the defined type scale
- Standardize letter-spacing to the 5 defined values (-0.02, -0.012,
  -0.007, 0.03, 0.06), eliminating 13 non-standard instances
- Fix mint details page: match contact row styling to details rows
  (RowTitle labels, RowSubtitle values), replace inline typography with
  style references, use title case for contact labels instead of all-caps
- Remove all divider lines from details, contact, and action sections —
  section headers and row padding provide sufficient visual separation
- Standardize action row icon gap to row_icon_gap (14dp) matching Settings

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…olor

The top and bottom gradient fades on the "Add your first item" empty
state were fading to pure black (#000000) in dark mode, but the actual
background is #0B1215 (Numo Dark). This created a harsh visible border
where the gradient met the background. Changed both gradients to fade
to/from #0B1215 for a seamless blend.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…te duplicates

Replace 28 drawable files' hardcoded hex colors with semantic @color/ references
for proper dark mode support. Add missing tokens: status pill backgrounds, opacity
scale, hero gradient tints, dynamic island states, and badge backgrounds. Consolidate
duplicate dimension tokens (radius_l, card_corner_radius, card_elevation_small) and
expand elevation scale. Add color_brand_foreground as canonical alias for the
misleadingly-named color_primary_green tokens.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…act strings

Replace technical jargon with merchant-friendly language across EN/ES/PT:
- "Fiat" → "Local Currency", "GTIN" → "Barcode", "IDENTIFICATION" → "BARCODE & SKU"
- "INVENTORY" → "STOCK", "BASIC INFORMATION" → "DETAILS"
- VAT labels lead with "Tax" (universal term), parenthetical "(VAT)"
- "Total (incl. VAT)" → "Customer pays" — what merchants actually care about

Improve validation errors to be instructive rather than prohibitive:
- "Item name is required" → "Give your item a name"
- "Price must be positive" → "Price can't be negative"
- "Maximum 2 decimal places allowed" → "Use up to 2 decimal places"

Extract 11 hardcoded error strings from ItemFormValidator.kt into string
resources for localization. Extract "Edit Item" and "Delete Item" from
ItemEntryActivity.kt. Rewrite delete confirmation to state consequences
directly instead of "Are you sure?" pattern.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…e, Material price inputs

Restructure the add item form for faster item entry:
- Move Save to a fixed bottom bar (always reachable)
- Collapse Identification/Inventory behind "Additional Options" toggle
- Separate Cancel from Delete in edit mode
- Replace standalone $/₿ symbols with Material TextInputLayout (OutlinedBox)
  using prefixText/suffixText for cleaner price inputs
- Add inline validation, save confirmation toasts, state preservation
- Shrink oversized VAT rate input, replace stock camera icon,
  normalize label widths, fix semantic token misuse

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add expandedHintEnabled=false to TextInputLayout style so $, ₿,
USD, and sats labels are visible even when the field is unfocused.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace 6+ inconsistent input field styles (filled, borderless, varying
radii/strokes) with a single outlined TextInputLayout pattern across all
screens. Converts 13 input fields to Material OutlinedBox, updates seed
word inputs and inline fields with matching outlined drawables, and
deletes 7 unused legacy drawables.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Receipt page: remove oversized hero icon, reduce amount to Heading1 scale,
replace heavy gray card sections with flat rows matching mint details
pattern, add Details section (payment type, mint, transaction ID), hide
redundant breakdown for simple single-currency payments, move print
action to primary bottom button.

Transaction detail: replace inline typography with style tokens
(Text.AmountSubtitle), hardcoded 2dp with row_subtitle_gap, hardcoded
28dp with icon_size_xs, align top bar padding with content rows.

Both pages now use consistent section headers, flat row patterns, and
design tokens from the shared type/spacing system.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ty, i18n, polish

- Typography: replace 282 inline textSize/textStyle with textAppearance style refs (~30% → ~90% compliance), add Text.DisplayLarge (28sp) and Text.DisplayXL (32sp) to type scale
- Accessibility: add contentDescription or importantForAccessibility to 111 image elements (100% coverage), fix 8 touch targets below 48dp minimum
- i18n: extract ~50 hardcoded English strings to strings.xml with ES/PT translations, mark non-translatable strings
- Top bars: standardize padding to space_l (16dp) across 11 screens, fix android:tint → app:tint on 13 screens, zero out rogue elevation on 5 screens
- Buttons: apply canonical Widget.Numo.Button styles to 15 unstyled buttons, remove redundant inline attrs
- Dialogs: unify dialog_confirmation layout to match dialog_delete_confirmation pattern
- Elevation: replace 3 hardcoded values with @dimen/elevation_* tokens
- Layout: flatten nested LinearLayouts in 3 files (auto_withdraw, mints, mint_details)
- Settings: remove chevron forward disclosure icons from all settings rows

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Backlog

Development

Successfully merging this pull request may close these issues.

1 participant