Spec version v0.2.0

Detail View

Purpose

The detail view composition displays a single entity (a repository, a dataset, a changelist, a VDB, a job, an engine, or similar) and all information associated with it. It is the standard page for viewing and acting on a specific record after navigating to it from a list page. The detail view replaces the list page in the main content area — it does not appear alongside it.

Use this composition whenever a user selects a specific item from a list and needs a dedicated view showing metadata, related data, tabs of detail sections, and entity-scoped actions. Do not use it for configuration or preferences (use the settings-page composition instead). Do not use it for multi-record bulk operations (those happen within the list page via the ControlsBar).

Structure

The detail view is organized as a vertical stack of four regions: breadcrumbs, a detail page header, a tab navigation bar, and a tab content area. At wider viewports, an optional metadata sidebar may appear as a right-aligned column alongside the tab content area.

+---------------------------------------------------------------------+
|  Breadcrumbs: [Section] > [Entity Name]                             |
+---------------------------------------------------------------------+
|  [Entity Title]    [Status Badge]  [Environment Badge]              |
|  [Metadata row: key-value pairs — e.g., Created by · 3 days ago]   |
|                        [Actions dropdown ▾]  [Primary Action btn]  |
+---------------------------------------------------------------------+
|  Overview  |  Configuration  |  History  |  Permissions  |         |
| ───────────                                                         |
+---------------------------------------------------------------------+
|                                          |                          |
|  Tab Content Area                        |  Metadata Sidebar        |
|  (fills ~70% width when sidebar present) |  (~30% width, optional) |
|                                          |                          |
|  [CalloutCards row: 3–4 metrics]         |  [InfoCard]             |
|  [ContentGrid: InfoCards 2–3 cols]       |  [InfoCard]             |
|                                          |                          |
+------------------------------------------+-------------------------+

Breadcrumbs

The breadcrumb row is the first element in the page, above the page header. It shows the navigation path from the top-level section down to the current entity. Each ancestor segment is a link colored --force-color-text-link (indigo-500), underlined on hover. Segments are separated by a right-pointing chevron icon (Material Symbols Rounded, size xs, 14px) in --force-color-text-tertiary. The final segment (the current entity name) is not a link. It uses --force-color-text-primary, bold weight. The breadcrumb row has no background and no border. Its bottom spacing to the page header is --force-spacing-2 (8px).

If the current page is only one level deep (already at the top-level section), breadcrumbs are omitted entirely. Do not show a breadcrumb row with only one item.

Detail Page Header

The detail page header spans the full content area width. It contains:

Left region: the entity title, status and context badges, and a metadata row.

  • Entity title: --force-font-size-3xl (30px), bold, --force-color-text-primary. The title is a plain string — do not embed badges, icons, or interactive elements inside the title text itself.
  • Status badges: placed immediately to the right of the title on the same baseline, or on the line below the title if space is constrained. Badges use the subtle variant at size md. Up to three badges may be shown; if more metadata is needed, move the excess into the metadata row.
  • Metadata row: a horizontal line of short key-value descriptors in --force-font-size-sm (14px), --force-color-text-tertiary. Keys and values are separated by a space, and each pair is separated from the next by a middle dot separator (·) in --force-color-text-tertiary. Examples: "Created by Jake Smith · 3 days ago · Workspace helix-main". This row uses one line; do not wrap it to multiple lines.

Right region: action controls, right-aligned.

  • A primary action button using the primary button variant (for example, "Connect", "Enable", "Sync Now"). This is the single most important action for the entity. Not all entities require a primary action button — omit it if there is no obvious single primary action.
  • An actions dropdown button using the secondary variant with a chevron-down icon, labeled "Actions". This contains all secondary and destructive entity-level actions (Edit, Clone, Disable, Delete, Export, etc.). Destructive actions within the dropdown are visually separated from constructive actions by a Separator and use --force-color-text-error as their label color.
  • Do NOT spread more than two buttons side-by-side in the header action region. Consolidate everything behind the Actions dropdown beyond the primary action.

The page header row containing the title and actions has a bottom border of 1px in --force-color-border-default and a bottom padding of --force-spacing-4 (16px) before that border, separating the header from the tab navigation bar below it.

Tab Navigation

The tab navigation bar sits directly below the page header, flush to the bottom border. It uses the Tabs component in the underline variant. Tabs are the primary mechanism for switching between different views of the same entity (Overview, Configuration, History, Permissions, Relationships, etc.).

