01 · Color

Palette

The whole brand sits on ~12 tokens. The terracotta accent is the only saturated color in the system — everything else is in the warm-stone neutral family. This is intentional: scarcity makes the accent meaningful.

Accent (the brand color)
accent
#C44536
Primary actions, links, focus rings, badges
accent-2
#8E2D24
Hover state, gradient pair, deeper emphasis
accent-ink
#6B1E18
Text/icon ON accent-soft surfaces
accent-soft
#F8DFD8
Icon chip background, tag background, progress track
Neutrals (ink + stone)
ink
#2B2424
Primary text, signature borders & shadows, primary button bg
text-2
#6E5E55
Secondary text, captions, hints
text-3
#9B8C82
Tertiary text, disabled, chevrons, dividers in dense lists
border
#E8DED3
Hairline borders on cards, list dividers
border-strong
#D6C9BB
Input default border, more present than hairline
surface-2
#FBF7F1
Subtle alt surface (filled inputs, zebra rows)
surface
#FFFFFF
All cards and panels
bg
#F5EFE8
App-level page background
Semantic
warn
#D9933A
Warning badges, "needs attention", soft alerts
warn-soft
#FBEFD9
Warning badge bg
success
#4F7A5C
Completed, delivered, "all good" states
success-soft
#DFEEE3
Success badge bg

Note: there is no separate "error" color. The accent is the error/destructive color. This is OK because: (1) the accent is reserved for emphasis, so seeing it on a destructive action reads correctly, and (2) it avoids a competing palette in a system that's already small.

Dark mode pair

bg
#1A1410
Warm-dark page bg
surface
#2A201A
Cards
surface-2
#352B24
Filled inputs, alt surface
ink
#F5EFE8
Primary text (was charcoal in light)
accent
#E55D4D
Brighter for dark-mode contrast
border
#3A2D24
Hairline

In dark mode the signature offset shadow flips: 4px 4px 0 var(--accent) instead of ink. Otherwise the signature would disappear into the bg.

02 · Type

Typography

Inter (or system: -apple-system, Roboto, system-ui). Weights 500 / 600 / 700 / 800. Tracking -0.01em on display sizes. Mono only for raw IDs (IDNO, phone, version numbers).

display
Bună dimineața, Andrei
28/32800 -0.02em
h1 / page title
Magazinul tău e aproape gata
22/28700 -0.01em
h2 / section
Echipa
18/24700
h3 / card title
Comanda #1248 e în drum
15/20700
body
Răsfoiește catalogul nostru exclusiv de vinuri moldovenești.
14/20400/500
label / button
Invită colegii în echipă
13/18600
caption / hint
2 din 4 pași completați
12/16500
eyebrow
Configurare
11/14700 +0.08em UPPER
mono / ID
IDNO 1003600012345
13/18500 mono
03 · Spacing

Spacing scale

Scale of 4. Pick from the scale — do not invent intermediate values. Common patterns: 18 (screen edge padding), 14-16 (card padding), 10-12 (card gap), 6-8 (icon-to-text gap).

space-1
4 px
space-2
8 px
space-3
12 px
space-4
16 px
space-5
18 px (screen padding)
space-6
24 px
space-7
32 px
space-8
48 px
04 · Radii

Border radius

Five values. The 14px hero-card radius is the most distinctive — pair it with the signature offset shadow for editorial moments.

radius-1
6 px
Brand mark · tag
radius-2
8 px
Small chip · cell
radius-3
10 px
Button · input · icon chip
radius-4
12 px
List card · standard
radius-5
14 px
Hero · signature card
pill
999 px
Badge · avatar · chip
05 · Elevation

Borders & shadows

Three elevation styles. The "signature" style is the brand's recognizable element — use sparingly for hero moments, not on every card.

Hero / momentum card
The signature treatment.
Signature
1.5px solid ink + 4 4 0 ink
Hero cards, momentum cards, primary CTAs
List card
For row items and standard cards.
Hairline
1px solid border + 0 1px 2px rgba(0,0,0,.05)
List rows, nav items, secondary cards
Flush
For inline groupings.
Flush
1px solid border
Grouped lists, inline tables
Inverted
When you need contrast.
Inverted (ink)
background: ink, color: bg
Profile header, route hero (expeditor), modal overlays
06 · Buttons

Buttons

5 variants. Primary action uses ink (not accent) — accent is reserved for emphasis moments. All buttons share radius-10 and weight-600.

Primary
bg: ink · color: bg
Use for the main action on a screen.
Accent
bg: accent · color: white
Use for "urgent" or hero CTAs (e.g. "Start route"). Rare.
Secondary
bg: white · border: 1.5px ink
Use beside primary as the alt action.
Ghost
bg: transparent · color: accent
Use for low-emphasis text-only actions.
Destructive
bg: accent · border: accent-2
Same as accent but with darker border for emphasis.
Disabled
bg: text-3 · cursor: not-allowed
07 · Inputs

Form inputs

Inputs use the slightly stronger border (border-strong) to feel substantial. Focus state is full ink. OTP cells are a specialized variant.

Default
Numărul de telefon
Vei primi un cod prin SMS.
Focused
Nume organizație
Acest nume va apărea pe facturi.
Error
IDNO
IDNO trebuie să aibă 10 sau 13 cifre.
Disabled
Email (opțional)
Editabil din profil.
OTP cells
Codul de verificare
1
2
3
|
Trimis la +373 60 123 456
08 · Indicators

Badges, chips, progress

Used for status, filters, and progress moments.

