Official design system
Campfire Design Book
The canonical product design book for Campfire. It defines how the site, dashboard, conversation workspace, Launch Room, customer 360, and widget should look, behave, and prove their work.
- Status
- Official
- Owner
- Product Design and Frontend Engineering
- Updated
- 2026-07-17
Campfire Deep Indigo · C1
Brand is deep indigo for CTAs, selection, and proof anchors. AI uses a cooler accent. Amber stays warning-only — never brand.
This is the canonical design system and design book for Campfire. It defines the product's visual thesis, interaction standards, token usage, surface rules, and implementation quality gates for the public site, dashboard, conversation workspace, onboarding, Launch Room, and widget.
If this document conflicts with older implementation notes, this document wins for design direction. Token definitions still live in code and remain the source of truth for exact values.
1. Product Thesis
Campfire is an operator-grade support command center.
The product should feel precise, fast, calm, and proof-backed. It is not a generic SaaS dashboard, a decorative AI shell, or a pile of cards. Every surface should help a support team answer four questions quickly:
- Who needs attention?
- What happened?
- What does Campfire know?
- What should happen next?
The signature experience is proof: setup, AI readiness, customer context, recommendations, and verification should always show evidence. Campfire should win trust by making the system visibly operational.
2. Design Principles
Quiet Authority
The interface should feel controlled before it feels expressive. Use warm neutrals, deep indigo brand accents, clear spacing, precise borders, and confident typography. Avoid novelty styling unless it improves comprehension or confidence.
Proof Over Decoration
Do not show intelligence as generic sparkle, gradients, or "AI magic" badges. Show evidence, readiness, cited sources, test results, timeline states, receipts, and next actions.
Operator Speed
Dashboard surfaces are built for people processing support work under time pressure. Default density is compact. Critical status, risk, assignment, and action affordances must be scannable without hunting.
Human Warmth
Customer-facing widget surfaces may be warmer and more welcoming than the internal dashboard, but they must still feel precise. The widget is hospitality at the edge of an operator system.
Consistency Is Product Quality
Page headers, rails, tabs, empty states, loading states, and action clusters must use the same grammar across the dashboard. If a pattern needs to diverge, document the reason.
3. Canonical Surfaces
Public Site
The public site should sell proof and speed, not generic productivity. Use product-led scenes: launch command, verification receipt, customer 360 evidence, AI readiness, and live support outcomes.
Rules:
- Lead with concrete product moments.
- Use strong editorial hierarchy and fewer, better sections.
- Avoid abstract AI illustrations unless paired with actual proof UI.
- Show terminal and dashboard proof together when explaining setup.
Dashboard Shell
The dashboard shell is an operating environment. It needs compact navigation, clear page identity, sticky context, and active-state clarity.
Rules:
- Use the page registry for title, subtitle, actions, layout density, and nav state.
- Do not infer layout behavior from brittle pathname matching.
- No visible dashboard nav route may lead to a dead destination.
- Header rhythm is canonical: title, concise purpose sentence, primary action, then secondary controls.
- Compact density is default for operator pages. Comfortable density is reserved for settings, docs, and long-form setup.
Conversation Workspace
The served conversation path is canonical:
ConversationsClientPage -> FullWidthConversationLayout -> src/components/conversations/new/*
Older inbox, header, and detail branches are frozen unless compatibility tests or imports require maintenance.
Rules:
- The thread pane is the hero surface.
- The list rail is a decision rail, not a decorative list.
- The right rail is customer 360 and proof, not miscellaneous metadata.
- Critical actions may not be hover-only. Hover can reveal accelerators, not required actions.
- Panel behavior must come from one layout state model.
Launch Room
The Launch Room is Campfire's activation signature: one command turns a site into a trained, verified support operation.
Rules:
- Show the generated command as the primary object.
- Show framework detection, patch plan, verification timeline, and launch receipt.
- Use terminal styling sparingly and accurately.
- Treat every verification step as proof, not onboarding decoration.
Widget
The widget is customer-facing, compact, and hospitable. It should feel connected to Campfire but may use widget-specific tokens for brand contrast, shell warmth, touch targets, and modal constraints.
Rules:
- Use
src/styles/widget-tokens.cssfor widget-specific color, elevation, focus, radius, and sizing. - Maintain accessible contrast even when customer brand colors are injected.
- Prioritize short copy, clear affordances, and fast recovery from errors.
- Do not let dashboard density rules make the widget feel cramped.
4. Visual Language
Campfire's visual language is warm operational precision with a deep indigo brand.
Core traits:
- Warm neutral canvas with white hero surfaces.
- Campfire Deep Indigo (
--brand-primary: 242 52% 46%) for primary actions, selected states, unread anchors, and strong links — premium and ownable, not neon “AI purple.” - AI uses a cooler, quieter indigo family (
--ai-accent) that never equals brand. - Semantic status colors for real system states only (amber warning, red danger, green success stay).
- Fine dividers instead of stacked card borders.
- Compact rows, clear text hierarchy, and low visual noise.
- Mono accents for commands, correlation IDs, tokens, and proof receipts.
- Proof over decoration: brand frames evidence, not wallpaper.
Avoid:
- Orange as brand or CTA (ember is decorative/channel-only).
- Pastel neon indigo / generic AI-purple washes.
- Generic glassmorphism.
- Card farms.
- Decorative badges without operational meaning.
- Arbitrary Tailwind values for one-off spacing, colors, or radius.
- Gradients that compete with work surfaces.
5. Token Sources
Exact values are defined in code:
- Core CSS variables:
src/styles/tokens.css - Widget CSS variables:
src/styles/widget-tokens.css - TypeScript token exports:
src/styles/tokens/index.ts - Legacy token helpers:
src/lib/design-system.tsandsrc/lib/design-system/tokens.ts
Use semantic tokens before raw values. Raw hex, HSL, and arbitrary Tailwind values require a documented exception.
6. Color System
Dashboard Surfaces
Use the shell surface ladder to create hierarchy:
| Token | Use |
|---|---|
--shell-surface-0 | App canvas and quiet background |
--shell-surface-1 | Hero surfaces, thread pane, raised panels |
--shell-surface-2 | Sidebar sections, filters, inset surfaces |
--shell-surface-3 | Hover, selected rows, clear interaction step |
The thread pane should usually be the brightest surface in the conversation workspace. List and context rails can be quieter so the user's attention lands on the active conversation.
Text
Use text hierarchy consistently:
| Token | Use |
|---|---|
--text-primary | Primary content, titles, important values |
--text-secondary | Supporting labels and readable secondary copy |
--text-muted | Metadata and low-priority context |
--text-tertiary | Timestamps, helper copy, subtle affordances |
--text-on-brand | Text on brand-filled controls |
Do not make muted text carry critical state. If the information changes what an operator does next, it needs enough contrast to scan.
Brand
Use deep indigo as a directional accent, not a wash:
--brand-primaryfor primary actions, selected state anchors, brand focus accents, and strong links.--brand-hoverand--brand-activefor interaction progression.--brand-foregroundor--text-on-brandfor text on brand fills.--ai-accent*for AI/model surfaces only — never reuse brand primary for AI chrome.- Structural focus rings stay neutral (
--focus-ring); brand focus is--focus-ring-accent.
Do not use brand color for every icon, pill, and heading. Campfire should feel composed, not saturated. Amber remains warning only. Channel oranges (e.g. Instagram, phone) stay third-party.
Status
Status color must map to real state:
| Token | Meaning |
|---|---|
--status-success | Resolved, verified, healthy, passed |
--status-warning | SLA risk, pending, degraded, needs review |
--status-error | Failed, blocked, breached, destructive |
--status-info | Informational state with no urgency |
--status-vip | Customer importance, not generic highlight |
--status-collab | Team collaboration or agent presence |
Never use warning/error color for decoration. Never use green for "new" unless the state is genuinely successful or verified.
7. Typography
Typography should be readable, compact, and product-grade.
Rules:
- Use the tokenized sans stack for dashboard UI.
- Use mono for commands, IDs, correlation IDs, config keys, metrics, timestamps, and receipts.
- Use weight for hierarchy before adding size.
- Avoid oversized dashboard headings. The page shell needs authority, not marketing scale.
- Public marketing sections may use larger editorial type, but product screenshots and dashboard UI should remain compact.
Dashboard rhythm:
| Element | Standard |
|---|---|
| Page title | Clear noun phrase, medium/semibold, compact line height |
| Subtitle | One sentence explaining purpose or current scope |
| Section title | Short, specific, no marketing adjectives |
| Row title | Customer, conversation, automation, document, or route name |
| Metadata | Muted but readable, never the only carrier of critical state |
Copy should be concrete. Prefer "Widget verified on fyves.com" over "Your experience is ready".
8. Spacing And Density
Use the 4px grid from the token system.
Density modes:
| Mode | Use |
|---|---|
| Compact | Conversation workspace, inbox/list rails, monitoring, analytics tables |
| Standard | Dashboard overview, onboarding, Launch Room, most settings |
| Comfortable | Docs, setup explanations, long forms, public marketing |
Rules:
- Compact does not mean cramped. Preserve readable line height and touch targets where needed.
- Operator rows should prioritize scan lines and status columns.
- Do not invent local row heights unless the component owns a documented density variant.
- Composer padding and thread padding must align.
- Page-level spacing should be calmer than component-level spacing.
9. Radius, Borders, And Elevation
Use radius to clarify containment, not to make every element soft.
| Token | Use |
|---|---|
--radius-sm | Buttons, chips, small controls |
--radius-md | Inputs, cards, menus, panels |
--radius-lg | Drawers, sheets, modals, major shells |
--radius-full / --radius-pill | Avatars, counters, true pills |
Border rules:
- Use
--divider-subtlefor row and section separation inside a surface. - Use
--border-defaultor panel border tokens for panel boundaries. - Avoid stacked borders in headers. If a header has multiple strips, reduce separators and rely on spacing.
- Prefer dividers and surface shifts over nested cards in operational surfaces.
Elevation rules:
- Use shadows for overlays, menus, popovers, drawers, and modals.
- Avoid shadows on every dashboard panel.
- If an element is always visible and not floating, it probably needs a divider, not elevation.
10. Motion
Motion should support orientation and confidence.
Rules:
- Use fast motion for controls and hover state.
- Use normal motion for panel open/close, drilldown, and sheet transitions.
- Use slower motion only for first-run or marketing reveals.
- Animate
opacityandtransformby default. - Do not animate layout in the conversation thread in a way that shifts reading position.
- Respect reduced-motion preferences.
Required motion behaviors:
- Mobile conversation drilldown should feel spatial and reversible.
- Context rail open/collapse should preserve thread stability.
- Launch verification should progress step by step without fake loading.
- Toasts should confirm completed work and include recovery when needed.
11. Interaction States
Every interactive component needs these states:
- Default
- Hover
- Focus-visible
- Active/pressed
- Selected/current
- Disabled
- Loading
- Error or failed
Focus-visible must be strong enough for keyboard navigation. Do not remove focus outlines without replacing them with an accessible tokenized ring.
Critical actions cannot be hover-only. In list rails, show critical actions on selected or focused rows. Hover may reveal convenience actions, but keyboard users and touch users need equal access.
Bulk selection must be an explicit mode. Do not let hidden checkboxes or accidental multi-select patterns create unclear state.
12. Page Grammar
Every dashboard page must follow this page grammar:
- Title row: specific page name.
- Purpose sentence: one sentence, no hype.
- Primary action: one clear action when applicable.
- Secondary controls: search, filter, sort, date range, density, export.
- Body: surface-specific content.
- Empty state: what happened, why it matters, and what to do next.
- Save/dirty/success feedback when data can be changed.
Header action density:
- One primary action.
- Two to four common secondary actions.
- Low-frequency actions in overflow.
- Search is visible on desktop when search is central to the workflow.
- Mobile may collapse secondary controls, but primary action stays reachable.
13. Conversation Workspace Grammar
List Rail
The list rail is a decision rail.
Rows should answer:
- Who is the customer?
- Is this unread or waiting?
- Who owns it?
- Is there SLA or VIP risk?
- What channel or team inbox does it belong to?
- What is the latest meaningful event?
Rules:
- Keep row density compact.
- Show assignee, SLA risk, and channel/team when available.
- Use unread and selected states with clear contrast.
- Do not hide operationally critical state behind hover.
- Use quick filters sparingly: Mine, Unassigned, Waiting/SLA risk.
Thread Header
The thread header should be surgical.
Rules:
- Resolve/Reopen is usually the primary action.
- Assign, snooze, priority, tags, and context toggle are visible when high-frequency.
- Low-frequency actions go to overflow.
- Reduce border stacking. Group information by purpose, not by implementation branch.
- Next-step AI guidance should be collapsible or persistent by user preference.
Message Thread
The message thread should feel editorial and stable.
Rules:
- Group messages by human rhythm: author, time gap, channel, and handoff boundary.
- Preserve scroll position across state changes.
- Align composer padding to thread padding.
- Internal notes must feel native, not like a mode hacked onto reply.
- Attachment validation must happen before upload and clearly explain type, size, and MIME failures.
Right Rail
The right rail is Customer 360 plus proof.
Tabs:
- Overview: identity, account, VIP/risk, health, lifecycle, channel, SLA state, next best action.
- History: prior conversations for the same customer or email fallback.
- Evidence: AI basis, citations, similar conversations, gaps, confidence, pending actions.
- Attributes: organization-scoped customer fields.
Rules:
- Evidence must explain recommendations.
- History must be prior-customer history, not current-thread metadata.
- Attributes must be organization-scoped and safe from cross-organization leakage.
- AI readiness is operational proof, not generic onboarding progress.
14. Launch Room Grammar
The Launch Room should make activation feel inevitable and verifiable.
Required objects:
- Generated command:
npx campfire@latest launch --claim <token> - Framework detection result.
- Diff or patch plan.
- Verification timeline.
- Doctor result.
- Launch receipt.
- Next recommended action.
Receipt fields:
- Elapsed time.
- Framework.
- Files changed.
- Widget status.
- AI readiness.
- First test result.
- Correlation ID.
- Next action.
Rules:
- The command block is the hero component.
- Use mono typography for commands, config, logs, and correlation IDs.
- Do not show vague progress. Show named verification steps.
- If verification fails, give one likely cause and one recovery action first.
15. Components
Buttons
Use one primary action per region. Primary buttons use brand fill. Secondary buttons use neutral or subtle surfaces. Destructive buttons use error only when the action is destructive.
Button copy starts with a verb:
- Resolve
- Assign
- Launch
- Verify
- Create KB gap
- Suggest automation
Avoid vague button copy:
- Continue
- Done
- Learn more
- Make it better
Chips And Badges
Chips are for state, filters, or small classifications. Badges are for counts or urgency.
Rules:
- A chip must either filter, explain state, or identify a category.
- Decorative chips are not allowed.
- SLA, VIP, unread, failed, verified, and AI-ready states need semantic color.
- Neutral metadata chips should remain quiet.
Inputs
Inputs should feel compact and calm.
Rules:
- Labels stay visible.
- Placeholder is example content, not a replacement for label.
- Error text explains recovery.
- Search inputs need visible affordance when search is central to the page.
Empty States
Empty states must be useful, not cute.
Structure:
- What is empty.
- Why it matters.
- Primary next action.
- Secondary learn/setup link only when useful.
Example:
No prior conversations yet. Campfire will build customer history here after this customer writes in again.
Proof Cards
Proof cards show operational evidence, not marketing claims.
Use them for:
- Widget installed.
- Test conversation passed.
- KB connected and processed.
- AI answer cited sources.
- Launch receipt.
- SLA risk detected.
Avoid them for:
- Generic feature promotion.
- Decorative onboarding milestones.
- Anything that cannot be backed by data.
16. Copy System
Campfire copy should be concrete, direct, and operational.
Voice:
- Clear.
- Calm.
- Specific.
- Evidence-backed.
- Low hype.
Avoid:
- Seamless.
- Unlock.
- Supercharge.
- Delightful.
- Magical.
- Effortless, unless the product actually completed the task.
Preferred patterns:
- "Widget verified on
app.fyves.com." - "3 KB gaps are blocking confident AI replies."
- "SLA risk: customer has waited 42 minutes."
- "Create a KB gap from this evidence."
Do not over-explain in the dashboard. If a user is in an operator surface, assume they need the next useful fact or action.
17. Accessibility
Accessibility is part of product quality.
Rules:
- Preserve visible focus states.
- Support keyboard navigation for rails, tabs, dialogs, menus, and command surfaces.
- Maintain contrast for text, icons, borders, and status chips.
- Use 44px minimum touch targets for mobile and widget controls where practical.
- Provide labels for icon-only controls.
- Respect
prefers-reduced-motion. - Do not rely on color alone for critical state.
- Preserve screen reader semantics when using custom tabs, sheets, and virtualized lists.
18. Data Visualization
Analytics should feel like operations, not decoration.
Rules:
- Use semantic color first.
- Use restrained chart palettes.
- Label axes, time ranges, and comparison periods clearly.
- Show "no data", "partial data", and "stale data" states.
- Do not overuse donut charts.
- Tie insights to actions when possible.
Analytics modes:
- Executive: trends, cost, volume, customer experience.
- Operations: SLA, queues, backlog, risk, routing.
- Agent performance: load, outcomes, quality, coaching.
19. Responsive Behavior
Desktop:
- Conversation workspace uses list, thread, and context rail when space allows.
- Search and high-frequency controls stay visible.
- Context rail may persist open/collapsed state.
Tablet:
- Preserve the thread and selected context.
- Allow rails to collapse or become sheets.
- Avoid squeezing all columns until content becomes illegible.
Mobile:
- Use drilldown for selected conversations.
- Keep primary thread actions reachable.
- Context moves to a sheet or dedicated view.
- Bottom navigation must show clear active state.
20. Implementation Rules
Token Usage
- Use semantic CSS variables and token exports.
- Do not introduce raw color values in components.
- Do not use arbitrary Tailwind values for repeated patterns.
- Add tokens when a value becomes a system pattern.
- Remove or isolate deprecated token usage when touching a component.
Component Ownership
Served conversation workspace owners:
ConversationWorkspaceShellConversationListRailThreadPaneContextRail
New conversation features should land in the owner that matches the user's mental model. Do not add cross-cutting rendering branches to FullWidthConversationLayout unless the shell state model requires it.
Quality Gates
Before shipping a new surface, verify:
- It uses the page grammar.
- It uses semantic tokens.
- It has loading, empty, error, disabled, and success states where applicable.
- Critical actions are not hover-only.
- It works on desktop and mobile.
- It has accessible focus and labels.
- It does not link to dead routes.
- It uses proof when claiming AI, readiness, setup, or verification.
21. Do And Do Not
Do:
- Build around proof, speed, and customer context.
- Make primary actions unmistakable.
- Keep operator surfaces compact.
- Use evidence before explanation.
- Make empty states productive.
- Use dividers and hierarchy before adding more cards.
- Make widget states warm, clear, and recoverable.
Do not:
- Ship visible incomplete routes.
- Hide critical state behind hover.
- Use decorative AI visuals as a substitute for evidence.
- Mix densities inside the same workflow.
- Create one-off colors, radii, or spacing ramps.
- Turn settings pages into unrelated forms.
- Add a new customer context table before proving existing data is insufficient.
22. Governance
This design book should be updated when:
- A new canonical dashboard surface is introduced.
- Token meaning changes.
- A component pattern becomes reusable across multiple surfaces.
- The widget design language changes.
- The Launch Room or customer 360 proof model changes.
Pull requests that introduce new visible UI should cite the relevant section of this book when the design decision is non-obvious.
The product standard is simple: if a support team opens Campfire, the interface should immediately feel like a serious operating system that knows the customer, proves what it knows, and makes the next action obvious.