# Flex app and web dashboard guidelines

Proposed product UI standards · 6 November 2026 · Typography pending selection

This README defines shared defaults for the Flex app, web dashboard, POS and sub-brands. The values below are proposed design decisions, not measurements of the current app. Use the same component system across products, with density adjusted for the task. The redesigned template edition of the brand guide uses a provisional pairing only; final font selection is still pending.

## Quick defaults

| Property | Default |
| --- | --- |
| General surface / card radius | **12 px** |
| Button / input / select radius | **8 px** |
| Dialog / popover radius | **16 px** |
| Mobile bottom-sheet top corners | **24 px** |
| Spacing base unit | **4 px**, favouring 8 px steps for layout |
| Card padding | **24 px desktop / 16 px mobile** |
| Page side padding | **32 px desktop / 24 px tablet / 16 px mobile** |
| Grid gap | **24 px desktop / 16 px mobile** |
| Form field gap | **16 px**; 24 px between groups |
| Standard button / input minimum height | **44 px** |
| POS / touch-first control minimum height | **48 px**; use 56 px for key transaction actions |
| Dashboard body text | **14 px / 20 px**, regular |
| Mobile / form input text | **16 px / 24 px**, regular |
| Border | **1 px**, using the relevant theme token |
| Standard icon | **20 px**, consistent 2 px stroke |
| Main page title | **28 px / 36 px**, bold |
| Primary / secondary fonts | **Pending**; recommended Manrope / Inter |

Use CSS pixels for the web and equivalent logical units for native UI; do not multiply native layout values by screen pixel density. Native hit targets should also follow the destination platform's requirements.

## Typography: choose exactly two families

**Primary** means headings and brand expression. **Secondary** means body text and the everyday interface; it will appear most often. They are roles, not a requirement to use the primary font for every important item.

### What the old website uses

