Files
RolemasterDB/docs/tables_frontend_overhaul_implementation_plan.md

46 KiB

Tables Frontend Overhaul Implementation Plan

Purpose

This document turns the vision in tables_ux_bible.md into an execution plan for the current Blazor Web App frontend in src/RolemasterDb.App.

It is intentionally implementation-focused:

  • clear task breakdown
  • explicit acceptance criteria
  • concrete definition of done
  • reasonable implementation order
  • minimal churn to the existing backend and API contracts

Source Inputs

  • tables_ux_bible.md
  • current Blazor app shell and routes in src/RolemasterDb.App/Components
  • current API and view models in src/RolemasterDb.App/Features

Constraints

  • keep the current tech stack
  • keep the current backend and API contracts
  • keep the current critical-table data model and curation workflow as the domain foundation
  • treat route and UI changes as frontend/presentation refactors unless an additive backend endpoint is explicitly approved later
  • keep changes incremental and shippable by phase

Working Status

  • Branch: frontend/tables-overhaul
  • Last updated: 2026-03-21
  • Current focus: Phase 3
  • Document mode: living plan and progress log

Progress Log

Date Phase Status Notes
2026-03-21 Phase 0 Completed Created overhaul branch, audited the current frontend, and locked the route map, component boundaries, migration path, and shared-state ownership.
2026-03-21 P1.1 Completed Replaced the legacy token root with semantic background, surface, text, border, focus, shadow, and semantic accent ramps while keeping compatibility aliases for incremental migration.
2026-03-21 P1.2 Completed Switched the app to Fraunces, IBM Plex Sans, and IBM Plex Mono with distinct display, body, UI, and code font roles instead of one shared heading font.
2026-03-21 P1.3 Completed Added explicit light, dark, and system theme modes in the token layer and introduced a scoped ThemeState service for later shell controls.
2026-03-21 P1.4 Completed Added shared browser-storage wrappers, persisted theme mode in localStorage, and initialize/apply theme state from the layout on interactive render.
2026-03-21 P1.5 Completed Replaced the permanent sidebar layout with a sticky top app shell and mobile bottom navigation backed by dedicated shell components.
2026-03-21 P1.6 Completed Added explicit shell slots for nav, omnibox, shortcuts, and utilities; switched shell navigation to Play, Tables, Curation, and Tools; and wired the first live theme control into the shell.
2026-03-21 P1.7 Completed Added a shell-level skip link and tightened the top-level header, navigation, and main landmarks around the new shell structure.
2026-03-21 P1.8 Completed Introduced a cooler tooling emphasis for Tools, diagnostics, and API surfaces, and styled the Tools destination as distinct without splitting the shell.
2026-03-21 Post-P1 fix 1 Completed Closed the 768px-1023px navigation gap by adding a shell hamburger menu and drawer so primary navigation never disappears at tablet widths.
2026-03-21 Post-P1 fix 2 Completed Replaced the most visible light-only surface and control colors with theme-aware tokens so switching between Light, Dark, and System produces a clear visual change.
2026-03-21 Post-P1 fix 3 Completed Restored layout-level shell interactivity by rendering routed content in InteractiveServer mode, which re-enabled shell event handlers such as the hamburger menu and theme selector.
2026-03-21 Post-P1 fix 4 Completed Added early theme bootstrapping in App.razor and theme.js so the stored mode is applied before hydration and remains visible after refresh.
2026-03-21 P2.1 Completed Added canonical /tools/diagnostics and /tools/api routes with dedicated tooling page components, extracted the diagnostics and API content into shared tool components, and updated the Tools landing page to link to the new route structure.
2026-03-21 P2.2 Completed Replaced the old /diagnostics and /api pages with lightweight compatibility routes that reuse a shared redirect component, preserve query strings and fragments, and replace browser history while forwarding into the canonical Tools routes.
2026-03-21 P2.3 Completed Added a shared RecentTablesState service backed by browser storage, centralized the recents storage key, and started recording successful table visits from the Tables page so later omnibox and rail work has real shared data.
2026-03-21 P2.4 Completed Added a shared PinnedTablesState service with browser persistence, centralized the pin storage key, initialized pin state in the Tables page, and added a first live pin/unpin action plus pinned status chips so later omnibox and navigation work have real saved pins to consume.
2026-03-21 P2.5 Completed Added shared table-context URL types and a serializer, registered the serializer centrally, and started round-tripping table context through /tables and /tools/diagnostics so direct links restore the selected table and diagnostic cell context instead of relying only on local storage defaults.
2026-03-21 P2.6 Completed Replaced the dead shell omnibox trigger with a live drawer-backed omnibox foundation that loads critical tables on demand, filters table search results, surfaces pinned and recent table sections from shared state, and exposes slash-command navigation for the core destinations and tooling routes.
2026-03-21 P2.7 Completed Added shared frontend primitives for app-bar actions, chips, segmented tabs, drawers, inspector sections, and status indicators, wired the shell omnibox trigger onto the new app-bar action primitive, and switched the new pinned-table labels in Tables to the shared status-chip primitive so later page work can build on reusable building blocks instead of fresh ad hoc markup.
2026-03-21 P2.8 Completed Added a shared TableContextState service on top of browser storage and the URL serializer, moved the Tables page off page-local table selection persistence, and switched diagnostics to the same restore/persist/build-URI flow so table context logic now lives in shared frontend state instead of being reinvented per page.
2026-03-21 Post-P2 fix 1 Completed Fixed the shell omnibox drawer regression by adding explicit shell offset variables, constraining drawer/body scrolling, and giving the omnibox its own backdrop geometry so the flyout opens within the visible viewport instead of collapsing into invalid top/bottom positioning.
2026-03-21 Post-P2 fix 2 Completed Rebuilt the shell omnibox as a dedicated command palette instead of a repurposed drawer, with shell-owned overlay markup, explicit viewport-safe geometry, autofocus, Escape and navigation close behavior, and a stable scrollable result body.
2026-03-21 Post-P2 fix 3 Completed Moved omnibox overlay ownership from the header subtree into AppShell itself via a shared omnibox state service and a top-level palette host, which restored full-screen backdrop coverage and reliable outside-click close behavior.
2026-03-21 P3.1 Completed Split Tables.razor into focused table components for the selector header, context bar, canvas, and legend while leaving loading, deep-link synchronization, and dialog state in the page host.
2026-03-21 P3.2 Completed Replaced the floating table picker with a permanent left-rail layout, converted the old selector component into a real page header, and kept the current selection flow intact inside the new reference frame.
2026-03-21 P3.3 Completed Added rail search, family filters, pinned and recent sections, curated status chips, and keyboard up/down plus Enter handling on top of the new permanent table index rail.
2026-03-21 P3.4 Completed Added a sticky context bar with reference-mode tabs, variant and severity selectors, roll-jump state, and active filter chips, then wired those controls into page state and canvas filtering.
2026-03-21 P3.5 Completed Reworked the canvas with sticky headers, a sticky roll-band column, row and column emphasis driven by selection and roll-jump state, selected-cell treatment, and a comfortable/dense density toggle.
2026-03-21 P3.6 Completed Removed the always-visible cell button stack from resting cells, leaving status-only hints by default and limiting compact edit/curation buttons to the currently selected cell.
2026-03-21 P3.7 Completed Added a dedicated desktop inspector column that reads from the shared selected-cell state and keeps the selected result readable beside the grid.

