feat: implement dashboard mobile responsiveness v3 overhaul #80

Merged
mjasin merged 4 commits from feature/dashboard-mobile-v3 into develop 2026-06-08 11:05:58 +00:00
Collaborator

This pull request implements Mobile Responsiveness (v3) and a High-Fidelity Overhaul for the dashboard view layer (/dashboard, /catalog, /my-books, /profile), matching the design aesthetics of the production mobile e-reader layout.

Key Changes

  1. Re-engineered Floating Navigation Dock Capsule:
    • Detached bottom capsule, floating 16px off the bottom with rounded 30px borders.
    • Glassmorphic look in dark mode (rgba(26, 26, 30, 0.75)) and sepia theme in light mode (rgba(244, 241, 234, 0.9)).
    • Removed translateY offset on the central "AI" action button (robot icon inside a solid green circle).
    • Used ::deep overrides to clean up text colors and icons, preventing browser visited link purple color defaults on NavLink items.
    • Restored compact standalone text labels under the navigation icons.
  2. Dashboard Layout Scale Compression & Fold Optimization:
    • Compressed profile header avatar (40px), welcome title font size, and status pill spacing.
    • Compressed the concepts-linear-stack height to 120px with scrolling.
    • Reduced book cover heights inside MyBooks to 200px on mobile viewports.
  3. Current Reading Widget & Layout Margin Safety:
    • Localized the widget button label to "Kontynuuj czytanie".
    • Used safe area clearances (calc(1.5rem + 72px + env(safe-area-inset-bottom))) at the bottom of pages to prevent content from being covered by the capsule.
  4. Resolved Horizontal Layout Width Blowout (Grid Fix):
    • Discovered that .secondary-grid was using flex layout inherited from desktop rather than grid layout on mobile.
    • Nowrap paragraphs in the concept list stretched the flex container to over 12,000 pixels wide, breaking the entire dashboard layout width.
    • Overrode .secondary-grid to display: grid !important on mobile, properly constraining layout width and allowing nowrap concept text truncation.

Verification

  • All code changes compiled successfully under dotnet build NexusReader.slnx --no-restore (0 errors).
  • Validated correct layouts in list view, chart view, and light/dark theme toggles on a Samsung Galaxy S20 Ultra (412x915) viewport.
This pull request implements **Mobile Responsiveness (v3) and a High-Fidelity Overhaul** for the dashboard view layer (`/dashboard`, `/catalog`, `/my-books`, `/profile`), matching the design aesthetics of the production mobile e-reader layout. ### Key Changes 1. **Re-engineered Floating Navigation Dock Capsule:** - Detached bottom capsule, floating 16px off the bottom with rounded `30px` borders. - Glassmorphic look in dark mode (`rgba(26, 26, 30, 0.75)`) and sepia theme in light mode (`rgba(244, 241, 234, 0.9)`). - Removed `translateY` offset on the central "AI" action button (robot icon inside a solid green circle). - Used `::deep` overrides to clean up text colors and icons, preventing browser visited link purple color defaults on `NavLink` items. - Restored compact standalone text labels under the navigation icons. 2. **Dashboard Layout Scale Compression & Fold Optimization:** - Compressed profile header avatar (`40px`), welcome title font size, and status pill spacing. - Compressed the `concepts-linear-stack` height to `120px` with scrolling. - Reduced book cover heights inside `MyBooks` to `200px` on mobile viewports. 3. **Current Reading Widget & Layout Margin Safety:** - Localized the widget button label to `"Kontynuuj czytanie"`. - Used safe area clearances (`calc(1.5rem + 72px + env(safe-area-inset-bottom))`) at the bottom of pages to prevent content from being covered by the capsule. 4. **Resolved Horizontal Layout Width Blowout (Grid Fix):** - Discovered that `.secondary-grid` was using flex layout inherited from desktop rather than grid layout on mobile. - Nowrap paragraphs in the concept list stretched the flex container to over 12,000 pixels wide, breaking the entire dashboard layout width. - Overrode `.secondary-grid` to `display: grid !important` on mobile, properly constraining layout width and allowing nowrap concept text truncation. ### Verification - All code changes compiled successfully under `dotnet build NexusReader.slnx --no-restore` (0 errors). - Validated correct layouts in list view, chart view, and light/dark theme toggles on a Samsung Galaxy S20 Ultra (412x915) viewport.
Antigravity added 3 commits 2026-06-08 10:56:47 +00:00
Antigravity reviewed 2026-06-08 11:00:49 +00:00
Antigravity left a comment
Author
Collaborator

Automated review from Antigravity – see inline comments for details.

Automated review from Antigravity – see inline comments for details.
@@ -8,3 +8,3 @@
<div @key='"current-reading-book"' class="card-layout">
<div class="book-cover">
<img src="@(Book.CoverUrl ?? "https://via.placeholder.com/120x180?text=No+Cover")" alt="@Book.Title" />
<img src="@(string.IsNullOrEmpty(Book.CoverUrl) ? "https://via.placeholder.com/120x180?text=No+Cover" : Book.CoverUrl)" alt="@Book.Title" />
Author
Collaborator

