diff --git a/docs/release-control/v6/internal/subsystems/frontend-primitives.md b/docs/release-control/v6/internal/subsystems/frontend-primitives.md index 4bc6768d95..7dec6d8c41 100644 --- a/docs/release-control/v6/internal/subsystems/frontend-primitives.md +++ b/docs/release-control/v6/internal/subsystems/frontend-primitives.md @@ -889,6 +889,14 @@ not a replacement status card, CTA band, or page-local nested card. an existing panel/card frame must use the shared `frame="flush"` mode rather than caller-local border overrides, horizontal-scroll wrappers, or negative margin compensation. + Dense platform tables must also preserve readable columns at phone widths. + `PlatformTableShell` owns the responsive minimum-width policy, preserves any + explicit base floor declared by the feature table, and otherwise applies + the shared platform minimum before breakpoint-specific widths take over. + Narrow viewports keep document-level overflow + contained by `Table` and scroll the table itself; feature tables must not + squeeze every declared column into the viewport, override the shared floor, + or add a second page-local scroll wrapper. Product-table subgroup/header rows must likewise consume the shared `frontend-modern/src/components/shared/groupedTableRowPresentation.ts` helper and `.grouped-table-row` CSS token contract instead of local @@ -3443,6 +3451,11 @@ of pushing tab-order or DOM lifecycle logic back into the shared shell. With support/admin controls moved under Settings, that utility ordering must no longer reserve a standalone `operations` slot; alerts, Patrol, and Settings are the remaining authenticated utility tabs. +The platform rail is the only horizontally scrolling region in that shell. +Alerts, Patrol, and Settings stay pinned in a separate utility rail so primary +platform breadth cannot push those global destinations beyond the phone +viewport, while active-platform centering and fade state remain scoped to the +primary rail. The shared command palette now follows that same owner split. `frontend-modern/src/components/shared/CommandPaletteModal.tsx` stays the render shell, `frontend-modern/src/components/shared/useCommandPaletteState.ts` diff --git a/docs/release-control/v6/internal/subsystems/performance-and-scalability.md b/docs/release-control/v6/internal/subsystems/performance-and-scalability.md index 2f001d9001..84cae18599 100644 --- a/docs/release-control/v6/internal/subsystems/performance-and-scalability.md +++ b/docs/release-control/v6/internal/subsystems/performance-and-scalability.md @@ -1492,6 +1492,11 @@ and viewport-sync plus selected-row reveal behavior now live in so future hot-path table-state changes must not fold selector derivation, layout policy, and scroll coordination back into one mixed owner or the render shell. +The same shared layout policy now preserves a 640-pixel mobile table floor for +the prioritized identity and metric columns. That width remains class-based +and contained by the frontend-primitives `Table` overflow shell, so phone +layouts gain legible tracks without reintroducing document-level overflow, +inline sizing maps, or extra hot-path measurement state. That same hot-path boundary now also owns CSP-safe table sizing. Infrastructure host, PBS, and PMG table shells must take their layout and column sizing from the shared presentation owner in diff --git a/docs/release-control/v6/internal/subsystems/unified-resources.md b/docs/release-control/v6/internal/subsystems/unified-resources.md index 4598038540..971e979a3d 100644 --- a/docs/release-control/v6/internal/subsystems/unified-resources.md +++ b/docs/release-control/v6/internal/subsystems/unified-resources.md @@ -956,8 +956,11 @@ AI-only summary payloads, or page-local heuristics. and `frontend-modern/src/components/Infrastructure/unifiedResourceTableStateModel.ts` owns the column-priority breakpoints for host and service infrastructure rows. When the app shell leaves tablet-sized space during live resize, the - table must hide lower-priority resource metadata columns rather than - publishing a horizontally scrolling canonical resource list. + table hides lower-priority metadata first, then preserves a readable + 640-pixel floor for the remaining identity and health columns inside the + shared table scroll shell. The document must not overflow, but the table + must not compress the prioritized mobile columns until resource names and + metric headings become ambiguous. 15. Keep shared policy-posture framing on the unified-resource card owner. `frontend-modern/src/components/Infrastructure/ResourcePolicySummary.tsx` may accept caller-owned subtitle or resource-count wording when Patrol or @@ -2252,6 +2255,11 @@ and viewport reveal plus scroll synchronization now route through `frontend-modern/src/components/Infrastructure/useUnifiedResourceTableViewportSync.ts`, so the shared consumer model is no longer interleaving selector derivation, layout policy, and DOM viewport coordination inside one mixed state boundary. +The mobile shell class from that shared state model now keeps a 640-pixel +minimum table width below the small-screen breakpoint while restoring +`min-w-full` above it. This retains the prioritized mobile column set without +forcing those columns into unreadable tracks, and the existing shared `Table` +overflow owner contains the horizontal scroll locally. That same unified-resource consumer contract now also owns CSP-safe table presentation for infrastructure rows. Host, PBS, and PMG table sections must consume the shared column presentation owner and render canonical table sizing diff --git a/frontend-modern/src/components/Infrastructure/__tests__/unifiedResourceTableStateModel.test.ts b/frontend-modern/src/components/Infrastructure/__tests__/unifiedResourceTableStateModel.test.ts index a145150c51..922538a295 100644 --- a/frontend-modern/src/components/Infrastructure/__tests__/unifiedResourceTableStateModel.test.ts +++ b/frontend-modern/src/components/Infrastructure/__tests__/unifiedResourceTableStateModel.test.ts @@ -129,12 +129,13 @@ describe('unifiedResourceTableStateModel', () => { const wideColumns = getUnifiedResourceTableColumnPresentations('wide'); expect(getUnifiedResourceTableShellClass('mobile')).toContain('table-fixed'); - expect(getUnifiedResourceTableShellClass('mobile')).toContain('min-w-full'); - expect(getUnifiedResourceTableShellClass('compact')).toContain('min-w-full'); - expect(getUnifiedResourceTableShellClass('wide')).toContain('min-w-full'); + expect(getUnifiedResourceTableShellClass('mobile')).toContain('min-w-[640px]'); + expect(getUnifiedResourceTableShellClass('mobile')).toContain('sm:min-w-full'); + expect(getUnifiedResourceTableShellClass('compact')).toContain('min-w-[640px]'); + expect(getUnifiedResourceTableShellClass('wide')).toContain('min-w-[640px]'); expect(getUnifiedResourceTableShellClass('wide')).not.toContain('min-w-[max-content]'); - // Mobile and tablet use percentage widths so the visible-column set fills - // the table surface without horizontal overflow. Wider modes keep all + // Mobile keeps the prioritized column set but preserves a readable width + // floor inside the shared horizontal-scroll shell. Wider modes keep all // host columns visible while compressing their tracks before any // lower-priority columns are dropped. expect(mobileColumns.resourceColumn.width).toBe('40%'); diff --git a/frontend-modern/src/components/Infrastructure/unifiedResourceTableStateModel.ts b/frontend-modern/src/components/Infrastructure/unifiedResourceTableStateModel.ts index 9b37dfa998..5a728b6e9a 100644 --- a/frontend-modern/src/components/Infrastructure/unifiedResourceTableStateModel.ts +++ b/frontend-modern/src/components/Infrastructure/unifiedResourceTableStateModel.ts @@ -284,7 +284,10 @@ const buildUnifiedResourceTableColumnPresentation = ( export const getUnifiedResourceTableShellClass = ( layoutMode: UnifiedResourceTableLayoutMode, -): string => `table-fixed min-w-full${layoutMode === 'wide' ? '' : ' text-[11px] sm:text-xs'}`; +): string => + `table-fixed min-w-[640px] sm:min-w-full${ + layoutMode === 'wide' ? '' : ' text-[11px] sm:text-xs' + }`; export const getUnifiedResourceTableHeaderLabels = ( layoutMode: UnifiedResourceTableLayoutMode, diff --git a/frontend-modern/src/components/shared/MobileNavBar.tsx b/frontend-modern/src/components/shared/MobileNavBar.tsx index 50ce6e1913..c2984cfada 100644 --- a/frontend-modern/src/components/shared/MobileNavBar.tsx +++ b/frontend-modern/src/components/shared/MobileNavBar.tsx @@ -18,48 +18,65 @@ export function MobileNavBar(props: MobileNavBarProps) { return ( <> -