Nuzhatwa's picture
Update index.html
880eede verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Branded Image Edit Prompt Builder</title>
<script src="https://cdn.tailwindcss.com"></script>
<style>
/* ================================================= */
/* 🟣 BRANDING AND DESIGN GUIDE STYLES 🟣 */
/* ================================================= */
:root {
/* 1. Color Palette */
--primary-purple: #8A2BE2; /* Heading, Button Hover, Top Border */
--accent-purple: #F3E5F5; /* Light Background (Output/Results) */
--text-color: #6A1B9A; /* Deep Purple Text */
--main-background: #ffffff; /* Main Body Background (White) */
--container-background: #f9f9f9; /* Card Background (Light Gray) */
--button-border: #D1C4E9; /* Light Button Border */
/* 2. Sizing & Layout */
--max-width: 450px; /* Note: The original template uses max-w-5xl, using 450px for container style */
--border-radius: 15px;
--button-radius: 8px;
--padding: 30px;
}
body {
font-family: sans-serif; /* 3. Typography */
background-color: var(--main-background) !important;
color: #333;
min-height: 100vh;
}
/* ------------------- HEADER ------------------- */
header {
border-bottom: 1px solid var(--button-border) !important;
background-color: var(--main-background) !important;
}
header h1 {
color: var(--primary-purple); /* Heading Color */
font-size: 2em !important;
font-weight: bold;
}
/* ------------------- MAIN LAYOUT & CARDS ------------------- */
main {
max-width: 1000px; /* Keeping a wider layout for this builder */
margin: 0 auto;
padding: 24px 1rem;
}
.builder-card, .output-card {
background-color: var(--container-background) !important;
padding: var(--padding) !important;
border-radius: var(--border-radius) !important;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1) !important;
border-top: 5px solid var(--primary-purple); /* Top Border */
}
.builder-card h2, .output-card h2 {
color: var(--primary-purple);
font-size: 1.5em !important;
margin-bottom: 15px;
}
/* ------------------- INPUTS / SELECTS ------------------- */
select, input[type="text"], textarea {
width: 100%;
padding: 20px !important; /* Input Padding: 20px */
border-radius: var(--button-radius) !important;
border: 1px solid var(--button-border) !important;
background-color: var(--main-background) !important;
color: #333 !important;
font-size: 1em !important;
box-sizing: border-box;
transition: border-color 0.2s, box-shadow 0.2s;
outline: none;
}
select:focus, input[type="text"]:focus, textarea:focus {
border-color: var(--primary-purple) !important;
box-shadow: 0 0 0 3px rgba(138, 43, 226, 0.2) !important; /* Soft purple focus ring */
}
/* Output Textarea Specifics */
#output {
background-color: var(--accent-purple) !important; /* Accent Purple Background */
color: var(--text-color) !important; /* Deep Purple Text */
font-size: 1.1em !important;
font-weight: bold;
resize: none;
}
/* ------------------- BUTTONS ------------------- */
.btn {
padding: 10px 15px !important;
border-radius: var(--button-radius) !important;
font-size: 0.9em !important;
font-weight: bold !important;
transition: all 0.2s ease-in-out;
border: 1px solid var(--button-border);
cursor: pointer;
text-decoration: none;
display: inline-block;
}
/* Primary Button (Copy) */
.btn-primary {
background-color: var(--primary-purple) !important;
color: var(--main-background) !important;
}
.btn-primary:hover {
background-color: #6A1B9A !important;
color: var(--main-background) !important;
}
/* Secondary Button (Reset, Download) */
.btn-secondary {
background-color: var(--accent-purple) !important;
color: var(--text-color) !important;
}
.btn-secondary:hover {
background-color: var(--primary-purple) !important;
color: var(--main-background) !important;
border-color: var(--primary-purple);
}
/* Overriding header button style */
#copyBtnHeader {
padding: 15px 20px !important;
font-size: 1em !important;
}
/* Details Summary Styling */
details summary {
cursor: pointer;
font-weight: 500;
color: var(--text-color);
transition: color 0.2s;
}
details summary:hover {
color: var(--primary-purple);
}
.text-sm-info {
font-size: 0.75rem;
color: #888;
margin-top: 5px;
}
</style>
</head>
<body class="min-h-screen bg-slate-50 text-slate-800">
<header class="sticky top-0 z-10 bg-white/80 backdrop-blur border-b border-slate-200">
<div class="max-w-5xl mx-auto px-4 py-4 flex items-center justify-between">
<h1 class="text-xl sm:text-2xl font-bold tracking-tight">Adding & Removing Elements</h1>
<a href="#" id="copyBtnHeader" class="btn btn-primary">Copy Prompt</a>
</div>
</header>
<main class="max-w-5xl mx-auto px-4 py-6 grid lg:grid-cols-2 gap-6">
<section class="builder-card p-5">
<div class="flex items-start justify-between">
<h2>Minimal Selections</h2>
<button id="resetBtn" class="btn btn-secondary">Reset</button>
</div>
<div class="mt-4 grid gap-5">
<div>
<label for="editType" class="block text-sm font-medium" style="color: var(--text-color);">Edit Type</label>
<select id="editType" class="mt-2 w-full p-3">
<option value="add">Add</option>
<option value="remove">Remove</option>
<option value="modify">Modify</option>
</select>
</div>
<div>
<label for="element" class="block text-sm font-medium" style="color: var(--text-color);">Element (what to add/remove/modify)</label>
<input id="element" type="text" placeholder="e.g., a red umbrella / the logo on the wall / background sky" class="mt-2 w-full p-3" />
</div>
<div>
<label for="integration" class="block text-sm font-medium" style="color: var(--text-color);">Integration (how it should fit)</label>
<select id="integration" class="mt-2 w-full p-3">
<option value="blends naturally and looks realistic">Blend naturally and look realistic</option>
<option value="matches the scene lighting and perspective">Match lighting and perspective</option>
<option value="keeps consistent color and texture with the scene">Keep consistent color and texture</option>
<option value="appears slightly stylized but remains believable">Slightly stylized but natural</option>
</select>
</div>
<details class="mt-1">
<summary>Optional: brief context</summary>
<div class="mt-3 grid gap-3">
<input id="context" type="text" placeholder="e.g., indoor daylight / cinematic low‑light / product photo" class="p-3" />
<input id="locationHint" type="text" placeholder="Optional location hint (e.g., left side / near window)" class="p-3" />
</div>
</details>
</div>
</section>
<section class="output-card p-5">
<div class="flex items-start justify-between">
<h2>Prompt Output</h2>
<div class="flex gap-2">
<button id="copyBtn" class="btn btn-primary">Copy</button>
<button id="downloadBtn" class="btn btn-secondary">Download .txt</button>
</div>
</div>
<p class="text-sm-info">Prompt updates automatically as you type.</p>
<textarea id="output" rows="12" class="mt-3 w-full p-4 font-mono text-sm"></textarea>
<div class="mt-4 text-sm-info">
<p><strong>Template</strong>: Using the provided image, <em>[add/remove/modify]</em> <em>[element]</em>, ensuring it <em>[integration]</em> within the scene. <em>(Optional: context/location)</em>.</p>
</div>
</section>
</main>
<footer class="max-w-5xl mx-auto px-4 pb-10 text-center text-xs" style="color: #888;">Coach Pro AI</footer>
<script>
const getEl = id => document.getElementById(id);
const editTypeEl = getEl('editType');
const elementEl = getEl('element');
const integrationEl = getEl('integration');
const contextEl = getEl('context');
const locationHintEl = getEl('locationHint');
const outputEl = getEl('output');
const copyBtn = getEl('copyBtn');
const copyBtnHeader = getEl('copyBtnHeader');
const downloadBtn = getEl('downloadBtn');
const resetBtn = getEl('resetBtn');
function buildPrompt(){
const t = editTypeEl.value || 'add';
const el = (elementEl.value || '[element]').trim();
const integ = integrationEl.value || 'blends naturally and looks realistic';
const ctx = (contextEl.value || '').trim();
const loc = (locationHintEl.value || '').trim();
let prompt = `Using the provided image, ${t} ${el}, ensuring it ${integ} within the scene.`;
const extras = [];
if(ctx) extras.push(ctx);
if(loc) extras.push(`place near ${loc}`);
if(extras.length) {
prompt += ` Context: ${extras.join('; ')}.`;
} else {
prompt += ` Please ensure a photorealistic result.`;
}
outputEl.value = prompt;
}
function copyPrompt(){
outputEl.select();
document.execCommand('copy');
const toast = document.createElement('div');
toast.textContent = 'Prompt copied!';
toast.className = 'fixed bottom-6 right-6 px-4 py-2 rounded-xl shadow-lg';
toast.style.cssText = `
background-color: var(--primary-purple);
color: white;
z-index: 1000;
transition: opacity 0.3s;
`;
document.body.appendChild(toast);
setTimeout(() => {
toast.style.opacity = '0';
setTimeout(() => toast.remove(), 300);
}, 1500);
}
function downloadPrompt(){
const blob = new Blob([outputEl.value], { type: 'text/plain' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'image-edit-prompt.txt';
a.click();
URL.revokeObjectURL(url);
}
function resetAll(){
editTypeEl.value = 'add';
elementEl.value = '';
integrationEl.value = 'blends naturally and looks realistic';
contextEl.value = '';
locationHintEl.value = '';
buildPrompt();
}
// Event bindings
[editTypeEl, elementEl, integrationEl, contextEl, locationHintEl].forEach(el=>{
el.addEventListener('input', buildPrompt);
el.addEventListener('change', buildPrompt);
});
copyBtn.addEventListener('click', copyPrompt);
copyBtnHeader.addEventListener('click', (e)=>{ e.preventDefault(); copyPrompt(); });
downloadBtn.addEventListener('click', downloadPrompt);
if(resetBtn) resetBtn.addEventListener('click', resetAll);
// Initial build
buildPrompt();
</script>
</body>
</html>