deepsite-project-41uyr / models.html
VibeCodingStudio's picture
🐳 19/05 - 17:17 - I want you to go through every page, and I want you to add smooth transitions and interactive elements and better looking elements as well as 3D elements and designs. As well as Exp
b94499a verified
Raw
History Blame Contribute Delete
20.8 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Models — NSFWStudio</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://unpkg.com/lucide@latest"></script>
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:opsz,wght@14..32,300..800&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
<script>
tailwind.config = { theme: { extend: { fontFamily: { sans: ['Inter','system-ui','sans-serif'], mono: ['JetBrains Mono','monospace'] }, colors: { bg: 'oklch(0.07 0.006 285)', surface: 'oklch(0.12 0.02 285)', 'surface-2': 'oklch(0.16 0.025 285)', 'surface-3': 'oklch(0.20 0.028 285)', fg: 'oklch(0.97 0.005 285)', muted: 'oklch(0.55 0.02 285)', primary: 'oklch(0.70 0.28 350)', 'primary-foreground': 'oklch(0.98 0.005 285)', secondary: 'oklch(0.75 0.15 215)', accent: 'oklch(0.80 0.18 85)', border: 'oklch(0.22 0.02 285)', ring: 'oklch(0.70 0.28 350)', destructive: 'oklch(0.55 0.22 25)', success: 'oklch(0.65 0.2 145)' } } } }
</script>
<style>
body { background-color: oklch(0.07 0.006 285); color: oklch(0.97 0.005 285); font-family: 'Inter', system-ui, sans-serif; -webkit-font-smoothing: antialiased; }
.glass { background: oklch(0.14 0.015 285 / 0.6); backdrop-filter: blur(24px) saturate(1.2); -webkit-backdrop-filter: blur(24px) saturate(1.2); border: 1px solid oklch(0.25 0.02 285 / 0.5); }
.gradient-text { background: linear-gradient(135deg, oklch(0.70 0.28 350), oklch(0.75 0.15 215)); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; }
::selection { background: oklch(0.70 0.28 350 / 0.3); }
body::after { content:''; position:fixed; inset:0; pointer-events:none; z-index:9999; opacity:0.025; background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"); background-repeat:repeat; background-size:256px 256px; }
.no-scrollbar::-webkit-scrollbar { display: none; } .no-scrollbar { -ms-overflow-style: none; scrollbar-width: none; }
.tabular-nums { font-variant-numeric: tabular-nums; }
.card-3d { transition: transform 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94), box-shadow 0.4s ease; }
.card-3d:hover { transform: perspective(1000px) rotateY(-3deg) rotateX(2deg) translateZ(20px); box-shadow: 0 25px 50px rgba(0,0,0,0.4), 0 0 0 1px oklch(0.70 0.28 350 / 0.2); }
.hover-lift { transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1), box-shadow 0.3s ease; }
.hover-lift:hover { transform: translateY(-6px) scale(1.02); box-shadow: 0 20px 40px rgba(0,0,0,0.3), 0 0 0 1px oklch(0.70 0.28 350 / 0.2); }
.gradient-border-animated { position: relative; isolation: isolate; }
.gradient-border-animated::before { content: ''; position: absolute; inset: 0; border-radius: inherit; padding: 1.5px; background: linear-gradient(270deg, oklch(0.70 0.28 350), oklch(0.75 0.15 215), oklch(0.80 0.18 85), oklch(0.70 0.28 350)); background-size: 300% 100%; -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0); -webkit-mask-composite: xor; mask-composite: exclude; opacity: 0; transition: opacity 0.3s ease; }
.gradient-border-animated:hover::before { opacity: 1; }
.glow-border { position: relative; isolation: isolate; }
.glow-border::after { content: ''; position: absolute; inset: -2px; border-radius: inherit; background: linear-gradient(135deg, oklch(0.70 0.28 350), oklch(0.75 0.15 215)); z-index: -1; opacity: 0; transition: opacity 0.3s ease; filter: blur(10px); }
.glow-border:hover::after { opacity: 0.6; }
</style>
</head>
<body class="antialiased">
<div id="root"></div>
<script type="text/babel">
const { useState } = React;
const Icon = ({ name, size = 20, className = "", strokeWidth = 2 }) => {
const ref = React.useRef(null);
React.useEffect(() => { if (ref.current) { const existing = ref.current.querySelector('svg'); if (existing) existing.remove(); const svg = lucide.createElement(lucide.icons[name]); if (svg) { svg.setAttribute('width',size); svg.setAttribute('height',size); svg.setAttribute('stroke-width',strokeWidth); ref.current.appendChild(svg); } } }, [name, size, className, strokeWidth]);
return <span ref={ref} className={`inline-flex items-center justify-center ${className}`} style={{ width: size, height: size }} />;
};
const navItems = [
{ name: 'Dashboard', icon: 'layout-dashboard', href: 'dashboard.html' },
{ name: 'Generator', icon: 'sparkles', href: 'generator.html' },
{ name: 'Playground', icon: 'code', href: 'playground.html' },
{ name: 'Models', icon: 'box', href: 'models.html', active: true },
{ name: 'Workflows', icon: 'workflow', href: 'workflows.html' },
{ name: 'Marketplace', icon: 'shopping-bag', href: 'marketplace.html' },
{ name: 'API Keys', icon: 'key', href: 'api-keys.html' },
{ divider: true },
{ name: 'Profile', icon: 'user', href: 'profile.html' },
{ name: 'Settings', icon: 'settings', href: 'settings.html' },
];
const Sidebar = ({ isOpen, setIsOpen }) => (
<>
<div className={`fixed inset-0 z-40 lg:hidden transition-all ${isOpen ? 'opacity-100 pointer-events-auto' : 'opacity-0 pointer-events-none'}`}>
<div className="absolute inset-0 bg-black/60 backdrop-blur-sm" onClick={() => setIsOpen(false)} />
</div>
<aside className={`fixed top-0 left-0 bottom-0 z-50 w-64 bg-surface border-r border-border flex flex-col transition-transform duration-300 lg:translate-x-0 ${isOpen ? 'translate-x-0' : '-translate-x-full'}`}>
<div className="p-4 flex items-center gap-2.5 border-b border-border"><div className="w-8 h-8 rounded-lg bg-primary flex items-center justify-center"><Icon name="sparkles" size={16} className="text-primary-foreground" /></div><span className="text-lg font-bold tracking-tight">NSFW<span className="text-muted">Studio</span></span></div>
<nav className="flex-1 p-3 space-y-1 overflow-y-auto no-scrollbar">{navItems.map((item, i) => item.divider ? <div key={i} className="my-3 border-t border-border" /> : <a key={i} href={item.href} className={`flex items-center gap-3 px-3 py-2.5 rounded-xl text-sm font-medium transition-colors ${item.active ? 'bg-primary/10 text-primary border border-primary/20' : 'text-muted hover:text-fg hover:bg-surface-2 border border-transparent'}`}><Icon name={item.icon} size={18} />{item.name}</a>)}</nav>
<div className="p-4 border-t border-border"><a href="#" className="flex items-center gap-3 px-3 py-2.5 rounded-xl text-sm text-muted hover:text-fg hover:bg-surface-2 transition-colors"><Icon name="book-open" size={18} />Documentation</a><a href="#" className="flex items-center gap-3 px-3 py-2.5 rounded-xl text-sm text-muted hover:text-fg hover:bg-surface-2 transition-colors"><Icon name="file-code" size={18} />API Reference</a></div>
</aside>
</>
);
const App = () => {
const [sidebarOpen, setSidebarOpen] = useState(false);
const [activeTab, setActiveTab] = useState('my-models');
const myModels = [
{ name: 'EroticDream XL', type: 'NSFW Image Generation', status: 'published', runs: '45.2K', rating: 4.9, revenue: '$2,340', updated: '2 days ago', img: 'http://static.photos/cyberpunk/400x300/20', desc: 'Ultra-realistic erotic art model with advanced anatomy and lighting' },
{ name: 'DarkSeduction v3', type: 'Fantasy Erotic', status: 'published', runs: '28.1K', rating: 4.8, revenue: '$1,890', updated: '1 week ago', img: 'http://static.photos/red/400x300/21', desc: 'Dark fantasy and fetish art with stunning detail and mood' },
{ name: 'MorphX Body v2', type: 'Body Morph', status: 'draft', runs: '0', rating: '-', revenue: '$0', updated: '3 days ago', img: 'http://static.photos/abstract/400x300/22', desc: 'Advanced body transformation and morphing model' },
{ name: 'Pleasure Enhance Pro', type: 'Upscaling', status: 'review', runs: '12.8K', rating: 4.7, revenue: '$890', updated: '5 days ago', img: 'http://static.photos/nature/400x300/23', desc: '4K upscaling optimized for adult content with detail recovery' },
];
const exploreModels = [
{ name: 'SinfulAnime XL', type: 'Hentai / Anime', author: '@velvet_sin', runs: '52K', rating: 4.9, price: '$7.99', img: 'http://static.photos/people/400x300/24' },
{ name: 'PhotoReal Erotica', type: 'Photorealistic', author: '@kink_architect', runs: '67K', rating: 4.9, price: '$14.99', img: 'http://static.photos/travel/400x300/25' },
{ name: 'Fantasy Flesh XL', type: 'Fantasy / Furry', author: '@fantasy_weaver', runs: '19.4K', rating: 4.8, price: '$5.99', img: 'http://static.photos/nature/400x300/26' },
{ name: 'Ink & Skink', type: 'Tattoo / Alt', author: '@dark_desires', runs: '15.3K', rating: 4.7, price: 'Free', img: 'http://static.photos/minimal/400x300/27' },
{ name: 'FutureBods', type: 'Sci-Fi Body', author: '@cosmic_ai', runs: '8.7K', rating: 4.6, price: '$3.99', img: 'http://static.photos/aerial/400x300/28' },
{ name: 'RetroPinup', type: 'Vintage Nude', author: '@retro_vibes', runs: '22.1K', rating: 4.8, price: 'Free', img: 'http://static.photos/vintage/400x300/29' },
];
const statusColors = { published: 'bg-success/10 text-success border-success/20', draft: 'bg-muted/10 text-muted border-border', review: 'bg-accent/10 text-accent border-accent/20' };
return (
<div className="min-h-screen bg-bg">
<Sidebar isOpen={sidebarOpen} setIsOpen={setSidebarOpen} />
<div className="lg:ml-64">
<header className="sticky top-0 z-30 glass border-b border-border">
<div className="flex items-center justify-between px-4 sm:px-6 h-16">
<div className="flex items-center gap-4">
<button onClick={() => setSidebarOpen(true)} className="lg:hidden p-2 rounded-lg hover:bg-surface-2 text-muted"><Icon name="menu" size={20} /></button>
<h1 className="text-xl font-bold">Models</h1>
</div>
<div className="flex items-center gap-3">
<div className="hidden sm:flex items-center gap-2 px-3 py-2 rounded-xl bg-surface-2 border border-border text-muted text-sm w-56"><Icon name="search" size={16} /><span>Search models...</span></div>
<a href="#" className="px-4 py-2 rounded-lg bg-primary text-primary-foreground text-sm font-semibold hover:brightness-110 transition-all hover:scale-105 shadow-lg shadow-primary/20 flex items-center gap-2"><Icon name="plus" size={16} />Train Model</a>
<a href="profile.html" className="w-9 h-9 rounded-lg overflow-hidden border border-border"><img src="http://static.photos/people/100x100/10" alt="" className="w-full h-full object-cover" /></a>
</div>
</div>
</header>
<main className="p-4 sm:p-6 lg:p-8">
<div className="flex items-center gap-2 mb-6 border-b border-border">
{[{ id: 'my-models', label: 'My Models' }, { id: 'explore', label: 'Explore' }, { id: 'training', label: 'Training' }].map(t => (
<button key={t.id} onClick={() => setActiveTab(t.id)} className={`px-4 py-3 border-b-2 text-sm font-semibold transition-all duration-300 -mb-px ${activeTab === t.id ? 'border-primary text-primary' : 'border-transparent text-muted hover:text-fg'}`}>{t.label}</button>
))}
</div>
{activeTab === 'my-models' && (
<div className="space-y-4">
{myModels.map((m, i) => (
<div key={i} className="group rounded-2xl bg-surface border border-border hover:border-primary/30 transition-all duration-500 overflow-hidden card-3d gradient-border-animated">
<div className="flex flex-col sm:flex-row">
<div className="sm:w-48 h-32 sm:h-auto shrink-0 overflow-hidden">
<img src={m.img} alt={m.name} className="w-full h-full object-cover group-hover:scale-110 transition-transform duration-700" />
</div>
<div className="flex-1 p-5">
<div className="flex items-start justify-between gap-3 mb-3">
<div>
<div className="flex items-center gap-2 mb-1">
<h3 className="font-bold text-fg group-hover:text-primary transition-colors duration-300">{m.name}</h3>
<span className={`px-2.5 py-0.5 rounded-full text-xs font-bold border ${statusColors[m.status]}`}>{m.status}</span>
</div>
<p className="text-sm text-muted">{m.type}</p>
<p className="text-xs text-muted/70 mt-1">{m.desc}</p>
</div>
<div className="text-right">
<div className="text-lg font-bold text-fg tabular-nums">{m.revenue}</div>
<div className="text-xs text-muted">Revenue</div>
</div>
</div>
<div className="flex items-center gap-6 text-sm text-muted">
<span className="flex items-center gap-1"><Icon name="play" size={14} />{m.runs} runs</span>
<span className="flex items-center gap-1"><Icon name="star" size={14} className="text-accent" />{m.rating}</span>
<span className="flex items-center gap-1"><Icon name="clock" size={14} />{m.updated}</span>
</div>
<div className="flex items-center gap-2 mt-4">
<button className="px-3 py-1.5 rounded-lg bg-primary text-primary-foreground text-sm font-semibold hover:brightness-110 transition-all duration-200 hover:scale-105">Manage</button>
<button className="px-3 py-1.5 rounded-lg border border-border text-sm text-muted hover:text-fg hover:bg-surface-2 transition-all duration-200">Analytics</button>
<button className="px-3 py-1.5 rounded-lg border border-border text-sm text-muted hover:text-fg hover:bg-surface-2 transition-all duration-200">Edit</button>
</div>
</div>
</div>
</div>
))}
</div>
)}
{activeTab === 'explore' && (
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
{exploreModels.map((m, i) => (
<div key={i} className="group rounded-2xl bg-surface border border-border hover:border-primary/30 overflow-hidden transition-all duration-500 hover:-translate-y-2 hover:shadow-2xl hover:shadow-primary/10 card-3d shine gradient-border-animated">
<div className="aspect-[4/3] overflow-hidden relative">
<img src={m.img} alt={m.name} className="w-full h-full object-cover group-hover:scale-110 transition-transform duration-700" />
<div className="absolute inset-0 bg-gradient-to-t from-black/70 to-transparent" />
<span className="absolute top-3 right-3 px-2.5 py-1 rounded-lg bg-black/50 backdrop-blur-sm text-xs font-bold border border-white/10">{m.type}</span>
</div>
<div className="p-4">
<div className="flex items-start justify-between mb-2">
<div>
<h3 className="font-bold text-fg group-hover:text-primary transition-colors duration-300">{m.name}</h3>
<p className="text-xs text-muted">{m.author}</p>
</div>
<span className="text-sm font-bold text-primary">{m.price}</span>
</div>
<div className="flex items-center gap-4 text-xs text-muted">
<span className="flex items-center gap-1"><Icon name="star" size={12} className="text-accent" />{m.rating}</span>
<span className="flex items-center gap-1"><Icon name="download" size={12} />{m.runs}</span>
</div>
</div>
</div>
))}
</div>
)}
{activeTab === 'training' && (
<div className="text-center py-16">
<div className="w-20 h-20 rounded-2xl bg-primary/10 flex items-center justify-center mx-auto mb-4 hover-lift"><Icon name="cpu" size={32} className="text-primary" /></div>
<h2 className="text-xl font-bold mb-2">No Active Training</h2>
<p className="text-muted mb-6 max-w-md mx-auto">Start training a new model by uploading your dataset and configuring your training parameters.</p>
<a href="#" className="inline-flex items-center gap-2 px-6 py-3 rounded-xl bg-primary text-primary-foreground font-bold hover:brightness-110 transition-all duration-300 hover:scale-105 shadow-lg shadow-primary/20"><Icon name="plus" size={18} />Start Training</a>
</div>
)}
</main>
</div>
</div>
);
};
ReactDOM.createRoot(document.getElementById('root')).render(<App />);
</script>
</body>
</html>