Files
vibn-frontend/justine/vibn front end/08_website.html
mawkone 99deb546c8 Rip out Theia, bump submodules, retire platform/ scaffold, snapshot docs + design assets
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
2026-04-22 18:06:37 -07:00

806 lines
57 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!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>