The master/detail screens use hardcoded grid-cols-[20rem_1fr] / [24rem_1fr] (objects-page.tsx, vocabularies-page.tsx, fields-page.tsx, search-page.tsx:8) plus a fixed w-44 sidebar (app-shell.tsx:20), with no breakpoint variants anywhere. On a smaller laptop / tablet / split-screen window the 20rem list + sidebar leave a cramped detail pane; below ~640px the master + detail can't coexist. The proportions also aren't user-adjustable.
Suggested fix
Add responsive breakpoints — collapse the sidebar to icons (or a drawer) and stack master/detail on narrow widths; consider a resizable splitter for the master/detail panes so curators can tune list-vs-detail width.
Source: frontend UX/design audit, 2026-06-06.
**Severity: Medium.** _From a frontend UX audit._
## Problem
The master/detail screens use hardcoded `grid-cols-[20rem_1fr]` / `[24rem_1fr]` (`objects-page.tsx`, `vocabularies-page.tsx`, `fields-page.tsx`, `search-page.tsx:8`) plus a fixed `w-44` sidebar (`app-shell.tsx:20`), with **no breakpoint variants anywhere**. On a smaller laptop / tablet / split-screen window the 20rem list + sidebar leave a cramped detail pane; below ~640px the master + detail can't coexist. The proportions also aren't user-adjustable.
## Suggested fix
Add responsive breakpoints — collapse the sidebar to icons (or a drawer) and stack master/detail on narrow widths; consider a resizable splitter for the master/detail panes so curators can tune list-vs-detail width.
_Source: frontend UX/design audit, 2026-06-06._
Partially addressed in 0a88a86 (the #44 milestone). The app shell is now responsive: the sidebar collapses to an icon rail (persisted; auto-collapses on narrow via useMediaQuery), and the Objects screen's master/detail is responsive — a right pane on wide viewports and a slide-in Base UI Drawer on narrow, at canonical /objects/:id. A reusable web/src/lib/use-media-query.ts hook was added.
Remaining (keeping this open): the other master/detail screens still use fixed grid-cols-[20rem_1fr] with no breakpoints — vocabularies (vocabularies-page), fields (fields-page), search (search-page), and the single-pane authorities screen. Apply the same responsive pane/drawer pattern (or stack) there.
Partially addressed in `0a88a86` (the #44 milestone). The **app shell** is now responsive: the sidebar collapses to an icon rail (persisted; auto-collapses on narrow via `useMediaQuery`), and the Objects screen's master/detail is responsive — a right pane on wide viewports and a slide-in Base UI `Drawer` on narrow, at canonical `/objects/:id`. A reusable `web/src/lib/use-media-query.ts` hook was added.
**Remaining (keeping this open):** the other master/detail screens still use fixed `grid-cols-[20rem_1fr]` with no breakpoints — vocabularies (`vocabularies-page`), fields (`fields-page`), search (`search-page`), and the single-pane authorities screen. Apply the same responsive pane/drawer pattern (or stack) there.
Remaining half done in merge a0b7dcd — all master/detail screens are now responsive (the sidebar + Objects were already done in 0a88a86).
Shared components/detail-drawer.tsx — generalized the objects-specific drawer into a reusable <DetailDrawer open onClose ariaLabel>{children}</DetailDrawer> (Base UI drawer + named dialog + close affordance). object-detail-drawer.tsx deleted; Objects retrofitted onto it (dropped the now-pointless lazy/Suspense since #67 already split @base-ui/react into its own app-wide chunk).
Vocabularies + Search — useMediaQuery("(min-width: 1024px)") + useMatch(":id"): wide keeps the current side-by-side grid (unchanged); narrow (<1024) shows the list/panel full-width and slides the detail into a DetailDrawer (close → index route). Drawer names reuse vocab.terms / objects.detailTitle.
Fields — pure-CSS responsive stack (grid-cols-1 lg:grid-cols-[20rem_1fr], list-above-form on narrow): it's useState-driven with an always-present create form, so a stack is the right fit (no drawer/new-trigger needed).
Breakpoint 1024px throughout, matching Objects. 289 tests pass (existing unchanged + new tests for the drawer + all three pages); typecheck/lint/build clean; check:size 90.2 KB gz (unchanged); check:colors clean; no new dependency; no new i18n keys; no codename.
Out of scope → follow-up: the "resizable splitter" / per-user pane-width preference the issue suggests considering (deferred — the responsive collapse is the actual fix). Authorities is single-pane → no change needed.
Remaining half done in merge `a0b7dcd` — all master/detail screens are now responsive (the sidebar + Objects were already done in `0a88a86`).
- **Shared `components/detail-drawer.tsx`** — generalized the objects-specific drawer into a reusable `<DetailDrawer open onClose ariaLabel>{children}</DetailDrawer>` (Base UI drawer + named dialog + close affordance). `object-detail-drawer.tsx` deleted; Objects retrofitted onto it (dropped the now-pointless `lazy`/`Suspense` since #67 already split `@base-ui/react` into its own app-wide chunk).
- **Vocabularies + Search** — `useMediaQuery("(min-width: 1024px)")` + `useMatch(":id")`: wide keeps the current side-by-side grid (unchanged); narrow (<1024) shows the list/panel full-width and slides the detail into a `DetailDrawer` (close → index route). Drawer names reuse `vocab.terms` / `objects.detailTitle`.
- **Fields** — pure-CSS responsive stack (`grid-cols-1 lg:grid-cols-[20rem_1fr]`, list-above-form on narrow): it's `useState`-driven with an always-present create form, so a stack is the right fit (no drawer/new-trigger needed).
Breakpoint 1024px throughout, matching Objects. 289 tests pass (existing unchanged + new tests for the drawer + all three pages); typecheck/lint/build clean; check:size 90.2 KB gz (unchanged); check:colors clean; no new dependency; no new i18n keys; no codename.
**Out of scope → follow-up:** the "resizable splitter" / per-user pane-width preference the issue *suggests considering* (deferred — the responsive collapse is the actual fix). Authorities is single-pane → no change needed.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Severity: Medium. From a frontend UX audit.
Problem
The master/detail screens use hardcoded
grid-cols-[20rem_1fr]/[24rem_1fr](objects-page.tsx,vocabularies-page.tsx,fields-page.tsx,search-page.tsx:8) plus a fixedw-44sidebar (app-shell.tsx:20), with no breakpoint variants anywhere. On a smaller laptop / tablet / split-screen window the 20rem list + sidebar leave a cramped detail pane; below ~640px the master + detail can't coexist. The proportions also aren't user-adjustable.Suggested fix
Add responsive breakpoints — collapse the sidebar to icons (or a drawer) and stack master/detail on narrow widths; consider a resizable splitter for the master/detail panes so curators can tune list-vs-detail width.
Source: frontend UX/design audit, 2026-06-06.
Partially addressed in
0a88a86(the #44 milestone). The app shell is now responsive: the sidebar collapses to an icon rail (persisted; auto-collapses on narrow viauseMediaQuery), and the Objects screen's master/detail is responsive — a right pane on wide viewports and a slide-in Base UIDraweron narrow, at canonical/objects/:id. A reusableweb/src/lib/use-media-query.tshook was added.Remaining (keeping this open): the other master/detail screens still use fixed
grid-cols-[20rem_1fr]with no breakpoints — vocabularies (vocabularies-page), fields (fields-page), search (search-page), and the single-pane authorities screen. Apply the same responsive pane/drawer pattern (or stack) there.Remaining half done in merge
a0b7dcd— all master/detail screens are now responsive (the sidebar + Objects were already done in0a88a86).components/detail-drawer.tsx— generalized the objects-specific drawer into a reusable<DetailDrawer open onClose ariaLabel>{children}</DetailDrawer>(Base UI drawer + named dialog + close affordance).object-detail-drawer.tsxdeleted; Objects retrofitted onto it (dropped the now-pointlesslazy/Suspensesince #67 already split@base-ui/reactinto its own app-wide chunk).useMediaQuery("(min-width: 1024px)")+useMatch(":id"): wide keeps the current side-by-side grid (unchanged); narrow (<1024) shows the list/panel full-width and slides the detail into aDetailDrawer(close → index route). Drawer names reusevocab.terms/objects.detailTitle.grid-cols-1 lg:grid-cols-[20rem_1fr], list-above-form on narrow): it'suseState-driven with an always-present create form, so a stack is the right fit (no drawer/new-trigger needed).Breakpoint 1024px throughout, matching Objects. 289 tests pass (existing unchanged + new tests for the drawer + all three pages); typecheck/lint/build clean; check:size 90.2 KB gz (unchanged); check:colors clean; no new dependency; no new i18n keys; no codename.
Out of scope → follow-up: the "resizable splitter" / per-user pane-width preference the issue suggests considering (deferred — the responsive collapse is the actual fix). Authorities is single-pane → no change needed.