Tab labels use --force-font-size-sm (14px), medium weight. The active tab has a 2px–3px bottom border line in --force-color-border-primary (indigo-500). Inactive tabs have --force-color-text-secondary label text. Hover state: --force-color-text-primary label. The tab bar itself has a bottom border in --force-color-border-default spanning the full content width, with the active tab's underline marker sitting on top of this border.

Tab content panels have zero additional padding added by the tab container itself. The content padding comes from the page shell's --force-layout-content-padding (24px) already applied to the content area, or from the individual components within the tab (cards add their own internal padding).

Limit the tab bar to seven tabs maximum. If an entity has more than seven sections, consider grouping related sections or using a secondary navigation pattern within a tab. Tabs should be named with short, specific nouns: "Overview", "Access", "History", not "View Details", "See History", "Manage Permissions."

Tab Content Area

The tab content area is everything below the tab bar. Its structure varies by tab, but the Overview tab follows a fixed pattern that all detail view implementations must use for their first tab.

The Overview tab always has this structure:

  1. A CalloutCards row: a horizontal grid of 2–4 metric display cards showing the most critical numbers for the entity (size, record count, last sync time, status summary, etc.). The grid uses grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)) with a gap of --force-spacing-4 (16px).
  2. A ContentGrid: a multi-column grid (typically 3 columns, or 2 columns when a metadata sidebar is present) of InfoCards, each containing a MetadataList of key-value property pairs. Gap is --force-spacing-4 (16px). Cards use align-items: start so they do not stretch to equal height.

The vertical gap between the CalloutCards row and the ContentGrid is --force-spacing-6 (24px).

Metadata Sidebar (Optional)

For entities with a distinct set of reference metadata that should always be visible while scrolling through tab content, an optional metadata sidebar may appear on the right side of the tab content area. It is approximately 30% of the tab content width. It contains one or more InfoCards with static or semi-static information (creator, timestamps, associated accounts, linked entities). The sidebar uses position: sticky with a top value of --force-layout-header-height plus the tab bar height to keep it anchored as the main content scrolls.

The metadata sidebar is separated from the main tab content by a gap of --force-spacing-6 (24px). It does not have its own border or background — the cards within it use the standard card border and --force-color-bg-surface background.

Use the metadata sidebar only when the metadata is genuinely useful to reference while scrolling through the tab content. Do not use it as a catch-all for overflow information. If the entity has few properties, put them in the Overview tab's ContentGrid instead and omit the sidebar entirely.

Responsive Behavior

At and above --force-breakpoint-xl (1200px), the metadata sidebar is displayed at approximately 30% width alongside the main tab content area at approximately 70%. The tab bar spans the full content width.

Between --force-breakpoint-lg (992px) and --force-breakpoint-xl (1200px), the metadata sidebar collapses into a new tab called "Details" that appears as the last tab in the tab bar. Its InfoCards then render in the standard tab content area at full width.

Between --force-breakpoint-md (768px) and --force-breakpoint-lg (992px), the page header title, badges, and action region stack vertically: title and badges on the first row, metadata row on the second row, and the action buttons row on the third row. The tab bar remains horizontal but may show fewer tabs if the labels are long — tabs that overflow the row are accessible via a horizontal scroll or overflow menu. The CalloutCards grid reduces to 2 columns. The ContentGrid reduces to 2 columns.

Below --force-breakpoint-md (768px), the page header stacks fully. The tab bar scrolls horizontally. The CalloutCards grid reduces to 1 column. The ContentGrid reduces to 1 column. Breadcrumbs may truncate the middle segments with an ellipsis, keeping only the first and last segments visible. The metadata sidebar (if present) continues to appear as the "Details" tab.

Token Usage

