972 lines
48 KiB
HTML
972 lines
48 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en" data-theme="dark">
|
||
<head>
|
||
<meta charset="UTF-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||
<title>SparkVault — Idea Tracker & Visual Mockup Studio</title>
|
||
<link rel="icon" type="image/svg+xml" href="/icon.svg" />
|
||
<link rel="stylesheet" href="/styles.css" />
|
||
</head>
|
||
<body>
|
||
<!-- TOP HEADER & QUICK CAPTURE BAR -->
|
||
<header class="topbar">
|
||
<div class="topbar-brand">
|
||
<div class="brand-logo" aria-hidden="true">⚡</div>
|
||
<div>
|
||
<div class="brand-title-row">
|
||
<h1 class="brand-title">SparkVault</h1>
|
||
<span class="brand-badge">Idea Studio</span>
|
||
</div>
|
||
<p class="brand-subtitle">Capture sparks, attach inspirations, and generate product & apparel mockups</p>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Instant Quick Capture Command Bar -->
|
||
<form id="quick-capture-form" class="quick-capture-bar" autocomplete="off">
|
||
<span class="qc-icon" title="Quick Capture (Ctrl+K)">✨</span>
|
||
<input
|
||
id="quick-capture-input"
|
||
type="text"
|
||
placeholder="Quick capture an idea... e.g. Retro Ski Club Tee @creative #tshirt !high (Ctrl+K)"
|
||
aria-label="Quick capture idea"
|
||
/>
|
||
<select id="quick-capture-category" aria-label="Idea category">
|
||
<option value="spark">⚡ Spark</option>
|
||
<option value="creative">🎨 Creative / Merch</option>
|
||
<option value="project">🛠️ Project / App</option>
|
||
<option value="research">🔬 Research</option>
|
||
</select>
|
||
<button type="submit" class="btn btn-primary btn-sm">Capture</button>
|
||
<button
|
||
type="button"
|
||
id="btn-generate-random-idea"
|
||
class="btn btn-secondary btn-sm"
|
||
title="Generate a personalized random idea tailored to your background"
|
||
>
|
||
🎲 Random Idea
|
||
</button>
|
||
<button
|
||
type="button"
|
||
id="btn-open-external-clip"
|
||
class="btn btn-ghost btn-sm"
|
||
title="Attach external notes, clipboard screenshots, photos, or image URLs to a spark"
|
||
>
|
||
📎 Clip / Attach
|
||
</button>
|
||
</form>
|
||
|
||
<div class="topbar-actions">
|
||
<button type="button" id="btn-open-settings" class="btn btn-ghost btn-sm" title="Configure AI Generator & Personal Background">
|
||
⚙️ <span id="api-key-status-dot" class="status-dot"></span> AI Settings
|
||
</button>
|
||
<div class="dropdown">
|
||
<button type="button" id="btn-export-menu" class="btn btn-ghost btn-sm">⬇️ Export</button>
|
||
<div id="export-dropdown-menu" class="dropdown-menu hidden">
|
||
<a href="/api/export?format=json" download="sparkvault-ideas.json" class="dropdown-item">📦 Export JSON Vault</a>
|
||
<a href="/api/export?format=markdown" download="sparkvault-ideas.md" class="dropdown-item">📝 Export Markdown Book</a>
|
||
</div>
|
||
</div>
|
||
<button type="button" id="btn-theme-toggle" class="btn btn-ghost btn-sm" title="Switch Dark / Warm Paper Theme">
|
||
☀️ Theme
|
||
</button>
|
||
</div>
|
||
</header>
|
||
|
||
<!-- OPTIONAL QUICK WHACK SPARK BANNER -->
|
||
<section id="quick-whack-banner" class="whack-prompt-banner hidden" aria-live="polite">
|
||
<div class="whack-banner-inner">
|
||
<img id="qwb-card-img" src="" alt="Whack Card" class="qwb-thumb" />
|
||
<div class="qwb-content">
|
||
<div class="qwb-meta">
|
||
<span id="qwb-suit-badge" class="suit-pill">Explorer</span>
|
||
<strong id="qwb-card-title">Card #1</strong>
|
||
</div>
|
||
<p id="qwb-card-question" class="qwb-question"></p>
|
||
</div>
|
||
<div class="qwb-actions">
|
||
<button type="button" id="btn-qwb-use" class="btn btn-primary btn-sm">✨ Create Idea from Card</button>
|
||
<button type="button" id="btn-qwb-redraw" class="btn btn-ghost btn-sm">🔄 Draw Another</button>
|
||
<button type="button" id="btn-qwb-close" class="btn btn-ghost btn-sm">✕</button>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- NAVIGATION & STATS STRIP -->
|
||
<nav class="subnav">
|
||
<div class="subnav-top-row">
|
||
<div class="view-tabs" role="tablist">
|
||
<button type="button" class="view-tab active" data-view="board" role="tab">
|
||
📋 Pipeline
|
||
</button>
|
||
<button type="button" class="view-tab" data-view="grid" role="tab">
|
||
🗂️ Explorer
|
||
</button>
|
||
<button type="button" class="view-tab" data-view="review" role="tab">
|
||
⚔️ Arena & Triage
|
||
</button>
|
||
<button type="button" class="view-tab view-tab-subtle" data-view="whack" role="tab" title="Creative Prompts & Whack Pack Deck">
|
||
💡 Prompts
|
||
</button>
|
||
</div>
|
||
<button type="button" id="btn-mobile-filter-toggle" class="btn btn-ghost btn-sm mobile-only">
|
||
🔍 Filters
|
||
</button>
|
||
</div>
|
||
|
||
<div class="filter-bar" id="global-filter-bar">
|
||
<input
|
||
type="search"
|
||
id="filter-search"
|
||
class="filter-input"
|
||
placeholder="Search ideas, notes, #tags..."
|
||
/>
|
||
<select id="filter-category" class="filter-select" aria-label="Filter by category">
|
||
<option value="all">All Categories</option>
|
||
<option value="creative">🎨 Creative / Merch</option>
|
||
<option value="project">🛠️ Project / Product</option>
|
||
<option value="spark">⚡ Quick Spark</option>
|
||
<option value="research">🔬 Research</option>
|
||
</select>
|
||
<select id="filter-tag" class="filter-select" aria-label="Filter by tag">
|
||
<option value="all">All #Tags</option>
|
||
</select>
|
||
<label class="filter-checkbox">
|
||
<input type="checkbox" id="filter-has-mockup" />
|
||
<span>🖼️ Has Mockup (<span id="stat-mockups-count">0</span>)</span>
|
||
</label>
|
||
<select id="filter-sort" class="filter-select" aria-label="Sort ideas">
|
||
<option value="score">Sort: Priority Score</option>
|
||
<option value="excitement">Sort: Excitement</option>
|
||
<option value="arena">Sort: Arena Wins</option>
|
||
<option value="updated">Sort: Recently Updated</option>
|
||
<option value="newest">Sort: Newest First</option>
|
||
</select>
|
||
<button type="button" id="btn-clear-filters" class="btn btn-ghost btn-sm hidden" title="Clear active filters">
|
||
✕ Reset
|
||
</button>
|
||
</div>
|
||
</nav>
|
||
|
||
<!-- MAIN WORKSPACE -->
|
||
<main class="workspace">
|
||
<!-- VIEW 1: PIPELINE KANBAN BOARD -->
|
||
<section id="view-board" class="view-section active">
|
||
<!-- Mobile Stage Switcher Pills -->
|
||
<div class="mobile-stage-switcher mobile-only" id="mobile-stage-switcher">
|
||
<button type="button" class="stage-tab active" data-mobile-stage="spark">
|
||
✨ Spark <span class="stage-tab-count" id="mcount-spark">0</span>
|
||
</button>
|
||
<button type="button" class="stage-tab" data-mobile-stage="exploring">
|
||
🔍 Exploring <span class="stage-tab-count" id="mcount-exploring">0</span>
|
||
</button>
|
||
<button type="button" class="stage-tab" data-mobile-stage="building">
|
||
🛠️ Building <span class="stage-tab-count" id="mcount-building">0</span>
|
||
</button>
|
||
<button type="button" class="stage-tab" data-mobile-stage="shipped">
|
||
🚀 Shipped <span class="stage-tab-count" id="mcount-shipped">0</span>
|
||
</button>
|
||
<button type="button" class="stage-tab" data-mobile-stage="archived">
|
||
📦 Archived <span class="stage-tab-count" id="mcount-archived">0</span>
|
||
</button>
|
||
<button type="button" class="stage-tab" data-mobile-stage="all">
|
||
All
|
||
</button>
|
||
</div>
|
||
<div class="kanban-board" id="kanban-board" data-mobile-active-stage="spark">
|
||
<div class="kanban-column" data-status="spark">
|
||
<div class="kanban-col-header">
|
||
<div>
|
||
<span class="status-dot status-spark"></span>
|
||
<h2>✨ Spark</h2>
|
||
<span class="role-hint">Raw Ideas</span>
|
||
</div>
|
||
<span class="col-count" id="count-spark">0</span>
|
||
</div>
|
||
<div class="kanban-dropzone" data-status="spark" id="col-spark"></div>
|
||
</div>
|
||
|
||
<div class="kanban-column" data-status="exploring">
|
||
<div class="kanban-col-header">
|
||
<div>
|
||
<span class="status-dot status-exploring"></span>
|
||
<h2>🔍 Exploring</h2>
|
||
<span class="role-hint">Research & Mockups</span>
|
||
</div>
|
||
<span class="col-count" id="count-exploring">0</span>
|
||
</div>
|
||
<div class="kanban-dropzone" data-status="exploring" id="col-exploring"></div>
|
||
</div>
|
||
|
||
<div class="kanban-column" data-status="building">
|
||
<div class="kanban-col-header">
|
||
<div>
|
||
<span class="status-dot status-building"></span>
|
||
<h2>🛠️ Building</h2>
|
||
<span class="role-hint">In Progress</span>
|
||
</div>
|
||
<span class="col-count" id="count-building">0</span>
|
||
</div>
|
||
<div class="kanban-dropzone" data-status="building" id="col-building"></div>
|
||
</div>
|
||
|
||
<div class="kanban-column" data-status="shipped">
|
||
<div class="kanban-col-header">
|
||
<div>
|
||
<span class="status-dot status-shipped"></span>
|
||
<h2>🚀 Shipped</h2>
|
||
<span class="role-hint">Launched</span>
|
||
</div>
|
||
<span class="col-count" id="count-shipped">0</span>
|
||
</div>
|
||
<div class="kanban-dropzone" data-status="shipped" id="col-shipped"></div>
|
||
</div>
|
||
|
||
<div class="kanban-column" data-status="archived">
|
||
<div class="kanban-col-header">
|
||
<div>
|
||
<span class="status-dot status-archived"></span>
|
||
<h2>📦 Archived</h2>
|
||
<span class="role-hint">Parked Vault</span>
|
||
</div>
|
||
<span class="col-count" id="count-archived">0</span>
|
||
</div>
|
||
<div class="kanban-dropzone" data-status="archived" id="col-archived"></div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- VIEW 2: EXPLORER GRID & MOCKUP GALLERY -->
|
||
<section id="view-grid" class="view-section hidden">
|
||
<div class="grid-toolbar">
|
||
<div class="status-pills" id="grid-status-pills">
|
||
<button type="button" class="pill-btn active" data-status="all">All Stages</button>
|
||
<button type="button" class="pill-btn" data-status="spark">✨ Spark</button>
|
||
<button type="button" class="pill-btn" data-status="exploring">🔍 Exploring</button>
|
||
<button type="button" class="pill-btn" data-status="building">🛠️ Building</button>
|
||
<button type="button" class="pill-btn" data-status="shipped">🚀 Shipped</button>
|
||
<button type="button" class="pill-btn" data-status="archived">📦 Archived</button>
|
||
</div>
|
||
<button type="button" id="btn-new-idea-modal" class="btn btn-primary btn-sm">+ New Detailed Idea</button>
|
||
</div>
|
||
<div id="explorer-grid" class="explorer-grid"></div>
|
||
</section>
|
||
|
||
<!-- VIEW 3: CREATIVE WHACK PACK STUDIO (64 CARDS) -->
|
||
<section id="view-whack" class="view-section hidden">
|
||
<div class="whack-studio-header">
|
||
<div>
|
||
<h2>🃏 Creative Whack Pack Catalyst Studio</h2>
|
||
<p>64 lateral-thinking strategies by Roger von Oech across 4 creative roles: <strong>🧭 Explorer (1–16)</strong>, <strong>🎨 Artist (17–32)</strong>, <strong>⚖️ Judge (33–48)</strong>, and <strong>⚔️ Warrior (49–64)</strong>.</p>
|
||
</div>
|
||
<div class="whack-mode-tabs">
|
||
<button type="button" class="pill-btn active" data-whack-mode="collider">⚡ Idea Collider (Card + Idea)</button>
|
||
<button type="button" class="pill-btn" data-whack-mode="spread">🎴 4-Role Creative Spread</button>
|
||
<button type="button" class="pill-btn" data-whack-mode="browser">📚 Browse All 64 Cards</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- SUB-MODE A: IDEA COLLIDER -->
|
||
<div id="whack-submode-collider" class="whack-submode">
|
||
<div class="collider-controls">
|
||
<div class="collider-control-group">
|
||
<label for="collider-suit-select">Filter Suit:</label>
|
||
<select id="collider-suit-select" class="filter-select">
|
||
<option value="">Stage-Matched / Any Suit</option>
|
||
<option value="explorer">🧭 Explorer (1–16: Gather & Discover)</option>
|
||
<option value="artist">🎨 Artist (17–32: Play & Transform)</option>
|
||
<option value="judge">⚖️ Judge (33–48: Evaluate & Test)</option>
|
||
<option value="warrior">⚔️ Warrior (49–64: Act & Ship)</option>
|
||
</select>
|
||
</div>
|
||
<div class="collider-control-group">
|
||
<label for="collider-idea-select">Target Idea:</label>
|
||
<select id="collider-idea-select" class="filter-select"></select>
|
||
</div>
|
||
<button type="button" id="btn-deal-collider" class="btn btn-primary">
|
||
🎲 Collide Card + Idea
|
||
</button>
|
||
<button type="button" id="btn-collider-random-both" class="btn btn-ghost">
|
||
🔀 Random Card & Random Spark
|
||
</button>
|
||
</div>
|
||
|
||
<div id="collider-stage" class="collider-stage"></div>
|
||
</div>
|
||
|
||
<!-- SUB-MODE B: 4-ROLE SPREAD -->
|
||
<div id="whack-submode-spread" class="whack-submode hidden">
|
||
<div class="spread-bar">
|
||
<p>Deal one card from each role (<strong>Explorer → Artist → Judge → Warrior</strong>) to walk an idea from raw spark to shipped execution.</p>
|
||
<button type="button" id="btn-deal-spread" class="btn btn-primary">🎴 Deal Fresh 4-Role Spread</button>
|
||
</div>
|
||
<div id="spread-grid" class="spread-grid"></div>
|
||
</div>
|
||
|
||
<!-- SUB-MODE C: 64-CARD DECK BROWSER -->
|
||
<div id="whack-submode-browser" class="whack-submode hidden">
|
||
<div class="deck-filter-bar">
|
||
<div class="suit-filter-buttons" id="deck-suit-filters">
|
||
<button type="button" class="pill-btn active" data-suit="all">All 64 Cards</button>
|
||
<button type="button" class="pill-btn suit-explorer-btn" data-suit="explorer">🧭 Explorer (1–16)</button>
|
||
<button type="button" class="pill-btn suit-artist-btn" data-suit="artist">🎨 Artist (17–32)</button>
|
||
<button type="button" class="pill-btn suit-judge-btn" data-suit="judge">⚖️ Judge (33–48)</button>
|
||
<button type="button" class="pill-btn suit-warrior-btn" data-suit="warrior">⚔️ Warrior (49–64)</button>
|
||
</div>
|
||
<input type="search" id="deck-search-input" class="filter-input" placeholder="Search 64 cards by title, number, or prompt..." />
|
||
</div>
|
||
<div id="deck-cards-grid" class="deck-cards-grid"></div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- VIEW 4: REVIEW & HEAD-TO-HEAD ARENA -->
|
||
<section id="view-review" class="view-section hidden">
|
||
<div class="review-header">
|
||
<div>
|
||
<h2>⚔️ Idea Resurfacing & Prioritization Studio</h2>
|
||
<p>Prevent the idea graveyard: pit ideas head-to-head to find what excites you most, or triage older sparks one card at a time.</p>
|
||
</div>
|
||
<div class="review-mode-tabs">
|
||
<button type="button" class="pill-btn active" data-review-mode="arena">⚔️ Head-to-Head Arena</button>
|
||
<button type="button" class="pill-btn" data-review-mode="triage">🃏 Stale Spark Triage Deck</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="review-submode-arena" class="review-submode">
|
||
<div class="arena-instructions">
|
||
<span>Which idea excites you more to work on or prototype next?</span>
|
||
<button type="button" id="btn-skip-arena" class="btn btn-ghost btn-sm">🔀 Skip / Deal New Pair</button>
|
||
</div>
|
||
<div id="arena-stage" class="arena-stage"></div>
|
||
</div>
|
||
|
||
<div id="review-submode-triage" class="review-submode hidden">
|
||
<div id="triage-stage" class="triage-stage"></div>
|
||
</div>
|
||
</section>
|
||
</main>
|
||
|
||
<!-- SLIDE-OVER RICH IDEA WORKBENCH & NANO BANANA MOCKUP STUDIO -->
|
||
<div id="drawer-backdrop" class="drawer-backdrop hidden"></div>
|
||
<aside id="idea-drawer" class="idea-drawer hidden" aria-label="Idea Workbench">
|
||
<div class="drawer-header">
|
||
<div class="drawer-title-group">
|
||
<div class="drawer-title-row">
|
||
<input type="text" id="drawer-title-input" class="drawer-title-input" placeholder="Idea Title" />
|
||
<button type="button" id="btn-suggest-names" class="btn btn-secondary btn-xs" title="Brainstorm 6 creative names & taglines for this idea">
|
||
✨ Suggest Names
|
||
</button>
|
||
</div>
|
||
<div id="drawer-name-suggestions-panel" class="name-suggestions-panel hidden"></div>
|
||
<div class="drawer-meta-row">
|
||
<select id="drawer-status-select" class="drawer-select">
|
||
<option value="spark">✨ Spark</option>
|
||
<option value="exploring">🔍 Exploring</option>
|
||
<option value="building">🛠️ Building</option>
|
||
<option value="shipped">🚀 Shipped</option>
|
||
<option value="archived">📦 Archived</option>
|
||
</select>
|
||
<select id="drawer-category-select" class="drawer-select">
|
||
<option value="creative">🎨 Creative / Merch</option>
|
||
<option value="project">🛠️ Project / Product</option>
|
||
<option value="spark">⚡ Quick Spark</option>
|
||
<option value="research">🔬 Research</option>
|
||
</select>
|
||
<button type="button" id="drawer-pin-btn" class="btn btn-ghost btn-sm" title="Pin Idea">📌 Pin</button>
|
||
<span id="drawer-score-badge" class="score-badge">Score: 75</span>
|
||
</div>
|
||
</div>
|
||
<div class="drawer-header-actions">
|
||
<button type="button" id="btn-open-dev-handoff" class="btn btn-primary btn-sm" title="Submit all Spark info, specs, and mockups to Antigravity or OpenAI Codex for development">
|
||
🚀 Send to Dev
|
||
</button>
|
||
<button type="button" id="drawer-delete-btn" class="btn btn-danger-ghost btn-sm" title="Delete Idea">🗑️</button>
|
||
<button type="button" id="drawer-close-btn" class="btn btn-ghost btn-sm" title="Close (Esc)">✕ Close</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- DRAWER SUB-TABS -->
|
||
<div class="drawer-tabs">
|
||
<button type="button" class="drawer-tab active" data-drawer-tab="details">
|
||
📝 Workbench & Notes
|
||
</button>
|
||
<button type="button" class="drawer-tab" data-drawer-tab="mockup">
|
||
🖼️ Image Mockup Studio <span id="drawer-mockup-count" class="tab-pill">0</span>
|
||
</button>
|
||
<button type="button" class="drawer-tab" data-drawer-tab="whack">
|
||
💡 Brainstorm Prompts <span id="drawer-whack-count" class="tab-pill">0</span>
|
||
</button>
|
||
</div>
|
||
|
||
<div class="drawer-body">
|
||
<!-- TAB 1: DETAILS, NOTES, CHECKLIST, PROS/CONS, RATINGS -->
|
||
<div id="drawer-tab-details" class="drawer-tab-panel active">
|
||
<!-- Main Spark Cover Thumbnail & Elevator Pitch Hero -->
|
||
<div class="spark-main-hero">
|
||
<div id="drawer-main-thumb-box" class="spark-main-thumb-box"></div>
|
||
<div class="spark-main-pitch-col">
|
||
<div class="field-group">
|
||
<label for="drawer-pitch-input">Elevator Pitch (One-sentence essence)</label>
|
||
<input type="text" id="drawer-pitch-input" class="text-input" placeholder="What makes this idea compelling in one sentence?" />
|
||
</div>
|
||
|
||
<!-- Markdown Notes -->
|
||
<div class="field-group">
|
||
<div class="field-header-row">
|
||
<label for="drawer-notes-input">Specs, Brainstorm & Markdown Notes</label>
|
||
<button type="button" id="btn-toggle-md-preview" class="btn btn-ghost btn-xs">👁️ Toggle Preview</button>
|
||
</div>
|
||
<textarea id="drawer-notes-input" rows="6" class="textarea-input" placeholder="Write specs, architecture notes, concept details, or markdown lists..."></textarea>
|
||
<div id="drawer-notes-preview" class="markdown-preview hidden"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Action Checklist -->
|
||
<div class="field-group">
|
||
<div class="field-header-row">
|
||
<label>Action Checklist</label>
|
||
<span id="drawer-checklist-progress" class="muted-label">0/0 completed</span>
|
||
</div>
|
||
<div id="drawer-checklist-items" class="checklist-container"></div>
|
||
<form id="drawer-add-checklist-form" class="inline-add-form">
|
||
<input type="text" id="drawer-new-checklist-input" class="text-input input-sm" placeholder="Add next concrete step..." />
|
||
<button type="submit" class="btn btn-secondary btn-sm">+ Add Step</button>
|
||
</form>
|
||
</div>
|
||
|
||
<!-- Pros & Cons Matrix -->
|
||
<div class="pros-cons-grid">
|
||
<div class="field-group">
|
||
<label>✅ Pros / Why It Works</label>
|
||
<ul id="drawer-pros-list" class="bullet-list pros-list"></ul>
|
||
<form id="drawer-add-pro-form" class="inline-add-form">
|
||
<input type="text" id="drawer-new-pro-input" class="text-input input-sm" placeholder="Add a pro..." />
|
||
<button type="submit" class="btn btn-ghost btn-sm">+</button>
|
||
</form>
|
||
</div>
|
||
<div class="field-group">
|
||
<label>⚠️ Cons / Risks & Constraints</label>
|
||
<ul id="drawer-cons-list" class="bullet-list cons-list"></ul>
|
||
<form id="drawer-add-con-form" class="inline-add-form">
|
||
<input type="text" id="drawer-new-con-input" class="text-input input-sm" placeholder="Add a risk or constraint..." />
|
||
<button type="submit" class="btn btn-ghost btn-sm">+</button>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- External Attachments: Clipped Notes, Screenshots & Reference Images -->
|
||
<div class="field-group">
|
||
<div class="field-header-row">
|
||
<label>📎 Attached External Notes & Reference Images (<span id="drawer-attachments-count">0</span>)</label>
|
||
<span class="muted-label">Paste (Ctrl+V), drop files, or clip from URL</span>
|
||
</div>
|
||
|
||
<div id="drawer-attachment-dropzone" class="attachment-dropzone">
|
||
<div class="dropzone-header">
|
||
<span>📥 <strong>Drop image here</strong>, press <kbd>Ctrl+V</kbd> to paste a screenshot, or attach a note/URL below:</span>
|
||
<label class="btn btn-secondary btn-xs" style="cursor:pointer;">
|
||
📷 Choose Image / Camera
|
||
<input type="file" id="drawer-attach-file-input" accept="image/*" hidden />
|
||
</label>
|
||
</div>
|
||
|
||
<div id="drawer-attach-preview-row" class="attach-preview-row hidden">
|
||
<img id="drawer-attach-preview-img" src="" alt="Staged attachment" />
|
||
<div style="flex:1;">
|
||
<strong style="font-size:0.82rem;">Staged Image Ready to Attach</strong>
|
||
<p class="muted-label">Add an optional caption or note below and click Attach.</p>
|
||
</div>
|
||
<button type="button" id="btn-drawer-clear-staged-img" class="btn btn-ghost btn-xs">✕ Remove</button>
|
||
</div>
|
||
|
||
<div class="form-row-2">
|
||
<input type="text" id="drawer-attach-title" class="text-input input-sm" placeholder="Title / Caption (e.g. Concept Sketch Ref)" />
|
||
<input type="url" id="drawer-attach-url" class="text-input input-sm" placeholder="External Image URL or Source Link (https://...)" />
|
||
</div>
|
||
<textarea id="drawer-attach-text" rows="2" class="textarea-input" placeholder="Paste external note, quote, spec snippet, or commentary..."></textarea>
|
||
<div style="display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:0.5rem;">
|
||
<div style="display:flex;gap:0.85rem;flex-wrap:wrap;">
|
||
<label class="filter-checkbox">
|
||
<input type="checkbox" id="drawer-attach-append-notes" />
|
||
<span>Also append text to Markdown Notes</span>
|
||
</label>
|
||
<label class="filter-checkbox">
|
||
<input type="checkbox" id="drawer-attach-set-cover" />
|
||
<span>Set image as Spark Cover</span>
|
||
</label>
|
||
</div>
|
||
<button type="button" id="btn-drawer-save-attachment" class="btn btn-primary btn-sm">
|
||
📎 Attach to Spark
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="drawer-attachments-list" class="attachments-grid"></div>
|
||
</div>
|
||
|
||
<!-- Reference Links -->
|
||
<div class="field-group">
|
||
<label>🔗 Reference Links & Inspiration</label>
|
||
<div id="drawer-links-list" class="links-list"></div>
|
||
<form id="drawer-add-link-form" class="inline-add-form">
|
||
<input type="text" id="drawer-link-title" class="text-input input-sm" placeholder="Label (e.g. Spec Doc)" />
|
||
<input type="url" id="drawer-link-url" class="text-input input-sm" placeholder="https://..." />
|
||
<button type="submit" class="btn btn-ghost btn-sm">+ Add Link</button>
|
||
</form>
|
||
</div>
|
||
|
||
<!-- Tags (Moved down the page) -->
|
||
<div class="field-group">
|
||
<label>Tags</label>
|
||
<div class="tags-editor">
|
||
<div id="drawer-tags-list" class="tags-list"></div>
|
||
<form id="drawer-add-tag-form" class="inline-add-form">
|
||
<input type="text" id="drawer-new-tag-input" class="text-input input-sm" placeholder="Add #tag..." />
|
||
<button type="submit" class="btn btn-ghost btn-sm">+ Add</button>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Prioritization Sliders (Moved down the page) -->
|
||
<div class="field-group">
|
||
<label>Prioritization Ratings</label>
|
||
<div class="ratings-card">
|
||
<div class="rating-control">
|
||
<label for="slider-excitement">🔥 Excitement: <strong id="val-excitement">3</strong>/5</label>
|
||
<input type="range" id="slider-excitement" min="1" max="5" step="1" value="3" />
|
||
</div>
|
||
<div class="rating-control">
|
||
<label for="slider-impact">🎯 Impact: <strong id="val-impact">3</strong>/5</label>
|
||
<input type="range" id="slider-impact" min="1" max="5" step="1" value="3" />
|
||
</div>
|
||
<div class="rating-control">
|
||
<label for="slider-ease">⚡ Ease / Feasibility: <strong id="val-ease">3</strong>/5</label>
|
||
<input type="range" id="slider-ease" min="1" max="5" step="1" value="3" />
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- TAB 2: IMAGE MOCKUP STUDIO -->
|
||
<div id="drawer-tab-mockup" class="drawer-tab-panel hidden">
|
||
<div class="mockup-studio-layout">
|
||
<!-- Left: Generator & Interactive T-Shirt / Product Compositor -->
|
||
<div class="mockup-controls-pane">
|
||
<div class="studio-card">
|
||
<div class="studio-card-header">
|
||
<h3>🖼️ Image Mockup Studio</h3>
|
||
<button type="button" id="btn-studio-auto-prompt" class="btn btn-ghost btn-xs">✨ Auto-Prompt from Idea</button>
|
||
</div>
|
||
|
||
<div class="field-group">
|
||
<label for="nb-generator-select">AI Image Generator Engine</label>
|
||
<select id="nb-generator-select" class="filter-select full-width">
|
||
<option value="codex-image-gen">🤖 OpenAI Codex (gpt-5.6-sol / Built-in image_gen) — High-Res PNG</option>
|
||
<option value="gemini-nano-banana-2.1">✨ Google Gemini (Nano Banana 2.1 / Flash-Lite Vector Fallback)</option>
|
||
<option value="gemini-3-pro-image">🎨 Google Gemini Pro Image (Studio Detail)</option>
|
||
<option value="gemini-3.1-flash-lite-image">⚡ Google Gemini Flash-Lite Image (Fast Sketch)</option>
|
||
</select>
|
||
</div>
|
||
|
||
<div class="form-row-2">
|
||
<div>
|
||
<label for="nb-template-select">Product / Surface Preset</label>
|
||
<select id="nb-template-select" class="filter-select full-width">
|
||
<option value="tshirt-front">👕 T-Shirt (Full-Front Graphic)</option>
|
||
<option value="tshirt-left-chest">👕 T-Shirt (5-in Left-Chest Emblem)</option>
|
||
<option value="isolated-graphic">🎨 Isolated Screenprint Vector Artwork</option>
|
||
<option value="sticker">🏷️ Die-Cut Vinyl Sticker / Patch</option>
|
||
<option value="poster">🖼️ Framed Art Poster</option>
|
||
<option value="app-ui">💻 Product / App Interface</option>
|
||
</select>
|
||
</div>
|
||
<div>
|
||
<label for="nb-whack-twist-select">Optional Prompt Twist</label>
|
||
<select id="nb-whack-twist-select" class="filter-select full-width">
|
||
<option value="">None (Direct Concept)</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Garment / Surface Color Swatches (Only shown when product is a T-Shirt) -->
|
||
<div id="nb-garment-color-group" class="field-group hidden">
|
||
<label>T-Shirt Garment Color: <strong id="nb-selected-color-label">Vintage Cream (#F5E8D3)</strong></label>
|
||
<div class="color-swatch-row" id="nb-color-swatches">
|
||
<button type="button" class="color-swatch active" data-color="#F5E8D3" data-name="Vintage Cream" style="background:#F5E8D3" title="Vintage Cream (#F5E8D3)"></button>
|
||
<button type="button" class="color-swatch" data-color="#1C1B1A" data-name="Vintage Black" style="background:#1C1B1A" title="Vintage Black (#1C1B1A)"></button>
|
||
<button type="button" class="color-swatch" data-color="#1B2A4A" data-name="Midnight Navy" style="background:#1B2A4A" title="Midnight Navy (#1B2A4A)"></button>
|
||
<button type="button" class="color-swatch" data-color="#1E3F2B" data-name="Forest Pine" style="background:#1E3F2B" title="Forest Pine (#1E3F2B)"></button>
|
||
<button type="button" class="color-swatch" data-color="#A8422B" data-name="Terracotta Rust" style="background:#A8422B" title="Terracotta Rust (#A8422B)"></button>
|
||
<button type="button" class="color-swatch" data-color="#C8C9CC" data-name="Heather Grey" style="background:#C8C9CC" title="Heather Grey (#C8C9CC)"></button>
|
||
<button type="button" class="color-swatch" data-color="#FFFFFF" data-name="Crisp White" style="background:#FFFFFF" title="Crisp White (#FFFFFF)"></button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="field-group">
|
||
<label for="nb-prompt-input">Visual Description / Artwork Prompt</label>
|
||
<textarea id="nb-prompt-input" rows="3" class="textarea-input" placeholder="Describe the visual concept, product UI, illustration, or mockup scene..."></textarea>
|
||
</div>
|
||
|
||
<!-- Iterative Image-to-Image Edit Banner (Active when a mockup is selected for refinement) -->
|
||
<div id="nb-edit-mode-box" class="nb-edit-box hidden">
|
||
<div class="nb-edit-header">
|
||
<span>✨ <strong>Iterative Edit Mode:</strong> Refining <em id="nb-edit-target-label">Selected Mockup</em></span>
|
||
<button type="button" id="btn-nb-clear-edit" class="btn btn-ghost btn-xs">Cancel Edit Mode</button>
|
||
</div>
|
||
<input
|
||
type="text"
|
||
id="nb-edit-instruction-input"
|
||
class="text-input"
|
||
placeholder="Describe what to change (e.g. 'Switch to dark mode layout' or 'Use bolder vintage typography')"
|
||
/>
|
||
</div>
|
||
|
||
<div class="studio-action-row">
|
||
<button type="button" id="btn-generate-nano-banana" class="btn btn-primary">
|
||
🖼️ Generate Image Mockup
|
||
</button>
|
||
<span id="nb-generation-status" class="muted-label"></span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Interactive T-Shirt & Emblem Compositor (Only shown when product is a T-Shirt) -->
|
||
<div id="tshirt-compositor-card" class="studio-card hidden">
|
||
<div class="studio-card-header">
|
||
<h3>👕 Interactive T-Shirt & Emblem Compositor</h3>
|
||
<span class="muted-label">Instant apparel layout & print proof</span>
|
||
</div>
|
||
|
||
<div class="form-row-3">
|
||
<div>
|
||
<label for="comp-surface-select">Mockup Surface</label>
|
||
<select id="comp-surface-select" class="filter-select full-width">
|
||
<option value="tshirt">👕 Crewneck T-Shirt</option>
|
||
<option value="sticker">🏷️ Die-Cut Sticker / Badge</option>
|
||
<option value="poster">🖼️ Framed Print</option>
|
||
</select>
|
||
</div>
|
||
<div>
|
||
<label for="comp-placement-select">Print Placement</label>
|
||
<select id="comp-placement-select" class="filter-select full-width">
|
||
<option value="center-chest">Full Center Chest</option>
|
||
<option value="left-chest">5-inch Left-Chest Pocket</option>
|
||
<option value="oversized">Oversized Vintage Front</option>
|
||
</select>
|
||
</div>
|
||
<div>
|
||
<label for="comp-emblem-select">Vector Emblem</label>
|
||
<select id="comp-emblem-select" class="filter-select full-width">
|
||
<option value="mountains">🏔️ Mountain & Sun</option>
|
||
<option value="espresso">☕ Espresso Cup</option>
|
||
<option value="lightbulb">💡 Lightbulb Boxer</option>
|
||
<option value="compass">🧭 Explorer Compass</option>
|
||
<option value="lightning">⚡ Spark Bolt</option>
|
||
<option value="none">No Icon (Text/Image Only)</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-row-2">
|
||
<div>
|
||
<div class="field-header-row">
|
||
<label for="comp-top-text">Top Headline / Club Name</label>
|
||
<button type="button" id="btn-comp-suggest-names" class="btn btn-ghost btn-xs">✨ Suggest Names</button>
|
||
</div>
|
||
<input type="text" id="comp-top-text" class="text-input input-sm" placeholder="HIGH ALTITUDE CLUB" />
|
||
</div>
|
||
<div>
|
||
<label for="comp-bottom-text">Bottom Tagline / Est.</label>
|
||
<input type="text" id="comp-bottom-text" class="text-input input-sm" placeholder="EST. 1984 • COLORADO" />
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-row-2">
|
||
<div>
|
||
<label for="comp-ink-color">Primary Screenprint Ink</label>
|
||
<input type="color" id="comp-ink-color" value="#BC4921" class="color-picker-input" />
|
||
</div>
|
||
<div>
|
||
<label for="comp-upload-art">Overlay Custom PNG/JPG Graphic</label>
|
||
<input type="file" id="comp-upload-art" accept="image/*" class="file-input" />
|
||
</div>
|
||
</div>
|
||
|
||
<div class="canvas-preview-wrapper">
|
||
<canvas id="mockup-compositor-canvas" width="680" height="680"></canvas>
|
||
</div>
|
||
|
||
<div class="studio-action-row">
|
||
<button type="button" id="btn-save-canvas-mockup" class="btn btn-secondary">
|
||
📸 Save Canvas Mockup to Idea
|
||
</button>
|
||
<button type="button" id="btn-download-canvas-png" class="btn btn-ghost btn-sm">
|
||
⬇️ Download PNG
|
||
</button>
|
||
<button type="button" id="btn-clear-uploaded-art" class="btn btn-ghost btn-sm">
|
||
Clear Overlay Image
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Right: Saved Mockup Gallery for this Idea -->
|
||
<div class="mockup-gallery-pane">
|
||
<div class="studio-card">
|
||
<div class="studio-card-header">
|
||
<h3>🖼️ Idea Mockup Gallery</h3>
|
||
<span class="muted-label">Click '✨ Refine' to iterate on any mockup</span>
|
||
</div>
|
||
<div id="drawer-mockup-gallery" class="drawer-mockup-gallery"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- TAB 3: WHACK THIS IDEA -->
|
||
<div id="drawer-tab-whack" class="drawer-tab-panel hidden">
|
||
<div class="drawer-whack-controls">
|
||
<div>
|
||
<h3>🃏 Give This Idea a Creative Whack</h3>
|
||
<p class="muted-label">Draw a stage-matched card from your 64-card deck to challenge assumptions or spark a new visual direction.</p>
|
||
</div>
|
||
<div class="drawer-whack-actions">
|
||
<select id="drawer-whack-suit-select" class="filter-select">
|
||
<option value="">Stage-Matched Suit (Recommended)</option>
|
||
<option value="explorer">🧭 Explorer (1–16)</option>
|
||
<option value="artist">🎨 Artist (17–32)</option>
|
||
<option value="judge">⚖️ Judge (33–48)</option>
|
||
<option value="warrior">⚔️ Warrior (49–64)</option>
|
||
</select>
|
||
<button type="button" id="btn-drawer-draw-whack" class="btn btn-primary btn-sm">
|
||
🃏 Draw Whack Card
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="drawer-active-whack-stage" class="drawer-whack-stage"></div>
|
||
|
||
<div class="field-group">
|
||
<h4>📜 Whack Breakthrough Log for This Idea</h4>
|
||
<div id="drawer-whack-history-list" class="whack-history-list"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</aside>
|
||
|
||
<!-- MODAL: AI GENERATOR & PROFILE SETTINGS -->
|
||
<div id="settings-modal" class="modal-backdrop hidden">
|
||
<div class="modal-card">
|
||
<div class="modal-header">
|
||
<h3>⚙️ AI Mockup Generator & Profile Settings</h3>
|
||
<button type="button" id="btn-close-settings" class="btn btn-ghost btn-sm">✕</button>
|
||
</div>
|
||
<form id="settings-form" class="modal-body">
|
||
<p class="muted-label">
|
||
Choose which AI generator powers the <strong>Image Mockup Studio</strong> (you can also switch generators anytime directly inside the Studio tab).
|
||
</p>
|
||
<div class="field-group">
|
||
<label for="settings-model-select">Default Image Mockup Generator</label>
|
||
<select id="settings-model-select" class="filter-select full-width">
|
||
<option value="codex-image-gen">🤖 OpenAI Codex (gpt-5.6-sol + Built-in image_gen) [Recommended]</option>
|
||
<option value="gemini-nano-banana-2.1">✨ Google Gemini (Nano Banana 2.1 / Flash-Lite Vector Fallback)</option>
|
||
<option value="gemini-3-pro-image">🎨 Google Gemini Pro Image (High-Detail Studio)</option>
|
||
<option value="gemini-3.1-flash-lite-image">⚡ Google Gemini Flash-Lite Image (Fast Sketch)</option>
|
||
</select>
|
||
</div>
|
||
<div class="field-group">
|
||
<label for="settings-api-key">Optional Google Gemini API Key (`GEMINI_API_KEY`)</label>
|
||
<input
|
||
type="password"
|
||
id="settings-api-key"
|
||
class="text-input"
|
||
placeholder="Only needed if using Google Gemini models (AIza...)"
|
||
autocomplete="off"
|
||
/>
|
||
<small id="settings-key-status" class="muted-label"></small>
|
||
</div>
|
||
<div class="field-group">
|
||
<label for="settings-user-background">🎲 Personal Background & Tastes (Used by '🎲 Random Idea')</label>
|
||
<textarea
|
||
id="settings-user-background"
|
||
rows="5"
|
||
class="textarea-input"
|
||
placeholder="Describe your interests, aesthetic tastes, homelab stack, apparel preferences..."
|
||
></textarea>
|
||
<small class="muted-label">When you click <strong>🎲 Random Idea</strong>, SparkVault combines this profile with a random Creative Whack Pack card to invent a tailored idea.</small>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button type="button" id="btn-cancel-settings" class="btn btn-ghost">Cancel</button>
|
||
<button type="submit" class="btn btn-primary">Save Settings</button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- MODAL: EXTERNAL CLIPPER / ATTACH TO SPARK -->
|
||
<div id="external-clip-modal" class="modal-backdrop hidden">
|
||
<div class="modal-card" style="max-width:600px;">
|
||
<div class="modal-header">
|
||
<h3>📎 Attach External Note or Image to Spark</h3>
|
||
<button type="button" id="btn-close-clip-modal" class="btn btn-ghost btn-sm">✕</button>
|
||
</div>
|
||
<form id="external-clip-form" class="modal-body">
|
||
<p class="muted-label">
|
||
Clip a screenshot (<kbd>Ctrl+V</kbd> anywhere in this dialog), upload a photo from your phone, fetch an external image URL, or attach notes/links to an existing Spark (or create a new one).
|
||
</p>
|
||
|
||
<div class="field-group">
|
||
<label for="clip-target-idea">Target Spark / Idea</label>
|
||
<select id="clip-target-idea" class="filter-select full-width"></select>
|
||
</div>
|
||
|
||
<div id="clip-new-idea-group" class="field-group hidden">
|
||
<label for="clip-new-idea-title">New Spark Title</label>
|
||
<input type="text" id="clip-new-idea-title" class="text-input" placeholder="e.g. Vintage Campfire Enamel Mug #merch @creative" />
|
||
</div>
|
||
|
||
<div class="field-group">
|
||
<label for="clip-title-input">Attachment Title / Caption</label>
|
||
<input type="text" id="clip-title-input" class="text-input" placeholder="e.g. Field Notes Photo / Competitor Spec / Article Excerpt" />
|
||
</div>
|
||
|
||
<div class="field-group">
|
||
<label>Image Source (File / Camera, Clipboard Paste, or Direct Image URL)</label>
|
||
<div id="clip-dropzone" class="attachment-dropzone">
|
||
<div style="display:flex;justify-content:space-between;align-items:center;gap:0.5rem;flex-wrap:wrap;">
|
||
<span class="muted-label">📋 Paste image (<kbd>Ctrl+V</kbd>) or drop file here</span>
|
||
<label class="btn btn-secondary btn-xs" style="cursor:pointer;">
|
||
📷 Select Photo / File
|
||
<input type="file" id="clip-file-input" accept="image/*" hidden />
|
||
</label>
|
||
</div>
|
||
<div id="clip-preview-row" class="attach-preview-row hidden">
|
||
<img id="clip-preview-img" src="" alt="Clip preview" />
|
||
<span class="muted-label" style="flex:1;">Image staged for attachment</span>
|
||
<button type="button" id="btn-clip-clear-img" class="btn btn-ghost btn-xs">✕ Clear</button>
|
||
</div>
|
||
<input type="url" id="clip-external-img-url" class="text-input input-sm" placeholder="Or paste an external image URL (https://example.com/photo.jpg)..." />
|
||
</div>
|
||
</div>
|
||
|
||
<div class="field-group">
|
||
<label for="clip-text-input">External Note / Excerpt / Markdown</label>
|
||
<textarea id="clip-text-input" rows="3" class="textarea-input" placeholder="Paste notes, thoughts, article quotes, or garment/project details..."></textarea>
|
||
</div>
|
||
|
||
<div class="field-group">
|
||
<label for="clip-source-url">Source Webpage URL (Optional)</label>
|
||
<input type="url" id="clip-source-url" class="text-input input-sm" placeholder="https://..." />
|
||
</div>
|
||
|
||
<div style="display:flex;gap:1rem;flex-wrap:wrap;">
|
||
<label class="filter-checkbox">
|
||
<input type="checkbox" id="clip-append-notes" checked />
|
||
<span>Append note text to Spark's Markdown Notes</span>
|
||
</label>
|
||
<label class="filter-checkbox">
|
||
<input type="checkbox" id="clip-set-cover" checked />
|
||
<span>Set image as Spark cover</span>
|
||
</label>
|
||
</div>
|
||
|
||
<div class="modal-footer">
|
||
<button type="button" id="btn-cancel-clip-modal" class="btn btn-ghost">Cancel</button>
|
||
<button type="submit" class="btn btn-primary">📎 Save Attachment to Spark</button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- MODAL: SUBMIT SPARK TO ANTIGRAVITY OR CODEX FOR DEVELOPMENT -->
|
||
<div id="dev-handoff-modal" class="modal-backdrop hidden">
|
||
<div class="modal-card modal-card-wide">
|
||
<div class="modal-header">
|
||
<h3>🚀 Submit Spark for Development</h3>
|
||
<button type="button" id="btn-close-dev-modal" class="btn btn-ghost btn-sm">✕</button>
|
||
</div>
|
||
<form id="dev-handoff-form" class="modal-body">
|
||
<p class="muted-label">
|
||
Packages all Spark information (title, pitch, markdown specs, checklist, pros/cons, reference links, and mockup/attachment URLs) and sends it to <strong>Antigravity</strong> or <strong>OpenAI Codex</strong>.
|
||
</p>
|
||
|
||
<div class="form-row-2">
|
||
<div class="field-group">
|
||
<label>1. Target Coding App</label>
|
||
<div class="dev-target-pills" id="dev-target-pills">
|
||
<button type="button" class="pill-btn active" data-dev-target="antigravity">
|
||
🛸 Google Antigravity
|
||
</button>
|
||
<button type="button" class="pill-btn" data-dev-target="codex">
|
||
🤖 OpenAI Codex
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="field-group">
|
||
<label for="dev-model-select">2. Select AI Model</label>
|
||
<select id="dev-model-select" class="filter-select full-width"></select>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="dev-options-row">
|
||
<label class="filter-checkbox">
|
||
<input type="checkbox" id="dev-include-homelab" checked />
|
||
<span>Include Homelab Stack Spec (vloser Docker + Gitea + Traefik + Homepage)</span>
|
||
</label>
|
||
<label class="filter-checkbox">
|
||
<input type="checkbox" id="dev-move-building" checked />
|
||
<span>Move Spark to 🛠️ Building stage</span>
|
||
</label>
|
||
<label class="filter-checkbox hidden" id="dev-server-codex-wrap">
|
||
<input type="checkbox" id="dev-run-server-codex" />
|
||
<span>⚡ Also run autonomous Codex blueprint on server</span>
|
||
</label>
|
||
</div>
|
||
|
||
<div class="field-group">
|
||
<div class="field-header-row">
|
||
<label for="dev-spec-preview-textarea">3. Complete Development Specification Payload (Editable)</label>
|
||
<div style="display:flex;gap:0.35rem;">
|
||
<button type="button" id="btn-copy-dev-spec" class="btn btn-ghost btn-xs">📋 Copy Prompt</button>
|
||
<button type="button" id="btn-download-dev-spec" class="btn btn-ghost btn-xs">⬇️ Download SPEC.md</button>
|
||
</div>
|
||
</div>
|
||
<textarea id="dev-spec-preview-textarea" rows="11" class="textarea-input dev-spec-textarea"></textarea>
|
||
</div>
|
||
|
||
<div id="dev-handoff-result-box" class="nb-edit-box hidden"></div>
|
||
|
||
<div id="dev-handoff-instruction-note" class="muted-label" style="font-size:0.8rem; padding:0.4rem 0.6rem; background:rgba(76,140,245,0.08); border-radius:6px; border-left:3px solid var(--accent-primary); margin-top:0.4rem;">
|
||
🛸 Submitting switches focus to Antigravity and copies the complete project specification to your clipboard. Simply press <kbd>Ctrl+V</kbd> in Antigravity's chat to start coding.
|
||
</div>
|
||
|
||
<div class="modal-footer">
|
||
<button type="button" id="btn-cancel-dev-modal" class="btn btn-ghost">Cancel</button>
|
||
<button type="submit" id="btn-submit-dev-handoff" class="btn btn-primary">
|
||
🚀 Submit & Launch in Antigravity
|
||
</button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- MODAL: CARD / MOCKUP LIGHTBOX INSPECTOR -->
|
||
<div id="lightbox-modal" class="modal-backdrop hidden">
|
||
<div class="lightbox-card">
|
||
<div class="modal-header">
|
||
<h3 id="lightbox-title">Card Preview</h3>
|
||
<button type="button" id="btn-close-lightbox" class="btn btn-ghost btn-sm">✕</button>
|
||
</div>
|
||
<div class="lightbox-body">
|
||
<img id="lightbox-img" src="" alt="Preview" />
|
||
<div id="lightbox-meta" class="lightbox-meta"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="toast-container" class="toast-container" aria-live="polite"></div>
|
||
|
||
<script type="module" src="/app.js"></script>
|
||
</body>
|
||
</html>
|