Skip to content

Campaign Brain Style Guide

Visual Identity & UI Design System

Version 1.0 • December 2025


1. Introduction

This style guide establishes the visual identity and design standards for Campaign Brain, a political campaign CRM and workflow management platform. The design language draws from the brand's core imagery—the eagle representing strength and clarity, paired with the brain symbolizing intelligent, data-driven decisions.

The visual system balances patriotic gravitas with modern usability, creating an interface that feels authoritative yet approachable. This guide covers color palette, typography, iconography, component design, and layout patterns specifically optimized for FastHTML implementations.


2. Color Palette

The Campaign Brain color system is derived directly from the logo, emphasizing a professional navy and patriotic red as primary brand colors. The current UI uses a teal/turquoise accent that should be phased out in favor of brand-aligned colors.

2.1 Primary Colors

These colors form the core of the Campaign Brain identity and should be used prominently throughout the interface.

Color Hex Value Usage
Navy Primary #1E3A5F Headers, navigation bars, primary buttons, headings
Navy Dark #152942 Hover states, active navigation, footer backgrounds
Brand Red #8B2332 Accent elements, call-to-action buttons, important highlights
Red Light #A63446 Hover states for red elements, secondary accents

2.2 Neutral Colors

A carefully calibrated gray scale provides the foundation for text, borders, backgrounds, and subtle UI elements.

Color Hex Value Usage
Background #F8FAFC Page backgrounds, subtle section dividers
Border Light #E2E8F0 Card borders, divider lines, input borders
Text Secondary #64748B Secondary text, placeholders, disabled states
Text Primary #334155 Body text, primary content, labels

2.3 Semantic Colors

Used for status indicators, alerts, and feedback. These should be applied consistently across all system messages.

Status Hex Value Usage
Success #059669 Active status, confirmations, positive indicators
Warning #D97706 Pending states, caution alerts, attention required
Error #DC2626 Error states, destructive actions, critical alerts
Info #0284C7 Informational messages, tips, links

2.4 CSS Variables

Implement these as CSS custom properties for consistent theming across the application:

:root {
    --color-navy-primary: #1E3A5F;
    --color-navy-dark: #152942;
    --color-red-primary: #8B2332;
    --color-red-light: #A63446;
    --color-bg-page: #F8FAFC;
    --color-bg-card: #FFFFFF;
    --color-border: #E2E8F0;
    --color-text-primary: #334155;
    --color-text-secondary: #64748B;
    --color-success: #059669;
    --color-warning: #D97706;
    --color-error: #DC2626;
    --color-info: #0284C7;
}

3. Typography

Typography establishes hierarchy and readability. Campaign Brain uses a two-font system: a serif display font for headings that conveys authority, paired with a clean sans-serif for body content that ensures readability in data-dense interfaces.

3.1 Font Selection (Google Fonts)

Primary Option: Libre Baskerville + Source Sans 3

Libre Baskerville is a refined serif with excellent readability at display sizes. It carries the gravitas appropriate for a political tool while remaining approachable. Use for all headings and display text.

Source Sans 3 (formerly Source Sans Pro) is an open-source sans-serif designed by Adobe for UI clarity. Its clean letterforms work exceptionally well in tables, forms, and dense data displays. Use for body text, labels, and interface elements.

Alternative Option: Merriweather + Inter

Merriweather offers a slightly warmer, more contemporary serif alternative if Libre Baskerville feels too formal.

Inter is an excellent fallback for body text—highly legible and widely supported, though slightly less distinctive than Source Sans 3.

<!-- Google Fonts embed -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Libre+Baskerville:wght@400;700&family=Source+Sans+3:wght@400;500;600;700&display=swap" rel="stylesheet">

3.2 Type Scale

A consistent type scale creates visual rhythm. Sizes are specified in rem for accessibility.

Element Size Weight Font / Notes
Page Title 2rem (32px) 700 Libre Baskerville, Navy Primary
Section Header 1.5rem (24px) 700 Libre Baskerville, Navy Dark
Card Title 1.125rem (18px) 600 Source Sans 3
Body Text 1rem (16px) 400 Source Sans 3, Text Primary
Small / Caption 0.875rem (14px) 400 Source Sans 3, Text Secondary
Button / Label 0.875rem (14px) 500-600 Source Sans 3, uppercase optional

4. Iconography

The current UI uses icons that appear inconsistent in weight and style. A unified icon set will significantly improve visual cohesion.

Primary Choice: Lucide Icons

Lucide (lucide.dev) is the recommended icon library for Campaign Brain. It offers clean, consistent stroke-based icons that work beautifully at the 20-24px sizes common in dashboard interfaces.

Key advantages: - Consistent 2px stroke weight across all icons - Extensive coverage of data and dashboard icons - MIT license with no attribution required - Easy integration via CDN or npm

<!-- Lucide via CDN -->
<script src="https://unpkg.com/lucide@latest"></script>
<script>lucide.createIcons();</script>

<!-- Usage in HTML -->
<i data-lucide="users"></i>
<i data-lucide="calendar"></i>
<i data-lucide="map-pin"></i>

4.2 Icon Sizing

Context Size Stroke
Navigation (sidebar) 20px 1.5px
Top navigation 20px 1.5px
Card headers 18-20px 1.5px
Stat cards (large) 24-28px 2px
Inline / buttons 16px 2px

Replace current icons with these Lucide equivalents for consistency:

Feature Lucide Icon
Dashboard layout-dashboard
Audience / Contacts users
Events calendar
Segments layers
Communications mail
Tags tag
Goals target
Reports bar-chart-2
Import/Export arrow-left-right
Map map
Settings settings
Tenants building-2
Ports network

5. Component Design

