Files
indee-demo/.cursor/rules/scroll-navigation.mdc
Dorian 0bb1bcc5f9 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>
2026-02-02 22:19:47 +00:00

112 lines
2.3 KiB
Plaintext

---
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;
}
```