Skip to content

Styling and Theming

Styling is done using Tailwind CSS v4. AppShell exports @tailor-platform/app-shell/styles, which includes the default palette and CSS variables.

To configure your application, import AppShell styles from your global CSS or top-level Tailwind CSS file:

css
@import "tailwindcss";
@import "@tailor-platform/app-shell/styles";

If you want a branded palette, import exactly one theme file after styles:

css
@import "tailwindcss";
@import "@tailor-platform/app-shell/styles";
@import "@tailor-platform/app-shell/themes/bloom";

After including this, your application's Tailwind utilities will resolve against the active AppShell tokens.

E.g.

tsx
<div className="text-muted-foreground bg-muted">...</div>

Note, many of these are default Tailwind colors, but there are some differences. If you omit this, much of the UI will look the same, but we will lose some of the Tailor-preferred colors.

A note on AppShell component class names

AppShell components use Tailwind utility classes for their styling. Tailwind classes are generated at build-time, so stylesheet for AppShell components is already built and is separate to the Tailwind stylesheet generated for your application.

In CSS, the order of style-definition affects the final styles which are computed for an element. Tailwind takes this into account when generating its stylesheet, however because it does not know that there's already a Tailwind-generated stylesheet included in the browser (AppShell's styles), there would be incorrect ordering of style definitions, and clashes can (though do not always) occur.

To avoid this situation, and to ensure correct style resolution, AppShell components use a class prefix "astw" (AppShell TailWind) to avoid clashes.

This is important to note for developing in AppShell.

Color Themes (Light / Dark / System)

AppShell supports three color modes: light, dark, and system (follows the OS setting).

Set the initial mode via the defaultColorTheme prop on <AppShell>. The user's selection is persisted to localStorage and restored on subsequent visits:

tsx
<AppShell defaultColorTheme="system" modules={modules}>
  {/* ... */}
</AppShell>

Use the useTheme hook to read or change the theme at runtime:

tsx
import { useTheme } from "@tailor-platform/app-shell";

function ThemeToggle() {
  const { theme, resolvedTheme, setTheme } = useTheme();
  return (
    <button onClick={() => setTheme(resolvedTheme === "dark" ? "light" : "dark")}>
      Switch to {resolvedTheme === "dark" ? "light" : "dark"} mode
    </button>
  );
}

Drop the pre-built AppearanceSwitcher component anywhere in your layout for a ready-made light/dark/system toggle:

tsx
import { AppearanceSwitcher } from "@tailor-platform/app-shell";

<AppearanceSwitcher />;

Theme Palettes

AppShell ships three palettes, each with light and dark variants:

PaletteCSS import
defaultIncluded automatically via @tailor-platform/app-shell/styles
cream@tailor-platform/app-shell/themes/cream
bloom@tailor-platform/app-shell/themes/bloom

Select a palette by importing its CSS file — no prop needed. Import it in your global CSS after @tailor-platform/app-shell/styles:

css
@import "@tailor-platform/app-shell/styles";
@import "@tailor-platform/app-shell/themes/cream"; /* overrides default palette */
@import "tailwindcss";

Only import one palette at a time.

Z-Index Layering

AppShell defines CSS custom properties for z-index values so you can adjust the stacking order to integrate with other libraries or overlays in your application.

These properties are defined in :root and can be overridden in your own CSS:

PropertyDefaultUsed for
--z-sidebar10The sidebar panel
--z-sidebar-rail20The sidebar collapse rail / toggle button
--z-popup50Portal-based popups (Menu, Select, Combobox, Autocomplete, Tooltip)
--z-overlay50Modal overlays (Dialog, Sheet)

Example: Raising popup z-index

css
/* your-app/globals.css */
@import "tailwindcss";
@import "@tailor-platform/app-shell/styles";

:root {
  --z-popup: 100;
}

Adding a palette

Theme tokens live in packages/core/src/assets/themes/. Copy _template.css to start a new palette — it lists exactly which sections to fill in for light and dark mode.

SectionRequired?What to set
1. BrandYesprimary, secondary, accent (+ foregrounds) — both modes
2. Shell gradientBranded palettes only--shell-gradient-base, --shell-gradient-tint
3. SystemTune or copy defaultSurfaces: background, card, popover, muted, borders
4. PaletteOptionalRadius, chart colors, shadows
5. SemanticDo not duplicateStatus and alert tokens inherit from default.css
6. StructuralBranded palettesCopy the structural override block from bloom.css or cream.css when needed

A palette is selected by CSS import, not by an AppShell prop. Import exactly one theme file after @tailor-platform/app-shell/styles; if you import none, the default palette from styles is used.

Preview token values at /custom-page/color in the Next.js example app.