Inspected [erpfy.app](https://www.erpfy.app/) in a browser on 6 November 2026:

- **Tanker:** large, condensed display headlines; the sampled section headline rendered at approximately 84 px at a 1440 px desktop viewport.
- **Satoshi:** paragraphs, navigation and controls, with loaded weights 400, 500, 700 and 900. A sampled navigation label was approximately 14.4 px; a section paragraph was 17 px.
- Sampled navigation CTA corners were 12 px; dropdown items used 14 px corners. These are observations from the marketing homepage, not an app design system.

The site has an energetic, editorial character. My design recommendation is to retain its confident orange accents while using less condensed, sentence-case typography for orders, menus, reporting and forms. Tanker is effective for short campaign headlines but would not be my choice for the dashboard's general heading font.

### Option A — recommended: Manrope + Inter

| Role | Font | Weights | Where to use |
| --- | --- | --- | --- |
| Primary | **Manrope** | 600, 700; 800 for occasional large display text | Page titles, section headings, marketing headlines |
| Secondary | **Inter** | 400, 500, 600; 700 for strong numerical emphasis | Paragraphs, buttons, navigation, labels, forms, tables, receipts shown on screen, KPI values |

My assessment: Manrope's geometric shape complements the Flex symbol without imitating the wordmark. Inter provides a clear, consistent working interface. The contrast between the families is restrained; size, weight and spacing establish most of the hierarchy.

### Option B — warmer alternative: Plus Jakarta Sans + Inter

| Role | Font | Weights | Where to use |
| --- | --- | --- | --- |
| Primary | **Plus Jakarta Sans** | 600, 700; 800 for occasional large display text | Page titles, section headings, marketing headlines |
| Secondary | **Inter** | 400, 500, 600; 700 for strong numerical emphasis | All body text and functional UI, as in Option A |

My assessment: this gives the headings a slightly warmer, more expressive geometric character. Choose this if the brand should feel more hospitality-led; choose Option A for a quieter product-led feel.

**Decision pending:** choose A or B. Both are two-family systems. Do not add Tanker or Satoshi as a third brand family after selection. Arial / platform sans-serif may remain technical fallbacks. The previous Arial-based guide was archived; the new template edition uses Manrope + Inter as a provisional layout pairing only.

See [font-comparison.html](font-comparison.html) for identical sample screens in both pairs. The preview loads fonts from Google Fonts and shows whether they loaded; internet access is needed.

### Typography roles after selection

| Role | Font role | Size / line height | Weight |
| --- | --- | --- | --- |
| Website display, desktop | Primary | 48 / 56 px, up to 64 / 72 for short heroes | 700–800 |
| Website display, mobile | Primary | 32 / 40 px | 700 |
| Dashboard page title | Primary | 28 / 36 px desktop; 24 / 32 px mobile | 700 |
| Section heading | Primary | 20 / 28 px | 600–700 |
| Card title | Primary | 18 / 24 px | 600 |
| KPI / amount | Secondary | 28 / 36 px | 600–700 |
| App body / inputs | Secondary | 16 / 24 px | 400 |
| Dashboard body / table | Secondary | 14 / 20 px | 400 |
| Button / nav / label | Secondary | 14 / 20 px | 500–600 |
| Helper / caption | Secondary | 12 / 16 px | 400–500 |

- Use sentence case. Reserve uppercase for short abbreviations such as POS, KDS and AI.
- Body and small labels: normal letter spacing. Large headings may use -0.02em; do not tighten table text.
- Set money, quantities, times and comparable KPI values to `font-variant-numeric: tabular-nums lining-nums`. Right-align monetary table columns and their headers. Use locale-aware currency and date formatting.
- Avoid 300-weight text and long blocks of bold copy. Keep paragraphs around 45–75 characters per line where the layout permits.
- Support user text scaling. Controls use minimum heights and can grow; never clip enlarged labels to maintain a screenshot-perfect height.
- Keep the logo as supplied outlined artwork. Neither candidate is a replacement logo font.
- After approval, self-host the chosen web fonts, retain licence files, and bundle appropriate native font assets. Load real weights rather than relying on synthetic bold. Use `font-display: swap` on the web. Check the exact language coverage required before rollout.

## Spacing and padding

Use this scale: **0, 4, 8, 12, 16, 24, 32, 40, 48, 64 px**. A 2 px value is allowed for optical alignment or separators, not routine layout spacing.

| Relationship | Spacing |
| --- | --- |
| Icon to button label | 8 px |
| Label to field | 8 px |
| Field to helper / error text | 4 px |
| Related inline actions | 8 px; allow wrapping |
| Form field to next field | 16 px |
| Form group to next group | 24 px |
| Card title to content | 16 px |
| Card content to footer | 24 px |
| Page heading to first content section | 24 px |
| Major dashboard section to next section | 32 px |
| Marketing section vertical padding | 64 px mobile / 96 px desktop; separate from dashboard density |

Use 24 px card padding on desktop and 16 px on mobile. Compact table wrappers may use 16 px headers and unpadded table bodies, with padding inside cells. Do not add card padding and another identical wrapper padding accidentally.

## Corners and nesting

| Token | Value | Use |
| --- | --- | --- |
| `radius-xs` | 4 px | Small tags, tooltip corners |
| `radius-sm` | 8 px | Buttons, fields, menu items, navigation selection |
| `radius-md` | 12 px | Cards, standard panels, product tiles |
| `radius-lg` | 16 px | Dialogs, dropdown containers, popovers |
| `radius-xl` | 24 px | Mobile bottom-sheet top corners, large promotional containers |
| `radius-pill` | 999 px | Status badges, avatar circles, switches |

Do not make every button pill-shaped. Nested surfaces should look related: a 12 px card can contain 8 px controls. For tight inset decorative surfaces, derive the inner corner from the outer radius minus the inset, rather than giving both the same large radius.

## Component defaults

| Component | Dimensions and spacing | Other rules |
| --- | --- | --- |
| Primary button | Minimum 44 px high; 16 px horizontal, 10 px vertical padding; 8 px icon gap; radius 8 px | Orange fill with navy label; one leading action per task group |
| Secondary button | Same geometry as primary | Neutral surface, readable text and visible border |
| Dense desktop button | Minimum 36 px high; 12 px horizontal, 6 px vertical padding | Only for pointer-oriented toolbars; use 44–48 px targets on touch |
| Icon-only button | Minimum 44 × 44 px; icon 20 px; radius 8 px | Accessible name; tooltip on desktop; 48 × 48 px in POS |
| Input / select | Minimum 44 px high; 12 px horizontal padding; radius 8 px | Persistent label above, 16 px entered text, helper below |
| Textarea | Minimum 112 px high; 12 px padding; radius 8 px | Allow vertical resize on desktop |
| Card | 24 / 16 px padding; radius 12 px; 1 px border | Use a border before adding a shadow |
| Dialog | 24 px padding; radius 16 px; 24 px sections; 8 px action gap | Default max-width 560 px; narrow confirmation 400 px; large form 720 px |
| Drawer | 400 px preferred width desktop, at most viewport minus 32 px | 24 px padding; modal behaviour on narrow screens |
| Menu / popover | 8 px container padding; radius 16 px | Items minimum 40 px high desktop, 48 px on touch; 8 px item radius |
| Badge | 4 px vertical / 8 px horizontal padding; 12 / 16 px text; pill radius | Status label plus colour; never colour alone |
| Table | 48 px minimum header / row height; 12 px vertical / 16 px horizontal cell padding | Rows grow with content; 40 px compact option on desktop only |
| Sidebar item | Minimum 44 px high; 12 px horizontal padding; 8 px gap; radius 8 px | Label and icon; explicit selected state |
| POS item tile | Minimum 96 × 96 px; 12 px padding; radius 12 px | Keep price and name legible; avoid hover-only actions |

Fixed widths are preferred/max widths, not constraints that cause overflow on smaller screens. All actionable components need hover where relevant, focus, pressed, disabled and loading states. Keep their size stable when showing a spinner.

## Layout and responsive behaviour

Use the content's needs to adjust layout; these are starting breakpoints.

| Width | Layout | Page padding / gutters |
| --- | --- | --- |
| Below 768 px | Single column; navigation drawer; optional stacked list in place of wide table | 16 px / 16 px |
| 768–1199 px | Two-column where useful; collapse sidebar if the task area gets cramped | 24 px / 24 px |
| 1200 px and above | Expanded sidebar and full dashboard layout | 32 px / 24 px |

Expanded sidebar: 240 px; collapsed icon rail: 72 px; top bar: minimum 64 px. Allow navigation labels and top-bar content to adapt to increased text sizes. Ordinary settings pages should have a readable max-width around 1200 px; reporting tables, POS and KDS can use the full work area.

On mobile, stack form columns and place primary actions where reachable, with safe-area padding. Keep long tables horizontally scrollable inside their own region instead of making the entire page overflow. Do not hide essential transaction information to fit the layout.

## Colours and themes

Brand colours are fixed: **orange #FD550A** primary, **green #015D47** secondary, **yellow #FFBA08** accent. Keep logo fills exact in both themes. The following neutral and interface colours are proposed product tokens; they do not change the brand palette.

| Role | Light | Dark |
| --- | --- | --- |
| Page background | #F7F8FA | #0D182E |
| Card / panel | #FFFFFF | #16243A |
| Raised surface / menu | #FFFFFF | #1E3048 |
| Primary text | #0D182E | #F8FAFC |
| Secondary text | #526174 | #B8C4D4 |
| Decorative divider | #E2E8F0 | #33465F |
| Essential control boundary | #7B8795 | #7B8BA1 |
| Focus outline / text link | #015D47 | #FFBA08 |
| Primary action background | #FD550A | #FD550A |
| Primary action text | #0D182E | #0D182E |

Orange identifies the main action; green supports the brand and selected contexts; yellow is used sparingly. Use restrained tinted surfaces for secondary emphasis. Success, warning and error must have explicit labels/icons, and their own semantic tokens; do not automatically interpret every green brand accent as “paid” or “successful.”

Calculated opaque sRGB contrast for the exact brand values:

| Text / background | Ratio | Use |
| --- | --- | --- |
| Navy on orange | 5.46:1 | Normal button labels |
| White on orange | 3.24:1 | Avoid for normal-size button labels |
| White on green | 7.90:1 | Normal text on green surfaces |
| Navy on yellow | 10.34:1 | Normal text on yellow surfaces |
| Green on white | 7.90:1 | Light-theme links |

Orange text on white is also 3.24:1, so use green or navy for normal-size light-theme links. Validate hover, disabled, translucent and tinted states separately. Decorative dividers can be subtle; essential input boundaries and state indicators need sufficient contrast. Do not reuse the light theme by merely inverting every colour.

## Borders, shadows and focus

Use 1 px borders for ordinary component boundaries and selected surfaces. Use a visible 2 px focus outline with a 2 px offset: green in the light theme, yellow in the dark theme. Ensure it is not clipped by overflow and remains visible against surrounding surfaces.

Cards are flat by default. For elevation, start with `0 2px 8px rgb(13 24 46 / 6%)`; menus/dialogs can use `0 12px 32px rgb(13 24 46 / 16%)`. In dark mode, rely on raised surface colours and borders rather than stronger black shadows. Use colour and position consistently; do not add glow effects to routine controls.

## Motion, loading and feedback

Use 120–160 ms transitions for hover/focus and 180–240 ms for menus, drawers and dialogs. Animate opacity and small translations; avoid bouncing operational controls or delaying task completion to play branding.

For loading, keep content layout stable, mark the relevant region busy and give a clear text status. Use the [Flex loader](../Animation/Loader/preview.html) at approximately 32–48 px when there is a meaningful wait; use a skeleton for data panels if it makes the expected layout clear. The brand loader's SVG includes intentional clear space, so evaluate its apparent size in context.

Use a static symbol or simple text when reduced motion is requested. Provide empty, error, offline and retry states. POS/payment screens must distinguish “processing,” “successful,” “failed,” and “status unknown”; do not imply payment success from an animation alone. Retain entered data after a recoverable error.

## Accessibility and product language

Our product target is at least 44 × 44 px for ordinary touch interactions and 48 × 48 px for POS controls. This is a product usability choice, distinct from the WCAG 2.2 AA pointer target-size criterion of 24 × 24 CSS px with exceptions.

Target 4.5:1 text contrast for normal text and 3:1 for large text. Support keyboard navigation, visible focus, labelled fields, associated inline errors and meaningful screen-reader announcements. Dialogs need appropriate focus handling and return focus to their trigger on close. Never rely on placeholders as labels, or colour alone for status.

Use concise verbs: “Save changes,” “Add item,” “Send to kitchen,” “Take payment.” Explain destructive actions with the item or consequence. Confirm irreversible high-impact actions and provide undo where feasible. Do not require users to understand technical implementation details.

## Developer handoff tokens

These snippets document the proposed values. They do not update any application. Font families are intentionally unresolved until selection; map `--font-primary` and `--font-secondary` only after approval.

```css
:root {
  /* Pending: primary = Manrope OR Plus Jakarta Sans; secondary = Inter. */
  --font-primary: system-ui, sans-serif;
  --font-secondary: system-ui, sans-serif;

  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-6: 24px;
  --space-8: 32px;
  --space-10: 40px;
  --space-12: 48px;
  --space-16: 64px;

  --radius-xs: 4px;
  --radius-sm: 8px;
  --radius-md: 12px;
  --radius-lg: 16px;
  --radius-xl: 24px;
  --radius-pill: 999px;

  --control-min-height: 44px;
  --control-touch-min-height: 48px;
  --card-padding: 24px;
  --page-padding: 32px;
  --layout-gap: 24px;

  --brand-primary: #FD550A;
  --brand-secondary: #015D47;
  --brand-accent: #FFBA08;
  --ui-page: #F7F8FA;
  --ui-surface: #FFFFFF;
  --ui-raised: #FFFFFF;
  --ui-text: #0D182E;
  --ui-text-secondary: #526174;
  --ui-divider: #E2E8F0;
  --ui-control-border: #7B8795;
  --ui-focus: #015D47;
  --ui-link: #015D47;
  --ui-action: #FD550A;
  --ui-on-action: #0D182E;
}

[data-theme="dark"] {
  color-scheme: dark;
  --ui-page: #0D182E;
  --ui-surface: #16243A;
  --ui-raised: #1E3048;
  --ui-text: #F8FAFC;
  --ui-text-secondary: #B8C4D4;
  --ui-divider: #33465F;
  --ui-control-border: #7B8BA1;
  --ui-focus: #FFBA08;
  --ui-link: #FFBA08;
}

@media (width < 1200px) {
  :root { --page-padding: 24px; }
}
@media (width < 768px) {
  :root {
    --page-padding: 16px;
    --card-padding: 16px;
    --layout-gap: 16px;
  }
}

.amount { font-variant-numeric: tabular-nums lining-nums; }
:focus-visible { outline: 2px solid var(--ui-focus); outline-offset: 2px; }
```

Use named tokens in components rather than adding new arbitrary radii and padding values per screen. The first implementation pass should cover one orders table, a settings form, a POS order flow and both themes before rolling the components across products.

## Sources and decision status

- [ERPFY homepage](https://www.erpfy.app/) — direct browser inspection for current typography and sampled component geometry, 6 November 2026.
- [Manrope / Google Fonts](https://fonts.google.com/specimen/Manrope) and [upstream description](https://github.com/google/fonts/blob/main/ofl/manrope/DESCRIPTION.en_us.html).
- [Plus Jakarta Sans / Google Fonts](https://fonts.google.com/specimen/Plus+Jakarta+Sans) and [upstream description](https://github.com/google/fonts/blob/main/ofl/plusjakartasans/DESCRIPTION.en_us.html).
- [Inter / official typeface site](https://rsms.me/inter/) — interface design, variable weights and tabular-number features.
- [WCAG 2.2: text contrast](https://www.w3.org/WAI/WCAG22/Understanding/contrast-minimum.html) and [pointer target size](https://www.w3.org/WAI/WCAG22/Understanding/target-size-minimum.html).

**Awaiting your choice of font pair.** The new template edition of the guide uses a provisional layout pairing and does not finalise this decision.
