AI Voice Designer
Run ID: 69cb829b61b1021a29a89b7d2026-03-31Design
PantheraHive BOS
BOS Dashboard

Design a completely custom AI voice by describing the characteristics you want

AI Voice Designer: Custom Voice Design Specifications

This document outlines comprehensive design specifications for creating a custom AI voice using advanced voice synthesis technology, such as Eleven Labs. It includes detailed voice characteristics, proposed wireframe descriptions for an intuitive design interface, recommended color palettes, and critical user experience (UX) recommendations to ensure a professional and highly customizable deliverable.


1. Detailed Voice Design Specifications

The following parameters define the core characteristics for designing a completely custom AI voice. These specifications allow for granular control, enabling the creation of unique and expressive vocal identities.

1.1 Core Vocal Attributes

  • Gender & Pitch Range:

* Options: Male, Female, Androgynous/Neutral.

* Control: Slider for fine-tuning pitch from very low (deep) to very high (squeaky), irrespective of chosen gender archetype.

* Example: "Female, slightly lower than average pitch for a calming effect."

  • Age Profile:

* Options: Young Adult (18-30), Middle-Aged (30-55), Senior (55+).

* Control: Discrete selection or a slider for subtle age-related vocal nuances (e.g., clarity, resonance).

* Example: "Middle-aged, with a touch of youthful clarity."

  • Accent & Regional Dialect:

* Options: Standard American, British English (RP), Australian, Indian, Irish, Scottish, Canadian, etc. (expandable based on language support).

* Control: Dropdown selection for primary accent, with a secondary option for regional variations if available (e.g., "British English (RP)" vs. "British English (Estuary)").

* Example: "Standard American English, neutral accent."

  • Speech Rate (Pace):

* Control: Slider from "Very Slow" to "Very Fast" (e.g., 80% to 120% of average human speech rate).

* Example: "Slightly slower than average, for clear articulation."

  • Volume & Loudness:

* Control: Slider from "Whisper" to "Loud" (relative to a base average).

* Example: "Normal conversational volume, but capable of subtle increases for emphasis."

  • Resonance & Timbre:

* Options/Control:

* Breathiness: Slider from "Clear" to "Breathy."

* Warmth: Slider from "Cool/Crisp" to "Warm/Rich."

* Depth: Slider from "Shallow" to "Deep/Resonant."

* Example: "Warm and rich timbre, with minimal breathiness for clarity."

1.2 Vocal Style & Personality

  • Overall Tone:

* Options: Authoritative, Friendly, Calm, Energetic, Empathetic, Serious, Playful, Professional, Confident, Soothing.

* Control: Multi-select checkboxes or a primary dropdown with intensity sliders for chosen tones.

* Example: "Friendly and Empathetic, with an underlying Professional tone."

  • Emotional Range (Expressiveness):

* Control: Slider from "Monotone/Neutral" to "Highly Expressive." This influences the voice's ability to convey a range of emotions (joy, sadness, anger, surprise) when prompted.

* Example: "Moderately expressive, suitable for storytelling and general narration."

  • Intonation & Cadence:

* Control: Slider from "Flat/Even" to "Varied/Dynamic." This affects the rise and fall of pitch within sentences.

* Example: "Dynamic intonation, preventing a robotic sound."

  • Pronunciation Clarity:

* Control: Slider from "Relaxed" to "Precise/Articulate."

* Example: "Highly precise and articulate, suitable for educational content."

1.3 Intended Use Case Optimizations

  • Application Focus:

* Options: Conversational AI, News Reader, Storyteller, Explainer Video, Podcast Host, IVR System, Audiobook Narrator, Gaming Character.

* Control: Primary dropdown for optimization presets, which can then be fine-tuned.

* Example: "Optimized for Conversational AI, with a focus on natural turn-taking and responsiveness."


2. Wireframe Descriptions (AI Voice Designer Interface)

The interface will be designed for intuitive navigation and real-time feedback, ensuring a seamless voice creation experience.

2.1 Main Layout: Two-Column Structure

  • Left Column (Voice Controls - ~65% width): Dedicated to all voice parameter adjustments.
  • Right Column (Preview & Management - ~35% width): For real-time testing, saving, and managing voices.

2.2 Left Column: Voice Controls Panel

  • Header: "Custom Voice Designer"
  • Section 1: Core Vocal Attributes

