social.plus — Design System v1.0
Build belonging
into every app.

Ready-to-use community infrastructure — feeds, chat, and communities inside your app.

Display typeface Figtree — ExtraBold 800 for display
Body typeface Figtree — 300 to 900
Primary colour Ultramarine · #3B41EC
Token architecture Primitive → Semantic → Component
Modes Dark (default) · Light
Colour in Context
Dark / Hero
All your
communities.
Primary dark surface. Use for hero sections, onboarding screens, and high-contrast moments.
Ultramarine / CTA
Join the
conversation.
Primary action colour. Buttons, highlights, and key conversion moments.
Light / Default
Real people,
real conversations.
Default app background. Clean, not clinical. Every screen breathes here.
Slate / Cards
Your
community awaits.
Card surfaces, secondary backgrounds, and soft UI containers.

Colors

Three primary families — Ultramarine, Slate, Picton Blue — anchored by Slate neutrals and a vivid accent palette for community identities. On dark surfaces, Ultramarine 600 is reserved for fills with white labels; ultramarine text and icons step up to Ultra 400 (--action-accent) to hold WCAG AA contrast.

Primary Families
Ultramarine
Ultra 50 #EDF4FF
Ultra 300 #A1BAFF
Ultra 400 #7B94FE
Text on dark
Ultra 600 #3B41EC
Primary
Ultra 800 #2B2FA8
Slate
Slate 100 #F5F5F5
Slate 300 #D3D3D3
Slate 500 #727272
Secondary
Slate 600 #535353
Picton Blue
Picton 50 #F1F7FE
Picton 300 #84C2F5
Picton 500 #1B89DC
Tertiary
Picton 700 #0C5598
Slate — Neutrals
Slate 950
#111111
Slate 800
#272727
Slate 600
#535353
Slate 400
#A3A3A3
Slate 200
#E6E6E6
Slate 50
#FAFAFA
White
#FFFFFF
Accent Palette — Community Identities

Used exclusively for community avatar gradients, category chips, and user-generated colour identifiers. Never used for UI controls.

Orange · #F66005
Yellow · #F7C506
Pink · #F568F0
Sky · #45A5ED
Periwinkle · #7B94FE
Magenta · #EB4AE5
Gradients
Brand Blue
Solar
Brand Pink
Energy
Gold
Prestige
Airy
Depth
Authority
Vibrant
Ember

Typography

One typeface. Figtree — geometric, warm, confident. ExtraBold carries display moments; Regular and Medium keep body copy clear and human.

Typefaces
Display — Figtree ExtraBold
Join the community.
Real people.
Real belonging.
Weights used 400 (Italic), 600, 700
Optical size 9 – 144
Usage Headlines, CTAs, quotes, hero copy
Body — Figtree
social.plus is the community infrastructure layer — feeds, chat, and communities your users choose to join.
Each one representing people or organisations you genuinely want to connect with, or topics you genuinely care about.
Weights used 300, 400, 500, 600, 700
Usage Body, UI labels, inputs, captions
Type Scale
Token Size Line Height Weight Preview
Display — Figtree ExtraBold
text-hero 3.25rem (52px) 0.95 700 social.plus
text-3xl 2.25rem (36px) 1.05 700 Be part of something
text-2xl 1.75rem (28px) 1.1 700 All your communities
text-xl 1.5rem (24px) 1.15 700 / 400i Join the community
text-xl-italic 1.5rem (24px) 1.15 400i Real belonging.
Interface — Figtree
text-lg 1.25rem (20px) 1.3 500 Section heading
text-md 1.0625rem (17px) 1.35 500 / 400 Card title or strong body
text-base 0.9375rem (15px) 1.45 400 Default body text — readable at all sizes
text-sm 0.8125rem (13px) 1.4 400 / 500 Secondary label or metadata
text-xs 0.75rem (12px) 1.4 500 / 600 CAPTION · OVERLINE · BADGE
Heading Scale — Fluid Clamp
H1 2.75rem - 5rem (44-80px)
clamp(2.75rem, 1.5rem + 2svw, 5rem)
1.1 700 Display
H2 2.25rem - 3.25rem (36-52px)
clamp(2.25rem, 1.5rem + 2svw, 3.25rem)
1.25 700 Section
H3 1.75rem - 2.25rem (28-36px)
clamp(1.75rem, 1rem + 2svw, 2.25rem)
1.25 700 Sub-section
H4 1.5rem - 1.75rem (24-28px)
clamp(1.5rem, 0.875rem + 2svw, 1.75rem)
1.25 700 Small heading
H5 1.25rem (20px) 1.25 700 Compact heading
H6 1.125rem (18px) 1.25 700 Smallest heading
Font Weights
Light 300--weight-light: 300
Regular 400--weight-regular: 400
Medium 500--weight-medium: 500
Semibold 600--weight-semibold: 600
Bold 700--weight-bold: 700
Type Pairings — In Context
Feed Post Header
The best hiking trails in Patagonia
Posted by María G. · Outdoors Community · 2h ago
CTA / Onboarding
Find your
people.
Join communities built around what you actually care about.
Section Title + Body
TRENDING NOW
What your communities are talking about
Conversations surfaced from communities you've joined this week.
Profile Name + Handle
Amadeus Vidal
@amadeus · 14 communities

