There is a moment in almost every ERP rollout that nobody puts in the project plan. A quality engineer opens the new system, looks at it for about four seconds, and quietly decides how much of their day they are going to spend avoiding it.
That decision is not made on feature coverage. It is made on the screen.
Gartner surveyed nearly 5,000 employees in 2021 and found that 60% had been frustrated by new software introduced in the previous two years, 40% had actively resisted using an application after a bad experience, and 51% named easier usability as the single improvement they most wanted from vendors. Gartner’s Craig Roth put the cause plainly: software teams keep adding features to keep pace with competitors, and the result is overly complex products with poor user experience.
ERP is the most exposed category of all, because the people using it did not choose it, and because they spend their evenings using software built to a completely different standard.
So when we built the Quality and Maintenance platform for an automotive component manufacturer, the interesting part of the brief was not the functional scope. It was whether an ERP module can be built to the same visual and interaction standard as the tools people actually like.
The constraint that made it interesting: Odoo 17 Community Edition. Odoo’s Quality Management app, the tablet Shop Floor interface, PLM and barcode manufacturing operations are all Enterprise. On Community you do not get a quality module to restyle. You get a framework, and you build the whole thing. Which means every screen in this article is a design decision somebody had to make on purpose, with nothing to inherit and nothing to blame.

Everyone serious about enterprise UI already has a standard
The useful thing about arguing for design standards in ERP is that you do not have to invent the argument. Every major enterprise software vendor has already made it, in public, in writing.
IBM Carbon puts the entire system on an 8px mini-unit. Breakpoints, gutters, padding and type all derive from it. Carbon’s type scale is generated from a single equation off a 12px base, and it splits into Productive styles for dense product UI and Expressive styles for editorial content. Its rule on theming is the one worth stealing: tokens are universal and never change across themes, only their values do.
Microsoft Fluent 2 separates global tokens, which are raw context-free values, from alias tokens, which carry semantic meaning. It states an explicit accessibility target: components meet or surpass WCAG 2.1 AA, with 4.5:1 contrast on body text, 3:1 on large text and non-text UI components, reflow without horizontal scroll at 400% zoom, and text zoom to 200% without clipping.
SAP Fiori does something that matters enormously for manufacturing and that almost nobody replicates in Odoo. It ships two named content density modes. Cozy gives roughly 3rem control heights for fingertip use. Compact gives roughly 2rem for mouse and keyboard, with more rows per screen. SAP’s documentation warns that density has to be set explicitly across an application, because controls do not agree on a default. That is exactly the failure mode of bolting a touch interface onto a desktop ERP.
Atlassian expresses its 8px base as percentage-named tokens, space.100 for 8px through space.1000 for 80px, and instructs designers to use tokens in place of raw pixel values everywhere.
Vercel’s Geist, which is where we drew most of our visual reference, is the cleanest articulation of the colour and type problem. Its non-background colour scales have ten fixed steps with fixed semantic roles: 100 to 300 for component backgrounds at rest, hover and active, 400 to 600 for borders, 700 to 800 for solid high-contrast fills, 900 to 1000 for text and icons. Typography is expressed as presets grouped by job, not by size: Headings, Labels for single-line UI text, and Copy for multi-line reading with a taller line height. You do not pick 14px. You pick a label.
And Linear, describing its most recent refresh, gave the two sentences we ended up quoting back to ourselves most often during this build: “Don’t compete for attention you haven’t earned” and “Structure should be felt not seen.”
Notice what none of these are. None of them are a component library you install. They are a set of decisions, written down, applied consistently. That is the part ERP is missing, and it is the part you can adopt without a single vendor dependency.
Reference, not dependency. To be precise about what we did and did not use: no Geist code is in this build. Not a component, not a stylesheet, not a package. Every component in these screens is custom OWL written for this project, and the token layer is our own. What we took from Geist was the thinking, the ten-step scales with fixed semantic roles, and typography expressed by job rather than by size.
That distinction also happens to be the licensing-safe one. The Geist Sans and Geist Mono typefaces are released under the SIL Open Font License 1.1, which permits embedding inside a commercial product provided the fonts are not sold on their own and modified versions do not reuse the Geist name. The Geist component library and Vercel’s brand marks are a separate matter and are not published for general reuse. A design system is a set of decisions. You can adopt the decisions without adopting anybody’s code.
What this actually looks like in Odoo 17 Community
Odoo does give you the mechanism. It is just under-documented and rarely used properly.
The web client is a single-page application built from the web addon, mid-migration from the legacy widget system to OWL, Odoo’s own declarative component framework with QWeb XML templates. Odoo’s developer documentation is unambiguous that all new front-end development should be done in OWL.
Styling flows through asset bundles declared in the module manifest. Beyond simple appends, the manifest supports prepend, before, after, replace and remove directives, and load order is deterministic precisely because stylesheet priority depends on it.
The mechanism that makes a token layer possible is Odoo’s SCSS inheritance model. Odoo explicitly warns against reassigning its variables directly, because compilation spans interdependent bundles and a reassignment in the wrong place cascades unpredictably. The sanctioned approach is SCSS’s !default flag: a value is only assigned if not already defined, so priority becomes a function of asset load order. In practice that means injecting your variable file into web._assets_primary_variables ahead of Odoo’s own, and keeping component-level styling in web.assets_backend.
That is the whole trick. One file defines the scales. Everything downstream inherits them.
Everything above that layer is custom OWL. The launcher, the dashboards, the stat tiles, the charts, the responsive behaviour of the tables: components written for this project against Odoo’s own framework, with no third-party component library underneath. That was not stubbornness. Once the token layer exists, writing an OWL component that consumes it is cheaper than bending someone else’s component to fit Odoo’s rendering model, and it leaves nothing to license, patch or replace later.

