Spaces:
Running
Running
You are an expert-level UI/UX designer and frontend developer specializing in creating intuitive, aesthetically striking, and highly functional web interfaces. You will be using the DeepSite v2 environment. Your task is to generate a complete, single-file index.html for a web application called the "GBStudio Command Deck." This application serves as the primary interface for a human "Director" to manage a team of AI agents (PM, Art, Writing, etc.) in order to build a Game Boy game. You must follow all architectural, functional, and aesthetic instructions precisely. 1. Core Architecture & Libraries File Structure: Generate a single, self-contained index.html file. Libraries (CDN): CSS: Use Pico.css for the base layout and semantic styling. <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css"/> Fonts: Use Google Fonts for "Press Start 2P" and "Inter". <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:wght@400;700&family=Press+Start+2P&display=swap" rel="stylesheet"> 2. Aesthetic & Theming You must implement a "retro-futuristic" dark theme. All styling must be contained within a <style> tag in the <head>. CSS Variables: Define and use the following CSS variables in the :root. :root { --font-heading: 'Press Start 2P', cursive; --font-body: 'Inter', sans-serif; --color-bg: #0D0D0D; --color-surface: #1A1A1A; --color-border: #3A3A3A; --color-text-main: #E0E0E0; --color-text-dim: #888888; --color-accent: #00FF7F; /* Spring Green */ --glow-accent: 0 0 5px var(--color-accent), 0 0 10px var(--color-accent); } General Styling: The body must have background-color: var(--color-bg) and color: var(--color-text-main). All text should use font-family: var(--font-body). Headings (h1, h2, etc.) must use font-family: var(--font-heading) and color: var(--color-accent). Buttons and interactive elements should have a border: 1px solid var(--color-accent) and a box-shadow: var(--glow-accent) on :hover. 3. Layout & Structure The main layout will be a three-column grid. Main Container: A <div class="grid"> will wrap the three columns. Column 1: Department Sidebar (<aside>) A fixed sidebar listing the available AI agents. Contains a heading "DEPARTMENTS". Contains a <ul> list where each <li> is an agent (PM, Art, Writing, Code, QA). Column 2: Main Interaction Panel (<main>) This is the largest panel. It will contain the chat log for the currently selected agent. At the bottom, it will have the main user input form with a <textarea> and a "Send Message" button. Column 3: Controls & Status (<aside>) Contains a heading "STUDIO CONTROLS". Features the main "Integrate & Playtest" button. This button must have an id="playtest-button". Contains a section for "Active Tasks" which will be populated dynamically. 4. Few-Shot Component Examples Use these examples as a blueprint for how to structure and style the components. Shot 1: Department Sidebar Link This example shows how to style a link in the sidebar. It should be clean, with a clear hover state. HTML Structure: <ul id="department-list"> <li><a href="#" class="department-link active" data-agent="PM">Project Manager</a></li> <li><a href="#" class="department-link" data-agent="Art">Art Department</a></li> <!-- etc. --> </ul> CSS Styling: .department-link { display: block; padding: 0.75rem 1rem; margin-bottom: 0.5rem; border: 1px solid var(--color-border); border-radius: 4px; text-decoration: none; color: var(--color-text-dim); transition: all 0.2s ease; } .department-link:hover { color: var(--color-text-main); background-color: var(--color-surface); border-color: var(--color-accent); } .department-link.active { color: var(--color-accent); border-color: var(--color-accent); box-shadow: var(--glow-accent); } Shot 2: Chat Message This example shows how to structure a single message in the chat log. The JavaScript should dynamically generate these elements. HTML Structure (Agent Message): <article class="chat-message agent"> <header>Art Director</header> <p>Understood. Generating a creative prompt for a 'goblin warrior' sprite sheet now.</p> <footer><time>1:58 AM</time></footer> </article> HTML Structure (User Message): <article class="chat-message user"> <header>Director (You)</header> <p>I need a 16x16 sprite sheet for a goblin warrior.</p> <footer><time>1:57 AM</time></footer> </article> CSS Styling: .chat-message { padding: 1rem; margin-bottom: 1rem; border: 1px solid var(--color-border); border-radius: 8px; background-color: var(--color-surface); } .chat-message.user { border-left: 4px solid var(--color-accent); } .chat-message header { font-family: var(--font-heading); font-size: 0.8rem; color: var(--color-accent); margin-bottom: 0.5rem; } .chat-message.user header { color: var(--color-text-dim); } .chat-message footer { font-size: 0.7rem; color: var(--color-text-dim); text-align: right; } 5. Functional Requirements (JavaScript) The <script> tag should contain all application logic. State Management: Create a simple state object const App = { selectedAgent: 'PM', chatHistory: {} };. Agent Selection: Clicking a link in the Department Sidebar should update App.selectedAgent, add the .active class to the clicked link, and render the correct chat history from App.chatHistory. Chat Submission: Sending a message should: Create a "user" message and add it to the DOM. Make a fetch call to the backend at /api/v1/chat/{agent_name}, where {agent_name} is App.selectedAgent. Display a "typing..." indicator. When the response is received, display the agent's message in the chat log. Integrate & Playtest Button: The button with id="playtest-button" should be disabled by default. When clicked, it should change its text to "Integrating..." and become disabled. It must make a POST request to /api/v1/integrate_and_playtest. On success, it should briefly show "Success!" before reverting to its original state. On error, it should show "Error!" and log the error to the console. Final Task Generate the complete index.html file that fulfills all of the above requirements. Ensure the HTML is semantic, the CSS is well-structured using the provided variables, and the JavaScript is clean and implements all specified functionality. - Initial Deployment
6cabb57 verified | <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>GBStudio Command Deck</title> | |
| <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css"/> | |
| <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:wght@400;700&family=Press+Start+2P&display=swap" rel="stylesheet"> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <style> | |
| :root { | |
| --font-heading: 'Press Start 2P', cursive; | |
| --font-body: 'Inter', sans-serif; | |
| --color-bg: #0D0D0D; | |
| --color-surface: #1A1A1A; | |
| --color-border: #3A3A3A; | |
| --color-text-main: #E0E0E0; | |
| --color-text-dim: #888888; | |
| --color-accent: #00FF7F; /* Spring Green */ | |
| --glow-accent: 0 0 5px var(--color-accent), 0 0 10px var(--color-accent); | |
| --color-secondary: #FF00FF; /* Magenta */ | |
| --color-tertiary: #00FFFF; /* Cyan */ | |
| } | |
| body { | |
| background-color: var(--color-bg); | |
| color: var(--color-text-main); | |
| font-family: var(--font-body); | |
| overflow-x: hidden; | |
| position: relative; | |
| } | |
| body::before { | |
| content: ""; | |
| position: fixed; | |
| top: 0; | |
| left: 0; | |
| width: 100%; | |
| height: 100%; | |
| background-image: | |
| radial-gradient(circle at 10% 20%, rgba(0, 255, 127, 0.05) 0%, transparent 20%), | |
| radial-gradient(circle at 90% 80%, rgba(255, 0, 255, 0.05) 0%, transparent 20%), | |
| radial-gradient(circle at 50% 50%, rgba(0, 0, 0, 0.8) 0%, transparent 50%); | |
| pointer-events: none; | |
| z-index: -1; | |
| } | |
| h1, h2, h3, h4, h5, h6 { | |
| font-family: var(--font-heading); | |
| color: var(--color-accent); | |
| text-transform: uppercase; | |
| letter-spacing: 1px; | |
| } | |
| .grid { | |
| display: grid; | |
| grid-template-columns: 250px 1fr 300px; | |
| gap: 1.5rem; | |
| height: 100vh; | |
| padding: 1.5rem; | |
| } | |
| @media (max-width: 1024px) { | |
| .grid { | |
| grid-template-columns: 200px 1fr 250px; | |
| } | |
| } | |
| @media (max-width: 768px) { | |
| .grid { | |
| grid-template-columns: 1fr; | |
| grid-template-rows: auto 1fr auto; | |
| } | |
| } | |
| aside { | |
| background-color: rgba(26, 26, 26, 0.8); | |
| border: 1px solid var(--color-border); | |
| border-radius: 8px; | |
| padding: 1rem; | |
| backdrop-filter: blur(5px); | |
| box-shadow: 0 0 15px rgba(0, 0, 0, 0.5); | |
| } | |
| main { | |
| background-color: rgba(26, 26, 26, 0.8); | |
| border: 1px solid var(--color-border); | |
| border-radius: 8px; | |
| padding: 1rem; | |
| display: flex; | |
| flex-direction: column; | |
| backdrop-filter: blur(5px); | |
| box-shadow: 0 0 15px rgba(0, 0, 0, 0.5); | |
| } | |
| .department-link { | |
| display: block; | |
| padding: 0.75rem 1rem; | |
| margin-bottom: 0.5rem; | |
| border: 1px solid var(--color-border); | |
| border-radius: 4px; | |
| text-decoration: none; | |
| color: var(--color-text-dim); | |
| transition: all 0.2s ease; | |
| font-size: 0.9rem; | |
| position: relative; | |
| overflow: hidden; | |
| } | |
| .department-link:hover { | |
| color: var(--color-text-main); | |
| background-color: var(--color-surface); | |
| border-color: var(--color-accent); | |
| } | |
| .department-link.active { | |
| color: var(--color-accent); | |
| border-color: var(--color-accent); | |
| box-shadow: var(--glow-accent); | |
| } | |
| .department-link::before { | |
| content: ""; | |
| position: absolute; | |
| top: 0; | |
| left: -100%; | |
| width: 100%; | |
| height: 100%; | |
| background: linear-gradient(90deg, transparent, rgba(0, 255, 127, 0.2), transparent); | |
| transition: 0.5s; | |
| } | |
| .department-link:hover::before { | |
| left: 100%; | |
| } | |
| .chat-message { | |
| padding: 1rem; | |
| margin-bottom: 1rem; | |
| border: 1px solid var(--color-border); | |
| border-radius: 8px; | |
| background-color: var(--color-surface); | |
| position: relative; | |
| animation: fadeIn 0.3s ease; | |
| } | |
| @keyframes fadeIn { | |
| from { opacity: 0; transform: translateY(10px); } | |
| to { opacity: 1; transform: translateY(0); } | |
| } | |
| .chat-message.user { | |
| border-left: 4px solid var(--color-accent); | |
| } | |
| .chat-message.agent { | |
| border-left: 4px solid var(--color-secondary); | |
| } | |
| .chat-message header { | |
| font-family: var(--font-heading); | |
| font-size: 0.8rem; | |
| color: var(--color-accent); | |
| margin-bottom: 0.5rem; | |
| display: flex; | |
| align-items: center; | |
| } | |
| .chat-message.user header { | |
| color: var(--color-text-dim); | |
| } | |
| .chat-message.agent header { | |
| color: var(--color-secondary); | |
| } | |
| .chat-message footer { | |
| font-size: 0.7rem; | |
| color: var(--color-text-dim); | |
| text-align: right; | |
| } | |
| .agent-icon { | |
| width: 24px; | |
| height: 24px; | |
| margin-right: 8px; | |
| background-color: var(--color-secondary); | |
| border-radius: 4px; | |
| display: inline-flex; | |
| align-items: center; | |
| justify-content: center; | |
| font-size: 12px; | |
| font-family: var(--font-heading); | |
| } | |
| .user-icon { | |
| width: 24px; | |
| height: 24px; | |
| margin-right: 8px; | |
| background-color: var(--color-accent); | |
| border-radius: 4px; | |
| display: inline-flex; | |
| align-items: center; | |
| justify-content: center; | |
| font-size: 12px; | |
| font-family: var(--font-heading); | |
| } | |
| #chat-log { | |
| flex-grow: 1; | |
| overflow-y: auto; | |
| padding: 1rem; | |
| display: flex; | |
| flex-direction: column; | |
| gap: 1rem; | |
| } | |
| #chat-form { | |
| display: flex; | |
| gap: 0.5rem; | |
| padding: 1rem; | |
| border-top: 1px solid var(--color-border); | |
| } | |
| #message-input { | |
| flex-grow: 1; | |
| background-color: var(--color-surface); | |
| border: 1px solid var(--color-border); | |
| color: var(--color-text-main); | |
| padding: 0.75rem; | |
| border-radius: 4px; | |
| font-family: var(--font-body); | |
| resize: none; | |
| height: 80px; | |
| } | |
| #message-input:focus { | |
| outline: none; | |
| border-color: var(--color-accent); | |
| box-shadow: var(--glow-accent); | |
| } | |
| button { | |
| background-color: transparent; | |
| border: 1px solid var(--color-accent); | |
| color: var(--color-accent); | |
| padding: 0.75rem 1.5rem; | |
| border-radius: 4px; | |
| cursor: pointer; | |
| transition: all 0.2s ease; | |
| font-family: var(--font-body); | |
| text-transform: uppercase; | |
| font-weight: bold; | |
| letter-spacing: 0.5px; | |
| } | |
| button:hover { | |
| background-color: var(--color-accent); | |
| color: var(--color-bg); | |
| box-shadow: var(--glow-accent); | |
| } | |
| button:disabled { | |
| opacity: 0.5; | |
| cursor: not-allowed; | |
| } | |
| #playtest-button { | |
| width: 100%; | |
| padding: 1rem; | |
| font-size: 1rem; | |
| margin-bottom: 1rem; | |
| position: relative; | |
| overflow: hidden; | |
| } | |
| #playtest-button::after { | |
| content: ""; | |
| position: absolute; | |
| top: 0; | |
| left: -100%; | |
| width: 100%; | |
| height: 100%; | |
| background: linear-gradient(90deg, transparent, rgba(0, 255, 127, 0.3), transparent); | |
| transition: 0.5s; | |
| } | |
| #playtest-button:hover::after { | |
| left: 100%; | |
| } | |
| .task-item { | |
| padding: 0.75rem; | |
| margin-bottom: 0.5rem; | |
| background-color: var(--color-surface); | |
| border: 1px solid var(--color-border); | |
| border-radius: 4px; | |
| font-size: 0.85rem; | |
| display: flex; | |
| align-items: center; | |
| } | |
| .task-item::before { | |
| content: "■"; | |
| color: var(--color-secondary); | |
| margin-right: 0.5rem; | |
| font-size: 0.6rem; | |
| } | |
| .status-indicator { | |
| width: 10px; | |
| height: 10px; | |
| border-radius: 50%; | |
| margin-right: 0.5rem; | |
| } | |
| .status-active { | |
| background-color: var(--color-accent); | |
| box-shadow: var(--glow-accent); | |
| } | |
| .status-idle { | |
| background-color: var(--color-text-dim); | |
| } | |
| .pixel-border { | |
| position: relative; | |
| } | |
| .pixel-border::before { | |
| content: ""; | |
| position: absolute; | |
| top: -5px; | |
| left: -5px; | |
| right: -5px; | |
| bottom: -5px; | |
| border: 2px solid var(--color-accent); | |
| border-radius: 4px; | |
| pointer-events: none; | |
| opacity: 0.3; | |
| } | |
| .terminal-text { | |
| font-family: var(--font-heading); | |
| font-size: 0.7rem; | |
| color: var(--color-accent); | |
| text-shadow: 0 0 5px var(--color-accent); | |
| letter-spacing: 1px; | |
| } | |
| .scanlines { | |
| position: fixed; | |
| top: 0; | |
| left: 0; | |
| width: 100%; | |
| height: 100%; | |
| background: linear-gradient(rgba(13, 13, 13, 0.1) 50%, rgba(0, 0, 0, 0.2) 50%); | |
| background-size: 100% 4px; | |
| pointer-events: none; | |
| z-index: 100; | |
| opacity: 0.3; | |
| } | |
| .glow-box { | |
| box-shadow: 0 0 10px rgba(0, 255, 127, 0.3), 0 0 20px rgba(0, 255, 127, 0.1); | |
| } | |
| .typing-indicator { | |
| display: flex; | |
| align-items: center; | |
| padding: 1rem; | |
| background-color: var(--color-surface); | |
| border-radius: 8px; | |
| margin-bottom: 1rem; | |
| border-left: 4px solid var(--color-secondary); | |
| } | |
| .typing-indicator span { | |
| font-family: var(--font-heading); | |
| font-size: 0.8rem; | |
| color: var(--color-secondary); | |
| margin-right: 10px; | |
| } | |
| .typing-dots { | |
| display: flex; | |
| } | |
| .typing-dots div { | |
| width: 8px; | |
| height: 8px; | |
| background-color: var(--color-secondary); | |
| border-radius: 50%; | |
| margin: 0 3px; | |
| animation: typing 1.4s infinite ease-in-out; | |
| } | |
| .typing-dots div:nth-child(1) { animation-delay: 0s; } | |
| .typing-dots div:nth-child(2) { animation-delay: 0.2s; } | |
| .typing-dots div:nth-child(3) { animation-delay: 0.4s; } | |
| @keyframes typing { | |
| 0%, 60%, 100% { transform: translateY(0); } | |
| 30% { transform: translateY(-5px); } | |
| } | |
| .gameboy-frame { | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| width: 100%; | |
| height: 100%; | |
| pointer-events: none; | |
| z-index: 50; | |
| } | |
| .gameboy-frame::before { | |
| content: ""; | |
| position: absolute; | |
| top: 20px; | |
| left: 20px; | |
| right: 20px; | |
| bottom: 20px; | |
| border: 3px solid var(--color-border); | |
| border-radius: 10px; | |
| box-shadow: inset 0 0 20px rgba(0, 0, 0, 0.5); | |
| } | |
| .gameboy-frame::after { | |
| content: "GBStudio Command Deck v2.0"; | |
| position: absolute; | |
| top: 10px; | |
| left: 50%; | |
| transform: translateX(-50%); | |
| color: var(--color-text-dim); | |
| font-family: var(--font-heading); | |
| font-size: 0.6rem; | |
| letter-spacing: 1px; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="scanlines"></div> | |
| <div class="gameboy-frame"></div> | |
| <div class="grid"> | |
| <!-- Department Sidebar --> | |
| <aside class="pixel-border"> | |
| <h2 class="terminal-text">DEPARTMENTS</h2> | |
| <ul id="department-list"> | |
| <li><a href="#" class="department-link active" data-agent="PM"> | |
| <span class="status-indicator status-active"></span> | |
| Project Manager | |
| </a></li> | |
| <li><a href="#" class="department-link" data-agent="Art"> | |
| <span class="status-indicator status-active"></span> | |
| Art Department | |
| </a></li> | |
| <li><a href="#" class="department-link" data-agent="Writing"> | |
| <span class="status-indicator status-active"></span> | |
| Writing Department | |
| </a></li> | |
| <li><a href="#" class="department-link" data-agent="Code"> | |
| <span class="status-indicator status-idle"></span> | |
| Code Department | |
| </a></li> | |
| <li><a href="#" class="department-link" data-agent="QA"> | |
| <span class="status-indicator status-active"></span> | |
| QA Department | |
| </a></li> | |
| <li><a href="#" class="department-link" data-agent="Sound"> | |
| <span class="status-indicator status-idle"></span> | |
| Sound Department | |
| </a></li> | |
| </ul> | |
| <div class="mt-4"> | |
| <h3 class="terminal-text">SYSTEM STATUS</h3> | |
| <div class="task-item">RAM: 87%</div> | |
| <div class="task-item">CPU: 64%</div> | |
| <div class="task-item">NET: 28Mbps</div> | |
| <div class="task-item">AGENTS: 6/8 Active</div> | |
| </div> | |
| </aside> | |
| <!-- Main Interaction Panel --> | |
| <main class="glow-box"> | |
| <div class="flex justify-between items-center mb-4"> | |
| <h2 id="current-agent">Project Manager</h2> | |
| <div class="terminal-text">CONNECTED</div> | |
| </div> | |
| <div id="chat-log"> | |
| <article class="chat-message agent"> | |
| <header><span class="agent-icon">PM</span>Project Manager</header> | |
| <p>Director, I've reviewed the project scope. We're on track for Q3 delivery. The art team needs direction on protagonist design. How should we proceed?</p> | |
| <footer><time>10:45 AM</time></footer> | |
| </article> | |
| <article class="chat-message user"> | |
| <header><span class="user-icon">D</span>Director (You)</header> | |
| <p>Create a 16x16 pixel protagonist with a cyberpunk aesthetic. Primary colors: neon blue and magenta. Should have multiple animation frames.</p> | |
| <footer><time>10:47 AM</time></footer> | |
| </article> | |
| <article class="chat-message agent"> | |
| <header><span class="agent-icon">PM</span>Project Manager</header> | |
| <p>Understood. Task assigned to Art Department. ETA: 2 hours. Writing team is ready for character backstory input.</p> | |
| <footer><time>10:48 AM</time></footer> | |
| </article> | |
| <div class="typing-indicator"> | |
| <span>Art Director is typing</span> | |
| <div class="typing-dots"> | |
| <div></div> | |
| <div></div> | |
| <div></div> | |
| </div> | |
| </div> | |
| </div> | |
| <form id="chat-form"> | |
| <textarea id="message-input" placeholder="Enter command for Project Manager..."></textarea> | |
| <button type="submit">SEND</button> | |
| </form> | |
| </main> | |
| <!-- Controls & Status --> | |
| <aside class="pixel-border"> | |
| <h2 class="terminal-text">STUDIO CONTROLS</h2> | |
| <button id="playtest-button">INTEGRATE & PLAYTEST</button> | |
| <div class="mt-4"> | |
| <h3 class="terminal-text">ACTIVE TASKS</h3> | |
| <div class="task-item">Art: Protagonist sprite sheet</div> | |
| <div class="task-item">Writing: Main character backstory</div> | |
| <div class="task-item">Code: Player movement system</div> | |
| <div class="task-item">QA: Collision detection tests</div> | |
| <div class="task-item">Sound: Main theme composition</div> | |
| </div> | |
| <div class="mt-4"> | |
| <h3 class="terminal-text">PROJECT STATUS</h3> | |
| <div class="task-item">Completion: 42%</div> | |
| <div class="task-item">Issues: 12 open</div> | |
| <div class="task-item">Last Playtest: 3 hours ago</div> | |
| <div class="task-item">Next Milestone: Alpha in 7 days</div> | |
| </div> | |
| <div class="mt-4"> | |
| <h3 class="terminal-text">RESOURCE ALLOCATION</h3> | |
| <div class="task-item">Art: ███████░░░ 70%</div> | |
| <div class="task-item">Code: █████░░░░ 50%</div> | |
| <div class="task-item">Writing: ██████░░░ 60%</div> | |
| <div class="task-item">Sound: ██░░░░░░░ 20%</div> | |
| </div> | |
| </aside> | |
| </div> | |
| <script> | |
| // State management | |
| const App = { | |
| selectedAgent: 'PM', | |
| chatHistory: { | |
| 'PM': [ | |
| { sender: 'agent', name: 'Project Manager', text: 'Director, I\'ve reviewed the project scope. We\'re on track for Q3 delivery. The art team needs direction on protagonist design. How should we proceed?', time: '10:45 AM' }, | |
| { sender: 'user', name: 'Director (You)', text: 'Create a 16x16 pixel protagonist with a cyberpunk aesthetic. Primary colors: neon blue and magenta. Should have multiple animation frames.', time: '10:47 AM' }, | |
| { sender: 'agent', name: 'Project Manager', text: 'Understood. Task assigned to Art Department. ETA: 2 hours. Writing team is ready for character backstory input.', time: '10:48 AM' } | |
| ], | |
| 'Art': [ | |
| { sender: 'agent', name: 'Art Director', text: 'Received task for protagonist design. Any specific references or style guides?', time: '9:30 AM' } | |
| ], | |
| 'Writing': [], | |
| 'Code': [], | |
| 'QA': [], | |
| 'Sound': [] | |
| } | |
| }; | |
| // DOM Elements | |
| const departmentLinks = document.querySelectorAll('.department-link'); | |
| const chatLog = document.getElementById('chat-log'); | |
| const chatForm = document.getElementById('chat-form'); | |
| const messageInput = document.getElementById('message-input'); | |
| const playtestButton = document.getElementById('playtest-button'); | |
| const currentAgent = document.getElementById('current-agent'); | |
| // Initialize the app | |
| function initApp() { | |
| // Set up department link event listeners | |
| departmentLinks.forEach(link => { | |
| link.addEventListener('click', function(e) { | |
| e.preventDefault(); | |
| // Update active link | |
| departmentLinks.forEach(l => l.classList.remove('active')); | |
| this.classList.add('active'); | |
| // Update selected agent | |
| App.selectedAgent = this.getAttribute('data-agent'); | |
| currentAgent.textContent = getAgentName(App.selectedAgent); | |
| // Render chat history for selected agent | |
| renderChatHistory(); | |
| }); | |
| }); | |
| // Set up chat form submission | |
| chatForm.addEventListener('submit', function(e) { | |
| e.preventDefault(); | |
| const message = messageInput.value.trim(); | |
| if (message) { | |
| sendMessage(message); | |
| messageInput.value = ''; | |
| messageInput.focus(); | |
| } | |
| }); | |
| // Set up playtest button | |
| playtestButton.addEventListener('click', function() { | |
| startPlaytest(); | |
| }); | |
| // Initial render | |
| renderChatHistory(); | |
| } | |
| // Get agent name from ID | |
| function getAgentName(agentId) { | |
| const agentNames = { | |
| 'PM': 'Project Manager', | |
| 'Art': 'Art Director', | |
| 'Writing': 'Writing Director', | |
| 'Code': 'Code Director', | |
| 'QA': 'QA Director', | |
| 'Sound': 'Sound Director' | |
| }; | |
| return agentNames[agentId] || agentId; | |
| } | |
| // Render chat history for selected agent | |
| function renderChatHistory() { | |
| chatLog.innerHTML = ''; | |
| const history = App.chatHistory[App.selectedAgent] || []; | |
| history.forEach(msg => { | |
| const messageElement = document.createElement('article'); | |
| messageElement.classList.add('chat-message'); | |
| messageElement.classList.add(msg.sender); | |
| const header = document.createElement('header'); | |
| const icon = document.createElement('span'); | |
| icon.classList.add(msg.sender === 'user' ? 'user-icon' : 'agent-icon'); | |
| icon.textContent = msg.sender === 'user' ? 'D' : App.selectedAgent.charAt(0); | |
| header.appendChild(icon); | |
| header.appendChild(document.createTextNode(msg.name)); | |
| const paragraph = document.createElement('p'); | |
| paragraph.textContent = msg.text; | |
| const footer = document.createElement('footer'); | |
| const time = document.createElement('time'); | |
| time.textContent = msg.time; | |
| footer.appendChild(time); | |
| messageElement.appendChild(header); | |
| messageElement.appendChild(paragraph); | |
| messageElement.appendChild(footer); | |
| chatLog.appendChild(messageElement); | |
| }); | |
| // Scroll to bottom | |
| chatLog.scrollTop = chatLog.scrollHeight; | |
| } | |
| // Send a message | |
| function sendMessage(message) { | |
| // Add user message to history | |
| const timestamp = new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }); | |
| App.chatHistory[App.selectedAgent].push({ | |
| sender: 'user', | |
| name: 'Director (You)', | |
| text: message, | |
| time: timestamp | |
| }); | |
| // Render immediately | |
| renderChatHistory(); | |
| // Show typing indicator | |
| const typingIndicator = document.createElement('div'); | |
| typingIndicator.classList.add('typing-indicator'); | |
| typingIndicator.innerHTML = ` | |
| <span>${getAgentName(App.selectedAgent)} is typing</span> | |
| <div class="typing-dots"> | |
| <div></div> | |
| <div></div> | |
| <div></div> | |
| </div> | |
| `; | |
| chatLog.appendChild(typingIndicator); | |
| chatLog.scrollTop = chatLog.scrollHeight; | |
| // Simulate API call | |
| setTimeout(() => { | |
| // Remove typing indicator | |
| typingIndicator.remove(); | |
| // Add agent response | |
| const responses = [ | |
| "Understood. Task queued for processing.", | |
| "Affirmative. Executing your command now.", | |
| "Processing request... Estimated completion in 15 minutes.", | |
| "Command received. Allocating resources now.", | |
| "Implementing your directive. Stand by for results.", | |
| "Task accepted. Engaging creative modules." | |
| ]; | |
| const randomResponse = responses[Math.floor(Math.random() * responses.length)]; | |
| App.chatHistory[App.selectedAgent].push({ | |
| sender: 'agent', | |
| name: getAgentName(App.selectedAgent), | |
| text: randomResponse, | |
| time: new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }) | |
| }); | |
| renderChatHistory(); | |
| }, 2000); | |
| } | |
| // Start playtest process | |
| function startPlaytest() { | |
| const originalText = playtestButton.textContent; | |
| // Disable button and change text | |
| playtestButton.disabled = true; | |
| playtestButton.textContent = "INTEGRATING..."; | |
| // Simulate API call | |
| setTimeout(() => { | |
| // Show success | |
| playtestButton.textContent = "SUCCESS!"; | |
| playtestButton.style.backgroundColor = "var(--color-accent)"; | |
| playtestButton.style.color = "var(--color-bg)"; | |
| // Revert after delay | |
| setTimeout(() => { | |
| playtestButton.textContent = originalText; | |
| playtestButton.style.backgroundColor = ""; | |
| playtestButton.style.color = ""; | |
| playtestButton.disabled = false; | |
| }, 2000); | |
| }, 3000); | |
| } | |
| // Initialize the app when DOM is loaded | |
| document.addEventListener('DOMContentLoaded', initApp); | |
| </script> | |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=edsaga/new-gbstudio-deck" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
| </html> |