Spacing

A 4px base grid. Every layout decision — padding, gap, margin — maps to a named step. This keeps rhythm consistent across every screen in the app.

Spacing Scale
Token Value px Common usage Visual
--space-1 1 × 4 4px Icon gap, badge padding, micro nudges
--space-2 2 × 4 8px Chip inner padding, tight icon + label
--space-3 3 × 4 12px Button padding (v), input inner padding
--space-4 4 × 4 16px Button padding (h), card inner gap, nav item
--space-5 5 × 4 20px Card padding, section inner gap
--space-6 6 × 4 24px Card padding (large), modal padding
--space-8 8 × 4 32px Section gap, screen horizontal padding
--space-10 10 × 4 40px Between major sections on screen
--space-12 12 × 4 48px Hero padding, large screen breathing room
--space-16 16 × 4 64px Page-level vertical rhythm
--space-20 20 × 4 80px Bottom nav safe area clearance
Spacing in Context — Mobile Screen Anatomy
9:41 ●●●
social.plus
space-4 · 16px
space-3 · 12px gap
Photography Community
3,240 members · 12 posts today
space-4 · 16px padding
Hiking & Outdoors
1,820 members
Film Lovers
4,100 members
👤
Screen layout tokens
space-4 (16px) — horizontal screen padding, app bar height rhythm
space-3 (12px) — gap between stacked cards
space-2 (8px) — avatar → text gap inside list items
space-20 (80px) — content bottom padding clears the nav bar
Touch targets
44px minimum — all interactive elements meet iOS/Android tap target guidelines

Border Radius

social.plus uses generous, soft curves — echoing the rounded logo mark. Never cold and boxy. Radius scales from sharp utility elements up to fully-circular avatars, with a clear semantic role at each step.

Radius Scale
--radius-xs 4px Tags, code badges, micro chips
--radius-sm 8px Buttons (small), nav items, tooltips
--radius-md 12px Buttons (default), input fields, small cards
--radius-lg 16px Feed cards, list items, dropdowns
--radius-xl 20px Large cards, context panels
--radius-2xl 24px Modal sheets, featured cards
--radius-3xl 32px Bottom sheets, hero images
--radius-pill 100px Pill buttons, search bar, toggles
--radius-full 50% Avatars, icon buttons, indicators
Radius in Context
Join Community
Button · radius-md (12px)
Follow
Pill button · radius-pill (100px)
Photography
Outdoors
Tags · radius-xs (4px)
Weekend hiking trip
48 replies · 2h ago
Feed card · radius-lg (16px)
Avatars · radius-full (50%)
Invite to community
Share a link or search for members
Modal card · radius-2xl (24px)

Elevation

Shadows create a sense of depth and hierarchy. In light mode they use soft neutral shadows — heavier as the layer rises. Switch to dark mode to see the background layering system. Shadows create a sense of depth and hierarchy. In dark mode they rely on background layering — surfaces get progressively lighter as they rise. No heavy drop shadows needed.

