Component Library

Every button, card, badge, input, modal, and pattern that exists in the FranchiseHQ design system. Source of truth for the web platform, the bot dashboards, and the future React Native app.

tokens.css — design tokens nav-styles.css — shell layout Palette A — refined cyan

Color

Brand uses cyan for action and gold for emotional weight. Status colors are semantic — use them for what they mean, not as decoration. Contrast labels show WCAG compliance against --bg-canvas.

Brand
Cyan
#00D4FF
--cyan
9.6:1 AAA
Cyan dim
#0099BB
--cyan-dim
Gold
#F0B429
--gold
9.0:1 AAA
Background
Canvas
#060E1A
--bg-canvas
Surface
#0A1628
--bg-surface
Card
#0D1A2E
--bg-card
Card-hi
#111F35
--bg-card-hi
Text
Primary
#E8EDF5
--text-primary
14.8:1 AAA
Muted
#8BA5C8
--text-muted
6.4:1 AAA
Dimmed
#6F8AAC
--text-dimmed
4.7:1 AA
n-500
#4A6080
--n-500
2.8:1 — borders only
Status
Success
#22C55E
--success
Warning
#F97316
--warning
Error
#EF4444
--error

Typography

Two families. Barlow Condensed for display, headings, labels, and buttons. Barlow for body. Headings stay white — the primary brand emphasis comes from Barlow Condensed at heavy weights, not from coloring text cyan.

Display Hero
Display/Hero
Barlow Condensed 900 · 56px
line-height 0.95 · uppercase
Display Section
Display/Section
Barlow Condensed 800 · 38px
Heading H1
Heading/H1
Barlow Condensed 800 · 28px
Heading H2
Heading/H2
Barlow Condensed 700 · 22px
Eyebrow Cyan (current page only)
Eyebrow/Cyan
Barlow Condensed 700 · 11px
tracking 2px · cyan
Eyebrow Gold (default for section labels)
Eyebrow/Gold
Barlow Condensed 700 · 11px
tracking 2px · gold
Body Regular — for descriptions, paragraph copy, and most readable text in the product. Barlow at 15px gives comfortable reading on desktop and mobile alike.
Body/Regular
Barlow 400 · 15px
line-height 1.65
Body Muted Small — captions, footers, secondary metadata.
Body/Small
Barlow 400 · 13px
color: text-muted
/post-schedule
Mono/Code
JetBrains Mono · 13px
cyan — used for slash commands

Spacing

8px base grid. Use these values for padding, margins, and gaps in new components. Existing components keep current values; migrate during regular maintenance, not as a sweeping refactor.

--space-1
4pxxs · icon offsets
--space-2
8pxsm · inner padding
--space-3
12pxmd-sm
--space-4
16pxmd · standard padding
--space-6
24pxlg · card padding
--space-8
32pxxl
--space-12
48px2xl · section sep
--space-16
64px3xl · hero sections

Border Radius

Corner radius scale. Use the smallest radius that reads correctly — buttons (md), cards (lg), modals (xl).

3px
xs
4px
sm
7px
md
10px
lg
14px
xl

Buttons

Primary CTAs use the cyan gradient. Secondary uses outline. Ghost is for tertiary actions. All buttons meet 44×44 minimum tap target. Keyboard focus shows a visible cyan outline.

Variants
.btn .btn-primary | .btn-secondary | .btn-ghost | .btn-gold | .btn-danger
States
:hover · :disabled · .btn-loading
Sizes
.btn-sm · default · .btn-lg · .btn-icon-only

Cards

Standard cards have a card background, 1px border, 24px padding. Hoverable cards lift on hover. Featured cards have a cyan border and corner badge.

Standard Card

Default card pattern — used everywhere. Padding follows the 8px grid (24px = --space-6).

Hoverable

Hover me — lifts and shows cyan border with shadow glow.

Featured

Has a cyan border and "FEATURED" badge above. Used sparingly.

.card · .card-hoverable · .card-feature

Forms & Inputs

All inputs share the same baseline: bg-surface, border, 13px text, 7px radius. Focus state shows a cyan border + glow ring. Min height 44px.

3–32 characters. Used for your public profile URL.

Please enter a valid email address.

.input-text · .input-select · .input-textarea · .is-error · .is-success

Badges & Pills

Badges use color semantically. Cyan = brand/info, Gold = premium/award, Success = active, Warning = attention, Error = problem, Muted = neutral.

🎮 PS5 ⭐ FEATURED 🟢 RECRUITING ⚠ DEADLINE ❌ EXPIRED 32 TEAMS
.badge .badge-{cyan|gold|success|warning|error|muted}
Pill (larger badge)
Madden Franchise Bot
.pill

Stats

Big number + small uppercase label. Use semantic colors: cyan for default data, gold for ratings, success for positive financial.

100+
Commands
4.9★
Rating
12
Active Leagues
$7.99
/month
214
Trades This Season
↑ 23% week over week
.stat .stat-num [.gold | .success | .error] .stat-label .stat-trend [.down]

Tables

Cyan uppercase column headers on bg-card-hi. Body rows with hover state. Use for standings, leaderboards, audit logs.

RankTeamRecordPFPA
1Bills11-3389241
2Patriots9-5312278
3Dolphins8-6301289
4Jets4-10234351
.tbl

Modals

14px radius, modal shadow, max-width 460px. On mobile, bottom-sheet pattern with swipe-down dismiss is preferred.

.modal-demo (max-width 460px, --shadow-modal, --r-xl)

Toasts

Brief feedback messages. Auto-dismiss after 2.5s. Position: bottom-center, 80px above bottom edge to avoid mobile CTA bar collision.

✓ League profile saved
⚠ Could not save — try again
📋 Link copied to clipboard
.toast .toast-{success|error|info}

Loading States (Skeletons)

Match the eventual layout shape. Better than spinners on data-heavy screens — perceived performance is faster, no layout shift when content arrives.

.skel .skel-line [.short|.med|.long] · .skel-card

Empty States

When there's no data, give the user something to do. Every empty state has an icon, a headline, a one-sentence explanation, and exactly one CTA.

🔍

No Matching Leagues

Try removing a filter or broadening your search.

🏟️

No Leagues Listed Yet

Be the first commish to list your league. Takes 30 seconds and you get a permanent profile.

.empty

Embed Previews

How Discord embeds look against Discord's actual chat background (#2b2d31). Color = semantic meaning. Cyan for default, gold for awards, green for success/accepted, red for declined/error.

📅 Week 8 Schedule Posted
All 16 matchups locked. Game channels created. Active check live now.
Matchups
16
Channels
Created
Deadline
Sun 11pm
Default — color=BRAND_CYAN (0x00D4FF)
🏆 Championship — LEFTY42 Season 3
Bills defeat Patriots 31–24 in OT. Josh Allen named Super Bowl MVP.
Award/Championship — color=BRAND_GOLD (0xF0B429)
✅ Trade Accepted
BillsPatriots. AI verdict: Slight edge to Bills (4%).
Success/Accepted — color=BRAND_GREEN (0x22C55E)
❌ Trade Declined
Patriots declined the proposal from Bills.
Decline/Error — color=BRAND_RED (0xEF4444)

Accessibility Rules

These are not guidelines, they're requirements. Any new component that violates these rules doesn't ship.

  • Min tap target 44×44px — WCAG 2.5.5. Buttons, nav items, checkboxes. Use min-height: var(--tap-min).
  • Min text contrast 4.5:1 — WCAG AA. Text-muted (#8BA5C8) and text-dimmed (#6F8AAC) both pass. --n-500 does NOT — borders only.
  • Focus-visible outline — 2px solid cyan, offset 2px. Already in nav-styles.css.
  • Color is never the only signal — trade-accepted has ✅ icon AND green color. Trade-declined has ❌ icon AND red color. Color-blind users need redundancy.
  • Reduced motion variant — components define @media (prefers-reduced-motion: reduce) behavior. Already wired in tokens.css.
  • Body copy minimum 13px — Barlow at 13px reads on phones. Captions in text-dimmed only at ≥13px.
  • Form labels are persistent, not placeholder-only — placeholder text disappears on focus, leaving users guessing what field they're in.
  • Loading states announce themselves — use aria-live="polite" on result counts and skeleton containers.
  • Modal close on Escape key — every modal binds Escape to its close handler.