## Remove All 'Calm' References & Reframe Platform Identity ### Documentation Updates - **Deleted**: CALM_UX_GUIDE.md (outdated philosophy document) - **Updated**: All documentation to remove 'calm' terminology - **Reframed**: Platform as 'friends-first' instead of 'calm' ### Design System Changes - Replace 'calm & elegant' with 'warm & welcoming' - Update theme descriptions to focus on friendliness - Change 'calm velocity' to 'authentic engagement' - Update UI microcopy for friendly tone ### Content Updates - Philosophy documents reframe for social connection focus - Design guides emphasize warmth over calmness - API documentation updated for new terminology - User-facing text changed to friendly language ### Key Terminology Changes - 'Calm design' 'Warm, welcoming design' - 'Calm velocity' 'Authentic engagement' - 'Calm UI' 'Friendly UI' - 'Structural calm' 'Structural friendliness' - 'Calm platform' 'Friends-first platform' ### Platform Focus Shift - From: Text-based calm platform - To: Friends-first social network prioritizing genuine connections - Emphasis on social connection over mindfulness - Focus on warmth and friendliness in design ### Files Modified - 15+ documentation files updated - Flutter app UI text updated - Design system rebranded - Philosophy documents reframed - API documentation updated The platform is now positioned as a warm, welcoming social network that prioritizes genuine human connections over calm minimalism.
482 lines
12 KiB
Markdown
482 lines
12 KiB
Markdown
# Sojorn Visual Design System
|
|
|
|
## Design Philosophy
|
|
|
|
Sojorn's visual system creates a **warm, welcoming, friends-first** experience through intentional design choices that prioritize human connection.
|
|
|
|
### Core Principles
|
|
|
|
1. **Warm, Not Overwhelming**
|
|
- Warm neutrals (beige/paper tones) instead of cold grays
|
|
- Soft shadows, never harsh
|
|
- Muted semantic colors that inform without alarming
|
|
|
|
2. **Modern, Not Trendy**
|
|
- Timeless color palette
|
|
- Classic typography hierarchy
|
|
- Subtle animations and transitions
|
|
|
|
3. **Connection-Focused**
|
|
- Generous line height (1.6-1.65 for body text)
|
|
- Optimized for reading and engagement
|
|
- Clear hierarchy without relying on color
|
|
|
|
4. **Intentionally Smooth**
|
|
- Animation durations: 300-400ms
|
|
- Ease curves that feel natural
|
|
- No jarring transitions
|
|
|
|
---
|
|
|
|
## Color Palette
|
|
|
|
### Background System
|
|
```dart
|
|
background = #F8F7F4 // Warm off-white (like paper)
|
|
surface = #FFFFFD // Barely warm white
|
|
surfaceElevated = #FFFFFF // Pure white for cards
|
|
surfaceVariant = #F0EFEB // Subtle warm gray (inputs)
|
|
```
|
|
|
|
**Usage:**
|
|
- `background`: Main app background
|
|
- `surface`: App bars, bottom navigation
|
|
- `surfaceElevated`: Cards, dialogs, elevated content
|
|
- `surfaceVariant`: Input fields, disabled states
|
|
|
|
### Border System
|
|
```dart
|
|
borderSubtle = #E8E6E1 // Barely visible dividers
|
|
border = #D8D6D1 // Default borders
|
|
borderStrong = #C8C6C1 // Emphasized borders
|
|
```
|
|
|
|
**Visual Hierarchy:**
|
|
- Use `borderSubtle` for dividers between list items
|
|
- Use `border` for cards, inputs, default separators
|
|
- Use `borderStrong` for focused/active states (rare)
|
|
|
|
### Text Hierarchy
|
|
```dart
|
|
textPrimary = #1C1B1A // Near-black with warmth
|
|
textSecondary = #6B6A68 // Medium warm gray
|
|
textTertiary = #9C9B99 // Light warm gray
|
|
textDisabled = #BDBBB8 // Very light gray
|
|
textOnAccent = #FFFFFD // For buttons/accents
|
|
```
|
|
|
|
**Usage:**
|
|
- `textPrimary`: Headlines, body text, primary content
|
|
- `textSecondary`: Metadata, labels, secondary info
|
|
- `textTertiary`: Placeholders, timestamps, tertiary info
|
|
- `textDisabled`: Disabled button text, inactive states
|
|
- `textOnAccent`: White text on colored backgrounds
|
|
|
|
### Accent Colors
|
|
```dart
|
|
accent = #5D6B7A // Muted slate (primary)
|
|
accentLight = #8A95A1 // Lighter slate
|
|
accentDark = #3F4A56 // Darker slate
|
|
accentSubtle = #E8EAED // Barely visible accent
|
|
```
|
|
|
|
**Usage:**
|
|
- `accent`: Primary buttons, links, active states
|
|
- `accentLight`: Hover states, dark mode primary
|
|
- `accentDark`: Pressed states (rare)
|
|
- `accentSubtle`: Background for subtle accent areas
|
|
|
|
### Interaction Colors
|
|
```dart
|
|
appreciate = #7A8B6F // Muted sage green (likes)
|
|
save = #6F7F92 // Muted blue-gray (saves)
|
|
share = #8B7A6F // Muted warm gray (shares)
|
|
```
|
|
|
|
### Semantic Colors
|
|
```dart
|
|
success = #7A8B6F // Soft sage (not bright green)
|
|
warning = #B89F7D // Soft amber (not orange alarm)
|
|
error = #B07F7F // Soft terracotta (not red alarm)
|
|
info = #7A8B9F // Soft blue
|
|
```
|
|
|
|
**Why Muted?**
|
|
Bright red errors create anxiety. Soft terracotta communicates the same information with less stress.
|
|
|
|
### Trust Tier Colors
|
|
```dart
|
|
tierNew = #9C9B99 // Light gray
|
|
tierTrusted = #7A8B6F // Sage green
|
|
tierEstablished = #5D6B7A // Slate blue
|
|
```
|
|
|
|
---
|
|
|
|
## Typography
|
|
|
|
### Font Stack
|
|
```dart
|
|
Primary: 'SF Pro Text' → system-ui → sans-serif
|
|
Monospace: 'SF Mono' → 'Courier New' → monospace
|
|
```
|
|
|
|
**Why System Fonts?**
|
|
- Free, pre-installed, optimized for each platform
|
|
- SF Pro Text is warm and highly readable
|
|
- No network requests, instant loading
|
|
|
|
### Type Scale
|
|
|
|
#### Display (Rare - Only for Large Headings)
|
|
```dart
|
|
displayLarge: 32px / 600 / 1.2 line-height / -0.8 tracking
|
|
displayMedium: 28px / 600 / 1.25 line-height / -0.6 tracking
|
|
```
|
|
|
|
#### Headlines (Section Titles, Screen Titles)
|
|
```dart
|
|
headlineLarge: 24px / 600 / 1.3 line-height / -0.4 tracking
|
|
headlineMedium: 20px / 600 / 1.3 line-height / -0.3 tracking
|
|
headlineSmall: 17px / 600 / 1.35 line-height / -0.2 tracking
|
|
```
|
|
|
|
#### Body (Reading-Optimized)
|
|
```dart
|
|
bodyLarge: 17px / 400 / 1.65 line-height ← GENEROUS for readability
|
|
bodyMedium: 15px / 400 / 1.6 line-height
|
|
bodySmall: 13px / 400 / 1.5 line-height
|
|
```
|
|
|
|
**Why 1.65 line-height?**
|
|
Research shows 1.5-1.6 is optimal for readability. We use 1.65 to reinforce comfortable spacing.
|
|
|
|
#### Labels (UI Elements, Buttons, Metadata)
|
|
```dart
|
|
labelLarge: 15px / 500 / 1.4 line-height / 0.1 tracking
|
|
labelMedium: 13px / 500 / 1.35 line-height / 0.1 tracking
|
|
labelSmall: 11px / 500 / 1.3 line-height / 0.3 tracking
|
|
```
|
|
|
|
### Typography Guidelines
|
|
|
|
**DO:**
|
|
- Use `bodyLarge` for post content
|
|
- Use `headlineMedium` for screen titles
|
|
- Use `labelMedium` for metadata (timestamps, handles)
|
|
- Use `mono` for technical data (@handles, IDs)
|
|
|
|
**DON'T:**
|
|
- Mix font weights excessively (400 for body, 500 for labels, 600 for headings)
|
|
- Use font sizes outside the scale
|
|
- Override line-height without good reason
|
|
|
|
---
|
|
|
|
## Spacing System
|
|
|
|
Based on **4px grid**:
|
|
|
|
```dart
|
|
spacing2xs = 2px // Rare, internal component spacing
|
|
spacingXs = 4px // Tight spacing
|
|
spacingSm = 8px // Small gaps
|
|
spacingMd = 16px // Default spacing
|
|
spacingLg = 24px // Large gaps (card padding)
|
|
spacingXl = 32px // Extra large (section gaps)
|
|
spacing2xl = 48px // Huge gaps
|
|
spacing3xl = 64px // Screen-level spacing
|
|
spacing4xl = 96px // Rare, dramatic spacing
|
|
```
|
|
|
|
### Semantic Spacing
|
|
```dart
|
|
spacingCardPadding = 24px // Internal card padding
|
|
spacingScreenPadding = 16px // Screen edge padding
|
|
spacingSectionGap = 32px // Between major sections
|
|
```
|
|
|
|
### Spacing Guidelines
|
|
|
|
**DO:**
|
|
- Use `spacingLg` (24px) for card padding
|
|
- Use `spacingMd` (16px) for screen padding
|
|
- Use `spacingXl` (32px) between sections
|
|
|
|
**DON'T:**
|
|
- Use arbitrary spacing values (stick to the scale)
|
|
- Create cramped UIs (when in doubt, use more space)
|
|
|
|
---
|
|
|
|
## Border Radius
|
|
|
|
```dart
|
|
radiusXs = 4px // Chips, badges
|
|
radiusSm = 8px // Small buttons
|
|
radiusMd = 12px // Inputs, buttons
|
|
radiusLg = 16px // Cards, dialogs
|
|
radiusXl = 24px // Large containers
|
|
radiusFull = 9999px // Pills, circular elements
|
|
```
|
|
|
|
**Consistency:**
|
|
- Cards: `radiusLg` (16px)
|
|
- Buttons: `radiusMd` (12px)
|
|
- Inputs: `radiusMd` (12px)
|
|
- Trust badges: `radiusXs` (4px)
|
|
|
|
---
|
|
|
|
## Elevation & Shadows
|
|
|
|
All shadows use **warm black** (`#1C1B1A`) at very low opacity:
|
|
|
|
```dart
|
|
shadowSm: 4% opacity, 4px blur, 1px offset
|
|
shadowMd: 6% opacity, 8px blur, 2px offset
|
|
shadowLg: 8% opacity, 16px blur, 4px offset
|
|
```
|
|
|
|
**Usage:**
|
|
- `shadowSm`: Default for cards
|
|
- `shadowMd`: Elevated cards, modals
|
|
- `shadowLg`: Floating action button, dialogs
|
|
|
|
**Why So Subtle?**
|
|
Heavy shadows create visual noise. Soft shadows suggest elevation without aggression.
|
|
|
|
---
|
|
|
|
## Animation
|
|
|
|
### Durations
|
|
```dart
|
|
durationFast: 200ms // Hovers, subtle transitions
|
|
durationMedium: 300ms // Default
|
|
durationSlow: 400ms // Modal entrance, page transitions
|
|
```
|
|
|
|
### Curves
|
|
```dart
|
|
curveDefault: easeInOutCubic // Most animations
|
|
curveEnter: easeOut // Elements appearing
|
|
curveExit: easeIn // Elements leaving
|
|
```
|
|
|
|
**Why Slow?**
|
|
Fast animations feel rushed. 300-400ms feels intentional and smooth.
|
|
|
|
---
|
|
|
|
## Custom Widgets
|
|
|
|
### SojornButton
|
|
Replaces `ElevatedButton`, `OutlinedButton`, `TextButton`
|
|
|
|
**Variants:**
|
|
- `primary`: Filled accent button
|
|
- `secondary`: Outlined button
|
|
- `tertiary`: Text-only button
|
|
- `destructive`: Filled error button
|
|
|
|
**Sizes:**
|
|
- `small`: 40px height
|
|
- `medium`: 48px height
|
|
- `large`: 56px height
|
|
|
|
**Example:**
|
|
```dart
|
|
SojornButton(
|
|
label: 'Sign In',
|
|
onPressed: _handleSignIn,
|
|
variant: SojornButtonVariant.primary,
|
|
size: SojornButtonSize.large,
|
|
isFullWidth: true,
|
|
isLoading: _isLoading,
|
|
)
|
|
```
|
|
|
|
### SojornInput
|
|
Replaces `TextField` with consistent styling
|
|
|
|
**Example:**
|
|
```dart
|
|
SojornInput(
|
|
label: 'Email',
|
|
hint: 'your@email.com',
|
|
controller: _emailController,
|
|
prefixIcon: Icons.email_outlined,
|
|
keyboardType: TextInputType.emailAddress,
|
|
)
|
|
```
|
|
|
|
### SojornTextArea
|
|
For long-form content (posts, comments)
|
|
|
|
**Example:**
|
|
```dart
|
|
SojornTextArea(
|
|
label: 'Write your post',
|
|
hint: 'Share something thoughtful...',
|
|
controller: _postController,
|
|
maxLength: 500,
|
|
showCharacterCount: true,
|
|
)
|
|
```
|
|
|
|
### SojornCard
|
|
Replaces `Card` with consistent elevation and borders
|
|
|
|
**Example:**
|
|
```dart
|
|
SojornCard(
|
|
onTap: () => navigateToPost(),
|
|
child: Column(
|
|
children: [
|
|
Text('Card title'),
|
|
Text('Card content'),
|
|
],
|
|
),
|
|
)
|
|
```
|
|
|
|
### SojornDialog
|
|
Replaces `showDialog` with friendly styling
|
|
|
|
**Static Methods:**
|
|
```dart
|
|
// Confirmation
|
|
SojornDialog.showConfirmation(
|
|
context: context,
|
|
title: 'Delete post?',
|
|
message: 'This cannot be undone.',
|
|
isDestructive: true,
|
|
)
|
|
|
|
// Info
|
|
SojornDialog.showInfo(
|
|
context: context,
|
|
title: 'Account created',
|
|
message: 'Welcome to Sojorn!',
|
|
)
|
|
|
|
// Error
|
|
SojornDialog.showError(
|
|
context: context,
|
|
title: 'Connection failed',
|
|
message: 'Please check your internet.',
|
|
)
|
|
```
|
|
|
|
### SojornSnackbar
|
|
Replaces `ScaffoldMessenger.showSnackBar`
|
|
|
|
**Static Methods:**
|
|
```dart
|
|
SojornSnackbar.show(context: context, message: 'Post saved')
|
|
SojornSnackbar.showSuccess(context: context, message: 'Post published')
|
|
SojornSnackbar.showError(context: context, message: 'Failed to load')
|
|
SojornSnackbar.showWarning(context: context, message: 'Slow connection')
|
|
```
|
|
|
|
---
|
|
|
|
## Visual Friendliness Enforcement
|
|
|
|
### How the System Enforces Friendliness
|
|
|
|
1. **No Hardcoded Colors**
|
|
- All colors come from `AppTheme`
|
|
- Impossible to use bright red/blue by accident
|
|
|
|
2. **No Arbitrary Spacing**
|
|
- All spacing uses the 4px grid constants
|
|
- Creates visual rhythm
|
|
|
|
3. **Generous Defaults**
|
|
- Card padding: 24px (not 16px)
|
|
- Line height: 1.65 (not 1.4)
|
|
- Animation: 300ms (not 150ms)
|
|
|
|
4. **Soft Shadows**
|
|
- Maximum 8% opacity
|
|
- Warm black, never pure black
|
|
|
|
5. **Warm Tint**
|
|
- All grays have warm undertones
|
|
- Avoids clinical/sterile feel
|
|
|
|
6. **Limited Font Weights**
|
|
- 400 (regular), 500 (medium), 600 (semibold)
|
|
- No bold (700) or black (900)
|
|
|
|
---
|
|
|
|
## Before/After Comparison
|
|
|
|
### Before (Material Default)
|
|
- Cold grays (#FAFAFA, #F5F5F5)
|
|
- Bright blue accent (#2196F3)
|
|
- Harsh shadows (24% opacity)
|
|
- Tight spacing (8px padding)
|
|
- Fast animations (100-150ms)
|
|
- Narrow line-height (1.4)
|
|
|
|
### After (Sojorn System)
|
|
- Warm neutrals (#F8F7F4, #F0EFEB)
|
|
- Muted slate accent (#5D6B7A)
|
|
- Soft shadows (4-8% opacity)
|
|
- Generous spacing (24px padding)
|
|
- Slow animations (300-400ms)
|
|
- Reading line-height (1.65)
|
|
|
|
**Result:** Feels like reading a book, not using an app.
|
|
|
|
---
|
|
|
|
## Testing Checklist
|
|
|
|
- [ ] All screens use `AppTheme` constants (no hardcoded colors)
|
|
- [ ] All spacing uses the 4px grid
|
|
- [ ] All buttons use `SojornButton` variants
|
|
- [ ] All inputs use `SojornInput` or `SojornTextArea`
|
|
- [ ] All cards use `SojornCard`
|
|
- [ ] All dialogs use `SojornDialog`
|
|
- [ ] All snackbars use `SojornSnackbar`
|
|
- [ ] Text hierarchy follows the type scale
|
|
- [ ] Shadows use the predefined shadow helpers
|
|
- [ ] Border radius uses the radius constants
|
|
|
|
---
|
|
|
|
## Dark Mode (Optional)
|
|
|
|
Dark theme uses the same warm philosophy:
|
|
|
|
```dart
|
|
darkBackground = #1C1B1A // Warm near-black
|
|
darkSurface = #252422 // Warm dark gray
|
|
darkSurfaceElevated = #2E2C2A // Lighter warm gray
|
|
darkTextPrimary = #ECEBE8 // Warm off-white
|
|
```
|
|
|
|
**Key Difference:**
|
|
- No pure black (#000000)
|
|
- No pure white (#FFFFFF)
|
|
- Reduced contrast for less eye strain
|
|
|
|
---
|
|
|
|
## Resources
|
|
|
|
- [Type Scale Calculator](https://type-scale.com/)
|
|
- [Color Palette Generator](https://coolors.co/)
|
|
- [Material Design 3 Guidelines](https://m3.material.io/)
|
|
- [iOS Human Interface Guidelines](https://developer.apple.com/design/human-interface-guidelines/)
|
|
|
|
---
|
|
|
|
**Last Updated:** 2026-01-06
|
|
**Maintained By:** Sojorn Design Team
|