Shadow Scale
No shadow
none Flat Inline elements, selected states with border, tab items
shadow-sm
--shadow-sm Level 1 Chips, input fields, subtle cards on light background
shadow-md
--shadow-md Level 2 Cards, dropdowns, context menus
shadow-lg
--shadow-lg Level 3 Floating action buttons, sticky headers, toasts
shadow-xl
--shadow-xl Level 4 Modals, bottom sheets, popovers
shadow-glow
--shadow-glow Glow Primary CTA buttons on hover/focus, featured items
Light Mode — Layering by Background

In light mode, depth is expressed through warm shadows and subtle background steps — from sunken inputs up to pure-white modals. Each layer has a named token.

bg-sunken #E6E6E6 Inputs, recessed areas
bg-base #FAFAFA App base — cream
bg-card #F5F5F5 Cards, feed rows
bg-elevated #FFFFFF Nav bar, modals
Dark Mode — Layering by Background

In dark mode, depth is communicated through progressively lighter backgrounds — not heavier shadows. Each layer has a named token.

bg-sunken #000000 Inputs, recessed areas
bg-deep #000000 Deepest background
bg-base #111111 App base background
bg-elevated #1A1A1A Nav bar, sidebars
bg-card #272727 Cards, panels
bg-card-2 #404040 Nested cards, chips
Z-Index Scale
TokenValueLayer
--z-base0Page content
--z-raised10Sticky cards, inline floats
--z-dropdown100Dropdowns, context menus
--z-sticky200Sticky headers, bottom nav
--z-toast400Toasts, snackbars
--z-overlay500Modal backdrop
--z-modal600Modals, bottom sheets
--z-top900System alerts, debug panels

Motion

Motion should feel warm and alive — never mechanical. Fast for micro-interactions, smooth for transitions, springy for moments of delight. All transitions respect prefers-reduced-motion.

Duration Scale
--duration-instant 80ms State flips — active/inactive toggle, checkbox tick
--duration-fast 150ms Button press feedback, hover reveals, badge updates
--duration-base 250ms Default — theme switch, card expand, drawer slide
--duration-enter 320ms Screen entry, modal appear, page transitions
--duration-slow 400ms Bottom sheet rise, complex layout changes
Easing Curves
--ease-out cubic-bezier(0.16, 1, 0.3, 1) Entering elements — things arriving on screen. Fast start, soft landing.
--ease-in-out cubic-bezier(0.4, 0, 0.2, 1) Transitions between states — smooth, symmetrical, controlled.
--ease-spring cubic-bezier(0.34, 1.56, 0.64, 1) Delight moments — avatar pop, like animation, join confirmation.
Live Interaction Demos

Hover or tap each element to see the motion token in action.

Button press · instant + spring
Photography
Hover me
Card hover · shadow-md · ease-out
Toggle · 150ms · ease-in-out
Avatar pop · spring · tap to try
Reduced Motion
All transitions and animations check prefers-reduced-motion. When enabled, durations collapse to 1ms and transforms are replaced with opacity-only fades.

Primitive Tokens

The raw, hardcoded values. These are never used directly in components — they exist solely as a named source of truth that semantic tokens reference. Change a primitive here and it cascades everywhere.