Six rules we now apply to every module
1. The number that matters is the biggest thing on the screen.
Our Quality Dashboard opens with three headline tiles, and reject rate is the one carrying colour and weight, with its denominator printed underneath: 4,892 defects against 1,438,204 readings. Below that sit the seven operational counts, in a single scannable row, in a smaller type step. Below that, analysis. A quality manager should learn whether today was a good day without constructing a pivot.
The visual hierarchy is not decoration. It is a claim about what matters, and it should be defensible.
2. Navigation follows the workflow, not the model list.
The Quality module carries 21 destinations. Ordered alphabetically or by model name, that is a wall. Grouped into Operations, Analytics and Setup, with a coloured rail marking each group, it becomes three short decisions. The user is not browsing your data model. They are trying to get to the thing they came for.
3. Density is a decision, not a default.
This is Fiori’s lesson and it is the one Odoo implementations most consistently miss. A quality engineer reviewing a 170-row operations table on a desktop wants compact rows, sticky headers, and as much on screen as legibility allows. An operator recording a Pass or Fail on a tablet at the machine wants targets they can hit while wearing gloves.
WCAG 2.2 sets a Level AA minimum target size of 24 by 24 CSS pixels, and WCAG 2.1 sets a Level AAA enhanced size of 44 by 44. For gloved, one-handed, badly-lit shop floor use, we treat the 44px AAA figure as the floor rather than the aspiration. That is a different density token set from the back-office view, and it needs to be built deliberately.

4. Tables have to earn their density.
Density is not the same thing as clutter. A 170-row operations grid works because the header is a solid contrasting band that stays put, because row striping is faint enough to guide the eye without competing, because status renders as a pill rather than free text, and because destructive actions are pushed to the right edge and given a single consistent icon. Every one of those is a token decision, not a per-view decision.
5. Cards carry identity, not everything.
The product kanban shows a thumbnail, part code, description, customer, customer part number, a plant tag, and a PIR count badge. That is seven facts, chosen because they are the seven a quality engineer uses to identify the right part. Everything else lives one click away. Linear’s line applies directly here: do not compete for attention you have not earned.

6. A phone is a supported viewport, not a degraded one.
This is where Community Edition bites hardest, and where most Odoo implementations quietly give up. The Odoo backend is a desktop application that happens to render in a browser. Put a standard list view on a phone and you get a horizontally scrolling table. Put a two-column form group on a phone and the labels and fields fight for the same 380 pixels. The community has been patching around this for years, which is why the OCA maintains a responsive web module at all.
We treated mobile as a first-class target rather than a fallback, and that turned out to be a token problem more than a layout problem. Three decisions did most of the work.
- Breakpoints live in the token layer. The same variable file that defines the colour steps defines where the grid collapses. A view does not decide its own breakpoints, because then every view decides differently.
- Cards collapse, tables transpose. The kanban already works on a phone because a card is a vertical object. A wide operations table does not, so below the breakpoint each row becomes a stacked block with the column name as a label. Horizontal scroll is not a responsive strategy, it is an admission of defeat.
- The touch density set is the mobile density set. This is the same decision as rule three, arriving from a different direction. Once you have built a 44px target scale for gloved shop floor use, the phone gets it for free.

