Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>AI Studio - CharacterVerse Nexus</title> | |
| <link rel="icon" type="image/x-icon" href="/static/favicon.ico"> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script> | |
| <script src="https://unpkg.com/feather-icons"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/animejs/lib/anime.iife.min.js"></script> | |
| <style> | |
| @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap'); | |
| body { | |
| font-family: 'Inter', sans-serif; | |
| } | |
| .sidebar { | |
| transition: all 0.3s ease; | |
| } | |
| @media (max-width: 768px) { | |
| .sidebar { | |
| transform: translateX(-100%); | |
| } | |
| .sidebar.open { | |
| transform: translateX(0); | |
| } | |
| } | |
| .glass-card { | |
| backdrop-filter: blur(16px) saturate(180%); | |
| -webkit-backdrop-filter: blur(16px) saturate(180%); | |
| background-color: rgba(255, 255, 255, 0.75); | |
| border-radius: 12px; | |
| border: 1px solid rgba(209, 213, 219, 0.3); | |
| } | |
| .gradient-text { | |
| background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); | |
| -webkit-background-clip: text; | |
| -webkit-text-fill-color: transparent; | |
| background-clip: text; | |
| } | |
| .context-preview { | |
| max-height: 200px; | |
| overflow-y: auto; | |
| font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace; | |
| font-size: 0.875rem; | |
| } | |
| .job-status { | |
| transition: all 0.3s ease; | |
| } | |
| .job-status.queued { color: #f59e0b; } | |
| .job-status.running { color: #3b82f6; } | |
| .job-status.succeeded { color: #10b981; } | |
| .job-status.failed { color: #ef4444; } | |
| .generation-card { | |
| transition: all 0.3s ease; | |
| border: 1px solid rgba(209, 213, 219, 0.3); | |
| } | |
| .generation-card:hover { | |
| transform: translateY(-2px); | |
| box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); | |
| } | |
| </style> | |
| </head> | |
| <body class="bg-gray-50 min-h-screen"> | |
| <!-- Mobile Menu Button --> | |
| <div class="md:hidden fixed top-4 left-4 z-50"> | |
| <button id="menuToggle" class="bg-white p-2 rounded-lg shadow-lg"> | |
| <i data-feather="menu" class="h-6 w-6 text-gray-700"></i> | |
| </button> | |
| </div> | |
| <!-- Sidebar --> | |
| <div id="sidebar" class="sidebar fixed inset-y-0 left-0 z-40 w-64 bg-white shadow-xl"> | |
| <div class="flex flex-col h-full"> | |
| <!-- Logo --> | |
| <div class="flex items-center justify-center h-16 border-b border-gray-200"> | |
| <i data-feather="users" class="h-8 w-8 text-purple-600"></i> | |
| <span class="ml-2 text-xl font-bold gradient-text">CharacterVerse Nexus</span> | |
| </div> | |
| <!-- Navigation --> | |
| <nav class="flex-1 px-4 py-6 space-y-2"> | |
| <a href="dashboard.html" class="flex items-center px-4 py-3 text-gray-700 hover:bg-gray-100 rounded-lg"> | |
| <i data-feather="home" class="h-5 w-5 mr-3"></i> | |
| Dashboard | |
| </a> | |
| <a href="characters.html" class="flex items-center px-4 py-3 text-gray-700 hover:bg-gray-100 rounded-lg"> | |
| <i data-feather="user" class="h-5 w-5 mr-3"></i> | |
| Characters | |
| </a> | |
| <a href="relationships.html" class="flex items-center px-4 py-3 text-gray-700 hover:bg-gray-100 rounded-lg"> | |
| <i data-feather="git-branch" class="h-5 w-5 mr-3"></i> | |
| Relationships | |
| </a> | |
| <a href="timeline.html" class="flex items-center px-4 py-3 text-gray-700 hover:bg-gray-100 rounded-lg"> | |
| <i data-feather="calendar" class="h-5 w-5 mr-3"></i> | |
| Timeline | |
| </a> | |
| <a href="ai-studio.html" class="flex items-center px-4 py-3 text-purple-600 bg-purple-50 rounded-lg"> | |
| <i data-feather="zap" class="h-5 w-5 mr-3"></i> | |
| AI Studio | |
| </a> | |
| <a href="search.html" class="flex items-center px-4 py-3 text-gray-700 hover:bg-gray-100 rounded-lg"> | |
| <i data-feather="search" class="h-5 w-5 mr-3"></i> | |
| Search | |
| </a> | |
| </nav> | |
| <!-- User Section --> | |
| <div class="border-t border-gray-200 p-4"> | |
| <div class="flex items-center"> | |
| <img src="http://static.photos/people/200x200/1" alt="User" class="h-8 w-8 rounded-full"> | |
| <div class="ml-3"> | |
| <p class="text-sm font-medium text-gray-900">Sarah Writer</p> | |
| <p class="text-xs text-gray-500">sarah@example.com</p> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Main Content --> | |
| <div class="md:ml-64"> | |
| <!-- Header --> | |
| <header class="bg-white shadow-sm border-b border-gray-200"> | |
| <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> | |
| <div class="flex justify-between items-center h-16"> | |
| <div> | |
| <h1 class="text-2xl font-bold text-gray-900">AI Studio</h1> | |
| <p class="text-gray-600">Generate consistent text and images using deterministic context packs</p> | |
| </div> | |
| <div class="flex items-center space-x-4"> | |
| <div class="text-sm text-gray-600"> | |
| <span class="font-medium">Tokens remaining:</span> 8,542 | |
| </div> | |
| </div> | |
| </div> | |
| </header> | |
| <!-- Main Content Area --> | |
| <main class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8"> | |
| <!-- Generation Interface --> | |
| <div class="grid grid-cols-1 lg:grid-cols-3 gap-8 mb-8"> | |
| <!-- Left Panel: Context Selection --> | |
| <div class="lg:col-span-1"> | |
| <div class="glass-card p-6 mb-6"> | |
| <h2 class="text-xl font-semibold text-gray-900 mb-4">Context Selection</h2> | |
| <!-- Character Selection --> | |
| <div class="mb-4"> | |
| <h3 class="font-medium text-gray-900 mb-2">Characters</h3> | |
| <div class="space-y-2 max-h-40 overflow-y-auto"> | |
| <div class="flex items-center"> | |
| <input type="checkbox" id="char-elara" class="rounded text-purple-600 focus:ring-purple-600"> | |
| <label for="char-elara" class="ml-2 text-sm text-gray-700">Elara (Protagonist)</label> | |
| </div> | |
| <div class="flex items-center"> | |
| <input type="checkbox" id="char-kaelen" class="rounded text-purple-600 focus:ring-purple-600" checked> | |
| <label for="char-kaelen" class="ml-2 text-sm text-gray-700">Kaelen (Mentor)</label> | |
| </div> | |
| <div class="flex items-center"> | |
| <input type="checkbox" id="char-malachi" class="rounded text-purple-600 focus:ring-purple-600" checked> | |
| <label for="char-malachi" class="ml-2 text-sm text-gray-700">Malachi (Antagonist)</label> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Relationship Neighborhood --> | |
| <div class="mb-4"> | |
| <h3 class="font-medium text-gray-900 mb-2">Relationship Scope</h3> | |
| <select class="w-full p-2 border border-gray-300 rounded-lg focus:ring-purple-600 focus:border-purple-600"> | |
| <option>1-hop neighborhood (selected + direct)</option> | |
| <option selected>2-hop neighborhood (selected + direct + indirect)</option> | |
| </select> | |
| </div> | |
| <!-- Timeline Beats --> | |
| <div class="mb-4"> | |
| <h3 class="font-medium text-gray-900 mb-2">Timeline Context</option> | |
| <select class="w-full p-2 border border-gray-300 rounded-lg focus:ring-purple-600 focus:border-purple-600"> | |
| <option selected>Latest 3 beats</option> | |
| <option>All beats in current arc</option> | |
| <option>Top 5 relevant beats</option> | |
| </select> | |
| </div> | |
| <!-- Style Guides --> | |
| <div> | |
| <h3 class="font-medium text-gray-900 mb-2">Style & Tone</option> | |
| <select class="w-full p-2 border border-gray-300 rounded-lg focus:ring-purple-600 focus:border-purple-600"> | |
| <option selected>Epic Fantasy</option> | |
| <option>Noir Detective</option> | |
| <option>Sci-Fi Cyberpunk</option> | |
| </select> | |
| </div> | |
| </div> | |
| <!-- Center Panel: Generation Input --> | |
| <div class="lg:col-span-2"> | |
| <div class="glass-card p-6 mb-6"> | |
| <h2 class="text-xl font-semibold text-gray-900 mb-4">Generation Request</h2> | |
| <!-- Generation Type --> | |
| <div class="grid grid-cols-2 gap-4 mb-4"> | |
| <button id="textGenBtn" class="bg-purple-600 text-white p-4 rounded-lg hover:bg-purple-700 transition-colors font-semibold"> | |
| <i data-feather="file-text" class="h-5 w-5 inline mr-2"></i> | |
| Text Generation | |
| </button> | |
| <button id="imageGenBtn" class="bg-white border border-gray-300 text-gray-700 p-4 rounded-lg hover:bg-gray-50 transition-colors font-semibold"> | |
| <i data-feather="image" class="h-5 w-5 inline mr-2"></i> | |
| Image Generation | |
| </button> | |
| </div> | |
| <!-- Prompt Input --> | |
| <div class="mb-4"> | |
| <label class="block text-sm font-medium text-gray-700 mb-2">Your Prompt</label> | |
| <textarea id="userPrompt" class="w-full h-32 p-3 border border-gray-300 rounded-lg focus:ring-purple-600 focus:border-purple-600" placeholder="Describe what you want to generate...">Write a tense dialogue scene between Kaelen and Malachi where they confront each other about the ancient prophecy.</textarea> | |
| </div> | |
| <!-- Context Preview --> | |
| <div class="mb-4"> | |
| <div class="flex justify-between items-center mb-2"> | |
| <label class="block text-sm font-medium text-gray-700">Context Pack Preview</label> | |
| <button id="togglePreview" class="text-sm text-purple-600 hover:text-purple-700">Show/Hide</button> | |
| </div> | |
| <div id="contextPreview" class="context-preview bg-gray-100 p-3 rounded-lg border"> | |
| <pre class="text-xs">{ | |
| "project_id": "proj_123", | |
| "user_prompt": "Write a tense dialogue scene...", | |
| "characters": [ | |
| { | |
| "id": "char_789", | |
| "name": "Kaelen", | |
| "spec": { | |
| "traits": ["wise", "patient", "protective"], | |
| "voice": {"pitch": "calm", "pace": "measured"} | |
| }, | |
| { | |
| "id": "char_456", | |
| "name": "Malachi", | |
| "spec": { | |
| "traits": ["ambitious", "deceptive", "power-hungry"], | |
| "voice": {"pitch": "sharp", "pace": "urgent"} | |
| } | |
| ], | |
| "relationships": [ | |
| { | |
| "a": "char_789", | |
| "b": "char_456", | |
| "type": "rivals", | |
| "direction": "bidirectional", | |
| "confidence": 0.9 | |
| } | |
| ], | |
| "beats": [ | |
| { | |
| "id": "beat_123", | |
| "order_index": 3, | |
| "snippet": "The prophecy foretells of a great conflict..." | |
| } | |
| ], | |
| "style_guides": [ | |
| { | |
| "name": "Epic Fantasy", | |
| "rules": ["formal language", "archaic terms", "epic scale"] | |
| } | |
| ] | |
| }</pre> | |
| </div> | |
| </div> | |
| <!-- Generation Controls --> | |
| <div class="flex justify-between items-center"> | |
| <div class="text-sm text-gray-600"> | |
| <span class="font-medium">Estimated tokens:</span> 1,200 | |
| </div> | |
| <button id="generateBtn" class="bg-purple-600 text-white px-6 py-3 rounded-lg hover:bg-purple-700 transition-colors font-semibold"> | |
| <i data-feather="zap" class="h-4 w-4 inline mr-2"></i> | |
| Generate Content | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Active Jobs --> | |
| <div class="glass-card p-6 mb-8"> | |
| <h2 class="text-xl font-semibold text-gray-900 mb-4">Active Jobs</h2> | |
| <div class="space-y-3"> | |
| <div class="flex items-center justify-between p-3 bg-gray-50 rounded-lg"> | |
| <div class="flex items-center space-x-3"> | |
| <div class="w-3 h-3 bg-yellow-400 rounded-full animate-pulse"></div> | |
| <div class="flex-1"> | |
| <p class="text-sm font-medium text-gray-900">Text Generation: Dialogue Scene</p> | |
| <p class="text-xs text-gray-500">Queued - Estimated wait: 15s</p> | |
| </div> | |
| <div class="text-xs job-status running">Running</p> | |
| </div> | |
| </div> | |
| <div class="flex items-center justify-between p-3 bg-gray-50 rounded-lg"> | |
| <div class="flex items-center space-x-3"> | |
| <div class="w-3 h-3 bg-green-400 rounded-full"></div> | |
| <div class="flex-1"> | |
| <p class="text-sm font-medium text-gray-900">Image Generation: Malachi Portrait</p> | |
| <p class="text-xs text-gray-500">Succeeded - 45s</p> | |
| </div> | |
| <button class="text-sm text-purple-600 hover:text-purple-700">View Output</button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Recent Generations --> | |
| <div class="glass-card p-6"> | |
| <h2 class="text-xl font-semibold text-gray-900 mb-6">Recent Generations</h2> | |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-6"> | |
| <!-- Generation 1 --> | |
| <div class="generation-card bg-white rounded-xl p-6 shadow-sm"> | |
| <div class="flex items-center justify-between mb-3"> | |
| <span class="px-2 py-1 bg-purple-100 text-purple-800 text-xs rounded-full">Text</span> | |
| <span class="text-xs text-gray-500">2 hours ago</span> | |
| </div> | |
| <h3 class="font-medium text-gray-900 mb-2">Dialogue Scene</h3> | |
| <p class="text-sm text-gray-600 mb-3">Write a tense dialogue scene between Kaelen and Malachi...</p> | |
| <div class="flex items-center justify-between text-sm"> | |
| <span class="text-gray-600">1,234 tokens</span> | |
| <a href="character-details.html" class="text-purple-600 hover:text-purple-700 text-sm">View Context & Output</a> | |
| </div> | |
| </div> | |
| <!-- Generation 2 --> | |
| <div class="generation-card bg-white rounded-xl p-6 shadow-sm"> | |
| <div class="flex items-center justify-between mb-3"> | |
| <span class="px-2 py-1 bg-blue-100 text-blue-800 text-xs rounded-full">Image</span> | |
| <span class="text-xs text-gray-500">4 hours ago</span> | |
| </div> | |
| <h3 class="font-medium text-gray-900 mb-2">Character Portrait</span> | |
| <p class="text-sm text-gray-600 mb-3">Generate a dramatic portrait of Malachi in his throne room...</p> | |
| <div class="flex items-center justify-between text-sm"> | |
| <span class="text-gray-600">Stable Diffusion</span> | |
| <a href="character-details.html" class="text-purple-600 hover:text-purple-700 text-sm">View Image</a> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </main> | |
| </div> | |
| <script> | |
| // Mobile menu toggle | |
| document.getElementById('menuToggle').addEventListener('click', function() { | |
| document.getElementById('sidebar').classList.toggle('open'); | |
| }); | |
| // Context preview toggle | |
| document.getElementById('togglePreview').addEventListener('click', function() { | |
| const preview = document.getElementById('contextPreview'); | |
| preview.classList.toggle('hidden'); | |
| }); | |
| // Generation type selection | |
| document.getElementById('textGenBtn').addEventListener('click', function() { | |
| this.classList.add('bg-purple-600', 'text-white'); | |
| this.classList.remove('bg-white', 'border', 'text-gray-700'); | |
| document.getElementById('imageGenBtn').classList.remove('bg-purple-600', 'text-white'); | |
| this.classList.add('bg-white', 'border', 'text-gray-700'); | |
| document.getElementById('imageGenBtn').classList.add('bg-white', 'border', 'text-gray-700'); | |
| }); | |
| document.getElementById('imageGenBtn').addEventListener('click', function() { | |
| this.classList.add('bg-purple-600', 'text-white'); | |
| this.classList.remove('bg-white', 'border', 'text-gray-700'); | |
| document.getElementById('textGenBtn').classList.remove('bg-purple-600', 'text-white'); | |
| this.classList.add('bg-white', 'border', 'text-gray-700'); | |
| document.getElementById('textGenBtn').classList.add('bg-white', 'border', 'text-gray-700'); | |
| }); | |
| // Generate button animation | |
| document.getElementById('generateBtn').addEventListener('click', function() { | |
| anime({ | |
| targets: this, | |
| scale: [1, 0.95, 1], | |
| duration: 200, | |
| easing: 'easeInOutQuad' | |
| }); | |
| // Simulate job submission | |
| setTimeout(() => { | |
| alert('Generation job submitted! Check the Active Jobs section for status.'); | |
| }, 300); | |
| }); | |
| // Initialize Feather Icons | |
| feather.replace(); | |
| </script> | |
| </body> | |
| </html> |