Primitive
--ultra-600: #3B41EC
Semantic
--action-primary: var(--ultra-600)
Component
--btn-bg: var(--action-primary)
Color — Ultramarine
--ultra-50#EDF4FF
--ultra-300#A1BAFF
--ultra-400#7B94FE
--ultra-600#3B41EC
--ultra-800#2B2FA8
Color — Slate (light)
--slate-100#F5F5F5
--slate-300#D3D3D3
--slate-500#727272
--slate-600#535353
Color — Picton Blue
--picton-50#F1F7FE
--picton-300#84C2F5
--picton-500#1B89DC
--picton-700#0C5598
Color — Slate (dark) & Neutrals
--slate-950#111111
--slate-800#272727
--slate-600#535353
--slate-400#A3A3A3
--slate-200#E6E6E6
--slate-50#FAFAFA
--white#FFFFFF
Color — Accents
--accent-orange#F66005
--accent-orange-light#FF9836
--accent-yellow#F7C506
--accent-pink#F568F0
--accent-sky#45A5ED
--accent-periwinkle#7B94FE
--accent-magenta#EB4AE5
Spacing
--space-14px
--space-28px
--space-312px
--space-416px
--space-520px
--space-624px
--space-832px
--space-1040px
--space-1248px
--space-1664px
--space-2080px
Border Radius
--radius-xs4px
--radius-sm8px
--radius-md12px
--radius-lg16px
--radius-xl20px
--radius-2xl24px
--radius-3xl32px
--radius-pill100px
--radius-full50%
Typography
--text-xs12px
--text-sm13px
--text-base15px
--text-md17px
--text-lg20px
--text-xl24px
--text-2xl28px
--text-3xl36px
--text-hero52px
--weight-light300
--weight-regular400
--weight-medium500
--weight-semibold600
--weight-bold700
Motion
--duration-instant80ms
--duration-fast150ms
--duration-base250ms
--duration-enter320ms
--duration-slow400ms
--ease-outcubic-bezier(0.16,1,0.3,1)
--ease-in-outcubic-bezier(0.4,0,0.2,1)
--ease-springcubic-bezier(0.34,1.56,0.64,1)

Semantic Tokens

Named by role, not by value. Components only ever reference semantic tokens — never primitives. This makes theming surgical: swap one semantic token and the whole system updates.

🎨 Background
--bg-baseslate-50#FAFAFAApp base — every screen
--bg-elevatedwhite#FFFFFFCards, nav bar, modals
--bg-cardslate-100#F5F5F5Feed cards, list rows
--bg-sunkenderived#E6E6E6Input fields, recessed zones
✏️ Text
--text-primaryslate-950#111111Headings, body copy
--text-secondaryslate-600#535353Supporting text, labels
--text-tertiaryslate-400#A3A3A3Timestamps, placeholders
--text-inversewhite#FFFFFFText on dark backgrounds
⬜ Border
--border-faintslate-950/6%rgba(17,17,17,.06)Section dividers, hairlines
--border-subtleslate-950/10%rgba(17,17,17,.10)Cards, inputs at rest
--border-defaultslate-950/16%rgba(17,17,17,.16)Default interactive borders
--border-strongslate-950/28%rgba(17,17,17,.28)Focus rings, strong dividers
⚡ Action — Primary
--action-primaryultra-600#3B41ECCTA buttons, links, highlights
--action-primary-hoverultra-700#3133D1Hover state
--action-primary-pressultra-800#2B2FA8Pressed/active state
--action-primary-subtleultra-50#EDF4FFTinted bg for active tabs
--action-accentultra-600#3B41ECText & icon ultramarine — 6.66:1 AA
✅ Status
--status-successgreen#1B89DCConfirmations, joined states
--status-warningderived#CC9202Alerts, pending states
--status-errorderived#FF305AErrors, destructive actions
--status-infoderived#1B89DCInformational banners
🌑 Shadows
--shadow-smInputs, inline chips
--shadow-mdCards, dropdowns
--shadow-lgFABs, sticky headers
--shadow-xlModals, bottom sheets
--shadow-glowPrimary CTA focus/hover

Component Tokens

The innermost tier. Each component owns a set of tokens that reference semantic tokens. Overriding a component token in a specific context never pollutes the rest of the system.

Button
--btn-bgaction-primary
--btn-bg-hoveraction-primary-hover
--btn-bg-pressaction-primary-press
--btn-texttext-inverse
--btn-radiusradius-md
--btn-height44px
--btn-shadowshadow-glow
Input
--input-bgbg-sunken
--input-borderborder-default
--input-border-focusaction-primary
--input-border-errorstatus-error
--input-texttext-primary
--input-placeholdertext-tertiary
--input-radiusradius-md
--input-height48px
Card
--card-bgbg-card
--card-borderborder-subtle
--card-radiusradius-lg
--card-paddingspace-4
--card-shadowshadow-sm
--card-shadow-hovershadow-md
Avatar
--avatar-size-xs24px
--avatar-size-sm32px
--avatar-size-md44px
--avatar-size-lg56px
--avatar-size-xl72px
--avatar-radiusradius-full
--avatar-borderbg-elevated 2px
Badge
--badge-bgaction-primary
--badge-texttext-inverse
--badge-radiusradius-pill
--badge-size18px
--badge-fonttext-xs / bold
Bottom Nav
--nav-bgbg-elevated
--nav-borderborder-subtle
--nav-icon-activeaction-primary
--nav-icon-defaulttext-tertiary
--nav-height56px
--nav-label-activeaction-primary
Toast / Snackbar
--toast-bgbg-card
--toast-borderborder-subtle
--toast-shadowshadow-lg
--toast-radiusradius-xl
--toast-zz-toast (400)
Toggle / Switch
--toggle-bg-offborder-default
--toggle-bg-onaction-primary
--toggle-thumbwhite
--toggle-durationduration-fast
--toggle-easeease-in-out

