"Can we get the ERP to match our brand colors" is a request I get from almost every client at some point, and the honest scoping conversation depends entirely on whether they mean "swap the accent color and logo" (an afternoon) or "restyle specific screens to match a very particular design system" (a real ongoing commitment). Modern UI's theming model supports both, but they're genuinely different amounts of work, and conflating them during scoping causes underestimated quotes.
CSS custom properties: the tier that covers most requests
Modern UI's qp-* component library is built on CSS custom properties (CSS variables) for its core visual tokens — accent color, base font, spacing scale, border radii. A theme applied at the instance or site level overrides these variables globally, and because every stock component already consumes them, this tier requires zero per-screen work — it cascades everywhere automatically:
:root {
--qp-accent-color: #0B5C3E; /* client's brand green */
--qp-accent-color-hover: #094a32;
--qp-font-family: "Segoe UI", sans-serif;
--qp-border-radius: 4px;
--qp-header-bg: #ffffff;
}
This is genuinely a small job — identify the client's brand palette, map it onto the variable set the framework exposes, package it as a theme, apply it. It covers the accent-color-and-logo request that's actually the majority of what clients ask for when they say "can it match our branding."
Per-component style overrides: where cost actually accumulates
The harder tier is when a client wants specific components restyled beyond what the variable set exposes — a grid with a genuinely different row-hover treatment, a form layout with non-standard field spacing, a toolbar that doesn't look like the standard qp-toolbar. This requires overriding the component's own scoped styles, which on a properly encapsulated component library usually means either a documented style-override hook the component exposes, or a more fragile CSS-specificity override targeting the component's internal structure:
/* Fragile — depends on internal DOM structure the framework
doesn't guarantee stable across versions */
qp-grid::part(row):hover {
background-color: var(--qp-accent-color-light);
}
CSS custom property overrides are stable across Acumatica version upgrades because they're an intentional, documented extension point. Overrides targeting a component's internal structure are not — a platform upgrade that changes a component's internal markup or class names can silently break a deep override with no warning, and you find out when a client reports a broken screen after an unrelated version update. I quote deep component overrides with an explicit line item for "revalidate after each platform upgrade," because that ongoing cost is real and clients deserve to see it upfront rather than discover it eighteen months later.
Scoping a theme: instance-wide, per-role, or per-screen
Themes can apply globally (every user sees the branded theme), which is the common case for a single-tenant client instance. Multi-branch or multi-entity instances sometimes want per-branch theming — a genuinely different accent color per subsidiary, so users can tell at a glance which company they're working in, which is a real safety feature on instances where users switch between branches frequently and mistaken postings to the wrong entity are a real risk. That's achievable by conditioning the applied CSS variable set on the current branch context, though it adds a layer of complexity worth confirming is actually needed before building it — most clients asking for "per-branch theming" are solving a training problem that a clearer branch indicator in the header solves just as well with far less ongoing maintenance.
Dark mode and accessibility contrast — test, don't assume
If the platform or the client's own theme includes a dark mode variant, every custom color override needs testing against both light and dark contexts explicitly — a brand accent color chosen for contrast against a white background can fail accessibility contrast ratios against a dark background, and testing only in the mode a developer happens to have open during development is how this slips through. I run a basic contrast-ratio check (WCAG AA, 4.5:1 for normal text) on every custom color pairing before considering a theme done, in both light and dark contexts if both are in scope.
The scoping question that saves a mismatched quote
Before quoting any theming request, I ask specifically: "show me an example of a screen you want changed, and point at what specifically should look different." That single question routinely reveals whether the request is a CSS-variable-tier job or a component-override-tier job, and the two are different enough in cost that quoting without asking it is how theming projects run over budget.
Wrapping up
Modern UI theming has two real tiers: CSS custom property overrides, which are cheap, stable across upgrades, and cover most branding requests; and component-level style overrides, which are more expensive, carry real upgrade risk, and deserve an explicit maintenance line item in any quote. Scope which tier a request actually needs before quoting it, and test any custom color choices for contrast in every mode the instance actually supports.
Independent software engineer in Nairobi specialising in Acumatica customisations, Laravel backends, and tax fiscalisation integrations across East and Southern Africa.