-
Notifications
You must be signed in to change notification settings - Fork 108
Improved Transactions Page For Smaller Screens #182
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
1. Switches from set number cols (12), to dynamic per group of transactions.
- This should fix spacing issues on smaller screens, and is more dynamic than changing pre-set widths.
2. Enabled categories to show on all views regarless of screen size.
3. Adjusted spacing between searchbar, headerbar & transactions to remove blank space on smaller screens.
4. Adjusted tick boxes, where higher = more left to signify weight.
5. Adjusted merchant images to fill the transaction row correctly.
6. Tidied automatch button & shortened to 'A/M' on smaller screens to increase usable space for transaction name.
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the WalkthroughMultiple ERB view updates: adjusted spacing, grid/flex layout and responsive visibility for category badges, entry groups, transactions list and transaction partials; added Changes
Sequence Diagram(s)sequenceDiagram
%% Styling note: primary interactions only
autonumber
actor User
participant Browser
participant Server
participant View as Transactions View (index/_transaction/_badge)
User->>Browser: Request /transactions
Browser->>Server: GET /transactions
Server-->>Browser: Rendered HTML (index + entry frames)
Browser->>View: Render page components
View->>View: Render entry frames → inner transaction frames
View->>View: Render badge (with icon_only when applicable)
Browser-->>User: Display updated layout (responsive badges, revised header, grouped controls)
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@alessiocappa, I know you where working on a similar fix, are you able to please have a look at this solution and let me know your thoughts. |
|
@ByteBard11 yes, I tried to fix the spacing to align the amounts in the table, but I was also thinking about adding the categories on the transaction page, so thanks for this big improvement! I did a quick test, not sure if I did something wrong, but in my case the transaction names are almost unreadable due to the category label:
The screen is from the Chrome inspect, using an iPhone 12 Pro. I tested it also on my device (iPhone 15) and I see it in the same way. I think the category takes a bit too much space, especially if the name is too long. |
cd98ab2 to
66709f5
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
app/views/categories/_badge.html.erb(1 hunks)app/views/categories/_menu.html.erb(1 hunks)app/views/transactions/_transaction.html.erb(5 hunks)app/views/transactions/_transaction_category.html.erb(1 hunks)
🧰 Additional context used
📓 Path-based instructions (15)
app/views/**/*.erb
📄 CodeRabbit inference engine (AGENTS.md)
app/views/**/*.erb: Keep heavy logic out of ERB views; prefer helpers/components instead
ERB templates are linted by erb-lint per .erb_lint.ymlAlways use the icon helper (icon) for icons; never call lucide_icon directly
Files:
app/views/transactions/_transaction_category.html.erbapp/views/categories/_badge.html.erbapp/views/transactions/_transaction.html.erbapp/views/categories/_menu.html.erb
app/views/**/*.html.*
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
app/views/**/*.html.*: Use partials only for simple, context-specific, mostly static HTML content.
Prefer semantic HTML; use Turbo Frames where possible instead of client-side solutions.
Use query params for state, not localStorage or sessionStorage.
Always perform server-side formatting for currencies, numbers, and dates.
Files:
app/views/transactions/_transaction_category.html.erbapp/views/categories/_badge.html.erbapp/views/transactions/_transaction.html.erbapp/views/categories/_menu.html.erb
**/*.{html,erb,slim,js,jsx,ts,tsx,css,scss}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Always use functional design tokens (e.g., text-primary, bg-container) from the design system; do not use raw colors or ad-hoc classes.
Files:
app/views/transactions/_transaction_category.html.erbapp/views/categories/_badge.html.erbapp/views/transactions/_transaction.html.erbapp/views/categories/_menu.html.erb
**/app/**/*.erb
📄 CodeRabbit inference engine (CLAUDE.md)
Always use the
iconhelper for icons in templates; never uselucide_icondirectly.
Files:
app/views/transactions/_transaction_category.html.erbapp/views/categories/_badge.html.erbapp/views/transactions/_transaction.html.erbapp/views/categories/_menu.html.erb
**/app/views/**/*.erb
📄 CodeRabbit inference engine (CLAUDE.md)
**/app/views/**/*.erb: Keep domain logic OUT of view templates; logic belongs in component files, not templates.
Use partials only for primarily static, simple HTML with minimal logic, and only when not likely to be reused.
Prefer native HTML over JavaScript components for UI elements (e.g., use<dialog>,<details><summary>).
Leverage Turbo frames for page sections over client-side JavaScript solutions.
Use query params (not localStorage/sessions) for client state management.
Perform server-side formatting for currencies, numbers, and dates in templates.
Files:
app/views/transactions/_transaction_category.html.erbapp/views/categories/_badge.html.erbapp/views/transactions/_transaction.html.erbapp/views/categories/_menu.html.erb
**/app/**/*.{rb,erb,js,css}
📄 CodeRabbit inference engine (CLAUDE.md)
Push Rails to its limits before adding new dependencies; a strong technical/business reason is required for new dependencies.
Files:
app/views/transactions/_transaction_category.html.erbapp/views/categories/_badge.html.erbapp/views/transactions/_transaction.html.erbapp/views/categories/_menu.html.erb
**/*.{rb,erb,haml,slim}
📄 CodeRabbit inference engine (.cursor/rules/general-rules.mdc)
**/*.{rb,erb,haml,slim}: UseCurrent.userfor the current user; do not usecurrent_user
UseCurrent.familyfor the current family; do not usecurrent_family
Ignore i18n methods; hardcode strings in English for now (do not useI18n.t,t, or similar)
Files:
app/views/transactions/_transaction_category.html.erbapp/views/categories/_badge.html.erbapp/views/transactions/_transaction.html.erbapp/views/categories/_menu.html.erb
app/views/**/*.html.erb
📄 CodeRabbit inference engine (.cursor/rules/project-conventions.mdc)
app/views/**/*.html.erb: Prefer native HTML elements (e.g., ,) over JS-based components
Leverage Turbo frames to break up pages instead of JS-driven client-side solutions
Prefer native client-side form validation when possible
Files:
app/views/transactions/_transaction_category.html.erbapp/views/categories/_badge.html.erbapp/views/transactions/_transaction.html.erbapp/views/categories/_menu.html.erb
app/{models,controllers,views}/**/*.{rb,erb}
📄 CodeRabbit inference engine (.cursor/rules/project-conventions.mdc)
Avoid N+1 queries
Files:
app/views/transactions/_transaction_category.html.erbapp/views/categories/_badge.html.erbapp/views/transactions/_transaction.html.erbapp/views/categories/_menu.html.erb
{app/javascript/controllers/**/*.{js,ts},app/views/**/*.erb,app/components/**/*.erb}
📄 CodeRabbit inference engine (.cursor/rules/stimulus_conventions.mdc)
Use declarative Stimulus actions in ERB (data-action) instead of imperative event listeners in controller lifecycle (e.g., avoid addEventListener in connect); controllers should just respond to actions
Files:
app/views/transactions/_transaction_category.html.erbapp/views/categories/_badge.html.erbapp/views/transactions/_transaction.html.erbapp/views/categories/_menu.html.erb
{app/components/**/*.{js,ts,erb},app/views/**/*.erb}
📄 CodeRabbit inference engine (.cursor/rules/stimulus_conventions.mdc)
Component-scoped Stimulus controllers in app/components must be used only within their component views, not in app/views
Files:
app/views/transactions/_transaction_category.html.erbapp/views/categories/_badge.html.erbapp/views/transactions/_transaction.html.erbapp/views/categories/_menu.html.erb
{app/views/**,app/helpers/**,app/javascript/controllers/**}
📄 CodeRabbit inference engine (.cursor/rules/ui-ux-design-guidelines.mdc)
{app/views/**,app/helpers/**,app/javascript/controllers/**}: Style UI using TailwindCSS v4.x with the custom design system defined in app/assets/tailwind/maybe-design-system.css
Always start by referencing app/assets/tailwind/maybe-design-system.css to understand available primitives, functional tokens, and component tokens before styling
Prefer functional tokens from the design system over raw Tailwind values (e.g., use text-primary, bg-container, border border-primary instead of text-white, bg-white, border-gray-200)
Files:
app/views/transactions/_transaction_category.html.erbapp/views/categories/_badge.html.erbapp/views/transactions/_transaction.html.erbapp/views/categories/_menu.html.erb
{app/views/**,app/helpers/**}
📄 CodeRabbit inference engine (.cursor/rules/ui-ux-design-guidelines.mdc)
Always generate semantic HTML
Files:
app/views/transactions/_transaction_category.html.erbapp/views/categories/_badge.html.erbapp/views/transactions/_transaction.html.erbapp/views/categories/_menu.html.erb
{app/views,app/components}/**/*.html.erb
📄 CodeRabbit inference engine (.cursor/rules/view_conventions.mdc)
{app/views,app/components}/**/*.html.erb: Keep domain logic out of ERB templates; compute values in component/controller code and reference them in the template
Integrate Stimulus declaratively in ERB: templates declare data-controller/data-action; controllers respond to those declarations
Pass data from Rails to Stimulus via data-*-value attributes, not inline JavaScript
Files:
app/views/transactions/_transaction_category.html.erbapp/views/categories/_badge.html.erbapp/views/transactions/_transaction.html.erbapp/views/categories/_menu.html.erb
app/views/**/_*.html.erb
📄 CodeRabbit inference engine (.cursor/rules/view_conventions.mdc)
Name partials with a leading underscore (e.g., _trend_change.html.erb, _form_errors.html.erb)
Files:
app/views/transactions/_transaction_category.html.erbapp/views/categories/_badge.html.erbapp/views/transactions/_transaction.html.erbapp/views/categories/_menu.html.erb
🧠 Learnings (1)
📚 Learning: 2025-09-23T22:21:06.637Z
Learnt from: CR
PR: we-promise/sure#0
File: .cursor/rules/project-conventions.mdc:0-0
Timestamp: 2025-09-23T22:21:06.637Z
Learning: Applies to app/views/layouts/application.html.erb : Use Turbo frames in the application layout to load controller actions as demonstrated
Applied to files:
app/views/transactions/_transaction.html.erb
🔇 Additional comments (9)
app/views/transactions/_transaction_category.html.erb (1)
7-7: LGTM! Consistent icon_only implementation.The addition of
icon_only: truefor non-categorizable transfers is consistent with the broader icon_only pattern being introduced across category badges to improve mobile layouts.app/views/categories/_menu.html.erb (1)
5-5: LGTM! Icon-only badge for menu button.Rendering the category badge with
icon_only: trueinside the menu button is appropriate for a compact, icon-based menu trigger.app/views/categories/_badge.html.erb (3)
1-1: Good addition of icon_only parameter.The
icon_onlylocal with a default offalseprovides backward compatibility while enabling the new icon-only display mode.
5-10: Inline styles necessary for dynamic colors.The inline
styleattributes usingcolor-mixare necessary for dynamic category colors and cannot be replaced with design system tokens in this case.
14-14: Verify screen reader accessibility for hidden category names.When
icon_onlyis true, the category name is visually hidden on small screens (hidden sm:inline). While the element remains in the DOM for screen readers, verify that this provides adequate context for users relying on assistive technologies, especially when the icon alone may not convey sufficient meaning.Consider adding an
aria-labelattribute to the badge container whenicon_onlyis true to ensure screen readers announce the full category name:<span class="inline-flex items-center gap-1 text-sm font-medium rounded-full px-2 py-1 border truncate focus-visible:outline-none focus-visible:ring-0 <%= 'min-w-[2.5rem] justify-center' if icon_only %>" + <%= "aria-label=\"#{category.name}\"" if icon_only %> style="background-color: color-mix(in oklab, <%= category.color %> 10%, transparent); border-color: color-mix(in oklab, <%= category.color %> 10%, transparent); color: <%= category.color %>;" >app/views/transactions/_transaction.html.erb (4)
20-20: Good fix for truncation behavior.Changing from
max-w-fulltomin-w-0 w-fullcorrectly enables text truncation in flex/grid containers by overriding the default minimum width behavior.
28-34: Icon size increased for better visibility.Changing the fallback icon from
size: "sm"tosize: "md"improves visibility and aligns better with the merchant logo dimensions (w-6 h-6).
98-100: Category rendering for larger screens looks good.The category is appropriately hidden on small screens and displayed in a right-aligned container on larger screens, providing clear visual hierarchy.
22-26: No N+1 query issue exists—merchant association is already preloaded.The transactions controller's
indexmethod already includes:merchantin the eager-load statement via.includes(:merchant, ...), so accessingtransaction.merchant&.logo_urlin the view will not trigger additional queries.
| <%= turbo_frame_tag dom_id(entry), class: "contents" do %> | ||
| <%= turbo_frame_tag dom_id(transaction), | ||
| class: "grid grid-cols-[subgrid] col-span-full items-center gap-x-2 md:gap-x-4 text-primary text-sm font-medium p-4 lg:p-4 #{entry.excluded ? 'opacity-50 text-gray-400' : ''}" do %> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
Grid subgrid implementation looks correct.
The use of grid-cols-[subgrid] with col-span-full is appropriate for inheriting the parent grid structure while spanning all columns. Ensure the parent container rendering this partial is configured as a grid.
Verify that the parent container (likely in app/views/transactions/index.html.erb or app/views/entries/_entry_group.html.erb) is properly configured as a CSS grid for the subgrid to work correctly:
🏁 Script executed:
#!/bin/bash
# Search for parent containers that render the transaction partial
rg -A 5 -B 5 'render.*transaction' app/views/transactions/index.html.erb app/views/entries/Length of output: 1252
I need to see more context around where the transaction partial is actually rendered to verify the parent grid structure is correct.
I need to see the complete grid structure to confirm the transaction partial is properly nested within the grid container.
---
🏁 Script executed:
```shell
#!/bin/bash
# Get more context around the grid and transaction rendering
rg -A 20 'grid grid-cols-\[1fr_auto\]' app/views/transactions/index.html.erb
Length of output: 77
🏁 Script executed:
#!/bin/bash
# Search for the complete grid structure and transaction rendering
rg -n 'grid grid-cols' app/views/transactions/index.html.erbLength of output: 153
🏁 Script executed:
#!/bin/bash
# Find where transaction partial is rendered
rg -n 'render.*_transaction' app/views/Length of output: 309
🏁 Script executed:
#!/bin/bash
# Get complete context around the grid at line 61
sed -n '55,85p' app/views/transactions/index.html.erbLength of output: 1090
🏁 Script executed:
#!/bin/bash
# Search for transaction rendering in entries directory
rg -n 'transaction' app/views/entries/ -t erbLength of output: 214
🏁 Script executed:
#!/bin/bash
# Find the entries partial
rg -n 'app/views/entries/_entry' app/views/entries/Length of output: 0
🏁 Script executed:
#!/bin/bash
# Check if entry template uses or renders transaction
cat app/views/entries/_entry.html.erbLength of output: 206
---
🏁 Script executed:
```shell
#!/bin/bash
# Get the complete _transaction.html.erb file
cat app/views/transactions/_transaction.html.erb
Length of output: 4620
Remove grid-cols-[subgrid] and restructure the transaction row layout.
The parent container for transaction items is space-y-4 in app/views/transactions/index.html.erb (line 77), which is a vertical flex stack, not a grid. The grid-cols-[subgrid] at line 6 of _transaction.html.erb cannot work because subgrid only functions when the parent is a grid container with defined grid-template-columns. The header grid (grid-cols-[1fr_auto]) is separate and does not apply to the entries below it.
Either restructure the entries container as a grid matching the header columns, or use a different layout approach for transaction rows that doesn't depend on subgrid.
🤖 Prompt for AI Agents
In app/views/transactions/_transaction.html.erb around lines 5 to 7, the
transaction row is using "grid-cols-[subgrid]" which is invalid because its
parent is a vertical stack (space-y-4) not a grid; remove "grid-cols-[subgrid]"
and restructure the row to not rely on subgrid — either change the row container
to a simple two-column grid like "grid grid-cols-[1fr_auto] items-center ..." to
match the header, or use a flex layout "flex justify-between items-center ..."
(and keep the existing spacing/padding and the conditional opacity class). If
you choose to keep subgrid, instead make the parent a grid with matching
grid-template-columns in the index view so subgrid will work.
| <div class="hidden sm:block flex-shrink-0"> | ||
| <% if transaction.merchant&.logo_url.present? %> | ||
| <%= image_tag transaction.merchant.logo_url, | ||
| class: "w-6 h-6 rounded-full", | ||
| loading: "lazy" %> | ||
| <% else %> | ||
| <%= render DS::FilledIcon.new( | ||
| variant: :text, | ||
| text: entry.name, | ||
| size: "md", | ||
| rounded: true | ||
| ) %> | ||
| <% end %> | ||
| </div> | ||
|
|
||
| <div class="sm:hidden flex-shrink-0"> | ||
| <%= render "transactions/transaction_category", transaction: transaction %> | ||
| </div> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider alternative layout to address mobile readability concerns.
While the responsive visibility logic is technically correct, this implementation places the category badge horizontally before the transaction name on small screens (lines 37-39), which aligns with the feedback from alessiocappa that "transaction names are almost unreadable due to the category label taking too much space."
Even with icon_only: true, the badge still consumes horizontal space (minimum 2.5rem plus padding from line 6 of _badge.html.erb), leaving limited room for the transaction name in the same flex row on narrow screens.
alessiocappa suggested an alternative: place the category text below the transaction name (similar to how account names appear on desktop) and use a category icon/color indicator on the left. This vertical stacking approach would free up horizontal space for the transaction name.
Consider refactoring the small-screen layout to stack vertically:
<!-- Merchant icon/category indicator on left -->
<div class="flex-shrink-0">
<% if transaction.merchant&.logo_url.present? %>
<%= image_tag transaction.merchant.logo_url, class: "w-6 h-6 rounded-full", loading: "lazy" %>
<% else %>
<!-- Category color indicator or icon instead of transaction initial -->
<div class="w-6 h-6 rounded-full flex items-center justify-center" style="background-color: <%= transaction.category&.color %>">
<%= icon transaction.category&.lucide_icon, size: "sm", color: "white" if transaction.category&.lucide_icon.present? %>
</div>
<% end %>
</div>
<!-- Transaction name and category stacked vertically -->
<div class="truncate">
<div class="space-y-0.5">
<div class="truncate">
<%= link_to(...) %> <!-- Transaction name with full width -->
</div>
<div class="text-xs text-secondary sm:hidden">
<%= transaction.category&.name %> <!-- Category name below on mobile -->
</div>
</div>
</div>🤖 Prompt for AI Agents
In app/views/transactions/_transaction.html.erb around lines 22 to 39, the
small-screen layout places the category badge before the transaction name which
consumes horizontal space and makes names hard to read; refactor the mobile
markup so the left-side space shows a compact merchant icon or small category
color/icon indicator, and move the category label to a stacked line below the
transaction name (use a vertical layout: left compact indicator + a truncate
container with the transaction name on top and the category name in smaller text
beneath, only visible on sm:hidden). Ensure classes preserve truncation for the
name, keep merchant logo handling unchanged, replace the badge with a fixed 24px
(w-6 h-6) indicator on mobile, and remove the horizontal badge rendering inside
the same flex row.
|
@alessiocappa |
@ByteBard11, I completely missed this update. 😄 I was also trying to improve the transactions and activities pages, this is what I got:
To summarise:
Please let me know your thoughts. If you’d like to review or test these changes, I can open another pull request. |
Signed-off-by: Juan José Mata <[email protected]>
|
Thoughts, @DeathCamel58? Since you also have #283 about this same issue ... |
|
@alessiocappa looks great! Would be happy to test. Does the overlapping merchant logo cause any touch issues? And any ideas how we can handle the automatch transfer button better? |
|
Personally I think stuffing those two logo/category icon together are touch-target nightmares. They solve the visual problem elegantly, but create another (bigger?) one? |
I haven’t encountered any touch-related issues due to the merchant logo. If you tap the category icon you’ll see the list of categories and can change it if necessary. Regarding the automatch transfer, I liked your idea of using a shorter "A/M" label and I’ve implemented it in the same way. Here’s the branch for testing: https://github.com/alessiocappa/sure/tree/FT-TransactionsPageImprovements Please let me know if you’d like me to create a pull request or if you’d prefer to integrate the changes into this one. I hope I haven’t missed anything as I’ve had to combine several commits. 😄 |
| border-color: color-mix(in oklab, <%= category.color %> 10%, transparent); | ||
| color: <%= category.color %>;"> | ||
| <span | ||
| class="inline-flex items-center gap-1 text-sm font-medium rounded-full px-2 py-1 border truncate focus-visible:outline-none focus-visible:ring-0 <%= 'min-w-[2.5rem] justify-center' if icon_only %>" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| <p class="justify-self-end">amount</p> | ||
| </div> | ||
|
|
||
| <% if @transactions.any? %> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| <div class="grow overflow-y-auto"> | ||
| <div class="grid-cols-12 bg-container-inset rounded-xl px-5 py-3 text-xs uppercase font-medium text-secondary items-center mb-4 hidden md:grid"> | ||
| <div class="pl-0.5 col-span-8 flex items-center gap-4"> | ||
| <div class="grid grid-cols-[1fr_auto] bg-container-inset rounded-xl px-3 py-3 text-xs uppercase font-medium text-secondary items-center mb-4"> | ||
| <div class="pl-0.5 flex items-center gap-4"> | ||
| <%= check_box_tag "selection_entry", | ||
| class: "checkbox checkbox--light", | ||
| data: { action: "bulk-select#togglePageSelection" } %> | ||
| class: "checkbox checkbox--light", | ||
| data: { action: "bulk-select#togglePageSelection" } %> | ||
| <p>transaction</p> | ||
| </div> | ||
|
|
||
| <p class="col-span-2">category</p> | ||
| <p class="col-span-2 justify-self-end">amount</p> | ||
| <p class="justify-self-end">amount</p> | ||
| </div> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we wrap this with a <% if @transactions.any? %> like the one on line 72? That would keep the title bar here from rendering if there aren't any transactions.
| data-bulk-select-singular-label-value="<%= t(".transaction") %>" | ||
| data-bulk-select-plural-label-value="<%= t(".transactions") %>" | ||
| class="flex flex-col bg-container rounded-xl shadow-border-xs p-4"> | ||
| class="flex flex-col bg-container rounded-xl shadow-border-xs p-4 space-y-4"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
Don't hate me for taking #283 first, guys. 🙏 Just simpler and a net win while we redesign things a little here. |









This pull request improves mobile usability on the transactions page, with a focus on smaller screens.
Changes
Replaced fixed column counts (e.g. grid-cols-12) with dynamic grid columns per transaction group, so column widths adapt to content.
Categories are now always visible across all screen sizes (previously hidden on smaller breakpoints).
Reduced excess spacing between the search bar, header bar, and transactions list for better use of space on small devices.
Updated checkbox alignment, so “heavier” checkboxes appear further left to convey hierarchy.
Adjusted merchant image sizing to align consistently and fill the transaction row height properly.
Refined the auto‑match button:
Addresses:
#166, #181
Together, these changes make the transactions page more consistent, space‑efficient, and readable across all screen sizes, with a particular improvement in usability on smaller devices.
Old vs New:
EXTRA SMALL SCREEN (iPhone SE selected in chrome inspect):

SMALL SCREEN:

LARGE SCREEN (Limited Changes):

Summary by CodeRabbit