# POS style reference Find the theme hooks for each InStore POS surface. This page connects visible POS surfaces to the theme payload you edit. Use it to identify each surface's theme path, `instore-*` class hook, MUI component, slot, and common properties. It also lists behavior and layout toggles, such as the sidebar side and mobile footer. It composes the rest of the chapter rather than repeating it: - [Run InStore POS API requests](/instore/customization/pos-api-access.md): authenticate and run the calls. - [Theme API reference](/instore/customization/pos-theme-api.md): the `GET`, `PUT`, and `PATCH` endpoints and validation rules. - [Customize POS styles and behavior](/instore/customization/pos-theming.md): the authoring guide these tables draw on. The class and component identifiers below are derived from [MUI](https://v7.mui.com/material-ui/). Today the themed surfaces are the cart and the shared POS chrome: header, sidebar, search bar, status bars, dialogs, and the camera scanner. ## How to target styles Every visual change lands in one of three layers of the theme payload. Knowing which layer a change belongs to tells you where in the JSON it goes. 1. Global tokens: `palette` (colors), `typography` (text), `shape` (corner radius), `spacing`, and `zIndex` (stacking) at the top level. A [token](/instore/customization/pos-theming.md#reference-palette-tokens-in-component-overrides) such as `'primary.main'` is defined once here and referenced everywhere. [Reuse the tokens the theme already defines](/instore/customization/pos-style-reference.md#use-the-tokens-the-theme-already-defines) wherever you can. For more information, see [Reference palette tokens](/instore/customization/pos-theming.md#reference-palette-tokens-in-component-overrides). 2. Per-component styling: under `components.MuiX`, using a [`styleOverrides` slot](/instore/customization/pos-theming.md#slots-styleoverrides-variants-and-defaultprops) or a [`variants`](/instore/customization/pos-theming.md#slots-styleoverrides-variants-and-defaultprops) entry. Most InStore surfaces are targeted by a nested class selector inside a slot, such as `styleOverrides.` then `&.instore-Y` (or `& .instore-Y` for a child), while a few are className `variants`. The "How to target" column below tells you which. 3. Behavior and global settings: under `customTokens` (InStore-specific layout flags), plus `components.MuiDrawer.defaultProps.anchor` for the sidebar side. To identify the supported layout flags and sidebar setting, see [Behavior and global settings](/instore/customization/pos-style-reference.md#behavior-and-global-settings). ```mermaid flowchart LR Want["A change you want to make"] Want --> L1["1 · Global token
palette · typography · shape · spacing"] Want --> L2["2 · Per-component style
components.MuiX · styleOverrides and variants"] Want --> L3["3 · Behavior
customTokens · MuiDrawer anchor"] L1 --> Pay["Theme payload (JSON)"] L2 --> Pay L3 --> Pay classDef src fill:#C2C2FF,stroke:#6359FF,stroke-width:2px,color:#191741; classDef proc fill:#8F8FFF,stroke:#4E4ED7,stroke-width:2px,color:#191741; classDef out fill:#9FF7EE,stroke:#08A88A,stroke-width:2px,color:#003037; class Want src; class L1,L2,L3 proc; class Pay out; ``` Every change lands in one of these three layers of the theme payload; the rest of this page shows which layer each surface uses. Two rules from the [Theme API reference](/instore/customization/pos-theme-api.md) govern how a change is saved, and both are reflected in the procedure below: - Component values resolve as MUI [`sx`](https://v7.mui.com/system/getting-started/the-sx-prop/), so a numeric `borderRadius` or spacing is a theme multiple, not pixels. Use a string such as `"8px"` for an exact value. To understand how component override values resolve and which palette token strings are supported, see the [note in the authoring guide](/instore/customization/pos-theming.md#reference-palette-tokens-in-component-overrides). - A `components.MuiX` block is replaced atomically ([leaf merge versus atomic replacement](/instore/customization/pos-theming.md#leaf-merge-versus-atomic-component-replacement)). `GET` the current block, edit it, and send the whole block back. Values under `customTokens` and `palette`, by contrast, deep-merge at the leaf. ### Use the tokens the theme already defines The InStore POS theme is a standard MUI theme plus a fixed set of [InStore-specific fields](/instore/customization/pos-theming.md#instore-specific-theme-fields). Set and reference only the tokens it already defines: - Palette colors: the standard `primary`, `secondary`, `error`, `warning`, `info`, and `success`, plus the InStore-defined `tertiary` and the `background.statusBar` surface. You can set their values and add shades you reference, such as `primary.dark`. - Typography: the standard variants (`h1` to `h6`, `body1`, `body2`, `caption`, …) plus the InStore secondary-body variant. - Scalars: `shape.borderRadius`, `spacing`, `breakpoints`, and `zIndex` are plain values you can set directly. Due to its hosted nature, the InStore POS supports only the theming strategies, fields, and components described in this documentation. Do not add custom theme tokens, components, variants, or other non-standard theming strategies. Non-standard theming is at risk of being overwritten by updates of the InStore POS. ## Find the identifier for any element If a surface is not in the tables below, read its identifier straight from a running POS: 1. Open the POS in a desktop browser, right-click the element, and choose **Inspect**. 2. In the **Elements** panel, read the element's class list. It tells you the MUI component (`.MuiButton-root` to `MuiButton`), the [slot](/instore/customization/pos-theming.md#slots-styleoverrides-variants-and-defaultprops) (the `-root`, `-paper`, `-elevation`, ... suffix), any state class (`Mui-disabled`, `Mui-selected`), and the `instore-*` hook. 3. Look the `instore-*` hook up in the tables below, or target it directly with the layer-2 procedure. For the longer DevTools walkthrough, see [Inspect and override a specific element](/instore/customization/pos-theming.md#inspect-and-override-a-specific-element). It explains how to read state and prop classes and verify that your rule has precedence. ## Update a component style step by step Work through the styling layers in order, applying only the ones you need. The layers are value tokens, component-level styles, and specific element styles. Each step names the exact JSON path so you know where the change goes. 1. `GET` the current theme and keep it. It is both your starting point and, because component blocks are replaced atomically, the block you will edit and resend. To review the endpoint response shape, see [`GET /theme`](/instore/customization/pos-theme-api.md#get-theme). 2. Find the element's row in the [component reference](/instore/customization/pos-style-reference.md#component-class-reference) to get its MUI component, slot, and class. 3. Layer 1: get or choose the token (the value layer). Reuse a value the theme [already defines](/instore/customization/pos-style-reference.md#use-the-tokens-the-theme-already-defines), or set one under the relevant top-level group: `palette` for a color, `shape.borderRadius` for corners, `spacing` for gaps, `zIndex` for stacking, `typography` for text. The example below changes a color, but the same step applies to any token type. This edits `palette.*`, `shape.*`, `spacing`, `zIndex.*`, or `typography.*`. 4. Layer 2: set the component-level (global) style. Put properties that should apply to every instance of that MUI component in `components.MuiX.styleOverrides.`. This edits `components.MuiX.styleOverrides.`. 5. Layer 3: set the specific element's style. Target the one surface through its class, either a nested `&.instore-Y` selector inside the slot or a `variants` entry with a `className` matcher. This edits the `&.instore-Y` block (or `components.MuiX.variants[]`). 6. `PATCH` the full `components.MuiX` block (atomic replacement), reload the POS, and re-inspect. Prefer [token references](/instore/customization/pos-theming.md#reference-palette-tokens-in-component-overrides) over hard-coded hex, and remember that numeric radius and spacing are theme multiples. If your rule is struck through in DevTools, it was overridden. To adjust selector specificity and rule order, see [Ensure your change has precedence](/instore/customization/pos-style-reference.md#ensure-your-change-has-precedence). ### Example: recolor the primary action button The checkout button carries the class `instore-primary-action` on a `MuiButton` (a className [variant](/instore/customization/pos-theming.md#slots-styleoverrides-variants-and-defaultprops)). Make it green as follows. Layer 1: set the `tertiary` color token. `tertiary` is one of the [defined palette colors](/instore/customization/pos-style-reference.md#use-the-tokens-the-theme-already-defines), so you can set and reference it. This is a leaf merge under `palette`, safe to send on its own: ```json title="Layer 1: palette token" { "palette": { "tertiary": { "main": "#1B7E3F", "dark": "#176B36", "contrastText": "#ffffff" } } } ``` Layer 3: reference the token from the variant. This belongs in `components.MuiButton.variants[]`: ```json title="Layer 3: the instore-primary-action variant" { "props": { "className": "instore-primary-action" }, "style": { "backgroundColor": "tertiary.main", "color": "tertiary.contrastText", "&:hover": { "backgroundColor": "tertiary.dark" } } } ``` The bundled variant also defines `&:active`, `&.Mui-disabled`, and `&.Mui-focusVisible` rules. Keep (or re-set) those in your variant so the button looks right in every state. To preserve state-specific styles and troubleshoot overridden rules, see [Ensure your change has precedence](/instore/customization/pos-style-reference.md#ensure-your-change-has-precedence). Because `components.MuiButton` is replaced [atomically](/instore/customization/pos-theming.md#leaf-merge-versus-atomic-component-replacement), send the whole `MuiButton` block (its `defaultProps`, the `styleOverrides.root` rules, and every `variants` entry), not just the one variant above, or the others are dropped. `GET` first, edit the block in place, then `PATCH` it. For the full worked example, see [Re-color the primary action button](/instore/customization/pos-theming.md#worked-example-recolor-the-primary-action-button). ### Example: restyle the cart line item The line-item card is `instore-line-item-card` on `MuiPaper`, slot [`elevation`](/instore/customization/pos-style-reference.md#cart-line-item), and its inner parts are nested `& .instore-line-item-*` selectors inside that block. To give the card more padding, a different surface color, and a larger image, edit `components.MuiPaper.styleOverrides.elevation`: ```json title="Layers 2 to 3: the line-item card block" { "components": { "MuiPaper": { "styleOverrides": { "elevation": { "&.instore-line-item-card": { "backgroundColor": "background.paper", "borderRadius": "8px", "padding": "28px 20px", "& .instore-line-item-image": { "width": "140px", "minWidth": "140px", "height": "140px" } } } } } } } ``` `MuiPaper` also styles other cart surfaces (the cart page card, section cards, the totals popover) under the same `elevation` slot. Include their `&.instore-*` blocks too when you resend, since the block is atomic. ## Ensure your change has precedence A single element on screen can match more than one style rule at once. For example, it can match a bundled POS theme rule and a rule you add in your override. For each property, the browser applies the value from the rule with precedence and overrides the others. CSS specificity decides which rule has precedence. A more specific selector, such as a class plus a state, takes precedence over a less specific selector. If two rules have the same specificity, the rule defined later has precedence. For the full layering, see [How overrides compose](/instore/customization/pos-theming.md#how-overrides-compose). This matters when theming the InStore POS. The POS ships a complete bundled theme, so most overrides compete with an existing rule. If your rule is less specific than the bundled one, the Theming API still accepts and stores your payload. The POS keeps rendering the original style, so it looks as though nothing changed. Giving your override precedence turns an accepted payload into a visible change. Re-inspect the element in DevTools after reloading. The **Styles** panel lists the competing rules in priority order and strikes through any value that was overridden. ```mermaid flowchart TD Bundled["Bundled theme rule"] --> El["The same element
(for example, the menu button)"] Yours["Your override rule"] --> El El --> Cmp{"Which selector is more specific?
equal to the rule defined later"} Cmp -->|your rule| Win["Your value has precedence
visible change"] Cmp -->|bundled rule| Lose["Your value is overridden
struck through in DevTools: looks unchanged"] classDef src fill:#C2C2FF,stroke:#6359FF,stroke-width:2px,color:#191741; classDef proc fill:#8F8FFF,stroke:#4E4ED7,stroke-width:2px,color:#191741; classDef dec fill:#FFE7A8,stroke:#FFC738,stroke-width:2px,color:#191741; classDef win fill:#9FF7EE,stroke:#08A88A,stroke-width:2px,color:#003037; classDef lose fill:#F9C9C0,stroke:#FF8A00,stroke-width:2px,color:#191741; class Bundled,Yours src; class El proc; class Cmp dec; class Win win; class Lose lose; ``` Two rules can match one element; for each property only the rule with precedence applies. Make your rule more specific, or define it later, so it has precedence. ### Why a change can be overridden Because the bundled POS theme already styles many surfaces across interaction states, on child elements, and with `!important`, a single-property change can be overridden. Four patterns cause this: - Interaction states: a surface is often styled separately for `&:hover`, `&:active`, `&.Mui-selected`, `&.Mui-disabled`, and `&.Mui-focusVisible`. Change the base alone and the states keep their old look. Set the ones you care about too. - Child elements re-scope a property: a parent often sets a color on its children by selector. For example, the sidebar button sets icon and label color with `& .MuiListItemIcon-root` and `& .MuiListItemText-primary`. Those children are also styled on their own components (`MuiListItemIcon`, `MuiListItemText`), so a color can live in two places. - `!important` in the bundled theme: a few sizes are pinned with `!important` (the add-coupon and coupon-scan buttons) so a component `sx` cannot beat them. To override those, your value must use `!important` as well. - More than one component or variant: the same look can come from several components (input focus borders) or from `variants` that override the base (the sidebar sub-item and the mobile footer item both re-set the button background). Use two habits to help a change take precedence. Prefer a [`variants`](/instore/customization/pos-theming.md#slots-styleoverrides-variants-and-defaultprops) entry or a class selector over a bare slot rule because it is more specific. Reference [tokens](/instore/customization/pos-style-reference.md#use-the-tokens-the-theme-already-defines) so one edit propagates to every rule that uses them. ### Surfaces that need extra care for precedence | Surface (class) | Why a simple change may be overridden | To take precedence, also set | | --- | --- | --- | | Sidebar menu button (`MuiListItemButton` root) | Background is set per state, the icon and label colors are re-scoped on child elements, and two variants override it. | `&:hover`, `&.Mui-selected`, `&.Mui-disabled`, `&.Mui-focusVisible`; icon and label color on `MuiListItemIcon` and `MuiListItemText`; the `instore-sidebar-subitem` and `instore-mobile-footer-item` variants. | | Primary action button (`instore-primary-action`) | The variant carries its own `:hover`, `:active`, `Mui-disabled`, and `Mui-focusVisible` rules. | `&:hover`, `&:active`, `&.Mui-disabled`, `&.Mui-focusVisible` inside the variant. | | Mobile footer item (`instore-mobile-footer-item`) | The selected color and the active indicator live on the selected state. | `&.Mui-selected` color and its `::before` indicator. | | Input focus and hover ring | The outline color is set on `MuiOutlinedInput`, `MuiInputBase`, and `MuiFormControl`, and the search field hard-codes its own border. | Change `primary.main`, or override those three components; for `instore-search-input`, edit its own border color. | | Active cart tab (`instore-cart-tab`) | The default tab indicator is hidden; the active marker is a top border. | `&.Mui-selected { borderTopColor }`, not `MuiTabs-indicator`. | | Sized dialog buttons (`instore-add-coupon-btn`, `instore-coupon-scan-btn`) | The size comes from a component `sx` that outranks the theme. | `width` and `height` with `!important`. | ### Worked example: recolor the sidebar menu button The sidebar category button (`MuiListItemButton`) is the clearest case. Its background is set on the base and again for the `:hover`, `Mui-selected`, `Mui-disabled`, and `Mui-focusVisible` states. Its icon and label colors are set both on the button (`& .MuiListItemIcon-root`, `& .MuiListItemText-primary`) and on `MuiListItemIcon` and `MuiListItemText`. To recolor it fully and give the override precedence, cover all of these rules in the `MuiListItemButton` block. Send the whole block because it is [atomic](/instore/customization/pos-theming.md#leaf-merge-versus-atomic-component-replacement): ```json title="Recolor the sidebar menu button: every state" { "components": { "MuiListItemButton": { "styleOverrides": { "root": { "backgroundColor": "primary.main", "color": "primary.contrastText", "& .MuiListItemIcon-root": { "color": "primary.contrastText" }, "& .MuiListItemText-primary": { "color": "primary.contrastText" }, "&:hover": { "backgroundColor": "primary.dark" }, "&.Mui-selected": { "backgroundColor": "primary.dark" }, "&.Mui-disabled": { "backgroundColor": "action.disabledBackground" } } } } } } ``` If you also use the sidebar sub-menu or the mobile footer, re-declare the `instore-sidebar-subitem` and `instore-mobile-footer-item` variants in the same block. Otherwise, they keep the bundled background. ## Component class reference Each table maps a surface to its class, MUI component, how to target it, and the properties you would typically change. See the **How to target** column for which selectors to use: - `styleOverrides.`, `&.instore-x`: a nested class selector inside a [`styleOverrides` slot](/instore/customization/pos-theming.md#slots-styleoverrides-variants-and-defaultprops) (most surfaces). - `variants` (className): a [className variant](/instore/customization/pos-theming.md#slots-styleoverrides-variants-and-defaultprops) entry. - `& .instore-x` (nested): a child element styled inside its parent's block; edit it there, not as a top-level component. Rows marked "Layout only" are structural wrappers (flexbox, grid, spacing) you rarely re-brand; they are listed for completeness. Bare color values shown come from the POS starter theme; replace them with [palette tokens](/instore/customization/pos-theming.md#reference-palette-tokens-in-component-overrides) where you can. Changing the property in the last column is often not enough on its own. Some surfaces are also styled across interaction states, on child elements, or by a competing variant. Your rule must cover those styles too to take precedence. The surfaces where this matters are called out in [Ensure your change has precedence](/instore/customization/pos-style-reference.md#ensure-your-change-has-precedence). ### App frame | Element | Class | MUI component | How to target | What changes | | --- | --- | --- | --- | --- | | Top header bar | `instore-header-bar` | `MuiAppBar` | `styleOverrides.root`, `&.instore-header-bar` | `bgcolor`, `color`, `boxShadow`; nested toolbar and button sizing | | Desktop status bar | `instore-bottom-bar` | `MuiAppBar` | `styleOverrides.root`, `&.instore-bottom-bar` | `bgcolor` (status-bar token), `color`, corner radius | | Status bar row | `instore-bottom-bar-row` | `Box` | `& .instore-bottom-bar-row` (nested) | Layout only: alignment, spacing | | Status bar item | `instore-bottom-bar-item` | `Box` | `& .instore-bottom-bar-item` (nested) | `fontSize`, `gap`, icon size | | Mobile footer bar | `instore-mobile-bottom-bar` | `MuiAppBar` | `styleOverrides.root`, `&.instore-mobile-bottom-bar` | `bgcolor`, `color`, padding, corner radius | | Mobile footer item | `instore-mobile-footer-item` | `MuiListItemButton` | `variants` (className) | `bgcolor`, `color`, selected color, active indicator (`::before`) | | Context menu (header ...) | `instore-context-menu` | `MuiPaper` | `styleOverrides.elevation`, `&.instore-context-menu` | `minWidth`, `backgroundColor`, `border`, `borderRadius` | To hide the header, status bar, or mobile footer entirely, use the [behavior toggles](/instore/customization/pos-style-reference.md#behavior-and-global-settings) rather than styling them away. ### Sidebar (navigation drawer) The sidebar is a `MuiDrawer`; its sections are nested under `styleOverrides.paper`. The side it docks on is a [behavior setting](/instore/customization/pos-style-reference.md#behavior-and-global-settings). | Element | Class | MUI component | How to target | What changes | | --- | --- | --- | --- | --- | | Drawer surface | None | `MuiDrawer` | `styleOverrides.paper` | `bgcolor`, `width` (per breakpoint), `borderRadius` | | Sidebar header | `instore-sidebar-header` | `MuiToolbar` | `MuiDrawer`, `styleOverrides.paper`, `& .instore-sidebar-header` | `bgcolor`, `color`, `height` | | Sidebar body | `instore-sidebar-body` | `Box` | `MuiDrawer`, `styleOverrides.paper`, `& .instore-sidebar-body` | Layout only: scroll area | | Sidebar footer | `instore-sidebar-footer` | `Box` | `MuiDrawer`, `styleOverrides.paper`, `& .instore-sidebar-footer` | `bgcolor`, `color` | | Menu button (category) | None | `MuiListItemButton` | `styleOverrides.root` | `bgcolor`, `color`, `minHeight`, `borderRadius`, icon and label size. Set every state and child color [to take precedence](/instore/customization/pos-style-reference.md#ensure-your-change-has-precedence) | | Submenu item | `instore-sidebar-subitem` | `MuiListItemButton` | `variants` (className) | `bgcolor`, `color`, border | | Menu list grid | `instore-sidebar-main-list` | `MuiList` | `styleOverrides.root` | Layout only: grid columns, gap | | Drilldown back button | `instore-sidebar-drilldown-back` | `MuiButton` | `MuiDrawer`, `styleOverrides.paper`, `& .instore-sidebar-drilldown-back` | `color`, `bgcolor`, `fontWeight` (mobile) | | Drilldown submenu list | `instore-sidebar-drilldown-list` | `MuiList` | `MuiDrawer`, `styleOverrides.paper`, `& .instore-sidebar-drilldown-list` | Layout only: shown on mobile drilldown | | Menu icon | None | `MuiListItemIcon` | `styleOverrides.root` | `color`, `fontSize` | | Menu label | None | `MuiListItemText` | `styleOverrides.primary` | `fontSize`, `fontWeight` | ### Search and scan | Element | Class | MUI component | How to target | What changes | | --- | --- | --- | --- | --- | | Search bar container | `instore-search-bar` | `MuiStack` | `styleOverrides.root`, `&.instore-search-bar` | Layout only: direction, gap | | Scan-mode button group | `instore-search-scan-group` | `MuiButtonGroup` | `styleOverrides.root`, `&.instore-search-scan-group` | `width`, `height`, `borderRadius` | | Scan-mode group, selected | `instore-search-scan-group--selected` | `MuiButtonGroup` | `styleOverrides.root`, `&.instore-search-scan-group--selected` | `backgroundColor`, `border` (active look) | | Scan button | `instore-search-scan-btn` | `MuiButton` | `variants` (className) | `backgroundColor`, `height`, icon color | | Search input field | `instore-search-input` | `MuiTextField` | `styleOverrides.root`, `&.instore-search-input` | `backgroundColor`, input height, border color, `fontSize` | | Search magnifier icon | `instore-search-magnifier` | `MuiIconButton` | `styleOverrides.root`, `&.instore-search-magnifier` | `color`, icon `fontSize` | | Search clear icon | `instore-search-clear` | `MuiIconButton` | `styleOverrides.root`, `&.instore-search-clear` | `color`, icon `fontSize` | | Camera scanner overlay | `instore-scanner-overlay` | `MuiStack` | `styleOverrides.root`, `&.instore-scanner-overlay` | Layout only: full-viewport overlay | | Scanner instruction text | `instore-scanner-text` | `Box` | `& .instore-scanner-text` (nested) | `color`, `fontSize` | | Scanner viewfinder | `instore-scanner-window` | `Box` | `& .instore-scanner-window` (nested) | Bracket `--c` color, `border`, `width`, and `height` | | Scanner action area | `instore-scanner-actions` | `Box` | `& .instore-scanner-actions` (nested) | Layout only | ### Cart page and layout | Element | Class | MUI component | How to target | What changes | | --- | --- | --- | --- | --- | | Cart page card | `instore-cart-page-paper` | `MuiPaper` | `styleOverrides.elevation`, `&.instore-cart-page-paper` | `backgroundColor`, `borderRadius`, `boxShadow`, `padding` | | Cart section card | `instore-cart-section-paper` | `MuiPaper` | `styleOverrides.elevation`, `&.instore-cart-section-paper` | `backgroundColor`, `border`, `borderRadius`, `padding` | | Items scroll area | `instore-cart-items-scroll` | `Box` | `& .instore-cart-items-scroll` (nested) | Scrollbar width and color | | Add-coupon button (float) | `instore-cart-fab` | `Box` | `& .instore-cart-fab` (nested) | Layout only: position | | Mobile totals block | `instore-cart-mobile-totals` | `Box` | `& .instore-cart-mobile-totals` (nested) | Layout only | | Sidebar (totals) column | `instore-cart-sidebar-col` | `MuiGrid` | `styleOverrides.item`, `&.instore-cart-sidebar-col` | Layout only: desktop column width | | Content (items) column | `instore-cart-content-col` | `MuiGrid` | `styleOverrides.item`, `&.instore-cart-content-col` | Layout only: desktop column width | | Cart tab strip | `instore-cart-tabs` | `MuiTabs` | `styleOverrides.root`, `&.instore-cart-tabs` | `minHeight`, `backgroundColor`, indicator | | Cart tab (Sale/Return/…) | `instore-cart-tab` | `MuiTab` | `styleOverrides.root`, `&.instore-cart-tab` | `backgroundColor`, `borderRadius`, `color`, `fontSize`, selected marker | | Cart tab subtitle | `instore-cart-tab-subtitle` | `Box` | `& .instore-cart-tab-subtitle` (nested) | `fontSize`, `color` | | Section label | `instore-cart-section-label` | `MuiTypography` | `styleOverrides.body1`, `&.instore-cart-section-label` | `fontWeight`, `marginBottom` | ### Cart line item The card is one `MuiPaper`, `elevation` block; most parts are nested selectors inside it. Text, dividers, the quantity field, and the icon buttons are styled on their own components (last rows). A line-item discount is displayed as a text badge below the quantity controls. | Element | Class | MUI component | How to target | What changes | | --- | --- | --- | --- | --- | | Line-item card | `instore-line-item-card` | `MuiPaper` | `styleOverrides.elevation`, `&.instore-line-item-card` | `backgroundColor`, `borderRadius`, `padding`, `gap` | | Product image | `instore-line-item-image` | `Box` | `& .instore-line-item-image` (nested) | `width`, `height`, `backgroundSize`, `borderRadius` | | Body column | `instore-line-item-body` | `Box` | `& .instore-line-item-body` (nested) | Layout only | | Top row (name + menu) | `instore-line-item-row-top` | `Box` | `& .instore-line-item-row-top` (nested) | Layout only | | Product name | `instore-line-item-name` | `MuiTypography` | `styleOverrides.h6`, `&.instore-line-item-name` | `fontSize`, `fontWeight`, `color` | | Actions (kebab) button | `instore-line-item-actions-btn` | `MuiIconButton` | `& .instore-line-item-actions-btn` (nested) | Layout only: position | | Meta row (SKU, price) | `instore-line-item-meta-row` | `Box` | `& .instore-line-item-meta-row` (nested) | Layout only | | Meta label | `instore-line-item-meta-label` | `MuiTypography` | `styleOverrides.caption`, `&.instore-line-item-meta-label` | `fontSize`, `color` (secondary) | | Meta value | `instore-line-item-meta-value` | `MuiTypography` | `styleOverrides.body2`, `&.instore-line-item-meta-value` | `fontSize`, `color` | | Meta divider | `instore-line-item-meta-divider` | `MuiDivider` | `& .instore-line-item-meta-divider` (nested) | `height`, `borderColor` | | Quantity row | `instore-line-item-qty-row` | `Box` | `& .instore-line-item-qty-row` (nested) | Layout only | | Quantity input | `instore-line-item-qty-input` | `MuiTextField` | `styleOverrides.root`, `&.instore-line-item-qty-input` | `width`, `height`, `backgroundColor`, `borderRadius` | | Quantity +/- button | `instore-line-item-qty-btn` | `MuiIconButton` | `styleOverrides.root`, `&.instore-line-item-qty-btn` | `width`, `height`, `color` | | Extended price block | `instore-line-item-extended-price-block` | `Box` | `& .instore-line-item-extended-price-block` (nested) | Layout only | | Extended price label | `instore-line-item-extended-price-label` | `MuiTypography` | `styleOverrides.caption`, `&.instore-line-item-extended-price-label` | `fontSize`, `color` | | Extended price value | `instore-line-item-extended-price` | `MuiTypography` | `styleOverrides.h6`, `&.instore-line-item-extended-price` | `fontSize`, `color` | | Attribute row | `instore-line-item-attr-row` | `Box` | `& .instore-line-item-attr-row` (nested) | Layout only | | Attribute item | `instore-line-item-attr-item` | `Box` | `& .instore-line-item-attr-item` (nested) | Layout only | | Attribute divider | `instore-line-item-attr-divider` | `MuiDivider` | `styleOverrides.root`, `&.instore-line-item-attr-divider` | `height`, `borderColor` | | Discount text badge | `instore-line-item-discount-label` | `MuiTypography` | `styleOverrides.body2`, `&.instore-line-item-discount-label` | `backgroundColor`, `color`, `borderRadius`, `padding` | | Struck-through price | `instore-line-item-price-strikethrough` | `MuiTypography` | `styleOverrides.body2`, `&.instore-line-item-price-strikethrough` | `textDecoration`, `color` | | Discount row | `instore-line-item-discount-row` | `Box` | `& .instore-line-item-discount-row` (nested) | Layout only | | Remove (delete) button | `instore-line-item-remove-btn` | `MuiIconButton` | `styleOverrides.root`, `&.instore-line-item-remove-btn` | `backgroundColor`, `border`, `color` | ### Cart totals (money box) | Element | Class | MUI component | How to target | What changes | | --- | --- | --- | --- | --- | | Totals list | `instore-totals-list` | `MuiList` | `styleOverrides.root`, `&.instore-totals-list` | Layout only: switches the list to block flow | | Totals row | `instore-totals-list-item` | `MuiListItem` | `styleOverrides.root`, `&.instore-totals-list-item` | Spacing, alignment | | Totals row, flush | `instore-totals-list-item-flush` | `MuiListItem` | `&.instore-totals-list-item-flush` (modifier) | Right padding | | Totals label | `instore-totals-header` | `MuiTypography` | `styleOverrides.h6`, `&.instore-totals-header` | `fontSize`, `fontWeight` | | Totals amount | `instore-totals-header-amount` | `MuiTypography` | `styleOverrides.h6`, `&.instore-totals-header-amount` | `fontSize`, `fontWeight` | | Emphasis modifier | `instore-totals-emphasized` | `MuiTypography` | combined with a totals class (modifier) | `fontWeight`, `fontSize` (bold totals) | | Net-due modifier | `instore-totals-net-due` | `MuiTypography` | combined with a totals class (modifier) | `fontSize` (large net-due amount) | | Totals note text | `instore-totals-text` | `MuiTypography` | `styleOverrides.h6`, `&.instore-totals-text` | `fontSize`, `fontStyle` | | Totals note amount | `instore-totals-amount` | `MuiTypography` | `styleOverrides.h6`, `&.instore-totals-amount` | `fontSize`, `fontStyle` | | Single divider | `instore-totals-divider-t1` | `MuiDivider` | `styleOverrides.root`, `&.instore-totals-divider-t1` | `margin`, `borderColor` | | Spacer divider | `instore-totals-divider-t2` | `MuiDivider` | `styleOverrides.root`, `&.instore-totals-divider-t2` | `borderBottomWidth`, `margin` | | Coupon chip | `instore-cart-coupon-chip` | `MuiChip` | `styleOverrides.root`, `&.instore-cart-coupon-chip` | `height`, `backgroundColor`, `border`, label padding | | Totals popover surface | `instore-totals-popper-content` | `MuiPaper` | `styleOverrides.elevation`, `&.instore-totals-popper-content` | `backgroundColor`, `border`, `borderRadius` | | Totals toggle (mobile) | `instore-cart-totals-toggle` | `MuiIconButton` | `styleOverrides.root`, `&.instore-cart-totals-toggle` | `boxShadow` | A cart-level discount in the totals area is displayed as a discount row created with a `MuiListItem` that has several nested parts: | Element | Class | MUI component | How to target | What changes | | --- | --- | --- | --- | --- | | Discount row | `instore-cart-discount-row` | `MuiListItem` | `styleOverrides.root`, `&.instore-cart-discount-row` | `backgroundColor`, `border`, `borderRadius`, `color` | | Discount icon box | `instore-cart-discount-icon-box` | `Box` | `& .instore-cart-discount-icon-box` (nested) | `backgroundColor`, size | | Discount icon | `instore-cart-discount-icon` | `MuiSvgIcon` | `& .instore-cart-discount-icon` (nested) | `color`, `fontSize` | | Discount name | `instore-cart-discount-name` | `Box` | `& .instore-cart-discount-name` (nested) | `fontSize`, `fontWeight`, `color` | | Discount description | `instore-cart-discount-desc` | `Box` | `& .instore-cart-discount-desc` (nested) | `fontSize`, `color` | | "Applied" status | `instore-cart-discount-applied` | `Box` | `& .instore-cart-discount-applied` (nested) | `color` | | Discount amount | `instore-cart-discount-amount` | `Box` | `& .instore-cart-discount-amount` (nested) | `color` | ### Dialogs | Element | Class | MUI component | How to target | What changes | | --- | --- | --- | --- | --- | | Add-coupon dialog | `instore-add-coupon-dialog` | `MuiDialog` | `styleOverrides.root`, `&.instore-add-coupon-dialog` | Dialog `width`, `border`, `borderRadius`; backdrop color (nested) | | Dialog title | `instore-add-coupon-title` | `MuiTypography` | `styleOverrides.body1`, `&.instore-add-coupon-title` | `fontSize`, `color` | | Input row | `instore-add-coupon-row` | `MuiStack` | `styleOverrides.root`, `&.instore-add-coupon-row` | Layout only | | Coupon code input | `instore-add-coupon-input` | `MuiTextField` | `styleOverrides.root`, `&.instore-add-coupon-input` | Input height | | Coupon scan button | `instore-coupon-scan-btn` | `MuiIconButton` | `styleOverrides.root`, `&.instore-coupon-scan-btn` | `backgroundColor`, size | | Action row | `instore-add-coupon-actions` | `MuiStack` | `styleOverrides.root`, `&.instore-add-coupon-actions` | Layout only | | Apply or cancel button | `instore-add-coupon-btn` | `MuiButton` | `styleOverrides.root`, `&.instore-add-coupon-btn` | `width`, `height` | ### Global component overrides (no class hook) These components are styled globally. They have no `instore-*` hook, so a change applies to every instance. Edit the slot shown to retune them across the POS. | Element | MUI component | How to target | What changes | | --- | --- | --- | --- | | Page background and body | `MuiCssBaseline` | `styleOverrides.body` | `bgcolor` (`background.default`), `color`, scrollbar | | Input focus and hover ring | `MuiOutlinedInput`, `MuiInputBase`, `MuiFormControl` | `styleOverrides.root` | Outline `borderColor` (`primary.main`) on focus/hover | | Field label | `MuiFormLabel` | `styleOverrides.root` | `color`, focused color | | Radio or checkbox | `MuiRadio`, `MuiCheckbox` | `styleOverrides.root` | `color` (`primary.main`) | | Menu surface | `MuiMenu` | `styleOverrides.paper` | Text color, `Mui-disabled` item color | | Dialog surface (default) | `MuiDialog` | `styleOverrides.paper` | `backgroundColor` (`background.default`) | | Modal backdrop | `MuiBackdrop` | `styleOverrides.root` | Scrim `backgroundColor` | ## Behavior and global settings Behavior and layout (what shows, and which side the sidebar sits on) are controlled outside the visual styling layers. Most are InStore-specific [`customTokens`](/instore/customization/pos-theming.md#instore-specific-theme-fields); the sidebar side is a `MuiDrawer` default prop. Each accepts the value types linked in the table. | Setting | Theme path | Values | POS starter default | | --- | --- | --- | --- | | Sidebar side | `components.MuiDrawer.defaultProps.anchor` | `"left"` or `"right"` ([atomic block](/instore/customization/pos-theming.md#leaf-merge-versus-atomic-component-replacement)) | `"right"` | | Show the header bar | `customTokens.layout.headerVisible` | `boolean` or [responsive map](/instore/customization/pos-theming.md#responsive-layout-tokens) | `true` | | Show the mobile footer menu | `customTokens.layout.mobileFooter` | `boolean` or [responsive map](/instore/customization/pos-theming.md#responsive-layout-tokens) | `{ "xs": true, "md": false }` | | Show the desktop status bar | `customTokens.layout.desktopFooter` | `boolean` or [responsive map](/instore/customization/pos-theming.md#responsive-layout-tokens) | `{ "xs": false, "md": true }` | | Show the sidebar logo | `customTokens.sidebar.showLogo` | `boolean` or [responsive map](/instore/customization/pos-theming.md#responsive-layout-tokens) | `false` | | Show the sidebar collapse button | `customTokens.sidebar.showCollapseButton` | `boolean` or [responsive map](/instore/customization/pos-theming.md#responsive-layout-tokens) | `{ "xs": true, "md": false }` | A [responsive map](/instore/customization/pos-theming.md#responsive-layout-tokens) (`{ "xs": …, "md": … }`) lets a setting differ per breakpoint, for example showing the footer on phones but not on terminals. A bare `boolean` applies at every size. When a layout flag is `false`, the component is not rendered (it is removed, not hidden with CSS). ### Example: hide the mobile footer menu `customTokens` values deep-merge at the leaf, so this is a small, safe `PATCH`: ```json title="PATCH: hide the mobile footer" { "customTokens": { "layout": { "mobileFooter": false } } } ``` To hide it only on a given size, send a [responsive map](/instore/customization/pos-theming.md#responsive-layout-tokens) instead: `{ "xs": false, "md": false }`. ### Example: move the sidebar to the left The sidebar side comes from `components.MuiDrawer.defaultProps.anchor`. The POS starter docks it on the right; set it to `"left"` and the surrounding layout flips to match: ```json title="PATCH: sidebar on the left (full block abbreviated)" { "components": { "MuiDrawer": { "defaultProps": { "anchor": "left", "variant": "permanent" }, "variants": [], "styleOverrides": { "paper": {} } } } } ``` `components.MuiDrawer` is replaced [atomically](/instore/customization/pos-theming.md#leaf-merge-versus-atomic-component-replacement). Sending only `defaultProps` (as the abbreviated example shows the shape) would drop the bundled sidebar `styleOverrides` and `variants` and break its appearance. `GET` the theme, change `defaultProps.anchor` inside the returned `MuiDrawer` block, and `PATCH` the whole block back. To review the full sidebar update example, see [PATCH /theme: move the sidebar](/instore/customization/pos-theme-api.md#patch-theme). ## Related pages - [Customize POS styles and behavior](/instore/customization/pos-theming.md): the guide for customizing POS styles with the layered override model and worked examples. - [Theme API reference](/instore/customization/pos-theme-api.md): the `GET`, `PUT`, and `PATCH` endpoints, `customTokens` field reference, and validation rules. - [Overview](/instore/customization/pos-overview.md): how theme configuration, MUI, and the InStore POS fit together. ## Related pages - [Area overview page with navigation](/instore.md) - [Previous page: Customize styles and behavior](/instore/customization/pos-theming.md) - [Search documentation and API specs](/search.md)