Ryan Malloy e6d335f5b5 Initial commit: story-teller.ink platform
- Complete Astro + Alpine.js implementation
- Docker Compose setup with Caddy reverse proxy
- Dual platform: Anonymous & Named Storytellers
- Interactive features: voting, comments, filtering
- Categories page with search functionality
- Content collections for markdown stories
- Responsive design with accessibility features
- Environment variable configuration

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-17 23:35:55 -06:00
2025-08-17 23:35:55 -06:00

story-teller.ink - Astro + Alpine.js Version

🏔️🚀 Lightning Fast Storytelling Platform

This is the Astro + Alpine.js implementation of story-teller.ink - a dual platform connecting seniors through storytelling with zero-JS-by-default performance and 15kb total JavaScript.

🎯 Why Astro + Alpine.js?

Performance for Seniors

  • ~20kb total per story page (vs 300kb+ React)
  • Instant story loading - static HTML with no hydration delay
  • 15kb Alpine.js only loads for interactive features
  • Works on ancient devices - no modern JS features required

Accessibility First

  • HTML-first - stories load immediately, work with JS disabled
  • Progressive enhancement - Alpine adds interactivity gracefully
  • Screen reader perfect - semantic HTML from the start
  • High contrast & reduced motion support built-in

Content Management

  • Markdown stories - easy to write and maintain
  • Content collections - organized by platform (nevertell/dignity)
  • Static generation - stories become permanent web pages
  • Type-safe frontmatter with Zod validation

🏗️ Architecture Overview

src/
├── content/
│   ├── nevertell/           # Anonymous stories (markdown)
│   │   ├── elvis-concert-1956.md
│   │   └── college-roommate-prank.md
│   └── dignity/             # Named stories (markdown)
│       ├── martha-navy-nurse.md
│       └── dorothy-civil-rights.md
├── pages/
│   ├── index.astro          # Main landing page
│   ├── nevertell/
│   │   ├── index.astro      # Anonymous story list + Alpine filtering
│   │   └── [slug].astro     # Static story + Alpine comments
│   └── dignity/
│       ├── index.astro      # Named story list
│       └── [slug].astro     # Static story + Alpine interactions
├── layouts/
│   ├── BaseLayout.astro     # Global Alpine.js setup
│   ├── NevertellLayout.astro
│   └── DignityLayout.astro
└── styles/
    └── global.css           # Tailwind + accessibility styles

🌟 Key Features

Dual Platform Architecture

  • Anonymous Storytellers 🤫 - Anonymous stories with mischievous tone
  • Named Storytellers 🏆 - Named stories with respectful tone
  • Cross-platform promotion - community can encourage anonymous→named

Static + Interactive

  • Static story pages load instantly
  • Alpine.js islands for voting, comments, filtering
  • Progressive enhancement - works without JavaScript
  • Real-time interactions where needed

Senior-Optimized

  • Large fonts (18px base, scalable to 20px+)
  • 44px minimum touch targets for mobile
  • High contrast mode support
  • Keyboard navigation optimized
  • Reduced motion preferences honored

🚀 Getting Started

Prerequisites

  • Node.js 18+
  • npm or yarn

Installation

cd story-bridge-astro
npm install

Development

npm run dev
# Visit http://localhost:4321

Build for Production

npm run build
npm run preview

📖 Content Management

Adding New Stories

Anonymous Story

---
# src/content/nevertell/new-story.md
title: "The Time I..."
excerpt: "Brief description..."
tags: ["1960s", "college", "pranks"]
location: "Senior Center, City State"
dateOfEvent: "Summer 1965"
upvotes: 0
promotionVotes: 0
publishedAt: 2024-01-20T00:00:00.000Z
commentCount: 0
---

Your amazing story content here in beautiful markdown...

Named Story

---
# src/content/dignity/new-story.md
title: "Hero's Journey"
excerpt: "Brief description..."
authorName: "John Smith"
authorAge: 87
tags: ["WWII", "service", "heroism"]
location: "Veterans Home, City State"
dateOfEvent: "1943-1945"
upvotes: 0
publishedAt: 2024-01-20T00:00:00.000Z
commentCount: 0
---