Buttons

Every button maps to a clear intent hierarchy. Primary drives conversion. Secondary offers alternatives. Ghost keeps things quiet. Destructive signals consequence. All hit 44px touch targets.

Variants
Primary
bg: --action-primary · text: white · radius: 12px
Secondary
bg: --bg-elevated · border: --border-default · text: --text-primary
Ghost
bg: transparent · text: --action-primary · no border
Tinted
bg: --action-primary-subtle · text: --action-primary
Destructive
bg: --status-error · text: white
Pill
radius: --radius-pill · compact horizontal padding
Sizes
xs · 32px · text-xs
sm · 36px · text-sm
md · 44px · text-sm
lg · 52px · text-base
xl · 60px · text-md
States — Primary
Default
Hover
Pressed
Loading
Disabled
Success
States — Secondary
Default
Hover
Pressed
Disabled
Icon Buttons
Primary
Secondary
Ghost
Destructive
Disabled
Full Width — Common on mobile screens

Inputs

Inputs are the primary way users contribute. They should feel open and welcoming — soft background, generous padding, expressive focus state.

Text Input — All States
At rest — border-subtle, bg-sunken
border: --action-primary · glow ring 3px
User has typed · bg-sunken · border-default
Community name must be at least 3 characters
✓ Name is available
Not editable — reduced opacity, no hover
With Adornments
This will be visible to anyone who finds your community
0/60
Textarea
Auto-grows with content · min 3 rows
Search Bar — App-level

Selections

Toggles, checkboxes, radios, and chips. These controls let users make choices — they should be immediately legible and satisfy to interact with.

Toggle / Switch
Notifications tap to toggle
Show in search
Subscription feature
Checkbox
Email updates tap to check
Push notifications
Select all indeterminate
Locked option
Radio
Public community
Private — invite only
Unlisted — link only
Secret Pro only
Filter Chips
All
Photography
Outdoors
Film
Books
Music
Members only

Avatars

Avatars represent people and communities. User avatars show photos or initials. Community avatars use the gradient palette to give each community a distinct, warm identity.

User Avatars — Sizes
AV
xl · 72px
MG
lg · 56px
JK
md · 44px
RP
sm · 32px
TL
xs · 24px
States & Decorators
Online indicator
AV
Offline
SB
Notification badge
JK
3
Verified
NW
Add button
Placeholder
Avatar Stack — Member Previews
AV
JK
RP
MG
+24
28 members
TL
CD
SB
3 mutual friends
Community Avatars — Community Identities

Each community picks from the gradient palette. The letter mark uses Figtree Bold.

P
Photography 3.2k
H
Hiking 1.8k
F
Film 4.1k
B
Books 2.6k
M
Music 5.4k
C
Cooking 890
D
Design 2.1k
S
Surfing 740

Badges & Tags

Badges communicate counts and status. Tags label content. Both are compact, high-signal, and should never compete with primary content for attention.

Notification Badges
3
Count
Dot
99+
Max (99+)
AV
New
New
Status Badges
✓ Joined ⏳ Pending ✕ Declined ℹ New Draft
Tags — Content Labels
Filled
Photography Outdoors Cooking General
Outlined
Photography Outdoors Cooking
With icon
Live now 482 members 🔒 Private
Dismissible
Photography Outdoors Film

Cards

Cards are the primary unit of information in social.plus. They surface communities, posts, members, and events. Soft slate background, generous radius, subtle lift on interaction.

