Initial commit: IndeeHub decentralized streaming platform
Built a complete Netflix-style streaming interface for IndeeHub's decentralized media platform with real film content. Features: - Vue 3 + TypeScript + Vite setup with hot module reloading - Netflix-inspired UI with hero section and horizontal scrolling content rows - Glass morphism design system with custom Tailwind configuration - 20+ real IndeeHub films organized into 6 categories (Bitcoin, Documentaries, Drama, etc.) - Full-featured video player component with custom controls - Mobile-responsive design with bottom navigation - Nostr integration ready (nostr-tools, relay pool, NIP-71 support) - Pinia state management for content - MCP tools configured (Filesystem, Memory, Nostr, Puppeteer) Components: - Browse.vue: Main streaming interface with hero and content rows - ContentRow.vue: Horizontal scrolling film cards with navigation arrows - VideoPlayer.vue: Custom video player with play/pause, seek, volume, fullscreen - MobileNav.vue: Bottom tab navigation for mobile devices Tech Stack: - Frontend: Vue 3 (Composition API), TypeScript - Build: Vite 7 - Styling: Tailwind CSS with custom theme - State: Pinia 3 - Router: Vue Router 4.6 - Protocol: Nostr (nostr-tools 2.22) Design: - 4px grid spacing system - Glass morphism UI components - Netflix-style hero section with featured content - Smooth animations and hover effects - Mobile-first responsive breakpoints - Dark theme with custom color palette Content: - 20+ IndeeHub films with titles, descriptions, categories - Bitcoin documentaries: God Bless Bitcoin, Dirty Coin, Searching for Satoshi - Independent films and documentaries - Working Unsplash CDN images for thumbnails and backdrops Ready for deployment to Umbrel, Start9, and Archy nodes. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
111
.cursor/rules/scroll-navigation.mdc
Normal file
111
.cursor/rules/scroll-navigation.mdc
Normal file
@@ -0,0 +1,111 @@
|
||||
---
|
||||
description: Scroll behavior and navigation patterns
|
||||
alwaysApply: false
|
||||
globs: **/*.{ts,tsx,js,jsx,vue,css,scss}
|
||||
---
|
||||
|
||||
# Scroll & Navigation Patterns
|
||||
|
||||
## Scroll Philosophy
|
||||
|
||||
**Default to Natural Scrolling**
|
||||
|
||||
Natural, uncontrolled scrolling should be your default. Only implement controlled scroll behaviors when they serve a clear purpose.
|
||||
|
||||
### When to Control Scroll
|
||||
|
||||
- ✅ Full-page sections (snap scrolling) - ONLY for portfolios/showcases
|
||||
- ✅ Carousels and galleries
|
||||
- ✅ Onboarding flows
|
||||
- ✅ Modal/overlay open states
|
||||
|
||||
### When to Allow Natural Scroll (Most Cases)
|
||||
|
||||
- ✅ Long-form content
|
||||
- ✅ Blog posts and articles
|
||||
- ✅ List views
|
||||
- ✅ Traditional navigation
|
||||
- ✅ E-commerce sites
|
||||
- ✅ Documentation
|
||||
- ✅ Applications and dashboards
|
||||
|
||||
## Snap Scrolling (Use Sparingly)
|
||||
|
||||
**⚠️ CAVEAT**: Snap scrolling is NOT always appropriate. Use only for specific cases like portfolios and presentations.
|
||||
|
||||
```css
|
||||
/* Container with snap behavior */
|
||||
html {
|
||||
scroll-snap-type: y mandatory;
|
||||
scroll-padding-top: 4rem;
|
||||
}
|
||||
|
||||
.snap-section {
|
||||
scroll-snap-align: start;
|
||||
scroll-snap-stop: always;
|
||||
min-height: 100vh;
|
||||
min-height: 100dvh;
|
||||
}
|
||||
```
|
||||
|
||||
## Smooth Scrolling
|
||||
|
||||
```css
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
/* Respect user preferences */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
html {
|
||||
scroll-behavior: auto;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Scroll Lock (Modal Open)
|
||||
|
||||
```javascript
|
||||
const lockScroll = () => {
|
||||
const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth;
|
||||
document.body.style.overflow = 'hidden';
|
||||
document.body.style.paddingRight = `${scrollbarWidth}px`;
|
||||
};
|
||||
|
||||
const unlockScroll = () => {
|
||||
document.body.style.overflow = '';
|
||||
document.body.style.paddingRight = '';
|
||||
};
|
||||
```
|
||||
|
||||
## Scroll Position Persistence
|
||||
|
||||
```javascript
|
||||
// Save before navigation
|
||||
const saveScrollPosition = () => {
|
||||
sessionStorage.setItem('scrollPosition', window.scrollY.toString());
|
||||
};
|
||||
|
||||
// Restore on page load
|
||||
const restoreScrollPosition = () => {
|
||||
const savedPosition = sessionStorage.getItem('scrollPosition');
|
||||
if (savedPosition) {
|
||||
window.scrollTo(0, parseInt(savedPosition, 10));
|
||||
sessionStorage.removeItem('scrollPosition');
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
## Overscroll Behavior
|
||||
|
||||
```css
|
||||
/* Disable bounce on body */
|
||||
body {
|
||||
overscroll-behavior: none;
|
||||
}
|
||||
|
||||
/* Contain overscroll to element */
|
||||
.modal {
|
||||
overscroll-behavior: contain;
|
||||
}
|
||||
```
|
||||
Reference in New Issue
Block a user