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:
parent
38653f5854
commit
b9351b76ae
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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.**
|
||||
|
|
|
|||
|
|
@ -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.**
|
||||
|
|
|
|||
|
|
@ -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.**
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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`
|
||||
|
|
|
|||
|
|
@ -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).
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue