Skip to content

Admin-Generated Themes

Baan’s Admin panel includes an AI theme generator. You describe what you want in plain text and the system produces a complete, functional theme. No file editing or code required.


The generator runs a three-step pipeline internally:

Your prompt (free text)
Step 1 — Design Brief AI
Interprets your concept → concrete values:
colors (HEX), layout type, card style, atmosphere
Step 2 — Preset Selection (no AI)
Picks the closest built-in preset as a structural base:
default / geek / news / the-publish
Step 3 — CSS-only AI
Generates the color palette in CSS variables
using the exact values from Step 1
Server enforces contrast minimums
--foreground lightness ≤ 15%
--muted-foreground lightness ≤ 40%

The AI never generates TSX components. Layout and structure come from the hand-crafted presets — only the color palette is AI-generated. This keeps the output consistent and avoids broken UI.


  1. Go to Admin → Settings → Theme
  2. Click Create new theme
  3. Switch to the Admin AI tab (the AI Agent tab is selected by default — that’s the recommended approach)
  4. Enter a theme name (lowercase letters and hyphens, e.g. spring-journal)
  5. Write a design concept (see tips below)
  6. Optionally choose component variants manually (or leave on “auto”)
  7. Select an AI model
  8. Click Generate

The new theme appears in the theme list immediately — select it and preview with the Customizer.


The most common mistake is being too vague. The AI interprets ambiguous prompts literally, often producing generic results.

Vague (poor results):

Something spring-like

Specific (good results):

Atmosphere: soft spring morning, cherry blossoms and fresh green, clean and elegant
Colors: light salmon pink and white base, muted green accent
Layout: single-column with generous whitespace
Card style: minimal (text-focused, no cover images)
Effects: subtle border on cards, light gradient in the header
ElementWhat to specify
Atmosphere1–2 sentences describing the mood or reference
ColorsBackground, text, accent — HEX values if you have them
LayoutSingle-column / two-column / sidebar position
Card styleImage-heavy, text-only, overlay, or minimal
EffectsShadows, gradients, border radius, animations
VariantDescription
single-columnFull width, no sidebar — good for writing-focused blogs
two-columnContent + right sidebar (default)
two-column-leftLeft sidebar + content
three-columnLeft + content + right
VariantDescription
cardImage + text, standard blog card (default)
list-itemHorizontal layout, image left
overlayText overlaid on full-bleed image — dramatic
minimalTitle, date, excerpt only — no images

The pipeline produces files saved in .theme-generated/{name}/:

.theme-generated/my-theme/
├── config.json ← layout, variants, Tailwind classes
├── styles/
│ └── theme.css ← CSS variables (colors, radius, fonts)
├── theme.json ← display name, fontKey, version, `ai` field
├── prompts/
│ └── concept.md ← your original prompt + the Design Brief JSON
└── _meta.json ← generation history, model used, prompt

These are also copied to public/themes/{name}/ (Docker) or cloud storage (Vercel) so the browser can load them at runtime without a rebuild.

Like all Baan themes, admin-generated themes follow the Theme Provenance specification: theme.json includes an ai field with agent: "Baan Admin", and prompts/concept.md captures both your original prompt and the Design Brief JSON produced by the pipeline. This means even admin-generated themes can be forked, shared, or regenerated with a different AI agent — the design intent travels with the theme.

The theme renders using Universal components (lib/theme/universal/) — shared TSX components that read config.json to determine layout and appearance. No theme-specific TSX is written.


Open the theme in Admin → Settings → Theme and use the chat UI to make changes in plain language:

Make the tag colors more muted
Switch the header to compact style
Increase the card border radius
Change the accent color to a warm amber

Each adjustment reads the existing config.json and theme.css and modifies only what you specified. The generation history is preserved in _meta.json.


Baan enforces WCAG AA contrast minimums server-side regardless of what the AI outputs:

  • --foreground (body text): lightness ≤ 15%
  • --muted-foreground (dates, tags, secondary text): lightness ≤ 40%

This prevents the most common failure mode — AI-generated light-on-light color combinations that make secondary text invisible.


The generator selects a preset based on your concept. The preset determines layout structure; the AI fills in colors.

PresetChosen whenLayoutHeaderCards
defaultGeneral two-column conceptsTwo-columnCentered large titleGrid
geekSingle-column, minimal, typographicSingle-columnCompact leftList
newsCompact header with card/list-item styleTwo-columnCompactFeatured-grid
the-publishOverlay card style, editorialTwo-columnCenteredOverlay

The selection logic:

  1. overlay card style → the-publish
  2. single-column layout or minimal card style → geek
  3. compact header with card/list-itemnews
  4. Everything else → default

If the Design Brief generation fails (AI timeout, JSON parse error), the pipeline falls back to the geek preset (single-column, no sidebar) as a safe default.

You can override the preset selection by explicitly specifying a layout and card style in your concept.


Admin-generated themes are constrained to the available variants and preset structures. For anything outside that — a fully custom layout, unique interactive elements, a reading progress sidebar — use AI Agent Built themes instead.

The Admin UI also shows an AI Agent tab with a copyable prompt template. This is the recommended approach for higher quality results.