Lessons Learned

  • The current app shell is simple enough that the redesign can land incrementally in MainLayout.razor without changing the hosting model in Program.cs.
  • The current Tables.razor page already contains three different concerns: reference browsing, curation queue work, and full editing. Splitting by workflow is the highest-value maintainability move.
  • Existing contracts in LookupContracts.cs already contain the identifiers needed for deep links and cross-surface navigation: table slug, group key, column key, roll band, and result id.
  • Diagnostics already behaves like a separate workflow and should be moved under Tools early, before the Tables page is rewritten further.
  • localStorage access is currently page-local and ad hoc. Theme, recents, pins, and table context need one shared storage boundary before more UI work starts.
  • The old typography setup coupled display and utility text under a single token. The new shell work needs separate display and UI font roles to avoid decorative type in controls.
  • Theme mode selection can be prepared independently of persistence. Splitting those concerns keeps the theme CSS and the storage wiring reviewable.
  • Shared UI state events in Blazor should stay synchronous unless the event contract is async-aware. Layout refresh can be triggered safely with InvokeAsync(StateHasChanged) from a synchronous handler.
  • Extracting shell markup into dedicated components is lower-risk than continuing to evolve MainLayout.razor directly. It isolates responsive frame work from page content and keeps later nav changes localized.
  • Once a Razor component exposes multiple named RenderFragment parameters, the page body must be passed explicitly through <ChildContent>. That pattern is now the baseline for shell composition here.
  • Accessibility work is cheaper when the shell owns the landmarks. Adding skip links and nav/main structure at the shell layer avoids repeating that work page by page.
  • Tooling can feel distinct through cooler surfaces and labeling alone. A separate app shell is unnecessary and would undermine the shared-product goal.
  • Responsive shell design needs an explicit tablet state, not just desktop and phone states. The original breakpoints left a navigation dead zone between the top nav and bottom nav layouts.
  • Theme infrastructure is not enough on its own. Any surface that keeps hardcoded light values will make the theme switch feel broken even when the selector logic is correct.
  • In Blazor Web Apps, page-level render modes do not automatically make layout-level controls interactive in the way this shell expects. The routed shell itself needs an interactive render boundary.
  • Persisted theme state should be applied before Blazor hydrates, not only after layout initialization. Otherwise refresh can look broken even when storage writes succeed.
  • For route migration in Blazor, extracting the destination UI into shared components keeps canonical routes and temporary compatibility routes from drifting while the redirect phase is still pending.
  • Compatibility routes should stay declarative and shared. A single redirect component is enough for route forwarding and avoids copy-pasted NavigationManager lifecycle logic in page files.
  • Shared browser-backed state becomes more useful once one real page writes to it immediately. Recording recents from Tables now keeps later omnibox work from being blocked on synthetic placeholder data.
  • Shared pinned-state services also need one live writer early. A minimal pin/unpin affordance in the current Tables page is enough to validate persistence before the larger navigation surfaces consume pins.
  • URL serializers only pay off when wired into real pages. Using the shared serializer in both Tables and diagnostics now gives the project one verified round-trip path before the larger table-context service lands.
  • The serializer alone is not the reusable boundary. The maintainable seam is a shared context-state helper that owns restore, persist, normalization, and URI-building conventions while pages keep only workflow-specific selection logic.
  • Primitive extraction lands best when one or two live consumers adopt the new components immediately. That keeps the foundation honest without forcing a broad page rewrite just to validate the abstraction.
  • The omnibox foundation does not need the full final interaction model to be useful. A drawer with real table search, real pinned/recent data, and a small slash-command set is enough to validate the shell surface before Phase 3 builds deeper index and inspector flows on top of it.
  • Shared overlay primitives should not depend on undeclared layout variables. If a drawer needs shell offsets, the shell must define them explicitly and overlay-specific backdrops should be adjustable instead of assuming full-screen dimming is always correct.
  • A command palette is not just a styled drawer. It needs shell-owned geometry, predictable focus behavior, and a bounded scroll region; treating it as a generic side panel led directly to the layout regressions found in Phase 2.
  • Backdrop and outside-click behavior depend on overlay ownership as much as CSS. If the trigger owns the overlay inside a sticky header subtree, fixed-position assumptions can break; shell-level overlays should be rendered by the shell, not by individual header controls.
  • The Tables rewrite is safer when orchestration and rendering are separated early. Keeping loading, persistence, and dialog state in the page host while extracting render-only components makes later layout and interaction changes much lower risk.
  • The Tables navigation model needs its own persistent geometry before advanced behaviors land. Converting the selector to a real rail first keeps later search and keyboard work from being tangled up with another structural rewrite.
  • Rail keyboard behavior is easiest to maintain when it works from one deduplicated option order, even if the UI shows multiple sections. Keeping one internal option list avoids separate arrow-key state per section.
  • The context bar controls should own one shared view-state model before the canvas gets more visual treatment. Wiring the filters into the host page now avoids a second refactor when row, column, and cell emphasis land.
  • Canvas emphasis becomes maintainable once selection, roll-jump, and density are all fed through one explicit state model. That lets the grid respond to context without hiding selection logic inside CSS-only heuristics.
  • Resting-cell quietness should be enforced structurally, not only visually. Showing actions only for the selected cell prevents future CSS regressions from reintroducing button clutter across the whole grid.
  • The inspector should be its own sibling surface in the page layout, not nested inside the table shell. That keeps the content reusable for both desktop and the later mobile sheet without coupling it to canvas markup.