* Gender & Pitch: Radio buttons (Male, Female, Neutral) and a horizontal slider for "Pitch (Hz)".

* Age Profile: Dropdown (Young Adult, Middle-Aged, Senior).

* Accent & Dialect: Two cascaded dropdowns (e.g., "Primary Accent: American", "Dialect: Standard").

* Speech Rate: Horizontal slider with numerical percentage display (e.g., "100% (Normal)").

* Volume: Horizontal slider with a visual indicator (e.g., "Normal").

* Resonance & Timbre: Three separate horizontal sliders labeled "Breathiness," "Warmth," "Depth."

  • Section 2: Vocal Style & Personality

* Overall Tone: Checkbox group (e.g., Friendly, Authoritative, Calm) with optional intensity sliders appearing next to selected tones.

* Emotional Range: Horizontal slider from "Neutral" to "Highly Expressive."

* Intonation & Cadence: Horizontal slider from "Flat" to "Dynamic."

* Pronunciation Clarity: Horizontal slider from "Relaxed" to "Precise."

  • Section 3: Intended Use Case

* Application Focus: Dropdown menu with predefined use case presets.

  • Action Buttons:

* "Reset to Default"

* "Load Preset" (opens a modal with existing templates)

2.3 Right Column: Preview & Management Panel

  • Header: "Voice Preview & Management"
  • Section 1: Text Input & Playback

* Text Area: Multi-line text input field (e.g., "Enter text to preview your voice..."). Placeholder text could include common phrases.

* Play Button: Large, prominent play icon.

* Stop Button: Appears during playback.

* Volume Control: Small slider next to the play button for preview volume.

* Loading Indicator: Visual feedback during voice synthesis.

  • Section 2: Voice Management

* Voice Name Input: Text field (e.g., "My Custom Voice 1").

* Save Button: Saves the current voice configuration.

* Load Voice Button: Opens a modal or dropdown to select from previously saved custom voices.

* Delete Voice Button: For managing saved voices.

* Export Options: Button to export voice settings (e.g., JSON) or integrate directly with other PantheraHive tools.

  • Section 3: Voice Information (Read-only)

* Displays a summary of key selected attributes (e.g., "Gender: Female, Age: Middle-Aged, Accent: American"). This serves as a quick reference.


3. Color Palettes

A professional, modern, and clean aesthetic will enhance usability and reflect the advanced nature of the tool.

3.1 Primary Palette (PantheraHive Brand Alignment)

  • Deep Blue/Teal: #0A2E36 (Dark background, headers, primary action buttons) - Represents professionalism, technology, depth.
  • Vibrant Teal/Aqua: #2EC4B6 (Accent color, interactive elements, selected states) - Represents innovation, clarity, energy.
  • Warm Grey: #E0E0E0 (Backgrounds for content areas, card elements) - Provides a neutral, calming base.
  • Off-White/Light Grey: #F5F5F5 (Main background, text input fields) - Ensures readability and clean separation.

3.2 Secondary Palette (UI Elements & Feedback)

  • Success Green: #4CAF50 (Confirmation messages, successful saves)
  • Warning Yellow: #FFC107 (Alerts, potential issues)
  • Error Red: #F44336 (Error messages, failed actions)
  • Neutral Grey: #607D8B (Subtle text, disabled states, borders)

3.3 Typography Colors

  • Primary Text: #333333 (Dark grey for main content, high readability)
  • Secondary Text/Labels: #757575 (Lighter grey for descriptions, hints)
  • Highlight Text: #2EC4B6 (For emphasis, links)

4. UX Recommendations

User experience is paramount for a complex tool like an AI voice designer. Recommendations focus on intuitiveness, feedback, and guidance.

  • Real-time Auditory Feedback:

* Instant Playback: Minimize latency between text input and audio generation.

* Parameter Change Preview: Offer an option for immediate, subtle auditory feedback when a slider or option is adjusted, even without a full playback. This could be a short "ping" or a quick snippet of the voice.

  • Intuitive Controls & Visualizations:

* Clear Labeling: All sliders, dropdowns, and buttons should have concise, unambiguous labels.

* Visual Indicators: Use visual cues (e.g., waveform icon next to volume, a small "person" icon next to age) to reinforce meaning.

