Spacing
4px base unit. Generous air around small, dense content.
Mokanata is an agent-first CRM. Agents triage, draft and follow up across nine channels; you approve the eighteen things that actually need a human.
Connected to WhatsApp, Instagram, Email and six more channelsThe floor for Growth is 85% of list, so 15% is the most I can offer. I drafted a reply at 15% with a two-year term option, citing the playbook. Confidence 0.74, so it is waiting in your approval queue.
1import { rule } from "@mokanata/guardrails";23// Block any discount below the tier floor.4export const pricingFloor = rule({5 id: "pricing.floor",6 when: (deal, tier) =>7 deal.price >= tier.floor * 0.85,8 onFail: "route_to_human",9 severity: "block",10 cite: true,11 notifiy: ["#deal-desk"],12});
Drafts land in under four seconds, with the sources the agent read pinned underneath.
No red badges and no confetti. Only the eighteen threads below 0.80 confidence wait for you.
Agents and reps work the same thread. Take over mid-draft and the agent steps aside.
Each role is a surface paired with its foreground, measured live. Blue is the only saturated colour outside code.
Muted foreground (#5a6170) measures about 5.6:1 on paper and 5.2:1 on pane, so it clears 4.5:1 for small text. It is for secondary text: metadata, timestamps, counts and descriptions. The lighter offgray (#727a89) only tints graph paper, lips and shadows.
Every tint is a color-mix() off one of these tokens.
One family everywhere: Inter Variable 4.0. Six roles, each with a default and a compact step, and three weights: 400 for text, 550 for headings and selected items, 700 only for the page title. No uppercase, no letter-spacing.
| Role | Default · compact | Weight | Use | Specimen |
|---|---|---|---|---|
| display | 28/34 · 24/30 | 700 | The page title, once per page | Revenue at resting pulse |
| title | 16/22 · 15/20 | 550 | Section headings; dialog, sheet, drawer and alert titles | Approval queue |
| subtitle | 14/20 · 13/18 | 550 titles, 400 text | Card, popover and question titles; leads, quotes, chat bubbles | Churn Watch |
| body | 13/20 · 12/18 | 400, 550 selected | Control labels, menu and nav items, body copy, dialog content | Drafted at 0.74 confidence with 3 sources. |
| caption | 12/16 · 11/14 | 400 | Descriptions, meta rows, errors, group labels, tooltips, chips | Needs approval · 2 min ago |
| micro | 11/14 · 10/12 | 400 | Keyboard caps, counters, tiny badges. One line only | ⌘K · 12 new |
Sizes are written as size/leading in px. In code, call typeClass(role) from @mokanata/ui/lib/type-scale, with "compact" for small and dense controls, and add weight-semibold or weight-bold. The older type-* utilities are aliases of these roles.
When an agent drafts below its confidence threshold, the reply waits in the approval queue with every source it read. The rule that held it back lives in guardrails/pricing.ts, and you can open the thread to see why. Approve it, edit it, or take the conversation over yourself.
4px base unit. Generous air around small, dense content.
Only buttons and small chips are rounded. Cards and sections are square.
Flat drafting paper. Depth is hairlines; shadows are reserved for the lip, floating layers and the editor.
Quiet and fast. Nothing enters on scroll.
Every section is a band; the column carries its own rules.
Lucide at 14px inside buttons, 16px elsewhere.
Lipped buttons, a trailing shortcut on every primary action, and toggles for filtering the approval queue. The blue stays on one button per group.
Triggers an action. Primary carries a trailing Kbd hint and a 2px inset lip that drops on hover.
default · The one action per view that moves work forward.
outline · Secondary action next to a primary one.
secondary · Quiet actions in toolbars and card footers.
tinted · Brand moment that shouldn't outrank the primary.
ghost · Low-emphasis actions in dense rows and menus.
destructive · Opens the confirmation for an irreversible action. Pair it with its icon. On headers and cards it lives in ActionBar’s menu instead.
danger · The confirm button inside that dialog (ConfirmDialog). Only there.
link · Navigation inside running text. Ends in a chevron.
| default | hover | focus | active | disabled | loading | |
|---|---|---|---|---|---|---|
| default | ||||||
| outline | ||||||
| secondary | ||||||
| tinted | ||||||
| ghost | ||||||
| destructive | ||||||
| danger | ||||||
| link |
Header, panel and card actions: one visible primary, the rest behind More actions. Destructive items sit last in red and always confirm.
Joins related actions into one control: split actions, paging, steppers.
A single on/off control, like pinning a guardrail or muting an agent.
| default | hover | focus | pressed | disabled | |
|---|---|---|---|---|---|
| default | |||||
| outline |
Picks one of 2–5 options, like filtering the inbox.
Short status and metadata on threads, agents and records.
Shortcut hints. Every primary action carries one.
Copies a value and says so for two seconds, visibly and to screen readers.
app.mokanata.com/invite/welcome-samIdentity-provider marks for sign-in buttons. Channels use ChannelIcon instead.
36px fields on paper, a 4px radius to match the buttons, and labels in mono. Errors use the deepened red; the blue is reserved for focus and the submit.
Wraps one control with its label, description and error. Every form row is a Field.
Shown to customers on every channel the agent replies from.
Locked while the agent is live. Pause it to change.
Single-line text. Pair it with a Label, or put it in a Field.
| default | hover | focus | disabled | invalid | |
|---|---|---|---|---|---|
| input |
An input with addons: icons, prefixes, shortcut hints or inline actions.
Multi-line text, like a system prompt or an internal note.
Becomes the system prompt. Keep it under 2,000 characters.
Picks one value from a list of 5–15. Base Select needs items for its value label.
Searchable pick from a long list, like assigning an agent.
Type “Legal” to see the empty state.
Independent options. Group them in a FieldSet with a legend.
One choice from 2–5 options that need a sentence each.
Settings that take effect immediately, like autonomy per account.
Drafts above 0.90 confidence go out without review.
The agent drafts but never sends.
Always requires approval.
Tunes a value inside a known range, with the number always visible.
One-time codes, like verifying a WhatsApp Business number.
Sent by SMS to +44 20 7946 0958.
New and current passwords. The toggle keeps one name and reports aria-pressed; the meter rates as you type.
Strong
Picks a date inline, like booking a meeting from a thread.
Sets the period for reports: presets apply at once, a drawn range applies with Apply.
RTL layouts flip with DirectionProvider plus dir on the wrapper.
يظهر للعملاء في كل قناة.
A complete form: FieldGroup rows, one primary submit with its shortcut.
Cards are square, flat and hairlined. Tables are dense mono. The only lift is the flat blue offset on a card you want read first.
A record you can act on. Full composition: header, content, footer.
Small for side panels. Highlight with a flat offset and graph paper, once per view.
Contacts and runs. Mono cells, hairline rows, stage as a badge.
| Channels | Agent | |||||
|---|---|---|---|---|---|---|
| Amara Osei | Northwind Traders | WhatsAppEmail | Negotiation | $184,000 | Closer | 4m ago |
| Jonas Lindqvist | Fjord Logistics | Qualified | $42,500 | Triage | 1h ago | |
| Priya Raman | Kestrel Health | EmailTelegram | Proposal | $96,000 | Meeting | Yesterday |
| Mateo Alvarez | Solano Foods International Holdings | Closed won | $12,800 | Onboarding | 3d ago |
| Name | Stage | Value |
|---|---|---|
No contacts in Closed lost this quarter Clear the stage filter to see all 1,920 contacts. | ||
Inbound volume and agent trends. Blue ramp only; syntax colours stay in the editor.
Stat tiles that choose what the panel below shows, like an agent's trends. Use inside Tabs.
The chart for the chosen metric goes here: auto sent, last 14 days.
Rows in a list: media, title, one line of detail, actions on the right.
Enterprise renewals · Claude Opus
Usage dips on paid accounts
Invoices and failed cards
Knowledge · synced 4m ago
People only. 2px framed squares with serif initials; the dot is the one circle.
FAQ rows and settings that fold. One open at a time.
New agents draft every reply but send nothing. You review the drafts, then turn on autonomy per channel when the numbers hold.
Reasoning you can open on demand, like “Why this draft?”.
Browse a short set side by side: agent templates in the wizard.
A fixed-height stream that scrolls on its own, like live agent activity.
Split panes the user can drag: thread list beside the open thread.
“Can you do 15% if we sign this week?” Closer proposes 12% with a two-year term.
Screenshot placeholders. Dark shot inside a dashed frame 6px out.
Hairlines in the line colour, between groups or inline between metadata.
Status speaks in ink and hairlines. Red is kept for things that will fail; the blue marks progress, not alarm.
A standing condition on the page. One action at most: top-right, or under the text when narrow.
A short confirmation after an action. Base UI toast, mounted at the root.
Known-length work: knowledge sync, imports, wizard steps.
Unknown-length work. Inside a button, it replaces the icon and disables it.
Hold the layout while a record loads. Same shapes as the real thing.
Settings forms with unsaved edits. Appears only while the form differs from what's saved.
Saved value: Northwind Labs
You have unsaved changes
Nothing to show is good news here. Say so, then offer the next step.
Every overlay sits on bg-2 with a hairline ring and the one soft shadow the system allows. Each trigger below is real; its caption says what it opens.
A focused edit that must finish or cancel, like editing an agent's draft.
Confirm an action that changes what agents are allowed to do.
Context that sits beside the thread: the contact record, autonomy settings.
The mobile composer. Swipe down to dismiss.
Explain a number in place without leaving the queue.
Preview an agent or contact named inline.
Name an icon-only action and its shortcut.
Thread actions: grouped items, toggles, a submenu, and the destructive action last.
The same actions on right-click, for power users triaging fast.
Jump anywhere by name. Inline here; ⌘K opens it as a dialog.
Customer, agent and human share one thread. MessageScroller owns the scrolling, Bubble owns the surface, and Marker records every handoff.
One mark per channel, in brand colour. ChannelLabel in text and table cells, ChannelBadge on records, ChannelIcon alone only with an aria-label. Pass mono on filled surfaces.
One WhatsApp conversation: the agent quotes, a guardrail holds a discount, a human takes over. Scroll up for history; the button jumps back to the latest.
A template or campaign as the customer gets it, in WhatsApp's own colours. Compose the parts; mark filled-in variables so they stay findable. For previews only, never for Mokanata's own threads.
This business uses a secure service from Meta to manage this chat.
Hi Nadia, following up on the pilot for Larkspur. Would a 20-minute call help?
What an agent did before it wrote: one line per tool call, folded into a run. It sits apart from the reply bubble. Say the status in the title too (Searching, Couldn’t), because colour and pulse alone don’t carry it.
An agent asks a human for a decision it isn't allowed to make alone.
A tinted bubble with its countdown and the shortcut to approve.
Agent text is Markdown with core syntax only: no raw HTML, no callouts, no heading IDs. While it streams, each update reparses the whole reply, and dangling blocks stay hidden until they have content.
Each variant has one job. Keep them consistent across channels.
Customers sit at the start; your team, human or agent, at the end. Group consecutive rows.
System notes, handoffs and day dividers. Never a Separator with a label.
Wire state to the real upload status. Errors say what went wrong and offer a retry.
Each pair renders a rule from zedative.DESIGN.md. The right-hand frames are deliberate counter-examples.
One blue button, with its shortcut hint. Everything else is outline or ghost.
Two blue buttons compete, and neither says which key fires it.
400 for text, 550 for headings and selected items, 700 only for the display page title.
A bold section heading competes with the page title, and a 15px label sits off the six-role scale.
Hierarchy comes from size and weight. An eyebrow is a plain caption in sentence case.
Capitals and wide tracking shout, read slower, and add a seventh style the scale does not have.
The Closer agent drafted 42 replies overnight. 18 sit under your approval threshold and wait in the queue.
Inter in --ink. Black is for headings and labels.
The Closer agent drafted 42 replies overnight. 18 sit under your approval threshold and wait in the queue.
A paragraph in pure black reads like a different product.
0 radius, a 1px border, no shadow. A highlighted card gets a flat offset.
Rounded corners, a soft drop shadow and a gradient fill: all three are banned.
At most two blue moments per viewport above the footer.
Blue icons, badges, links and buttons all at once: nothing stands out.
The DESIGN.md's recipes assembled from shadcn components and tokens only. If one needed a raw value, the token map would be incomplete.
We stopped triaging WhatsApp by hand in week one. The queue only shows what actually needs a human, and it cites where every number came from.
Our Closer agent drafts renewals at 2am, and nothing over $100k leaves without my sign-off. That guardrail is why legal said yes.
Nine channels, one thread per customer. Handoff time dropped from hours to four minutes, and I can see why each draft was written.
Dashed-frame screenshots, serif titles, mono body. Questions fold into + rows below.
WhatsApp, Instagram, Email, TikTok, Telegram, LinkedIn, Facebook, X and Threads in a single thread list.
Every reply carries a confidence score and the sources it cited, inline.
Approve, edit or reassign. Bulk-approve anything above the threshold you set.
Rules like deal.price ≥ tier.floor × 0.85 block, warn or route to a human.
New agents draft but never send until you turn autonomy on.
One person across WhatsApp, LinkedIn and Email, with one open deal.
Every action is logged with who did it, why, and which source it leaned on. These are last night's numbers.
Start from a template, then tune its guardrails. Rows fade as they fall out of the top picks.
Drafts follow-ups and nudges deals to signature.
☺ mokanataTags, routes and answers tier-one questions.
☺ mokanataFlags churn signals 60 days before renewal.
☺ mokanataFinds a slot and sends the invite in-thread.
☺ calpathFills company, role and stage from public data.
☺ dataloomAnswers invoice questions with ledger citations.
☺ ledgerlyTurns Instagram comments into qualified leads.
☺ mokanataWalks new accounts through their first week.
☺ kitestackBuilds quotes inside the price floor guardrail.
☺ northwindMessages booth visitors within the hour.
☺ boothlyRe-opens lost deals when a trigger fires.
☺ mokanataHands regional leads to the right reseller.
☺ meridianRevenue teams spend their mornings copying the same answer into nine different apps. We built Mokanata so that work happens overnight, by agents, and lands in front of you as a short queue of decisions.
The rule we never bend: an agent that isn't sure asks. Every draft shows its confidence and its sources, and anything risky waits for a human. Autonomy is something you grant, account by account.
One realistic screen built only from the tokens and components above.
1,284 actions in the last 24h · 18 need your sign-off
Hi Mei, the 12-seat Team plan comes to $588/month. I've attached the quote with the annual discount applied.
Jonas, your renewal is on 14 Nov. Usage is up 40%, so I'd suggest moving to Fleet before then.
Thanks for the comment! Yes, Mokanata connects Instagram DMs and comments to the same inbox.