Target Outcomes

The overhaul is complete when the app behaves as one coherent product with four clear destination families:

  • Play for live lookup and fast resolution
  • Tables for reference and inspection
  • Curation for queue-based repair work
  • Tools for diagnostics and API documentation

The new shell, navigation, spacing, theming, and interaction grammar must be reusable for future pages.

Overall Definition Of Done

The frontend overhaul is done when all of the following are true:

  • the app uses a shared design system with explicit light, dark, and system themes
  • the primary navigation matches the UX bible and no longer reflects implementation buckets
  • /tables is browse-first, selection-driven, and free of resting-state cell action clutter
  • Curation is a dedicated queue-first workflow rather than ambient clutter inside Tables
  • diagnostics and API docs are grouped under Tools
  • Play and Tables share the same shell and interaction model
  • deep links preserve object context for key user journeys
  • keyboard, focus, contrast, responsive behavior, and sticky layout behavior meet the UX bible rules
  • the solution is maintainable, with the current monolithic Tables page split into reusable components and services

Delivery Strategy

Implement in vertical slices, not by page-wide rewrites. Each phase should leave the app in a buildable, reviewable, and partially usable state.

Recommended order:

  1. foundation and shell
  2. shared state and deep-link infrastructure
  3. Tables reference experience
  4. Curation workflow
  5. Tools consolidation
  6. Play alignment
  7. hardening, QA, and rollout cleanup

Phase 0: Discovery And Technical Baseline

Status

Completed

Goal

Create the implementation foundation so the visual overhaul does not start with uncontrolled edits in page files.

Tasks

  • P0.1 Audit current component ownership in Components/Layout, Components/Pages, and Components/Shared.
  • P0.2 Identify which behaviors already exist and should be preserved:
    • selected table persistence
    • cell editor and curation dialogs
    • diagnostics selection model
    • lookup forms and result cards
  • P0.3 Define the target frontend structure for the overhaul.
  • P0.4 Decide the new route map and compatibility redirects.
  • P0.5 Define a shared frontend state strategy for:
    • theme
    • recent tables
    • pinned tables
    • selected table context
    • deep-link parsing and serialization
  • P0.6 Define component boundaries for shared primitives before major page work starts.

