Theia rip-out (parent):
- Remove theia submodule entry (the local fork, Gitea repo, Coolify app,
Cloud Run services, and Artifact Registry image are all gone)
- Drop README.md + INFRASTRUCTURE.md (obsolete "Project OS" snapshots
that also leaked API tokens) and setup.sh (Theia clone bootstrap)
- Delete UI-DESIGN-GUIDE.md, BACKEND_AGENTS_PLAN.md, VIBN_BUILD_PLAN.md,
VISUAL_EDITOR_PLAN.md, core-packages.md, ai-packages.md, tools-list.md
(all 100% Theia-specific or superseded)
- Surgical scrubs of remaining Theia mentions in
AGENT_EXECUTION_ARCHITECTURE.md and TURBOREPO_MIGRATION_PLAN.md
Submodule bumps:
- vibn-agent-runner: Theia rip-out + MCP refactor (api/wrapper/server
pattern across shell/file/git/memory/prd/search/agent/gitea/coolify)
- vibn-frontend: Theia rip-out + P5.1 attach E2E + Justine UI WIP
Retire platform/ scaffold:
- Remove platform/backend/ (control-plane, executors, mcp-adapter),
platform/client-ide/ (gcp-productos extension), platform/contracts/,
platform/infra/terraform/, platform/scripts/templates/turborepo/
(replaced by vibn-agent-runner + vibn-frontend + Coolify direct)
- Drop architecture.md, technical_spec.md, vision-ext.md,
"1.Generate Control Plane API scaffold.md" (same era)
Docs / planning snapshots (new):
- AI_CAPABILITIES.md, AI_CAPABILITIES_ROADMAP.md
- AGENT_TELEMETRY_STREAMING_PROJECT.md
- VIBN_PRD.md, product-idea-a.md
Design assets (new):
- branding/{coolify,gitea,ux-testing}/ static brand collateral
- justine/ HTML mockups for the new onboarding/build flows
- preview-assist-ui/ Vite scratch app
- master-ai.code-workspace
Infra helpers (new):
- setup-coolify-montreal.sh provisioner
- gitea-docker-compose.yml
- vibn-coolify-schema.sql for the Coolify Postgres extensions
- prd-agent-prompt.pdf, prompt, root.txt, remixed-9edec9e9.tsx scratch
- flatten.sh helper
.gitignore: ignore **/node_modules, **/.next, **/.turbo, **/coverage
Made-with: Cursor
806 lines
57 KiB
HTML
806 lines
57 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><link rel="icon" href="favicon_clean.ico">
|
||
<script>if(localStorage.getItem('vibn-theme')==='dark')document.documentElement.dataset.theme='dark';</script>
|
||
<title>vibn — Website</title>
|
||
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap" rel="stylesheet">
|
||
<style>
|
||
*{box-sizing:border-box;margin:0;padding:0;}
|
||
:root{--ink:#1a1510;--ink2:#2c2c2a;--ink3:#444441;--mid:#5f5e5a;--muted:#888780;--stone:#b4b2a9;--parch:#d3d1c7;--cream:#f1efe8;--paper:#f7f4ee;--white:#fdfcfa;--border:#e8e2d9; --section: #b8a9e93f;}
|
||
/* ── Dark mode tokens — exact match with design.html ── */
|
||
[data-theme="dark"]{--ink:#EEEEFF;--ink2:#B8B8D0;--ink3:#8484A8;--mid:#9898B8;--muted:#c2c2ee;--border:rgba(255,255,255,0.08);--cream:rgba(108,124,255,0.14);--paper:#0A1120;--white:rgba(255,255,255,0.05);--stone:rgba(255,255,255,0.08);--parch:rgba(255,255,255,0.06);--section:rgba(108,124,255,0.55);--accent-primary:#6C7CFF;--dm-surf-sidebar:rgba(12,18,34,0.72);--dm-surf-topbar:rgba(12,18,34,0.58);--dm-surf-panel:rgba(12,18,34,0.58);--dm-surf-right:rgba(12,18,34,0.58);--dm-surf-card:rgba(255,255,255,0.05);--dm-surf-refine:rgba(8,12,22,0.60);--dm-border:rgba(255,255,255,0.08);--dm-border-strong:rgba(255,255,255,0.14);--dm-border-hero:rgba(255,255,255,0.18);--dm-accent:#6C7CFF;--dm-accent-fill:rgba(108,124,255,0.14);--dm-accent-fill-mid:rgba(108,124,255,0.20);--dm-accent-border:rgba(108,124,255,0.55);--dm-text-1:#EEEEFF;--dm-text-2:#B4B4CC;--dm-text-3:#d2d2ef;--dm-shadow-panel:0 4px 36px rgba(0,0,0,0.55);--dm-shadow-hero:0 20px 70px rgba(0,0,0,0.65),0 6px 24px rgba(0,0,0,0.40),inset 0 1px 0 rgba(255,255,255,0.10);}
|
||
html:not([data-theme="dark"]) .preview-box {background: linear-gradient(to bottom, #FAFAFA, #F5F3FF);}
|
||
[data-theme="dark"] body{background:linear-gradient(to bottom,rgba(108,80,255,0.06) 0%,rgba(60,120,255,0.10) 38%,transparent 62%),linear-gradient(to bottom,rgba(108,124,255,0.10),transparent 180px),radial-gradient(900px 520px at 14% -8%,rgba(108,124,255,0.24),transparent 62%),radial-gradient(760px 420px at 88% 0%,rgba(72,145,255,0.16),transparent 60%),linear-gradient(180deg,#18213B 0%,#101726 48%,#0A1120 100%);}
|
||
[data-theme="dark"] .sidebar-col{background:var(--dm-surf-sidebar)!important;border-right:1px solid var(--dm-border)!important;box-shadow:2px 0 28px rgba(0,0,0,0.60)!important;-webkit-backdrop-filter:blur(20px)!important;backdrop-filter:blur(20px)!important;}
|
||
[data-theme="dark"] .sidebar-col [style*="color:#1a1a1a"],[data-theme="dark"] .sidebar-col [style*="color: #1a1a1a"]{color:var(--dm-text-1)!important;}
|
||
[data-theme="dark"] .sidebar-col [style*="color:#6b7280"],[data-theme="dark"] .sidebar-col [style*="color: #6b7280"]{color:var(--dm-text-3)!important;}
|
||
[data-theme="dark"] .sidebar-col [style*="color: #9ca3af"]{color:var(--dm-text-3)!important;}
|
||
.ph-name{color:#9ca3af;}
|
||
[data-theme="dark"] .ph-name{color:var(--dm-text-3);}
|
||
[data-theme="dark"] .sidebar-col [style*="color:#444441"]{color:var(--dm-text-3)!important;}
|
||
[data-theme="dark"] .sidebar-col [style*="background:#6366F1"]{background:var(--dm-accent)!important;color:#0F1424!important;}
|
||
[data-theme="dark"] .sidebar-col [style*="background:#e5e7eb"]{background:rgba(255,255,255,0.08)!important;}
|
||
[data-theme="dark"] .sidebar-phase.active{background:var(--dm-accent-fill)!important;}
|
||
[data-theme="dark"] .sidebar-phase:not(.active):hover{background:rgba(255,255,255,0.08)!important;}
|
||
[data-theme="dark"] .sidebar-col [style*="background:#fafaff"]{background:rgba(108,124,255,0.08)!important;}
|
||
[data-theme="dark"] .sidebar-col [style*="border:1px solid rgba(99,102,241"]{border-color:var(--dm-border)!important;}
|
||
[data-theme="dark"] .sidebar-col [style*="border-top:1px solid #e5e7eb"]{border-top-color:var(--dm-border)!important;}
|
||
[data-theme="dark"] .sidebar-col [style*="background:#eef2ff"]{background:var(--dm-accent-fill)!important;border-color:var(--dm-accent-border)!important;}
|
||
[data-theme="dark"] .sidebar-col [style*="background:#eef2ff"] span{color:var(--dm-accent)!important;}
|
||
[data-theme="dark"] button[onclick="saveAndExit()"]{background:var(--dm-accent-fill)!important;border-color:var(--dm-accent-border)!important;}
|
||
[data-theme="dark"] button[onclick="saveAndExit()"]:hover{background:var(--dm-accent-fill-mid)!important;}
|
||
[data-theme="dark"] button[onclick="saveAndExit()"]:hover span{color:#fff!important;}
|
||
[data-theme="dark"] button[onclick="saveAndExit()"] span{color:var(--dm-accent)!important;}
|
||
[data-theme="dark"] #sidebar-project-name{color:var(--dm-text-3)!important;}
|
||
[data-theme="dark"] #dark-toggle{background:rgba(255,255,255,0.05)!important;border-color:var(--dm-border)!important;color:var(--dm-text-3)!important;}
|
||
[data-theme="dark"] #dark-toggle:hover{background:rgba(255,255,255,0.10)!important;color:var(--dm-text-1)!important;}
|
||
[data-theme="dark"] .vibn-avatar{background:var(--dm-accent)!important;}
|
||
[data-theme="dark"] .arch-topbar{background:var(--dm-surf-topbar)!important;border-bottom:1px solid rgba(255,255,255,0.04)!important;-webkit-backdrop-filter:blur(20px)!important;backdrop-filter:blur(20px)!important;}
|
||
[data-theme="dark"] .arch-topbar .f{color:var(--dm-text-1)!important;}
|
||
[data-theme="dark"] .arch-topbar [style*="color:#9ca3af"]{color:var(--dm-text-3)!important;}
|
||
[data-theme="dark"] .website-left{background:var(--dm-surf-panel)!important;border-right:1px solid var(--dm-border)!important;box-shadow:4px 0 36px rgba(0,0,0,0.55)!important;-webkit-backdrop-filter:blur(20px)!important;backdrop-filter:blur(20px)!important;}
|
||
[data-theme="dark"] .website-left [style*="color:#9ca3af"]{color:var(--dm-text-3)!important;}
|
||
[data-theme="dark"] .website-left [style*="background:#f0f0f8"]{background:rgba(108,124,255,0.08)!important;}
|
||
[data-theme="dark"] .tab{color:var(--dm-text-3)!important;}
|
||
[data-theme="dark"] .tab.on{color:var(--dm-accent)!important;border-bottom-color:var(--dm-accent)!important;}
|
||
body{font-family:'Plus Jakarta Sans',sans-serif;background:var(--paper);display:flex;flex-direction:column;height:100vh;overflow:hidden;}
|
||
.f{font-family:'Plus Jakarta Sans',sans-serif;}
|
||
.sidebar-phase{display:flex;align-items:center;gap:9px;padding:9px 10px;border-radius:8px;}
|
||
.sidebar-phase.active{background:#fafaff;}
|
||
.phase-dot{width:20px;height:20px;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0;font-size:10px;}
|
||
.tab{padding:11px 22px;border:none;background:transparent;cursor:pointer;font-family:'Plus Jakarta Sans',sans-serif;font-size:13.5px;color:var(--muted);border-bottom:2px solid transparent;}
|
||
.tab.on{color:#6366F1;border-bottom-color:#6366F1;font-weight:600;}
|
||
input[type=range]{-webkit-appearance:none;width:100%;height:4px;border-radius:2px;background:#c7d2fe;outline:none;cursor:pointer;}
|
||
input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;width:16px;height:16px;border-radius:50%;background:#6366F1;cursor:pointer;}
|
||
[data-theme="dark"] input[type=range]{background:rgba(255,255,255,0.12);}
|
||
[data-theme="dark"] input[type=range]::-webkit-slider-thumb{background:var(--dm-accent);}
|
||
.section{display:none;}
|
||
.section.active{display:block;}
|
||
#sec-style.active{display:flex;}
|
||
.ws-btn{border-radius:9px;border:1px solid var(--border);padding:11px 13px;cursor:pointer;text-align:left;margin-bottom:7px;width:100%;transition:all 0.15s;}
|
||
.ws-btn.selected{border:2px solid var(--ink);}
|
||
.deliverable-row{display:flex;align-items:center;gap:8px;padding:7px 10px;font-size:12px;color:var(--mid);border-bottom:1px solid var(--border);}
|
||
.deliverable-row:last-child{border-bottom:none;}
|
||
.vpill{border:1.5px solid #e0e7ff;border-radius:20px;padding:4px 11px;font-size:11px;font-weight:500;color:#6b7280;background:#fff;cursor:pointer;font-family:'Plus Jakarta Sans',sans-serif;transition:all 0.15s;white-space:nowrap;}
|
||
.vpill:hover{border-color:#6366F1;color:#6366F1;}
|
||
.vpill.active{background:#6366F1;border-color:#6366F1;color:#fff;font-weight:600;box-shadow:0 2px 10px rgba(99,102,241,0.12);}
|
||
.tchip{border:1.5px solid #e0e7ff;border-radius:20px;padding:4px 12px;font-size:11.5px;font-weight:500;color:#6b7280;background:#fff;cursor:pointer;font-family:'Plus Jakarta Sans',sans-serif;transition:all 0.15s;}
|
||
.tchip:hover{border-color:#6366F1;color:#6366F1;}
|
||
.tchip.active{background:#6366F1;border-color:#6366F1;color:#fff;font-weight:600;box-shadow:0 1px 6px rgba(99,102,241,0.10);}
|
||
.scard{border:2px solid #e0e7ff;border-radius:8px;cursor:pointer;text-align:left;background:#fff;overflow:hidden;transition:all 0.15s;padding:0;}
|
||
.scard:hover{border-color:#a5b4fc;}
|
||
.scard.selected{border-color:#6366F1;box-shadow:0 0 0 3px rgba(99,102,241,0.1),0 2px 10px rgba(99,102,241,0.12);}
|
||
.ws-rp-card{box-shadow:0 2px 12px rgba(99,102,241,0.08);}
|
||
.next-btn{width:100%;background:linear-gradient(135deg,#4338CA,#6366F1);color:#FFFFFF;border:none;border-radius:8px;padding:12px 14px;font-family:'Plus Jakarta Sans',sans-serif;font-size:13px;font-weight:600;cursor:pointer;box-shadow:0 4px 18px rgba(99,102,241,0.22),0 1px 4px rgba(99,102,241,0.12);transition:box-shadow 0.2s;}
|
||
.scard-name{font-size:11px;font-weight:700;color:#1a1a1a;}
|
||
.scard-desc{font-size:9.5px;color:#6b7280;margin-top:1px;}
|
||
[data-theme="dark"] .vpill{background:var(--dm-surf-card)!important;border-color:var(--dm-border)!important;color:#fff)!important;}
|
||
[data-theme="dark"] .vpill:hover{border-color:rgba(108,124,255,0.45)!important;color:var(--dm-text-2)!important;}
|
||
[data-theme="dark"] .vpill.active{background:var(--dm-accent)!important;border-color:var(--dm-accent)!important;color:#fff!important;}
|
||
[data-theme="dark"] .tchip{background:var(--dm-surf-card)!important;border-color:var(--dm-border)!important;color:var(--dm-text-3)!important;}
|
||
[data-theme="dark"] .tchip.active{background:var(--dm-accent)!important;border-color:var(--dm-accent)!important;color:#fff!important;}
|
||
[data-theme="dark"] .scard{background:var(--dm-surf-card)!important;border-color:var(--dm-border)!important;}
|
||
[data-theme="dark"] .scard:hover{border-color:var(--dm-border-strong)!important;}
|
||
[data-theme="dark"] .scard.selected{border-color:var(--dm-accent)!important;box-shadow:0 0 0 2px rgba(108,124,255,0.22)!important;}
|
||
[data-theme="dark"] .scard-name{color:var(--dm-text-1)!important;}
|
||
[data-theme="dark"] .scard-desc{color:var(--dm-text-3)!important;}
|
||
[data-theme="dark"] .main-content-area{background:transparent!important;}
|
||
[data-theme="dark"] .main-content-area [style*="background:#f0f0f8"],[data-theme="dark"] .main-content-area [style*="background:#f8f9ff"]{background:rgba(255,255,255,0.03)!important;}
|
||
@keyframes pulse-dot{0%,100%{opacity:1}50%{opacity:0.35}}
|
||
.opt-btns{display:flex;gap:0;flex-shrink:0;border:1.5px solid var(--border);border-radius:8px;overflow:visible;}
|
||
.opt-btn{flex:1;text-align:center;font-size:12px;font-weight:500;color:var(--mid);background:transparent;border:none;border-right:1.5px solid var(--border);border-radius:0;padding:6px 13px;cursor:pointer;font-family:'Plus Jakarta Sans',sans-serif;transition:all 0.15s;white-space:nowrap;position:relative;}
|
||
.opt-btn:first-child{border-radius:7px 0 0 7px;}
|
||
.opt-btn:last-child{border-right:none;border-radius:0 7px 7px 0;}
|
||
.opt-btn:hover{background:#f5f5ff;color:#6366F1;}
|
||
.opt-btn.selected{background:rgba(99,102,241,0.08);color:#4338CA;font-weight:600;}
|
||
[data-theme="dark"] .opt-btns{border-color:var(--dm-border)!important;}
|
||
[data-theme="dark"] .opt-btn{color:var(--dm-text-2)!important;border-right-color:var(--dm-border)!important;}
|
||
[data-theme="dark"] .opt-btn:hover{background:rgba(108,124,255,0.09)!important;color:var(--dm-accent)!important;}
|
||
[data-theme="dark"] .opt-btn.selected{background:var(--dm-accent-fill)!important;color:var(--dm-accent)!important;font-weight:600!important;box-shadow:inset 0 0 0 1px rgba(108,124,255,0.32),0 2px 16px rgba(108,124,255,0.22)!important;}
|
||
[data-theme="dark"] .website-right{background:var(--dm-surf-right)!important;border-left:1px solid var(--dm-border)!important;box-shadow:-4px 0 36px rgba(0,0,0,0.55)!important;-webkit-backdrop-filter:blur(20px)!important;backdrop-filter:blur(20px)!important;}
|
||
[data-theme="dark"] .website-right [style*="border-bottom:1px solid #c7d2fe"]{border-bottom-color:var(--dm-border)!important;}
|
||
[data-theme="dark"] .website-right [style*="color:#4338ca"]{color:var(--dm-accent)!important;}
|
||
[data-theme="dark"] .website-right [style*="background:#eef2ff"]{background:var(--dm-accent-fill)!important;color:var(--dm-accent)!important;}
|
||
.sec-div{height:1px;background: var(--section);}
|
||
[data-theme="dark"] .website-left .sec-div{background:rgba(108,124,255,0.20)!important;}
|
||
|
||
.surprise-btn{width:100%;padding:10px;border:1.5px solid #e0e7ff;border-radius:9px;background:#6366F1;font-family:'Plus Jakarta Sans',sans-serif;font-size:12px;font-weight:600;color:#ffffff;cursor:pointer;transition:all 0.15s;text-align:center;display:block;box-shadow:0 2px 14px rgba(99,102,241,0.22);}
|
||
.surprise-btn:hover{background:#5045c8;border-color:#c7d2fe;}
|
||
[data-theme="dark"] .preview-box{background:rgba(6,10,20,0.32)!important;}
|
||
[data-theme="dark"] .preview-chrome-box{border:1.5px solid var(--dm-border-hero)!important;box-shadow:var(--dm-shadow-hero),0 0 0 1px rgba(108,124,255,0.08)!important;}
|
||
[data-theme="dark"] [style*="background:#eef2ff;border-radius:11px"]{background:var(--dm-surf-topbar)!important;border-color:var(--dm-border)!important;}
|
||
[data-theme="dark"] span[style*="color:#6366F1;background:#eef2ff"]{color:var(--dm-accent)!important;background:var(--dm-accent-fill)!important;}
|
||
[data-theme="dark"] [style*="color:#6366F1"][style*="text-transform:uppercase"]{color:var(--dm-accent)!important;}
|
||
[data-theme="dark"] .surprise-btn{background:linear-gradient(135deg,#5450CC,var(--dm-accent))!important;border-color:rgba(108,124,255,0.35)!important;color:#fff!important;box-shadow:0 4px 18px rgba(108,124,255,0.22)!important;}
|
||
[data-theme="dark"] .surprise-btn:hover{background:linear-gradient(135deg,#4840BE,#6070F8)!important;box-shadow:0 6px 26px rgba(108,124,255,0.30)!important;}
|
||
[data-theme="dark"] ::-webkit-scrollbar{width:5px;height:5px;}
|
||
[data-theme="dark"] ::-webkit-scrollbar-track{background:transparent;}
|
||
[data-theme="dark"] ::-webkit-scrollbar-thumb{background:rgba(255,255,255,0.12);border-radius:3px;}
|
||
[data-theme="dark"] ::-webkit-scrollbar-thumb:hover{background:rgba(255,255,255,0.22);}
|
||
[data-theme="dark"] *{scrollbar-color:rgba(255,255,255,0.12) transparent;scrollbar-width:thin;}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div style="display:flex;height:100%;overflow:hidden;">
|
||
|
||
<!-- SIDEBAR -->
|
||
<div class="sidebar-col" style="width:200px;background:#ffffff;border-right:1px solid #e5e7eb;display:flex;flex-direction:column;padding:18px 12px;flex-shrink:0;">
|
||
<div style="padding:0 6px;margin-bottom:26px;">
|
||
<div style="display:flex;align-items:center;gap:8px;margin-bottom:6px;">
|
||
<div class="vibn-avatar" style="width:26px;height:26px;background:linear-gradient(135deg,#2E2A5E,#4338CA);border-radius:6px;display:flex;align-items:center;justify-content:center;flex-shrink:0;"><span class="f" style="font-size:13px;font-weight:700;color:#FFFFFF;">V</span></div>
|
||
<span class="f" style="font-size:16px;font-weight:700;color:var(--ink);letter-spacing:-0.02em;">vibn</span>
|
||
</div>
|
||
<div id="sidebar-project-name" style="font-size:11px;font-weight:500;color:#9ca3af;padding-left:34px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:none;"></div>
|
||
</div>
|
||
<div class="ph-name" style="font-size:9.5px;font-weight:600;letter-spacing:0.08em;text-transform:uppercase;padding:0 6px;margin-bottom:8px;">MVP Setup</div>
|
||
<div style="display:flex;flex-direction:column;gap:2px;flex:1;">
|
||
<div class="sidebar-phase" onclick="window.location.href='05_describe.html'" style="cursor:pointer;" onmouseover="this.style.background='#f5f3ff'" onmouseout="this.style.background='transparent'">
|
||
<div class="phase-dot" style="background:#6366F1;color:#ffffff;">✓</div>
|
||
<div class="ph-name" style="font-size:12.5px;">Describe</div>
|
||
</div>
|
||
<div class="sidebar-phase" onclick="window.location.href='06_architect.html'" style="cursor:pointer;" onmouseover="this.style.background='#f5f3ff'" onmouseout="this.style.background='transparent'">
|
||
<div class="phase-dot" style="background:#6366F1;color:#ffffff;">✓</div>
|
||
<div class="ph-name" style="font-size:12.5px;">Architect</div>
|
||
</div>
|
||
<div class="sidebar-phase" onclick="window.location.href='07_design.html'" style="cursor:pointer;" onmouseover="this.style.background='#f5f3ff'" onmouseout="this.style.background='transparent'">
|
||
<div class="phase-dot" style="background:#6366F1;color:#ffffff;">✓</div>
|
||
<div class="ph-name" style="font-size:12.5px;">Design</div>
|
||
</div>
|
||
<div class="sidebar-phase active">
|
||
<div class="phase-dot" style="background:#6366F1;color:#ffffff;">◉</div>
|
||
<div><div style="font-size:12.5px;font-weight:600;color:var(--ink);">Website</div><div class="ph-name" style="font-size:10px;">How you'll grow</div></div>
|
||
</div>
|
||
<div class="sidebar-phase">
|
||
<div class="phase-dot" style="background:#e5e7eb;color:#9ca3af;">▲</div>
|
||
<div class="ph-name" style="font-size:12.5px;">Build MVP</div>
|
||
</div>
|
||
</div>
|
||
<div style="border-top:1px solid #e5e7eb;margin-top:14px;padding-top:12px;">
|
||
<button onclick="saveAndExit()" style="display:flex;align-items:center;justify-content:center;gap:7px;width:100%;background:#eef2ff;border:1px solid #e0e7ff;border-radius:8px;padding:9px 10px;cursor:pointer;font-family:'Plus Jakarta Sans',sans-serif;transition:background 0.15s;" onmouseover="this.style.background=document.documentElement.dataset.theme==='dark'?'':'#e0e7ff'" onmouseout="this.style.background=document.documentElement.dataset.theme==='dark'?'':'#eef2ff'">
|
||
<span style="font-size:12px;font-weight:600;color:#6366F1;">Save & go to dashboard</span>
|
||
</button>
|
||
<button id="dark-toggle" onclick="toggleTheme()" style="margin-top:8px;display:flex;align-items:center;justify-content:center;width:100%;background:transparent;border:1px solid var(--border);border-radius:8px;padding:8px 10px;cursor:pointer;font-family:'Plus Jakarta Sans',sans-serif;font-size:12px;font-weight:500;color:var(--mid);transition:background 0.15s,border-color 0.15s;" onmouseover="this.style.borderColor='#6366F1';this.style.color='#6366F1';" onmouseout="this.style.borderColor='var(--border)';this.style.color='var(--mid)';">🌙 Dark mode</button>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
<!-- MAIN -->
|
||
<!-- TOP BAR -->
|
||
<div style="flex:1;display:flex;flex-direction:column;overflow:hidden;min-width:0;">
|
||
<div class="arch-topbar" style="padding:18px 28px 14px;background:var(--white);border-bottom:1px solid var(--border);display:flex;align-items:center;justify-content:space-between;flex-shrink:0;">
|
||
<div>
|
||
<div class="f" style="font-size:17px;font-weight:700;color:var(--ink);margin-bottom:3px;">Website</div>
|
||
<div style="font-size:12.5px;color:#9ca3af;">This is what people see before signing up. Set your voice, topics, and website style</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="main-content-area" style="flex:1;overflow:hidden;display:flex;background:#f8f9ff;">
|
||
|
||
<!-- LEFT: Controls — single panel, no individual cards -->
|
||
<div class="website-left" style="width:272px;border-right:1px solid #e0e7ff;overflow-y:auto;padding:0;display:flex;flex-direction:column;flex-shrink:0;background:linear-gradient(to bottom,#FAFAFA,#F5F3FF);">
|
||
|
||
<!-- Voice section -->
|
||
<div style="padding:16px 16px 14px;">
|
||
<div style="font-size:9.5px;font-weight:700;letter-spacing:0.09em;text-transform:uppercase;color:#6366F1;margin-bottom:12px;">Voice</div>
|
||
<div style="margin-bottom:10px;">
|
||
<div style="font-size:10.5px;color:#9ca3af;margin-bottom:5px;">Tone</div>
|
||
<div style="display:flex;gap:5px;" id="pills-tone">
|
||
<button class="vpill active" onclick="setPill(this,'tone',0)">Friendly</button>
|
||
<button class="vpill" onclick="setPill(this,'tone',50)">Balanced</button>
|
||
<button class="vpill" onclick="setPill(this,'tone',100)">Professional</button>
|
||
</div>
|
||
</div>
|
||
<div style="margin-bottom:10px;">
|
||
<div style="font-size:10.5px;color:#9ca3af;margin-bottom:5px;">Style</div>
|
||
<div style="display:flex;gap:5px;" id="pills-style">
|
||
<button class="vpill" onclick="setPill(this,'style',0)">Casual</button>
|
||
<button class="vpill active" onclick="setPill(this,'style',50)">Balanced</button>
|
||
<button class="vpill" onclick="setPill(this,'style',100)">Precise</button>
|
||
</div>
|
||
</div>
|
||
<div>
|
||
<div style="font-size:10.5px;color:#9ca3af;margin-bottom:5px;">Personality</div>
|
||
<div style="display:flex;gap:5px;" id="pills-pers">
|
||
<button class="vpill active" onclick="setPill(this,'pers',0)">Warm</button>
|
||
<button class="vpill" onclick="setPill(this,'pers',50)">Steady</button>
|
||
<button class="vpill" onclick="setPill(this,'pers',100)">Direct</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="sec-div" style="height:1px;background: var(--section);margin:0 16px;"></div>
|
||
|
||
<!-- Topics section -->
|
||
<div style="padding:14px 16px;">
|
||
<div style="font-size:9.5px;font-weight:700;letter-spacing:0.09em;text-transform:uppercase;color:#6366F1;margin-bottom:10px;">Topics</div>
|
||
<div style="display:flex;flex-wrap:wrap;gap:6px;">
|
||
<button class="tchip active" onclick="toggleTopic(this,'problem')">The problem</button>
|
||
<button class="tchip active" onclick="toggleTopic(this,'audience')">Who it's for</button>
|
||
<button class="tchip active" onclick="toggleTopic(this,'timing')">Why now</button>
|
||
<button class="tchip" onclick="toggleTopic(this,'benefits')">Key benefits</button>
|
||
<button class="tchip" onclick="toggleTopic(this,'comparison')">vs. alternatives</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="sec-div" style="height:1px;background: var(--section);margin:0 16px;"></div>
|
||
|
||
<!-- Style section -->
|
||
<div style="padding:14px 16px;">
|
||
<div style="font-size:9.5px;font-weight:700;letter-spacing:0.09em;text-transform:uppercase;color:#6366F1;margin-bottom:10px;">Website style</div>
|
||
<div style="display:grid;grid-template-columns:1fr 1fr;gap:7px;">
|
||
<button class="scard selected" id="sc-editorial" onclick="setStyle('editorial','#ffffff','#ef4444','Editorial','Bold headlines, strong opinions')">
|
||
<div style="height:28px;background:#fff;border-radius:5px 5px 0 0;padding:5px 8px;display:flex;flex-direction:column;gap:3px;border:1px solid rgba(0,0,0,0.07);border-bottom:none;">
|
||
<div style="width:50%;height:3px;border-radius:2px;background:#111;"></div>
|
||
<div style="width:26%;height:6px;border-radius:3px;background:#ef4444;"></div>
|
||
</div>
|
||
<div style="padding:4px 8px 6px;"><div class="scard-name">Editorial</div><div class="scard-desc" style="color:#ef4444;">Bold & opinionated</div></div>
|
||
</button>
|
||
<button class="scard" id="sc-startup" onclick="setStyle('startup','#f8fafc','#0ea5e9','Startup energy','Clear, conversion-focused')">
|
||
<div style="height:28px;background:#f8fafc;border-radius:5px 5px 0 0;padding:5px 8px;display:flex;flex-direction:column;gap:3px;border:1px solid rgba(0,0,0,0.05);border-bottom:none;">
|
||
<div style="width:50%;height:3px;border-radius:2px;background:#0f172a;opacity:0.65;"></div>
|
||
<div style="width:26%;height:6px;border-radius:3px;background:#0ea5e9;"></div>
|
||
</div>
|
||
<div style="padding:4px 8px 6px;"><div class="scard-name">Startup</div><div class="scard-desc" style="color:#0ea5e9;">Clean & focused</div></div>
|
||
</button>
|
||
<button class="scard" id="sc-minimal" onclick="setStyle('minimal','#ffffff','#111111','Ultra minimal','Let the product speak')">
|
||
<div style="height:28px;background:#fff;border-radius:6px 6px 0 0;padding:5px 8px;display:flex;flex-direction:column;gap:3px;border:1px solid rgba(0,0,0,0.06);border-bottom:none;">
|
||
<div style="width:50%;height:3px;border-radius:2px;background:#111;opacity:0.75;"></div>
|
||
<div style="width:26%;height:6px;border-radius:3px;background:#111;"></div>
|
||
</div>
|
||
<div style="padding:4px 8px 6px;"><div class="scard-name">Minimal</div><div class="scard-desc" style="color:#6b6b6b;">Less is more</div></div>
|
||
</button>
|
||
<button class="scard" id="sc-soft" onclick="setStyle('soft','#FAFCFA','#7FA58A','Soft UI','Smooth, friendly, and polished')">
|
||
<div style="height:28px;background:#FAFCFA;border-radius:5px 5px 0 0;padding:5px 8px;display:flex;flex-direction:column;gap:3px;border:1px solid rgba(0,0,0,0.06);border-bottom:none;">
|
||
<div style="width:50%;height:3px;border-radius:2px;background:#1f2937;opacity:0.45;"></div>
|
||
<div style="width:26%;height:6px;border-radius:3px;background:#7FA58A;"></div>
|
||
</div>
|
||
<div style="padding:4px 8px 6px;">
|
||
<div class="scard-name">Soft UI</div>
|
||
<div class="scard-desc" style="color:#6B8A78;">Smooth & approachable</div>
|
||
</div>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- AI decide — flush to bottom -->
|
||
<div style="margin-top:auto;padding:14px 16px 18px;">
|
||
<div class="sec-div" style="margin:0 0 14px;"></div>
|
||
<button class="surprise-btn" onclick="aiDecide()">✨ Surprise me</button>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
<!-- RIGHT: Preview — fills all available space -->
|
||
<div class = "preview-box"style="flex:1;display:flex;flex-direction:column;overflow:hidden;padding:4px 6px 6px;min-width:0;">
|
||
|
||
<!-- Label + device toggle -->
|
||
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:5px;padding:0 2px;">
|
||
<div style="font-size:9.5px;font-weight:700;letter-spacing:0.1em;text-transform:uppercase;color:#9ca3af;display:flex;align-items:center;gap:7px;">
|
||
<span style="width:6px;height:6px;border-radius:50%;background:#22c55e;display:inline-block;animation:pulse-dot 2s infinite;"></span>
|
||
Live preview
|
||
</div>
|
||
<div class="opt-btns">
|
||
<button class="opt-btn selected" data-group="device" data-tip="Runs in any browser, desktop & mobile" onclick="setDevice(this)">Web app</button>
|
||
<button class="opt-btn" data-group="device" data-tip="Optimised for phones, still works on desktop" onclick="setDevice(this)">Mobile-first</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Browser chrome -->
|
||
<div class="preview-chrome-box" style="flex:1;border-radius:12px;overflow:hidden;border:1.5px solid #e0e7ff;box-shadow:0 4px 24px rgba(99,102,241,0.08);display:flex;flex-direction:column;min-height:0;">
|
||
<div style="background:#f5f3ff;padding:7px 12px;display:flex;align-items:center;gap:8px;border-bottom:1px solid #e0e7ff;flex-shrink:0;">
|
||
<div style="display:flex;gap:4px;"><div style="width:7px;height:7px;border-radius:50%;background:#c7d2fe;"></div><div style="width:7px;height:7px;border-radius:50%;background:#c7d2fe;"></div><div style="width:7px;height:7px;border-radius:50%;background:#c7d2fe;"></div></div>
|
||
<div style="flex:1;background:#fff;border:1px solid #e0e7ff;border-radius:4px;padding:2px 9px;font-family:monospace;font-size:10px;color:#6366F1;">yourproduct.com</div>
|
||
</div>
|
||
<div id="preview-scroll" style="flex:1;overflow-y:auto;transition:background 0.3s;">
|
||
<div id="live-preview"></div>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
<!-- Hidden: copy IDs kept for JS compatibility -->
|
||
<div style="display:none;">
|
||
<div id="copy-headline"></div>
|
||
<div id="copy-sub"></div>
|
||
<div id="copy-cta"></div>
|
||
<div id="copy-bullets"></div>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
<!-- RIGHT PANEL -->
|
||
<div class="website-right" style="width:384px;border-left:1px solid var(--border);background:#f5f3ff;display:flex;flex-direction:column;flex-shrink:0;">
|
||
<div style="flex-shrink:0;padding:18px 0 0;">
|
||
<div style="margin:0 16px;padding-bottom:14px;border-bottom:1px solid #c7d2fe;">
|
||
<div style="font-size:15px;font-weight:800;letter-spacing:0.04em;text-transform:uppercase;color:#4338ca;margin-bottom:5px;">Your brand at a glance</div>
|
||
<div style="font-size:12px;color:#A0A0B8;line-height:1.5;">A summary of how your brand will look and sound to the world.</div>
|
||
</div>
|
||
</div>
|
||
<div style="flex:1;overflow-y:auto;padding:16px;">
|
||
|
||
<!-- 1. Your brand voice -->
|
||
<div style="font-size:9.5px;font-weight:700;letter-spacing:0.08em;text-transform:uppercase;color:var(--muted);margin-bottom:8px;">Your brand voice</div>
|
||
<div class="ws-rp-card" id="rp-voice-sentence" style="background:var(--white);border:1px solid var(--border);border-radius:10px;padding:11px 13px;margin-bottom:16px;font-size:12.5px;color:var(--ink);line-height:1.55;"></div>
|
||
|
||
<!-- 2. Website experience -->
|
||
<div style="font-size:9.5px;font-weight:700;letter-spacing:0.08em;text-transform:uppercase;color:var(--muted);margin-bottom:8px;">Website experience</div>
|
||
<div class="ws-rp-card" id="rp-experience" style="background:var(--white);border:1px solid var(--border);border-radius:10px;overflow:hidden;margin-bottom:16px;"></div>
|
||
|
||
<!-- 3. How users will perceive it -->
|
||
<div style="font-size:9.5px;font-weight:700;letter-spacing:0.08em;text-transform:uppercase;color:var(--muted);margin-bottom:8px;">How users will perceive it</div>
|
||
<div class="ws-rp-card" id="rp-perception" style="background:var(--white);border:1px solid var(--border);border-radius:10px;overflow:hidden;margin-bottom:16px;"></div>
|
||
|
||
<!-- 4. Optimized for -->
|
||
<div style="font-size:9.5px;font-weight:700;letter-spacing:0.08em;text-transform:uppercase;color:var(--muted);margin-bottom:8px;">Optimized for</div>
|
||
<div class="ws-rp-card" id="rp-topics-list" style="background:var(--white);border:1px solid var(--border);border-radius:10px;overflow:hidden;margin-bottom:16px;"></div>
|
||
|
||
<!-- Hidden: kept for JS compat -->
|
||
<span id="rp-tone" style="display:none;">Friendly</span>
|
||
<span id="rp-style" style="display:none;">Balanced</span>
|
||
<span id="rp-pers" style="display:none;">Warm</span>
|
||
<span id="rp-ws-name" style="display:none;">Editorial</span>
|
||
<span id="rp-ws-desc" style="display:none;">Bold headlines, strong opinions</span>
|
||
|
||
</div>
|
||
<div style="border-top:1px solid var(--border);padding:9px 0 13px;flex-shrink:0;display:flex;flex-direction:column;align-items:center;">
|
||
<p style="font-size:11.5px;color:var(--muted);text-align:center;margin:0 0 10px;line-height:1.5;">All set — let's build it.</p>
|
||
<a href="09_build.html" style="text-decoration:none;display:block;width:80%;"><button class="next-btn">Next : Build my product</button></a>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
/* ── State ── */
|
||
var VOICE = {tone:'Friendly', style:'Balanced', pers:'Warm'};
|
||
var TOPICS = {problem:true, audience:true, timing:true, benefits:false, comparison:false};
|
||
var STYLE = {id:'editorial', bg:'#ffffff', accent:'#ef4444', label:'Editorial', desc:'Bold headlines, strong opinions'};
|
||
var DEVICE = 'desktop';
|
||
|
||
var PILL_LABELS = {
|
||
tone: {0:'Friendly', 50:'Balanced', 100:'Professional'},
|
||
style: {0:'Casual', 50:'Balanced', 100:'Precise'},
|
||
pers: {0:'Warm', 50:'Steady', 100:'Direct'}
|
||
};
|
||
|
||
var COPY_MATRIX = {
|
||
/* Friendly ─────────────────────────────────────────────────────────────── */
|
||
'Friendly-Casual-Warm': {h:'Build something people actually love', s:"We make it super easy to go from idea to product — no stress, just results. You'll wonder why you waited.", cta:"Let's build together"},
|
||
'Friendly-Casual-Steady': {h:'From idea to launch, one step at a time', s:"We walk with you every step — from your first spark to your first 1,000 users. No rush, just progress.", cta:'Start your journey'},
|
||
'Friendly-Casual-Direct': {h:'Stop waiting. Start building.', s:"Your idea is good. Let's make it real — it's way simpler than you think.", cta:'Get started now'},
|
||
'Friendly-Balanced-Warm': {h:'Your idea deserves to exist', s:'A thoughtful platform for founders who want to move fast without cutting corners.', cta:'Build something real'},
|
||
'Friendly-Balanced-Steady': {h:'Build, launch, and grow — all in one place', s:'Everything you need to turn a product idea into a growing business.', cta:'Start building'},
|
||
'Friendly-Balanced-Direct': {h:'From zero to product in days', s:'The fastest path from idea to market — no fluff, no wasted time.', cta:'Launch your product'},
|
||
'Friendly-Precise-Warm': {h:'From rough idea to live product in 5 clear steps', s:'A guided, step-by-step process that covers every decision — from architecture to your first customer — with care.', cta:'See how it works'},
|
||
'Friendly-Precise-Steady': {h:'A proven 5-step path to your first 1,000 users', s:'Our structured process covers architecture, design, copy, and launch — every stage defined, nothing left to chance.', cta:'Follow the process'},
|
||
'Friendly-Precise-Direct': {h:"Ship in days. Here's exactly how.", s:'5 defined steps. One platform. From idea to production-ready product — zero guesswork, zero wasted time.', cta:'Start now'},
|
||
/* Balanced ─────────────────────────────────────────────────────────────── */
|
||
'Balanced-Casual-Warm': {h:'Turn your idea into something real', s:"We're here to help you build the thing you've been thinking about — no overthinking required.", cta:'Build something real'},
|
||
'Balanced-Casual-Steady': {h:'Build it. Ship it. Grow it.', s:'We take the guesswork out of building a product. Just follow the process and watch it come together.', cta:'Start building'},
|
||
'Balanced-Casual-Direct': {h:'Idea to product. Fast.', s:'Stop planning, start shipping. We give you everything you need to move fast and get to market.', cta:'Get moving'},
|
||
'Balanced-Balanced-Warm': {h:'Your idea deserves to exist', s:'A thoughtful platform for founders who want to move fast without cutting corners.', cta:'Build something real'},
|
||
'Balanced-Balanced-Steady': {h:'Build, launch, and grow — all in one place', s:'Everything you need to turn a product idea into a growing business.', cta:'Start building'},
|
||
'Balanced-Balanced-Direct': {h:'From zero to product in days', s:'The fastest path from idea to market. No fluff, no wasted time.', cta:'Launch your product'},
|
||
'Balanced-Precise-Warm': {h:'From concept to customers in one structured flow', s:'Our platform guides you through every decision — from architecture to launch copy — with precision and care.', cta:'Explore the workflow'},
|
||
'Balanced-Precise-Steady': {h:'A structured path from idea to market', s:'Every step is defined, every deliverable is clear. Move confidently from concept to launch.', cta:'See the process'},
|
||
'Balanced-Precise-Direct': {h:'Zero to launched in 5 defined steps', s:'Architecture, design, copy, and deployment — all mapped upfront. No surprises, no wasted cycles.', cta:'Start now'},
|
||
/* Professional ─────────────────────────────────────────────────────────── */
|
||
'Professional-Casual-Warm': {h:'Sophisticated tools for ambitious builders', s:'We combine enterprise-grade infrastructure with a process that feels surprisingly human and approachable.', cta:'Explore the platform'},
|
||
'Professional-Casual-Steady': {h:'The reliable way to go from idea to product', s:'A proven approach that serious founders use to ship faster — without the complexity or the headaches.', cta:'Get started'},
|
||
'Professional-Casual-Direct': {h:'Build fast. Ship confident.', s:'Skip the setup headaches. We handle the complexity so you can focus on what actually matters — shipping.', cta:'Start now'},
|
||
'Professional-Balanced-Warm': {h:'Enterprise-grade tools, founder-friendly experience',s:'Sophisticated infrastructure wrapped in an experience designed for ambitious builders.', cta:'Explore the platform'},
|
||
'Professional-Balanced-Steady': {h:'The reliable path from idea to market', s:'A structured, proven approach to building and launching software products at speed.', cta:'Get started'},
|
||
'Professional-Balanced-Direct': {h:'Build fast. Ship confident.', s:'Production-ready infrastructure and AI-assisted development. Ship in days, not months.', cta:'Start now'},
|
||
'Professional-Precise-Warm': {h:'Production-grade infrastructure with a human touch',s:'From scalable architecture to conversion-optimised copy — every component built to specification, every decision explained.',cta:'Review the specs'},
|
||
'Professional-Precise-Steady': {h:'A methodical approach to product development at speed',s:'Defined workflows, documented architecture, and measurable milestones — from initial concept through to market launch.',cta:'See the methodology'},
|
||
'Professional-Precise-Direct': {h:'Ship production-ready in days.', s:'Automated architecture decisions, AI-generated copy, one-click deployment. Measurable output at every stage.', cta:'Get started'}
|
||
};
|
||
|
||
var TOPIC_TEXT = {
|
||
problem: 'Solves a real, painful problem',
|
||
audience: 'Built for a specific, well-defined audience',
|
||
timing: 'The market is ready right now',
|
||
benefits: 'Clear advantages over the status quo',
|
||
comparison: 'Better than existing alternatives'
|
||
};
|
||
|
||
var TOPIC_RP_LABELS = {
|
||
problem: 'Highlighting a clear pain point',
|
||
audience: 'Targeting a specific audience',
|
||
timing: 'Creating urgency',
|
||
benefits: 'Showing value quickly',
|
||
comparison: 'Differentiating from competitors'
|
||
};
|
||
|
||
/* ── Device ── */
|
||
function setDevice(btn) {
|
||
document.querySelectorAll('[data-group="device"]').forEach(function(b){ b.classList.remove('selected'); });
|
||
btn.classList.add('selected');
|
||
DEVICE = btn.getAttribute('data-tip') === 'Optimised for phones, still works on desktop' ? 'mobile' : 'desktop';
|
||
renderPreview();
|
||
}
|
||
|
||
/* ── Controls ── */
|
||
function saveWebsiteState(){
|
||
try {
|
||
var topicLabels = {problem:'The problem', audience:"Who it's for", timing:'Why now', benefits:'Key benefits', comparison:'vs. alternatives'};
|
||
var activeTopics = Object.keys(TOPICS).filter(function(k){ return TOPICS[k]; }).map(function(k){ return topicLabels[k]; });
|
||
localStorage.setItem('vibn_website', JSON.stringify({
|
||
voice: VOICE,
|
||
styleLabel: STYLE.label,
|
||
topics: activeTopics
|
||
}));
|
||
} catch(e){}
|
||
}
|
||
|
||
function setPill(el, key, val) {
|
||
document.getElementById('pills-' + key).querySelectorAll('.vpill').forEach(function(p){ p.classList.remove('active'); });
|
||
el.classList.add('active');
|
||
VOICE[key] = PILL_LABELS[key][val];
|
||
document.getElementById('rp-' + key).textContent = VOICE[key];
|
||
renderAll();
|
||
saveWebsiteState();
|
||
}
|
||
|
||
function toggleTopic(el, key) {
|
||
var on = !el.classList.contains('active');
|
||
el.classList.toggle('active', on);
|
||
TOPICS[key] = on;
|
||
renderAll();
|
||
saveWebsiteState();
|
||
}
|
||
|
||
function setStyle(id, bg, accent, label, desc) {
|
||
document.querySelectorAll('.scard').forEach(function(c){ c.classList.remove('selected'); });
|
||
document.getElementById('sc-' + id).classList.add('selected');
|
||
STYLE = {id:id, bg:bg, accent:accent, label:label, desc:desc};
|
||
document.getElementById('rp-ws-name').textContent = label;
|
||
document.getElementById('rp-ws-desc').textContent = desc;
|
||
renderAll();
|
||
saveWebsiteState();
|
||
}
|
||
|
||
/* ── Copy generation ── */
|
||
function getCopy() {
|
||
return COPY_MATRIX[VOICE.tone + '-' + VOICE.style + '-' + VOICE.pers] || COPY_MATRIX['Balanced-Balanced-Steady'];
|
||
}
|
||
|
||
function getBullets() {
|
||
return Object.keys(TOPICS).filter(function(k){ return TOPICS[k]; }).map(function(k){ return TOPIC_TEXT[k]; });
|
||
}
|
||
|
||
/* ── Render ── */
|
||
function renderPreview() {
|
||
var copy = getCopy();
|
||
var bullets = getBullets();
|
||
var bg = STYLE.bg;
|
||
var accent = STYLE.accent;
|
||
var isDark = ['#0f172a','#0c0a09','#1a1a1a'].indexOf(bg) !== -1;
|
||
var tc = isDark ? '#ffffff' : '#111111';
|
||
var sub = isDark ? 'rgba(255,255,255,0.55)' : '#6b7280';
|
||
var border = isDark ? 'rgba(255,255,255,0.07)' : 'rgba(0,0,0,0.06)';
|
||
|
||
/* ── Per-style theme variables ── */
|
||
function hexRgbaW(h,a){ var r=parseInt(h.slice(1,3),16),g=parseInt(h.slice(3,5),16),b=parseInt(h.slice(5,7),16); return 'rgba('+r+','+g+','+b+','+a+')'; }
|
||
var S = {
|
||
editorial: {
|
||
r: 4, cardR: 4, navR: 4,
|
||
shadow: 'none', cardShadow: 'none',
|
||
headingWeight: 800, headingTracking: '-0.03em',
|
||
border: isDark ? 'rgba(255,255,255,0.10)' : 'rgba(0,0,0,0.12)',
|
||
navBorder: isDark ? 'rgba(255,255,255,0.10)' : 'rgba(0,0,0,0.12)',
|
||
cardBg: isDark ? 'rgba(255,255,255,0.05)' : '#fff',
|
||
sectionBg: isDark ? 'rgba(255,255,255,0.03)' : 'rgba(0,0,0,0.02)',
|
||
pillBg: isDark ? 'rgba(255,255,255,0.08)' : hexRgbaW(accent,0.10),
|
||
ctaR: '4px', secPad: '22px 24px', heroPad: '24px 24px 14px',
|
||
subColor: isDark ? 'rgba(255,255,255,0.50)' : '#374151'
|
||
},
|
||
startup: {
|
||
r: 8, cardR: 8, navR: 6,
|
||
shadow: '0 1px 4px rgba(0,0,0,0.07)', cardShadow: '0 1px 4px rgba(0,0,0,0.07)',
|
||
headingWeight: 700, headingTracking: '-0.02em',
|
||
border: isDark ? 'rgba(255,255,255,0.07)' : 'rgba(0,0,0,0.07)',
|
||
navBorder: isDark ? 'rgba(255,255,255,0.07)' : 'rgba(0,0,0,0.07)',
|
||
cardBg: isDark ? 'rgba(255,255,255,0.05)' : '#fff',
|
||
sectionBg: isDark ? 'rgba(255,255,255,0.03)' : 'rgba(99,102,241,0.03)',
|
||
pillBg: isDark ? 'rgba(255,255,255,0.08)' : hexRgbaW(accent,0.07),
|
||
ctaR: '8px', secPad: '28px 24px', heroPad: '26px 24px 16px',
|
||
subColor: sub
|
||
},
|
||
minimal: {
|
||
r: 4, cardR: 4, navR: 4,
|
||
shadow: 'none', cardShadow: 'none',
|
||
headingWeight: 600, headingTracking: '-0.01em',
|
||
border: isDark ? 'rgba(255,255,255,0.05)' : 'rgba(0,0,0,0.05)',
|
||
navBorder: isDark ? 'rgba(255,255,255,0.05)' : 'rgba(0,0,0,0.05)',
|
||
cardBg: isDark ? 'rgba(255,255,255,0.03)' : '#fafafa',
|
||
sectionBg: isDark ? 'rgba(255,255,255,0.02)' : 'rgba(0,0,0,0.01)',
|
||
pillBg: isDark ? 'rgba(255,255,255,0.05)' : 'rgba(0,0,0,0.04)',
|
||
ctaR: '4px', secPad: '36px 24px', heroPad: '36px 24px 20px',
|
||
subColor: isDark ? 'rgba(255,255,255,0.40)' : '#9ca3af'
|
||
},
|
||
warm: {
|
||
r: 14, cardR: 14, navR: 8,
|
||
shadow: '0 2px 12px rgba(0,0,0,0.08)', cardShadow: '0 2px 8px rgba(0,0,0,0.06)',
|
||
headingWeight: 700, headingTracking: '-0.01em',
|
||
border: isDark ? 'rgba(255,255,255,0.07)' : 'rgba(0,0,0,0.05)',
|
||
navBorder: isDark ? 'rgba(255,255,255,0.07)' : 'rgba(0,0,0,0.06)',
|
||
cardBg: isDark ? 'rgba(255,255,255,0.05)' : hexRgbaW(accent,0.04),
|
||
sectionBg: isDark ? 'rgba(255,255,255,0.03)' : hexRgbaW(accent,0.05),
|
||
pillBg: isDark ? 'rgba(255,255,255,0.08)' : hexRgbaW(accent,0.08),
|
||
ctaR: '14px', secPad: '28px 24px', heroPad: '30px 24px 18px',
|
||
subColor: sub
|
||
}
|
||
}[STYLE.id] || {
|
||
r:8, cardR:8, navR:6, shadow:'none', cardShadow:'none',
|
||
headingWeight:700, headingTracking:'-0.02em',
|
||
border: border, navBorder: border,
|
||
cardBg: isDark?'rgba(255,255,255,0.05)':'#fff',
|
||
sectionBg: isDark?'rgba(255,255,255,0.03)':'rgba(99,102,241,0.03)',
|
||
pillBg: isDark?'rgba(255,255,255,0.08)':hexRgbaW(accent,0.07),
|
||
ctaR:'8px', secPad:'28px 24px', heroPad:'26px 24px 16px',
|
||
subColor: sub
|
||
};
|
||
|
||
/* override shared vars with per-style ones */
|
||
border = S.border;
|
||
sub = S.subColor;
|
||
|
||
var pillsHtml = '';
|
||
if (bullets.length) {
|
||
pillsHtml = '<div style="padding:0 24px 18px;display:flex;flex-wrap:wrap;gap:6px;justify-content:center;">';
|
||
bullets.forEach(function(b) {
|
||
pillsHtml += '<div style="background:' + S.pillBg + ';border-radius:20px;padding:3px 11px;font-size:10px;color:' + (isDark ? 'rgba(255,255,255,0.65)' : accent) + ';">' + b + '</div>';
|
||
});
|
||
pillsHtml += '</div>';
|
||
}
|
||
|
||
// Problem section
|
||
var problemHtml = (TOPICS.problem || TOPICS.audience)
|
||
? '<div style="padding:'+S.secPad+';background:' + S.sectionBg + ';border-top:1px solid ' + S.border + ';text-align:center;">'
|
||
+ '<div style="font-size:8.5px;font-weight:700;letter-spacing:0.1em;text-transform:uppercase;color:' + accent + ';margin-bottom:10px;">The Problem</div>'
|
||
+ '<div style="font-size:15px;font-weight:'+S.headingWeight+';color:' + tc + ';letter-spacing:'+S.headingTracking+';line-height:1.3;margin-bottom:8px;">Most founders waste months on the wrong things</div>'
|
||
+ '<div style="font-size:11px;color:' + sub + ';line-height:1.65;max-width:340px;margin-left:auto;margin-right:auto;">Building a product is hard. Knowing what to build, how to position it, and who to build it for shouldn\'t be. That\'s what we fix.</div>'
|
||
+ '</div>'
|
||
: '';
|
||
|
||
// Benefits section
|
||
var benefitItems = [
|
||
{icon:'⚡', title:'10× faster setup', body:'Skip the research rabbit hole — vibn structures everything for you.'},
|
||
{icon:'🎯', title:'Laser-focused', body:'Every decision is tied to your specific audience and problem.'},
|
||
{icon:'🚀', title:'Launch-ready output', body:'Get copy, architecture, and a website in one session.'}
|
||
];
|
||
var benefitCols = DEVICE === 'mobile' ? '1fr' : '1fr 1fr 1fr';
|
||
var benefitsHtml = '<div style="padding:'+S.secPad+';border-top:1px solid ' + S.border + ';">'
|
||
+ '<div style="font-size:8.5px;font-weight:700;letter-spacing:0.1em;text-transform:uppercase;color:' + accent + ';margin-bottom:14px;">Why it works</div>'
|
||
+ '<div style="display:grid;grid-template-columns:' + benefitCols + ';gap:10px;">';
|
||
benefitItems.forEach(function(b) {
|
||
benefitsHtml += '<div style="background:' + S.cardBg + ';border:1px solid ' + S.border + ';border-radius:' + S.cardR + 'px;padding:12px;box-shadow:' + S.cardShadow + ';">'
|
||
+ '<div style="font-size:16px;margin-bottom:6px;">' + b.icon + '</div>'
|
||
+ '<div style="font-size:10.5px;font-weight:'+S.headingWeight+';color:' + tc + ';margin-bottom:4px;">' + b.title + '</div>'
|
||
+ '<div style="font-size:9.5px;color:' + sub + ';line-height:1.5;">' + b.body + '</div>'
|
||
+ '</div>';
|
||
});
|
||
benefitsHtml += '</div></div>';
|
||
|
||
// Final CTA section
|
||
var ctaSectionHtml = '<div style="padding:36px 24px;text-align:center;background:' + accent + ';margin-top:0;">'
|
||
+ '<div style="font-size:17px;font-weight:'+S.headingWeight+';color:#fff;letter-spacing:'+S.headingTracking+';line-height:1.25;margin-bottom:8px;">Ready to stop planning<br>and start building?</div>'
|
||
+ '<div style="font-size:10.5px;color:rgba(255,255,255,0.75);margin-bottom:16px;">Join founders who shipped their MVP in days, not months.</div>'
|
||
+ '<div style="display:inline-block;background:#fff;color:' + accent + ';font-size:11px;font-weight:700;padding:9px 22px;border-radius:' + S.ctaR + ';">' + copy.cta + '</div>'
|
||
+ '</div>';
|
||
|
||
var isAppDark = document.documentElement.dataset.theme === 'dark';
|
||
var phoneGlow = isAppDark
|
||
? '0 8px 40px rgba(0,0,0,0.65),0 0 0 1px rgba(255,255,255,0.18),0 0 32px rgba(255,255,255,0.12),0 0 64px rgba(255,255,255,0.06)'
|
||
: '0 8px 32px rgba(0,0,0,0.15)';
|
||
var mobileWrapOpen = DEVICE === 'mobile'
|
||
? '<div style="background:' + (isDark ? '#111827' : '#f0f0f8') + ';padding:20px 0;min-height:100%;"><div style="background:' + bg + ';max-width:375px;margin:0 auto;border-radius:' + S.r*2 + 'px;overflow:hidden;box-shadow:' + phoneGlow + ';font-family:\'Plus Jakarta Sans\',sans-serif;">'
|
||
: '';
|
||
var mobileWrapClose = DEVICE === 'mobile' ? '</div></div>' : '';
|
||
|
||
var html = (DEVICE === 'mobile' ? mobileWrapOpen : '<div style="background:' + bg + ';font-family:\'Plus Jakarta Sans\',sans-serif;">')
|
||
+ '<div style="padding:9px 16px;display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid ' + S.navBorder + ';box-shadow:' + S.shadow + ';">'
|
||
+ '<span style="font-size:12px;font-weight:'+S.headingWeight+';color:' + tc + ';">YourApp</span>'
|
||
+ '<div style="display:flex;gap:12px;"><span style="font-size:9.5px;color:' + sub + ';">Product</span><span style="font-size:9.5px;color:' + sub + ';">Pricing</span></div>'
|
||
+ '<div style="background:' + accent + ';color:#fff;font-size:9.5px;font-weight:700;padding:4px 10px;border-radius:' + S.ctaR + ';">' + copy.cta + '</div>'
|
||
+ '</div>'
|
||
+ '<div style="padding:'+S.heroPad+';text-align:center;">'
|
||
+ '<div style="font-size:20px;font-weight:'+S.headingWeight+';color:' + tc + ';letter-spacing:'+S.headingTracking+';line-height:1.2;margin-bottom:9px;">' + copy.h + '</div>'
|
||
+ '<div style="font-size:11.5px;color:' + sub + ';line-height:1.65;margin-bottom:16px;max-width:300px;margin-left:auto;margin-right:auto;">' + copy.s + '</div>'
|
||
+ '<div style="display:inline-flex;gap:8px;justify-content:center;">'
|
||
+ '<div style="background:' + accent + ';color:#fff;font-size:11px;font-weight:700;padding:8px 18px;border-radius:' + S.ctaR + ';box-shadow:' + S.shadow + ';">' + copy.cta + '</div>'
|
||
+ '<div style="background:transparent;color:' + sub + ';font-size:11px;padding:8px 14px;border-radius:' + S.ctaR + ';border:1px solid ' + S.border + ';">See how it works</div>'
|
||
+ '</div></div>'
|
||
+ pillsHtml
|
||
+ problemHtml
|
||
+ benefitsHtml
|
||
+ ctaSectionHtml
|
||
+ (DEVICE === 'mobile' ? mobileWrapClose : '</div>');
|
||
|
||
var el = document.getElementById('live-preview');
|
||
el.style.transition = 'opacity 0.25s';
|
||
el.style.opacity = '0';
|
||
setTimeout(function() { el.innerHTML = html; el.style.opacity = '1'; }, 150);
|
||
}
|
||
|
||
function renderCopy() {
|
||
var copy = getCopy();
|
||
var bullets = getBullets();
|
||
|
||
function fade(id, fn) {
|
||
var el = document.getElementById(id);
|
||
el.style.transition = 'opacity 0.2s';
|
||
el.style.opacity = '0';
|
||
setTimeout(function() { fn(el); el.style.opacity = '1'; }, 130);
|
||
}
|
||
|
||
fade('copy-headline', function(el) { el.textContent = copy.h; });
|
||
fade('copy-sub', function(el) { el.textContent = copy.s; });
|
||
fade('copy-cta', function(el) { el.textContent = copy.cta; });
|
||
fade('copy-bullets', function(el) {
|
||
el.innerHTML = bullets.map(function(b) {
|
||
return '<div style="display:flex;align-items:flex-start;gap:6px;font-size:11.5px;color:#6b7280;"><span style="color:#6366F1;flex-shrink:0;font-size:11px;">✓</span><span>' + b + '</span></div>';
|
||
}).join('');
|
||
});
|
||
|
||
// Update right panel topics
|
||
var rpTopics = document.getElementById('rp-topics-list');
|
||
if (rpTopics) {
|
||
rpTopics.innerHTML = Object.keys(TOPICS).filter(function(k) { return TOPICS[k]; }).map(function(k) {
|
||
return '<div class="deliverable-row"><div style="width:5px;height:5px;border-radius:50%;background:#6366F1;flex-shrink:0;"></div>' + TOPIC_RP_LABELS[k] + '</div>';
|
||
}).join('');
|
||
}
|
||
}
|
||
|
||
/* ── Right-panel lookup tables ── */
|
||
var RP_TONE_ADJ = {Friendly:'Approachable', Balanced:'Measured', Professional:'Authoritative'};
|
||
var RP_STYLE_ADJ = {Casual:'conversational and informal', Balanced:'clear and well-crafted', Precise:'precise and data-led'};
|
||
var RP_PERS_ADJ = {Warm:'a warm, human feel', Steady:'a steady, reliable character', Direct:'a bold, direct edge'};
|
||
|
||
/* "Website experience" — bullet 1: visual style, bullet 2: writing style, bullet 3: tone */
|
||
var RP_EXP_VSTYLE = {
|
||
editorial: 'Strong visual hierarchy — bold headlines, designed to stop the scroll',
|
||
startup: 'Clean, conversion-first layout with benefit-led sections and clear CTAs',
|
||
minimal: 'Generous whitespace — nothing wasted, content takes centre stage',
|
||
warm: 'Approachable visuals and soft forms with trust signals woven in naturally'
|
||
};
|
||
var RP_EXP_WRITINGSTYLE = {
|
||
Casual: 'Copy that feels natural and conversational — no jargon, no fluff',
|
||
Balanced: 'Clear, well-crafted messaging that informs and builds confidence',
|
||
Precise: 'Data-led, specific language with measurable claims and no vagueness'
|
||
};
|
||
var RP_EXP_TONE = {
|
||
Friendly: 'Designed to welcome and reassure — visitors feel at ease immediately',
|
||
Balanced: 'Positioned to engage and convert — approachable and credible in equal measure',
|
||
Professional: 'Built to establish authority and attract qualified, high-intent leads'
|
||
};
|
||
|
||
/* "How users will perceive it" — bullet 1: visual style, bullet 2: tone, bullet 3: personality quote */
|
||
var RP_PERC_VSTYLE = {
|
||
editorial: 'Bold and self-assured',
|
||
startup: 'Modern and credible',
|
||
minimal: 'Calm and considered',
|
||
warm: 'Genuine and human'
|
||
};
|
||
var RP_PERC_TONE = {
|
||
Friendly: 'Inviting',
|
||
Balanced: 'Trustworthy',
|
||
Professional: 'Authoritative'
|
||
};
|
||
var RP_PERC_PERS = {
|
||
Warm: '\u201cThey actually get my problem\u201d',
|
||
Steady: '\u201cThese people know what they\u2019re doing\u201d',
|
||
Direct: '\u201cI want to try this right now\u201d'
|
||
};
|
||
|
||
function renderRightPanel() {
|
||
var dot = '<div style="width:5px;height:5px;border-radius:50%;background:#6366F1;flex-shrink:0;"></div>';
|
||
|
||
// 1. Brand voice sentence
|
||
var vEl = document.getElementById('rp-voice-sentence');
|
||
if (vEl) {
|
||
vEl.textContent =
|
||
(RP_TONE_ADJ[VOICE.tone] || VOICE.tone) + ', ' +
|
||
(RP_STYLE_ADJ[VOICE.style]|| VOICE.style) + ' \u2014 with ' +
|
||
(RP_PERS_ADJ[VOICE.pers] || VOICE.pers) + '.';
|
||
}
|
||
|
||
// 2. Website experience — reflects website style + writing style + tone
|
||
var expEl = document.getElementById('rp-experience');
|
||
if (expEl) {
|
||
expEl.innerHTML = [
|
||
RP_EXP_VSTYLE[STYLE.id] || '',
|
||
RP_EXP_WRITINGSTYLE[VOICE.style] || '',
|
||
RP_EXP_TONE[VOICE.tone] || ''
|
||
].map(function(b) {
|
||
return '<div class="deliverable-row">' + dot + b + '</div>';
|
||
}).join('');
|
||
}
|
||
|
||
// 3. How users will perceive it — reflects website style + tone + personality
|
||
var percEl = document.getElementById('rp-perception');
|
||
if (percEl) {
|
||
percEl.innerHTML = [
|
||
RP_PERC_VSTYLE[STYLE.id] || '',
|
||
RP_PERC_TONE[VOICE.tone] || '',
|
||
RP_PERC_PERS[VOICE.pers] || ''
|
||
].map(function(b) {
|
||
return '<div class="deliverable-row">' + dot + b + '</div>';
|
||
}).join('');
|
||
}
|
||
}
|
||
|
||
function renderAll() {
|
||
renderPreview();
|
||
renderCopy();
|
||
renderRightPanel();
|
||
}
|
||
|
||
/* ── AI Decide ── */
|
||
function aiDecide() {
|
||
// Balanced tone, Balanced style, Warm personality
|
||
document.getElementById('pills-tone').querySelectorAll('.vpill').forEach(function(p, i) { p.classList.toggle('active', i === 1); });
|
||
VOICE.tone = 'Balanced'; document.getElementById('rp-tone').textContent = 'Balanced';
|
||
|
||
document.getElementById('pills-style').querySelectorAll('.vpill').forEach(function(p, i) { p.classList.toggle('active', i === 1); });
|
||
VOICE.style = 'Balanced'; document.getElementById('rp-style').textContent = 'Balanced';
|
||
|
||
document.getElementById('pills-pers').querySelectorAll('.vpill').forEach(function(p, i) { p.classList.toggle('active', i === 0); });
|
||
VOICE.pers = 'Warm'; document.getElementById('rp-pers').textContent = 'Warm';
|
||
|
||
// Topics: problem + audience + benefits
|
||
var aiTopics = {problem:true, audience:true, timing:false, benefits:true, comparison:false};
|
||
document.querySelectorAll('.tchip').forEach(function(c) {
|
||
var m = c.getAttribute('onclick').match(/'(\w+)'\)/);
|
||
if (m) { var k = m[1]; c.classList.toggle('active', !!aiTopics[k]); TOPICS[k] = !!aiTopics[k]; }
|
||
});
|
||
|
||
// Startup style (also calls renderAll internally)
|
||
setStyle('startup', '#f8fafc', '#0ea5e9', 'Startup energy', 'Clear, conversion-focused');
|
||
}
|
||
|
||
/* ── Theme ── */
|
||
function saveAndExit() { window.location.href = '03_dashboard.html'; }
|
||
function toggleTheme() {
|
||
const html = document.documentElement;
|
||
const isDark = html.dataset.theme === 'dark';
|
||
html.dataset.theme = isDark ? '' : 'dark';
|
||
document.getElementById('dark-toggle').textContent = isDark ? '🌙 Dark mode' : '☀️ Light mode';
|
||
localStorage.setItem('vibn-theme', isDark ? '' : 'dark');
|
||
}
|
||
(function() {
|
||
const saved = localStorage.getItem('vibn-theme');
|
||
if (saved === 'dark') {
|
||
document.documentElement.dataset.theme = 'dark';
|
||
document.addEventListener('DOMContentLoaded', function() {
|
||
const btn = document.getElementById('dark-toggle');
|
||
if (btn) btn.textContent = '☀️ Light mode';
|
||
});
|
||
}
|
||
})();
|
||
|
||
document.addEventListener('DOMContentLoaded', function() {
|
||
try {
|
||
var name = localStorage.getItem('vibn_project_name') || 'My project';
|
||
var el = document.getElementById('sidebar-project-name');
|
||
el.textContent = name; el.style.display = 'block';
|
||
} catch(e) {}
|
||
|
||
// Sync device mode from Architect frontend selection
|
||
try {
|
||
var frontendTip = localStorage.getItem('vibn_frontend');
|
||
if (frontendTip === 'Optimised for phones, still works on desktop') {
|
||
DEVICE = 'mobile';
|
||
document.querySelectorAll('[data-group="device"]').forEach(function(b) {
|
||
b.classList.toggle('selected', b.getAttribute('data-tip') === frontendTip);
|
||
});
|
||
}
|
||
} catch(e) {}
|
||
|
||
renderAll();
|
||
});
|
||
</script>
|
||
</body></html>
|