The payoff is not that a quality engineer will do their day’s work on a phone. It is that a supervisor can approve a control plan from the floor, an operator can raise an alert without walking to a terminal, and a plant head can check the reject rate from a car. Those are the moments where ERP either becomes part of how the plant runs, or does not.
The honest constraints
It would be a poor consulting article that pretended this is unbounded.
Odoo’s view grammar is fixed. Form views are assembled from a defined vocabulary: sheet, group, notebook, page, header, footer, separator, label, field, button. Groups default to two columns. You can restyle every one of those primitives and you can register custom field widgets and view types in the JS registries, but you cannot simply drop a modern layout system in over the top. Anything genuinely bespoke has to be expressed either through that grammar or as a purpose-built OWL client action, which is the route we took for the dashboards.
Odoo’s own theming documentation admits it is incomplete. The SCSS inheritance page states that its compilation-order diagram does not match the current bundle organisation. That is honest of them, and it is also a fair summary of how under-specified Odoo theming is relative to Carbon or Fluent.
Accessibility is unaddressed at the platform level. An issue filed against the Odoo repository in 2016 catalogued WCAG failures including near-total absence of heading structure, unlabelled view-toggle buttons, and inputs without label association. It was closed with a Wishlist label. There is no published Odoo WCAG conformance statement or VPAT that we could find. With the European Accessibility Act applicable from June 2025, any organisation with EU exposure should treat that as a live risk rather than a nice-to-have, and should expect to close the gap in its own layer.
Community Edition means you build the module, not just the skin. Odoo maintains two web client designs, with enterprise primary variables loading ahead of community ones, and on the functional side Quality Management, the Shop Floor tablet interface, PLM and barcode manufacturing operations all sit in Enterprise. That is a larger scope than a theming project, and it should be priced as one. It also means scanner input and focus management have to be designed explicitly rather than inherited, which matters more than it sounds: a study in the Journal of the American Medical Informatics Association measured a 3.7% discrepancy rate when humans manually keyed instrument readings that were also captured electronically, with roughly five dangerous mistranscriptions per thousand results. Its conclusion was that electronic interfaces are the safest and most reliable method of data transfer. Scan over type, wherever the check allows it.
Responsive has a ceiling on the standard views. Custom OWL client actions, which is what the dashboards are, will do whatever you tell them. Standard list and form views will only go so far before you are fighting the framework rather than configuring it. Know which screens are worth the fight. For us that was the dashboards, the kanban and the alert-raising path, and not the master data maintenance screens that nobody was ever going to edit from a phone.
There is also a standard from the manufacturing world itself worth citing here, because it predates all of this. ANSI/ISA-101.01-2015, covering human machine interfaces for process automation, requires a governing style guide and a full HMI lifecycle from design through ongoing management. Its stated objectives are situational awareness, consistency across interfaces, alarm management and clear navigation. The shop floor’s own standards body has been asking for a design system since 2015. ERP simply has not been holding itself to it.
Why this is worth the budget line
The usual objection is that UI work is cosmetic and the money belongs in functionality.
Three responses. First, the Gartner numbers say resistance to enterprise software is a UX outcome, not a change-management outcome, and resistance is what turns a working implementation into a shelved one. Second, Nielsen Norman Group’s long-running work on usability ROI found that spending around 10% of a development budget on usability produced an average 83% improvement in the business metrics being targeted. That study is from 2008 and NN/g themselves noted the return had declined from an earlier measurement, so treat it as directional rather than precise, but the direction has never reversed. Third, and most concretely, every error a better interface prevents at the point of entry is an error nobody has to find, investigate and correct downstream.
None of this requires a platform migration. It requires a token layer, a density decision, a hierarchy that reflects what the module is actually for, and the willingness to treat the interface as part of the specification rather than as whatever the framework happened to render.
The standard for enterprise software has moved. ERP is allowed to move with it.
Arsenal IT Consultants builds and customises Odoo, ERPNext and SQL Server systems for manufacturing, healthcare and financial services clients from Chennai. The Quality and Maintenance platform shown here was built on Odoo 17 Community Edition, with a custom token layer and a mobile-first responsive pass. Screenshots have been reproduced with representative data. If you are running an Odoo manufacturing or quality deployment that works but that nobody enjoys using, we would be glad to look at it with you.
References
- Gartner, Gartner Survey Finds 60% of Employees Experience Frustration With New Software (November 2021)
- Nielsen Norman Group, Usability ROI Declining, But Still Strong (2008)
- Journal of the American Medical Informatics Association, Measuring the rate of manual transcription error in outpatient point-of-care testing (2019)
- IBM Carbon Design System: 2x Grid, Typography, Themes and Tokens
- Microsoft Fluent 2: Design Tokens, Accessibility
- SAP Fiori for Web: Content Density (Cozy and Compact)
- Atlassian Design System: Spacing, Design Tokens
- Vercel Geist: Colors, Typography, Grid; Geist Font (SIL Open Font License 1.1)
- Linear, A calmer interface for a product in motion
- Odoo Community Association (OCA), web_responsive module
- Odoo 17 Developer Documentation: Assets, SCSS Inheritance, Framework Overview, OWL Components, View Architectures
- W3C, Web Content Accessibility Guidelines 2.2 (October 2023)
- ANSI/ISA-101.01-2015, Human Machine Interfaces for Process Automation Systems