Deliverables

  • agreed route map
  • agreed component and state boundaries
  • agreed migration path from current shell and pages

Acceptance Criteria

  • every planned frontend surface has an explicit owner component or service area
  • route compatibility is defined before navigation work begins
  • there is a clear plan for what stays in page components versus what moves to shared services/components

Definition Of Done

  • no unresolved structural ambiguity remains around shell, routes, state ownership, or shared primitives

Current Repo Audit

Area Current owner Current responsibility Phase 0 decision
App host src/RolemasterDb.App/Components/App.razor document shell, fonts, global CSS/script includes keep as the document root; only update fonts and global assets during Phase 1
Router src/RolemasterDb.App/Components/Routes.razor route resolution and layout selection keep single router; add compatibility route components instead of special middleware redirects
App shell src/RolemasterDb.App/Components/Layout/MainLayout.razor current sidebar layout and page body host replace with the new top app bar shell and mobile bottom nav
Primary nav src/RolemasterDb.App/Components/Layout/NavMenu.razor implementation-bucket navigation retire after the new shell lands; replace with destination navigation primitives
Home page src/RolemasterDb.App/Components/Pages/Home.razor live lookup flow keep behavior, later restyle and reframe as Play
Tables page src/RolemasterDb.App/Components/Pages/Tables.razor table selection, table rendering, persisted selection, editor launch, curation queue work split into page shell, selection state, index rail, context bar, table canvas, inspector, and action services
Diagnostics page src/RolemasterDb.App/Components/Pages/Diagnostics.razor engineering inspection of a selected cell move under Tools and reuse shared table-selection state
API page src/RolemasterDb.App/Components/Pages/Api.razor static API docs page move under Tools with updated framing
Shared editor and curation UI src/RolemasterDb.App/Components/Shared/CriticalCellEditorDialog.razor, src/RolemasterDb.App/Components/Shared/CriticalCellCurationDialog.razor full editing and quick curation interactions preserve behavior; change launch points and page ownership
Lookup and table contracts src/RolemasterDb.App/Features/LookupContracts.cs frontend-facing DTOs for tables, lookups, editing, and diagnostics preserve contracts; build frontend state and deep links around them

Behaviors To Preserve

Behavior Current source Preserve as Notes
Selected table persistence Tables.razor local storage key rolemaster.tables.selectedTable shared per-destination context persistence service move out of page code during Phase 2
Full cell editor flow Tables.razor + CriticalCellEditorDialog.razor stable editor entry from inspector, curation, and tools editor remains modal for now
Quick curation flow and save-next behavior Tables.razor + CriticalCellCurationDialog.razor dedicated Curation workflow with reused quick-parse components queue logic moves off the reference page
Diagnostics selection model Diagnostics.razor shared table-position selector model used by Tools existing selection order is a good starting point
Attack and direct critical lookup flows Home.razor Play page behaviors preserve contracts and calculation behavior
Result preview components CriticalLookupResultCard.razor, CompactCriticalCell.razor, related shared components reusable reference and inspector content keep and adapt instead of rewriting presentation logic from scratch

Resolved Route Map

Surface Target route Compatibility handling Owner page/component
Play / none Pages/Home.razor until renamed later
Tables /tables none Pages/Tables.razor, later split into page components under Components/Tables
Curation /curation none new page introduced in Phase 4
Tools landing /tools none new page introduced in Phase 5
Diagnostics /tools/diagnostics keep /diagnostics as compatibility page that forwards to /tools/diagnostics new page in Pages/Tools/Diagnostics.razor
API docs /tools/api keep /api as compatibility page that forwards to /tools/api new page in Pages/Tools/Api.razor

Route Compatibility Strategy

  • Use lightweight compatibility pages instead of server-side redirects so route behavior stays inside the Blazor app.
  • Compatibility pages should preserve query string values and replace browser history when forwarding, so old bookmarks do not create noisy back-stack entries.
  • New deep-link work should target the destination routes only. Compatibility pages are temporary migration aids and should not gain new UI.

Target Frontend Structure

Area Planned location Responsibility
Shell components src/RolemasterDb.App/Components/Shell app frame, top app bar, bottom nav, destination nav, shell actions
Shared app state src/RolemasterDb.App/Frontend/AppState theme, recents, pins, selected context, URL serialization, storage access
Shared primitives src/RolemasterDb.App/Components/Primitives chips, tabs, buttons, drawers, inspector sections, empty states
Tables-specific components src/RolemasterDb.App/Components/Tables index rail, context bar, table canvas, inspector, state adapters
Curation-specific components src/RolemasterDb.App/Components/Curation queue layout, quick parse surface, save-and-advance actions
Tools-specific components src/RolemasterDb.App/Components/Tools diagnostics inspector, API docs framing, context links
Play-specific components src/RolemasterDb.App/Components/Play lookup forms, result rail, deep-link actions

