# KeluargaMart Design Family — Uniformity Contract One brand, three frontends (B2B, ERP, POS). This file is **identical and synced** across all three frontend repos. The canonical copy lives in `keluargamart-b2b-frontend`; the ERP and POS copies are derived. - Sync: `bash scripts/sync-design.sh` (run from any frontend repo — pulls the canonical copy into all three). - Verify: `bash scripts/sync-design.sh check` — exits 1 on drift (CI-friendly). - Edit the canonical copy in `keluargamart-b2b-frontend`, never the ERP/POS copies. - Per-app `DESIGN.md` stays per-app (product-specific prose); only this file and the sync script are synced. Audited 2026-08-20: computed styles on all three logged-in UIs, cross-checked against each repo's DESIGN.md. ## 1. Shared foundation — fixed everywhere These are the family contract values. Every frontend must render them identically (tokens wired per app: Nuxt UI `--ui-*` + `app.config.ts` in B2B; Tailwind v4 `@theme` in `src/assets/base.css` (ERP) and `src/styles/main.css` (POS)). | Token | Value | | --- | --- | | Brand primary | `#142B80` — hover `#102268`, soft `#DCE7FC`, line `#C4D4F5` | | Canvas / surface / well | `#F5F8FF` / `#FFFFFF` / `#EEF3FA` | | Line / line-strong | `#D9E2F0` / `#BCCBE4` | | Ink (primary) | `#14213D` — ≥14:1 on every surface | | Ink-2 (muted) | `#475569` — ≥6.8:1 on every surface | | Ink-3 (subtle) | `#64748B` — white surfaces only (4.76:1) | | Ink-disabled | `#94A3B8` — non-text only | | Status tones | success `#15803D`/`#ECFAF0` · warning `#B45309`/`#FFF8EB` · danger `#C0372C`/`#FBE7E4` · info `#0E7490`/`#ECFEFF` · neutral `#475569`/`#EEF3FA` | | Fonts | IBM Plex Sans (all text) + IBM Plex Mono (numerals, codes, `label`); self-hosted, no network fonts | | Type scale | headline 1.5rem/600 · title 1.125rem/600 · body 0.875rem/400 · label 0.75rem mono/500/0.04em | | Focus ring | `outline: 2px solid #142B80; outline-offset: 2px` on every interactive element | | Motion | transform/opacity only; `prefers-reduced-motion` respected; light mode only | | Demo logins | demo login buttons intentionally kept on all login pages | ## 2. Per-app mapping — intentional deltas (do not silently equalize) | Dimension | B2B (Nuxt UI) | ERP | POS | | --- | --- | --- | --- | | Radius scale | badge 8 · control 8 · card 12 | badge 6 · button 8 · input 8 · card 12 · modal 16 | sm 8 · md 10 · lg 12 · xl 16 | | Control height | 32px (framework default) | 44px | 50px (44px touch min) | | Micro type step | not in scale (min 0.75rem) | 0.6875rem/500 | — (uses label/body) | | Primary button | 8px radius, 8×16 padding | 8px radius, 44px height | 8px radius, 15px/700 | | Sidebar | white 256px, pill nav | white 256px, pill nav | white 256px, pill nav | Rationale: radius/height differences track the input paradigm — mouse-dense ERP, touch-first POS, web storefront B2B. When converging, POS `md` 10px and 44–50px controls are the touch-safe targets; B2B inherits Nuxt UI defaults and overrides `--ui-radius` / control height to match. ## 3. Known drift (code vs contract) — verify queue - B2B: Control radius 8px verified (`--ui-radius: 0.5rem` and unlayered `.rounded-md` in `app/assets/css/main.css`) ✓. - B2B: Sidebar active pill (`primary-100` #DCE7FC) and hover pill (`bg-muted` #EEF3FA) wired in `app.config.ts` matching ERP/POS ✓. - ERP: Button radius 8px — measured 8px ✓. POS: lg 12px — measured 12px ✓. ## 4. Sync protocol - Canonical: `keluargamart-b2b-frontend/UNIFORMITY.md` + `keluargamart-b2b-frontend/scripts/sync-design.sh`. - After editing the canonical: run `bash scripts/sync-design.sh` from any repo — it copies both files into all three repos, then verifies checksums. - CI / pre-commit: `bash scripts/sync-design.sh check`. - Never hand-edit the ERP/POS copies; they are byte-for-byte mirrors.