* Logical Grouping: Group related voice characteristics together (as proposed in the wireframe) to reduce cognitive load.

  • Presets and Templates:

* Starting Points: Provide a library of diverse pre-designed voices (e.g., "Podcast Narrator," "Friendly AI Assistant," "Authoritative Spokesperson") to help users quickly begin and understand the range of possibilities.

* Save/Load Custom Presets: Allow users to save their unique voice designs as custom presets for future use or sharing.

  • Guidance and Tooltips:

* Contextual Help: Implement tooltips for each parameter explaining its effect on the voice.

* Onboarding Tour: A brief, optional guided tour for first-time users to highlight key features.

  • Iterative Design Workflow:

* A/B Testing (Internal): Allow users to compare two slightly different voice configurations side-by-side (e.g., Voice A vs. Voice B) to make nuanced decisions.

* Version History: For complex projects, consider a simple version history or "undo/redo" functionality for voice parameter changes.

  • Performance and Responsiveness:

* Fast Synthesis: Optimize the backend for rapid voice generation, especially for short preview snippets.

* Smooth UI Transitions: Ensure the interface is responsive and animations are fluid.

  • Accessibility:

* Keyboard Navigation: All interactive elements should be reachable and operable via keyboard.

* High Contrast: Adhere to WCAG guidelines for color contrast to ensure readability for all users.

* Screen Reader Compatibility: Ensure elements are properly labeled for screen reader users.

  • Clear Error Handling:

* Provide clear, actionable error messages if voice generation fails or parameters conflict.

* Suggest solutions or next steps for the user.


This detailed output provides a robust foundation for developing an "AI Voice Designer" tool that is powerful, flexible, and user-friendly, directly addressing the customer's need for a custom AI voice.

