| | <!DOCTYPE html> |
| | <html lang="en"> |
| | <head> |
| | <meta charset="UTF-8"/> |
| | <meta name="viewport" content="width=device-width, initial-scale=1.0"/> |
| | <title>AI Boardroom β Multi-Agent Strategic Decision System</title> |
| | <style> |
| | @import url('https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,400;0,600;0,700;1,400;1,600&family=Raleway:wght@300;400;500;600;700&family=Courier+Prime:wght@400;700&display=swap'); |
| | |
| | :root { |
| | --bg: #0A0705; |
| | --bg2: #110D09; |
| | --bg3: #18120D; |
| | --bg4: #201810; |
| | --border: #2E2218; |
| | --border2:#3D3020; |
| | --tx: #E8DDD0; |
| | --t2: #A89880; |
| | --t3: #6A5A48; |
| | --brass: #B8902A; |
| | --brass2: #D4AE50; |
| | --brass3: #8A6A18; |
| | --cream: #F0E8D8; |
| | --red: #C0392B; |
| | --green: #27AE60; |
| | --amber: #E67E22; |
| | --blue: #2980B9; |
| | --purple: #8E44AD; |
| | } |
| | |
| | * { box-sizing: border-box; margin: 0; padding: 0; } |
| | body { |
| | font-family: 'Raleway', sans-serif; |
| | background: var(--bg); |
| | color: var(--tx); |
| | min-height: 100vh; |
| | |
| | background-image: |
| | repeating-linear-gradient( |
| | 92deg, |
| | transparent, |
| | transparent 2px, |
| | rgba(184,144,42,.015) 2px, |
| | rgba(184,144,42,.015) 4px |
| | ), |
| | repeating-linear-gradient( |
| | 178deg, |
| | transparent, |
| | transparent 8px, |
| | rgba(255,255,255,.008) 8px, |
| | rgba(255,255,255,.008) 9px |
| | ); |
| | } |
| | |
| | input, textarea, button, select { font-family: 'Raleway', sans-serif; } |
| | button { cursor: pointer; } |
| | textarea:focus, input:focus, select:focus { outline: 1px solid var(--brass3); } |
| | ::-webkit-scrollbar { width: 4px; } |
| | ::-webkit-scrollbar-track { background: var(--bg2); } |
| | ::-webkit-scrollbar-thumb { background: var(--border2); border-radius: 2px; } |
| | |
| | |
| | @keyframes fadeIn { from { opacity:0; transform:translateY(8px); } to { opacity:1; transform:translateY(0); } } |
| | @keyframes shimmer { 0% { background-position:200% center; } 100% { background-position:-200% center; } } |
| | @keyframes pulse { 0%,100% { opacity:.3; } 50% { opacity:1; } } |
| | @keyframes typing { from { width:0; } to { width:100%; } } |
| | @keyframes gavel { 0%,100% { transform:rotate(-15deg); } 50% { transform:rotate(5deg); } } |
| | @keyframes slideIn { from { opacity:0; transform:translateX(-12px); } to { opacity:1; transform:translateX(0); } } |
| | @keyframes expand { from { max-height:0; opacity:0; } to { max-height:800px; opacity:1; } } |
| | |
| | .brass-text { |
| | background: linear-gradient(90deg, var(--brass3), var(--brass2), var(--brass), var(--brass2), var(--brass3)); |
| | background-size: 200% auto; |
| | -webkit-background-clip: text; |
| | -webkit-text-fill-color: transparent; |
| | background-clip: text; |
| | animation: shimmer 5s linear infinite; |
| | } |
| | |
| | |
| | .panel { |
| | background: var(--bg2); |
| | border: 1px solid var(--border); |
| | border-radius: 4px; |
| | padding: 24px; |
| | position: relative; |
| | } |
| | .panel::before { |
| | content: ''; |
| | position: absolute; |
| | top: 0; left: 0; right: 0; |
| | height: 2px; |
| | background: linear-gradient(90deg, transparent, var(--brass3), var(--brass), var(--brass3), transparent); |
| | border-radius: 4px 4px 0 0; |
| | } |
| | |
| | .inp { |
| | width: 100%; |
| | background: var(--bg3); |
| | border: 1px solid var(--border); |
| | border-radius: 3px; |
| | color: var(--tx); |
| | padding: 10px 14px; |
| | font-size: 13px; |
| | font-family: 'Raleway', sans-serif; |
| | transition: border-color .2s; |
| | } |
| | .inp:focus { border-color: var(--brass3); } |
| | .inp::placeholder { color: var(--t3); } |
| | |
| | .btn-brass { |
| | background: linear-gradient(135deg, var(--brass3), var(--brass), var(--brass2)); |
| | border: none; |
| | border-radius: 3px; |
| | color: #0A0705; |
| | font-family: 'Raleway', sans-serif; |
| | font-weight: 700; |
| | font-size: 13px; |
| | letter-spacing: 1.5px; |
| | text-transform: uppercase; |
| | cursor: pointer; |
| | transition: opacity .15s; |
| | padding: 11px 28px; |
| | } |
| | .btn-brass:hover:not(:disabled) { opacity: .85; } |
| | .btn-brass:disabled { background: var(--bg4); color: var(--t3); cursor: not-allowed; } |
| | |
| | .btn-ghost { |
| | background: transparent; |
| | border: 1px solid var(--border2); |
| | border-radius: 3px; |
| | color: var(--t2); |
| | font-size: 11px; |
| | font-weight: 600; |
| | letter-spacing: .8px; |
| | text-transform: uppercase; |
| | padding: 6px 14px; |
| | cursor: pointer; |
| | transition: all .15s; |
| | } |
| | .btn-ghost:hover { border-color: var(--brass3); color: var(--brass); } |
| | .btn-ghost.on { border-color: var(--brass); color: var(--brass); background: rgba(184,144,42,.1); } |
| | |
| | .label { |
| | font-size: 9px; |
| | font-weight: 700; |
| | letter-spacing: 2.5px; |
| | text-transform: uppercase; |
| | color: var(--brass3); |
| | margin-bottom: 8px; |
| | } |
| | |
| | |
| | #pg-setup { display: block; } |
| | #pg-board { display: none; } |
| | |
| | |
| | .a-strategy { --ac: #D4AE50; --abg: rgba(212,174,80,.1); --abd: rgba(212,174,80,.35); } |
| | .a-finance { --ac: #27AE60; --abg: rgba(39,174,96,.1); --abd: rgba(39,174,96,.35); } |
| | .a-tech { --ac: #2980B9; --abg: rgba(41,128,185,.1); --abd: rgba(41,128,185,.35); } |
| | .a-market { --ac: #E67E22; --abg: rgba(230,126,34,.1); --abd: rgba(230,126,34,.35); } |
| | .a-risk { --ac: #C0392B; --abg: rgba(192,57,43,.1); --abd: rgba(192,57,43,.35); } |
| | .a-moderator{ --ac: #8E44AD; --abg: rgba(142,68,173,.15); --abd: rgba(142,68,173,.5); } |
| | </style> |
| | </head> |
| | <body> |
| |
|
| | |
| | <div id="pg-setup"> |
| | <div style="min-height:100vh; display:flex; flex-direction:column; align-items:center; padding:48px 20px 60px"> |
| |
|
| | |
| | <div style="text-align:center; margin-bottom:44px"> |
| |
|
| | |
| | <div style="margin:0 auto 20px; width:80px; height:80px; position:relative; display:flex; align-items:center; justify-content:center"> |
| | <svg width="80" height="80" viewBox="0 0 80 80"> |
| | <defs> |
| | <radialGradient id="gbg" cx="50%" cy="50%" r="50%"> |
| | <stop offset="0%" stop-color="#2E1E08"/> |
| | <stop offset="100%" stop-color="#0A0705"/> |
| | </radialGradient> |
| | <radialGradient id="gbr" cx="30%" cy="30%" r="70%"> |
| | <stop offset="0%" stop-color="#D4AE50"/> |
| | <stop offset="60%" stop-color="#B8902A"/> |
| | <stop offset="100%" stop-color="#7A5A10"/> |
| | </radialGradient> |
| | </defs> |
| | |
| | <circle cx="40" cy="40" r="38" fill="url(#gbg)" stroke="#B8902A" stroke-width="1.2"/> |
| | <circle cx="40" cy="40" r="35" fill="none" stroke="#3D3020" stroke-width=".5"/> |
| | |
| | <path d="M12 12L18 12M12 12L12 18M68 12L62 12M68 12L68 18M12 68L18 68M12 68L12 62M68 68L62 68M68 68L68 62" |
| | stroke="#B8902A" stroke-width="1.2" stroke-linecap="round" opacity=".6"/> |
| | |
| | <g style="animation:gavel 3s ease-in-out infinite; transform-origin:40px 45px"> |
| | <rect x="22" y="26" width="28" height="14" rx="3" fill="url(#gbr)" transform="rotate(-30 36 33)"/> |
| | <rect x="23" y="27" width="26" height="5" rx="1" fill="rgba(255,255,255,.15)" transform="rotate(-30 36 33)"/> |
| | </g> |
| | |
| | <line x1="48" y1="40" x2="62" y2="62" stroke="#8A6A18" stroke-width="4" stroke-linecap="round"/> |
| | <line x1="49" y1="40" x2="63" y2="62" stroke="rgba(255,255,255,.12)" stroke-width="1.5" stroke-linecap="round"/> |
| | |
| | <ellipse cx="26" cy="58" rx="8" ry="3" fill="#1A1208" stroke="#3D3020" stroke-width="1"/> |
| | <line x1="20" y1="58" x2="34" y2="58" stroke="#3D3020" stroke-width="1"/> |
| | </svg> |
| | </div> |
| |
|
| | <div style="font-family:'Cormorant Garamond',serif; font-size:42px; font-weight:700; letter-spacing:-0.5px; line-height:1; margin-bottom:6px"> |
| | <span class="brass-text">AI Boardroom</span> |
| | </div> |
| | <div style="font-size:11px; font-weight:600; letter-spacing:4px; text-transform:uppercase; color:var(--t3); margin-bottom:14px"> |
| | Multi-Agent Strategic Decision System |
| | </div> |
| | <p style="font-size:14px; color:var(--t2); max-width:500px; margin:0 auto; line-height:1.8; font-style:italic; font-family:'Cormorant Garamond',serif"> |
| | Five expert agents analyze your strategic question.<br> |
| | They debate, challenge each other, then reach a verdict. |
| | </p> |
| | </div> |
| |
|
| | |
| | <div style="display:grid; grid-template-columns:repeat(5,1fr); max-width:780px; width:100%; background:var(--bg2); border:1px solid var(--border); border-radius:4px; overflow:hidden; margin-bottom:36px; position:relative"> |
| | <div style="position:absolute; top:0; left:0; right:0; height:2px; background:linear-gradient(90deg,transparent,var(--brass3),var(--brass),var(--brass3),transparent)"></div> |
| | <div style="padding:16px 14px; border-right:1px solid var(--border)"> |
| | <div class="label">01</div> |
| | <div style="font-size:12px; font-weight:600; margin-bottom:3px">Question</div> |
| | <div style="font-size:11px; color:var(--t3); line-height:1.4">Pose your strategic challenge</div> |
| | </div> |
| | <div style="padding:16px 14px; border-right:1px solid var(--border)"> |
| | <div class="label">02</div> |
| | <div style="font-size:12px; font-weight:600; margin-bottom:3px">Analysis</div> |
| | <div style="font-size:11px; color:var(--t3); line-height:1.4">5 agents form independent views</div> |
| | </div> |
| | <div style="padding:16px 14px; border-right:1px solid var(--border)"> |
| | <div class="label">03</div> |
| | <div style="font-size:12px; font-weight:600; margin-bottom:3px">Debate</div> |
| | <div style="font-size:11px; color:var(--t3); line-height:1.4">Agents challenge each other</div> |
| | </div> |
| | <div style="padding:16px 14px; border-right:1px solid var(--border)"> |
| | <div class="label">04</div> |
| | <div style="font-size:12px; font-weight:600; margin-bottom:3px">Synthesis</div> |
| | <div style="font-size:11px; color:var(--t3); line-height:1.4">Moderator weighs all views</div> |
| | </div> |
| | <div style="padding:16px 14px"> |
| | <div class="label">05</div> |
| | <div style="font-size:12px; font-weight:600; margin-bottom:3px">Verdict</div> |
| | <div style="font-size:11px; color:var(--t3); line-height:1.4">Final recommendation + scenarios</div> |
| | </div> |
| | </div> |
| |
|
| | |
| | <div style="display:grid; grid-template-columns:1fr 1fr; gap:20px; max-width:840px; width:100%; margin-bottom:20px"> |
| |
|
| | |
| | <div class="panel"> |
| | <div class="label">API Configuration</div> |
| | <div style="font-size:11px; color:var(--t3); margin-bottom:18px; line-height:1.5"> |
| | Powered by Claude Sonnet. Your key goes directly to Anthropic β never stored anywhere. |
| | </div> |
| | <div style="margin-bottom:14px"> |
| | <div style="display:flex; justify-content:space-between; margin-bottom:5px"> |
| | <span style="font-size:12px; font-weight:600; color:var(--brass)">Anthropic API Key <span style="font-size:9px; color:var(--brass); font-weight:700">β
REQUIRED</span></span> |
| | <a href="https://console.anthropic.com" target="_blank" rel="noreferrer" style="font-size:10px; color:var(--brass3); text-decoration:none; letter-spacing:.5px">get key β</a> |
| | </div> |
| | <input type="password" id="api-key" class="inp" placeholder="sk-ant-api03-β¦" style="font-family:'Courier Prime',monospace; font-size:12px"/> |
| | <div style="font-size:10px; color:var(--t3); margin-top:4px">Uses Claude Sonnet for all 6 agents</div> |
| | </div> |
| |
|
| | <div style="border-top:1px solid var(--border); padding-top:14px; margin-top:6px"> |
| | <div class="label" style="margin-bottom:10px">Boardroom Configuration</div> |
| | <div style="display:grid; grid-template-columns:1fr 1fr; gap:8px"> |
| | <div> |
| | <div style="font-size:11px; color:var(--t2); margin-bottom:4px">Debate Rounds</div> |
| | <select id="rounds" class="inp" style="font-size:12px; cursor:pointer"> |
| | <option value="1">1 round β quick</option> |
| | <option value="2" selected>2 rounds β balanced</option> |
| | <option value="3">3 rounds β deep</option> |
| | </select> |
| | </div> |
| | <div> |
| | <div style="font-size:11px; color:var(--t2); margin-bottom:4px">Response Depth</div> |
| | <select id="depth" class="inp" style="font-size:12px; cursor:pointer"> |
| | <option value="brief">Brief</option> |
| | <option value="standard" selected>Standard</option> |
| | <option value="detailed">Detailed</option> |
| | </select> |
| | </div> |
| | </div> |
| | </div> |
| | </div> |
| |
|
| | |
| | <div class="panel"> |
| | <div class="label">The Board</div> |
| | <div style="font-size:11px; color:var(--t3); margin-bottom:14px; line-height:1.5"> |
| | Five specialist agents plus one moderator. Each brings a distinct strategic lens. |
| | </div> |
| | <div style="display:grid; gap:7px"> |
| | <div class="a-strategy" style="padding:9px 12px; border-radius:3px; border:1px solid var(--abd); background:var(--abg); display:flex; align-items:center; gap:10px"> |
| | <span style="font-size:16px">π§ </span> |
| | <div><div style="font-size:12px; font-weight:600; color:var(--ac)">Strategy Agent</div><div style="font-size:10px; color:var(--t3)">Long-term competitive advantage & positioning</div></div> |
| | </div> |
| | <div class="a-finance" style="padding:9px 12px; border-radius:3px; border:1px solid var(--abd); background:var(--abg); display:flex; align-items:center; gap:10px"> |
| | <span style="font-size:16px">π°</span> |
| | <div><div style="font-size:12px; font-weight:600; color:var(--ac)">Finance Agent</div><div style="font-size:10px; color:var(--t3)">ROI, capital requirements & financial risk</div></div> |
| | </div> |
| | <div class="a-tech" style="padding:9px 12px; border-radius:3px; border:1px solid var(--abd); background:var(--abg); display:flex; align-items:center; gap:10px"> |
| | <span style="font-size:16px">βοΈ</span> |
| | <div><div style="font-size:12px; font-weight:600; color:var(--ac)">Technology Agent</div><div style="font-size:10px; color:var(--t3)">Technical feasibility & implementation</div></div> |
| | </div> |
| | <div class="a-market" style="padding:9px 12px; border-radius:3px; border:1px solid var(--abd); background:var(--abg); display:flex; align-items:center; gap:10px"> |
| | <span style="font-size:16px">π</span> |
| | <div><div style="font-size:12px; font-weight:600; color:var(--ac)">Market Agent</div><div style="font-size:10px; color:var(--t3)">Demand, competitors & market trends</div></div> |
| | </div> |
| | <div class="a-risk" style="padding:9px 12px; border-radius:3px; border:1px solid var(--abd); background:var(--abg); display:flex; align-items:center; gap:10px"> |
| | <span style="font-size:16px">β οΈ</span> |
| | <div><div style="font-size:12px; font-weight:600; color:var(--ac)">Risk Agent</div><div style="font-size:10px; color:var(--t3)">Regulatory, operational & market risks</div></div> |
| | </div> |
| | <div class="a-moderator" style="padding:9px 12px; border-radius:3px; border:1px solid var(--abd); background:var(--abg); display:flex; align-items:center; gap:10px"> |
| | <span style="font-size:16px">π±</span> |
| | <div><div style="font-size:12px; font-weight:600; color:var(--ac)">Moderator Agent</div><div style="font-size:10px; color:var(--t3)">Synthesizes debate β final verdict</div></div> |
| | </div> |
| | </div> |
| | </div> |
| | </div> |
| |
|
| | |
| | <div style="max-width:840px; width:100%; margin-bottom:20px"> |
| | <div class="panel"> |
| | <div class="label" style="margin-bottom:12px">Example Strategic Questions</div> |
| | <div style="display:flex; gap:8px; flex-wrap:wrap" id="examples"></div> |
| | </div> |
| | </div> |
| |
|
| | <div id="setup-err" style="display:none; max-width:840px; width:100%; padding:12px 16px; background:rgba(192,57,43,.1); border:1px solid rgba(192,57,43,.4); border-radius:3px; font-size:12px; color:#E74C3C; margin-bottom:16px"></div> |
| |
|
| | <button class="btn-brass" onclick="goBoard()" style="font-size:14px; padding:14px 56px; letter-spacing:2px"> |
| | βοΈ CONVENE THE BOARD |
| | </button> |
| |
|
| | </div> |
| | </div> |
| |
|
| | |
| | <div id="pg-board" style="display:none"> |
| |
|
| | |
| | <div style="background:var(--bg2); border-bottom:1px solid var(--border); padding:0 28px; position:sticky; top:0; z-index:100"> |
| | <div style="max-width:1280px; margin:0 auto; display:flex; align-items:center; justify-content:space-between; height:56px"> |
| | <div style="display:flex; align-items:center; gap:14px"> |
| | <svg width="32" height="32" viewBox="0 0 80 80"> |
| | <circle cx="40" cy="40" r="38" fill="url(#gbg)" stroke="#B8902A" stroke-width="1.2"/> |
| | <g style="animation:gavel 3s ease-in-out infinite; transform-origin:40px 45px"> |
| | <rect x="22" y="26" width="28" height="14" rx="3" fill="url(#gbr)" transform="rotate(-30 36 33)"/> |
| | </g> |
| | <line x1="48" y1="40" x2="62" y2="62" stroke="#8A6A18" stroke-width="4" stroke-linecap="round"/> |
| | </svg> |
| | <div> |
| | <div style="font-family:'Cormorant Garamond',serif; font-size:17px; font-weight:700"> |
| | <span class="brass-text">AI Boardroom</span> |
| | </div> |
| | <div id="board-sub" style="font-size:9px; color:var(--t3); letter-spacing:2px; text-transform:uppercase">STRATEGIC DECISION SYSTEM</div> |
| | </div> |
| | </div> |
| | <div style="display:flex; gap:8px"> |
| | <button class="btn-ghost" id="pdf-btn" onclick="doPDF()" style="display:none">β¬ Download Report</button> |
| | <button class="btn-ghost" onclick="goSetup()">β New Session</button> |
| | </div> |
| | </div> |
| | </div> |
| |
|
| | <div style="max-width:1280px; margin:0 auto; padding:28px 28px"> |
| |
|
| | |
| | <div class="panel" style="margin-bottom:24px"> |
| | <div class="label" style="margin-bottom:10px">Strategic Question</div> |
| | <textarea id="question-box" class="inp" rows="2" style="resize:vertical; font-family:'Cormorant Garamond',serif; font-size:16px; line-height:1.6; font-style:italic" |
| | placeholder="State the strategic question for the boardβ¦"></textarea> |
| | <div style="display:flex; align-items:center; justify-content:space-between; margin-top:14px; flex-wrap:wrap; gap:10px"> |
| | <div id="agent-status-row" style="display:flex; gap:8px; flex-wrap:wrap"></div> |
| | <button class="btn-brass" id="run-btn" onclick="runBoard()" style="letter-spacing:1.5px"> |
| | βοΈ CONVENE |
| | </button> |
| | </div> |
| | </div> |
| |
|
| | |
| | <div id="results-area" style="display:none"> |
| |
|
| | |
| | <div style="display:flex; gap:6px; margin-bottom:20px"> |
| | <button class="btn-ghost on" onclick="switchTab('debate',this)">π£ Boardroom Debate</button> |
| | <button class="btn-ghost" onclick="switchTab('votes',this)">π³ Agent Votes</button> |
| | <button class="btn-ghost" onclick="switchTab('scenarios',this)">π Scenarios</button> |
| | <button class="btn-ghost" onclick="switchTab('verdict',this)">βοΈ Final Verdict</button> |
| | </div> |
| |
|
| | <div id="tab-debate"></div> |
| | <div id="tab-votes" style="display:none"></div> |
| | <div id="tab-scenarios" style="display:none"></div> |
| | <div id="tab-verdict" style="display:none"></div> |
| | </div> |
| | </div> |
| |
|
| | <div style="border-top:1px solid var(--border); padding:14px 28px; display:flex; justify-content:space-between; margin-top:32px; background:var(--bg2)"> |
| | <span style="font-size:11px; color:var(--t3); letter-spacing:.5px">βοΈ AI Boardroom v1.0 Β· Multi-Agent Strategic Decision System</span> |
| | <span style="font-size:11px; color:var(--border2)">Powered by Claude Sonnet Β· Keys stay local</span> |
| | </div> |
| | </div> |
| |
|
| | <script> |
| | |
| | var AGENTS = [ |
| | { |
| | id: 'strategy', name: 'Strategy Agent', emoji: 'π§ ', |
| | cls: 'a-strategy', color: '#D4AE50', |
| | role: 'You are the Strategy Agent in a high-level executive boardroom. You focus exclusively on long-term competitive advantage, market positioning, strategic differentiation, and sustainable business models. You are confident, visionary, and think in 5-10 year horizons. You cite strategic frameworks when relevant (Porter, Blue Ocean, etc.). Keep your response focused and sharp.', |
| | }, |
| | { |
| | id: 'finance', name: 'Finance Agent', emoji: 'π°', |
| | cls: 'a-finance', color: '#27AE60', |
| | role: 'You are the Finance Agent in a high-level executive boardroom. You focus exclusively on financial viability: ROI, unit economics, capital requirements, cash flow, valuation, and financial risk. You think in numbers and ranges. You are pragmatic and skeptical of projections without evidence. Keep your response focused and sharp.', |
| | }, |
| | { |
| | id: 'tech', name: 'Technology Agent', emoji: 'βοΈ', |
| | cls: 'a-tech', color: '#2980B9', |
| | role: 'You are the Technology Agent in a high-level executive boardroom. You focus exclusively on technical feasibility, build-vs-buy decisions, tech stack complexity, scalability, talent requirements, and implementation timeline. You are precise and realistic about what technology can and cannot do. Keep your response focused and sharp.', |
| | }, |
| | { |
| | id: 'market', name: 'Market Agent', emoji: 'π', |
| | cls: 'a-market', color: '#E67E22', |
| | role: 'You are the Market Agent in a high-level executive boardroom. You focus exclusively on market size, customer demand, competitive landscape, go-to-market strategy, and emerging trends. You think about who the customer is, why they would buy, and what the competition looks like. Keep your response focused and sharp.', |
| | }, |
| | { |
| | id: 'risk', name: 'Risk Agent', emoji: 'β οΈ', |
| | cls: 'a-risk', color: '#C0392B', |
| | role: 'You are the Risk Agent in a high-level executive boardroom. You focus exclusively on identifying and quantifying risks: regulatory, operational, reputational, market, and execution risks. You are not there to block decisions β you are there to ensure risks are acknowledged and mitigated. Keep your response focused and sharp.', |
| | }, |
| | ]; |
| | |
| | var MODERATOR = { |
| | id: 'moderator', name: 'Moderator', emoji: 'π±', |
| | cls: 'a-moderator', color: '#8E44AD', |
| | role: 'You are the Moderator of a high-level AI executive boardroom. You have heard all agent analyses and debates. Your job is to synthesize the discussion into a clear, decisive recommendation. You must: 1) Acknowledge the strongest points from each agent, 2) Identify the key tensions and how to resolve them, 3) Give a clear YES/NO/CONDITIONAL recommendation with justification, 4) Provide a confidence score 0-100, 5) Give 3 key action items if proceeding. Be decisive β boards need verdicts, not more questions.', |
| | }; |
| | |
| | var EXAMPLES = [ |
| | 'Should a fintech startup focus on women\'s wealth management in India?', |
| | 'Should we enter the UAE market in 2025?', |
| | 'Should a startup invest in AI infrastructure or AI applications?', |
| | 'Should we acquire a competitor or build the capability in-house?', |
| | 'Should we launch a B2C product or stay B2B-only?', |
| | 'Is now the right time to raise a Series A?', |
| | 'Should we expand to Southeast Asia before consolidating our home market?', |
| | ]; |
| | |
| | |
| | var apiKey = ''; |
| | var rounds = 2; |
| | var depth = 'standard'; |
| | var sessionData = { question:'', analyses:{}, debates:[], verdict:null }; |
| | |
| | |
| | window.onload = function() { |
| | buildExamples(); |
| | }; |
| | |
| | function buildExamples() { |
| | var el = document.getElementById('examples'); |
| | if (!el) return; |
| | el.innerHTML = EXAMPLES.map(function(q, i) { |
| | return '<button onclick="setExample(' + i + ',this)" style="padding:5px 12px; border-radius:20px; border:1px solid var(--border2); background:transparent; color:var(--t2); font-size:11px; cursor:pointer; font-family:Raleway,sans-serif; line-height:1.4; text-align:left; transition:all .15s" onmouseover="this.style.borderColor=\'var(--brass3)\';this.style.color=\'var(--brass)\'" onmouseout="if(!this._on){this.style.borderColor=\'var(--border2)\';this.style.color=\'var(--t2)\'}">' + q + '</button>'; |
| | }).join(''); |
| | } |
| | |
| | function setExample(i, btn) { |
| | document.querySelectorAll('#examples button').forEach(function(b) { |
| | b._on = false; b.style.borderColor = 'var(--border2)'; b.style.color = 'var(--t2)'; |
| | }); |
| | btn._on = true; btn.style.borderColor = 'var(--brass)'; btn.style.color = 'var(--brass)'; |
| | document.getElementById('question-box').value = EXAMPLES[i]; |
| | } |
| | |
| | |
| | function goBoard() { |
| | var key = document.getElementById('api-key').value.trim(); |
| | var err = document.getElementById('setup-err'); |
| | if (!key.startsWith('sk-ant-')) { |
| | err.textContent = 'β οΈ Anthropic API key required β must start with sk-ant-'; |
| | err.style.display = 'block'; return; |
| | } |
| | err.style.display = 'none'; |
| | apiKey = key; |
| | rounds = parseInt(document.getElementById('rounds').value); |
| | depth = document.getElementById('depth').value; |
| | |
| | buildAgentStatusRow(); |
| | document.getElementById('pg-setup').style.display = 'none'; |
| | document.getElementById('pg-board').style.display = 'block'; |
| | document.getElementById('results-area').style.display = 'none'; |
| | document.getElementById('pdf-btn').style.display = 'none'; |
| | sessionData = { question:'', analyses:{}, debates:[], verdict:null }; |
| | } |
| | |
| | function goSetup() { |
| | document.getElementById('pg-board').style.display = 'none'; |
| | document.getElementById('pg-setup').style.display = 'block'; |
| | } |
| | |
| | function buildAgentStatusRow() { |
| | var all = AGENTS.concat([MODERATOR]); |
| | document.getElementById('agent-status-row').innerHTML = all.map(function(a) { |
| | return '<div class="' + a.cls + '" style="display:flex; align-items:center; gap:5px; padding:3px 10px; border-radius:20px; border:1px solid var(--abd); background:var(--abg)">' + |
| | '<span style="font-size:10px">' + a.emoji + '</span>' + |
| | '<span style="font-size:11px; font-weight:600; color:var(--ac)">' + a.name.split(' ')[0] + '</span>' + |
| | '<span id="ast-' + a.id + '" style="font-size:10px"></span>' + |
| | '</div>'; |
| | }).join(''); |
| | } |
| | |
| | function setASt(id, st) { |
| | var el = document.getElementById('ast-' + id); |
| | if (!el) return; |
| | var map = { |
| | idle: '', |
| | thinking: '<span style="color:#3B82F6; animation:pulse 1s ease-in-out infinite"> thinkingβ¦</span>', |
| | debating: '<span style="color:var(--brass); animation:pulse 1s ease-in-out infinite"> debatingβ¦</span>', |
| | done: '<span style="color:var(--green)"> β</span>', |
| | error: '<span style="color:var(--red)"> β</span>', |
| | }; |
| | el.innerHTML = map[st] || ''; |
| | } |
| | |
| | function switchTab(name, btn) { |
| | ['debate','votes','scenarios','verdict'].forEach(function(t) { |
| | document.getElementById('tab-' + t).style.display = t === name ? 'block' : 'none'; |
| | }); |
| | document.querySelectorAll('#pg-board .btn-ghost').forEach(function(b) { b.classList.remove('on'); }); |
| | btn.classList.add('on'); |
| | } |
| | |
| | |
| | async function callClaude(prompt, systemPrompt, maxTokens) { |
| | maxTokens = maxTokens || 600; |
| | var r = await fetch('https://api.anthropic.com/v1/messages', { |
| | method: 'POST', |
| | headers: { |
| | 'Content-Type': 'application/json', |
| | 'x-api-key': apiKey, |
| | 'anthropic-version': '2023-06-01', |
| | 'anthropic-dangerous-direct-browser-access': 'true' |
| | }, |
| | body: JSON.stringify({ |
| | model: 'claude-sonnet-4-20250514', |
| | max_tokens: maxTokens, |
| | system: systemPrompt, |
| | messages: [{ role: 'user', content: prompt }] |
| | }) |
| | }); |
| | if (!r.ok) { |
| | var e = await r.json().catch(function() { return {}; }); |
| | throw new Error((e.error && e.error.message) || 'API error ' + r.status); |
| | } |
| | var d = await r.json(); |
| | return (d.content && d.content[0] && d.content[0].text) || ''; |
| | } |
| | |
| | |
| | async function runBoard() { |
| | var question = document.getElementById('question-box').value.trim(); |
| | if (!question) return; |
| | sessionData.question = question; |
| | sessionData.analyses = {}; |
| | sessionData.debates = []; |
| | sessionData.verdict = null; |
| | |
| | var btn = document.getElementById('run-btn'); |
| | btn.disabled = true; btn.textContent = 'β³ In sessionβ¦'; |
| | document.getElementById('results-area').style.display = 'none'; |
| | AGENTS.forEach(function(a) { setASt(a.id, 'idle'); }); |
| | setASt('moderator', 'idle'); |
| | |
| | var depthInstr = depth === 'brief' ? 'Be concise β 3-4 sentences max per point.' : |
| | depth === 'detailed' ? 'Be thorough β provide detailed reasoning with specific examples and data where possible.' : |
| | 'Be clear and substantive β 2-3 paragraphs.'; |
| | |
| | |
| | renderProgress('Phase 1 of 3: Independent Analysis', 'Each agent forms their independent viewβ¦'); |
| | AGENTS.forEach(function(a) { setASt(a.id, 'thinking'); }); |
| | |
| | var analysisCalls = AGENTS.map(function(a) { |
| | var prompt = 'STRATEGIC QUESTION:\n' + question + '\n\nProvide your independent expert analysis from your specific perspective. ' + depthInstr + '\n\nStructure your response as:\n**Your Position:** (1 clear sentence)\n**Key Points:** (3 bullet points)\n**Confidence:** X% (your confidence this is the right direction)'; |
| | return callClaude(prompt, a.role, depth === 'detailed' ? 800 : depth === 'brief' ? 300 : 500) |
| | .then(function(text) { sessionData.analyses[a.id] = text; setASt(a.id, 'done'); return { id: a.id, text: text }; }) |
| | .catch(function(e) { setASt(a.id, 'error'); return { id: a.id, text: 'β οΈ ' + e.message, error: true }; }); |
| | }); |
| | await Promise.all(analysisCalls); |
| | |
| | |
| | for (var round = 1; round <= rounds; round++) { |
| | renderProgress('Phase 2 of 3: Debate Round ' + round + ' of ' + rounds, 'Agents challenge and respond to each otherβ¦'); |
| | |
| | var allAnalyses = AGENTS.map(function(a) { |
| | return a.emoji + ' ' + a.name + ':\n' + (sessionData.analyses[a.id] || 'No analysis available.'); |
| | }).join('\n\n---\n\n'); |
| | |
| | var debateRound = []; |
| | for (var i = 0; i < AGENTS.length; i++) { |
| | var agent = AGENTS[i]; |
| | setASt(agent.id, 'debating'); |
| | var otherAgents = AGENTS.filter(function(a) { return a.id !== agent.id; }); |
| | var challengePrompt = 'STRATEGIC QUESTION:\n' + question + '\n\n' + |
| | 'ALL BOARD MEMBERS HAVE SPOKEN:\n\n' + allAnalyses + '\n\n' + |
| | 'Round ' + round + ' of debate. From your perspective as ' + agent.name + ':\n' + |
| | '1. Challenge the weakest argument made by another agent (name them)\n' + |
| | '2. Defend or refine your own position based on what you heard\n' + |
| | '3. Identify one point of agreement with another agent\n\n' + |
| | depthInstr; |
| | try { |
| | var debateText = await callClaude(challengePrompt, agent.role, 500); |
| | debateRound.push({ agent: agent, text: debateText, round: round }); |
| | setASt(agent.id, 'done'); |
| | } catch(e) { |
| | debateRound.push({ agent: agent, text: 'β οΈ ' + e.message, round: round, error: true }); |
| | setASt(agent.id, 'error'); |
| | } |
| | } |
| | sessionData.debates.push(debateRound); |
| | } |
| | |
| | |
| | renderProgress('Phase 3 of 3: Moderator Synthesis', 'Weighing all arguments and forming final verdictβ¦'); |
| | setASt('moderator', 'thinking'); |
| | |
| | var fullTranscript = 'STRATEGIC QUESTION:\n' + question + '\n\n'; |
| | fullTranscript += '=== INDEPENDENT ANALYSES ===\n\n'; |
| | AGENTS.forEach(function(a) { |
| | fullTranscript += a.emoji + ' ' + a.name.toUpperCase() + ':\n' + (sessionData.analyses[a.id] || '') + '\n\n'; |
| | }); |
| | sessionData.debates.forEach(function(round, ri) { |
| | fullTranscript += '=== DEBATE ROUND ' + (ri+1) + ' ===\n\n'; |
| | round.forEach(function(d) { |
| | fullTranscript += d.agent.emoji + ' ' + d.agent.name.toUpperCase() + ':\n' + d.text + '\n\n'; |
| | }); |
| | }); |
| | fullTranscript += '\nNow synthesize everything above into a final boardroom verdict. Structure your response as:\n\n**VERDICT:** [PROCEED / DO NOT PROCEED / PROCEED WITH CONDITIONS]\n\n**Confidence Score:** X/100\n\n**Rationale:** (2-3 paragraphs synthesizing the key arguments)\n\n**Key Tensions Resolved:** (how you resolved the main disagreements)\n\n**Action Items (if proceeding):**\n1. ...\n2. ...\n3. ...\n\n**3 Scenarios to Model:**\n- Optimistic: ...\n- Base Case: ...\n- Downside: ...\n\n**Agent Vote Summary:** (list each agent\'s implied vote: PROCEED/AGAINST/CONDITIONAL and confidence %)'; |
| | |
| | try { |
| | var verdictText = await callClaude(fullTranscript, MODERATOR.role, 1000); |
| | sessionData.verdict = verdictText; |
| | setASt('moderator', 'done'); |
| | } catch(e) { |
| | sessionData.verdict = 'β οΈ Moderator error: ' + e.message; |
| | setASt('moderator', 'error'); |
| | } |
| | |
| | renderAll(); |
| | btn.disabled = false; btn.textContent = 'βοΈ RECONVENE'; |
| | document.getElementById('pdf-btn').style.display = 'inline-block'; |
| | } |
| | |
| | |
| | function renderProgress(phase, detail) { |
| | document.getElementById('results-area').style.display = 'block'; |
| | document.getElementById('tab-debate').innerHTML = |
| | '<div class="panel" style="text-align:center; padding:40px">' + |
| | '<div style="font-size:11px; font-weight:700; letter-spacing:2px; text-transform:uppercase; color:var(--brass); margin-bottom:8px">' + phase + '</div>' + |
| | '<div style="font-size:14px; color:var(--t2); font-family:Cormorant Garamond,serif; font-style:italic">' + detail + '</div>' + |
| | '<div style="margin-top:20px; display:flex; justify-content:center; gap:6px">' + |
| | '<div style="width:6px;height:6px;border-radius:50%;background:var(--brass);animation:pulse .6s ease-in-out infinite"></div>' + |
| | '<div style="width:6px;height:6px;border-radius:50%;background:var(--brass);animation:pulse .6s ease-in-out infinite .2s"></div>' + |
| | '<div style="width:6px;height:6px;border-radius:50%;background:var(--brass);animation:pulse .6s ease-in-out infinite .4s"></div>' + |
| | '</div></div>'; |
| | } |
| | |
| | function agentCard(agent, text, subtitle) { |
| | return '<div class="' + agent.cls + '" style="border:1px solid var(--abd); border-radius:4px; overflow:hidden; margin-bottom:14px; animation:slideIn .4s ease">' + |
| | '<div style="padding:10px 16px; background:var(--abg); border-bottom:1px solid var(--abd); display:flex; align-items:center; gap:10px">' + |
| | '<span style="font-size:18px">' + agent.emoji + '</span>' + |
| | '<div>' + |
| | '<div style="font-size:13px; font-weight:700; color:var(--ac); font-family:Cormorant Garamond,serif">' + agent.name + '</div>' + |
| | (subtitle ? '<div style="font-size:10px; color:var(--t3); letter-spacing:.5px">' + subtitle + '</div>' : '') + |
| | '</div>' + |
| | '</div>' + |
| | '<div style="padding:16px; font-size:13px; color:var(--t2); line-height:1.8; white-space:pre-wrap; font-family:Raleway,sans-serif">' + esc(text) + '</div>' + |
| | '</div>'; |
| | } |
| | |
| | function renderAll() { |
| | renderDebate(); |
| | renderVotes(); |
| | renderScenarios(); |
| | renderVerdict(); |
| | document.getElementById('results-area').style.display = 'block'; |
| | |
| | switchTab('debate', document.querySelector('#pg-board .btn-ghost')); |
| | } |
| | |
| | function renderDebate() { |
| | var html = ''; |
| | |
| | |
| | html += '<div style="font-family:Cormorant Garamond,serif; font-size:20px; font-weight:700; color:var(--brass); margin-bottom:16px; padding-bottom:10px; border-bottom:1px solid var(--border)">Phase I β Independent Analysis</div>'; |
| | AGENTS.forEach(function(a) { |
| | html += agentCard(a, sessionData.analyses[a.id] || 'No response.', 'Independent analysis'); |
| | }); |
| | |
| | |
| | sessionData.debates.forEach(function(round, ri) { |
| | html += '<div style="font-family:Cormorant Garamond,serif; font-size:20px; font-weight:700; color:var(--brass); margin:24px 0 16px; padding-bottom:10px; border-bottom:1px solid var(--border)">Phase II β Debate Round ' + (ri+1) + '</div>'; |
| | round.forEach(function(d) { |
| | html += agentCard(d.agent, d.text, 'Round ' + (ri+1) + ' response'); |
| | }); |
| | }); |
| | |
| | document.getElementById('tab-debate').innerHTML = html; |
| | } |
| | |
| | function renderVotes() { |
| | |
| | var votes = AGENTS.map(function(a) { |
| | var text = sessionData.analyses[a.id] || ''; |
| | |
| | var match = text.match(/(\d+)%/); |
| | var conf = match ? parseInt(match[1]) : 50; |
| | |
| | var lower = text.toLowerCase(); |
| | var vote = lower.includes('not recommend') || lower.includes('advise against') || lower.includes('do not') ? 'AGAINST' |
| | : lower.includes('conditional') || lower.includes('depends') || lower.includes('if ') ? 'CONDITIONAL' |
| | : 'PROCEED'; |
| | return { agent: a, confidence: conf, vote: vote }; |
| | }); |
| | |
| | var voteColors = { PROCEED: 'var(--green)', AGAINST: 'var(--red)', CONDITIONAL: 'var(--amber)' }; |
| | var proceed = votes.filter(function(v) { return v.vote === 'PROCEED'; }).length; |
| | var against = votes.filter(function(v) { return v.vote === 'AGAINST'; }).length; |
| | var cond = votes.filter(function(v) { return v.vote === 'CONDITIONAL'; }).length; |
| | var avgConf = Math.round(votes.reduce(function(s,v){return s+v.confidence;},0)/votes.length); |
| | |
| | var html = '<div style="display:grid; grid-template-columns:1fr 1fr; gap:20px; margin-bottom:24px">'; |
| | |
| | |
| | html += '<div class="panel">'; |
| | html += '<div class="label" style="margin-bottom:14px">Vote Tally</div>'; |
| | html += '<div style="display:grid; grid-template-columns:1fr 1fr 1fr; gap:10px; margin-bottom:18px">'; |
| | [['PROCEED',proceed,'var(--green)'],['CONDITIONAL',cond,'var(--amber)'],['AGAINST',against,'var(--red)']].forEach(function(x) { |
| | html += '<div style="text-align:center; padding:14px; background:var(--bg3); border-radius:3px; border:1px solid ' + x[2] + '44">' + |
| | '<div style="font-size:28px; font-weight:800; color:' + x[2] + '; line-height:1">' + x[1] + '</div>' + |
| | '<div style="font-size:9px; font-weight:700; color:' + x[2] + '; letter-spacing:1.5px; text-transform:uppercase; margin-top:3px">' + x[0] + '</div>' + |
| | '</div>'; |
| | }); |
| | html += '</div>'; |
| | html += '<div style="text-align:center; padding:14px; background:var(--bg3); border-radius:3px; border:1px solid var(--border)">' + |
| | '<div style="font-size:11px; color:var(--t3); letter-spacing:1px; text-transform:uppercase; margin-bottom:4px">Board Confidence</div>' + |
| | '<div style="font-size:36px; font-weight:800; color:var(--brass); font-family:Cormorant Garamond,serif">' + avgConf + '<span style="font-size:18px">%</span></div>' + |
| | '</div>'; |
| | html += '</div>'; |
| | |
| | |
| | html += '<div class="panel">'; |
| | html += '<div class="label" style="margin-bottom:14px">Individual Positions</div>'; |
| | html += '<div style="display:grid; gap:8px">'; |
| | votes.forEach(function(v) { |
| | var vc = voteColors[v.vote]; |
| | html += '<div class="' + v.agent.cls + '" style="display:flex; align-items:center; gap:10px; padding:10px 12px; border-radius:3px; border:1px solid var(--abd); background:var(--abg)">' + |
| | '<span style="font-size:16px">' + v.agent.emoji + '</span>' + |
| | '<div style="flex:1"><div style="font-size:12px; font-weight:600; color:var(--ac)">' + v.agent.name + '</div></div>' + |
| | '<div style="text-align:right">' + |
| | '<span style="font-size:11px; font-weight:700; color:' + vc + '; padding:2px 8px; border-radius:3px; border:1px solid ' + vc + '44; background:' + vc + '15">' + v.vote + '</span>' + |
| | '<div style="font-size:10px; color:var(--t3); margin-top:2px">' + v.confidence + '% confident</div>' + |
| | '</div>' + |
| | '</div>'; |
| | }); |
| | html += '</div></div></div>'; |
| | |
| | |
| | html += '<div class="panel">'; |
| | html += '<div class="label" style="margin-bottom:16px">Confidence by Agent</div>'; |
| | html += '<div style="display:grid; gap:10px">'; |
| | votes.forEach(function(v) { |
| | var vc = voteColors[v.vote]; |
| | html += '<div style="display:flex; align-items:center; gap:12px">' + |
| | '<span style="font-size:14px; width:24px">' + v.agent.emoji + '</span>' + |
| | '<div style="width:130px; font-size:12px; font-weight:600; color:var(--t2)">' + v.agent.name.replace(' Agent','') + '</div>' + |
| | '<div style="flex:1; height:8px; background:var(--bg4); border-radius:4px; overflow:hidden">' + |
| | '<div style="height:100%; width:' + v.confidence + '%; background:' + vc + '; border-radius:4px; transition:width .8s ease"></div>' + |
| | '</div>' + |
| | '<div style="font-size:12px; font-weight:700; color:' + vc + '; min-width:36px; text-align:right">' + v.confidence + '%</div>' + |
| | '</div>'; |
| | }); |
| | html += '</div></div>'; |
| | |
| | document.getElementById('tab-votes').innerHTML = html; |
| | } |
| | |
| | function renderScenarios() { |
| | |
| | var verdict = sessionData.verdict || ''; |
| | var scenarioSection = verdict.match(/3 Scenarios[\s\S]*?(?=\n\n[A-Z*]|$)/i); |
| | var scenarioText = scenarioSection ? scenarioSection[0] : ''; |
| | |
| | var scenarios = [ |
| | { name: 'Optimistic', icon: 'π', color: 'var(--green)', desc: 'Best-case market conditions align.' }, |
| | { name: 'Base Case', icon: 'βοΈ', color: 'var(--brass)', desc: 'Moderate progress with expected friction.' }, |
| | { name: 'Downside', icon: 'β', color: 'var(--red)', desc: 'Headwinds, slower adoption, capital pressure.' }, |
| | ]; |
| | |
| | |
| | var optMatch = scenarioText.match(/Optimistic[:\s]+([^\n-]+)/i); |
| | var baseMatch = scenarioText.match(/Base Case[:\s]+([^\n-]+)/i); |
| | var downMatch = scenarioText.match(/Downside[:\s]+([^\n-]+)/i); |
| | if (optMatch) scenarios[0].desc = optMatch[1].trim(); |
| | if (baseMatch) scenarios[1].desc = baseMatch[1].trim(); |
| | if (downMatch) scenarios[2].desc = downMatch[1].trim(); |
| | |
| | var html = '<div style="display:grid; grid-template-columns:repeat(3,1fr); gap:16px; margin-bottom:24px">'; |
| | scenarios.forEach(function(sc) { |
| | html += '<div class="panel" style="border-color:' + sc.color + '44">' + |
| | '<div style="font-size:28px; margin-bottom:10px">' + sc.icon + '</div>' + |
| | '<div style="font-size:14px; font-weight:700; color:' + sc.color + '; font-family:Cormorant Garamond,serif; margin-bottom:8px">' + sc.name + '</div>' + |
| | '<div style="font-size:13px; color:var(--t2); line-height:1.7; font-style:italic">' + esc(sc.desc) + '</div>' + |
| | '</div>'; |
| | }); |
| | html += '</div>'; |
| | |
| | |
| | html += '<div class="panel">'; |
| | html += '<div class="label" style="margin-bottom:16px">Risk Γ Opportunity Radar</div>'; |
| | var W=560, H=300, cx=W/2, cy=H/2, R=110; |
| | var dims = ['Market Size','Execution Risk','Capital Need','Competition','Regulatory','Team Fit']; |
| | var n = dims.length; |
| | var angs = dims.map(function(_,i){return(i/n)*Math.PI*2-Math.PI/2;}); |
| | function pt(v,i){return[cx+(v/100)*R*Math.cos(angs[i]),cy+(v/100)*R*Math.sin(angs[i])];} |
| | |
| | |
| | var allText = Object.values(sessionData.analyses).join(' ').toLowerCase(); |
| | var vals = [ |
| | allText.includes('large market') || allText.includes('significant') ? 75 : 55, |
| | allText.includes('high risk') || allText.includes('significant risk') ? 70 : 45, |
| | allText.includes('capital') || allText.includes('investment') ? 65 : 40, |
| | allText.includes('competitive') || allText.includes('competitors') ? 60 : 35, |
| | allText.includes('regulat') ? 65 : 30, |
| | allText.includes('team') || allText.includes('talent') ? 55 : 50, |
| | ]; |
| | |
| | var grid = [25,50,75,100].map(function(p){var pts=dims.map(function(_,i){return pt(p,i).join(',');}).join(' ');return'<polygon points="'+pts+'" fill="none" stroke="var(--border2)" stroke-width="1"/>';}).join(''); |
| | var axes = dims.map(function(_,i){var p=pt(100,i);return'<line x1="'+cx+'" y1="'+cy+'" x2="'+p[0]+'" y2="'+p[1]+'" stroke="var(--border2)" stroke-width="1"/>';}).join(''); |
| | var labels = dims.map(function(d,i){var p=pt(125,i);var a=p[0]<cx-5?'end':p[0]>cx+5?'start':'middle';return'<text x="'+p[0]+'" y="'+p[1]+'" fill="var(--t2)" font-size="10" text-anchor="'+a+'" dominant-baseline="middle" font-family="Raleway,sans-serif">'+d+'</text>';}).join(''); |
| | var poly = '<polygon points="'+dims.map(function(_,i){return pt(vals[i],i).join(',');}).join(' ')+'" fill="rgba(184,144,42,.12)" stroke="var(--brass)" stroke-width="2"/>'; |
| | |
| | html += '<div style="overflow-x:auto"><svg width="'+W+'" height="'+H+'" viewBox="0 0 '+W+' '+H+'" style="display:block;max-width:100%;margin:0 auto">'+grid+axes+poly+labels+'</svg></div>'; |
| | html += '</div>'; |
| | document.getElementById('tab-scenarios').innerHTML = html; |
| | } |
| | |
| | function renderVerdict() { |
| | var text = sessionData.verdict || 'No verdict generated.'; |
| | var verdictLine = text.match(/\*\*VERDICT\*\*[:\s]*([^\n]+)/i); |
| | var confLine = text.match(/Confidence Score[:\s]*(\d+)/i); |
| | var verdictWord = verdictLine ? verdictLine[1].trim() : 'UNDETERMINED'; |
| | var conf = confLine ? parseInt(confLine[1]) : 50; |
| | |
| | var vcolor = verdictWord.includes('NOT') || verdictWord.includes('DO NOT') ? 'var(--red)' |
| | : verdictWord.includes('CONDITION') ? 'var(--amber)' |
| | : 'var(--green)'; |
| | |
| | var html = ''; |
| | |
| | |
| | html += '<div class="a-moderator" style="border:1px solid var(--abd); border-radius:4px; overflow:hidden; margin-bottom:20px">'; |
| | html += '<div style="padding:12px 20px; background:var(--abg); border-bottom:1px solid var(--abd); display:flex; align-items:center; gap:12px">' + |
| | '<span style="font-size:20px">π±</span>' + |
| | '<div style="font-family:Cormorant Garamond,serif; font-size:16px; font-weight:700; color:var(--ac)">Moderator β Final Boardroom Verdict</div>' + |
| | '</div>'; |
| | |
| | |
| | html += '<div style="padding:24px; display:grid; grid-template-columns:1fr auto; gap:20px; align-items:center; border-bottom:1px solid var(--border)">'; |
| | html += '<div>'; |
| | html += '<div style="font-size:10px; font-weight:700; letter-spacing:2px; text-transform:uppercase; color:var(--t3); margin-bottom:8px">Board Verdict</div>'; |
| | html += '<div style="font-family:Cormorant Garamond,serif; font-size:32px; font-weight:700; color:' + vcolor + '; line-height:1">' + verdictWord + '</div>'; |
| | html += '</div>'; |
| | html += '<div style="text-align:center; padding:16px 24px; background:var(--bg3); border-radius:3px; border:1px solid var(--border)">'; |
| | html += '<div style="font-size:10px; color:var(--t3); letter-spacing:1px; text-transform:uppercase; margin-bottom:4px">Confidence</div>'; |
| | html += '<div style="font-size:40px; font-weight:800; color:var(--brass); font-family:Cormorant Garamond,serif; line-height:1">' + conf + '<span style="font-size:20px">%</span></div>'; |
| | html += '</div>'; |
| | html += '</div>'; |
| | |
| | |
| | html += '<div style="padding:20px; font-size:13px; color:var(--t2); line-height:1.9; white-space:pre-wrap; font-family:Raleway,sans-serif">' + esc(text) + '</div>'; |
| | html += '</div>'; |
| | |
| | document.getElementById('tab-verdict').innerHTML = html; |
| | } |
| | |
| | |
| | function esc(s) { |
| | return (s || '').replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>'); |
| | } |
| | |
| | |
| | function doPDF() { |
| | var q = sessionData.question; |
| | var ts = new Date().toLocaleString('en-GB', { dateStyle:'long', timeStyle:'short' }); |
| | |
| | var agentSections = AGENTS.map(function(a) { |
| | return '<div style="margin-bottom:20px;border:1px solid #E5E7EB;border-radius:6px;overflow:hidden;page-break-inside:avoid">' + |
| | '<div style="background:#F9FAFB;padding:10px 14px;border-bottom:1px solid #E5E7EB;display:flex;align-items:center;gap:8px">' + |
| | '<span style="font-size:16px">' + a.emoji + '</span>' + |
| | '<strong style="font-size:13px">' + a.name + '</strong>' + |
| | '</div>' + |
| | '<div style="padding:14px;font-size:12px;line-height:1.7;white-space:pre-wrap;color:#374151">' + (sessionData.analyses[a.id] || '') + '</div>' + |
| | '</div>'; |
| | }).join(''); |
| | |
| | var style = '@page{size:A4;margin:15mm}*{box-sizing:border-box;margin:0;padding:0}body{font-family:Georgia,serif;color:#111;font-size:12px;line-height:1.6}@media screen{body{max-width:860px;margin:0 auto;padding:24px}}.savebtn{display:block;width:100%;padding:14px;background:#1a1208;color:#D4AE50;border:none;border-radius:6px;font-size:14px;font-weight:700;cursor:pointer;margin-bottom:24px;text-align:center;letter-spacing:1px}@media print{.savebtn{display:none}}.hdr{border-bottom:3px solid #1a1208;padding-bottom:14px;margin-bottom:20px}.h1{font-size:24px;font-weight:800;color:#1a1208}.sub{font-size:10px;color:#6B7280;text-transform:uppercase;letter-spacing:2px;margin-top:4px}.qbox{background:#F9F5EC;border-left:4px solid #B8902A;padding:12px 16px;margin:16px 0;font-size:14px;font-style:italic;color:#374151}h2{font-size:13px;font-weight:700;margin:20px 0 10px;padding-bottom:6px;border-bottom:1px solid #E5E7EB;text-transform:uppercase;letter-spacing:1px;color:#6B7280}section{margin-bottom:20px}.verdict-box{background:#F9F5EC;border:2px solid #B8902A;border-radius:6px;padding:16px;margin-bottom:20px}.ftr{margin-top:20px;padding-top:10px;border-top:1px solid #E5E7EB;display:flex;justify-content:space-between;font-size:10px;color:#9CA3AF}'; |
| | |
| | var html = '<!DOCTYPE html><html><head><meta charset="UTF-8"><title>AI Boardroom Report</title><style>' + style + '</style></head><body>' + |
| | '<button class="savebtn" onclick="window.print()">β¬ Click to Save as PDF β set Destination to "Save as PDF" in print dialog</button>' + |
| | '<div class="hdr"><div class="h1">βοΈ AI Boardroom β Strategic Decision Report</div><div class="sub">Multi-Agent Analysis Β· ' + ts + '</div></div>' + |
| | '<div class="qbox"><strong>Strategic Question:</strong> ' + esc(q) + '</div>' + |
| | '<section><h2>Independent Agent Analyses</h2>' + agentSections + '</section>' + |
| | (sessionData.debates.length ? '<section><h2>Board Debate</h2>' + |
| | sessionData.debates.map(function(round, ri) { |
| | return '<div style="margin-bottom:12px"><strong>Round ' + (ri+1) + '</strong></div>' + |
| | round.map(function(d) { |
| | return '<div style="margin-bottom:14px;padding:10px 14px;border-left:3px solid #E5E7EB;font-size:12px;line-height:1.7;color:#374151">' + |
| | '<div style="font-weight:700;margin-bottom:4px">' + d.agent.emoji + ' ' + d.agent.name + '</div>' + |
| | esc(d.text) + '</div>'; |
| | }).join(''); |
| | }).join('') |
| | + '</section>' : '') + |
| | '<section><h2>Final Verdict</h2><div class="verdict-box">' + |
| | '<div style="font-size:12px;line-height:1.8;white-space:pre-wrap;color:#374151">' + esc(sessionData.verdict || '') + '</div>' + |
| | '</div></section>' + |
| | '<div class="ftr"><span>βοΈ AI Boardroom v1.0 Β· Multi-Agent Strategic Decision System</span><span>Powered by Claude Sonnet</span></div>' + |
| | '</body></html>'; |
| | |
| | |
| | var blob = new Blob([html], { type:'text/html;charset=utf-8' }); |
| | var url = URL.createObjectURL(blob); |
| | var a = document.createElement('a'); |
| | a.href = url; |
| | a.download = 'boardroom-report.html'; |
| | document.body.appendChild(a); |
| | a.click(); |
| | document.body.removeChild(a); |
| | setTimeout(function() { URL.revokeObjectURL(url); }, 10000); |
| | } |
| | </script> |
| | </body> |
| | </html> |
| |
|