Community Card
Default
P
Photography
3,240 members · 12 posts today
A space for photographers at every level to share, learn, and find their next shot.
Joined state
H
Hiking & Outdoors ✓ Joined
1,820 members · 4 posts today
Early mornings, mountain air, and the people who get it.
Compact / list view
F
Film Lovers
4,100 members
B
Book Club
2,650 members · Joined
M
Music Production
5,430 members
Post / Feed Card
Default post
AV

Caught this light at 6am. Alarm at 5 was worth it. What's your favourite time to shoot?

Photo attachment
Card states
Hover
Hover lifts card with shadow-md
Selected
Border becomes action-primary
Disabled
40% opacity, no interactions

List Items

The repeating unit of every feed, settings screen, and member list. Consistent height, generous touch target, clear visual hierarchy across leading / content / trailing zones.

Anatomy & Variants
Basic row
Account settings
With subtitle
Push notifications Manage alerts for communities and messages
Leading icon
Profile Edit your public info
With avatar — Member row
AV
Amadeus Vidal @amadeus · 14 communities
With community avatar
F
Film Lovers 4,100 members · 8 posts today
2
With toggle
Notifications New posts and mentions
Destructive action
Leave community
Disabled
Private messaging Upgrade to unlock
Pro
Grouped Section List — Settings pattern
Account
Profile
Devices
Privacy & Security
Preferences
Notifications
Appearance

Overlays

Modals, bottom sheets, and tooltips layer above the current screen. They use the z-index scale and always sit behind a darkened overlay backdrop.

Bottom Sheet
Join this community?
Photography is a community of 3,240 members sharing daily shots, tips, and creative challenges.
Dialog / Modal
Context Menu
Save post
Share post
Copy link
Report post
Tooltip
Appears when you hover
Left-anchored tooltip

Feedback

Toasts, banners, progress indicators, and skeleton loaders. The system's way of communicating status without disrupting the user's flow.

Toasts / Snackbars
Joined Photography!
You're now part of 3,240 members.
Couldn't send message
Check your connection and try again.
3 new posts in Hiking
Community is nearly full
Only 12 spots remaining.
Progress Indicators
Profile completion72%
Community capacity91%
Photo uploadDone
Uploading… 43%
Skeleton Loaders

States

Every interactive element exists in multiple states. This matrix shows how each component responds to user actions, system conditions, and data states — so nothing is left undesigned.

Component × State Matrix
Component
Default
Hover
Pressed
Focused
Disabled
Loading
Error
Success
Button Primary
Input Text field
Toggle Switch
Checkbox Selection
Card Feed / community
Post content
Post content
Post content
Post content
Post content
Failed to load
✓ Joined!
List item Row
Settings
Settings
Settings
Settings
Settings
Loading
Error
✓ Saved
Screen-Level States
Loading
Skeleton screens and spinners while content fetches. Never block the whole screen — load progressively.
Error
Something went wrong. Always show a clear message, a reason if possible, and a recovery action.
Offline
No network connection. Show cached content where possible. Disable actions that require connectivity.
Success
Action completed. Show confirmation, then transition automatically or let the user continue.
Partial load
Some content loaded, some failed. Show what you have, indicate what's missing with inline error states.
Permission gate
Feature requires a permission (notifications, camera). Explain why before requesting. Never surprise the OS dialog.

Empty States

The moment before content exists. Empty states should feel warm and inviting — not clinical. Each one has a clear illustration area, a human headline, a supporting line, and one action.

Find your communities
You haven't joined any communities yet. Discover communities built around things you actually care about.
Home feed — first visit
No messages yet
Start a conversation with someone in one of your communities. Real connections start with a real message.
Messages — empty inbox
No results for "Bonsai"
We couldn't find any communities matching that. Try different keywords or start your own community.
Search — no results
All caught up
No new activity in your communities. When someone replies to your posts or mentions you, it'll show up here.
Activity — all read
No members yet
Be the first to invite people to this community. Share the link or search for people you know.
Community — no members
Couldn't load this
Something went wrong loading this content. Check your connection and try again.
Generic error state
Inline Empty — Within a list or card
No posts yet
Be the first to share something with this community.