@conversionpros/aiva 1.0.1 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (149) hide show
  1. package/bin/aiva.js +26 -14
  2. package/lib/bluebubbles.js +145 -0
  3. package/lib/config-gen.js +253 -0
  4. package/lib/constants.js +72 -0
  5. package/lib/launch-agent.js +112 -0
  6. package/lib/prerequisites.js +236 -0
  7. package/lib/process.js +59 -145
  8. package/lib/setup.js +224 -194
  9. package/lib/validate.js +194 -0
  10. package/package.json +7 -32
  11. package/auto-deploy.js +0 -190
  12. package/cli-sync.js +0 -126
  13. package/d2a-prompt-template.txt +0 -106
  14. package/diagnostics-api.js +0 -304
  15. package/docs/ara-dedup-fix-scope.md +0 -112
  16. package/docs/ara-fix-round2-scope.md +0 -61
  17. package/docs/ara-greeting-fix-scope.md +0 -70
  18. package/docs/calendar-date-fix-scope.md +0 -28
  19. package/docs/getting-started.md +0 -115
  20. package/docs/network-architecture-rollout-scope.md +0 -43
  21. package/docs/scope-google-oauth-integration.md +0 -351
  22. package/docs/settings-page-scope.md +0 -50
  23. package/docs/xai-imagine-scope.md +0 -116
  24. package/docs/xai-voice-integration-scope.md +0 -115
  25. package/docs/xai-voice-tools-scope.md +0 -165
  26. package/email-router.js +0 -512
  27. package/follow-up-handler.js +0 -606
  28. package/gateway-monitor.js +0 -158
  29. package/google-email.js +0 -379
  30. package/google-oauth.js +0 -310
  31. package/grok-imagine.js +0 -97
  32. package/health-reporter.js +0 -287
  33. package/invisible-prefix-base.txt +0 -206
  34. package/invisible-prefix-owner.txt +0 -26
  35. package/invisible-prefix-slim.txt +0 -10
  36. package/invisible-prefix.txt +0 -43
  37. package/knowledge-base.js +0 -472
  38. package/lib/cli.js +0 -19
  39. package/lib/server.js +0 -42
  40. package/meta-capi.js +0 -206
  41. package/meta-leads.js +0 -411
  42. package/notion-oauth.js +0 -323
  43. package/public/agent-config.html +0 -241
  44. package/public/aiva-avatar-anime.png +0 -0
  45. package/public/css/docs.css.bak +0 -688
  46. package/public/css/onboarding.css +0 -543
  47. package/public/diagrams/claude-subscription-pool.html +0 -329
  48. package/public/diagrams/claude-subscription-pool.png +0 -0
  49. package/public/docs-icon.png +0 -0
  50. package/public/escalation.html +0 -237
  51. package/public/group-config.html +0 -300
  52. package/public/icon-192.png +0 -0
  53. package/public/icon-512.png +0 -0
  54. package/public/icons/agents.svg +0 -1
  55. package/public/icons/attach.svg +0 -1
  56. package/public/icons/characters.svg +0 -1
  57. package/public/icons/chat.svg +0 -1
  58. package/public/icons/docs.svg +0 -1
  59. package/public/icons/heartbeat.svg +0 -1
  60. package/public/icons/messages.svg +0 -1
  61. package/public/icons/mic.svg +0 -1
  62. package/public/icons/notes.svg +0 -1
  63. package/public/icons/settings.svg +0 -1
  64. package/public/icons/tasks.svg +0 -1
  65. package/public/images/onboarding/p0-communication-layer.png +0 -0
  66. package/public/images/onboarding/p0-infinite-surface.png +0 -0
  67. package/public/images/onboarding/p0-learning-model.png +0 -0
  68. package/public/images/onboarding/p0-meet-aiva.png +0 -0
  69. package/public/images/onboarding/p4-contact-intelligence.png +0 -0
  70. package/public/images/onboarding/p4-context-compounds.png +0 -0
  71. package/public/images/onboarding/p4-message-router.png +0 -0
  72. package/public/images/onboarding/p4-per-contact-rules.png +0 -0
  73. package/public/images/onboarding/p4-send-messages.png +0 -0
  74. package/public/images/onboarding/p6-be-precise.png +0 -0
  75. package/public/images/onboarding/p6-review-escalations.png +0 -0
  76. package/public/images/onboarding/p6-voice-input.png +0 -0
  77. package/public/images/onboarding/p7-completion.png +0 -0
  78. package/public/index.html +0 -11594
  79. package/public/js/onboarding.js +0 -699
  80. package/public/manifest.json +0 -24
  81. package/public/messages-v2.html +0 -2824
  82. package/public/permission-approve.html.bak +0 -107
  83. package/public/permissions.html +0 -150
  84. package/public/styles/design-system.css +0 -68
  85. package/router-db.js +0 -604
  86. package/router-utils.js +0 -28
  87. package/router-v2/adapters/imessage.js +0 -191
  88. package/router-v2/adapters/quo.js +0 -82
  89. package/router-v2/adapters/whatsapp.js +0 -192
  90. package/router-v2/contact-manager.js +0 -234
  91. package/router-v2/conversation-engine.js +0 -498
  92. package/router-v2/data/knowledge-base.json +0 -176
  93. package/router-v2/data/router-v2.db +0 -0
  94. package/router-v2/data/router-v2.db-shm +0 -0
  95. package/router-v2/data/router-v2.db-wal +0 -0
  96. package/router-v2/data/router.db +0 -0
  97. package/router-v2/db.js +0 -457
  98. package/router-v2/escalation-bridge.js +0 -540
  99. package/router-v2/follow-up-engine.js +0 -347
  100. package/router-v2/index.js +0 -441
  101. package/router-v2/ingestion.js +0 -213
  102. package/router-v2/knowledge-base.js +0 -231
  103. package/router-v2/lead-qualifier.js +0 -152
  104. package/router-v2/learning-loop.js +0 -202
  105. package/router-v2/outbound-sender.js +0 -160
  106. package/router-v2/package.json +0 -13
  107. package/router-v2/permission-gate.js +0 -86
  108. package/router-v2/playbook.js +0 -177
  109. package/router-v2/prompts/base.js +0 -52
  110. package/router-v2/prompts/first-contact.js +0 -38
  111. package/router-v2/prompts/lead-qualification.js +0 -37
  112. package/router-v2/prompts/scheduling.js +0 -72
  113. package/router-v2/prompts/style-overrides.js +0 -22
  114. package/router-v2/scheduler.js +0 -301
  115. package/router-v2/scripts/migrate-v1-to-v2.js +0 -215
  116. package/router-v2/scripts/seed-faq.js +0 -67
  117. package/router-v2/seed-knowledge-base.js +0 -39
  118. package/router-v2/utils/ai.js +0 -129
  119. package/router-v2/utils/phone.js +0 -52
  120. package/router-v2/utils/response-validator.js +0 -98
  121. package/router-v2/utils/sanitize.js +0 -222
  122. package/router.js +0 -5005
  123. package/routes/google-calendar.js +0 -186
  124. package/scripts/deploy.sh +0 -62
  125. package/scripts/macos-calendar.sh +0 -232
  126. package/scripts/onboard-device.sh +0 -466
  127. package/server.js +0 -5131
  128. package/start.sh +0 -24
  129. package/templates/AGENTS.md +0 -548
  130. package/templates/IDENTITY.md +0 -15
  131. package/templates/docs-agents.html +0 -132
  132. package/templates/docs-app.html +0 -130
  133. package/templates/docs-home.html +0 -83
  134. package/templates/docs-imessage.html +0 -121
  135. package/templates/docs-tasks.html +0 -123
  136. package/templates/docs-tips.html +0 -175
  137. package/templates/getting-started.html +0 -809
  138. package/templates/invisible-prefix-base.txt +0 -171
  139. package/templates/invisible-prefix-owner.txt +0 -282
  140. package/templates/invisible-prefix.txt +0 -338
  141. package/templates/manifest.json +0 -61
  142. package/templates/memory-org/clients.md +0 -7
  143. package/templates/memory-org/credentials.md +0 -9
  144. package/templates/memory-org/devices.md +0 -7
  145. package/templates/updates.html +0 -464
  146. package/tts-proxy.js +0 -96
  147. package/voice-call-local.js +0 -731
  148. package/voice-call.js +0 -732
  149. package/wa-listener.js +0 -354
