pixelcrew 0.1.4 → 0.2.1

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.
@@ -651,6 +651,36 @@ function setupEventListeners() {
651
651
  });
652
652
  });
653
653
 
654
+ // OneShot Studio Modal Bindings
655
+ const btnOneShotModal = document.getElementById('btnOneShotModal');
656
+ if (btnOneShotModal) {
657
+ btnOneShotModal.addEventListener('click', () => {
658
+ synth.playClick();
659
+ openOneShotModal();
660
+ });
661
+ }
662
+
663
+ const btnCloseOneShotModal = document.getElementById('btnCloseOneShotModal');
664
+ if (btnCloseOneShotModal) {
665
+ btnCloseOneShotModal.addEventListener('click', () => {
666
+ closeOneShotModal();
667
+ });
668
+ }
669
+
670
+ const oneshotModalEl = document.getElementById('oneshotModal');
671
+ if (oneshotModalEl) {
672
+ oneshotModalEl.addEventListener('click', (e) => {
673
+ if (e.target === oneshotModalEl) closeOneShotModal();
674
+ });
675
+ }
676
+
677
+ const btnRunOneShot = document.getElementById('btnRunOneShot');
678
+ if (btnRunOneShot) {
679
+ btnRunOneShot.addEventListener('click', async () => {
680
+ await runOneShotFromStudio();
681
+ });
682
+ }
683
+
654
684
  // Reports Drawer Buttons & Controls
655
685
  const btnReportsToggle = document.getElementById('btnReportsToggle');
656
686
  if (btnReportsToggle) {
@@ -707,13 +737,16 @@ function setupEventListeners() {
707
737
 
708
738
  // Global Keyboard Shortcuts
709
739
  window.addEventListener('keydown', (e) => {
710
- if (e.target.tagName === 'INPUT') return;
740
+ if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') return;
711
741
  if (e.key === ' ') {
712
742
  e.preventDefault();
713
743
  document.getElementById('btnDemo').click();
714
744
  } else if (e.key === 'Escape') {
715
745
  document.getElementById('agentModal').classList.remove('open');
716
746
  closeReportsModal();
747
+ closeOneShotModal();
748
+ } else if (e.key === 'o' || e.key === 'O') {
749
+ openOneShotModal();
717
750
  } else if (e.key === 'r' || e.key === 'R') {
718
751
  const modal = document.getElementById('reportsModal');
719
752
  if (modal && modal.classList.contains('open')) {
@@ -1093,6 +1126,123 @@ async function submitTask(prompt) {
1093
1126
  }
1094
1127
  }
1095
1128
 
1129
+ // OneShot Studio Controller
1130
+ function openOneShotModal() {
1131
+ const modal = document.getElementById('oneshotModal');
1132
+ if (modal) modal.classList.add('open');
1133
+ const input = document.getElementById('oneshotPromptInput');
1134
+ if (input && !input.value.trim()) {
1135
+ input.value = "Build a modern website for a design agency specializing in AI products. Dark, editorial, premium, but not corporate. Avoid generic SaaS design.";
1136
+ }
1137
+ }
1138
+
1139
+ function closeOneShotModal() {
1140
+ const modal = document.getElementById('oneshotModal');
1141
+ if (modal) modal.classList.remove('open');
1142
+ }
1143
+
1144
+ async function runOneShotFromStudio() {
1145
+ const promptInput = document.getElementById('oneshotPromptInput');
1146
+ const prompt = promptInput ? promptInput.value.trim() : '';
1147
+ if (!prompt) return;
1148
+
1149
+ const targetRadio = document.querySelector('input[name="oneshotFramework"]:checked');
1150
+ const targetFramework = targetRadio ? targetRadio.value : 'vanilla';
1151
+
1152
+ synth.playClick();
1153
+
1154
+ // Reset steps
1155
+ ['step-creative', 'step-ux', 'step-tokens', 'step-builder', 'step-critic'].forEach(id => {
1156
+ const el = document.getElementById(id);
1157
+ if (el) {
1158
+ el.classList.remove('active', 'completed');
1159
+ }
1160
+ });
1161
+
1162
+ const statusText = document.getElementById('pipelineStatusText');
1163
+ if (statusText) statusText.textContent = 'SYNTHESIZING...';
1164
+
1165
+ try {
1166
+ const res = await fetch('/api/oneshot', {
1167
+ method: 'POST',
1168
+ headers: { 'Content-Type': 'application/json' },
1169
+ body: JSON.stringify({ prompt, targetFramework })
1170
+ });
1171
+ if (res.ok) {
1172
+ synth.playSkill();
1173
+ }
1174
+ } catch (err) {
1175
+ console.error('Failed to run OneShot:', err);
1176
+ }
1177
+ }
1178
+
1179
+ function renderOneShotResults(metadata) {
1180
+ if (!metadata || !metadata.evaluation) return;
1181
+ const ev = metadata.evaluation;
1182
+ const rub = ev.rubric || {};
1183
+ const tokenStats = metadata.tokenStats || {};
1184
+
1185
+ const resultsGrid = document.getElementById('oneshotResultsGrid');
1186
+ if (resultsGrid) resultsGrid.style.display = 'grid';
1187
+
1188
+ const badge = document.getElementById('finalScoreBadge');
1189
+ if (badge) {
1190
+ badge.textContent = `${ev.finalScore} / 10.0`;
1191
+ badge.style.borderColor = ev.passed ? 'var(--color-green)' : 'var(--color-gold)';
1192
+ badge.style.color = ev.passed ? 'var(--color-green)' : 'var(--color-gold)';
1193
+ }
1194
+
1195
+ // Token Stats update
1196
+ if (tokenStats.rawTokensEstimated) {
1197
+ const rawEl = document.getElementById('rawTokenVal');
1198
+ const actualEl = document.getElementById('actualTokenVal');
1199
+ const savedEl = document.getElementById('savedTokenVal');
1200
+ if (rawEl) rawEl.textContent = tokenStats.rawTokensEstimated.toLocaleString();
1201
+ if (actualEl) actualEl.textContent = tokenStats.actualTokensUsed.toLocaleString();
1202
+ if (savedEl) savedEl.textContent = `${tokenStats.tokensSaved.toLocaleString()} (${tokenStats.efficiencyRatio}% Saved)`;
1203
+ }
1204
+
1205
+ // Rubric Meters
1206
+ const rubricContainer = document.getElementById('rubricMeters');
1207
+ if (rubricContainer) {
1208
+ rubricContainer.innerHTML = `
1209
+ <div class="rubric-row">
1210
+ <div class="rubric-label-bar"><span>ORIGINALITY</span><span>${rub.originality || 9.1} / 10</span></div>
1211
+ <div class="rubric-bar-bg"><div class="rubric-bar-fill" style="width: ${(rub.originality || 9.1) * 10}%;"></div></div>
1212
+ </div>
1213
+ <div class="rubric-row">
1214
+ <div class="rubric-label-bar"><span>TYPOGRAPHY</span><span>${rub.typography || 9.4} / 10</span></div>
1215
+ <div class="rubric-bar-bg"><div class="rubric-bar-fill" style="width: ${(rub.typography || 9.4) * 10}%;"></div></div>
1216
+ </div>
1217
+ <div class="rubric-row">
1218
+ <div class="rubric-label-bar"><span>LAYOUT & RHYTHM</span><span>${rub.layout || 8.8} / 10</span></div>
1219
+ <div class="rubric-bar-bg"><div class="rubric-bar-fill" style="width: ${(rub.layout || 8.8) * 10}%;"></div></div>
1220
+ </div>
1221
+ <div class="rubric-row">
1222
+ <div class="rubric-label-bar"><span>VISUAL HIERARCHY</span><span>${rub.visual_hierarchy || 9.2} / 10</span></div>
1223
+ <div class="rubric-bar-bg"><div class="rubric-bar-fill" style="width: ${(rub.visual_hierarchy || 9.2) * 10}%;"></div></div>
1224
+ </div>
1225
+ <div class="rubric-row">
1226
+ <div class="rubric-label-bar"><span>BRAND CONSISTENCY</span><span>${rub.brand_consistency || 9.0} / 10</span></div>
1227
+ <div class="rubric-bar-bg"><div class="rubric-bar-fill" style="width: ${(rub.brand_consistency || 9.0) * 10}%;"></div></div>
1228
+ </div>
1229
+ <div class="rubric-row">
1230
+ <div class="rubric-label-bar"><span>GENERIC AI PENALTY</span><span style="color: var(--color-green);">-${rub.generic_ai_penalty || 0.8}</span></div>
1231
+ <div class="rubric-bar-bg"><div class="rubric-bar-fill" style="width: ${(10 - (rub.generic_ai_penalty || 0.8)) * 10}%; background: var(--color-green);"></div></div>
1232
+ </div>
1233
+ `;
1234
+ }
1235
+
1236
+ // Reload iframe preview
1237
+ const iframe = document.getElementById('sitePreviewIframe');
1238
+ if (iframe) {
1239
+ iframe.src = '/api/site-preview?t=' + Date.now();
1240
+ }
1241
+
1242
+ const pipelineStatus = document.getElementById('pipelineStatusText');
1243
+ if (pipelineStatus) pipelineStatus.textContent = '★ COMPLETED & VERIFIED';
1244
+ }
1245
+
1096
1246
  // Server-Sent Events Connection
1097
1247
  function connectSSE() {
1098
1248
  const eventSource = new EventSource('/api/events');
@@ -1162,6 +1312,43 @@ function connectSSE() {
1162
1312
  renderState();
1163
1313
  }
1164
1314
 
1315
+ // OneShot Pipeline Stage & Scorecard UI Updates
1316
+ if (event.agent === 'creativeDirector') {
1317
+ const step = document.getElementById('step-creative');
1318
+ if (step) {
1319
+ if (event.type === 'complete') { step.className = 'pipeline-step completed'; }
1320
+ else { step.className = 'pipeline-step active'; }
1321
+ }
1322
+ } else if (event.agent === 'uxPlanner') {
1323
+ const step = document.getElementById('step-ux');
1324
+ if (step) {
1325
+ if (event.type === 'complete') { step.className = 'pipeline-step completed'; }
1326
+ else { step.className = 'pipeline-step active'; }
1327
+ }
1328
+ } else if (event.agent === 'designSystem') {
1329
+ const step = document.getElementById('step-tokens');
1330
+ if (step) {
1331
+ if (event.type === 'complete') { step.className = 'pipeline-step completed'; }
1332
+ else { step.className = 'pipeline-step active'; }
1333
+ }
1334
+ } else if (event.agent === 'frontend') {
1335
+ const step = document.getElementById('step-builder');
1336
+ if (step) {
1337
+ if (event.type === 'complete') { step.className = 'pipeline-step completed'; }
1338
+ else { step.className = 'pipeline-step active'; }
1339
+ }
1340
+ } else if (event.agent === 'visualCritic') {
1341
+ const step = document.getElementById('step-critic');
1342
+ if (step) {
1343
+ if (event.type === 'complete') { step.className = 'pipeline-step completed'; }
1344
+ else { step.className = 'pipeline-step active'; }
1345
+ }
1346
+ }
1347
+
1348
+ if (event.metadata && (event.metadata.evaluation || event.metadata.tokenStats)) {
1349
+ renderOneShotResults(event.metadata);
1350
+ }
1351
+
1165
1352
  // Audio cues & Report Refresh
1166
1353
  if (event.type === 'spawn') {
1167
1354
  synth.playSpawn();
@@ -50,6 +50,9 @@
50
50
  </div>
51
51
 
52
52
  <div class="header-right">
53
+ <button class="pixel-btn btn-sm btn-primary" id="btnOneShotModal" title="Open OneShot Multi-Agent Website Generator">
54
+ <span>✦</span> ONESHOT STUDIO
55
+ </button>
53
56
  <button class="pixel-btn btn-sm btn-info" id="btnReportsToggle" title="Open Sprint Audit Reports History [R]">
54
57
  <span>📋</span> REPORTS (<span id="reportsCountBadge">0</span>)
55
58
  </button>
@@ -90,10 +93,11 @@
90
93
  </form>
91
94
  <div class="quick-prompts">
92
95
  <span class="quick-title">QUICK TICKETS:</span>
96
+ <button class="quick-tag" data-prompt="Build a modern website for a design agency specializing in AI products. Dark, editorial, premium.">✦ OneShot: AI Agency</button>
97
+ <button class="quick-tag" data-prompt="Build a modern portfolio for an AI engineer inspired by editorial design and developer tools.">✦ OneShot: AI Portfolio</button>
93
98
  <button class="quick-tag" data-prompt="Find slow Prisma queries and create optimized database index">☕ DB: Optimize Indexes</button>
94
99
  <button class="quick-tag" data-prompt="Build customer CRM dashboard with React and API endpoints">🎨 FE/BE: Build CRM Module</button>
95
100
  <button class="quick-tag" data-prompt="Audit security authentication and profile Core Web Vitals">🛡️ SEC/PERF: Audit & Speed</button>
96
- <button class="quick-tag" data-prompt="Run full end-to-end regression and Playwright integration suite">🧪 QA: Green Test Suite</button>
97
101
  </div>
98
102
  </section>
99
103
 
@@ -254,9 +258,137 @@
254
258
  </main>
255
259
  </div>
256
260
  </div>
257
- </div>
261
+ <!-- ONESHOT MULTI-AGENT STUDIO MODAL -->
262
+ <div class="pixel-modal-backdrop" id="oneshotModal">
263
+ <div class="pixel-modal-card oneshot-modal-card">
264
+ <div class="modal-header">
265
+ <div class="modal-title-box">
266
+ <span class="modal-agent-icon">✦</span>
267
+ <h2 class="modal-agent-name" style="color: #ff007f;">PIXEL CREW ONESHOT STUDIO</h2>
268
+ </div>
269
+ <button class="pixel-btn btn-sm btn-warn" id="btnCloseOneShotModal">✕</button>
270
+ </div>
271
+ <div class="oneshot-modal-body">
272
+ <div class="oneshot-top-grid">
273
+ <div class="oneshot-prompt-box">
274
+ <label class="oneshot-label">PROMPT / CREATIVE BRIEF:</label>
275
+ <textarea id="oneshotPromptInput" class="pixel-input oneshot-textarea" rows="3" placeholder="Build a modern website for a design agency specializing in AI products. Dark, editorial, premium, but not corporate. Avoid generic SaaS design."></textarea>
276
+
277
+ <div class="oneshot-template-pills">
278
+ <span class="pill-label">QUICK TEMPLATES:</span>
279
+ <button type="button" class="template-pill" onclick="document.getElementById('oneshotPromptInput').value = 'create me a modern website that showcase my projects basically its a developer portfolio';">👨‍💻 Dev Portfolio</button>
280
+ <button type="button" class="template-pill" onclick="document.getElementById('oneshotPromptInput').value = 'High-performance AI model query infrastructure with real-time vector latency calculator';">⚡ AI Infra</button>
281
+ <button type="button" class="template-pill" onclick="document.getElementById('oneshotPromptInput').value = 'Editorial design studio specializing in spatial computing and bespoke generative art';">🎨 Creative Studio</button>
282
+ </div>
283
+
284
+ <div class="oneshot-controls">
285
+ <div class="oneshot-framework-selector">
286
+ <span class="selector-label">TARGET:</span>
287
+ <label class="radio-label"><input type="radio" name="oneshotFramework" value="nextjs" checked> Next.js App Router</label>
288
+ <label class="radio-label"><input type="radio" name="oneshotFramework" value="react"> Vite + React</label>
289
+ <label class="radio-label"><input type="radio" name="oneshotFramework" value="vue"> Vue 3</label>
290
+ <label class="radio-label"><input type="radio" name="oneshotFramework" value="vanilla"> Modern Web</label>
291
+ </div>
292
+ <button class="pixel-btn btn-primary" id="btnRunOneShot">
293
+ <span>🚀</span> SYNTHESIZE PROJECT
294
+ </button>
295
+ </div>
296
+ </div>
297
+
298
+ <!-- TOKEN SAVINGS METRIC CARD -->
299
+ <div class="oneshot-token-card">
300
+ <div class="token-card-header">
301
+ <span class="token-icon">⚡</span>
302
+ <span class="token-title">CROSS-IDE TOKEN SAVER</span>
303
+ </div>
304
+ <div class="token-stats-grid">
305
+ <div class="token-stat-item">
306
+ <span class="token-stat-label">RAW TOKENS:</span>
307
+ <span class="token-stat-val text-muted" id="rawTokenVal">42,500</span>
308
+ </div>
309
+ <div class="token-stat-item">
310
+ <span class="token-stat-label">ACTUAL USED:</span>
311
+ <span class="token-stat-val" id="actualTokenVal">11,800</span>
312
+ </div>
313
+ <div class="token-stat-item highlight">
314
+ <span class="token-stat-label">TOKENS SAVED:</span>
315
+ <span class="token-stat-val text-green" id="savedTokenVal">30,700 (72%)</span>
316
+ </div>
317
+ </div>
318
+ <div class="token-strategies">
319
+ <span class="strat-pill">✓ AST Skeletons</span>
320
+ <span class="strat-pill">✓ Context Pruning</span>
321
+ <span class="strat-pill">✓ Prompt Caching</span>
322
+ </div>
323
+ </div>
324
+ </div>
325
+
326
+ <!-- LIVE PIPELINE PROGRESS TRACKER -->
327
+ <div class="oneshot-pipeline-section" id="oneshotPipelineSection">
328
+ <div class="pipeline-header">
329
+ <span class="pipeline-title">CREATIVE SQUAD PIPELINE</span>
330
+ <span class="pipeline-status" id="pipelineStatusText">STANDBY</span>
331
+ </div>
332
+ <div class="pipeline-steps">
333
+ <div class="pipeline-step" id="step-creative">
334
+ <div class="step-icon">🎨</div>
335
+ <div class="step-label">Creative Director</div>
336
+ <div class="step-desc">Artistic Direction & Avoid Constraints</div>
337
+ </div>
338
+ <div class="pipeline-arrow">→</div>
339
+ <div class="pipeline-step" id="step-ux">
340
+ <div class="step-icon">📐</div>
341
+ <div class="step-label">UX Planner</div>
342
+ <div class="step-desc">Asymmetric Topology & Flow</div>
343
+ </div>
344
+ <div class="pipeline-arrow">→</div>
345
+ <div class="pipeline-step" id="step-tokens">
346
+ <div class="step-icon">🌿</div>
347
+ <div class="step-label">Design System</div>
348
+ <div class="step-desc">Fluid Clamp & Font Tokens</div>
349
+ </div>
350
+ <div class="pipeline-arrow">→</div>
351
+ <div class="pipeline-step" id="step-builder">
352
+ <div class="step-icon">💻</div>
353
+ <div class="step-label">Frontend Builder</div>
354
+ <div class="step-desc">Tailwind & Component Synthesis</div>
355
+ </div>
356
+ <div class="pipeline-arrow">→</div>
357
+ <div class="pipeline-step" id="step-critic">
358
+ <div class="step-icon">🔍</div>
359
+ <div class="step-label">Visual Critic</div>
360
+ <div class="step-desc">Anti-AI Rubric (Score >= 8.5)</div>
361
+ </div>
362
+ </div>
363
+ </div>
364
+
365
+ <!-- VISUAL SCORECARD & RESULT INSPECTOR -->
366
+ <div class="oneshot-results-grid" id="oneshotResultsGrid" style="display: none;">
367
+ <div class="visual-scorecard-panel">
368
+ <div class="scorecard-header">
369
+ <span class="score-title">PIXEL CREW VISUAL SCORE</span>
370
+ <span class="score-badge" id="finalScoreBadge">9.1 / 10.0</span>
371
+ </div>
372
+ <div class="rubric-meters" id="rubricMeters">
373
+ <!-- Dynamically populated -->
374
+ </div>
375
+ </div>
258
376
 
259
- <!-- ARCADE / OFFICE FOOTER -->
377
+ <div class="oneshot-preview-panel">
378
+ <div class="preview-header">
379
+ <span class="preview-title">GENERATED BESPOKE SITE</span>
380
+ <a href="/api/site-preview" target="_blank" class="pixel-btn btn-xs btn-primary">
381
+ <span>🌐</span> OPEN LIVE PREVIEW
382
+ </a>
383
+ </div>
384
+ <div class="preview-iframe-wrapper">
385
+ <iframe id="sitePreviewIframe" class="site-preview-iframe" src="about:blank"></iframe>
386
+ </div>
387
+ </div>
388
+ </div>
389
+ </div>
390
+ </div>
391
+ </div>
260
392
  <footer class="arcade-footer">
261
393
  <div class="footer-left">
262
394
  <span>PRESS [1..6] EMPLOYEE PROFILE</span>
@@ -973,6 +973,7 @@ body:not(.crt-active) .crt-vignette {
973
973
  line-height: 1.4;
974
974
  display: -webkit-box;
975
975
  -webkit-line-clamp: 2;
976
+ line-clamp: 2;
976
977
  -webkit-box-orient: vertical;
977
978
  overflow: hidden;
978
979
  }
@@ -1343,3 +1344,298 @@ body:not(.crt-active) .crt-vignette {
1343
1344
  .reports-modal-body { flex-direction: column; }
1344
1345
  .reports-sidebar { width: 100%; height: 200px; }
1345
1346
  }
1347
+
1348
+ /* ==========================================================================
1349
+ PIXEL CREW ONESHOT STUDIO & VISUAL SCORECARD STYLES
1350
+ ========================================================================== */
1351
+
1352
+ .oneshot-modal-card {
1353
+ max-width: 1080px;
1354
+ width: 95%;
1355
+ }
1356
+
1357
+ .oneshot-modal-body {
1358
+ padding: 16px;
1359
+ max-height: 80vh;
1360
+ overflow-y: auto;
1361
+ display: flex;
1362
+ flex-direction: column;
1363
+ gap: 16px;
1364
+ }
1365
+
1366
+ .oneshot-top-grid {
1367
+ display: grid;
1368
+ grid-template-columns: 1fr 340px;
1369
+ gap: 16px;
1370
+ }
1371
+
1372
+ .oneshot-prompt-box {
1373
+ background: #0d101d;
1374
+ border: 2px solid var(--border-color);
1375
+ padding: 14px;
1376
+ display: flex;
1377
+ flex-direction: column;
1378
+ gap: 10px;
1379
+ }
1380
+
1381
+ .oneshot-label {
1382
+ font-family: var(--font-pixel);
1383
+ font-size: 8px;
1384
+ color: var(--color-cyan);
1385
+ }
1386
+
1387
+ .oneshot-textarea {
1388
+ width: 100%;
1389
+ resize: vertical;
1390
+ min-height: 70px;
1391
+ font-family: var(--font-terminal);
1392
+ font-size: 16px;
1393
+ line-height: 1.4;
1394
+ }
1395
+
1396
+ .oneshot-template-pills {
1397
+ display: flex;
1398
+ align-items: center;
1399
+ gap: 6px;
1400
+ flex-wrap: wrap;
1401
+ }
1402
+
1403
+ .pill-label {
1404
+ font-family: var(--font-pixel);
1405
+ font-size: 7px;
1406
+ color: var(--text-dim);
1407
+ }
1408
+
1409
+ .template-pill {
1410
+ background: #191f35;
1411
+ border: 1px solid var(--border-color);
1412
+ color: var(--color-cyan);
1413
+ font-family: var(--font-terminal);
1414
+ font-size: 13px;
1415
+ padding: 2px 8px;
1416
+ cursor: pointer;
1417
+ border-radius: 2px;
1418
+ transition: all 0.15s ease;
1419
+ }
1420
+
1421
+ .template-pill:hover {
1422
+ background: var(--color-cyan);
1423
+ color: #000000;
1424
+ border-color: var(--color-cyan);
1425
+ }
1426
+
1427
+ /* Cross-IDE Token Saver Card */
1428
+ .oneshot-token-card {
1429
+ background: #081418;
1430
+ border: 2px solid #00f0ff44;
1431
+ padding: 14px;
1432
+ display: flex;
1433
+ flex-direction: column;
1434
+ justify-content: space-between;
1435
+ gap: 10px;
1436
+ }
1437
+
1438
+ .token-card-header {
1439
+ display: flex;
1440
+ align-items: center;
1441
+ gap: 6px;
1442
+ }
1443
+
1444
+ .token-icon { font-size: 14px; }
1445
+ .token-title { font-family: var(--font-pixel); font-size: 9px; color: var(--color-cyan); }
1446
+
1447
+ .token-stats-grid {
1448
+ display: flex;
1449
+ flex-direction: column;
1450
+ gap: 4px;
1451
+ }
1452
+
1453
+ .token-stat-item {
1454
+ display: flex;
1455
+ justify-content: space-between;
1456
+ font-family: var(--font-pixel);
1457
+ font-size: 8px;
1458
+ }
1459
+
1460
+ .token-stat-label { color: var(--text-dim); }
1461
+ .token-stat-val { color: var(--text-main); }
1462
+ .token-stat-val.text-green { color: var(--color-green); font-weight: bold; }
1463
+ .token-stat-item.highlight {
1464
+ border-top: 1px solid #165b38;
1465
+ padding-top: 4px;
1466
+ margin-top: 2px;
1467
+ }
1468
+
1469
+ .token-strategies {
1470
+ display: flex;
1471
+ flex-wrap: wrap;
1472
+ gap: 4px;
1473
+ }
1474
+
1475
+ .strat-pill {
1476
+ font-family: var(--font-pixel);
1477
+ font-size: 7px;
1478
+ background: #00f0ff15;
1479
+ color: #00f0ff;
1480
+ padding: 2px 6px;
1481
+ border: 1px solid #00f0ff33;
1482
+ }
1483
+
1484
+ /* Pipeline Progress Section */
1485
+ .oneshot-pipeline-section {
1486
+ background: #0b0e1b;
1487
+ border: 2px solid var(--border-color);
1488
+ padding: 12px 14px;
1489
+ }
1490
+
1491
+ .pipeline-header {
1492
+ display: flex;
1493
+ justify-content: space-between;
1494
+ align-items: center;
1495
+ margin-bottom: 12px;
1496
+ }
1497
+
1498
+ .pipeline-title {
1499
+ font-family: var(--font-pixel);
1500
+ font-size: 9px;
1501
+ color: var(--color-gold);
1502
+ }
1503
+
1504
+ .pipeline-status {
1505
+ font-family: var(--font-pixel);
1506
+ font-size: 8px;
1507
+ color: var(--color-cyan);
1508
+ }
1509
+
1510
+ .pipeline-steps {
1511
+ display: flex;
1512
+ align-items: center;
1513
+ justify-content: space-between;
1514
+ gap: 6px;
1515
+ }
1516
+
1517
+ .pipeline-step {
1518
+ flex: 1;
1519
+ background: #111526;
1520
+ border: 1px solid var(--border-color);
1521
+ padding: 8px 6px;
1522
+ text-align: center;
1523
+ transition: all 0.3s ease;
1524
+ }
1525
+
1526
+ .pipeline-step.active {
1527
+ border-color: var(--color-gold);
1528
+ background: #1a1e36;
1529
+ box-shadow: 0 0 10px rgba(255, 215, 0, 0.2);
1530
+ }
1531
+
1532
+ .pipeline-step.completed {
1533
+ border-color: var(--color-green);
1534
+ background: #0d1e16;
1535
+ }
1536
+
1537
+ .step-icon { font-size: 16px; margin-bottom: 4px; }
1538
+ .step-label { font-family: var(--font-pixel); font-size: 7px; color: var(--text-main); margin-bottom: 2px; }
1539
+ .step-desc { font-family: var(--font-terminal); font-size: 11px; color: var(--text-dim); }
1540
+
1541
+ .pipeline-arrow {
1542
+ color: var(--text-dim);
1543
+ font-family: var(--font-pixel);
1544
+ font-size: 10px;
1545
+ }
1546
+
1547
+ /* Results & Scorecard */
1548
+ .oneshot-results-grid {
1549
+ display: grid;
1550
+ grid-template-columns: 360px 1fr;
1551
+ gap: 16px;
1552
+ }
1553
+
1554
+ .visual-scorecard-panel {
1555
+ background: #080a14;
1556
+ border: 2px solid var(--color-magenta);
1557
+ padding: 14px;
1558
+ }
1559
+
1560
+ .scorecard-header {
1561
+ display: flex;
1562
+ justify-content: space-between;
1563
+ align-items: center;
1564
+ margin-bottom: 14px;
1565
+ border-bottom: 1px solid #ff007f33;
1566
+ padding-bottom: 8px;
1567
+ }
1568
+
1569
+ .score-title { font-family: var(--font-pixel); font-size: 9px; color: var(--color-magenta); }
1570
+ .score-badge { font-family: var(--font-pixel); font-size: 11px; color: var(--color-green); background: #0c1a14; padding: 3px 8px; border: 1px solid var(--color-green); }
1571
+
1572
+ .rubric-meters {
1573
+ display: flex;
1574
+ flex-direction: column;
1575
+ gap: 8px;
1576
+ }
1577
+
1578
+ .rubric-row {
1579
+ display: flex;
1580
+ flex-direction: column;
1581
+ gap: 2px;
1582
+ }
1583
+
1584
+ .rubric-label-bar {
1585
+ display: flex;
1586
+ justify-content: space-between;
1587
+ font-family: var(--font-pixel);
1588
+ font-size: 7px;
1589
+ color: var(--text-dim);
1590
+ }
1591
+
1592
+ .rubric-bar-bg {
1593
+ width: 100%;
1594
+ height: 6px;
1595
+ background: #15192c;
1596
+ border: 1px solid #000;
1597
+ }
1598
+
1599
+ .rubric-bar-fill {
1600
+ height: 100%;
1601
+ background: var(--color-cyan);
1602
+ }
1603
+
1604
+ .oneshot-preview-panel {
1605
+ background: #080a14;
1606
+ border: 2px solid var(--border-color);
1607
+ display: flex;
1608
+ flex-direction: column;
1609
+ }
1610
+
1611
+ .preview-header {
1612
+ display: flex;
1613
+ justify-content: space-between;
1614
+ align-items: center;
1615
+ padding: 8px 12px;
1616
+ background: #111526;
1617
+ border-bottom: 1px solid var(--border-color);
1618
+ }
1619
+
1620
+ .preview-title { font-family: var(--font-pixel); font-size: 8px; color: var(--text-main); }
1621
+
1622
+ .preview-iframe-wrapper {
1623
+ flex: 1;
1624
+ min-height: 280px;
1625
+ }
1626
+
1627
+ .site-preview-iframe {
1628
+ width: 100%;
1629
+ height: 100%;
1630
+ min-height: 280px;
1631
+ border: none;
1632
+ background: #0b0c10;
1633
+ }
1634
+
1635
+ @media (max-width: 900px) {
1636
+ .oneshot-top-grid { grid-template-columns: 1fr; }
1637
+ .oneshot-results-grid { grid-template-columns: 1fr; }
1638
+ .pipeline-steps { flex-direction: column; }
1639
+ .pipeline-arrow { transform: rotate(90deg); }
1640
+ }
1641
+