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

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

AI Voice Designer: Detailed Design Specifications & User Experience

This document outlines the comprehensive design specifications, wireframe descriptions, color palettes, and user experience (UX) recommendations for the "AI Voice Designer" tool. The goal is to enable users to create completely custom AI voices with granular control, leveraging advanced AI voice synthesis capabilities, specifically referencing parameters akin to Eleven Labs' advanced features.


1. Detailed Design Specifications (Voice Characteristics & Parameters)

The AI Voice Designer will provide a robust set of parameters, allowing users to sculpt a voice from the ground up or refine existing characteristics. Each parameter will be controllable via intuitive UI elements.

1.1 Core Voice Identity

  • Gender:

* Options: Male, Female, Neutral/Androgynous.

* Control: Radio buttons or a slider from 'Feminine' to 'Masculine'.

  • Age Range:

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

* Control: Dropdown menu or selectable age range buttons.

  • Accent/Region:

* Options: American English (Standard, Southern, New York), British English (RP, Cockney, Scottish), Australian, Indian English, Spanish (Castilian, Latin American), French (Standard, Canadian), German, Italian, Japanese, Korean, Mandarin, etc. (Aligned with Eleven Labs' language support).

* Control: Searchable dropdown with flags/regions.

  • Language:

* Options: Primary language selection, with accent options dynamically updating based on language.

* Control: Searchable dropdown.

1.2 Speaking Style & Tone

  • Speaking Style:

* Options: Conversational, Newsreader, Storyteller, Explainer, Energetic, Calm, Authoritative, Friendly, Empathetic, Serious, Playful, Whispering, Shouting.

* Control: Multi-select checkboxes or a primary style dropdown with intensity slider.

  • Emotional Range (Subtlety & Expressiveness):

* Parameters: Happiness, Sadness, Anger, Surprise, Fear, Disgust, Neutral.

* Control: Sliders for each emotion (0-100%) to define the voice's capacity to express it. A "Global Expressiveness" slider can control overall emotional range.

  • Pace/Speed:

* Options: Very Slow, Slow, Moderate, Fast, Very Fast.

* Control: Slider (e.g., words per minute or relative speed).

  • Pitch:

* Control: Fine-tune slider for overall pitch adjustment (e.g., -50% to +50% relative to base).

  • Volume:

* Control: Slider for overall loudness (e.g., -10dB to +10dB).

1.3 Timbre & Resonance (Advanced)

  • Timbre:

* Options: Warm, Bright, Deep, Husky, Clear, Resonant, Nasal.

* Control: Multiple sliders or a 2D control pad (e.g., Warm-Bright on X-axis, Deep-Clear on Y-axis).

  • Breathiness:

* Control: Slider (0-100%) to add or remove audible breath sounds.

  • Vocal Fry:

* Control: Slider (0-100%) to introduce or reduce vocal fry characteristics.

  • Mouth Feel/Articulation:

* Control: Subtle slider to adjust perceived clarity of articulation (e.g., 'Crisp' to 'Smooth').

1.4 AI Model Parameters (Eleven Labs specific, if exposed)

  • Stability:

* Description: Controls the variability of the voice. Higher stability results in a more consistent voice, while lower stability allows for more expressiveness and variation.

* Control: Slider (0-100%).

  • Clarity + Similarity Enhancement:

* Description: Improves the clarity and distinctiveness of the voice. Higher values can make the voice sound more professional and less "AI-like."

* Control: Slider (0-100%).

  • Style Exaggeration:

* Description: Controls how much the AI exaggerates the speech characteristics. Higher values can lead to more dramatic or stylized delivery.

* Control: Slider (0-100%).

1.5 Customization & Reference

  • Reference Audio Upload (Optional):

* Functionality: Allow users to upload a short audio clip (e.g., 5-10 seconds) to extract core characteristics (gender, accent, general tone) as a starting point.

* Control: File upload button with clear instructions on optimal audio quality.

  • Text-to-Speech Preview:

* Functionality: Input text (up to 500 characters) to hear the voice in real-time.

* Control: Textarea, "Play" button, "Stop" button.


2. Wireframe Descriptions

The AI Voice Designer will be presented as a single-page application or a multi-step wizard, prioritizing real-time feedback and ease of iteration.

2.1 Overall Layout

  • Header: Logo, "AI Voice Designer" title, Navigation (if multi-step).
  • Main Content Area: Divided into "Voice Parameters," "Preview," and "Actions."
  • Footer: Copyright, Help/Support links.

2.2 Section: Voice Parameters (Left Panel / Top Section)

  • Core Identity Block:

* Gender: Radio buttons (Male, Female, Neutral).

* Age Range: Dropdown.

* Accent/Language: Searchable dropdown.

  • Speaking Style Block:

* Style: Multi-select checkboxes/dropdown.

* Emotional Range: Individual sliders for Happiness, Sadness, Anger, etc., or a single "Global Expressiveness" slider.

* Pace, Pitch, Volume: Individual sliders.

  • Timbre & Resonance Block (Advanced/Toggleable):

* Timbre: 2D slider or multiple individual sliders (Warmth, Brightness, Depth).

* Breathiness, Vocal Fry, Articulation: Individual sliders.

  • AI Model Parameters Block (Advanced/Toggleable):

* Stability, Clarity, Style Exaggeration: Individual sliders.

  • Reference Audio Upload Block:

* "Upload Audio" button, clear instructions, file input area, status indicator.

2.3 Section: Real-time Preview (Right Panel / Middle Section)

  • Text Input Area:

* Large textarea for user to type/paste text (e.g., 500 characters limit).

* Character counter.

  • Playback Controls:

* "Play" button (with loading indicator during synthesis).

* "Stop" button.

* Progress bar for audio playback.

  • Voice Description Summary:

* A dynamic text summary displaying the current voice characteristics (e.g., "A Middle-Aged Male voice with a Standard American accent, calm and empathetic in tone, with high clarity.").

  • Comparison (Optional):

* A feature to compare the current voice with a previously saved version or a preset.

2.4 Section: Actions & Management (Bottom / Sidebar)

  • Preset Voices:

* Dropdown or scrollable list of pre-designed voices (e.g., "Narrator," "Customer Service Rep," "Podcast Host") to use as starting points.

* "Load Preset" button.

  • Save/Manage Voice:

* "Save Voice" button (prompts for voice name).

* "My Voices" button/link to access a library of saved custom voices.

* "Download Voice Model" (if applicable, though typically voices are used via API).

  • Clear/Reset:

* "Reset to Default" button.

  • Help/Tutorial:

* Contextual help icons next to complex parameters, linking to detailed explanations.


3. Color Palettes

A professional, modern, and user-friendly aesthetic is crucial.

3.1 Primary Palette: "PantheraHive Professional"

  • Primary Brand Blue: #007BFF (Strong, trustworthy, digital) - For primary buttons, active states, key highlights.
  • Secondary Accent Teal: #00C1D4 (Energetic, modern, refreshing) - For secondary actions, progress indicators, subtle accents.
  • Dark Neutral Grey: #343A40 (Strong, professional text and background elements) - For main text, darker backgrounds.
  • Light Neutral Grey: #F8F9FA (Clean, spacious background) - For main content backgrounds, card elements.
  • White: #FFFFFF (Clean, crisp) - For text on dark backgrounds, interactive elements.

3.2 Accent Palette: "Vibrant Feedback"

  • Success Green: #28A745 - For successful actions, positive feedback.
  • Warning Yellow: #FFC107 - For warnings, attention-grabbing elements.
  • Error Red: #DC3545 - For error messages, destructive actions.
  • Info Blue: #17A2B8 - For informational messages, subtle hints.

3.3 Typography

  • Font Family: A clean, modern sans-serif font like 'Inter', 'Roboto', or 'Open Sans' for readability and professional appeal.
  • Hierarchy: Clear use of font sizes and weights for headings, subheadings, and body text.

3.4 Accessibility Considerations

  • Ensure sufficient contrast ratios (WCAG 2.1 AA standard) between text and background colors.
  • Provide focus indicators for keyboard navigation.
  • Use semantic HTML for screen reader compatibility.

4. UX Recommendations

User experience is paramount for a tool as nuanced as voice design. The interface must be intuitive, responsive, and provide clear feedback.

4.1 Iterative Design & Real-time Feedback

  • Instant Preview: Prioritize low-latency text-to-speech synthesis for the preview function. Users should hear changes almost immediately.
  • A/B Comparison: Implement a "Compare" feature allowing users to save a snapshot of a voice and compare it side-by-side (audibly) with the current design.
  • Undo/Redo: Essential for experimentation, allowing users to revert changes easily.

4.2 Intuitive Controls & Guidance

  • Sliders for Nuance: Utilize sliders for parameters with continuous ranges (pitch, speed, emotional intensity).
  • Clear Labels & Tooltips: Every control should have a clear, concise label. Complex parameters should include tooltips with brief explanations and examples.
  • Default Values & Presets: Start users with sensible default values or a selection of high-quality preset voices to accelerate the design process.
  • Visual Feedback: When a slider is moved or an option is selected, provide subtle visual cues (e.g., highlight the active state).

4.3 Workflow & Management

  • Guided Workflow (Optional): For first-time users, a simple wizard could guide them through the most critical parameters first.
  • Voice Library: A dedicated section to manage, rename, duplicate, and delete saved custom voices.
  • Tagging/Categorization: Allow users to tag their custom voices (e.g., "Narration," "Character," "Brand Voice") for easier organization.
  • Export/Integration Options: Clearly indicate how the custom voice can be used (e.g., "Use with API," "Download Audio," "Integrate with [Platform]").

4.4 Performance & Reliability

  • Fast Synthesis: Optimize the backend for quick voice generation, especially for previews.
  • Error Handling: Provide clear, actionable error messages if a voice parameter combination is invalid or if synthesis fails.
  • Loading Indicators: Use subtle loading spinners or progress bars during synthesis to manage user expectations.

4.5 Accessibility

  • Keyboard Navigation: Ensure all interactive elements are reachable and operable via keyboard.
  • Screen Reader Support: Use appropriate ARIA attributes and semantic HTML.
  • High Contrast Mode: Offer an optional high-contrast theme for users with visual impairments.

This comprehensive design specification and UX recommendation document provides a robust framework for developing a powerful and user-friendly AI Voice Designer. By focusing on granular control, real-time feedback, and an intuitive interface, users will be empowered to create unique and compelling AI voices tailored to their specific needs.

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