@@ -1,107 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Permission Request - AIVA</title>
7
- <style>
8
- * { box-sizing: border-box; margin: 0; padding: 0; }
9
- body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; background: #0a0a0a; color: #e0e0e0; min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: 20px; }
10
- .card { background: #1a1a1a; border: 1px solid #333; border-radius: 16px; padding: 32px; max-width: 480px; width: 100%; }
11
- .icon { font-size: 48px; margin-bottom: 16px; }
12
- h1 { font-size: 20px; margin-bottom: 8px; color: #fff; }
13
- .subtitle { color: #888; font-size: 14px; margin-bottom: 24px; }
14
- .field { margin-bottom: 16px; }
15
- .field label { display: block; font-size: 12px; color: #666; text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 4px; }
16
- .field .value { font-size: 15px; color: #ccc; background: #111; padding: 10px 12px; border-radius: 8px; border: 1px solid #222; }
17
- .field .value.message { white-space: pre-wrap; font-style: italic; }
18
- .actions { display: flex; gap: 12px; margin-top: 24px; }
19
- .btn { flex: 1; padding: 14px; border: none; border-radius: 10px; font-size: 16px; font-weight: 600; cursor: pointer; transition: opacity 0.2s; }
20
- .btn:hover { opacity: 0.85; }
21
- .btn:disabled { opacity: 0.4; cursor: not-allowed; }
22
- .btn-allow { background: #22c55e; color: #fff; }
23
- .btn-deny { background: #333; color: #ccc; }
24
- .result { text-align: center; padding: 20px 0; font-size: 18px; }
25
- .result.approved { color: #22c55e; }
26
- .result.denied { color: #ef4444; }
27
- .loading { text-align: center; color: #666; padding: 40px 0; }
28
- .error { text-align: center; color: #ef4444; padding: 40px 0; }
29
- </style>
30
- </head>
31
- <body>
32
- <div class="card" id="main">
33
- <div class="loading" id="loading">Loading request...</div>
34
- <div id="content" style="display:none">
35
- <div class="icon">&#x1f510;</div>
36
- <h1>Permission Request</h1>
37
- <div class="subtitle">Someone is requesting AIVA to take action on their behalf.</div>
38
- <div class="field"><label>Contact</label><div class="value" id="contact"></div></div>
39
- <div class="field"><label>Request Type</label><div class="value" id="type"></div></div>
40
- <div class="field"><label>What they're asking</label><div class="value" id="details"></div></div>
41
- <div class="field"><label>Original Message</label><div class="value message" id="message"></div></div>
42
- <div class="field"><label>Notes / Instructions for AIVA</label><textarea id="notes" placeholder="How should AIVA handle this? (e.g., 'always book for mornings', 'check with me first on cost')" style="width:100%;min-height:80px;background:#111;color:#ccc;border:1px solid #222;border-radius:8px;padding:10px 12px;font-size:14px;font-family:inherit;resize:vertical;"></textarea></div>
43
- <div class="actions" style="flex-wrap: wrap;">
44
- <button class="btn btn-allow" id="btnApproveOnce" onclick="resolve('approved', false)" style="background:#3b82f6;">Approve This Time</button>
45
- <button class="btn btn-allow" id="btnAlwaysAllow" onclick="resolve('approved', true)">Always Allow</button>
46
- <button class="btn btn-deny" id="btnDeny" onclick="resolve('denied', false)">Deny</button>
47
- </div>
48
- </div>
49
- <div id="result" style="display:none"></div>
50
- <div id="error" style="display:none" class="error"></div>
51
- </div>
52
- <script>
53
- const token = window.location.pathname.split('/').pop();
54
- const API = '/api/router/permission-requests/' + token;
55
-
56
- fetch(API, { headers: { 'x-aiva-internal': 'true' } })
57
- .then(r => { if (!r.ok) throw new Error('Not found'); return r.json(); })
58
- .then(data => {
59
- document.getElementById('loading').style.display = 'none';
60
- if (data.status !== 'pending') {
61
- document.getElementById('result').style.display = 'block';
62
- document.getElementById('result').className = 'result ' + data.status;
63
- document.getElementById('result').textContent = 'This request has already been ' + data.status + '.';
64
- return;
65
- }
66
- document.getElementById('content').style.display = 'block';
67
- document.getElementById('contact').textContent = (data.contact_name || 'Unknown') + ' (' + data.phone + ')';
68
- document.getElementById('type').textContent = data.permission_type;
69
- document.getElementById('details').textContent = data.request_details || 'N/A';
70
- document.getElementById('message').textContent = data.original_message || 'N/A';
71
- })
72
- .catch(() => {
73
- document.getElementById('loading').style.display = 'none';
74
- document.getElementById('error').style.display = 'block';
75
- document.getElementById('error').textContent = 'Permission request not found or expired.';
76
- });
77
-
78
- function resolve(status, alwaysAllow) {
79
- document.querySelectorAll('.btn').forEach(b => b.disabled = true);
80
- const notes = (document.getElementById('notes')?.value || '').trim();
81
- fetch(API + '/resolve', {
82
- method: 'POST',
83
- headers: { 'Content-Type': 'application/json', 'x-aiva-internal': 'true' },
84
- body: JSON.stringify({ status, alwaysAllow: !!alwaysAllow, notes: notes || undefined })
85
- })
86
- .then(r => r.json())
87
- .then(() => {
88
- document.getElementById('content').style.display = 'none';
89
- document.getElementById('result').style.display = 'block';
90
- document.getElementById('result').className = 'result ' + status;
91
- if (status === 'approved' && alwaysAllow) {
92
- document.getElementById('result').textContent = 'Approved! This permission type is now always allowed for this contact.';
93
- } else if (status === 'approved') {
94
- document.getElementById('result').textContent = 'Approved this time! They\'ll need approval again next time.';
95
- } else {
96
- document.getElementById('result').textContent = 'Denied. They can ask again later.';
97
- }
98
- })
99
- .catch(() => {
100
- document.getElementById('error').style.display = 'block';
101
- document.getElementById('error').textContent = 'Failed to process. Try again.';
102
- document.querySelectorAll('.btn').forEach(b => b.disabled = false);
103
- });
104
- }
105
- </script>
106
- </body>
107
- </html>
@@ -1,150 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <link rel="stylesheet" href="/styles/design-system.css">
7
- <title>AIVA - Permission Request</title>
8
- <style>
9
- body{font-family:var(--font-sans);background:var(--bg-secondary);color:var(--text);min-height:100vh;display:flex;flex-direction:column;align-items:center;padding:20px}
10
- .container{max-width:480px;width:100%}
11
- .header{text-align:center;margin-bottom:24px;padding:16px 0;border-bottom:1px solid var(--border-dim)}
12
- .header h1{font-size:18px;color:var(--text-dim);font-weight:500;letter-spacing:1px}
13
- .contact-info{background:var(--surface-glass);border:1px solid var(--border-dim);border-radius:var(--radius-lg);padding:var(--space-lg);margin-bottom:var(--space-lg)}
14
- .contact-name{font-size:20px;font-weight:600;color:var(--text)}
15
- .contact-phone{font-size:14px;color:var(--text-dim);margin-top:var(--space-xs)}
16
- .bubble{background:#1c2333;border:1px solid var(--border-dim);border-radius:var(--radius-xl);border-top-left-radius:var(--radius-sm);padding:14px 18px;margin-bottom:var(--space-lg);font-size:16px;line-height:1.5;color:var(--text-secondary)}
17
- .bubble-label{font-size:12px;color:var(--text-dim);margin-bottom:6px;text-transform:uppercase;letter-spacing:.5px}
18
- .detail-box{background:var(--surface-glass);border:1px solid var(--border-dim);border-radius:var(--radius-lg);padding:var(--space-lg);margin-bottom:var(--space-lg)}
19
- .detail-label{font-size:12px;color:var(--text-dim);text-transform:uppercase;letter-spacing:.5px;margin-bottom:var(--space-xs)}
20
- .detail-value{font-size:15px;color:var(--text-secondary);line-height:1.4}
21
- .permission-badge{display:inline-block;background:#1f2937;border:1px solid var(--border);border-radius:var(--radius-md);padding:6px 12px;font-size:14px;color:var(--blue);font-weight:600;margin-top:var(--space-xs)}
22
- .decision-section{margin-top:var(--space-xl)}
23
- .decision-label{font-size:12px;color:var(--text-dim);text-transform:uppercase;letter-spacing:.5px;margin-bottom:var(--space-md)}
24
- .decision-btn{width:100%;padding:14px 16px;border:2px solid var(--border);border-radius:var(--radius-lg);font-size:15px;font-weight:600;cursor:pointer;margin-bottom:var(--space-sm);transition:all .2s;background:var(--surface-glass);color:var(--text-secondary);text-align:left;display:flex;align-items:center;gap:10px;font-family:var(--font-sans)}
25
- .decision-btn:hover{border-color:var(--blue);background:#1c2333}
26
- .decision-btn.selected{border-color:var(--blue);background:#1c2333}
27
- .decision-btn.approve-once.selected{border-color:var(--green-border);background:var(--green-bg)}
28
- .decision-btn.approve-always.selected{border-color:var(--yellow-border);background:var(--yellow-bg)}
29
- .decision-btn.deny.selected{border-color:var(--red-border);background:var(--red-bg)}
30
- .decision-icon{font-size:20px;flex-shrink:0}
31
- .decision-text{flex:1}
32
- .decision-title{font-size:15px;font-weight:600}
33
- .decision-desc{font-size:12px;color:var(--text-dim);margin-top:2px;font-weight:400}
34
- .btn{width:100%;padding:14px;color:#fff;border:none;border-radius:var(--radius-lg);font-size:16px;font-weight:600;cursor:pointer;transition:all .2s;margin-top:var(--space-md)}
35
- .btn-approve{background:var(--green-border)}
36
- .btn-approve:hover{background:#2ea043}
37
- .btn-warn{background:var(--yellow-border)}
38
- .btn-warn:hover{background:#d29922}
39
- .btn-deny{background:var(--red-border)}
40
- .btn-deny:hover{background:#f85149}
41
- .btn:disabled{background:var(--border-dim);color:var(--text-muted);cursor:not-allowed}
42
- .status{text-align:center;padding:16px;border-radius:var(--radius-lg);margin-top:var(--space-lg);font-size:15px}
43
- .status.success{background:var(--green-bg);border:1px solid var(--green-border);color:var(--green)}
44
- .status.error{background:var(--red-bg);border:1px solid var(--red-border);color:var(--red)}
45
- .status.denied{background:var(--red-bg);border:1px solid var(--red-border);color:var(--red)}
46
- .expired{text-align:center;padding:40px 20px}
47
- .expired h2{color:var(--red);margin-bottom:var(--space-md)}
48
- .expired p{color:var(--text-dim)}
49
- .loading{text-align:center;padding:60px;color:var(--text-dim)}
50
- </style>
51
- </head>
52
- <body>
53
- <div class="container" id="app">
54
- <div class="loading" id="loading">Loading permission request...</div>
55
- </div>
56
- <script>
57
- (async()=>{
58
- const app=document.getElementById('app');
59
- const token=window.location.pathname.split('/').pop();
60
- if(!token){app.innerHTML='<div class="expired"><h2>Invalid Link</h2><p>Missing token.</p></div>';return}
61
- try{
62
- const res=await fetch(`/api/router/permission-requests/${encodeURIComponent(token)}`,{headers:{'x-aiva-internal':'true'}});
63
- if(!res.ok){app.innerHTML='<div class="expired"><h2>Not Found</h2><p>This permission request was not found or has expired.</p></div>';return}
64
- const d=await res.json();
65
- if(d.status!=='pending'){
66
- const color=d.status==='approved'?'#3fb950':'#f85149';
67
- app.innerHTML=`<div class="header"><h1>AIVA PERMISSION</h1></div><div class="status" style="background:${d.status==='approved'?'#0d1f0d':'#1f0d0d'};border:1px solid ${color};color:${color};padding:24px;font-size:18px">This request has already been ${esc(d.status)}.</div>`;
68
- return}
69
- app.innerHTML=`
70
- <div class="header"><h1>AIVA PERMISSION REQUEST</h1></div>
71
- <div class="contact-info">
72
- <div class="contact-name">${esc(d.contact_name||'Unknown')}</div>
73
- <div class="contact-phone">${esc(d.phone)}</div>
74
- </div>
75
- <div class="bubble-label">Their message</div>
76
- <div class="bubble">${esc(d.original_message)}</div>
77
- <div class="detail-box">
78
- <div class="detail-label">What they're requesting</div>
79
- <div class="detail-value">${esc(d.request_details)}</div>
80
- </div>
81
- <div class="detail-box">
82
- <div class="detail-label">Permission needed</div>
83
- <div class="permission-badge">${esc(d.permission_type)}</div>
84
- </div>
85
- <div class="decision-section">
86
- <div class="decision-label">What do you want to do?</div>
87
- <button class="decision-btn approve-once" id="approveOnceBtn" onclick="selectDecision('approved',this)">
88
- <span class="decision-icon">✅</span>
89
- <span class="decision-text">
90
- <div class="decision-title">Allow This Time</div>
91
- <div class="decision-desc">Handle this one request only</div>
92
- </span>
93
- </button>
94
- <button class="decision-btn approve-always" id="approveAlwaysBtn" onclick="selectDecision('approved_always',this)">
95
- <span class="decision-icon">🔓</span>
96
- <span class="decision-text">
97
- <div class="decision-title">Allow Always</div>
98
- <div class="decision-desc">Auto-approve this type of request from ${esc(d.contact_name||'this contact')} going forward</div>
99
- </span>
100
- </button>
101
- <button class="decision-btn deny" id="denyBtn" onclick="selectDecision('denied',this)">
102
- <span class="decision-icon">🚫</span>
103
- <span class="decision-text">
104
- <div class="decision-title">Deny</div>
105
- <div class="decision-desc">Reject this request</div>
106
- </span>
107
- </button>
108
- </div>
109
- <button class="btn" id="sendBtn" disabled>Select a decision above</button>
110
- <div id="status"></div>`;
111
- }catch(e){app.innerHTML='<div class="expired"><h2>Error</h2><p>Could not load request.</p></div>'}
112
- function esc(s){const d=document.createElement('div');d.textContent=s||'';return d.innerHTML}
113
- let currentDecision=null;
114
- window.selectDecision=function(decision,btn){
115
- currentDecision=decision;
116
- document.querySelectorAll('.decision-btn').forEach(b=>b.classList.remove('selected'));
117
- btn.classList.add('selected');
118
- const sendBtn=document.getElementById('sendBtn');
119
- sendBtn.disabled=false;
120
- if(decision==='approved'){sendBtn.textContent='Allow This Time';sendBtn.className='btn btn-approve';sendBtn.onclick=resolve}
121
- else if(decision==='approved_always'){sendBtn.textContent='Allow Always';sendBtn.className='btn btn-warn';sendBtn.onclick=resolve}
122
- else{sendBtn.textContent='Deny Request';sendBtn.className='btn btn-deny';sendBtn.onclick=resolve}
123
- };
124
- window.resolve=async()=>{
125
- if(!currentDecision)return;
126
- const sendBtn=document.getElementById('sendBtn');
127
- sendBtn.disabled=true;sendBtn.textContent='Saving...';
128
- const status=currentDecision==='approved_always'?'approved':currentDecision;
129
- const always=currentDecision==='approved_always';
130
- try{
131
- const r=await fetch(`/api/router/permission-requests/${encodeURIComponent(token)}/resolve`,{method:'POST',headers:{'Content-Type':'application/json','x-aiva-internal':'true'},body:JSON.stringify({status,always})});
132
- const d=await r.json();
133
- const el=document.getElementById('status');
134
- if(r.ok){
135
- el.className='status '+(status==='approved'?'success':'denied');
136
- el.textContent=status==='approved'?(always?'Permission granted permanently. AIVA will auto-approve this going forward.':'Permission granted for this request. AIVA will handle it now.'):'Request denied.';
137
- sendBtn.style.display='none';
138
- document.querySelectorAll('.decision-btn').forEach(b=>{b.style.pointerEvents='none';b.style.opacity='0.5'});
139
- }else{
140
- el.className='status error';el.textContent=d.error||'Failed';
141
- sendBtn.disabled=false;sendBtn.textContent='Retry';
142
- }
143
- }catch(e){
144
- const el=document.getElementById('status');el.className='status error';el.textContent='Network error';
145
- sendBtn.disabled=false;sendBtn.textContent='Retry';
146
- }}
147
- })();
148
- </script>
149
- </body>
150
- </html>
@@ -1,68 +0,0 @@
1
- /* AIVA Design System — Shared across all pages */
2
-
3
- /* Global reset */
4
- *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
5
-
6
- :root {
7
- /* Colors */
8
- --bg: #0a0a0f;
9
- --bg-secondary: #0f1117;
10
- --surface: #14141f;
11
- --surface2: #1e1e2e;
12
- --surface-glass: #161b22;
13
- --border: #2a2a3e;
14
- --border-dim: #21262d;
15
-
16
- /* Text */
17
- --text: #e0e0f0;
18
- --text-secondary: #c9d1d9;
19
- --text-dim: #8888aa;
20
- --text-muted: #484f58;
21
-
22
- /* Accent */
23
- --accent: #6c63ff;
24
- --accent-hover: #7c74ff;
25
-
26
- /* Semantic */
27
- --green: #4ade80;
28
- --green-bg: #0d1f0d;
29
- --green-border: #238636;
30
- --red: #f87171;
31
- --red-bg: #1f0d0d;
32
- --red-border: #da3633;
33
- --yellow: #fbbf24;
34
- --yellow-bg: #1f1a0d;
35
- --yellow-border: #f0883e;
36
- --blue: #60a5fa;
37
- --blue-bg: rgba(96,165,250,0.1);
38
-
39
- /* Spacing scale */
40
- --space-xs: 4px;
41
- --space-sm: 8px;
42
- --space-md: 12px;
43
- --space-lg: 16px;
44
- --space-xl: 20px;
45
- --space-2xl: 24px;
46
- --space-3xl: 32px;
47
-
48
- /* Border radius scale */
49
- --radius-sm: 4px;
50
- --radius-md: 8px;
51
- --radius-lg: 12px;
52
- --radius-xl: 16px;
53
-
54
- /* Typography */
55
- --font-sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
56
- --font-mono: ui-monospace, 'Cascadia Code', 'Source Code Pro', Menlo, Consolas, monospace;
57
- }
58
-
59
- /* Focus styles — global accessibility */
60
- *:focus-visible {
61
- outline: 2px solid var(--accent);
62
- outline-offset: 2px;
63
- }
64
-
65
- /* Remove outline for mouse users */
66
- *:focus:not(:focus-visible) {
67
- outline: none;
68
- }