Repository navigation
Studio layout skeleton: the 48 px three-column shell header, one 240 px rail and one 300 px inspector aside shared by all four pillars, and the item-header + tab-row scaffold each pillar renders its existing content into (supersedes #12447, #12448, #12449) #12459
Description
Source
Epic #12446, decisions 1, 2 and 3. This card is the structural half of the redesign: the shell header, the rail and the inspector aside that all four pillars share, and the content-column scaffold (item header row + tab row + body) each pillar renders its existing content into. The pillar cards (#12450, #12451, #12454, #12455, #12456) restyle what goes inside that scaffold; the read-only card (#12453) adds its two signals to it. It supersedes #12447 (shell header), #12448 (shared rail) and #12449 (shared inspector aside), which close as duplicates of this card.
Ruling
Maintainer, in the epic PM session on 2026-10-15, verbatim:
我建议你先派一张整体布局的卡,你负责改了。
Under that ruling the epic PM session (session_cdb7a717-def7-4e71-9988-f089fbaa18ff) implements this one card itself — the maintainer's explicit per-card exception to the rule that the PM seat writes no code. The remaining children stay with the domain:ui lane and are accepted by the epic PM against the reference artboards.
Target
Measured on objectui main a2225f91. The numbers below are the ones every other child cites; the artboards under docs/design/studio-redesign/ (landing in a separate docs-only PR) show them as pixels.
- Shell header, 48 px, a CSS grid
1fr auto 1fr. Left: the home icon button (32 px), then thePackageSwitchertrigger rendered as an app chip — a 24 px rounded tile with the package's app icon on its color (the Home tile's icon and color; a generic package glyph when the package has no app), the name at 13 px / 600, a chevron. Center: the pillars as a segmented control — a 3 px padded muted track, 28 px items, the active item on the card surface with a 1 px shadow and its icon in the primary color. Right: Changes as an outline button whose pending count is an 18 px primary pill; Publish unchanged in behavior. The "·" separator span goes. The More overflow stays exactly as objectui#11794 ruled until decision A on the epic is answered (that is Studio pillar nav: Access sits in the segmented control and the More overflow retires while it holds a single pillar (reverses the objectui#11794 More ruling; decision anchored in the epic) #12452's card); the segmented control simply renders it as its last item. - One rail,
StudioRail.tsx, 240 px, used by Data, Automations, Interfaces and Access: a 44 px header row (11 px uppercase heading with 0.06 em tracking, an 18 px count pill, a 28 px add button at the right that the pillar passes in or omits), a 32 px search input, 32 px rows with a 16 px glyph slot, a truncating 13 px label and a trailing slot, group-header rows of 28 px with a chevron and 12 px child indent, an empty-group row, an optional legend slot. Active row: primary-soft background, primary text, 500 weight. Each pillar's rows keep their current content, icons, search behavior, badges and separators; only the frame and the measurements change. The Data rail's "Read-only" footer is removed here (its signal returns in Studio read-only posture: a lock in the app chip and one "Read-only · Customize with an overlay" link in the item header replace the banner, the rail footer, the amber badge and the form strips #12453). - One inspector aside,
StudioInspector.tsx, 300 px, at the right of every pillar's content body: a header with an 11 px uppercase eyebrow (the kind), a 15 px / 600 title, an 11 px mono id and a 28 px close button; a 16 px padded body the pillar fills; a pinned 12 px muted footer "Edits save as drafts. Publish the package to apply them." (one new i18n key in every locale). The Automationsw-72aside, the Interfaces "Canvas / Properties" tab pair with itsw-9icon strip, and the Data column and field inspector mounts all render through it; below a 1000 px content row the aside folds into the existing sheet in every pillar (the objectui#11795 narrow-row behavior, today Automations-only). - Content-column scaffold in each pillar: an item header row (18 px top and 24 px side padding; a 32 px primary-soft icon tile; the item's label at 18 px / 600; its api name as an 11 px mono chip; a 12 px muted meta slot; a right-aligned actions slot), then a 36 px tab row with a 2 px primary underline on the active tab, then the body. The pillar-specific second band retires and its content moves into the scaffold without redesign: Automations' Enabled switch and "Off by default" sentence go to the header's actions slot (the sentence as the switch's title); Interfaces' "Home · Dashboard" becomes the header's label plus a kind chip; Access' "Permission matrix" band becomes the header's meta slot ("Objects × CRUD · field-level R/W") with Explain access in the actions slot. The Data pillar's object header moves from above the rail into the scaffold. Today's tab strips (Records / Form / Advanced ▾; Layout / Preview stays inside the Form body) render in the tab row with their current names and behavior; flattening Advanced is Data pillar: the object header moves into the content column, Records / Form / Validations / Hooks / Actions / API / Settings become one underline tab row, and the Records toolbar and grid lose their nested containers #12450's card and decision B.
- Shared constants in
studio-tokens.ts: the sizes above as named Tailwind class strings, so the pillar cards compose them instead of restating numbers.
File surface
packages/app-shell/src/views/studio-design/StudioDesignSurface.tsx (shell header, the four pillars' rail and aside mounts, the four item headers and tab rows, the three retired bands), new StudioRail.tsx, StudioInspector.tsx, studio-tokens.ts in the same folder, ObjectListViewInspector.tsx (header only), packages/app-shell/src/views/metadata-admin/i18n.ts (the footer sentence; retired band keys in every locale).
Acceptance
- A screenshot of each pillar at 1280 px, light and dark, with HotCRM open: the rail's heading, search and first row, the item header's title and the tab row sit at the same y in all four; the aside's header sits at the same x and y in the three pillars that show one.
- The segmented control's center is the viewport's center within 4 px with a 14-character package name on the left and "Changes" plus a count on the right.
- No full-width band between the shell header and the rail in any pillar; Automations' switch still toggles
statusthrough the same confirmation and refusal paths (AutomationsPillar.authorRefusal-11785,heldIncomplete-11786,StudioDesignSurface.flowStatusTruth-11779green). - The narrow-row fold works in all four pillars (
AutomationsPillar.narrowRow-11795extended to one more pillar). - Every test under
packages/app-shell/src/views/studio-design/green; tests that pinned the retired bands, the "·" separator, the "Changes · N" text or thew-9strip are updated in the same PR, each ablated once. pnpm --filter @object-ui/app-shell test,lint,buildgreen;pnpm check:i18ngreen for the key changes.
Constraints
- Tailwind utilities and theme tokens only; no inline style, so
.darkstays a real variant. - Existing
data-testids and i18n keys stay; new ids:studio-rail-data,studio-rail-automations,studio-rail-interfaces,studio-rail-access,studio-inspector. - No pillar body restyle, no read-only consolidation, no nav-kind picker, no flow grouping in this card.
- The objectstack console pin bump is a follow-up outside this subtree.
Supersedes: #12447, #12448, #12449 (closed as duplicates of this card).
Parent: #12446
Activity
objectstack-fleet commentedon Oct 15, 2026
Claim: PM loop round 1 (epic #12446 subtree)
Session:
session_cdb7a717-def7-4e71-9988-f089fbaa18ffAccount:
hotlong(the seat's linked user; the card's assignee)Branch:
claude/issue-12459-studio-layout-skeletonWorktree:
objectui-issue-12459Domain:
domain:uiSeat:
domain:ui#1File surface:
packages/app-shell/src/views/studio-design/(StudioDesignSurface.tsx; new StudioRail.tsx, StudioInspector.tsx, studio-tokens.ts; ObjectListViewInspector.tsx header) andpackages/app-shell/src/views/metadata-admin/i18n.ts(stop on breach; explain in the report)Container & model:
L,mode:local-session,model: maintainer-directed (the epic PM session implements this card itself, under the ruling quoted on the card)Clause-②: no
Thread-read: none
Serial constraints cleared: none in flight on this file surface at claim time (no open PR touches studio-design on objectui main a2225f9)
Written 2026-10-15T08:16Z.
objectstack-fleet commentedon Oct 15, 2026
Implemented in #12460 (branch
claude/issue-12459-studio-layout-skeleton, on maina2225f91).Evidence in the PR: the four pillars at 1280 px, light and dark, under
docs/design/studio-redesign/after/;pnpm exec vitest run packages/app-shell/src/views/studio-design173 files / 1275 tests green;tsc --noEmitclean; eslint no errors; aminorchangeset for@object-ui/app-shell. One test updated (moreKeepsName-11794: the segmented control's active tokens; the ruling it pins is unchanged). Deviations from the artboards are listed in the PR body: pillar bodies, the read-only posture, decision A and the flow grouping stay with their own cards.The epic PM session implemented this card itself under the maintainer's ruling quoted on the card; the merge is the maintainer's.
Written 2026-10-15T09:01Z by the epic PM session
session_cdb7a717-def7-4e71-9988-f089fbaa18ff.feat(app-shell): Studio layout skeleton: the shell header, one rail, …