PromptBase
Upgrade
Close icon
General
Home
Marketplace
Create
Hire
Login
Chat
Sell
Explore

Prompt Details

Model
(gemini-3.1-pro)
Token size
3,884
Example input
[Coloring Book Character App for printable creators]: Coloring Book Character App for printable creators [KDP sellers, Etsy sellers, kids aged 5 to 10]: KDP sellers, Etsy sellers, kids aged 5 to 10 [Cute full-body characters for coloring pages]: Cute full-body characters for coloring pages [Clean black white preview, simple kid-friendly UI, soft transitions]: Clean black white preview, simple kid-friendly UI, soft transitions [Coloring page prompts, cover prompt, variation generator, TXT export]: Coloring page prompts, cover prompt, variation generator, TXT export
Example output
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>ColoryMascot Studio - Printable IP Generator</title> <style> /* CSS Framework & Design System */ :root { --bg: #f8fafc; --surface: #ffffff; --primary: #0f172a; --primary-hover: #334155; --border: #e2e8f0; --border-focus: #94a3b8; --text: #0f172a; --text-muted: #64748b; --accent: #3b82f6; --success: #10b981; --warning: #f59e0b; --danger: #ef4444; --radius-md: 0.75rem; --radius-lg: 1.5rem; --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05); --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); } * { box-sizing: border-box; margin: 0; padding: 0; } body { font-family: system-ui, -apple-system, sans-serif; background-color: var(--bg); color: var(--text); line-height: 1.5; padding-bottom: 4rem; } /* Typography */ h1, h2, h3, h4 { font-weight: 800; letter-spacing: -0.025em; line-height: 1.2; } h1 { font-size: 2.25rem; } h2 { font-size: 1.5rem; margin-bottom: 1rem; } h3 { font-size: 1.25rem; margin-bottom: 0.5rem; } p { margin-bottom: 1rem; color: var(--text-muted); } strong { color: var(--text); } /* Layout */ .container { max-width: 1400px; margin: 0 auto; padding: 0 1.5rem; } .grid { display: grid; gap: 1.5rem; } .grid-cols-12 { grid-template-columns: repeat(12, 1fr); } .col-span-4 { grid-column: span 4; } .col-span-8 { grid-column: span 8; } .flex { display: flex; } .flex-col { flex-direction: column; } .items-center { align-items: center; } .justify-between { justify-content: space-between; } .justify-center { justify-content: center; } .gap-2 { gap: 0.5rem; } .gap-4 { gap: 1rem; } .gap-6 { gap: 1.5rem; } .mt-4 { margin-top: 1rem; } .mt-8 { margin-top: 2rem; } .mb-4 { margin-bottom: 1rem; } .mb-8 { margin-bottom: 2rem; } .p-4 { padding: 1rem; } .p-6 { padding: 1.5rem; } /* Components */ .card { background: var(--surface); border: 2px solid var(--border); border-radius: var(--radius-lg); padding: 1.5rem; box-shadow: var(--shadow-sm); } .btn { display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem; padding: 0.75rem 1.25rem; border-radius: 999px; font-weight: 600; font-size: 0.875rem; cursor: pointer; transition: all 0.2s ease; border: 2px solid transparent; text-decoration: none; } .btn:disabled { opacity: 0.5; cursor: not-allowed; } .btn-primary { background: var(--primary); color: white; } .btn-primary:hover:not(:disabled) { background: var(--primary-hover); transform: translateY(-1px); box-shadow: var(--shadow-md); } .btn-secondary { background: white; border-color: var(--border); color: var(--text); } .btn-secondary:hover:not(:disabled) { border-color: var(--primary); color: var(--primary); } .btn-outline { background: transparent; border-color: var(--primary); color: var(--primary); } .btn-outline:hover:not(:disabled) { background: var(--primary); color: white; } .btn-small { padding: 0.5rem 1rem; font-size: 0.75rem; } .btn-danger { background: var(--danger); color: white; } .input-group { display: flex; flex-direction: column; gap: 0.375rem; margin-bottom: 1rem; } .label { font-size: 0.875rem; font-weight: 600; color: var(--text); } .input, .select { padding: 0.625rem 1rem; border: 2px solid var(--border); border-radius: var(--radius-md); font-size: 0.875rem; background: var(--bg); transition: all 0.2s; color: var(--text); width: 100%; font-family: inherit; } .input:focus, .select:focus { outline: none; border-color: var(--primary); background: white; box-shadow: 0 0 0 3px rgba(15, 23, 42, 0.1); } .chip { display: inline-flex; align-items: center; padding: 0.25rem 0.75rem; background: var(--bg); border: 1px solid var(--border); border-radius: 999px; font-size: 0.75rem; font-weight: 600; color: var(--text-muted); } .chip.success { background: #dcfce7; color: #166534; border-color: #bbf7d0; } .chip.warning { background: #fef3c7; color: #92400e; border-color: #fde68a; } /* UI Elements */ .tabs { display: flex; gap: 0.5rem; overflow-x: auto; padding-bottom: 0.5rem; border-bottom: 2px solid var(--border); margin-bottom: 1.5rem; scrollbar-width: none; } .tabs::-webkit-scrollbar { display: none; } .tab { padding: 0.5rem 1rem; font-weight: 600; color: var(--text-muted); cursor: pointer; border: none; background: none; border-bottom: 2px solid transparent; margin-bottom: -2px; white-space: nowrap; transition: all 0.2s; } .tab:hover { color: var(--text); } .tab.active { color: var(--primary); border-bottom-color: var(--primary); } .tab-content { display: none; animation: fadeIn 0.4s cubic-bezier(0.16, 1, 0.3, 1); } .tab-content.active { display: block; } /* Generated Output Styles */ .output-block { background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius-md); padding: 1.5rem; margin-bottom: 1.5rem; } .output-block h4 { border-bottom: 2px solid var(--border); padding-bottom: 0.5rem; margin-bottom: 1rem; color: var(--primary); } .output-text { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; font-size: 0.875rem; white-space: pre-wrap; color: var(--primary); background: white; padding: 1rem; border-radius: var(--radius-md); border: 1px solid var(--border); } /* Mascot CSS Art */ .mascot-preview { width: 140px; height: 140px; background: white; border: 8px solid var(--primary); border-radius: 40% 60% 60% 40% / 50% 50% 50% 50%; position: relative; animation: float 4s ease-in-out infinite; margin: 0 auto; box-shadow: inset -12px -12px 0px rgba(0,0,0,0.04), 0 10px 20px rgba(0,0,0,0.1); } .mascot-eyes { position: absolute; top: 45px; left: 0; width: 100%; display: flex; justify-content: center; gap: 30px; } .mascot-eye { width: 16px; height: 16px; background: var(--primary); border-radius: 50%; animation: blink 4s infinite; } .mascot-smile { position: absolute; top: 70px; left: 50%; transform: translateX(-50%); width: 24px; height: 12px; border-bottom: 6px solid var(--primary); border-radius: 0 0 20px 20px; } .mascot-blush { position: absolute; top: 60px; left: 0; width: 100%; display: flex; justify-content: center; gap: 50px; opacity: 0.2; } .blush-spot { width: 16px; height: 10px; background: var(--primary); border-radius: 50%; } /* Utils & Animations */ @keyframes float { 0%, 100% { transform: translateY(0) rotate(0deg); } 50% { transform: translateY(-10px) rotate(2deg); } } @keyframes blink { 0%, 96%, 98% { transform: scaleY(1); } 97% { transform: scaleY(0.1); } } @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } .hidden { display: none !important; } .toast { position: fixed; bottom: 2rem; right: 2rem; background: var(--primary); color: white; padding: 1rem 1.5rem; border-radius: var(--radius-md); box-shadow: var(--shadow-md); z-index: 1000; animation: slideUp 0.3s ease; } @keyframes slideUp { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } .score-circle { width: 80px; height: 80px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 1.5rem; font-weight: 800; border: 6px solid var(--border); color: var(--primary); transition: all 0.5s; background: white;} #loading-overlay { position: fixed; inset: 0; background: rgba(255,255,255,0.8); backdrop-filter: blur(4px); z-index: 50; display: flex; flex-direction: column; align-items: center; justify-content: center; } .spinner { width: 40px; height: 40px; border: 4px solid var(--border); border-top-color: var(--primary); border-radius: 50%; animation: spin 1s linear infinite; } @keyframes spin { to { transform: rotate(360deg); } } /* Print Styles */ @media print { body { background: white; color: black; padding: 0; } .no-print, .input-panel, header, .tabs { display: none !important; } .col-span-8 { grid-column: span 12 !important; } .card { border: none; box-shadow: none; padding: 0; } .output-block { page-break-inside: avoid; border: 1px solid #ccc; } } /* Mobile Responsive */ @media (max-width: 1024px) { .col-span-4, .col-span-8 { grid-column: span 12; } .container { padding: 0 1rem; } .mascot-preview { width: 100px; height: 100px; } .mascot-eyes { top: 30px; gap: 20px; } .mascot-smile { top: 50px; } .mascot-blush { top: 40px; gap: 36px; } } /* Custom Scrollbar for textareas */ textarea { resize: vertical; min-height: 80px; } </style> </head> <body> <header class="container mt-8 mb-8 no-print"> <div class="card bg-primary text-white" style="background: var(--primary); color: white;"> <div class="flex items-center justify-between flex-col md:flex-row gap-6" style="flex-wrap: wrap;"> <div style="flex: 1;"> <div class="flex gap-2 mb-2"> <span class="chip">No External APIs</span> <span class="chip">Local Save</span> <span class="chip">Print Ready</span> </div> <h1 style="color: white; margin-bottom: 0.5rem;">ColoryMascot Studio</h1> <p style="color: #cbd5e1; font-size: 1.125rem; max-width: 600px;">Generate complete, IP-safe, kid-friendly mascot systems and coloring page prompts for KDP, Etsy, and creative printables.</p> <div class="flex gap-4 mt-6"> <button class="btn btn-secondary" style="border-color: white;" id="btn-demo-data"> <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z"></path><polyline points="13 2 13 9 20 9"></polyline></svg> Load Demo Data </button> <button class="btn" style="background: white; color: var(--primary);" id="btn-scroll-gen">Start Generating</button> </div> </div> <div class="p-6"> <div class="mascot-preview"> <div class="mascot-eyes"> <div class="mascot-eye"></div> <div class="mascot-eye"></div> </div> <div class="mascot-blush"> <div class="blush-spot"></div> <div class="blush-spot"></div> </div> <div class="mascot-smile"></div> </div> </div> </div> </div> </header> <main class="container grid grid-cols-12"> <!-- LEFT: INPUT STUDIO --> <aside class="col-span-4 input-panel"> <div class="card mb-4"> <div class="flex justify-between items-center mb-4"> <h2>Input Studio</h2> <div class="flex gap-2"> <button class="btn btn-small btn-secondary" id="btn-randomize" title="Randomize Ideas">🎲</button> <button class="btn btn-small btn-secondary" id="btn-clear-form" title="Clear Form">↺</button> </div> </div> <form id="generator-form"> <div class="input-group"> <label class="label">Mascot Base Type *</label> <input type="text" id="baseType" class="input" placeholder="e.g., Robot, Fox, Mushroom, Star" required> </div> <div class="input-group"> <label class="label">Target Audience *</label> <select id="targetAudience" class="select" required> <option value="Preschool (Ages 3-5)">Preschool (Ages 3-5)</option> <option value="Kids (Ages 5-10)" selected>Kids (Ages 5-10)</option> <option value="Middle School">Middle School</option> <option value="Parents & Families">Parents & Families</option> <option value="Teachers & Classrooms">Teachers & Classrooms</option> <option value="General Commercial Buyers">General Commercial Buyers</option> </select> </div> <div class="input-group"> <label class="label">Commercial Use Case *</label> <select id="useCase" class="select" required> <option value="Coloring Book (KDP)">Coloring Book (KDP)</option> <option value="Sticker Sheet (Etsy)">Sticker Sheet (Etsy)</option> <option value="Storybook Illustration">Storybook Illustration</option> <option value="Classroom Printables">Classroom Printables</option> <option value="Brand Mascot/Logo">Brand Mascot/Logo</option> <option value="Merchandise (T-Shirts/Mugs)">Merchandise (T-Shirts/Mugs)</option> </select> </div> <div class="input-group"> <label class="label">Theme World</label> <input type="text" id="themeWorld" class="input" placeholder="e.g., Magic Forest, Space Station, Cozy Town"> </div> <div class="input-group"> <label class="label">Personality Direction</label> <input type="text" id="personality" class="input" placeholder="e.g., Brave, Sleepy, Mischievous"> </div> <div class="input-group"> <label class="label">Visual Style</label> <select id="visualStyle" class="select"> <option value="Thick Line Art (B&W)">Thick Line Art (B&W) - Best for Coloring</option> <option value="Kawaii Minimalist">Kawaii Minimalist</option> <option value="Storybook Sketch">Storybook Sketch</option> <option value="Flat Vector Mascot">Flat Vector Mascot</option> <option value="Doodle Style">Doodle Style</option> </select> </div> <div class="input-group"> <label class="label">Signature Prop (Optional)</label> <input type="text" id="signatureProp" class="input" placeholder="e.g., Star Wand, Oversized Hat, Paintbrush"> </div> <div class="input-group mb-6"> <label class="label">IP Safety Strictness</label> <select id="ipSafety" class="select"> <option value="Strict">Strict (Commercial Safe)</option> <option value="Standard">Standard</option> </select> <p style="font-size: 0.75rem; margin-top: 0.25rem;">Removes copyrighted terms automatically.</p> </div> <div class="flex flex-col gap-3"> <button type="button" class="btn btn-primary" id="btn-generate-system">Generate Full System</button> <button type="button" class="btn btn-secondary" id="btn-ip-check">Run IP Safety Check</button> </div> </form> </div> <!-- Project Manager --> <div class="card mb-4"> <div class="flex justify-between items-center mb-4"> <h2>Saved Projects</h2> <span class="chip" id="project-count">0</span> </div> <div class="flex gap-2 mb-4"> <button class="btn btn-secondary btn-small" style="flex: 1;" id="btn-save-project">Save Current</button> <button class="btn btn-outline btn-small" id="btn-clear-projects">Clear</button> </div> <div id="project-list" class="flex flex-col gap-2" style="max-height: 200px; overflow-y: auto;"> <p class="text-center" style="font-size: 0.875rem;">No saved projects. Data saves locally to your browser.</p> </div> </div> </aside> <!-- RIGHT: OUTPUT DASHBOARD --> <main class="col-span-8"> <div class="card" style="min-height: 800px; display: flex; flex-direction: column;"> <!-- Dashboard Header --> <div class="flex justify-between items-center mb-6 border-b pb-4 border-gray-200"> <div class="flex items-center gap-4"> <div class="score-circle" id="quality-score" title="Quality Score based on inputs & safety">0</div> <div> <h2 style="margin: 0;">Output Canvas</h2> <p style="margin: 0; font-size: 0.875rem;" id="active-project-name">Unsaved Project</p> </div> </div> <div class="flex gap-2 no-print"> <button class="btn btn-secondary btn-small" id="btn-copy-active">Copy Text</button> <select class="select" id="exportFormat" style="width: auto; padding: 0.3rem 0.5rem;"> <option value="txt">Export .TXT</option> <option value="json">Export .JSON</option> <option value="html">Export .HTML</option> <option value="pdf">Print / PDF</option> </select> <button class="btn btn-primary btn-small" id="btn-export">Download</button> </div> </div> <!-- Empty State --> <div id="empty-state" class="flex flex-col items-center justify-center flex-1 text-center py-12"> <div class="mascot-preview" style="transform: scale(0.6); animation: none; border-color: var(--border);"> <div class="mascot-eyes" style="top: 55px;"><div class="mascot-eye" style="background: var(--border); animation: none;"></div><div class="mascot-eye" style="background: var(--border); animation: none;"></div></div> <div class="mascot-smile" style="border-bottom-color: var(--border);"></div> </div> <h3 class="mt-4" style="color: var(--text-muted);">Awaiting Instructions</h3> <p style="max-width: 400px;">Fill out the Input Studio and click generate to create a comprehensive, IP-safe mascot system.</p> </div> <!-- Generated Content Area --> <div id="generated-state" class="hidden" style="flex: 1;"> <!-- Mode Generators (Secondary Actions) --> <div class="flex gap-2 mb-6 flex-wrap p-4 bg-gray-50 rounded-lg border border-gray-200 no-print" style="background: var(--bg); border-radius: var(--radius-md);"> <span style="font-size: 0.75rem; font-weight: 600; width: 100%; text-transform: uppercase; color: var(--text-muted);">Generate Specific Modes</span> <button class="btn btn-secondary btn-small" id="btn-gen-variations">12 Variations</button> <button class="btn btn-secondary btn-small" id="btn-gen-prompts">Prompt Pack</button> <button class="btn btn-secondary btn-small" id="btn-gen-coloring">Coloring Book</button> <button class="btn btn-secondary btn-small" id="btn-gen-brand">Brand Kit</button> <button class="btn btn-secondary btn-small" id="btn-gen-story">Storybook</button> <button class="btn btn-secondary btn-small" id="btn-gen-merch">Sticker/Merch</button> </div> <!-- Tabs --> <div class="tabs no-print" id="output-tabs"> <button class="tab active" data-target="tab-system">Full System</button> <button class="tab" data-target="tab-variations">Variations</button> <button class="tab" data-target="tab-prompts">Prompt Pack</button> <button class="tab" data-target="tab-coloring">Coloring Book</button> <button class="tab" data-target="tab-brand">Brand Kit</button> <button class="tab" data-target="tab-story">Storybook</button> <button class="tab" data-target="tab-merch">Merch & Stickers</button> </div> <!-- Tab Contents --> <div id="tab-system" class="tab-content active"></div> <div id="tab-variations" class="tab-content"></div> <div id="tab-prompts" class="tab-content"></div> <div id="tab-coloring" class="tab-content"></div> <div id="tab-brand" class="tab-content"></div> <div id="tab-story" class="tab-content"></div> <div id="tab-merch" class="tab-content"></div> </div> </div> </main> </main> <footer class="container text-center mt-8 mb-4 no-print" style="font-size: 0.875rem; color: var(--text-muted);"> <p>ColoryMascot Studio · 100% Local Client-Side Processing · No External APIs Required</p> </footer> <!-- Global Loading Overlay --> <div id="loading-overlay" class="hidden"> <div class="spinner"></div> <h3 class="mt-4">Forging IP System...</h3> <p id="loading-text">Applying safe margins and validating audience fit.</p> </div> <!-- Script Block --> <script> /** * MascotVerse Forge Engine * No external libraries. Pure Vanilla JS. */ // --- Data & State --- const appState = { inputs: {}, outputs: { system: null, variations: null, prompts: null, coloring: null, brand: null, story: null, merch: null }, score: 0, activeTab: 'tab-system', projects: [] }; const Dictionaries = { bases: ['Fox', 'Bear', 'Robot', 'Cloud', 'Star', 'Cat', 'Dragon', 'Sloth', 'Mushroom', 'Alien', 'Ghost', 'Acorn', 'Bunny', 'Turtle', 'Owl'], themes: ['Magic Forest', 'Space Station', 'Cozy Town', 'Underwater Reef', 'Candyland', 'Dino Park', 'Sky Castle', 'Steampunk City', 'Winter Village'], personalities: ['Brave', 'Sleepy', 'Curious', 'Mischievous', 'Gentle', 'Energetic', 'Clumsy', 'Shy', 'Grumpy but sweet', 'Helpful'], props: ['Star Wand', 'Oversized Hat', 'Paintbrush', 'Lantern', 'Backpack', 'Magnifying Glass', 'Teddy Bear', 'Scarf', 'Goggles', 'Book'], protectedIPs: { 'disney': 'classic animated', 'marvel': 'heroic comic', 'star wars': 'sci-fi fantasy', 'pikachu': 'electric yellow companion', 'mickey': 'cheerful round-eared mascot', 'minnie': 'cheerful bow-wearing mascot', 'nintendo': 'retro gaming', 'mario': 'plumber hero', 'sonic': 'fast blue creature', 'peppa': 'friendly piglet', 'paw patrol': 'rescue pup', 'batman': 'dark vigilante', 'superman': 'caped hero', 'hello kitty': 'cute bow cat', 'spongebob': 'cheerful sea sponge', 'harry potter': 'student wizard', 'anime': 'expressive cartoon', 'pokemon': 'pocket monster' } }; // --- DOM Elements --- const UI = { form: document.getElementById('generator-form'), baseType: document.getElementById('baseType'), targetAudience: document.getElementById('targetAudience'), useCase: document.getElementById('useCase'), themeWorld: document.getElementById('themeWorld'), personality: document.getElementById('personality'), visualStyle: document.getElementById('visualStyle'), signatureProp: document.getElementById('signatureProp'), ipSafety: document.getElementById('ipSafety'), emptyState: document.getElementById('empty-state'), generatedState: document.getElementById('generated-state'), scoreCircle: document.getElementById('quality-score'), activeProjectName: document.getElementById('active-project-name'), loader: document.getElementById('loading-overlay'), tabs: document.querySelectorAll('.tab'), tabContents: document.querySelectorAll('.tab-content'), projectList: document.getElementById('project-list'), projectCount: document.getElementById('project-count') }; // --- Initialization --- function init() { loadProjectsFromStorage(); bindEvents(); } function bindEvents() { // Main Generate document.getElementById('btn-generate-system').addEventListener('click', () => handleGenerate('system')); // Specific Mode Generators document.getElementById('btn-gen-variations').addEventListener('click', () => handleGenerate('variations')); document.getElementById('btn-gen-prompts').addEventListener('click', () => handleGenerate('prompts')); document.getElementById('btn-gen-coloring').addEventListener('click', () => handleGenerate('coloring')); document.getElementById('btn-gen-brand').addEventListener('click', () => handleGenerate('brand')); document.getElementById('btn-gen-story').addEventListener('click', () => handleGenerate('story')); document.getElementById('btn-gen-merch').addEventListener('click', () => handleGenerate('merch')); // Utilities document.getElementById('btn-demo-data').addEventListener('click', loadDemoData); document.getElementById('btn-randomize').addEventListener('click', randomizeInputs); document.getElementById('btn-clear-form').addEventListener('click', () => UI.form.reset()); document.getElementById('btn-ip-check').addEventListener('click', runIPCheckWithUI); document.getElementById('btn-scroll-gen').addEventListener('click', () => document.getElementById('generator-form').scrollIntoView({behavior: 'smooth'})); // Export & Project document.getElementById('btn-copy-active').addEventListener('click', copyActiveOutput); document.getElementById('btn-export').addEventListener('click', handleExport); document.getElementById('btn-save-project').addEventListener('click', saveCurrentProject); document.getElementById('btn-clear-projects').addEventListener('click', clearProjects); // Tabs UI.tabs.forEach(tab => { tab.addEventListener('click', () => switchTab(tab.dataset.target)); }); } // --- Core Application Logic --- function getFormData() { return { baseType: UI.baseType.value.trim(), targetAudience: UI.targetAudience.value, useCase: UI.useCase.value, themeWorld: UI.themeWorld.value.trim() || 'A neutral studio background', personality: UI.personality.value.trim() || 'Friendly', visualStyle: UI.visualStyle.value, signatureProp: UI.signatureProp.value.trim() || 'none', ipSafety: UI.ipSafety.value }; } function loadDemoData() { UI.baseType.value = "Chubby Mushroom"; UI.targetAudience.value = "Kids (Ages 5-10)"; UI.useCase.value = "Coloring Book (KDP)"; UI.themeWorld.value = "Enchanted Autumn Forest"; UI.personality.value = "Curious and slightly clumsy"; UI.visualStyle.value = "Thick Line Art (B&W)"; UI.signatureProp.value = "Oversized Oak Leaf Umbrella"; showToast("Demo Data Loaded!"); } function randomizeInputs() { const pick = arr => arr[Math.floor(Math.random() * arr.length)]; UI.baseType.value = pick(Dictionaries.bases); UI.themeWorld.value = pick(Dictionaries.themes); UI.personality.value = pick(Dictionaries.personalities); UI.signatureProp.value = pick(Dictionaries.props); showToast("Inputs Randomized!"); } function sanitizeIP(text) { if(!text) return text; let sanitized = text.toLowerCase(); let triggered = false; for (const [ip, safeTerm] of Object.entries(Dictionaries.protectedIPs)) { const regex = new RegExp(`\\b${ip}\\b`, 'gi'); if (regex.test(sanitized)) { sanitized = sanitized.replace(regex, safeTerm); triggered = true; } } return { text: sanitized, triggered }; } function runIPCheckWithUI() { const inputs = getFormData(); let triggered = false; let checks = [UI.baseType, UI.themeWorld, UI.personality, UI.signatureProp]; checks.forEach(input => { const result = sanitizeIP(input.value); if(result.triggered) { input.value = result.text; triggered = true; } }); if(triggered) { showToast("IP Risk Detected! Protected terms converted to safe traits.", 'warning'); } else { showToast("IP Check Passed! 100% Safe.", 'success'); } } // --- Generators --- async function handleGenerate(mode) { if (!UI.form.checkValidity()) { UI.form.reportValidity(); return; } // Run strict IP check silently const checks = [UI.baseType, UI.themeWorld, UI.personality, UI.signatureProp]; checks.forEach(input => { input.value = sanitizeIP(input.value).text; }); appState.inputs = getFormData(); showLoader(); // Simulate processing time for UX await new Promise(r => setTimeout(r, 600)); // Generate content based on mode generateScore(); if (mode === 'system' || !appState.outputs.system) { appState.outputs.system = generateSystemText(appState.inputs); } if (mode === 'variations') appState.outputs.variations = generateVariationsText(appState.inputs); if (mode === 'prompts') appState.outputs.prompts = generatePromptsText(appState.inputs); if (mode === 'coloring') appState.outputs.coloring = generateColoringText(appState.inputs); if (mode === 'brand') appState.outputs.brand = generateBrandText(appState.inputs); if (mode === 'story') appState.outputs.story = generateStoryText(appState.inputs); if (mode === 'merch') appState.outputs.merch = generateMerchText(appState.inputs); hideLoader(); renderOutputs(); switchTab(`tab-${mode}`); UI.emptyState.classList.add('hidden'); UI.generatedState.classList.remove('hidden'); showToast(`${mode.toUpperCase()} Generated Successfully!`); } function generateScore() { let score = 100; const i = appState.inputs; if(!i.themeWorld || i.themeWorld.length < 3) score -= 10; if(!i.personality || i.personality.length < 3) score -= 10; if(i.signatureProp === 'none') score -= 5; // Check audience match complexity if (i.targetAudience.includes("Preschool") && i.visualStyle !== "Thick Line Art (B&W)") score -= 15; appState.score = Math.max(0, score); UI.scoreCircle.innerText = appState.score; // Color coding if(score > 85) UI.scoreCircle.style.borderColor = "var(--success)"; else if(score > 60) UI.scoreCircle.style.borderColor = "var(--warning)"; else UI.scoreCircle.style.borderColor = "var(--danger)"; } // --- Text Building Engines --- const audienceRules = { "Preschool (Ages 3-5)": "Extremely simple shapes, no small details, ultra-thick lines, highly clear silhouette.", "Kids (Ages 5-10)": "Fun expressions, engaging props, clean thick lines, medium detail for coloring.", "Middle School": "Edgier or more detailed line art, dynamic poses, deeper lore.", "Parents & Families": "Wholesome, safe, universally appealing, highly commercial.", "Teachers & Classrooms": "Educational styling, friendly, clear subjects, space for text.", "General Commercial Buyers": "Premium vector quality, highly brandable, scalable, perfectly symmetric options." }; function getAudienceRule(aud) { return audienceRules[aud] || audienceRules["General Commercial Buyers"]; } function generateSystemText(i) { const rule = getAudienceRule(i.targetAudience); return ` <div class="output-block"> <h4>1. Research Brief</h4> <p><strong>Target Audience Fit:</strong> ${i.targetAudience}. Logic: ${rule}</p> <p><strong>Commercial Goal:</strong> Optimized for ${i.useCase}.</p> <p><strong>Originality Check:</strong> Verified IP-Safe. Transformed into neutral archetype traits.</p> </div> <div class="output-block"> <h4>2. Mascot Concept Snapshot</h4> <div class="output-text">Name Concept: "Pip the ${i.baseType}" (Placeholder) Core Identity: A ${i.personality} ${i.baseType} living in ${i.themeWorld}. Visual Hook: Instantly recognizable by their ${i.signatureProp}. Style Mandate: ${i.visualStyle}</div> </div> <div class="output-block"> <h4>3. Visual Consistency Bible</h4> <p>To keep the character looking identical across different AI generations or illustrator briefs, enforce these rules strictly:</p> <ul> <li><strong>Proportions:</strong> Head-to-body ratio must remain 1:1 (large head, small body) to maintain cuteness.</li> <li><strong>Silhouette:</strong> The outline must clearly show a ${i.baseType} shape, even if fully blacked out.</li> <li><strong>The Anchor Prop:</strong> The ${i.signatureProp} MUST be present in at least 80% of generations to ground the identity.</li> <li><strong>Line Weight:</strong> Maintain consistent thick outlines for coloring applications.</li> </ul> </div> <div class="output-block"> <h4>4. Commercial Use Ideas</h4> <ul> <li><strong>Primary:</strong> Full page ${i.useCase} featuring the character.</li> <li><strong>Secondary:</strong> Die-cut stickers for Etsy featuring the face only.</li> <li><strong>Tertiary:</strong> Cover design featuring the character fully colored as an example.</li> </ul> </div> `; } function generateVariationsText(i) { let html = `<div class="output-block"><h4>12 Market-Tested Variations</h4><div class="grid grid-cols-12 gap-4">`; const pick = arr => arr[Math.floor(Math.random() * arr.length)]; for(let j=1; j<=12; j++) { const trait = pick(Dictionaries.personalities); const prop = pick(Dictionaries.props); html += ` <div class="col-span-4" style="border:1px solid var(--border); padding: 1rem; border-radius: var(--radius-md);"> <strong>Var ${j}: The ${trait} ${i.baseType}</strong> <p style="font-size:0.75rem; margin-top:0.5rem; margin-bottom:0;">Hook: Holding a ${prop}</p> </div>`; } html += `</div></div>`; return html; } function generatePromptsText(i) { const basePrompt = `White background, full body character, centered subject, safe margin, no cropped body parts. ${i.visualStyle} style illustration of a cute ${i.personality} ${i.baseType}. ${i.signatureProp !== 'none' ? `The character is holding/wearing a ${i.signatureProp}.` : ''} Theme: ${i.themeWorld}.`; const audRule = getAudienceRule(i.targetAudience); return ` <div class="output-block"> <h4>Copy-Ready AI Image Prompts</h4> <p>Optimized for Midjourney, DALL-E 3, and Stable Diffusion.</p> <strong>1. Hero Cover Image (Colored)</strong> <div class="output-text mb-4">${basePrompt} Vibrant flat colors, 2d vector art, premium commercial illustration, no shading. --ar 4:5</div> <strong>2. Standard Coloring Page</strong> <div class="output-text mb-4">${basePrompt} Pure black and white line art, thick clean outlines, no grayscale, no shading, minimal intersecting lines, easy to color. ${audRule} --ar 8:11</div> <strong>3. Sticker Sheet Generation</strong> <div class="output-text mb-4">Sticker sheet layout, white border around characters. Multiple poses of a cute ${i.personality} ${i.baseType} with a ${i.signatureProp}. Flat vector style, clean white background, evenly spaced. --ar 3:2</div> <strong>4. Action Pose (Jumping)</strong> <div class="output-text mb-4">${basePrompt} The character is jumping happily in the air. Dynamic pose. Pure black and white line art, thick outlines. --ar 1:1</div> <strong>Negative Prompt (Append to all)</strong> <div class="output-text">ugly, deformed, cropped, out of frame, grayscale, shading, gradients, messy lines, text, watermark, signature, realistic, 3d, complex background</div> </div> `; } function generateColoringText(i) { const rule = getAudienceRule(i.targetAudience); return ` <div class="output-block"> <h4>Strict Coloring Book Mode</h4> <p>This mode formats the IP specifically for KDP and printable creators. Copy the prompt block below directly into your AI generator.</p> <div class="output-text" style="font-size: 1rem; padding: 1.5rem; border-color: var(--primary);"> <strong>[SYSTEM DIRECTIVE: STRICT BLACK AND WHITE COLORING PAGE]</strong> <strong>Subject:</strong> A full body, centered ${i.personality} ${i.baseType} character. <strong>Prop:</strong> Must include a ${i.signatureProp}. <strong>Environment:</strong> ${i.themeWorld} elements in the background, but kept extremely simple and non-distracting. <strong>Style:</strong> Thick, bold, pure black continuous outlines. <strong>Background:</strong> Pure #FFFFFF white background. <strong>Exclusions:</strong> NO shading. NO hatching. NO stippling. NO grayscale. NO gradients. NO complex textures. NO cropped body parts. <strong>Audience Adaptation:</strong> ${rule} <strong>Composition:</strong> Ensure a 10% safe margin around the entire character so it is not cut off during printing. </div> </div> `; } function generateBrandText(i) { return ` <div class="output-block"> <h4>Brand Kit & Packaging Mode</h4> <p><strong>Brand Voice:</strong> ${i.personality}, approachable, and perfect for ${i.targetAudience}.</p> <p><strong>Color Palette Suggestion:</strong></p> <div class="flex gap-2 mb-4"> <div style="width: 40px; height: 40px; border-radius: 50%; background: #0f172a;" title="Primary Ink"></div> <div style="width: 40px; height: 40px; border-radius: 50%; background: #ffffff; border: 1px solid #ccc;" title="Paper White"></div> <div style="width: 40px; height: 40px; border-radius: 50%; background: #3b82f6;" title="Brand Accent"></div> <div style="width: 40px; height: 40px; border-radius: 50%; background: #f59e0b;" title="Warm Highlight"></div> </div> <strong>Typography Pairing (System Safe):</strong> <p>Header: <em>Arial Rounded MT Bold</em> or <em>Nunito</em><br>Body: <em>Verdana</em> or <em>Quicksand</em></p> <strong>Slogan Ideas:</strong> <ul> <li>"Colors of the ${i.themeWorld}!"</li> <li>"Your ${i.personality} friend, ready to color!"</li> </ul> <strong>Packaging Integration:</strong> <p>Place the ${i.baseType} on the bottom right corner of the printable bundle cover, looking up and pointing at the title, holding the ${i.signatureProp}.</p> </div> `; } function generateStoryText(i) { return ` <div class="output-block"> <h4>Storybook Framework</h4> <p>A quick 6-scene narrative for ${i.targetAudience}.</p> <div class="grid grid-cols-12 gap-4"> <div class="col-span-12 card" style="padding: 1rem;"> <strong>1. The Opening:</strong> The ${i.baseType} wakes up in the ${i.themeWorld}, feeling very ${i.personality}. </div> <div class="col-span-12 card" style="padding: 1rem;"> <strong>2. The Problem:</strong> They drop their beloved ${i.signatureProp} and it rolls away! </div> <div class="col-span-12 card" style="padding: 1rem;"> <strong>3. The Discovery:</strong> While searching, they find a blank, colorless area of the world. </div> <div class="col-span-12 card" style="padding: 1rem;"> <strong>4. The Turning Point:</strong> Using the ${i.signatureProp}, they realize they can bring color back to the area. </div> <div class="col-span-12 card" style="padding: 1rem;"> <strong>5. The Climax:</strong> A giant, friendly puzzle needs solving using colors. (Interactive coloring page). </div> <div class="col-span-12 card" style="padding: 1rem;"> <strong>6. The Closing:</strong> The ${i.baseType} goes to sleep, the world colorful and bright. </div> </div> </div> `; } function generateMerchText(i) { return ` <div class="output-block"> <h4>Sticker & Merch Mode</h4> <p>Optimized for die-cut stickers and Redbubble/Etsy products.</p> <strong>12 Sticker Pose Ideas:</strong> <div class="output-text mb-4"> 1. Waving hello 2. Sleeping cutely 3. Hugging the ${i.signatureProp} 4. Peeking over a wall 5. Jumping with joy 6. Looking confused/curious 7. Sitting down eating 8. Wearing sunglasses (Cool mode) 9. Running fast 10. Holding a blank sign (for sellers to add text) 11. Tangled up playfully 12. Looking at a butterfly </div> <strong>T-Shirt Concept:</strong> <p>Center chest placement. The ${i.baseType} inside a thick circular border featuring elements of the ${i.themeWorld}. Text wrap around border: "Stay ${i.personality}!"</p> </div> `; } // --- Render & UI Updates --- function renderOutputs() { if(!appState.outputs.system) return; document.getElementById('tab-system').innerHTML = appState.outputs.system || ''; document.getElementById('tab-variations').innerHTML = appState.outputs.variations || '<div class="output-block"><p>Click the "12 Variations" button to generate.</p></div>'; document.getElementById('tab-prompts').innerHTML = appState.outputs.prompts || '<div class="output-block"><p>Click the "Prompt Pack" button to generate.</p></div>'; document.getElementById('tab-coloring').innerHTML = appState.outputs.coloring || '<div class="output-block"><p>Click the "Coloring Book" button to generate.</p></div>'; document.getElementById('tab-brand').innerHTML = appState.outputs.brand || '<div class="output-block"><p>Click the "Brand Kit" button to generate.</p></div>'; document.getElementById('tab-story').innerHTML = appState.outputs.story || '<div class="output-block"><p>Click the "Storybook" button to generate.</p></div>'; document.getElementById('tab-merch').innerHTML = appState.outputs.merch || '<div class="output-block"><p>Click the "Sticker/Merch" button to generate.</p></div>'; } function switchTab(targetId) { appState.activeTab = targetId; UI.tabs.forEach(t => t.classList.remove('active')); UI.tabContents.forEach(c => c.classList.remove('active')); document.querySelector(`[data-target="${targetId}"]`).classList.add('active'); document.getElementById(targetId).classList.add('active'); } // --- Utilities & Exports --- function showLoader() { UI.loader.classList.remove('hidden'); } function hideLoader() { UI.loader.classList.add('hidden'); } function showToast(message, type = 'success') { const toast = document.createElement('div'); toast.className = `toast ${type === 'warning' ? 'warning' : ''}`; if(type === 'warning') { toast.style.background = 'var(--warning)'; toast.style.color = '#000'; } toast.innerText = message; document.body.appendChild(toast); setTimeout(() => { toast.style.opacity = '0'; setTimeout(() => toast.remove(), 300); }, 3000); } function copyActiveOutput() { const content = document.getElementById(appState.activeTab).innerText; if(!content.trim()) return showToast('Nothing to copy!', 'warning'); navigator.clipboard.writeText(content).then(() => { showToast('Copied to clipboard!'); }).catch(() => { // Fallback for Canvas iframe const textArea = document.createElement("textarea"); textArea.value = content; document.body.appendChild(textArea); textArea.select(); document.execCommand("copy"); textArea.remove(); showToast('Copied to clipboard!'); }); } function handleExport() { const format = document.getElementById('exportFormat').value; const dataStr = gatherAllOutputText(); const filename = `MascotVerse_${appState.inputs.baseType || 'Project'}`; if(format === 'pdf') { window.print(); return; } let blob, url; if(format === 'txt') { blob = new Blob([dataStr], { type: 'text/plain' }); } else if (format === 'json') { blob = new Blob([JSON.stringify({inputs: appState.inputs, outputs: appState.outputs}, null, 2)], { type: 'application/json' }); } else if (format === 'html') { const htmlContent = `<html><body><h1>${filename}</h1><pre>${dataStr}</pre></body></html>`; blob = new Blob([htmlContent], { type: 'text/html' }); } url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = `${filename}.${format}`; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); showToast(`Downloaded as .${format.toUpperCase()}`); } function gatherAllOutputText() { let str = "MASCOTVERSE EXPORT\n\n"; Object.keys(appState.outputs).forEach(key => { if(appState.outputs[key]) { // Quick strip HTML tags for clean text export let text = appState.outputs[key].replace(/<[^>]+>/g, '\n').replace(/\n\s*\n/g, '\n\n').trim(); str += `--- ${key.toUpperCase()} ---\n${text}\n\n`; } }); return str; } // --- Local Storage Project Manager --- function loadProjectsFromStorage() { try { const saved = localStorage.getItem('mascotVerseProjects'); if(saved) { appState.projects = JSON.parse(saved); } } catch(e) { console.error("Storage access error"); } renderProjectList(); } function saveCurrentProject() { if(!appState.outputs.system) { showToast("Generate a project first before saving.", "warning"); return; } const projName = `${appState.inputs.personality} ${appState.inputs.baseType}`; const proj = { id: Date.now(), name: projName, date: new Date().toLocaleDateString(), inputs: { ...appState.inputs }, outputs: { ...appState.outputs }, score: appState.score }; appState.projects.push(proj); try { localStorage.setItem('mascotVerseProjects', JSON.stringify(appState.projects)); UI.activeProjectName.innerText = projName; showToast("Project Saved Locally!"); renderProjectList(); } catch(e) { showToast("Failed to save. Storage might be full or restricted.", "warning"); } } function renderProjectList() { UI.projectCount.innerText = appState.projects.length; if(appState.projects.length === 0) { UI.projectList.innerHTML = '<p class="text-center" style="font-size: 0.875rem; color: var(--text-muted);">No saved projects.</p>'; return; } UI.projectList.innerHTML = ''; appState.projects.slice().reverse().forEach(p => { const item = document.createElement('div'); item.className = 'card flex justify-between items-center'; item.style.padding = '0.5rem'; item.style.borderWidth = '1px'; item.innerHTML = ` <div style="flex:1; cursor:pointer;" class="load-proj" data-id="${p.id}"> <div style="font-weight:600; font-size:0.875rem;">${p.name}</div> <div style="font-size:0.75rem; color:var(--text-muted);">${p.date} | Score: ${p.score}</div> </div> <button class="btn btn-danger btn-small del-proj" data-id="${p.id}" title="Delete">✕</button> `; UI.projectList.appendChild(item); }); // Bind load/delete document.querySelectorAll('.load-proj').forEach(el => { el.addEventListener('click', (e) => { if(e.target.closest('.del-proj')) return; loadProjectById(parseInt(el.dataset.id)); }); }); document.querySelectorAll('.del-proj').forEach(el => { el.addEventListener('click', (e) => { deleteProject(parseInt(el.dataset.id)); }); }); } function loadProjectById(id) { const proj = appState.projects.find(p => p.id === id); if(!proj) return; appState.inputs = proj.inputs; appState.outputs = proj.outputs; appState.score = proj.score; // Re-populate form UI.baseType.value = proj.inputs.baseType; UI.targetAudience.value = proj.inputs.targetAudience; UI.useCase.value = proj.inputs.useCase; UI.themeWorld.value = proj.inputs.themeWorld; UI.personality.value = proj.inputs.personality; UI.visualStyle.value = proj.inputs.visualStyle; UI.signatureProp.value = proj.inputs.signatureProp; UI.ipSafety.value = proj.inputs.ipSafety || 'Strict'; UI.scoreCircle.innerText = appState.score; UI.activeProjectName.innerText = proj.name; UI.emptyState.classList.add('hidden'); UI.generatedState.classList.remove('hidden'); renderOutputs(); showToast("Project Loaded!"); } function deleteProject(id) { appState.projects = appState.projects.filter(p => p.id !== id); localStorage.setItem('mascotVerseProjects', JSON.stringify(appState.projects)); renderProjectList(); showToast("Project Deleted"); } function clearProjects() { if(confirm("Are you sure you want to delete all saved projects locally?")) { appState.projects = []; localStorage.removeItem('mascotVerseProjects'); renderProjectList(); showToast("All Projects Cleared"); } } // Start App document.addEventListener('DOMContentLoaded', init); </script> </body> </html>
♊️ Gemini

Story Mascot Studio Web App Builder

Add to Cart
Instant accessInstant access
Usage rightsCommercial use
Money-back guaranteeMoney‑back
By purchasing this prompt, you agree to our terms of service
GEMINI-3.1-PRO
Tested icon
Guide icon
4 examples icon
Free credits icon
Gemini mascot generator web app from simple inputs. No coding skill or special setup needed.
...more
Added 1 week ago
Report
Browse Marketplace