Communitygithub.com

App Shell UI

Build or restyle frontends with two deliberately separate modes: App Mode for a clean, restrained macOS-style desktop-tool shell, and Website Mode for public web frontends such as marketing sites, landing pages, portfolios, editorial surfaces, catalogs, and documentation.

What is App Shell UI?

App Shell UI is a reusable frontend design skill that enforces a deliberate separation between two fundamentally different surface modes: App Mode and Website Mode. App Mode is designed for logged-in tools, settings, consoles, chat, mail, workbenches, and operational flows, providing a persistent left navigation with a task canvas in a restrained, macOS-style desktop-tool aesthetic. It enforces strict rules including dual light/dark themes, a single brand accent, a surface and text ladder, stroke icons over emoji, equal-height side-by-side columns, and a single-viewport content budget to avoid unnecessary scrolling. Website Mode is for public-facing web work such as marketing sites, landing pages, portfolios, editorial and documentation sites, and uses normal document scrolling without app-like chrome. It guides the designer through a structured workflow: making a design read based on audience and tone, picking a surface mode (Persuade, Read, Experience, Catalog), selecting a macrostructure, committing to a visual system, planning media truthfully, building an information journey, implementing complete interactive behavior, and inspecting the rendered output. The skill can be used with plain HTML/CSS or frameworks like React and Tailwind, and it is ideal for developers and designers who need a disciplined, systematic approach to creating coherent, accessible, and visually polished user interfaces for both internal tools and public web surfaces.

Works with~Claude Code~Codex CLI~Cursor
npx skills add yg2224/app-shell-ui

Ask in your favorite AI

Open a new chat with this agent skill pre-loaded.

Documentation

What does App Shell UI do?

You are implementing App Shell UI: a reusable frontend design skill with two modes. Choose the surface before choosing pixels. Do not turn every request into a desktop shell, and do not turn every app into a generic marketing page.

Choose the surface first

ModeUse forDefault structureDo not use for
App ModeLogged-in tools, settings, consoles, chat, mail, workbenches, operational flowsPersistent left navigation + task canvasPublic marketing, reading, commerce, or portfolio surfaces
Website ModeMarketing sites, product launches, portfolios, editorial pages, catalogues, docs, public contentA page-specific macrostructure selected from the user journeyA generic hero + three cards + CTA template, or a fake app shell

If the request has both surfaces, design them separately: Website Mode for acquisition or public information, App Mode for the signed-in product. Share brand tokens where appropriate, but do not force the same layout or density across both.

Pre-flight (both modes)

Before making visual decisions in an existing project, inspect the route and its nearest visual source of truth: current tokens, typography, theme mechanism, assets, framework, component primitives, and installed icon/motion libraries. Preserve an established system unless the user asks for a redesign. Check package.json before adding a dependency; do not assume a library exists or mix two unrelated design systems in one surface.

If the brief is genuinely ambiguous between two materially different outcomes, ask exactly one short question. Otherwise state the inference in one sentence and continue. Do not turn a small implementation request into a requirements interview.

App Mode Workflow

  1. Pick a layout template (required before pixels):
    • Settings type — narrow left nav + form / toggle list
    • Console type — left nav + card grid / status list
    • Workbench type — session tree + centered empty state + composer card
    • IM / Three-column type — icon rail + list + detail
  2. Set the viewport budget — define the target desktop viewport (minimum 1280×800) and the one primary task for the route before adding content. See references/layouts.md → Viewport budget / Single page capacity.
  3. Lock dual-theme tokens — use references/tokens.md (light + dark are both required by default).
  4. Compose from recipes — use references/components.md (nav item, card, list row, toggle, pill, empty/composer). Recipes are theme-agnostic; only variables change.
  5. Implement with CSS variables + data-theme="light"|"dark"; add a theme toggle; Tailwind/shadcn mapping optional.
  6. Self-check — run the checklist at the end of this file in both themes and at the target viewport before delivery.

Default stack when free to choose:

LayerDefault
MarkupSemantic HTML or React
StyleCSS variables + light utility/Tailwind
Componentsshadcn / @coss style (New York + zinc-like neutrals)
IconsLucide-style 1.5–2px stroke, one family only
ThemeLight + Dark (toggle + optional OS prefers-color-scheme)

Prefer a single self-contained HTML for demos unless the user wants project integration.

App Mode Architecture

L0  Window chrome (optional traffic lights / title bar / top tools + theme toggle)
L1  Sidebar or icon rail
L2  Content canvas (soft gray light / soft charcoal dark)
L3  Surfaces (raised cards, panels, lists)

