Theming
The Blueprint AI panel is styled by a CSS-flavored split stylesheet under Plugins/BlueprintAI/Resources/Theme/. Every visible element — text, borders, buttons, code blocks, the terminal — reads from this stylesheet. Changes hot-reload as soon as you save a .json file under the directory.
Directory layout
Section titled “Directory layout”Resources/Theme/├── _shared/ ← design tokens, typography, icons, scroll│ ├── _tokens.json ← :root design tokens (--brand-blue, --panel-bg, ...)│ ├── typography.json│ ├── icon-base.json│ ├── icon-button.json│ └── scroll.json├── ChatPanel/ ← message bubbles, tool-use blocks, thinking, etc.├── InputBar/ ← input field, action row, attachments, send button├── Session/ ← session drawer├── Terminal/ ← terminal-specific colors and font├── Onboarding/ ← login screen├── Mode/ ← mode selector modal└── ... (one folder per widget feature-area)The subdirectories are grouped by panel area (chat, input bar, terminal, sessions, …), so finding the stylesheet for a particular widget is usually a one-folder hop.
File format
Section titled “File format”Each .json file is a flat list of CSS-style selector → property maps:
{ ":root": { "--brand-blue": "#5a9abf", "--brand-cream": "#f5eed6" }, ".message-bubble": { "background-color": "var(--panel-bg)", "padding": "12px 14px", "border-radius": "var(--border-radius)" }, ".send-button:hover": { "background-color": "var(--button-hover)" }}- Top-level keys are CSS-style selectors (
.class-name,:root,.foo:hover,.foo.bar). - Nested objects hold the CSS properties.
:rootdefines--variablesthat any rule can reference viavar(--name).
Design tokens
Section titled “Design tokens”The authoritative tokens live in _shared/_tokens.json. Every widget references these, so flipping a token here cascades to every chat bubble, button, border, and font that uses it.
{ ":root": { "--brand-blue": "#5a9abf", // primary accent "--brand-cream": "#f5eed6", // secondary accent
"--text": "#C0C0C0", "--text-muted": "#808080", "--panel-bg": "#242424", "--input-bg": "#0E0E0E", "--code-bg": "#151515", "--terminal-bg": "#151515", "--border": "#575757", // ... }}Edit a token here and every widget that references it updates on the next save.
Property support
Section titled “Property support”The stylesheet engine understands a subset of CSS that maps cleanly to Slate’s brush / font / margin model:
| Property | Maps to |
|---|---|
background-color, border-color | Slate brush color |
color | Text color |
padding, margin | FMargin (CSS shorthand: 12px 14px, 12px 14px 8px 10px) |
border-radius, border-width | Brush corners + outline |
font-family, font-size, font-weight | Font info |
width, height | FOptionalSize |
gap | Slot padding inside containers |
opacity | Render opacity |
linear-gradient(...) is supported for backgrounds (background: linear-gradient(135deg, #5a9abf 0%, #f5eed6 100%)) — the engine resolves it into a UE gradient brush.
Properties the engine doesn’t understand are ignored, with a warning in the editor Output Log.
Selectors
Section titled “Selectors”| Selector | What it matches |
|---|---|
:root | The global token scope |
.foo | Any widget tagged with the foo style class |
.foo.bar | Widgets tagged with both foo and bar |
.foo:hover | foo widgets while hovered |
.foo:active | foo widgets while pressed |
.foo:focus | foo widgets with keyboard focus |
.foo.disabled | Used when the widget is in a disabled state |
Every panel widget is pre-tagged with the right style classes, so dropping a new property into an existing rule (.message-bubble, .send-button, …) takes effect immediately — no recompile, no editor restart.
Hot reload
Section titled “Hot reload”Saving a .json file under Resources/Theme/ triggers an immediate re-parse and re-style of every visible Blueprint AI panel. There’s no editor restart, no recompile.
If you make a typo (invalid JSON, unknown property), the engine logs a structured warning and keeps the previous valid stylesheet. You’ll see the diagnostic in the Output Log filtered to BlueprintAI/Stylesheet.
Last-wins merge
Section titled “Last-wins merge”The loader walks the directory tree recursively in sorted path order and merges rules. When two files set the same (selector, property) pair, the later one wins.
This lets you keep:
- Shared / token files near the top (
_shared/_tokens.jsonis loaded first because_sorts first) - Feature-specific overrides under the matching subdirectory
You don’t need to worry about file order beyond that — the sort is deterministic.
Adding a custom theme
Section titled “Adding a custom theme”To keep your overrides separate from the bundled stylesheets:
-
Create
Resources/Theme/_custom.json(the underscore prefix loads it early, but not before_shared/; alphabetically_custom≥_shared). -
Override any tokens you want:
{":root": {"--brand-blue": "#ff6b35","--brand-cream": "#ffeaa7"}} -
Save. Every Blueprint AI panel re-renders in your palette.
Removing the file restores the defaults.
Light mode
Section titled “Light mode”The panel is dark-only by design — it lives inside Unreal’s dark editor and a white block would clash. To run it light anyway, override the dark tokens in _custom.json:
{ ":root": { "--panel-bg": "#faf7eb", "--text": "#1a1a1a", "--input-bg": "#ece5cd", "--border": "#b9b6a5" }}Revisit the gradient stops too — the cream-on-blue contrast is tuned for dark.