Shared State Strategy

Concern Planned owner Persistence Consumers
Theme mode ThemeState service localStorage shell, all pages
Recent tables RecentTablesState service localStorage shell omnibox, tables rail, curation
Pinned tables PinnedTablesState service localStorage shell shortcuts, tables rail, curation
Selected table context TableContextState service URL first, localStorage fallback per destination tables, curation, tools
Table deep-link parsing and serialization TableContextUrlSerializer helper URL only tables, curation, tools, play deep links
Local storage access BrowserStorageService wrapper around JS interop all frontend state services

State Ownership Rules

  • URL state is the source of truth for sharable context.
  • Local storage is only for preferences and last-used convenience state.
  • Page components should consume state services and emit intents. They should not own persistence logic directly.
  • Editor and curation dialog transient state stays local to the workflow component that opened it.

Shared Primitive Boundaries

Primitive First consumer Notes
App bar and destination nav shell replaces NavMenu.razor
Bottom nav shell mobile-only persistent destination nav
Omnibox trigger and panel shell, tables foundation in Phase 2; full search later
Chip and status pill primitives shell, tables, curation, tools replace ad hoc chip styling in app.css
Tabs and segmented controls tables, tools mode switching and filtered views
Drawer and bottom sheet primitives tables, curation inspector on small screens
Inspector section cards tables, tools, curation unify right-rail and sheet layout

Migration Path

  1. Land the new shell and theme infrastructure in MainLayout.razor and wwwroot/app.css without changing page internals.
  2. Add shared state and compatibility routes before splitting the largest pages.
  3. Move diagnostics and API docs under Tools early to reduce noise in the main navigation.
  4. Split Tables.razor into composable pieces while preserving existing editor and curation behaviors.
  5. Extract the dedicated Curation workflow once the shared selector and table context code already exists.
  6. Restyle and reconnect Play after shell, deep links, and shared primitives are stable.

Phase 0 Exit Criteria

  • the route map above is treated as implementation truth unless a later change is explicitly recorded here
  • page, shell, and shared-state ownership are defined strongly enough to begin Phase 1 without structural rework
  • compatibility handling for /diagnostics and /api is decided
  • preserved behaviors are identified so later phases do not regress them accidentally

Next Implementation Slice

  • Start Phase 1 with the shell and design-token foundation in MainLayout.razor, App.razor, and wwwroot/app.css.
  • Introduce the shared theme state and browser storage wrapper before rewriting destination pages.
  • Replace the current sidebar navigation first so later page work lands inside the target shell instead of the legacy layout.

Phase 1: Design System And Application Shell

Status

Completed

Task Progress

Task Status Notes
P1.1 Completed Semantic token layer landed in wwwroot/app.css with compatibility aliases to keep existing pages stable.
P1.2 Completed Font loading now uses Fraunces, IBM Plex Sans, and IBM Plex Mono with explicit role-based tokens.
P1.3 Completed Explicit light, dark, and system modes now exist in CSS, backed by a scoped ThemeState service.
P1.4 Completed Theme mode now persists through a shared storage service and is applied from the layout during interactive startup.
P1.5 Completed The sidebar is gone; pages now render inside a sticky top-shell with a mobile bottom nav.
P1.6 Completed The shell now has explicit nav, omnibox, shortcut, and utility slots, plus a live theme selector and destination-model navigation.
P1.7 Completed The shell now exposes a skip link and explicit header/nav/main landmarks.
P1.8 Completed Tooling surfaces and the Tools nav item now use a cooler emphasis without leaving the shared shell system.

Goal

Establish the shared shell, tokens, typography, and theme system that every destination will inherit.

Tasks

  • P1.1 Replace the current token set in wwwroot/app.css with a semantic token system aligned to the UX bible:
    • --bg-*
    • --surface-*
    • --text-*
    • --border-*
    • --focus-*
    • --shadow-*
    • accent ramp
    • success ramp
    • warning ramp
    • danger ramp
    • info ramp
  • P1.2 Update typography to:
    • Fraunces for display and section titles
    • IBM Plex Sans for body and UI labels
    • IBM Plex Mono for diagnostics and code
  • P1.3 Implement theme modes:
    • Light
    • Dark
    • System
  • P1.4 Persist theme preference in browser storage.
  • P1.5 Replace the current sidebar-first layout with a responsive shell:
    • top app bar on desktop
    • mobile top bar
    • mobile bottom nav
  • P1.6 Add global shell slots for:
    • app mark
    • primary destination nav
    • omnibox trigger or field
    • recent/pinned shortcut slot
    • theme/settings/help utilities
  • P1.7 Add a skip link and ensure main-content landmarks are valid.
  • P1.8 Keep tools visually separated from play-facing surfaces through styling and labeling, not a separate app.

Deliverables

  • global shell component(s)
  • theme service or equivalent state holder
  • revised design token layer
  • updated app typography