Sidebar width: 220–260px (text nav) or 48–56px (icon rail).
Content padding: 20–28px. Spacing on 4px grid.

Default page budget: the initial desktop state should complete its primary task in one viewport after the shell chrome is included. Keep a small bottom breathing room; do not make the whole page vertically scroll just to reveal routine secondary content. Long collections may use one bounded inner scroll region when the product genuinely needs it. Each page should ideally fit on one screen; stop stacking once the content fills the first viewport.

App Mode Non-negotiables

  1. Two themes: ship light and dark token sets unless the user explicitly wants only one.
  2. One brand primary for: primary buttons, toggle ON, progress fill, selected border/bg, links. Dark primary may be a slightly brighter twin (e.g. #007AFF → #0A84FF).
  3. Surface ladder (both themes): app bg → sidebar bg → raised surface (weak contrast). Light: soft gray + white cards. Dark: soft charcoal + elevated gray cards — not pure #000 page + pure #fff cards.
  4. Text ladder: primary / secondary / tertiary (values differ per theme).
  5. Hierarchy via 1px borders first; shadow optional and theme-specific.
  6. Radius ladder: 8 / 12 / 16 / 999 (shared across themes).
  7. Copy pattern: title + one muted subtitle line.
  8. Motion: 150–200ms color/background only; no bounce theater.
  9. Theme switch: data-theme on root + visible toggle; persist with localStorage when possible.
  10. Icon restraint (content): right-hand content defaults to text + stroke icons + status pills. Emoji/illustration are optional accents only — never the default for every list row or card. Prefer zero emoji in dense lists; at most one decorative mark in a banner or empty state.
  11. Equal-height peers: any side-by-side content pair (list + composer, panel + panel, stats siblings that form a pair of cards in one row) must share the same outer bottom edge. Use grid/flex stretch + column flex + flex: 1 on surfaces — never align-items: start that leaves one short card. See references/layouts.md → Equal-height side-by-side columns.
  12. Single-viewport content budget: on desktop, the default route must not require page-level vertical scrolling. Fill the usable canvas with prioritized content, but stop before the first viewport is exceeded. If content does not fit, remove, shorten, paginate, disclose, tab, or split it into another route; never clip controls or shrink text below readability. On mobile, keep the primary action and status in the first viewport; natural scrolling is reserved for genuinely long content.

App Mode Do / Don't

DoDon't
Left nav + right contentFull-bleed hero art as the whole app
Soft canvas + raised cards in both themesNeon cyber dark or pure OLED black by default
Single accent (paired light/dark)Rainbow nav icons as multiple primaries
Stroke icons (Lucide-style) in nav + contentMixed filled + stroke icon sets
Text-first cards/lists; pill for statusEmoji on every row / card / section header
Status as small pills / muted textLoud full-width alert banners for normal states
Theme toggle in chromeDark mode via filter: invert()
Border separation via tokensHard-coded #fff / #000 chrome colors
Airy spacingDense spreadsheet packing
≤1 emoji accent per major region (or none)Banner + cards + lists all emoji-heavy
Side-by-side cards equal height (stretch)One tall / one short peer (align-items: start)
One-screen route with prioritized blocksUnbounded page scroll for routine content
Bounded inner scroll for long collectionsHiding or clipping content with fixed heights

App Mode Page Assembly Order

  1. Shell (window + sidebar + main)
  2. Brand block in sidebar
  3. Nav groups + active item
  4. Page header (H1 + muted subtitle + actions)
  5. Theme toggle in titlebar or settings (required for demos)
  6. Optional toolbar (search + segmented filter)
  7. Content blocks by priority: banner → stats → primary grid/list → secondary two-column. Stop when the viewport budget is full; move lower-priority blocks to tabs, disclosure, pagination, or another route.
  8. For every two-column peer row: apply equal-height recipe (stretch + flex surfaces) without forcing overflow.
  9. Wire interaction: nav switch, selection, toggles, filters, theme toggle

App Mode Implementation Notes

  • Put light tokens on :root, :root[data-theme="light"] and dark on :root[data-theme="dark"] (see references/tokens.md).
  • Components only consume variables — no hard-coded brand/surface hex in component rules.
  • Selected nav: soft primary wash + primary text, radius 8px (wash mix differs by theme).
  • Cards: --bg-surface + 1px --border + radius 12; selected: primary ring/border. Leading mark = stroke icon in muted plate or no mark — not emoji by default.
  • Settings / feed rows: 16–18px stroke icon (optional soft plate) + title + muted desc + right control. Avoid emoji list icons.
  • Empty / new session: centered title + large rounded composer; chips + primary CTA. Empty watermark may be one faint stroke icon or a single subdued glyph — not a stack of emoji.
  • Banner: text-first; optional one small accent tile max (often none).
  • Dashed add zone for "empty collection + create" (plus sign, not emoji).
  • Secondary buttons, segment tracks, toggle OFF tracks must use theme tokens (--secondary-btn-bg, --seg-track, --toggle-off) — light gray rgba does not work on dark.
  • Keep the page shell fixed (min-height: 0; overflow: hidden) by default. If a list, log, table, or message history is inherently long, put scrolling on one bounded child region with a clear height budget; do not make the document body or whole content canvas the default scroll container.
  • Validate the first-load state at a desktop viewport of at least 1280×800 (and a narrow mobile viewport). Check that the primary task, controls, and status are visible without page scrolling and that no text or control is clipped.

Theme API (canonical)

// data-theme = "light" | "dark"
// localStorage key: "app-shell-theme"
// toggle flips attribute; init reads storage then prefers-color-scheme

Minimal CSS token block

Copy the dual-theme block from references/tokens.md.

Minimal HTML skeleton

<html data-theme="light">
…
<div class="window">
  <header class="titlebar">
    …
    <button type="button" data-theme-toggle aria-label="Toggle light/dark mode">…</button>
  </header>
  <div class="shell">
    <aside class="sidebar">…</aside>
    <main class="main">…</main>
  </div>
</div>

App Mode Prompt Seed

Light

macOS desktop-utility light UI: 240px soft-gray sidebar (stroke icons + label, selected = light primary wash + 8px radius), main canvas soft gray with white rounded cards; single primary #007AFF for buttons, toggles, progress, selection ring; three text grays; radius 8–16px; almost no shadow, 1px light borders; settings/list rows with small stroke icons (not emoji) + title/desc + right toggle or status pill; content area text-first, minimal or no emoji; empty state = centered title + large rounded composer.

Dark

Same shell in dark mode: soft charcoal canvas #1C1C1E, sidebar #161617, raised cards #2C2C2E, borders white 8% alpha, text #F5F5F7 / #A1A1A6 / #6C6C70, primary #0A84FF, selected nav = primary 22% mix into card surface; no pure black page; no invert filter; include theme toggle.

Swap business nouns only; keep shell + dual-theme rules.

Website Mode Workflow

Website Mode is for public-facing web work. It may use normal document scrolling and should not inherit App Mode's fixed canvas, sidebar, artificial window chrome, or one-viewport content limit. Read references/web-frontend.md before implementing Website Mode.

  1. Make a design read — state the page kind, audience, primary job, and a concrete tone. "Clean and modern" is not a direction. Infer from the brief and existing brand; ask one short question only when two directions would produce materially different work.
  2. Pick the surface mode — Persuade for a conversion page or launch, Read for docs or editorial content, Experience for portfolio/gallery/event work, or Catalog for browsing and buying. The signed-in product stays in App Mode.
  3. Pick a macrostructure before components — choose a page shape that fits the job, such as product reveal, evidence-led story, editorial narrative, work index, catalogue, reading guide, or campaign poster. Do not default to centered hero -> three equal cards -> CTA.
  4. Commit to a visual system — lock a palette, type roles, spacing/radius rules, image treatment, and one visible differentiator. Reuse existing brand tokens; otherwise define semantic CSS variables and consume them rather than improvising colors or fonts per section.
  5. Plan truth and media — use supplied facts, real screenshots/product states, licensed assets, or generated bitmap visuals appropriate to the brief. Do not invent customers, metrics, testimonials, logos, fake dashboards, browser chrome, or placeholder data that reads as real. Unknown claims stay visibly marked as placeholders or are omitted.
  6. Build the information journey — use semantic landmarks and a hierarchy that makes the next action obvious. Let sections vary in composition when their jobs differ; cards are for repeated, bounded items rather than a default page-section wrapper.
  7. Implement complete behavior — use native controls and links, visible focus, loading, empty, error, disabled, and success states when relevant. Motion must explain feedback or spatial change, use transform/opacity, respect prefers-reduced-motion, and stay out of high-frequency flows unless it is effectively instant.
  8. Inspect rendered output — validate desktop and mobile screenshots, real content extremes, contrast, keyboard navigation, loading image dimensions, overflow, and the first viewport. The hero's proposition, primary action, and visual focal point must fit at 1280x800; page scrolling below it is normal for a website.

Website Mode non-negotiables

  1. Do not wrap a public website in App Mode chrome unless the user explicitly asks for a product preview or signed-in application route.
  2. Give every public

…

[truncated for translation]

Related Skills