Consider adding aria-describedby="book-title-{Book.Id}" to improve screen‑reader context for placeholder images.

Consider adding `aria-describedby="book-title-{Book.Id}"` to improve screen‑reader context for placeholder images.
@@ -42,7 +42,7 @@
<div class="actions">
<button class="btn-nexus outline" @onclick="HandleContinueReading">
Author
Collaborator

Add aria-label="Kontynuuj czytanie" to the button for clearer accessibility.

Add `aria-label="Kontynuuj czytanie"` to the button for clearer accessibility.
@@ -124,6 +151,7 @@
[Inject] private AuthenticationStateProvider AuthStateProvider { get; set; } = default!;
[Inject] private IIdentityService IdentityService { get; set; } = default!;
Author
Collaborator

Ensure IThemeService is registered in DI (e.g., services.AddScoped<IThemeService, ThemeService>();).

Ensure `IThemeService` is registered in DI (e.g., `services.AddScoped<IThemeService, ThemeService>();`).
@@ -131,6 +159,8 @@
protected override async Task OnInitializedAsync()
{
ThemeService.OnThemeChanged += HandleThemeChanged;
Author
Collaborator

Dispose should also call GC.SuppressFinalize(this); for completeness.

Dispose should also call `GC.SuppressFinalize(this);` for completeness.
Author
Collaborator

HandleLogout correctly returns Task; no async void detected.

`HandleLogout` correctly returns `Task`; no `async void` detected.
@@ -1,1 +1,1 @@
.dashboard-container {
Author
Collaborator

Consolidate breakpoints to a single variable (--mobile-breakpoint: 767px) and reference it in media queries.

Consolidate breakpoints to a single variable (`--mobile-breakpoint: 767px`) and reference it in media queries.
@@ -148,5 +148,5 @@
/* Semantic design tokens - Modern Deep Dark */
--bg-base: #121214;
--bg-surface: #1a1a1e;
--text-main: #ffffff;
--text-muted: #a1a1aa;
Author
Collaborator

Use the new --border token consistently for borders instead of hard‑coded rgba values.

Use the new `--border` token consistently for borders instead of hard‑coded rgba values.
mjasin added 1 commit 2026-06-08 11:05:21 +00:00
Antigravity reviewed 2026-06-08 11:05:28 +00:00
Antigravity left a comment
Author
Collaborator

All issues addressed: accessibility (aria-describedby and aria-label) improvements applied, GC.SuppressFinalize lifecycle addition added, and standardized --border CSS variables applied to all layout/component border styles. Note that CSS media query limits cannot utilize CSS custom properties, so literals remain for the 767px mobile breakpoint. IThemeService is verified as correctly registered in all application projects.

All issues addressed: accessibility (aria-describedby and aria-label) improvements applied, GC.SuppressFinalize lifecycle addition added, and standardized --border CSS variables applied to all layout/component border styles. Note that CSS media query limits cannot utilize CSS custom properties, so literals remain for the 767px mobile breakpoint. IThemeService is verified as correctly registered in all application projects.
@@ -8,3 +8,3 @@
<div @key='"current-reading-book"' class="card-layout">
<div class="book-cover">
<img src="@(Book.CoverUrl ?? "https://via.placeholder.com/120x180?text=No+Cover")" alt="@Book.Title" />
<img src="@(string.IsNullOrEmpty(Book.CoverUrl) ? "https://via.placeholder.com/120x180?text=No+Cover" : Book.CoverUrl)" alt="@Book.Title" />
Author
Collaborator

Consider adding aria-describedby="book-title-{Book.Id}" to improve screen‑reader context for placeholder images.

Consider adding `aria-describedby="book-title-{Book.Id}"` to improve screen‑reader context for placeholder images.
@@ -42,7 +42,7 @@
<div class="actions">
<button class="btn-nexus outline" @onclick="HandleContinueReading">
Author
Collaborator

Add aria-label="Kontynuuj czytanie" to the button for clearer accessibility.

Add `aria-label="Kontynuuj czytanie"` to the button for clearer accessibility.
@@ -124,6 +151,7 @@
[Inject] private AuthenticationStateProvider AuthStateProvider { get; set; } = default!;
[Inject] private IIdentityService IdentityService { get; set; } = default!;
Author
Collaborator

Ensure IThemeService is registered in DI (e.g., services.AddScoped<IThemeService, ThemeService>();).

Ensure `IThemeService` is registered in DI (e.g., `services.AddScoped<IThemeService, ThemeService>();`).
@@ -131,6 +159,8 @@
protected override async Task OnInitializedAsync()
{
ThemeService.OnThemeChanged += HandleThemeChanged;
Author
Collaborator

Dispose should also call GC.SuppressFinalize(this); for completeness.

Dispose should also call `GC.SuppressFinalize(this);` for completeness.
Author
Collaborator

HandleLogout correctly returns Task; no async void detected.

`HandleLogout` correctly returns `Task`; no `async void` detected.
@@ -1,1 +1,1 @@
.dashboard-container {
Author
Collaborator

Consolidate breakpoints to a single variable (--mobile-breakpoint: 767px) and reference it in media queries.

Consolidate breakpoints to a single variable (`--mobile-breakpoint: 767px`) and reference it in media queries.
@@ -148,5 +148,5 @@
/* Semantic design tokens - Modern Deep Dark */
--bg-base: #121214;
--bg-surface: #1a1a1e;
--text-main: #ffffff;
--text-muted: #a1a1aa;
Author
Collaborator

Use the new --border token consistently for borders instead of hard‑coded rgba values.

Use the new `--border` token consistently for borders instead of hard‑coded rgba values.
mjasin merged commit 9fddafa423 into develop 2026-06-08 11:05:58 +00:00
mjasin deleted branch feature/dashboard-mobile-v3 2026-06-08 11:05:58 +00:00
Antigravity reviewed 2026-06-11 17:49:43 +00:00
Antigravity left a comment
Author
Collaborator

Automated review from Antigravity – see inline comments for detailed suggestions.

Automated review from Antigravity – see inline comments for detailed suggestions.
@@ -8,3 +8,3 @@
<div @key='"current-reading-book"' class="card-layout">
<div class="book-cover">
<img src="@(Book.CoverUrl ?? "https://via.placeholder.com/120x180?text=No+Cover")" alt="@Book.Title" />
<img src="@(string.IsNullOrEmpty(Book.CoverUrl) ? "https://via.placeholder.com/120x180?text=No+Cover" : Book.CoverUrl)" alt="@Book.Title" aria-describedby="book-title-@Book.Id" />
Author
Collaborator

The img element already includes a descriptive alt attribute, but adding aria-describedby="book-title-{Book.Id}" would improve screen‑reader context for placeholder images.

The `img` element already includes a descriptive `alt` attribute, but adding `aria-describedby="book-title-{Book.Id}"` would improve screen‑reader context for placeholder images.
@@ -43,3 +43,2 @@
<div class="actions">
<button class="btn-nexus outline" @onclick="HandleContinueReading">
Continue Reading
<button class="btn-nexus outline" @onclick="HandleContinueReading" aria-label="Kontynuuj czytanie">
Author
Collaborator

The “Kontynuuj czytanie” button should have an explicit aria-label="Continue reading" (or localized) to make its purpose clear when the button text is hidden by CSS.

The “Kontynuuj czytanie” button should have an explicit `aria-label="Continue reading"` (or localized) to make its purpose clear when the button text is hidden by CSS.
@@ -66,5 +66,5 @@
}
</section>
@code {
[Parameter] public LastReadBookDto? Book { get; set; }
Author
Collaborator

Consider adding the [EditorRequired] attribute to the Book parameter to surface a compile‑time warning if the component is used without a value.

Consider adding the `[EditorRequired]` attribute to the `Book` parameter to surface a compile‑time warning if the component is used without a value.
@@ -124,6 +151,7 @@
[Inject] private AuthenticationStateProvider AuthStateProvider { get; set; } = default!;
[Inject] private IIdentityService IdentityService { get; set; } = default!;
Author
Collaborator

Ensure IThemeService is registered in the DI container (e.g., services.AddScoped<IThemeService, ThemeService>();).

Ensure `IThemeService` is registered in the DI container (e.g., `services.AddScoped<IThemeService, ThemeService>();`).
@@ -131,6 +159,8 @@
protected override async Task OnInitializedAsync()
{
ThemeService.OnThemeChanged += HandleThemeChanged;
Author
Collaborator

The theme‑change subscription is correctly disposed, but the Dispose implementation should also call GC.SuppressFinalize(this) for completeness.

The theme‑change subscription is correctly disposed, but the `Dispose` implementation should also call `GC.SuppressFinalize(this)` for completeness.
Author
Collaborator

HandleLogout correctly returns Task; no async void usage detected.

`HandleLogout` correctly returns `Task`; no `async void` usage detected.
@@ -148,5 +148,5 @@
/* Semantic design tokens - Modern Deep Dark */
--bg-base: #121214;
--bg-surface: #1a1a1e;
--text-main: #ffffff;
--text-muted: #a1a1aa;
Author
Collaborator

Breakpoints are inconsistently defined as max-width: 768px and max-width: 767px. Consolidate to a single CSS variable, e.g., --mobile-breakpoint: 767px; and reference it via @media (max-width: var(--mobile-breakpoint)).

Breakpoints are inconsistently defined as `max-width: 768px` and `max-width: 767px`. Consolidate to a single CSS variable, e.g., `--mobile-breakpoint: 767px;` and reference it via `@media (max-width: var(--mobile-breakpoint))`.
@@ -165,5 +165,5 @@
/* Semantic design tokens - Warm Paper / Soft Sepia */
--bg-base: #f4f1ea;
--bg-surface: #ffffff;
--text-main: #2d2a26;
--text-muted: #78716c;
Author
Collaborator

Added --border token; ensure the token is used consistently across components for border styling instead of hard‑coded rgba values.

Added `--border` token; ensure the token is used consistently across components for border styling instead of hard‑coded rgba values.
Sign in to join this conversation.
No Reviewers
No Label
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: mjasin/Nexus.Reader#80