Getting it into your agent
One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.
npx skills add bendaamerahmed/backstage-idp-plugin --skill backstage-theminggit clone --depth 1 https://github.com/bendaamerahmed/backstage-idp-pluginWrote this? Show the measurements
A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.
[](https://agentmods.dev/skills/bendaamerahmed/backstage-idp-plugin/backstage-theming)<a href="https://agentmods.dev/skills/bendaamerahmed/backstage-idp-plugin/backstage-theming"><img src="https://agentmods.dev/badge/skills/bendaamerahmed/backstage-idp-plugin/backstage-theming/github.svg" alt="Measured on agentmods" height="20"></a>Or the 80×15 button, for a site that already has a row of RSS and ATOM ones. Only the verdict fits; the numbers stay here.
<a href="https://agentmods.dev/skills/bendaamerahmed/backstage-idp-plugin/backstage-theming"><img src="https://agentmods.dev/badge/skills/bendaamerahmed/backstage-idp-plugin/backstage-theming.svg" alt="Reviewed on agentmods" width="80" height="20"></a>What it costs to keep this loaded
Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.
| Model | Per session | Once invoked |
|---|---|---|
| Fable 5.1 | $0.00042 | $0.02288 |
| Opus 5 | $0.00021 | $0.01144 |
| Sonnet 5 | $0.00008 | $0.00458 |
| Haiku 4.5 | $0.00004 | $0.00229 |
Grade A, and why
backstage-theming scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 10d ago.
A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.
Nothing flagged
None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.
How it starts
The opening of the file, as written. The whole thing — 151 lines — stays where its author put it; the contents beside it link to each section on GitHub.
Backstage theming and design
Two theme systems run side by side in a current Backstage app, and most theming bugs are one of them being styled while the other is not. Decide which surface you are changing before you change anything.
Preconditions
- Frontend generation known. NFS:
createAppfrom@backstage/frontend-defaults, themes registered as extensions viaThemeBlueprintfrom@backstage/plugin-app-react. Legacy:createAppfrom@backstage/app-defaultswith athemesarray option. The theme objects are nearly identical; only registration differs. Runbackstage-repo-discoveryif unsure. - Which system owns the pixels you are changing:
@backstage/ui("BUI") — CSS custom properties,--bui-*. Newer surfaces: entity cards, headers, tables, form controls.@backstage/theme+ Material UI — a JS theme object. Older plugin pages and every third-party plugin that has not migrated. A portal on a current line contains both. Styling one and declaring victory is the single most common outcome here.
packages/app/src/index.tsximports@backstage/ui/css/styles.css. Without it no BUI token has a value and every BUI component renders unstyled.- Exact theme factory signatures (
createUnifiedTheme,createBaseThemeOptions,genPageTheme, and theThemeBlueprintinput shape) read from the installed@backstage/themeand@backstage/plugin-app-reacttypes, not from memory. - Brand assets available as real files. Do not invent colour values; ask for the brand tokens or read them from an existing asset, and record the source.
Procedure
- Inventory what is themed today.
rg -n "createUnifiedTheme|UnifiedThemeProvider|ThemeBlueprint|themes:" packages/app/srcandrg -n "\-\-bui-" packages plugins. Note whether a custom theme exists at all — a defaultcreate-apphas none, and adding the first one is a different job from editing an existing one. - Change BUI tokens first, in one place. Override the custom properties on
:rootin a stylesheet imported after@backstage/ui/css/styles.css. The families are--bui-bg-*,--bui-fg-*,--bui-gray-*,--bui-accent-*,--bui-border-*,--bui-radius-*,--bui-font-*,--bui-space-*, plus the status families--bui-positive-*,--bui-negative-*,--bui-warning-*and--bui-announcement-*. Read the shippeddist/css/styles.cssin the installed@backstage/uifor the exact names on your version; they are added to between minors. - Do light and dark together or neither. BUI scopes its palette with a
data-themeattribute on a root element. An override written only against:rootleaks the light value into dark mode, which looks like "dark mode is broken" and is really a missing scoped override. Set every colour token under both selectors. - Then the Material UI side.
createUnifiedThemefrom@backstage/themeproduces a theme both v4 and v5 consumers can use;createUnifiedThemeFromV4adapts an existing v4 theme rather than rewriting it. Compose fromcreateBaseThemeOptionsandpalettes.light/palettes.darkinstead of building a palette by hand — the defaults carry the page gradients and status colours plugins expect to exist. - Set page themes deliberately.
genPageTheme({ colors, shape })builds the header gradient per page type (home,tool,service,website,library,app,apis,documentation,other). Omitting a page type leaves it on the default, which is the usual cause of "one page still has the old header". - Register the theme for your generation.
- NFS: create a theme extension with
ThemeBlueprintfrom@backstage/plugin-app-reactand add it to a frontend module. Read the blueprint's parameter names from the installed package before writing it. - Legacy: pass
themes: [{ id, title, variant, icon, Provider }]tocreateApp, withProviderrenderingUnifiedThemeProvider. Registering a theme does not select it: users pick per account in settings, so verify by switching, not by loading the page once.
- NFS: create a theme extension with
- Keep
BUIProviderin the tree, inside the router. It supplies the analytics context and, when it detects a router, installs react-aria'sRouterProviderso BUI navigation resolves client-side. Outside the router it silently degrades to no routing integration. - Override a component's look through its definition, not its internals.
Each BUI component exports a
<Name>Definitionalongside it. Prefer a token change, then a definition override, then a wrapper component. Never target BUI's generated class names — they are not a public API and change without a major. - Brand the app shell. Logos live in
packages/app/src/modules/nav/(LogoFull.tsx,LogoIcon.tsx,SidebarLogo.tsx) in a current scaffold. Replace the SVG contents, keep the components' exported names and theirviewBox-driven sizing, and check the collapsed sidebar as well as expanded. - Set
app.titleandorganization.nameinapp-config.yaml. They drive the browser title and several page headers, and a rebrand that misses them leaves the old name in the tab. - Check contrast before shipping. Brand colours frequently fail WCAG AA on Backstage's surfaces, particularly accent-on-surface for links and the status families. Fix the token, not the component.
What this file has done since we first saw it
Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.
- 10d ago First seen · 151 lines · 42 tokens per session scan A faaffd15b35d
backstage-theming is a skill published in the GitHub repository bendaamerahmed/backstage-idp-plugin (1 stars, last pushed 1mo ago), licensed MIT. It adds 42 tokens to every session and 2,288 once invoked, about $0.0002 per session on Opus 5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-31.
Other skills, from other repositories
shiny-bslib-theming
Advanced theming for Shiny apps using bslib and Bootstrap 5. Use when customizing app appearance with bstheme(), Bootswatch themes, custom colors, typography, brand.yml integration, Bootstrap Sass variables, custom Sass/CSS rules, dark mode and color modes, dynamic theme switching, real-time theming, theme inspection…
shiny-bslib
Build modern Shiny dashboards and applications using bslib (Bootstrap 5). Use when creating new Shiny apps, modernizing legacy apps (fluidPage, fluidRow/column, tabsetPanel, wellPanel, shinythemes), or working with bslib page layouts, grid systems, cards, value boxes, navigation, sidebars, filling layouts, theming…
interface-craft
Raises the visual and interaction quality of an interface — layout, hierarchy, type, spacing, density, and the details that separate a considered product from a generic one. Use this when a screen works but looks unfinished or default, when a layout feels crowded or arbitrary, when a page has no clear focal point, or…
design-system
Builds and maintains the design system a product is assembled from — tokens for color, type, spacing and elevation, component contracts, and the rules that keep them coherent as the product grows. Use this when starting a new interface, when screens have drifted apart visually, when the same component exists three…
interface-redesign
Upgrades an existing interface to a higher standard without rebuilding it — auditing what is there, identifying what reads as generic or unfinished, and sequencing changes by impact. Use this when a product works but looks dated or default, when a redesign is being considered, when deciding whether to restyle or…
design-motion
Use when adding or reviewing motion on an already-settled layout or component — never to hide or compensate for an unfinished one.