Consistent component styling creates a cohesive user experience. These specifications are optimized for FastHTML implementations.

5.1 Buttons

Variant Styles
Primary Background: Navy Primary (#1E3A5F), Text: White, Border: none, Hover: Navy Dark (#152942), Border-radius: 6px, Padding: 0.625rem 1.25rem, Font-weight: 600
Secondary Background: White, Text: Navy Primary, Border: 1px solid #E2E8F0, Hover: Background #F1F5F9, Border-radius: 6px
Accent (CTA) Background: Brand Red (#8B2332), Text: White, Hover: Red Light (#A63446), Use sparingly for primary actions
Ghost Background: transparent, Text: Text Secondary, Hover: Background #F1F5F9, For low-emphasis actions

Note: Replace the current teal "+ New Tenant" button with the Accent (CTA) style to align with brand colors. The current teal (#10B981 range) should be phased out entirely.

5.2 Cards

Cards are the primary container for content grouping. The current implementation is solid but can be refined:

  1. Background: Pure white (#FFFFFF)
  2. Border: 1px solid #E2E8F0
  3. Border-radius: 8px (slightly larger than current)
  4. Shadow: 0 1px 3px rgba(0, 0, 0, 0.05) — subtle, not pronounced
  5. Padding: 1.5rem (24px)
  6. Hover (interactive cards): Border-color: #CBD5E1, Shadow: 0 4px 6px rgba(0, 0, 0, 0.07)

5.3 Status Badges

The current "Pending" badges are functional but could be more refined:

Status Styles
Active Background: #ECFDF5, Text: #059669, Border: 1px solid #A7F3D0
Pending Background: #FFFBEB, Text: #D97706, Border: 1px solid #FDE68A
Inactive Background: #F1F5F9, Text: #64748B, Border: 1px solid #E2E8F0
Error Background: #FEF2F2, Text: #DC2626, Border: 1px solid #FECACA

Badge styling: Font-size: 0.75rem (12px), Font-weight: 500, Padding: 0.25rem 0.75rem, Border-radius: 9999px (pill shape)


6. Layout Patterns

6.1 Navigation

Top Navigation Bar

  1. Background: Navy Primary (#1E3A5F)
  2. Height: 56-64px
  3. Text/Icons: White with 80% opacity, 100% on hover
  4. Logo: Left-aligned, with product name in white
  1. Width: 240px expanded, 64px collapsed
  2. Background: White (#FFFFFF)
  3. Border: Right border 1px solid #E2E8F0
  4. Nav Items: Padding 0.75rem 1rem, border-radius 6px
  5. Active State: Background #F1F5F9, left border 3px solid Navy Primary, text color Navy Primary
  6. Hover State: Background #F8FAFC

6.2 Spacing System

Use a consistent 4px base grid for all spacing. Common values:

Token Value Usage
space-1 4px Tight spacing, icon gaps
space-2 8px Form element gaps, badge padding
space-3 12px Button padding, list item spacing
space-4 16px Standard component padding
space-6 24px Card padding, section spacing
space-8 32px Large section gaps

6.3 Data Tables

The voter database table in your screenshots is well-structured. Refinements:

  1. Header row: Background #F8FAFC, text #64748B (Text Secondary), font-weight 600, font-size 0.75rem, uppercase with letter-spacing 0.05em
  2. Body rows: Background white, border-bottom 1px solid #F1F5F9
  3. Row hover: Background #F8FAFC
  4. Cell padding: 0.75rem 1rem
  5. Zebra striping: Optional — alternate rows #FAFAFA if preferred

7. FastHTML Implementation

FastHTML's Python-first approach means styling is typically applied via CSS classes. Here's a recommended approach for implementing this style guide.

7.1 CSS Setup

Create a centralized CSS file with the design tokens defined as custom properties. Include in your FastHTML app's head:

from fasthtml.common import *

app = FastHTML(
    hdrs=[
        Link(rel="preconnect", href="https://fonts.googleapis.com"),
        Link(rel="preconnect", href="https://fonts.gstatic.com", crossorigin=True),
        Link(href="https://fonts.googleapis.com/css2?family=Libre+Baskerville:wght@400;700&family=Source+Sans+3:wght@400;500;600;700&display=swap", rel="stylesheet"),
        Link(rel="stylesheet", href="/static/styles.css"),
        Script(src="https://unpkg.com/lucide@latest"),
    ]
)

7.2 Component Helpers

Define reusable component functions for consistent styling:

def Button(text, variant="primary", icon=None, **attrs):
    cls = f"btn btn-{variant}"
    children = []
    if icon:
        children.append(I(data_lucide=icon, cls="btn-icon"))
    children.append(text)
    return Button_(*children, cls=cls, **attrs)

def Card(*children, title=None, icon=None, **attrs):
    header = []
    if icon or title:
        header = [Div(
            I(data_lucide=icon, cls="card-icon") if icon else None,
            H3(title, cls="card-title") if title else None,
            cls="card-header"
        )]
    return Div(*header, *children, cls="card", **attrs)

def Badge(text, status="default"):
    return Span(text, cls=f"badge badge-{status}")

8. Summary: Quick Wins

To immediately improve the UI with minimal effort, prioritize these changes:

  • Replace teal accents — Change the "+ New Tenant" button and any teal elements to Brand Red (#8B2332)
  • Unify icon library — Switch all icons to Lucide with consistent 20px sizing and 1.5px stroke
  • Add Google Fonts — Implement Libre Baskerville for headings and Source Sans 3 for body text
  • Refine card shadows — Use subtle shadows (0 1px 3px rgba(0,0,0,0.05)) instead of hard borders
  • Improve active nav states — Add left border accent and background highlight to current page

— End of Style Guide —