Nou Tier 2 În curând Livrată Anulată Beta Badges — 10.5px / 700 / 3×9 / pill
Toate Vinuri Băuturi Sezon Chips — 12px / 600 / 6×12 / pill
Progress
2 din 4 pași completați
09 · Icons

Icon system

Stroked icons from Lucide React Native (or Phosphor as a fallback). 1.5px stroke weight, 20-22px size. Always rendered in an "icon chip" container: 32×32 or 36×36 rounded square with accent-soft bg.

home
Acasă tab
grid
Catalog/Produse
clipboard-list
Comenzi
users
Echipa
map-pin
Rute / Vizite
star
Loialitate
settings
Setări
bell
Notificări
?
help-circle
Suport
log-out
Ieși din cont

The glyphs above (▤ ◑ ⌖ etc.) are placeholder geometry for these mockups only. Production uses the actual SVG icons from Lucide React Native.

10 · Chrome

Top bar & bottom tab bar

The two pieces of chrome that bracket every authenticated screen.

Top bar
S
Magazin Central
Proprietar
AG

Brand mark + org/role chip on the left. Bell (notifications) + avatar (tap → profile screen) on the right. Avatar has a 2px ink border to signal it's tappable.

Bottom tab bar
Acasă
Magazin
Echipa
Comenzi

Always 4 tabs. Active tab gets the accent color plus a small accent indicator at the top. Inactive tabs are text-3. Background is pure white to maximize legibility against the warm bg.

10b · Chrome scale

Chrome reads ~15–25% bigger than the content type scale

The type scale in section 02 is correct for content — display headings, body copy, captions inside cards. When the same tokens are applied verbatim to chrome (top bars, tab bars, brand marks, input fields, role badges, sheet rows, CTA labels), the result reads too small at native DPI. Chrome elements need an explicit bump.

Chrome overrides (use these in primitives, not the content tokens)
Element Spec (was) Chrome (use this) Lives in
TopBar brand mark 28×28, font 12 36×36, font 15 TopBar.tsx
TopBar title label · 13/18 h3 · 15/20 TopBar.tsx
TopBar subtitle 11/14 13/16 TopBar.tsx
TopBar bell 32×32 40×40 TopBar.tsx
Tab bar label 10/13 12/16 (tabs)/_layout.tsx
Tab bar icon 18 22 (tabs)/_layout.tsx
Tab bar height 64 76 + safe-area (tabs)/_layout.tsx
Button label label · 13/18 15/20 · weight 700 Button.tsx
Button height ~46 (s3+2 padding) ~52 (s4 padding) Button.tsx
Input field height ~44 (s3 padding) ~52 (s4 padding) Input.tsx
Input label caption · 12/16 13/18 · weight 600 Input.tsx
Badge text 10.5 11.5 Badge.tsx
BottomSheet subtitle 14 15 BottomSheet.tsx
List-row label (member name, settings row, sheet row, role picker) label · 13/18 17/22 · weight 600 (matches iOS Settings) ListRow.tsx + per-screen overrides
List-row trailing meta (e.g. "v0.1.0") caption · 12/16 15/18 · weight 500 per-screen
Screen-edge padding s5 · 18px s6 · 24px every screen

Why this exists. Native rendering at high DPI makes the literal token values feel smaller than they look in the static HTML mockup. The rule isn't that the type scale is wrong — it's that chrome and content are different problems. Body type at 14 inside a card is readable; the same 14 in a tab bar disappears.

How to apply. Implement chrome elements as primitives (Button, Input, TopBar, Badge, BottomSheet, the eventual ScreenHeader). Bake the bumped values into the primitive so every consumer gets the right size by default. If you find yourself overriding a primitive's font/padding inline because "it feels small", the bump belongs in the primitive instead.

What we did not do. Add a separate chrome namespace to constants/tokens.ts. With ~6 primitives, inline overrides are easier to read than a second indirection layer. Revisit if primitive count doubles.

CSS variables (ready to copy into constants/Colors.ts)
/* LIGHT */
--bg#F5EFE8
--surface#FFFFFF
--surface-2#FBF7F1
--ink#2B2424
--text-2#6E5E55
--text-3#9B8C82
--border#E8DED3
--border-strong#D6C9BB
--accent#C44536
--accent-2#8E2D24
--accent-soft#F8DFD8
--accent-ink#6B1E18
--warn / warn-soft#D9933A / #FBEFD9
--success / success-soft#4F7A5C / #DFEEE3
/* DARK */
--bg#1A1410
--surface#2A201A
--ink (text)#F5EFE8
--accent#E55D4D
--border#3A2D24
/* TYPE */
font-family'Inter', -apple-system, Roboto, system-ui
display / h1 / h2 / h328 800 / 22 700 / 18 700 / 15 700
body / label / caption14 500 / 13 600 / 12 500
eyebrow / mono11 700 +0.08em UPPER / 13 mono
/* SPACE */
scale4 8 12 16 18 24 32 48
screen padding24px horizontal (s6 — chrome scale)
/* CHROME (overrides; see §10b) */
topbar mark / title / sub / bell36 / 15 / 13 / 40
tabbar label / icon / height12 / 22 / 76 + safe-area
button label / height15 / ~52
input field / label~52 / 13
badge text11.5
list-row label / trailing17 600 / 15 500 (iOS Settings parity)
/* RADIUS */
scale6 8 10 12 14 999
hero/signature14px
/* ELEVATION */
--shadow-offset (light)4px 4px 0 var(--ink)
--shadow-offset (dark)4px 4px 0 var(--accent)
--shadow-hair0 1px 2px rgba(43,36,36,.05)
← back to index