Reframe Sojorn as Friends-First Social Network

## 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.
This commit is contained in:
Patrick Britton 2026-01-30 09:49:36 -06:00
parent 38653f5854
commit b9351b76ae
19 changed files with 75 additions and 1035 deletions

View file

@ -4,10 +4,10 @@
The Sojorn app now supports two themes that users can switch between:
### 1. **Basic Theme** (Original)
- Calm and elegant design
- Warm and welcoming design
- Lighter feel with subtle pink tints
- Slightly larger font sizes
- Perfect for reading and reflection
- Perfect for reading and connection
### 2. **Pop Theme** (New - "Awakening")
- High contrast and energetic
@ -67,7 +67,7 @@ The selected theme is automatically saved and persists across app sessions.
- Background: Very pale lavender/pink (#F9F2F7)
- Text: 19px body, softer navy
- Spacing: More generous
- Feel: Calm, elegant, reflective
- Feel: Warm, welcoming, social
### Pop Theme:
- Background: Clean pale lavender (#F9F6F9)

View file

@ -425,7 +425,7 @@ class _ProfileSettingsScreenState extends ConsumerState<ProfileSettingsScreen> {
Expanded(
child: _ThemeOption(
title: 'Basic',
description: 'Calm & elegant',
description: 'Warm & welcoming',
isSelected: currentTheme == app_theme.ThemeMode.basic,
onTap: () => ref
.read(app_theme.themeProvider.notifier)

View file

@ -8,7 +8,7 @@ import 'markdown_post_body.dart';
/// Widget for displaying a sponsored post (First-Party Contextual Ad)
///
/// Design: Distinguishable from regular posts but not distracting.
/// - "Sponsored by [advertiserName]" header (small, uppercase, calm)
/// - "Sponsored by [advertiserName]" header (small, uppercase, subtle)
/// - Subtle background tint (surfaceVariant) to legally distinguish from editorial
/// - Markdown body content
/// - Distinct CTA button (OutlinedButton with "Visit Site" icon)

View file

@ -5,7 +5,7 @@ import '../theme/app_theme.dart';
/// Safety Redirect Sheet
///
/// A calm, clean modal bottom sheet that reminds users to be careful
/// A clean, friendly modal bottom sheet that reminds users to be careful
/// when visiting external links.
class SafetyRedirectSheet extends StatelessWidget {
final String url;

View file

@ -10,7 +10,7 @@ This guide consolidates all development, architecture, and design system documen
### Core Principles
Sojorn's calm is not aspirational—it is **structural**. The architecture enforces behavioral philosophy through database constraints, API design, and systematic patterns that make certain behaviors impossible, not just discouraged.
Sojorn's friendliness is not aspirational—it is **structural**. The architecture enforces behavioral philosophy through database constraints, API design, and systematic patterns that make certain behaviors impossible, not just discouraged.
### 1. Blocking: Complete Disappearance
@ -198,7 +198,7 @@ $$ LANGUAGE SQL;
### Visual Philosophy
**Calm, Not Sterile**
**Warm, Not Overwhelming**
- Warm neutrals (beige/paper tones) instead of cold grays
- Soft shadows, never harsh
- Muted semantic colors that inform without alarming
@ -230,7 +230,7 @@ surfaceVariant = #F0EFEB // Subtle warm gray (inputs)
#### Semantic Colors
```dart
primary = #6B5B95 // Soft purple (calm authority)
primary = #6B5B95 // Soft purple (friendly authority)
secondary = #8B7355 // Warm brown (earth tone)
success = #6B8E6F // Muted green (gentle confirmation)
warning = #B8956A // Soft amber (warm caution)

View file

@ -54,7 +54,7 @@ Comprehensive deployment and operations guide, covering infrastructure setup, de
#### **Platform Philosophy** (`philosophy/`)
- `CORE_VALUES.md` - Core platform values
- `CALM_UX_GUIDE.md` - Calm UX design principles
- `UX_GUIDE.md` - UX design principles
- `FOURTEEN_PRECEPTS.md` - Platform precepts
- `HOW_SHARP_SPEECH_STOPS.md` - Communication guidelines
- `SEEDING_PHILOSOPHY.md` - Content seeding philosophy

View file

@ -2,7 +2,7 @@
## How Boundaries Are Enforced
Sojorn's calm is not aspirational—it is structural. The database itself enforces the behavioral philosophy through **Row Level Security (RLS)**, constraints, and functions that make certain behaviors impossible, not just discouraged.
Sojorn's friendliness is not aspirational—it is structural. The database itself enforces the behavioral philosophy through **Row Level Security (RLS)**, constraints, and functions that make certain behaviors impossible, not just discouraged.
---
@ -148,7 +148,7 @@ Sojorn's calm is not aspirational—it is structural. The database itself enforc
## What This Enables
1. **Calm is enforced, not suggested.** The database will not allow hostile interactions.
1. **Friendliness is enforced, not suggested.** The database will not allow hostile interactions.
2. **Boundaries are private.** Blocking and filtering leave no trace visible to the blocked party.
3. **Consent is required.** You cannot force your words into someone's space.
4. **Exposure is controlled.** Users see only what they choose to see.

View file

@ -23,7 +23,7 @@ All Edge Functions for Sojorn backend are ready to deploy.
### Feeds
10. **feed-personal** - Chronological feed from follows
11. **feed-sojorn** - Algorithmic FYP with calm velocity
11. **feed-sojorn** - Algorithmic FYP with authentic engagement
12. **trending** - Category-scoped trending
### System
@ -201,7 +201,7 @@ curl -X POST "https://zwkihedetedlatyvplyz.supabase.co/functions/v1/publish-post
-H "Content-Type: application/json" \
-d '{
"category_id": "'$CATEGORY_ID'",
"body": "This is my first calm post on Sojorn."
"body": "This is my first friendly post on Sojorn."
}'
```
@ -227,9 +227,9 @@ curl "https://zwkihedetedlatyvplyz.supabase.co/functions/v1/feed-personal" \
---
## Calm Microcopy
## Friendly Microcopy
All functions include calm, intentional messaging:
All functions include friendly, intentional messaging:
- **Signup:** "Welcome to Sojorn. Your journey begins quietly."
- **Follow:** "Followed. Mutual follow enables conversation."
@ -240,4 +240,4 @@ All functions include calm, intentional messaging:
---
**Your Sojorn backend is ready to support calm, structural moderation from day one.**
**Your Sojorn backend is ready to support friendly, structural moderation from day one.**

View file

@ -217,7 +217,7 @@ curl -X POST https://YOUR_PROJECT_REF.supabase.co/functions/v1/publish-post \
-H "Content-Type: application/json" \
-d '{
"category_id": "CATEGORY_UUID",
"body": "This is a calm test post."
"body": "This is a friendly test post."
}'
# Test getting personal feed
@ -408,4 +408,4 @@ After deployment:
---
**Sojorn backend is ready to support calm, structural moderation from day one.**
**Sojorn backend is ready to support thoughtful, structural moderation from day one.**

View file

@ -32,7 +32,7 @@ curl -X POST "https://zwkihedetedlatyvplyz.supabase.co/functions/v1/signup" \
-d '{
"handle": "sojorn_poet",
"display_name": "Sojorn Poet",
"bio": "Sharing calm words for a busy world"
"bio": "Sharing thoughtful words for a connected world"
}'
```
@ -42,7 +42,7 @@ Go to https://app.supabase.com/project/zwkihedetedlatyvplyz/sql/new
Paste the contents of `supabase/seed/seed_test_posts.sql` and run it.
This will inject 20 beautiful, calm posts with poetry and wisdom.
This will inject 20 beautiful, thoughtful posts with poetry and wisdom.
---
@ -84,7 +84,7 @@ flutter run -d ios
### 4.2 View Feeds
- **Following** tab: Will be empty until you follow someone
- **Sojorn** tab: Shows all posts ranked by calm velocity
- **Sojorn** tab: Shows all posts ranked by authentic engagement
- **Profile** tab: Shows your profile, trust tier, and posting limits
### 4.3 Create a Post
@ -203,7 +203,7 @@ curl -X POST "https://zwkihedetedlatyvplyz.supabase.co/functions/v1/publish-post
-H "Content-Type: application/json" \
-d '{
"category_id": "CATEGORY_UUID",
"body": "A calm, thoughtful post."
"body": "A thoughtful, engaging post."
}'
```
@ -257,7 +257,7 @@ Before going live:
- [ ] Enable email confirmation
- [ ] Set up custom domain
- [ ] Configure email templates with calm copy
- [ ] Configure email templates with friendly copy
- [ ] Set up SMTP for transactional emails
- [ ] Enable RLS on all tables (already done)
- [ ] Set up monitoring and alerts
@ -270,4 +270,4 @@ Before going live:
---
**You're all set! Enjoy building Sojorn - a calm corner of the internet.**
**You're all set! Enjoy building Sojorn - a friendly corner of the internet.**

View file

@ -206,7 +206,7 @@ curl -X POST "https://YOUR_PROJECT_REF.supabase.co/functions/v1/publish-post" \
-H "Content-Type: application/json" \
-d '{
"category_id": "CATEGORY_UUID",
"body": "This is my first calm post on Sojorn."
"body": "This is my first friendly post on Sojorn."
}'
# Test getting personal feed

View file

@ -1,16 +1,16 @@
# Sojorn Flutter Client
A calm, text-only social platform built with Flutter.
A friends-first social platform built with Flutter that prioritizes genuine human connections.
## Status
✅ **Core functionality implemented:**
- Authentication (sign up, sign in, profile creation)
- Personal feed (chronological from follows)
- Sojorn feed (algorithmic FYP with calm velocity)
- Sojorn feed (algorithmic FYP with engaging content)
- Post creation with tone detection
- Profile viewing with trust tier display
- Clean, minimal UI theme
- Clean, modern UI theme
🚧 **Features to be added:**
- Engagement actions (appreciate, save, comment on posts)
@ -97,7 +97,7 @@ lib/
│ ├── api_service.dart # Edge Functions client
│ └── auth_service.dart # Supabase Auth wrapper
├── theme/
│ └── app_theme.dart # Calm, minimal theme
│ └── app_theme.dart # Warm, welcoming theme
├── widgets/
│ ├── compose_fab.dart # Floating compose button
│ └── post_card.dart # Post display widget
@ -114,7 +114,7 @@ lib/
### Feed System
- **Personal Feed**: Chronological posts from followed users
- **Sojorn Feed**: Algorithmic feed using calm velocity ranking
- **Sojorn Feed**: Algorithmic feed using authentic engagement ranking
- Pull-to-refresh on both feeds
- Infinite scroll with pagination
@ -123,7 +123,7 @@ lib/
- Category selection (currently hardcoded to "general", needs UI)
- Tone detection at publish time
- Character count display
- Calm, intentional UX
- Friendly, intentional UX
### Profile Display
- Shows display name, handle, bio
@ -133,7 +133,7 @@ lib/
- Sign out button
### Theme
- Muted, calm color palette
- Muted, warm color palette
- Generous spacing
- Soft borders and shadows
- Clean typography
@ -241,7 +241,7 @@ flutter build web --release
- Future: Consider migrating to go_router for deep linking
### Design Philosophy
- **Calm UI**: Muted colors, generous spacing, minimal animations
- **Friendly UI**: Muted colors, generous spacing, minimal animations
- **Intentional UX**: No infinite feeds, clear posting limits, thoughtful language
- **Structural boundaries**: Blocking, mutual-follow, category opt-in enforced by backend
@ -265,7 +265,7 @@ flutter build web --release
## Contributing
When adding features:
1. Match the calm, minimal design language
1. Match the warm, welcoming design language
2. Use the existing theme constants
3. Follow the established patterns for API calls
4. Add error handling and loading states

View file

@ -2,11 +2,11 @@
## Design Philosophy
Sojorn's visual system enforces **calm, modern, text-forward** design through intentional constraints and thoughtful defaults.
Sojorn's visual system creates a **warm, welcoming, friends-first** experience through intentional design choices that prioritize human connection.
### Core Principles
1. **Calm, Not Sterile**
1. **Warm, Not Overwhelming**
- Warm neutrals (beige/paper tones) instead of cold grays
- Soft shadows, never harsh
- Muted semantic colors that inform without alarming
@ -16,14 +16,14 @@ Sojorn's visual system enforces **calm, modern, text-forward** design through in
- Classic typography hierarchy
- Subtle animations and transitions
3. **Text-Forward**
3. **Connection-Focused**
- Generous line height (1.6-1.65 for body text)
- Optimized for reading, not scanning
- Optimized for reading and engagement
- Clear hierarchy without relying on color
4. **Intentionally Slow**
4. **Intentionally Smooth**
- Animation durations: 300-400ms
- Ease curves that feel deliberate
- Ease curves that feel natural
- No jarring transitions
---
@ -149,7 +149,7 @@ 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 calm spacing.
Research shows 1.5-1.6 is optimal for readability. We use 1.65 to reinforce comfortable spacing.
#### Labels (UI Elements, Buttons, Metadata)
```dart
@ -265,7 +265,7 @@ curveExit: easeIn // Elements leaving
```
**Why Slow?**
Fast animations feel rushed. 300-400ms feels intentional and calm.
Fast animations feel rushed. 300-400ms feels intentional and smooth.
---
@ -318,7 +318,7 @@ For long-form content (posts, comments)
```dart
SojornTextArea(
label: 'Write your post',
hint: 'Share something calm...',
hint: 'Share something thoughtful...',
controller: _postController,
maxLength: 500,
showCharacterCount: true,
@ -342,7 +342,7 @@ SojornCard(
```
### SojornDialog
Replaces `showDialog` with calm styling
Replaces `showDialog` with friendly styling
**Static Methods:**
```dart
@ -382,9 +382,9 @@ SojornSnackbar.showWarning(context: context, message: 'Slow connection')
---
## Visual Calm Enforcement
## Visual Friendliness Enforcement
### How the System Enforces Calm
### How the System Enforces Friendliness
1. **No Hardcoded Colors**
- All colors come from `AppTheme`

View file

@ -1,10 +1,10 @@
# sojorn
sojorn is a calm, consent-first social platform built to slow attention and reduce hostility by design. The project pairs a Flutter client with a Supabase backend and Edge Functions that enforce tone gating, mutual-consent conversations, and trust-aware ranking.
sojorn is a friends-first, consent-first social platform built to foster genuine connections and reduce hostility by design. The project pairs a Flutter client with a Go backend that enforces tone gating, mutual-consent conversations, and trust-aware ranking.
## Product Principles
- Calm is structural, not performative.
- Friendliness is structural, not performative.
- Hostility is contained; clean content remains visible.
- Exposure is opt-in, filtering is private, and blocking is absolute.
- Conversation requires mutual consent (mutual follow).

View file

@ -1,960 +0,0 @@
# Sojorn Calm UX Guide
## Design Philosophy
Sojorn enforces calm through **intentional friction, respectful boundaries, and visual restraint**. Every interaction should feel like settling in, not being rushed.
---
## Part 1: Reading & Feed Experience
### Design Intent
- Reading feels like settling into a book, not scrolling a timeline
- No visual shouting or metric obsession
- No urgency cues or FOMO mechanics
### Feed Layout Decisions
#### 1. **Comfortable Max Width (680px)**
**Why:**
- Optimal line length for reading is 50-75 characters
- Wide text blocks strain eye tracking
- Creates "settling in" feeling vs infinite scroll anxiety
**Implementation:**
```dart
Container(
constraints: const BoxConstraints(maxWidth: 680),
// ...
)
```
#### 2. **Generous Vertical Spacing (24px between posts)**
**Why:**
- Tight spacing = rushed feeling
- Space = permission to pause
- Each post gets breathing room
**Visual Effect:**
- Posts feel like chapters in a book
- No "wall of content" anxiety
#### 3. **No Aggressive Dividers**
**Why:**
- Heavy dividers create visual noise
- Soft shadows and spacing create natural separation
- Avoids the "list item" feeling
**Implementation:**
```dart
boxShadow: AppTheme.shadowSm // Only 4% opacity
```
### Post Card Design Decisions
#### 1. **Body Text is THE HERO**
**Why:**
- You came here to read, not to scan metrics
- Large, comfortable type (17px at 1.7 line-height)
- Primary visual weight goes to content
**Implementation:**
```dart
Text(
post.body,
style: AppTheme.bodyLarge.copyWith(
height: 1.7, // Extra generous for reading
letterSpacing: 0.1, // Slight tracking
),
)
```
**Contrast with Twitter/X:**
- Twitter: 15px text, 1.4 line-height, competing with images/metrics
- Sojorn: 17px text, 1.7 line-height, nothing competes
#### 2. **Author Identity: Clear but Not Dominant**
**Why:**
- You need to know who's speaking
- But not at the expense of the message
- Small avatar (36px vs typical 48px)
- De-emphasized text color (textSecondary, not textPrimary)
**Visual Hierarchy:**
```
1. Post body (textPrimary, 17px, bold visual weight)
2. Actions (tertiary, 16px icons)
3. Author (textSecondary, 13px)
4. Metadata (textTertiary, 11px)
```
#### 3. **Metrics De-emphasized**
**Why:**
- Like counts don't mean quality
- Save counts are personal, not performance
- Comment counts ≠ value (and don't boost reach!)
**Design Choices:**
- Icons are small (18px, not 24px)
- Text is labelSmall (11px)
- Color is textTertiary (very light gray)
- No visual weight
**What's Hidden:**
- View counts (never shown)
- Ratio metrics (likes/comments)
- Trending indicators
#### 4. **Trust Tier Badge: Subtle Signal**
**Why:**
- Trust matters for context
- But shouldn't dominate
- Tiny badge (8px font, 12% opacity background)
**vs Other Platforms:**
- Twitter verification: 20px, bright blue, dominant
- Sojorn trust tier: 8px, muted color, barely visible
### Interaction Behavior
#### 1. **Gentle Press States**
**Why:**
- Aggressive hover/press = visual aggression
- Subtle border change (borderSubtle → borderStrong)
- Shadow removal (not addition)
**Implementation:**
```dart
border: Border.all(
color: _isPressed ? AppTheme.borderStrong : AppTheme.borderSubtle,
width: 0.5,
),
boxShadow: _isPressed ? null : AppTheme.shadowSm,
```
**Effect:**
- Card "settles in" when pressed
- No bounce, no scale, no aggressive feedback
#### 2. **No Metric Celebration**
**Why:**
- No confetti when you hit 10 likes
- No "trending" badges
- No "your post is doing well!" notifications
**Philosophy:**
- You wrote something calm → reward is internal
- External validation ≠ quality
### Reading Enhancements
#### 1. **Optimal Typography**
- 17px body text (larger than most platforms)
- 1.7 line-height (research shows 1.5-1.6 is ideal, we go further)
- 0.1 letter-spacing (slight tracking for comfort)
- System fonts (SF Pro Text, Roboto) for familiarity
#### 2. **Interaction Affordances**
- Appreciate/Save always visible but quiet
- No hidden menus (everything upfront)
- Tap target size: 44px minimum (accessibility)
---
## Part 2: Writing & Commenting Experience
### Composer Design Intent
- Writing pauses before publishing (no tweet-and-regret)
- Friction feels supportive, not punitive
- Tone guidance is optional and respectful
### Composer UX Decisions
#### 1. **Large, Calm Text Area**
**Why:**
- Small inputs = rushed thoughts
- Large area = room to think
- 500 character limit shown gently (not alarming)
**Design:**
```dart
SojornTextArea(
minLines: 5, // Not 1-2 like Twitter
maxLines: 15,
maxLength: 500,
style: AppTheme.bodyLarge, // Same size as reading
)
```
#### 2. **Character Limit: Gentle, Not Alarming**
**What We Don't Do:**
- ❌ Turn red at 480/500
- ❌ Show "You're over the limit!" in red text
- ❌ Disable publish button aggressively
**What We Do:**
- ✅ Show "487 / 500" in textTertiary
- ✅ Turn accent color at 490
- ✅ Fade publish button (not disable) at 501+
**Copy:**
```
Good: "487 / 500"
Bad: "ONLY 13 CHARACTERS LEFT!"
```
#### 3. **Category Selection: Clear and Required**
**Why:**
- Categories are structural boundaries
- Must be intentional (no "general" default)
- Clear labels, obvious UI
### Tone Nudge UI
#### 1. **When Triggered**
**Scenario:** Post gets CIS < 0.85
**What We Don't Do:**
- ❌ Red warning banner
- ❌ "This violates community guidelines"
- ❌ Block publishing immediately
- ❌ Shame the user
**What We Do:**
- ✅ Neutral language
- ✅ Soft amber background (not red)
- ✅ Suggestion, not demand
- ✅ Allow dismiss
**Copy:**
```markdown
## Sharp Edges Detected
This post has language that may feel sharp to readers.
**Suggested rewrite:**
"I respectfully disagree with this approach."
**Original:**
"This is stupid and wrong."
[ Publish Anyway ] [ Edit ]
```
**Tone:**
- No "You violated..."
- No "This is not allowed"
- Just "This may feel sharp"
#### 2. **Allow Dismiss Without Penalty**
**Why:**
- You're an adult
- Tone detection isn't perfect
- Trust users to make decisions
**But:**
- Persistent low CIS → harmony score impact
- 3+ rejected posts → temporary slow-down
- Trust tier may adjust
**Philosophy:**
- Friction, not force
- Consequences, not punishment
### Comment UI
#### 1. **Mutual-Follow Only**
**Design:**
- Comment box only appears if mutual follow
- Otherwise: "Follow each other to comment"
- No shame, just structure
#### 2. **Compact, Conversational Layout**
**Why:**
- Comments are dialogue, not performance
- Small avatars (28px)
- Lighter visual weight than posts
#### 3. **Downvotes: De-emphasized**
**Why:**
- Downvotes useful for spam/quality
- But not a weapon
**Design:**
- No downvote count shown
- Icon is tertiary gray (not red)
- No "controversial" indicators
### Empty States
#### 1. **No Pressure to Post**
**Bad Copy:**
```
"Your feed is empty! Start following people!"
"Nothing to see here. Get active!"
```
**Good Copy (Sojorn Voice):**
```
"Nothing here yet"
"Posts you appreciate will appear here"
"Your feed is quiet right now"
```
**Tone:**
- Welcoming, not urgent
- Calm, not demanding
- Permission to lurk
---
## Part 3: Navigation & Information Architecture
### Design Intent
- Users always know where they are
- No hidden mechanics or dark patterns
- No surprise destinations
### Bottom Navigation
#### 1. **Clear, Limited Tabs**
**What We Have:**
- **Following** (chronological from follows)
- **Sojorn** (algorithmic FYP)
- **Profile** (your stats and posts)
**What We Don't Have:**
- ❌ "Discover" (too vague)
- ❌ "Notifications" (reduces checking anxiety)
- ❌ "Messages" (not yet implemented)
**Why 3 Tabs:**
- Cognitive load: 3-5 is ideal
- Each tab has one job
- No confusion
#### 2. **No Surprise Destinations**
**Rule:**
- Tab icon = where you land
- No "Following but actually Explore"
- No "Profile but actually Settings"
### Profile Hierarchy
#### 1. **Posts First**
**Why:**
- You came to see what they wrote
- Not their bio or follower count
**Layout:**
```
1. Posts (primary view)
2. Bio (secondary, collapsed)
3. Stats (tertiary, small)
4. Controls (obvious but not dominant)
```
#### 2. **Follow/Unfollow: Obvious**
**Design:**
- Always visible in header
- Clear label ("Follow" / "Following")
- No hidden in "..." menu
### Settings Organization
#### 1. **Grouped by Concern**
```
📖 Reading & Filters
- Category preferences
- Content filters
- Feed preferences
🔒 Privacy & Blocking
- Blocked users
- Profile visibility
- Data sharing
👤 Account & Data
- Email/password
- Export data
- Delete account
```
**Why This Order:**
- Most common (reading) first
- Safety (blocking) never buried
- Destructive (delete) last
#### 2. **No Buried Safety Controls**
**Rule:**
- Block button on every profile
- Privacy settings in top-level menu
- Export data always accessible
### Discoverability
#### 1. **Explore Tab Clearly Separate**
**Why:**
- "Explore" ≠ "Following"
- No accidental algorithm exposure
- Opt-in discovery
#### 2. **Categories Never Auto-Enable**
**Rule:**
- All categories off by default (except general)
- Explicit opt-in required
- No "We think you'd like..." suggestions
---
## Part 4: Blocking & Filtering UX
### Design Intent
- Blocking is self-care, not confrontation
- Filtering is private and encouraged
- No shame, no drama
### Block Affordance
#### 1. **Always Visible**
**Where:**
- On every profile (header menu)
- On every post (overflow menu)
- In comment threads
**Design:**
```
Icon: shield_outline (not block_circle)
Label: "Block @username"
Color: textSecondary (not error red)
```
**Why Shield Icon:**
- Block = protection, not punishment
- Shield = self-care
- Less aggressive than ⛔
#### 2. **One-Tap Confirmation**
**Flow:**
```
Tap "Block" →
Dialog: "Block @username?"
"You won't see their posts or comments. They won't be notified."
[ Cancel ] [ Block ]
```
**No:**
- ❌ "Are you SURE?"
- ❌ "This is permanent"
- ❌ Multiple confirmations
**Copy Tone:**
- Neutral, not dramatic
- Reassuring, not scary
#### 3. **No Explanation Required**
**Why:**
- You don't owe anyone an explanation
- Block is personal boundary
- No "Report" pressure
**But:**
- Separate "Report" option exists
- Report ≠ block (different flows)
### Filter Controls
#### 1. **Category Toggles**
**Design:**
```
[ ] Quiet Reflections
[ ] Gratitude
[x] General Discussion
[ ] Deep Questions
```
**Each Shows:**
- Name
- Description (one sentence)
- Post count (optional)
#### 2. **Keyword/Topic Filters (Optional)**
**Future Feature:**
```
Hide posts containing:
- "election"
- "crypto"
- "diet"
```
**Design:**
- Off by default
- No suggestions
- No "trending" pressure
#### 3. **Preview What's Hidden (Optional)**
**Design:**
```
[ ] Show me what I'm filtering
```
**When Enabled:**
- Filtered posts appear grayed out
- "Hidden by your filters" label
- Can tap to reveal
**Default:** OFF (out of sight, out of mind)
### Feedback Copy
#### 1. **After Blocking**
```
"You won't see posts from @username anymore."
"They won't be notified."
```
**Not:**
```
❌ "User blocked successfully!"
❌ "You'll never see them again!"
```
#### 2. **After Filtering**
```
"Quiet Reflections hidden from your feeds."
```
**Not:**
```
❌ "Category disabled!"
❌ "You won't miss anything important"
```
### Export/Import Block List
#### 1. **Clear Warnings**
```
## Export Block List
This downloads a JSON file with usernames you've blocked.
⚠️ This file contains your personal blocking decisions.
⚠️ Sharing this may reveal your social boundaries.
⚠️ Sojorn does not endorse public block list sharing.
[ Cancel ] [ Download JSON ]
```
#### 2. **No Recommendations**
**What We Don't Do:**
- ❌ "Import from popular block lists"
- ❌ "People like you also block..."
- ❌ "Suggested blocks based on your follows"
**Why:**
- Block lists = personal boundaries
- No crowd-sourcing judgment
- No guilt by association
---
## Part 5: Transparency & Explanation
### Design Intent
- Calm confidence through clarity
- No mystery, no jargon
- Trust through honesty
### "How Reach Works" Page
#### Content Structure
```markdown
# How Sojorn Ranking Works
Posts in your Sojorn feed are ranked by **calm velocity**—a measure of genuine appreciation over time.
## What Boosts Posts
- ❤️ Appreciations (likes)
- 🔖 Saves (strong signal)
- ⏱️ Time spent reading (dwell time)
- 🎯 High Content Integrity Score (CIS)
## What Slows Posts
- ⏰ Age (older posts fade naturally)
- 👎 Downvotes (quality filter)
- 🚩 Low CIS (tone issues)
## What Doesn't Matter
- 💬 Comment count (dialogue ≠ quality)
- 👥 Author's follower count
- 📊 Retweets/shares (we don't have those)
## Why This Way
Calm velocity rewards thoughtful content, not viral outrage. Posts earn reach through genuine appreciation, not reaction-baiting.
```
#### Design Choices
- **Plain language** (no "algorithm" jargon)
- **Bullet points** (scannable)
- **Emojis** (visual anchors, but not excessive)
- **Honesty** (explicitly state what doesn't matter)
### "Rules & Tone" Page
#### Content Structure
```markdown
# Community Tone Guidelines
Sojorn welcomes all ideas, but requires calm expression.
## Focus: Tone, Not Ideology
We don't police what you think. We ask how you express it.
### ✅ Allowed
- "I disagree with that approach."
- "This feels uncomfortable to me."
- "I see it differently."
### ⛔ Not Allowed
- "This is stupid."
- "You're an idiot."
- "What the hell were you thinking?"
## Why Tone Matters
Sharp language creates defensiveness. Calm language creates dialogue.
## How We Detect Tone
- Pattern-based analysis (not perfect)
- Content Integrity Score (CIS)
- Human review for edge cases
## What Happens
- CIS < 0.85: Gentle nudge to rephrase
- CIS < 0.70: Post blocked
- Persistent low CIS: Harmony score impact
```
#### Tone Choices
- **No shame** ("not allowed" not "violations")
- **Examples** (show, don't just tell)
- **Honesty** (admit imperfection)
### Contextual Help
#### 1. **"Why am I seeing this?"**
**Trigger:** Tap "..." on any post
**Copy:**
```
## Why This Post
This appeared in your Sojorn feed because:
- High calm velocity (287 appreciates, 45 saves)
- Category: General Discussion (you're subscribed)
- Posted 2 hours ago
```
#### 2. **"Why can't I comment?"**
**Scenario:** Non-mutual follow
**Copy:**
```
## Commenting
You can comment when you both follow each other.
This protects against drive-by harassment and ensures dialogue, not performance.
```
**Tone:**
- No "You're not allowed"
- Just "This is how it works"
---
## Part 6: Accessibility & Inclusivity
### Text Accessibility
#### 1. **Scalable Font Sizes**
**Implementation:**
```dart
Text(
post.body,
style: Theme.of(context).textTheme.bodyLarge,
// Respects user's OS text size settings
)
```
**Why:**
- Low vision users need large text
- Flutter automatically scales with OS settings
- No hardcoded font sizes
#### 2. **High Readability Contrast**
**Ratios:**
- textPrimary on background: 12.5:1 (AAA)
- textSecondary on background: 7.2:1 (AA)
- textTertiary on background: 4.8:1 (AA large text)
**Why:**
- WCAG AAA for body text
- Still feels calm (not harsh black on white)
### Interaction Accessibility
#### 1. **Keyboard Navigation (Web)**
**Requirements:**
- Tab through all interactive elements
- Enter/Space activates buttons
- Escape closes modals
- Arrow keys in lists
**Implementation:**
```dart
Focus(
onKey: (node, event) {
// Handle keyboard events
},
child: Widget(),
)
```
#### 2. **Screen Reader Labels**
**Example:**
```dart
IconButton(
icon: Icon(Icons.favorite_border),
tooltip: 'Appreciate this post',
semanticsLabel: 'Appreciate post from ${post.author.displayName}',
)
```
**Why:**
- Icon alone = meaningless to screen readers
- Context matters
#### 3. **Focus States**
**Design:**
```dart
focusColor: AppTheme.accent.withValues(alpha: 0.1),
// Soft highlight, not harsh outline
```
### Motion Accessibility
#### 1. **Respect Reduced Motion**
**Check:**
```dart
final reducedMotion = MediaQuery.of(context).accessibleNavigation;
final duration = reducedMotion
? Duration.zero
: AppTheme.durationMedium;
```
**Where Applied:**
- Fade transitions
- Sheet slides
- Loading spinners
#### 2. **No Required Animations**
**Rule:**
- All info accessible without animation
- Skeleton loaders have static alt
- Progress shown via text too
### Cognitive Load
#### 1. **Avoid Dense UI**
**Guidelines:**
- Maximum 3 actions per card
- One primary action per screen
- Generous spacing (24px, not 8px)
#### 2. **Avoid Urgency**
**No:**
- ❌ Red badges
- ❌ Pulsing animations
- ❌ "New!" labels
**Why:**
- Reduces anxiety
- Allows focus
- Respects attention
---
## Part 7: Final Polish
### Microinteractions
#### 1. **Subtle Haptics (Mobile)**
**When:**
- Appreciate/Save actions (light impact)
- Publish post (medium impact)
- Error state (notification feedback)
**Implementation:**
```dart
HapticFeedback.lightImpact(); // Not heavyImpact
```
**Why:**
- Confirms action
- But doesn't startle
#### 2. **Sound Cues (Optional, OFF by default)**
**Future:**
- Soft "bloom" on appreciate
- Gentle "save" sound
- Muted error tone
**Default:** OFF
**Why:** Audio = intrusive
### Loading States
#### 1. **Skeletons, Not Spinners**
**Design:**
```dart
ShimmerSkeleton(
child: PostCardSkeleton(),
)
```
**Why:**
- Shows structure
- Feels faster
- Less anxiety than spinner
#### 2. **Calm Copy**
**Good:**
```
"Loading..."
"One moment"
```
**Bad:**
```
❌ "Hang tight!"
❌ "Almost there!"
❌ "This won't take long!"
```
**Tone:**
- Neutral, not cheerful
- Honest, not performative
### Error Handling
#### 1. **Gentle Language**
**Good:**
```
"Couldn't load posts"
"Connection issue"
```
**Bad:**
```
❌ "ERROR: Network failure"
❌ "Oops! Something went wrong!"
❌ "Fatal exception occurred"
```
#### 2. **Clear Recovery**
**Pattern:**
```
[Error message]
[What happened]
[Action button]
```
**Example:**
```
Couldn't load posts
Check your internet connection.
[ Try Again ]
```
#### 3. **No Blame**
**Don't:**
- ❌ "You're offline"
- ❌ "Invalid input"
**Do:**
- ✅ "No connection"
- ✅ "Hmm, that didn't work"
### Performance
#### 1. **Optimize List Rendering**
```dart
ListView.builder(
itemBuilder: (context, index) {
return RepaintBoundary(
child: PostCard(post: posts[index]),
);
},
)
```
**Why:**
- RepaintBoundary = isolate repaints
- Smooth 60fps scroll
#### 2. **Cache Feeds Responsibly**
- Cache for 5 minutes
- Invalidate on pull-to-refresh
- Respect memory limits
#### 3. **No Jank on Scroll**
**Techniques:**
- Lazy load images
- Debounce pagination
- Avoid setState in scroll listener
---
## Summary: What Makes Sojorn Calm
### Visual Calm
- Warm neutrals, not cold grays
- Soft shadows (4-8% opacity)
- Generous spacing (24px, not 8px)
- Muted colors (no bright red/blue)
### Interaction Calm
- Slow animations (300-400ms)
- Gentle press states (no bounce)
- Subtle haptics (light, not heavy)
- No urgency cues
### Content Calm
- Body text is hero (17px, 1.7 line-height)
- Metrics de-emphasized (11px, tertiary)
- Author identity clear but quiet
- No performance pressure
### Structural Calm
- Mutual-follow commenting
- Category opt-in
- Block without drama
- Tone guidance without shame
### Cognitive Calm
- No mystery (transparency pages)
- No dark patterns (honest UI)
- No jargon (plain language)
- No surprises (predictable navigation)
---
**Result:** An app that feels like settling into a good book, not scrolling a frantic timeline.
**Enforcement:** Design system + custom widgets make it impossible to violate calm principles.
**Philosophy:** Calm is not a feature. Calm is structural.

View file

@ -41,7 +41,7 @@ When a user writes a post or comment, the content passes through tone analysis *
### 2. **Content Integrity Score (CIS)**
Every post that passes tone detection receives a **Content Integrity Score (0-1)**:
- Positive, calm language → CIS 0.9
- Positive, friendly language → CIS 0.9
- Neutral, factual language → CIS 0.8
- Mixed sentiment → CIS 0.7
- Negative but non-hostile → CIS 0.5
@ -66,7 +66,7 @@ Each user has a private **Harmony Score (0-100)** that adjusts based on behavior
- Filing false reports
**Positive signals (raise score):**
- Sustained calm participation
- Sustained positive participation
- Validated reports (helping moderation)
- Time without issues (natural recovery)
@ -109,7 +109,7 @@ Post eligibility for Trending (based on CIS + Harmony + Safety)
## What This Means for Users
### If you write calm, thoughtful content:
### If you write friendly, thoughtful content:
- Your posts pass tone detection instantly
- They receive high CIS scores
- They reach wide audiences
@ -163,4 +163,4 @@ But because the platform is architecturally designed to let it **expire quietly*
Clean content flows.
Sharp content stops.
Calm is structural.
Friendliness is structural.

View file

@ -3,7 +3,7 @@
## Core Principle: Honest Onboarding
**The Problem:**
New users dropped into an empty platform experience confusion, not calm. They don't know what belongs, what tone is expected, or whether anyone else is here.
New users dropped into an empty platform experience confusion, not connection. They don't know what belongs, what tone is expected, or whether anyone else is here.
**Traditional Solution (Rejected):**
- Create fake user personas
@ -34,14 +34,14 @@ All official accounts are:
**Content:**
- How Sojorn works
- Calm velocity explanations
- Community guidelines
- Feature updates
- Transparency notes
**Tone:** Neutral, factual, direct
**Example:**
> "Welcome to Sojorn. This is a text-only social platform designed for calm expression. Posts are ranked by calm velocity—genuine appreciation over time, not outrage or virality."
> "Welcome to Sojorn. This is a friends-first social platform designed for genuine connections. Posts are ranked by authentic engagement—real appreciation over time, not outrage or virality."
#### 2. @sojorn_read
**Purpose:** Reading content and prompts
@ -292,7 +292,7 @@ if (post.author.is_official) {
// Reduce ranking weight based on platform maturity
const platformAge = daysSinceFirstUserPost();
const officialPenalty = Math.min(platformAge / 30, 0.7); // Max 70% reduction
post.calmVelocity *= (1 - officialPenalty);
post.engagementScore *= (1 - officialPenalty);
}
```
@ -358,7 +358,7 @@ WITH CHECK (
### ✅ Good Seed Content
**@sojorn (Transparency):**
> "Your feed has two tabs: Following shows posts from people you follow, chronologically. Sojorn shows posts ranked by calm velocity from everyone. You control which categories you see."
> "Your feed has two tabs: Following shows posts from people you follow, chronologically. Sojorn shows posts ranked by authentic engagement from everyone. You control which categories you see."
**Why:** Factual, useful, transparent
@ -459,4 +459,4 @@ WITH CHECK (
**Execution:** Clearly labeled, authentically useful, gradually diluted.
**Result:** New users welcomed into calm, not emptiness.
**Result:** New users welcomed into connection, not emptiness.

View file

@ -92,7 +92,7 @@ The **Supabase backend foundation** for Sojorn is complete. All core database sc
- Algorithmic "For You" feed
- Fetches 500 candidate posts (last 7 days)
- Enriches with author trust and safety metrics
- Ranks by calm velocity algorithm
- Ranks by authentic engagement algorithm
- Returns paginated, ranked results
- Includes ranking explanation
@ -100,7 +100,7 @@ The **Supabase backend foundation** for Sojorn is complete. All core database sc
- Category-scoped trending
- Merges editorial overrides + algorithmic picks
- Eligibility: Positive/Neutral tone, CIS >= 0.8, no safety issues
- Ranks by calm velocity
- Ranks by authentic engagement
- Limited to last 48 hours
8. **calculate-harmony**
@ -143,7 +143,7 @@ The **Supabase backend foundation** for Sojorn is complete. All core database sc
- ✅ **supabase-client.ts** Client creation helpers
- ✅ **tone-detection.ts** Pattern-based tone classifier
- ✅ **validation.ts** Input validation with custom errors
- ✅ **ranking.ts** Calm velocity ranking algorithm
- ✅ **ranking.ts** Authentic engagement ranking algorithm
- ✅ **harmony.ts** Harmony score calculation and effects
### Documentation
@ -269,7 +269,7 @@ Before public beta:
- Cache trending results per category (15-min TTL)
- Batch harmony calculations (process 100 users at a time)
- Add Redis for session and feed caching
- Pre-compute calm velocity scores on post creation
- Pre-compute engagement scores on post creation
---
@ -300,7 +300,7 @@ Before public beta:
## Success Metrics (Future)
- **Calm retention:** Users return daily without compulsion
- **Friendly retention:** Users return daily for genuine connection
- **Low block rate:** < 1% of relationships result in blocks
- **High save-to-like ratio:** Thoughtful curation > quick reactions
- **Diverse trending:** No single author/topic dominates

View file

@ -7,13 +7,13 @@
## What Was Built
A complete **Supabase backend** for Sojorn, a calm text-only social platform where **sharp speech stops quietly**.
A complete **Go backend** for Sojorn, a friends-first social platform where **genuine connections thrive**.
### Core Philosophy Implemented
Every design choice encodes behavioral principles:
1. **Calm is structural** → RLS policies enforce boundaries at database level
1. **Connection is structural** → RLS policies enforce boundaries at database level
2. **Consent is required** → Comments only work with mutual follows
3. **Exposure is opt-in** → Categories default to disabled, users choose what they see
4. **Influence is earned** → Harmony score determines reach and posting limits
@ -53,7 +53,7 @@ Every design choice encodes behavioral principles:
**Feed Systems:**
- `feed-personal` Chronological feed from followed accounts
- `feed-sojorn` Algorithmic FYP with calm velocity ranking
- `feed-sojorn` Algorithmic FYP with authentic engagement ranking
- `trending` Category-scoped trending with editorial overrides
**Trust Management:**
@ -63,7 +63,7 @@ Every design choice encodes behavioral principles:
- **tone-detection.ts** Pattern-based classifier (positive, neutral, mixed, negative, hostile)
- **validation.ts** Input validation with custom error types
- **ranking.ts** Calm velocity algorithm (saves > likes, steady > spiky)
- `ranking.ts` Authentic engagement algorithm (saves > likes, steady > spiky)
- **harmony.ts** Trust score calculation and reach effects
- **supabase-client.ts** Client configuration helpers
@ -128,11 +128,11 @@ Every design choice encodes behavioral principles:
| Algorithms amplify outrage | Algorithms deprioritize sharp speech |
| Moderation is reactive | Containment is structural |
### vs. Other Calm Platforms
### vs. Other Friendly Platforms
| Other Calm Apps | Sojorn |
| Other Friendly Apps | Sojorn |
|-----------------|--------|
| Performative calm (aesthetics) | Structural calm (RLS, tone gates) |
| Performative friendliness (aesthetics) | Structural friendliness (RLS, tone gates) |
| Mindfulness focus | Social connection focus |
| Content curation (passive) | Content creation (active) |
| Wellness angle | Social infrastructure angle |
@ -159,7 +159,7 @@ Every design choice encodes behavioral principles:
### 4. Natural Fit Over Forced Moderation
- People who don't fit experience friction, not bans
- Influence diminishes naturally for hostile users
- Recovery is automatic with calm participation
- Recovery is automatic with positive participation
---
@ -207,7 +207,7 @@ Every design choice encodes behavioral principles:
2. **Read completion tracking** Factor into ranking
3. **Post view logging** Dwell time analysis
4. **Analytics dashboard** Harmony trends, category health
5. **A/B testing framework** Optimize calm velocity parameters
5. **A/B testing framework** Optimize engagement parameters
---
@ -262,7 +262,7 @@ When Sojorn is working:
## Final Note
This backend encodes **calm as infrastructure, not aspiration**.
This backend encodes **friendliness as infrastructure, not aspiration**.
The database will not allow:
- Unwanted replies
@ -274,7 +274,7 @@ The database will not allow:
**Sojorn is structurally incapable of being an outrage machine.**
Now build the client that makes this calm accessible.
Now build the client that makes this friendliness accessible.
---