Acceptance Criteria

  • the app no longer depends on the old permanent navigation rail for primary navigation
  • theme selection survives reload
  • light and dark themes are intentionally designed, not simple inversion
  • sticky top navigation does not obscure page content
  • the shell works at 375px, 768px, 1024px, and 1440px without horizontal overflow

Definition Of Done

  • all pages render inside the new shell
  • primary navigation shows Play, Tables, Curation, and Tools
  • the app has a stable theme system and global spacing/typography rules

Phase 1 Exit Notes

  • The app now has a semantic token system, explicit typography roles, theme modes with persistence, and a responsive shell.
  • The shell already uses the destination model Play, Tables, Curation, and Tools, even though deeper route migration remains a Phase 2 concern.
  • The next implementation focus is Phase 2: shared route compatibility, recents, pins, omnibox foundations, and deep-link infrastructure.

Phase 2: Shared Navigation, Search, And State Infrastructure

Status

Completed

Task Progress

Task Status Notes
P2.1 Completed Canonical Tools child routes now exist, backed by dedicated route pages and shared tooling content components.
P2.2 Completed Old /diagnostics and /api routes now forward into the canonical Tools routes with shared redirect behavior.
P2.3 Completed Recent critical-table visits now persist through a shared app-state service and are recorded from the Tables page.
P2.4 Completed Pinned tables now persist through a shared app-state service and can already be toggled from the Tables page.
P2.5 Completed Shared table-context URLs now parse and serialize through one helper and are consumed by /tables and /tools/diagnostics.
P2.6 Completed The shell omnibox now opens a live drawer with table search, pinned tables, recent tables, and slash-command navigation.
P2.7 Completed Shared primitives for chips, tabs, drawers, inspector sections, app-bar actions, and status indicators now exist in reusable components.
P2.8 Completed Table-context restore, persistence, normalization, and URI building now flow through one shared state service used by Tables and diagnostics.

Goal

Build the shared interaction infrastructure needed by multiple destinations before page-specific UI work deepens.

Tasks

  • P2.1 Implement the frontend route structure:
    • keep /
    • keep /tables
    • add /curation
    • add /tools
    • move diagnostics and API docs under /tools/...
  • P2.2 Add compatibility redirects or navigation helpers for old /diagnostics and /api links.
  • P2.3 Implement a shared recent-items model for critical tables.
  • P2.4 Implement pinned tables state and persistence.
  • P2.5 Implement deep-link parsing and URL serialization for table context:
    • table slug
    • group key
    • column key
    • roll band or roll jump
    • selected cell result id
    • mode
  • P2.6 Build an omnibox foundation that can support:
    • table search
    • recent items
    • pinned items
    • slash commands
  • P2.7 Create shared primitives for:
    • chips
    • tabs
    • app-bar actions
    • drawers or sheets
    • inspector sections
    • status indicators
  • P2.8 Create a shared table-selection service or helper so Tables, Curation, and Tools do not each reinvent selection logic.

Deliverables

  • route updates
  • local storage persistence helpers
  • omnibox/search primitives
  • shared state services/helpers

Acceptance Criteria

  • direct links into a selected table context can be opened and restored reliably
  • recent and pinned tables are available to any page that needs them
  • diagnostics and API docs remain reachable via new tools routes
  • shared controls exist before page-specific implementations duplicate them

Definition Of Done

  • common navigation and state concerns are implemented once and consumed from shared code

Phase 3: Tables Reference Experience

Status

In progress

Task Progress

Task Status Notes
P3.1 Completed Tables.razor now acts as the stateful host while selector/header/canvas/legend rendering lives in dedicated Components/Tables components.
P3.2 Completed The old dropdown picker is gone; /tables now uses a permanent left rail and a real page header while keeping the current selection flow intact.
P3.3 Completed The rail now supports search-as-you-type, family filters, pinned and recent sections, curated status chips, and a deduplicated arrow/Enter keyboard path.
P3.4 Completed The table surface now has a sticky context bar with mode tabs, variant/severity focus, roll-jump state, and active filter chips wired into host-page view state.
P3.5 Completed The canvas now supports sticky headers and roll bands, row and column emphasis from selection and roll-jump state, selected-cell treatment, and a comfortable/dense density toggle.
P3.6 Completed Resting cells now show only status hints; compact edit/curation buttons appear only for the selected cell.
P3.7 Completed Desktop now has a dedicated inspector column driven by the shared selected-cell state instead of forcing result reading back into the grid alone.
P3.8 Pending Add the mobile bottom-sheet inspector variant.
P3.9 Pending Move legend/help to an on-demand secondary surface.
P3.10 Pending Hide maintenance and developer noise in default reference mode.
P3.11 Pending Preserve editor and curation entry points through the inspector.
P3.12 Pending Normalize click/tap/keyboard selection and close the phase with a hardening pass.

Goal

Turn /tables into the canonical reference surface for reading and inspecting critical tables quickly.

