DocMosaicdocs

Theming

The shadcn-aligned semantic token surface and the base / brand-theme split. Rebrand with a single variable, or ship your own theme on top of the shared structural base.

@docmosaic/react reads every accent color, radius, and shadow from CSS custom properties - the same --background, --foreground, --primary, --secondary, --muted, --accent, --destructive, --border, --input, --ring, --radius every shadcn-based app already exposes. Rebrand the editor with the same variable an app uses for the rest of its UI.

No JavaScript-side theme provider, no runtime config - just CSS.

Mental model

The package ships its styles split into layers so you can swap colors without reinventing the structural defaults:

  • styles/base.css - brand-agnostic structural tokens (--editor-radius-section, --editor-shadow-section, --radius) and the cascade-layer order declaration.
  • styles/themes/docmosaic.css - the DocMosaic brand colors as shadcn semantic tokens, including the bundled .dark scope. Default.
  • styles/themes/minimal-light.css - shadcn-inspired neutral grays on a white surface.
  • styles.css - convenience bundle that imports base + the DocMosaic brand theme.

All token values land in a @layer docmosaic cascade layer. base.css declares the layer order as docmosaic, base, components, utilities - so any consumer that already has a shadcn :root { --background: ... } block in @layer base (the default Tailwind @tailwind base layer) wins automatically.

You pick one of these layering patterns at import time:

1. Default DocMosaic look      →  import '@docmosaic/react/styles.css';
2. Custom theme on shared base →  import '@docmosaic/react/styles/base.css';
                                  import './my-theme.css';
3. Explicit DocMosaic theme    →  import '@docmosaic/react/styles/base.css';
                                  import '@docmosaic/react/styles/themes/docmosaic.css';
4. Minimal light (shadcn-ish)  →  import '@docmosaic/react/styles/base.css';
                                  import '@docmosaic/react/styles/themes/minimal-light.css';

For dark mode, import styles.css (or themes/docmosaic.css) and toggle the .dark class on <html> - the theme ships a .dark scope. See the dark mode recipe.

Available themes

ThemeSurfaceAccentImport path
DocMosaicwhitedeep aubergine@docmosaic/react/styles/themes/docmosaic.css (default)
Minimal Lightwhitenear-black@docmosaic/react/styles/themes/minimal-light.css

Token reference

Color tokens are stored as space-separated RGB triplets so they compose with the modern rgb(R G B / <alpha-value>) syntax that Tailwind v3 and modern CSS expect.

Semantic surface (shadcn-aligned)

TokenPurposeDocMosaic value
--backgroundEditor canvas surround255 255 255
--foregroundDefault text on --background56 29 42 (#381D2A)
--cardElevated surfaces - sidebars, inspector255 255 255
--card-foregroundText on --card56 29 42
--primaryPrimary accent - buttons, active borders56 29 42
--primary-foregroundText/icons on --primary252 222 156
--secondarySoft accent - hover states, subtle fills252 222 156
--secondary-foregroundText on --secondary56 29 42
--mutedPlaceholder / disabled background244 244 245
--muted-foregroundPlaceholder / disabled text113 113 122
--accentSelection highlight196 214 176
--accent-foregroundText on --accent56 29 42
--destructiveErrors, destructive actions, warnings186 86 36
--destructive-foregroundText on --destructive255 255 255
--borderDefault border color228 228 231
--inputInput border color228 228 231
--ringFocus ring56 29 42
--radiusDefault border radius0.5rem

Structural tokens

TokenPurposeDefault
--editor-radius-sectionBorder radius for image sections6px
--editor-shadow-sectionShadow for image sections0 1px 3px rgba(0, 0, 0, 0.1)
--radiusDefault border radius0.5rem

One-variable rebrand

The fastest path. Override --primary and let everything else inherit:

:root {
    --primary: 79 70 229; /* indigo-600 */
    --primary-foreground: 255 255 255;
}

Every button, focus ring, and selected section reflects the new accent without touching the React tree.

Custom theme on shared base

For a full custom theme - every accent, surface, and border - supply the whole semantic surface:

import '@docmosaic/react/styles/base.css';
import './my-theme.css';
/* my-theme.css */
:root {
    --background: 250 250 252;
    --foreground: 15 23 42;
    --card: 255 255 255;
    --card-foreground: 15 23 42;
    --primary: 79 70 229;
    --primary-foreground: 255 255 255;
    --secondary: 224 231 255;
    --secondary-foreground: 15 23 42;
    --muted: 244 244 245;
    --muted-foreground: 113 113 122;
    --accent: 34 197 94;
    --accent-foreground: 255 255 255;
    --destructive: 220 38 38;
    --destructive-foreground: 255 255 255;
    --border: 228 228 231;
    --input: 228 228 231;
    --ring: 79 70 229;
    --radius: 0.5rem;
}

Dark mode

The bundled DocMosaic theme ships a .dark scope out of the box. Toggle the class on <html> (or any ancestor of the editor) and every semantic token flips.

With next-themes

The recommended pattern. attribute="class" toggles .dark on <html>, which the DocMosaic theme's .dark scope reads:

// app/layout.tsx
import { ThemeProvider } from 'next-themes';
import '@docmosaic/react/styles.css';

export default function Layout({ children }: { children: React.ReactNode }) {
    return (
        <html lang="en" suppressHydrationWarning>
            <body>
                <ThemeProvider attribute="class" defaultTheme="system" enableSystem>
                    {children}
                </ThemeProvider>
            </body>
        </html>
    );
}

See the dark mode recipe for a full walkthrough with the toggle button.

See also