Skip to content

Surfaces (dark & light)

Ordermatic is intentionally dual-surface: a dark β€œcockpit” frame (the rail, nav, dark panels) around a bright, scannable work surface. The design system models this with adaptive tokens that flip per surface β€” not a global light/dark toggle.

West DCsubmitted
West DCsubmitted

Nothing about the components changes between the columns. Only the wrapper differs.

Wrap a region in Surface (or set data-surface). That flips a small set of adaptive tokens and color-scheme for everything inside:

import { Surface } from '@repo/ui';
<Surface variant="dark">
<Button variant="outline">Works on dark</Button>
</Surface>
Adaptive token Light Dark
--om-bg workspace paper ink-black
--om-panel white raised navy
--om-panel-2 subtle paper ink
--om-text ink white
--om-text-2 grey warm white
--om-text-muted light grey fog
--om-line bone border hairline
--om-hover paper wash white 6%

color-scheme rides along, so native controls (radio, checkbox, select) match their surface automatically β€” no dark widgets stranded on a light card.

  • Build primitives on adaptive tokens (--om-text, --om-panel, --om-line…), not the fixed --om-surface-* / --om-fg-on-light-* primitives. That’s what makes them work anywhere.
  • This is surface-scoped, not a user theme toggle β€” you opt a region into dark; content stays on the bright workspace by brand intent.
  • Status colors stay fixed (system signals read on both surfaces). Card is the one component where you pick the surface explicitly (variant="dark").

In apps/webapp, the dual-surface system powers the AppShell + Three-Pane Cockpit architecture (ShellFrame.astro + CockpitShell.astro):

  • Dark Cockpit Frame (--om-indigo-black): ShellFrame.astro renders a full-viewport (h-screen w-screen overflow-hidden) dark frame with the 56px AppRail.astro (RailNav.tsx) on the left and optional top ImpersonationHazard.astro banner.
  • Bright Three-Pane Workspaces (--om-bg / --om-panel): Inside CockpitShell.astro (scroll="hidden"), both primary operator workflows use three independently scrolling panes framed by --om-line hairlines:
    1. /inbox (InboxCockpit.tsx): 56px dark AppRail β†’ center CockpitRow queue list pane β†’ right CockpitDetail + CockpitItemPreview pane.
    2. /orders/pdf/[documentId]/review (ReviewResponsiveBody.tsx): 280px ReviewIssuesRail β†’ minmax(320px, 1fr) ReviewCenterPane / RevisionPanel β†’ minmax(0, 1.5fr) ReviewDocViewer (PDF/spreadsheet/email preview with synchronized bounding-box highlights), anchored above ReadinessFooter.tsx.