ai_voice_designer.md
Download as Markdown
Copy all content
Full output as text
Download ZIP
IDE-ready project ZIP
Copy share link
Permanent URL for this run
Get Embed Code
Embed this result on any website
Print / Save PDF
Use browser print dialog
\n\n\n"); var hasSrcMain=Object.keys(extracted).some(function(k){return k.indexOf("src/main")>=0;}); if(!hasSrcMain) zip.file(folder+"src/main."+ext,"import React from 'react'\nimport ReactDOM from 'react-dom/client'\nimport App from './App'\nimport './index.css'\n\nReactDOM.createRoot(document.getElementById('root')!).render(\n \n \n \n)\n"); var hasSrcApp=Object.keys(extracted).some(function(k){return k==="src/App."+ext||k==="App."+ext;}); if(!hasSrcApp) zip.file(folder+"src/App."+ext,"import React from 'react'\nimport './App.css'\n\nfunction App(){\n return(\n
\n
\n

"+slugTitle(pn)+"

\n

Built with PantheraHive BOS

\n
\n
\n )\n}\nexport default App\n"); zip.file(folder+"src/index.css","*{margin:0;padding:0;box-sizing:border-box}\nbody{font-family:system-ui,-apple-system,sans-serif;background:#f0f2f5;color:#1a1a2e}\n.app{min-height:100vh;display:flex;flex-direction:column}\n.app-header{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;padding:40px}\nh1{font-size:2.5rem;font-weight:700}\n"); zip.file(folder+"src/App.css",""); zip.file(folder+"src/components/.gitkeep",""); zip.file(folder+"src/pages/.gitkeep",""); zip.file(folder+"src/hooks/.gitkeep",""); Object.keys(extracted).forEach(function(p){ var fp=p.startsWith("src/")?p:"src/"+p; zip.file(folder+fp,extracted[p]); }); zip.file(folder+"README.md","# "+slugTitle(pn)+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\nnpm install\nnpm run dev\n\`\`\`\n\n## Build\n\`\`\`bash\nnpm run build\n\`\`\`\n\n## Open in IDE\nOpen the project folder in VS Code or WebStorm.\n"); zip.file(folder+".gitignore","node_modules/\ndist/\n.env\n.DS_Store\n*.local\n"); } /* --- Vue (Vite + Composition API + TypeScript) --- */ function buildVue(zip,folder,app,code,panelTxt){ var pn=pkgName(app); var C=cc(pn); var extracted=extractCode(panelTxt); zip.file(folder+"package.json",'{\n "name": "'+pn+'",\n "version": "0.0.0",\n "type": "module",\n "scripts": {\n "dev": "vite",\n "build": "vue-tsc -b && vite build",\n "preview": "vite preview"\n },\n "dependencies": {\n "vue": "^3.5.13",\n "vue-router": "^4.4.5",\n "pinia": "^2.3.0",\n "axios": "^1.7.9"\n },\n "devDependencies": {\n "@vitejs/plugin-vue": "^5.2.1",\n "typescript": "~5.7.3",\n "vite": "^6.0.5",\n "vue-tsc": "^2.2.0"\n }\n}\n'); zip.file(folder+"vite.config.ts","import { defineConfig } from 'vite'\nimport vue from '@vitejs/plugin-vue'\nimport { resolve } from 'path'\n\nexport default defineConfig({\n plugins: [vue()],\n resolve: { alias: { '@': resolve(__dirname,'src') } }\n})\n"); zip.file(folder+"tsconfig.json",'{"files":[],"references":[{"path":"./tsconfig.app.json"},{"path":"./tsconfig.node.json"}]}\n'); zip.file(folder+"tsconfig.app.json",'{\n "compilerOptions":{\n "target":"ES2020","useDefineForClassFields":true,"module":"ESNext","lib":["ES2020","DOM","DOM.Iterable"],\n "skipLibCheck":true,"moduleResolution":"bundler","allowImportingTsExtensions":true,\n "isolatedModules":true,"moduleDetection":"force","noEmit":true,"jsxImportSource":"vue",\n "strict":true,"paths":{"@/*":["./src/*"]}\n },\n "include":["src/**/*.ts","src/**/*.d.ts","src/**/*.tsx","src/**/*.vue"]\n}\n'); zip.file(folder+"env.d.ts","/// \n"); zip.file(folder+"index.html","\n\n\n \n \n "+slugTitle(pn)+"\n\n\n
\n \n\n\n"); var hasMain=Object.keys(extracted).some(function(k){return k==="src/main.ts"||k==="main.ts";}); if(!hasMain) zip.file(folder+"src/main.ts","import { createApp } from 'vue'\nimport { createPinia } from 'pinia'\nimport App from './App.vue'\nimport './assets/main.css'\n\nconst app = createApp(App)\napp.use(createPinia())\napp.mount('#app')\n"); var hasApp=Object.keys(extracted).some(function(k){return k.indexOf("App.vue")>=0;}); if(!hasApp) zip.file(folder+"src/App.vue","\n\n\n\n\n"); zip.file(folder+"src/assets/main.css","*{margin:0;padding:0;box-sizing:border-box}body{font-family:system-ui,sans-serif;background:#fff;color:#213547}\n"); zip.file(folder+"src/components/.gitkeep",""); zip.file(folder+"src/views/.gitkeep",""); zip.file(folder+"src/stores/.gitkeep",""); Object.keys(extracted).forEach(function(p){ var fp=p.startsWith("src/")?p:"src/"+p; zip.file(folder+fp,extracted[p]); }); zip.file(folder+"README.md","# "+slugTitle(pn)+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\nnpm install\nnpm run dev\n\`\`\`\n\n## Build\n\`\`\`bash\nnpm run build\n\`\`\`\n\nOpen in VS Code or WebStorm.\n"); zip.file(folder+".gitignore","node_modules/\ndist/\n.env\n.DS_Store\n*.local\n"); } /* --- Angular (v19 standalone) --- */ function buildAngular(zip,folder,app,code,panelTxt){ var pn=pkgName(app); var C=cc(pn); var sel=pn.replace(/_/g,"-"); var extracted=extractCode(panelTxt); zip.file(folder+"package.json",'{\n "name": "'+pn+'",\n "version": "0.0.0",\n "scripts": {\n "ng": "ng",\n "start": "ng serve",\n "build": "ng build",\n "test": "ng test"\n },\n "dependencies": {\n "@angular/animations": "^19.0.0",\n "@angular/common": "^19.0.0",\n "@angular/compiler": "^19.0.0",\n "@angular/core": "^19.0.0",\n "@angular/forms": "^19.0.0",\n "@angular/platform-browser": "^19.0.0",\n "@angular/platform-browser-dynamic": "^19.0.0",\n "@angular/router": "^19.0.0",\n "rxjs": "~7.8.0",\n "tslib": "^2.3.0",\n "zone.js": "~0.15.0"\n },\n "devDependencies": {\n "@angular-devkit/build-angular": "^19.0.0",\n "@angular/cli": "^19.0.0",\n "@angular/compiler-cli": "^19.0.0",\n "typescript": "~5.6.0"\n }\n}\n'); zip.file(folder+"angular.json",'{\n "$schema": "./node_modules/@angular/cli/lib/config/schema.json",\n "version": 1,\n "newProjectRoot": "projects",\n "projects": {\n "'+pn+'": {\n "projectType": "application",\n "root": "",\n "sourceRoot": "src",\n "prefix": "app",\n "architect": {\n "build": {\n "builder": "@angular-devkit/build-angular:application",\n "options": {\n "outputPath": "dist/'+pn+'",\n "index": "src/index.html",\n "browser": "src/main.ts",\n "tsConfig": "tsconfig.app.json",\n "styles": ["src/styles.css"],\n "scripts": []\n }\n },\n "serve": {"builder":"@angular-devkit/build-angular:dev-server","configurations":{"production":{"buildTarget":"'+pn+':build:production"},"development":{"buildTarget":"'+pn+':build:development"}},"defaultConfiguration":"development"}\n }\n }\n }\n}\n'); zip.file(folder+"tsconfig.json",'{\n "compileOnSave": false,\n "compilerOptions": {"baseUrl":"./","outDir":"./dist/out-tsc","forceConsistentCasingInFileNames":true,"strict":true,"noImplicitOverride":true,"noPropertyAccessFromIndexSignature":true,"noImplicitReturns":true,"noFallthroughCasesInSwitch":true,"paths":{"@/*":["src/*"]},"skipLibCheck":true,"esModuleInterop":true,"sourceMap":true,"declaration":false,"experimentalDecorators":true,"moduleResolution":"bundler","importHelpers":true,"target":"ES2022","module":"ES2022","useDefineForClassFields":false,"lib":["ES2022","dom"]},\n "references":[{"path":"./tsconfig.app.json"}]\n}\n'); zip.file(folder+"tsconfig.app.json",'{\n "extends":"./tsconfig.json",\n "compilerOptions":{"outDir":"./dist/out-tsc","types":[]},\n "files":["src/main.ts"],\n "include":["src/**/*.d.ts"]\n}\n'); zip.file(folder+"src/index.html","\n\n\n \n "+slugTitle(pn)+"\n \n \n \n\n\n \n\n\n"); zip.file(folder+"src/main.ts","import { bootstrapApplication } from '@angular/platform-browser';\nimport { appConfig } from './app/app.config';\nimport { AppComponent } from './app/app.component';\n\nbootstrapApplication(AppComponent, appConfig)\n .catch(err => console.error(err));\n"); zip.file(folder+"src/styles.css","* { margin: 0; padding: 0; box-sizing: border-box; }\nbody { font-family: system-ui, -apple-system, sans-serif; background: #f9fafb; color: #111827; }\n"); var hasComp=Object.keys(extracted).some(function(k){return k.indexOf("app.component")>=0;}); if(!hasComp){ zip.file(folder+"src/app/app.component.ts","import { Component } from '@angular/core';\nimport { RouterOutlet } from '@angular/router';\n\n@Component({\n selector: 'app-root',\n standalone: true,\n imports: [RouterOutlet],\n templateUrl: './app.component.html',\n styleUrl: './app.component.css'\n})\nexport class AppComponent {\n title = '"+pn+"';\n}\n"); zip.file(folder+"src/app/app.component.html","
\n
\n

"+slugTitle(pn)+"

\n

Built with PantheraHive BOS

\n
\n \n
\n"); zip.file(folder+"src/app/app.component.css",".app-header{display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:60vh;gap:16px}h1{font-size:2.5rem;font-weight:700;color:#6366f1}\n"); } zip.file(folder+"src/app/app.config.ts","import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';\nimport { provideRouter } from '@angular/router';\nimport { routes } from './app.routes';\n\nexport const appConfig: ApplicationConfig = {\n providers: [\n provideZoneChangeDetection({ eventCoalescing: true }),\n provideRouter(routes)\n ]\n};\n"); zip.file(folder+"src/app/app.routes.ts","import { Routes } from '@angular/router';\n\nexport const routes: Routes = [];\n"); Object.keys(extracted).forEach(function(p){ var fp=p.startsWith("src/")?p:"src/"+p; zip.file(folder+fp,extracted[p]); }); zip.file(folder+"README.md","# "+slugTitle(pn)+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\nnpm install\nng serve\n# or: npm start\n\`\`\`\n\n## Build\n\`\`\`bash\nng build\n\`\`\`\n\nOpen in VS Code with Angular Language Service extension.\n"); zip.file(folder+".gitignore","node_modules/\ndist/\n.env\n.DS_Store\n*.local\n.angular/\n"); } /* --- Python --- */ function buildPython(zip,folder,app,code){ var title=slugTitle(app); var pn=pkgName(app); var src=code.replace(/^\`\`\`[\w]*\n?/m,"").replace(/\n?\`\`\`$/m,"").trim(); var reqMap={"numpy":"numpy","pandas":"pandas","sklearn":"scikit-learn","tensorflow":"tensorflow","torch":"torch","flask":"flask","fastapi":"fastapi","uvicorn":"uvicorn","requests":"requests","sqlalchemy":"sqlalchemy","pydantic":"pydantic","dotenv":"python-dotenv","PIL":"Pillow","cv2":"opencv-python","matplotlib":"matplotlib","seaborn":"seaborn","scipy":"scipy"}; var reqs=[]; Object.keys(reqMap).forEach(function(k){if(src.indexOf("import "+k)>=0||src.indexOf("from "+k)>=0)reqs.push(reqMap[k]);}); var reqsTxt=reqs.length?reqs.join("\n"):"# add dependencies here\n"; zip.file(folder+"main.py",src||"# "+title+"\n# Generated by PantheraHive BOS\n\nprint(title+\" loaded\")\n"); zip.file(folder+"requirements.txt",reqsTxt); zip.file(folder+".env.example","# Environment variables\n"); zip.file(folder+"README.md","# "+title+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\npython3 -m venv .venv\nsource .venv/bin/activate\npip install -r requirements.txt\n\`\`\`\n\n## Run\n\`\`\`bash\npython main.py\n\`\`\`\n"); zip.file(folder+".gitignore",".venv/\n__pycache__/\n*.pyc\n.env\n.DS_Store\n"); } /* --- Node.js --- */ function buildNode(zip,folder,app,code){ var title=slugTitle(app); var pn=pkgName(app); var src=code.replace(/^\`\`\`[\w]*\n?/m,"").replace(/\n?\`\`\`$/m,"").trim(); var depMap={"mongoose":"^8.0.0","dotenv":"^16.4.5","axios":"^1.7.9","cors":"^2.8.5","bcryptjs":"^2.4.3","jsonwebtoken":"^9.0.2","socket.io":"^4.7.4","uuid":"^9.0.1","zod":"^3.22.4","express":"^4.18.2"}; var deps={}; Object.keys(depMap).forEach(function(k){if(src.indexOf(k)>=0)deps[k]=depMap[k];}); if(!deps["express"])deps["express"]="^4.18.2"; var pkgJson=JSON.stringify({"name":pn,"version":"1.0.0","main":"src/index.js","scripts":{"start":"node src/index.js","dev":"nodemon src/index.js"},"dependencies":deps,"devDependencies":{"nodemon":"^3.0.3"}},null,2)+"\n"; zip.file(folder+"package.json",pkgJson); var fallback="const express=require(\"express\");\nconst app=express();\napp.use(express.json());\n\napp.get(\"/\",(req,res)=>{\n res.json({message:\""+title+" API\"});\n});\n\nconst PORT=process.env.PORT||3000;\napp.listen(PORT,()=>console.log(\"Server on port \"+PORT));\n"; zip.file(folder+"src/index.js",src||fallback); zip.file(folder+".env.example","PORT=3000\n"); zip.file(folder+".gitignore","node_modules/\n.env\n.DS_Store\n"); zip.file(folder+"README.md","# "+title+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\nnpm install\n\`\`\`\n\n## Run\n\`\`\`bash\nnpm run dev\n\`\`\`\n"); } /* --- Vanilla HTML --- */ function buildVanillaHtml(zip,folder,app,code){ var title=slugTitle(app); var isFullDoc=code.trim().toLowerCase().indexOf("=0||code.trim().toLowerCase().indexOf("=0; var indexHtml=isFullDoc?code:"\n\n\n\n\n"+title+"\n\n\n\n"+code+"\n\n\n\n"; zip.file(folder+"index.html",indexHtml); zip.file(folder+"style.css","/* "+title+" — styles */\n*{margin:0;padding:0;box-sizing:border-box}\nbody{font-family:system-ui,-apple-system,sans-serif;background:#fff;color:#1a1a2e}\n"); zip.file(folder+"script.js","/* "+title+" — scripts */\n"); zip.file(folder+"assets/.gitkeep",""); zip.file(folder+"README.md","# "+title+"\n\nGenerated by PantheraHive BOS.\n\n## Open\nDouble-click \`index.html\` in your browser.\n\nOr serve locally:\n\`\`\`bash\nnpx serve .\n# or\npython3 -m http.server 3000\n\`\`\`\n"); zip.file(folder+".gitignore",".DS_Store\nnode_modules/\n.env\n"); } /* ===== MAIN ===== */ var sc=document.createElement("script"); sc.src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"; sc.onerror=function(){ if(lbl)lbl.textContent="Download ZIP"; alert("JSZip load failed — check connection."); }; sc.onload=function(){ var zip=new JSZip(); var base=(_phFname||"output").replace(/\.[^.]+$/,""); var app=base.toLowerCase().replace(/[^a-z0-9]+/g,"_").replace(/^_+|_+$/g,"")||"my_app"; var folder=app+"/"; var vc=document.getElementById("panel-content"); var panelTxt=vc?(vc.innerText||vc.textContent||""):""; var lang=detectLang(_phCode,panelTxt); if(_phIsHtml){ buildVanillaHtml(zip,folder,app,_phCode); } else if(lang==="flutter"){ buildFlutter(zip,folder,app,_phCode,panelTxt); } else if(lang==="react-native"){ buildReactNative(zip,folder,app,_phCode,panelTxt); } else if(lang==="swift"){ buildSwift(zip,folder,app,_phCode,panelTxt); } else if(lang==="kotlin"){ buildKotlin(zip,folder,app,_phCode,panelTxt); } else if(lang==="react"){ buildReact(zip,folder,app,_phCode,panelTxt); } else if(lang==="vue"){ buildVue(zip,folder,app,_phCode,panelTxt); } else if(lang==="angular"){ buildAngular(zip,folder,app,_phCode,panelTxt); } else if(lang==="python"){ buildPython(zip,folder,app,_phCode); } else if(lang==="node"){ buildNode(zip,folder,app,_phCode); } else { /* Document/content workflow */ var title=app.replace(/_/g," "); var md=_phAll||_phCode||panelTxt||"No content"; zip.file(folder+app+".md",md); var h=""+title+""; h+="

"+title+"

"; var hc=md.replace(/&/g,"&").replace(//g,">"); hc=hc.replace(/^### (.+)$/gm,"

$1

"); hc=hc.replace(/^## (.+)$/gm,"

$1

"); hc=hc.replace(/^# (.+)$/gm,"

$1

"); hc=hc.replace(/\*\*(.+?)\*\*/g,"$1"); hc=hc.replace(/\n{2,}/g,"

"); h+="

"+hc+"

Generated by PantheraHive BOS
"; zip.file(folder+app+".html",h); zip.file(folder+"README.md","# "+title+"\n\nGenerated by PantheraHive BOS.\n\nFiles:\n- "+app+".md (Markdown)\n- "+app+".html (styled HTML)\n"); } zip.generateAsync({type:"blob"}).then(function(blob){ var a=document.createElement("a"); a.href=URL.createObjectURL(blob); a.download=app+".zip"; a.click(); URL.revokeObjectURL(a.href); if(lbl)lbl.textContent="Download ZIP"; }); }; document.head.appendChild(sc); } function phShare(){navigator.clipboard.writeText(window.location.href).then(function(){var el=document.getElementById("ph-share-lbl");if(el){el.textContent="Link copied!";setTimeout(function(){el.textContent="Copy share link";},2500);}});}function phEmbed(){var runId=window.location.pathname.split("/").pop().replace(".html","");var embedUrl="https://pantherahive.com/embed/"+runId;var code='';navigator.clipboard.writeText(code).then(function(){var el=document.getElementById("ph-embed-lbl");if(el){el.textContent="Embed code copied!";setTimeout(function(){el.textContent="Get Embed Code";},2500);}});}