Visual foundation for the map (ideas #2, #3, #4, #6 — features #5/#7 intentionally deferred to a later pass): #2 Crisp pins, not blobs: - Reworked createSkateSpotIcon — solid neon teardrop with a TIGHT glow halo (inset dark ring + focused shadow) instead of the soft box-shadow that read as a fuzzy cloud on light tiles. Cluster badges given the same crisp treatment. #3 Marker = spot type (a readable language): - Category emoji inside each pin: 🛹 street / 🏞️ park / 🔧 DIY / 🏛️ plaza / 🌊 transition. - Covered/indoor spots get a cyan roof "cap" so dry spots stand out at a glance — the payoff of the shelter data living on the map, not just a badge. - createSkateSpotIcon now takes an options object (weatherColor/weatherIcon/ category/shelter); all call sites updated. Weather-layer colouring unchanged. #4 Less scrim, floating loading: - Suspense map-load fallback dimming reduced (bg-black/50 → /20). - "Finding spots" pill moved from dead-centre (top 46%) to a slim top pill so it never blocks the map where the spots are. #6 Micro-interactions (CSS, GPU-friendly, reduced-motion aware): - New pins drop in with a spring; hover/focus/tap lifts the pin and pulses its neon halo once. Build clean, no console errors. No tile/theme change — the "og" light map is untouched per request. Co-authored-by: shakespeare.diy <assistant@shakespeare.diy> |
||
|---|---|---|
| .agents/skills | ||
| .github | ||
| .nsite | ||
| .vscode | ||
| android-templates | ||
| cvm-server | ||
| eslint-rules | ||
| public | ||
| scripts | ||
| skills | ||
| src | ||
| .gitignore | ||
| .gitlab-ci.yml | ||
| .mcp.json | ||
| .npmrc | ||
| AGENTS.md | ||
| BOUNTY-SYSTEM-PLAN.md | ||
| BUDGET_IMPLEMENTATION.md | ||
| capacitor.config.ts | ||
| components.json | ||
| CONTEXTVM_INTEGRATION.md | ||
| DEPLOYMENT_COMPARISON.md | ||
| EMERGENCY_FIX.md | ||
| eslint.config.js | ||
| FINAL_POLISH_BREAKDOWN.md | ||
| FINAL_SCOPE.md | ||
| FIXES_BREAKDOWN.md | ||
| FOLLOW_MANAGEMENT_BRIEFING.md | ||
| HOW_TO_ENABLE_RELATR.md | ||
| IMPLEMENTATION_COMPLETE.md | ||
| IMPLEMENTATION_PLAN.md | ||
| index.html | ||
| INTEGRATION_BRIEFING.md | ||
| LIVE_MUSIC_PROPOSAL.md | ||
| LOGO_USAGE.md | ||
| MCP_SERVER_SPEC.md | ||
| netlify.toml | ||
| NIP-06-IMPLEMENTATION.md | ||
| NIP.md | ||
| NOGOOD_RADIO_PROPOSAL.md | ||
| opencode.json | ||
| package-lock.json | ||
| package.json | ||
| postcss.config.js | ||
| RADIO_PLAYER_GUIDE.md | ||
| README.md | ||
| RELATR_INTEGRATION.md | ||
| RELAY_FIX.md | ||
| RELAY_SETUP.md | ||
| release-notes.txt | ||
| SECURITY.md | ||
| SHOP_VERIFICATION_ANALYSIS.md | ||
| stack.json | ||
| tailwind.config.ts | ||
| tsconfig.json | ||
| vite.config.ts | ||
| WEATHER_FEATURE.md | ||
| ZAP_INTEGRATION_PROPOSAL.md | ||
| ZAP_QUICK_WINS.md | ||
| ZAP_SIMPLE_PLAN.md | ||
| ZAPSTORE.md | ||
| zapstore.yaml | ||
SkateSpots - Decentralized Skate Map & Community
A decentralized skateboarding community platform built on Nostr. Discover skate spots, find coaches, join events, and connect with skaters worldwide.
🌐 Live App
- Deployed URL: https://skate-spots.org
- Nostr Git: nostr://npub1yrnuj56rnen08zp2h9h7p74ghgjx6ma39spmpj6w9hzxywutevsst7k5cx/git.shakespeare.diy/SkateSpots
✨ Features
- 🗺️ Interactive Skate Map - Discover skate spots worldwide with geolocation
- 🛹 Spot Database - Browse, create, and review skate parks and street spots
- 📅 Events Calendar - Find and create skateboarding events and competitions
- 👨🏫 The Lab - Connect with coaches, filmers, and video editors in your area
- 🎬 Video Editors - Find editors who list their software, hardware, and portfolio
- 🛍️ Skate Shops - Discover local skate shops and support the community
- 🔄 Buy/Sell Gear - Marketplace for used skate gear (NIP-99 classified listings)
- 🎒 My Stash - Private encrypted gear inventory with location tracking
- 🎵 NoGood Radio - 24/7 vibing music (lofi, synthwave, electronica)
- ⚡ Lightning Zaps - Send Bitcoin tips to content creators
- 🌤️ Weather Integration - Check conditions before you skate
- 🔐 Nostr Authentication - Decentralized login with your Nostr keys
- 📱 PWA Support - Install as a native app on any device
- ❤️ Supporters - Community funding via Angor (decentralized Bitcoin crowdfunding)
🛠️ Technology Stack
- React 18 - Modern UI with hooks and concurrent rendering
- Nostr Protocol - Decentralized data storage and communication
- TailwindCSS 3 - Utility-first CSS framework
- Vite - Lightning-fast build tool and dev server
- shadcn/ui - Beautiful, accessible UI components
- Nostrify - Nostr framework for web applications
- TanStack Query - Data fetching and caching
- OpenStreetMap - Interactive maps
- TypeScript - Type-safe development
🚀 Getting Started
Prerequisites
- Node.js 18+
- npm or yarn
Installation
# Clone the repository
git clone nostr://npub1yrnuj56rnen08zp2h9h7p74ghgjx6ma39spmpj6w9hzxywutevsst7k5cx/git.shakespeare.diy/SkateSpots
# Install dependencies
npm install
# Start development server
npm run dev
Building
# Build for production
npm run build
# Run tests
npm test
🌍 Deployment
The app is configured for deployment via:
- Shakespeare Deploy - Nostr-native deployment (configured)
- Netlify - Static site hosting
- Vercel - Edge deployment
- nsite - Nostr-native sites
Deploy command:
npm run deploy
📱 PWA Installation
SkateSpots works as a Progressive Web App (PWA) and can be installed on:
- Desktop: Chrome, Edge, Safari - Look for install icon in address bar
- Android: Chrome - "Add to Home Screen" from menu
- iOS: Safari - "Add to Home Screen" from share menu
🔌 Nostr Integration
Custom Event Kinds
This app uses custom Nostr event kinds defined in NIP.md:
| Kind | Type | Description |
|---|---|---|
| 30017 | Addressable | Skate Shops (NIP-15 Stall) |
| 30402 | Addressable | Gear Listings (NIP-99 Classified) |
| 30818 | Addressable | Skate Spots |
| 30823 | Addressable | Skate Tours |
| 31923 | Addressable | Skate Events (NIP-52 Calendar) |
| 35001 | Addressable | Skate Coaches |
| 35002 | Addressable | Skate Filmers / Photographers |
| 35003 | Addressable | Skate Video Editors |
Relay Configuration
Default relay: wss://goskatespots.nostr1.com
Users can manage relays in Settings following NIP-65.
🎒 My Stash
The Stash is a private, encrypted gear inventory (NIP-51 kind 30001). Users can track their equipment with:
- Categories: Decks, trucks, wheels, bearings, shoes, apparel, protective gear, and more
- Storage locations: Home, car, backpack, wardrobe, van, skatepark, friend's, parents', warehouse, storage unit, sponsor, or other
- Condition rating (1–5 stars), rarity tier, and optional price
- Visibility control: Private (encrypted), friends-only, or public
- Filter & search by category, storage location, or keyword
🧪 The Lab
The Lab connects skaters with service providers in three categories:
- Coaches - Skateboarding instructors with skill specializations
- Filmers - Videographers and photographers with equipment/style details
- Video Editors - Editors who list their software (Premiere, DaVinci, After Effects, etc.), hardware setup, portfolio, and contact details
📦 Dependencies Overview
Core Dependencies
@nostrify/nostrify- Nostr protocol implementation@nostrify/react- React integration for Nostrreact&react-dom- UI frameworkreact-router-dom- Client-side routing@tanstack/react-query- Data fetching and statenostr-tools- Nostr utilities and cryptography
UI & Styling
tailwindcss- Utility-first CSS@radix-ui/*- Accessible UI primitiveslucide-react- Icon libraryclass-variance-authority- Component variantstailwind-merge- Class name merging
Maps & Location
- OpenStreetMap - Interactive maps
ngeohash- Geohash encoding/decoding
Bitcoin & Lightning
@getalby/sdk- Alby wallet integration@cashu/cashu-ts- Cashu ecash protocolnpubcash-sdk- npub.cash integrationbitcoinjs-lib- Bitcoin utilities@noble/curves&@noble/hashes- Cryptography
Media & Streaming
hls.js- HLS streaming supportqrcode- QR code generationhtml5-qrcode- QR code scanning
Utilities
date-fns- Date formattingzod- Schema validationreact-hook-form- Form handlingbuffer- Node.js buffer polyfillidb&dexie- IndexedDB wrappers
🏗️ Project Structure
/src
├── components/ # React components
│ ├── ui/ # shadcn/ui components (48+)
│ ├── auth/ # Authentication components
│ └── ... # Feature components
├── hooks/ # Custom React hooks
├── pages/ # Route pages
├── lib/ # Utilities and helpers
├── contexts/ # React context providers
└── test/ # Testing utilities
/public
├── images/ # Static images and icons
├── manifest.webmanifest
└── robots.txt
/skills # Implementation guides for features
🧪 Testing
# Run all tests (TypeScript, ESLint, Vitest, Build)
npm test
# Type checking only
npx tsc --noEmit
# Linting only
npx eslint
🤝 Contributing
This is a Nostr-based open source project. Contributions are welcome!
- Fork/clone the repository via Shakespeare or git
- Create your feature branch
- Make your changes
- Run tests (
npm test) - Commit your changes
- Push and create a pull request
📄 License
YOU ARE FREE TO SKATEBOARD
This project is open. Share it, fork it, build on it, skate it. The streets belong to everyone. So does this code. Just keep skating and don't be a kook.
Copyright © 2025–∞ SkateSpots contributors & the community
See /license in the app for the full license page.
❤️ Support the Project
SkateSpots is 100% free, open-source, and community-funded. No ads, no data selling, no investors.
- Angor: https://angor.io/project/angor1qtunna00uqyx52rr0nvqa059z2gknhrmn7urd6z
- Supporters page: https://skate-spots.org/supporters
🙏 Credits
- Built with: MKStack - Nostr client framework
- Vibed with: Shakespeare - AI-powered development
- Powered by: Nostr - Decentralized protocol
- Funded by: Angor - Decentralized Bitcoin crowdfunding
🔗 Links
📞 Support
For issues or questions:
- Open an issue on the repository
- Contact via Nostr: npub1yrnuj56rnen08zp2h9h7p74ghgjx6ma39spmpj6w9hzxywutevsst7k5cx
Made with ❤️ for the skateboarding community