Skill v1.0.0
currentLLM-judged scan90/100triggers: ["app layout", "dashboard", "data table", "window resize", "responsive app"] name: matrix-app-ui-patterns description: UI patterns and layouts for Matrix OS apps — dashboards, workspaces, data views, mobile, and windowed contexts. Use this when building the interior of an app, not the design tokens (see matrix-design-system). version: 1.0.0 author: Matrix OS license: MIT platforms: [linux, macos] related_skills: [matrix-design-system, matrix-app-builder] metadata: agent: tags: [Matrix OS, UI, layout, patterns, dashboard, mobile, responsive] related_skills: [matrix-design-system, matrix-app-builder]
Matrix OS App UI Patterns
The color, type and material examples below use Matrix platform tokens as a baseline. Generated products substitute the coherent app-local semantic palette, typography, shapes and materials recorded in DESIGN.md; the examples do not require a muted palette or a single visual family. Keep task structure, responsive behavior, focus and accessibility intact.
When to Use
Use this when building the layout and interaction patterns inside a Matrix OS app. For colors, typography, and token values, use matrix-design-system. This skill covers how things are arranged, not how they look at the token level.
Context: Apps Run in Windows
Matrix OS apps render inside iframes within window frames. The OS provides title bar chrome (traffic lights, title, drag handle). Apps should:
- Fill the full window space:
html, body, #root { width: 100%; height: 100%; margin: 0; overflow: hidden; } - Handle arbitrary resize gracefully (min: 320×200px)
- Use their own scroll containers, not body scroll
- Never render their own title bar or window chrome
- Never add internal margin against window edges
- Keep fixed-format UI stable with explicit dimensions, grid tracks, aspect ratios, or min/max constraints so
hover states, labels, icons, tiles, and loading states do not shift layout.
App Shell Pattern
Choose a structure around the primary task. This shell is an option for apps with navigation, not a required dashboard wrapper for readers, tools, or games:
┌─────────────────────────────────────┐│ App Bar (optional) │├──────┬──────────────────────────────┤│ Side │ Content Area ││ bar │ ││ │ ││ │ │├──────┴──────────────────────────────┤│ Status Bar (optional) │└─────────────────────────────────────┘
.app-shell {height: 100vh;display: grid;grid-template-rows: auto 1fr auto;background: var(--bg);color: var(--fg);font-family: var(--matrix-font-sans, system-ui, sans-serif);}.app-content {display: grid;grid-template-columns: auto 1fr;overflow: hidden;}.app-main {overflow-y: auto;padding: 24px;}
Pattern: Dashboard
Use an overview only when real summaries help the user decide what to do. Do not invent statistics or add a greeting/command bar to every app. Prefer the core content for readers, focused tools, and games.
┌─────────────────────────────────────┐│ Good morning, Arian. ││ Monday, May 12 — 3 tasks │├───────────┬───────────┬─────────────┤│ 12 │ 3.2k │ 99% ││ Apps │ Requests │ Uptime │├───────────┴───────────┴─────────────┤│ ┌─────────────────────────────┬───┐ ││ │ Ask anything... │ → │ ││ └─────────────────────────────┴───┘ │└─────────────────────────────────────┘
- Heading uses the inherited shell font with a size appropriate to the window. Avoid redundant greetings.
- Stats use inherited fonts and tabular numbers; give labels sufficient size and contrast. Only show real, relevant metrics.
- Stat cards have
--bgbackground, 14px radius, 16px padding - Command bar is a composite input: text input + icon button in a single container with
--bgbackground, 14-16px radius - Keep the dashboard to a single scroll-free view when possible
Pattern: Data Table
For lists, records, logs — the workhorse view.
┌─────────────────────────────────────┐│ Title [Filter] [+ New] │├─────────────────────────────────────┤│ Name Status Date ··· ││ ──────────────────────────────── ││ Project A ● Active May 10 ··· ││ Project B ● Draft May 8 ··· ││ Project C ● Done May 5 ··· │└─────────────────────────────────────┘
- Header row: Inter weight 600,
--muted-fgcolor, tiny uppercase - Data rows: Inter weight 400, full
--fg - Row hover:
--mutedbackground, smooth 150ms transition - Status badges: pill-shaped with tinted backgrounds (see design-system badge variants)
- Row height: 48-52px for comfortable touch targets
- Alternate row backgrounds are NOT used — keep it clean with hover instead
- Border-bottom between rows: 1px
--border
Pattern: Detail / Side Sheet
For viewing a single record alongside a list.
┌──────────────────┬──────────────────┐│ List │ Detail Sheet ││ ● Item A │ ││ Item B │ Item A ││ Item C │ Status: Active ││ Item D │ Created: May 10 ││ │ ││ │ [Edit] [Delete] │└──────────────────┴──────────────────┘
- List takes 35-40% width, detail takes 60-65%
- Separator: 1px
--bordervertical line - On mobile (< 640px): detail overlays as a full-width sheet sliding from right
- Detail sheet close: X button, swipe right (mobile), Escape key
Pattern: Form
For settings, creation, and edit flows.
┌─────────────────────────────────────┐│ Create New Project ││ ││ PROJECT NAME ││ ┌─────────────────────────────────┐ ││ │ My Project │ ││ └─────────────────────────────────┘ ││ ││ DESCRIPTION ││ ┌─────────────────────────────────┐ ││ │ A brief description... │ ││ └─────────────────────────────────┘ ││ ││ CATEGORY ││ ┌─────────────────────────────────┐ ││ │ Productivity ▾ │ ││ └─────────────────────────────────┘ ││ ││ [Cancel] [Create] │└─────────────────────────────────────┘
- Labels: Inter 0.65rem, weight 600, letter-spacing 0.15em, uppercase,
--muted-fg - Inputs: 14px radius, 1.5px border, 12-14px vertical padding
- Form width: constrained to 480-560px max, centered if the window is wider
- Spacing: 20-24px between fields, 32px before action buttons
- Actions: right-aligned. Primary on the right, secondary on the left.
- Validation: show errors below the field,
--destructivecolor, only after the user has interacted
Pattern: Workspace / Canvas
For spatial apps: whiteboards, kanban boards, node editors.
- Full-bleed canvas: no padding, fills the entire window
- Floating toolbar: glass-morphism bar, positioned top-center or left side
- Toolbar buttons: ghost variant, compact visible icons with at least 44×44px touch hit areas; provide accessible labels, with tooltips as supplementary help
- Zoom controls: bottom-right corner, small pill-shaped container
- Canvas background: very subtle dot grid or topo pattern at 2-3% opacity
- Cancellation must be explicit: Escape/cancel should suppress follow-up blur commits for inline editors.
- Destructive actions and failed saves should not clear visible local state until the bridge/server confirms.
Pattern: Empty State
Every empty view needs:
- Icon or illustration — simple, monochrome, 48-64px
- Headline — Inter weight 600, 1-1.25rem, short, active voice ("No tasks yet")
- Description — Inter, one sentence,
--muted-fg - Call to action — a button or text link ("Create your first task")
Place the empty state in the same position where content will appear when populated. Don't center it in the viewport unless the entire view is empty.
Pattern: Notifications / Activity Feed
.notification {display: flex;gap: 14px;padding: 16px 20px;background: var(--bg);border-radius: 14px;border-left: 3px solid var(--primary);}
- Left border accent: Forest for informational, Ember for urgent
- Avatar: 32-36px, 10-12px radius, Inter weight 700 initial or icon on colored background
- Title: Inter 0.8rem weight 600
- Description: Inter 0.75rem,
--muted-fg - Timestamp: JetBrains Mono 0.6rem,
--muted-fg, right-aligned
Pattern: Mobile Adaptation
Apps should remain usable in narrow resizable containers, including 320px where supported. This is a fit check, not a fixed app minimum width. Follow Responsive layout and verification for observed width checks and accessible compact navigation.
- Sidebar → collapses to hamburger menu or bottom tabs
- Data table → labeled rows/details retaining all fields, or an explicit accessible scroll region for essential tables where comparison needs two dimensions
- Side sheet → full-width overlay
- Stats grid → 2 columns, then 1 column
- Command bar → full width with reduced padding
- Font sizes remain the same (don't shrink body text below 0.875rem)
Pattern: Loading States
- Skeleton screens: use
--mutedplaceholders matching the eventual content. Shimmer is optional; keep reduced-motion placeholders static and show ready content immediately. - Spinners: use a simple 16-20px circle with
--primarycolor, 2px stroke, rotating. Not a full-page overlay — inline where the content will appear. - Progress bars: 4px height,
--mutedtrack, fill color matches the context (Forest for neutral, Ember for important).
Composition Rules
- No marketing within apps. The first screen is the usable product. No hero banners, no onboarding carousels, no "Welcome to App Name" splash screens.
- Dense where useful. Productivity apps should pack information. Don't add whitespace between every element in a data table.
- Airy where reflective. Journals, notes, creative tools should breathe. More padding, fewer borders.
- One primary action per view. The main thing the user came to do should be immediately obvious.
- Never nest cards inside cards. If you need hierarchy, use muted backgrounds or border-left accents.
- Navigation fits the available container. Top tabs, a sidebar or accessible compact navigation should preserve all destinations; app navigation must not cover content or conflict with OS controls and safe areas.
- No layout shift under data refresh. Loading, empty, error, and populated states should reserve compatible
space for the same controls.
- Keyboard behavior is stateful. Pause overlays, inline editors, and selected tools should treat Enter,
Escape, and arrow keys according to the current mode instead of restarting or committing unexpectedly.