Their incredible story of service and sacrifice...

Content Validation

All story frontmatter is validated with Zod schemas in src/content/config.ts.

Performance Metrics

Page Load Sizes

  • Main page: ~25kb (HTML + CSS + 15kb Alpine)
  • Story pages: ~20kb (mostly static HTML content)
  • Story list: ~30kb (static HTML + Alpine filtering)

Performance Benefits

  • 0ms hydration - stories load as static HTML
  • Instant navigation - no client-side routing delays
  • Offline reading - cached HTML works without connection
  • SEO perfect - fully rendered HTML for search engines

🎨 Styling & Themes

Platform-Specific Themes

/* Anonymous Storytellers - playful, mischievous */
nevertell: {
  primary: '#6366f1',    // indigo
  secondary: '#ec4899',  // pink
  accent: '#f59e0b',     // amber
}

/* Named Storytellers - warm, respectful */
dignity: {
  primary: '#059669',    // emerald
  secondary: '#dc2626',  // red
  accent: '#d97706',     // amber
}

Accessibility Features

  • Large fonts with scalable sizing
  • High contrast mode support
  • Reduced motion preferences
  • Focus indicators for keyboard navigation
  • Screen reader optimized markup

🌐 Deployment

npm install -g vercel
vercel --prod

Netlify

npm run build
# Upload dist/ folder to Netlify

Static Hosting

npm run build
# Serve dist/ folder from any static host

Domain Configuration

Configure story-teller.ink for hosting. The platform handles both anonymous and named storytellers on the same domain with different routes.

🔧 Alpine.js Features

Global Stores

// Utility functions available everywhere
Alpine.store('utils', {
  formatDate(dateString),
  formatRelativeTime(dateString),
  truncateText(text, maxLength)
});

// API functions for voting and comments
Alpine.store('api', {
  vote(storyId, type),
  submitComment(storyId, content, authorName),
  loadComments(storyId)
});

Interactive Components

  • Story filtering with real-time search and tag selection
  • Voting systems for upvotes and promotions
  • Comment systems with threaded discussions
  • Form validation and submission handling

🎯 Mission Statement

We're building bridges between the generation that invented rock & roll and the generation that invented the internet.

The Story Bridge Effect

  1. Stories flow out (resident → internet)
  2. Connections flow back (internet → resident)
  3. Social energy flows within (resident ↔ other residents)

🤝 Contributing

Adding Features

  1. Static content goes in src/pages/ and src/content/
  2. Interactive features use Alpine.js data functions
  3. Maintain accessibility standards
  4. Test on mobile and with keyboard navigation

Content Guidelines

  • Anonymous stories should be fun, engaging, authentic
  • Named stories should be respectful, honoring, dignified
  • All stories must have proper frontmatter and tags
  • Excerpts should be compelling and draw readers in

📊 Analytics & Monitoring

Metrics to Track

  • Story reading time (engagement)
  • Comment engagement (community building)
  • Cross-platform promotions (success indicator)
  • Mobile vs desktop usage (senior preferences)
  • Accessibility feature usage

Success Indicators

  • Stories being shared outside the platform
  • Comments creating real connections
  • Anonymous stories being promoted to named storytellers
  • Seniors discussing stories in their facilities

🔮 Future Enhancements

Planned Features

  • RSS feeds for story subscriptions
  • Story search with full-text indexing
  • Related stories based on tags and themes
  • Email notifications for story responses
  • Print-friendly story formats
  • Audio narration for accessibility

Technical Improvements

  • Progressive Web App features
  • Offline story caching
  • Image optimization for story photos
  • CDN integration for global performance

Built with ❤️ for the generation that has the best stories to tell.

Performance: Astro Interactivity: Alpine.js 🏔️ Accessibility: Senior-first

Description
Astro + Alpine.js platform for connecting seniors through storytelling
Readme 76 KiB
Languages
Astro 91.8%
CSS 3.4%
JavaScript 2.6%
TypeScript 1.5%
Shell 0.4%
Other 0.3%