Tasks

  • P3.1 Split the current Tables.razor into smaller components:
    • page header
    • table index rail
    • sticky context bar
    • table canvas
    • inspector
    • filter and mode controls
  • P3.2 Replace the current dropdown table picker with a searchable left rail.
  • P3.3 Add table index behavior:
    • search-as-you-type
    • keyboard arrow navigation
    • enter to open
    • pinned group
    • recent group
    • all tables list
    • status chip showing curated percentage
    • optional family filters
  • P3.4 Build the sticky context bar with:
    • current table title
    • variant selector when applicable
    • roll jump input
    • optional severity focus
    • mode tabs
    • filter chips
  • P3.5 Rework the table canvas for reference reading:
    • sticky top headers
    • sticky left roll-band column
    • active row emphasis
    • active column emphasis
    • selected cell focus treatment
    • optional roll-jump marker
    • density toggle
  • P3.6 Remove resting-state button clutter from cells.
  • P3.7 Move cell actions to a selection-driven inspector and optional compact selected-cell affordances.
  • P3.8 Build the right inspector on desktop and bottom-sheet inspector on mobile.
  • P3.9 Rework legend/help so it is on-demand and secondary to the canvas.
  • P3.10 Hide maintenance and developer noise in default Reference mode.
  • P3.11 Preserve the current full editor and curation entry points, but expose them from the inspector instead of per-cell button stacks.
  • P3.12 Ensure one-tap or one-click selection works the same on desktop and touch.

Deliverables

  • new Tables page composition
  • left rail selector
  • sticky context bar
  • selection-driven inspector
  • deep-link-aware table state

Acceptance Criteria

  • a user can open a table in one search action from the index rail or omnibox
  • a user can jump to a roll using a dedicated roll field
  • the selected row, column, and cell are visually obvious
  • a result can be read without opening a modal
  • no action in Tables depends on hover-only discovery
  • non-selected cells remain visually quiet
  • mobile keeps the same task model using sheets instead of a persistent inspector

Definition Of Done

  • /tables is browse-first, not edit-first
  • the grid is visually dominant and the inspector is secondary
  • resting cells contain state hints, not visible action stacks

Phase 4: Curation Workflow Surface

Goal

Create a dedicated queue-first curation workflow so repair work is fast and does not pollute the reference experience.

Tasks

  • P4.1 Create the new /curation page and route.
  • P4.2 Reuse shared table/context selection patterns from Phase 2 and Phase 3.
  • P4.3 Define queue scopes:
    • all tables
    • selected table
    • pinned set
  • P4.4 Build a stable queue-first layout with:
    • current queue item summary
    • source image
    • parsed preview
    • quick parse area
    • save-and-advance actions
  • P4.5 Move the current “next uncurated” logic into the dedicated workflow surface.
  • P4.6 Keep full editor access available, but make quick parse and mark curated the fast path.
  • P4.7 Ensure save-and-advance keeps the user in the same workflow lane without reopening context.
  • P4.8 Use warning styling only for disruptive repair actions, not for normal save flow.
  • P4.9 Hide developer-only diagnostics from the normal curation workflow.

Deliverables

  • /curation page
  • queue-first layout
  • integrated save-and-advance flow
  • quick parse in-context workflow

Acceptance Criteria

  • a curator can move from one uncurated cell to the next with one primary action after save
  • source and parsed result are visible side by side on wide screens
  • quick parse can be completed without opening the full editor for common cases
  • Tables no longer carries the primary queue-work burden

Definition Of Done

  • curation is a dedicated workflow page with a stable repeated interaction loop

Phase 5: Tools Consolidation

Goal

Separate diagnostic and developer tooling from player-facing flows without losing deep-link usefulness.

Tasks

  • P5.1 Create a Tools landing page.
  • P5.2 Move diagnostics to /tools/diagnostics.
  • P5.3 Move API documentation to /tools/api.
  • P5.4 Reuse shared selection and table-context patterns so tooling feels related but distinct.
  • P5.5 Add cross-links back to Tables and Curation preserving object context where possible.
  • P5.6 Keep raw JSON, parser provenance, and deep inspection limited to tooling surfaces.
  • P5.7 Style tooling surfaces with the shared system but with the subdued “cool slate” tooling emphasis defined by the UX bible.

Deliverables

  • Tools hub
  • migrated diagnostics page
  • migrated API docs page
  • context-preserving navigation back into reference and curation views

Acceptance Criteria

  • diagnostics and API docs remain bookmarkable
  • player-facing pages no longer expose raw payload inspection
  • a developer can inspect a cell in tools and jump back to its reference or curation context

Definition Of Done

  • developer-facing tools are clearly separated in both navigation and presentation

Phase 6: Play Alignment

Goal

Make the default landing experience feel like part of the same product and connect it to the new reference surfaces.