Element Token
Breadcrumb link color --force-color-text-link (indigo-500)
Breadcrumb link hover --force-color-text-link-hover (indigo-600)
Breadcrumb separator color --force-color-text-tertiary
Breadcrumb current page color --force-color-text-primary
Breadcrumb current page weight --force-font-weight-bold (700)
Breadcrumb-to-header gap --force-spacing-2 (8px)
Entity title size --force-font-size-3xl (30px)
Entity title weight --force-font-weight-bold (700)
Entity title color --force-color-text-primary
Metadata row size --force-font-size-sm (14px)
Metadata row color --force-color-text-tertiary
Page header bottom border --force-color-border-default
Page header bottom padding --force-spacing-4 (16px)
Tab bar bottom border --force-color-border-default
Active tab indicator --force-color-border-primary (indigo-500)
Active tab label --force-color-text-interactive-active (indigo-700)
Inactive tab label --force-color-text-secondary
Hover tab label --force-color-text-primary
CalloutCard to ContentGrid gap --force-spacing-6 (24px)
CalloutCard grid gap --force-spacing-4 (16px)
ContentGrid gap --force-spacing-4 (16px)
Metadata sidebar gap --force-spacing-6 (24px)
InfoCard background --force-color-bg-surface
InfoCard border --force-color-border-default
InfoCard border radius --force-radius-card (8px)
InfoCard padding --force-spacing-6 (24px)
Destructive dropdown item color --force-color-text-error
Actions dropdown shadow --force-shadow-xs

Accessibility

The breadcrumb list must be wrapped in a <nav> element with aria-label="Breadcrumb". The list itself uses <ol> (ordered list) because breadcrumbs represent a hierarchical sequence. The current page breadcrumb carries aria-current="page".

The detail page header does not need a landmark role — it is within the <main> region. The entity title should be an <h1> (there is exactly one <h1> per page). Section headings within tab content should use <h2> for InfoCard titles and <h3> for metadata groups within those cards.

The tab navigation uses the ARIA tabs pattern: the tab row has role="tablist", each tab has role="tab" with aria-selected (true/false) and aria-controls pointing to the id of the corresponding tab panel, and each panel has role="tabpanel" with aria-labelledby pointing back to its tab. Keyboard navigation within the tab bar uses left/right arrow keys to move between tabs, Enter or Space to activate a tab. Tab focus moves into the tab panel content after the tab bar.

The Actions dropdown uses the aria-haspopup="menu" attribute on the trigger button, and role="menu" with role="menuitem" on the dropdown content. Keyboard navigation within the menu uses up/down arrow keys. Pressing Escape closes the menu and returns focus to the trigger button.

Status badges in the page header are informational. They should carry aria-label attributes that describe their full meaning (for example, aria-label="Status: Active") rather than relying on color alone to communicate the state, since color alone is not accessible.

Guidance

The entity title in the page header is always a plain string. Do not embed clickable elements, icons, copy buttons, or editable inputs in the <h1> title. If inline editing of the title is required, use an edit icon button adjacent to the title that, when clicked, transforms the title into an editable input field. This keeps the heading structure and the interactive affordance separate.

Do NOT use more than one primary button in the detail page header. If there are two competing primary actions, only one of them is truly primary — demote the other to the Actions dropdown with the secondary treatment.

Do NOT add padding to the tab content panels themselves. The padding is inherited from the page shell and must not be doubled. Inner components (cards, tables) manage their own interior padding.

The Actions dropdown must always contain an option to navigate to "Edit" or "Configure" if the entity is editable, even if an inline edit pattern is also available within a tab. This ensures discoverability from the header without requiring users to explore tabs first.

Do NOT place destructive actions (Delete, Revoke, Reset) in the page header as visible buttons. They belong exclusively in the Actions dropdown, after a Separator from the constructive actions, and they must open a confirmation dialog before executing.

Data tables within tabs (for example, a History tab or a Permissions tab) carry their own full-width treatment. They should use negative horizontal margins equal to --force-layout-content-padding (24px) to bleed edge-to-edge within the content area, giving the table the visual weight it deserves for data-dense views. This is the only exception to the general rule that inner components do not reach into the shell's padding.

The Overview tab is mandatory for every entity with the detail view composition. It must be the first tab and must be named "Overview." All other tabs are optional and product-specific.

Composition

The detail view composes the Breadcrumb component (linked breadcrumb items with chevron separators), a PageHeader containing the entity title (<h1>), Badge components (subtle variant) for status indicators, a metadata row of text, and a Button cluster (primary action + Actions dropdown using DropdownMenu). The tab navigation uses the Tabs component with the underline variant and TabsList, TabsTrigger, and TabsContent. The Overview tab content uses CalloutCard components in a CSS grid row and Card components (with CardHeader, CardContent) in a ContentGrid. The optional metadata sidebar is composed of additional Card components using the same InfoCard structure. The Actions dropdown uses the DropdownMenu component with DropdownMenuItems, DropdownMenuSeparator, and error-colored items for destructive actions.