Tasks

  • P6.1 Reframe the current home page as Play.
  • P6.2 Apply the new shell, typography, spacing, token, and action hierarchy to lookup forms and results.
  • P6.3 Reorganize the page to prioritize fast resolution over dashboard-like symmetry.
  • P6.4 Add deep links from lookup outcomes into Tables where the user wants to inspect the underlying critical result.
  • P6.5 Ensure player-facing copy avoids maintenance terminology.
  • P6.6 Preserve current lookup behavior and contracts while improving layout, clarity, and action priority.

Deliverables

  • updated / page within the new shell
  • unified visual and interaction system
  • result-to-table deep-link paths

Acceptance Criteria

  • a lookup result can lead directly into the relevant table context
  • Play shares the same design language as Tables and Curation
  • the primary action on the page is always obvious

Definition Of Done

  • Play and Tables feel connected, not like separate demos

Phase 7: Hardening, Accessibility, Performance, And Rollout Cleanup

Goal

Stabilize the overhaul and ensure the final UX matches the bible under real usage conditions.

Tasks

  • P7.1 Review keyboard reachability for all app-bar actions, chips, tabs, table index items, table cells, inspector actions, and drawers.
  • P7.2 Verify visible focus states across light and dark themes.
  • P7.3 Verify contrast and accent-vs-semantic color distinction in both themes.
  • P7.4 Test sticky headers, sticky context bars, inspectors, and sheets across target breakpoints.
  • P7.5 Verify no page content is obscured by fixed or sticky shell elements.
  • P7.6 Verify deep links round-trip correctly across Play, Tables, Curation, and Tools.
  • P7.7 Verify last-used context persistence per destination.
  • P7.8 Measure table-switch and inspector-open performance and optimize obvious hotspots.
  • P7.9 Introduce virtualization only if profiling shows it is required and sticky behavior remains intact.
  • P7.10 Remove obsolete CSS and component paths left behind by the old shell or old /tables flow.
  • P7.11 Update documentation to reflect the final route map and shell model.

Deliverables

  • accessibility review pass
  • responsive review pass
  • performance review pass
  • cleaned-up documentation and obsolete styles/components removed

Acceptance Criteria

  • keyboard-only usage is viable for the major reference and curation flows
  • the app has no hover-only critical actions
  • mobile hit targets are at least 44x44 px on primary controls
  • there is no horizontal page overflow except intentional table-canvas panning
  • table switching feels fast after initial load

Definition Of Done

  • the overhaul is stable, accessible, responsive, and cleaned up for future extension

Cross-Cutting Technical Tasks

These tasks should be scheduled alongside the phases above rather than saved for the end.

Component Architecture

  • extract new classes and services into their own files
  • keep page components thin and move reusable logic into helpers/services
  • favor shared components over repeated markup in page files

State Management

  • centralize local storage keys
  • avoid duplicating route parsing logic across pages
  • keep selection state deterministic and serializable

Visual Consistency

  • use shared button hierarchy and chip patterns
  • reserve warning and danger styles for true risk states
  • ensure tools, curation, and reference surfaces differ through emphasis, not through unrelated styling systems

Accessibility

  • use semantic headings in order
  • use true button and link elements for interactions
  • only use grid semantics if keyboard behavior matches the semantics

Documentation

  • update related docs when route names, page responsibilities, or user flows materially change

Proposed Task Sequencing Within The Repo

This is the recommended execution order at file and module level.

  1. create shared theme, shell, and app-bar primitives
  2. update root app layout and route structure
  3. add shared state helpers for theme, recents, pins, and deep links
  4. migrate diagnostics and API routes into the Tools shape with compatibility handling
  5. split Tables.razor into focused components and land the new reference mode
  6. add the dedicated Curation page reusing shared selectors and editor flows
  7. align Home.razor into Play
  8. remove obsolete shell and /tables implementation fragments
  9. complete accessibility, responsive, and performance hardening

Milestone-Based Acceptance Summary

Milestone A

Foundation is accepted when the new shell, theme system, and route structure are in place without breaking basic navigation.

Milestone B

Tables is accepted when a gamemaster can locate a table, jump to a result, and read it without modal friction or cell-level chrome clutter.

Milestone C

Curation is accepted when a curator can save and advance through a stable queue flow without using Tables as the primary repair surface.

Milestone D

Tools is accepted when diagnostics and API documentation are grouped under tooling routes and do not pollute player-facing flows.

Milestone E

The overhaul is fully accepted when Play, Tables, Curation, and Tools all share the same shell, theme, navigation grammar, and deep-link model.

Non-Goals For This Plan

  • changing the backend data model
  • redesigning API contracts
  • adding speculative admin surfaces not described in the UX bible
  • introducing a new frontend framework
  • forcing virtualization before actual profiling justifies it

Start with a narrow but high-leverage slice:

  1. semantic tokens and theme persistence
  2. top app bar and mobile bottom nav
  3. route restructuring for Tools
  4. shared state helpers for recents, pins, and deep links
  5. extraction of /tables shell pieces without yet rewriting every detail of the canvas

This sequence reduces risk because it establishes the shared infrastructure before the most complex page rewrite.