chenglu commited on
Commit
90ce608
Β·
verified Β·
1 Parent(s): 74337ab

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +282 -256
app.py CHANGED
@@ -110,26 +110,27 @@ html, body {
110
  }
111
 
112
  /* ========================================
113
- Cards & Groups - Consistent with About Section
114
  ======================================== */
115
  .group {
116
  background: var(--bg-card) !important;
117
  border: 1px solid var(--border-color) !important;
118
- border-radius: 20px !important;
119
- padding: 32px !important;
120
  margin-bottom: 24px !important;
121
- box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06) !important;
122
- backdrop-filter: none !important;
123
  transition: var(--transition);
124
  }
125
 
126
  .group:hover {
127
- box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05), 0 0 40px rgba(139, 92, 246, 0.15) !important;
 
128
  }
129
 
130
  .dark .group {
131
- background: var(--bg-card) !important;
132
- border: 1px solid var(--border-color) !important;
133
  }
134
 
135
  /* ========================================
@@ -198,15 +199,16 @@ button.secondary:hover {
198
  Tabs - Premium Look
199
  ======================================== */
200
  .tabs {
201
- background: transparent !important;
202
  border: 1px solid var(--border-color) !important;
203
- border-radius: 16px !important;
204
  overflow: hidden !important;
205
- box-shadow: none !important;
206
  }
207
 
208
  .dark .tabs {
209
- border-color: var(--border-color) !important;
 
210
  }
211
 
212
  .tab-nav {
@@ -241,24 +243,24 @@ button.secondary:hover {
241
 
242
  .tabitem {
243
  background: var(--bg-secondary) !important;
244
- padding: 24px !important;
245
  }
246
 
247
  /* ========================================
248
  Accordion - Expandable Sections
249
  ======================================== */
250
  .accordion {
251
- background: var(--bg-tertiary) !important;
252
  border: 1px solid var(--border-color) !important;
253
- border-radius: 14px !important;
254
- margin-top: 16px !important;
255
  overflow: hidden !important;
256
  transition: var(--transition);
257
  }
258
 
259
  .dark .accordion {
260
- background: var(--bg-tertiary) !important;
261
- border: 1px solid rgba(249, 115, 22, 0.2) !important;
262
  }
263
 
264
  .accordion:hover {
@@ -382,30 +384,6 @@ button.secondary:hover {
382
  padding: 0 !important;
383
  }
384
 
385
- /* Header Row - Remove any background and styling */
386
- .header-row,
387
- .header-row > *,
388
- .header-column,
389
- .header-column > * {
390
- background: transparent !important;
391
- background-color: transparent !important;
392
- border: none !important;
393
- box-shadow: none !important;
394
- padding: 0 !important;
395
- margin: 0 !important;
396
- }
397
-
398
- /* Remove default Gradio block backgrounds for header area */
399
- .header-row .block,
400
- .header-row .panel,
401
- .header-column .block,
402
- .header-column .panel {
403
- background: transparent !important;
404
- background-color: transparent !important;
405
- border: none !important;
406
- box-shadow: none !important;
407
- }
408
-
409
  /* Container max width */
410
  .gradio-container > .main {
411
  padding: 0 !important;
@@ -432,10 +410,100 @@ button.secondary:hover {
432
  }
433
 
434
  /* ========================================
435
- Custom Card Classes - Matching About Section Style
436
  ======================================== */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
437
 
438
- /* Base card styling - matching About section exactly */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
439
  .command-center-card,
440
  .pipeline-status-card,
441
  .campaign-output-card {
@@ -445,60 +513,44 @@ button.secondary:hover {
445
  padding: 32px !important;
446
  margin-bottom: 24px !important;
447
  box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06) !important;
448
- transition: all 0.3s ease !important;
449
  }
450
 
451
  .command-center-card:hover,
452
  .pipeline-status-card:hover,
453
  .campaign-output-card:hover {
454
- box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05), 0 0 40px rgba(139, 92, 246, 0.15) !important;
455
  }
456
 
457
- /* Dark mode - matching About section dark styling */
458
  .dark .command-center-card,
459
  .dark .pipeline-status-card,
460
- .dark .campaign-output-card,
461
- [data-theme="dark"] .command-center-card,
462
- [data-theme="dark"] .pipeline-status-card,
463
- [data-theme="dark"] .campaign-output-card {
464
  background: var(--bg-card, #1c1c1f) !important;
465
- border: 1px solid var(--border-color, #27272a) !important;
466
- box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.4) !important;
467
- }
468
-
469
- /* Command Center - Purple accent in dark mode */
470
- .dark .command-center-card,
471
- [data-theme="dark"] .command-center-card {
472
- border-color: rgba(139, 92, 246, 0.2) !important;
473
  }
474
 
475
- /* Pipeline Status - Green accent in dark mode */
476
- .dark .pipeline-status-card,
477
- [data-theme="dark"] .pipeline-status-card {
478
- border-color: rgba(34, 197, 94, 0.2) !important;
 
479
  }
480
 
481
- /* Campaign Output - Cyan/Green accent in dark mode */
482
- .dark .campaign-output-card,
483
- [data-theme="dark"] .campaign-output-card {
484
- border-color: rgba(6, 182, 212, 0.2) !important;
485
  }
486
 
487
- /* Override default Gradio group styles for our custom cards */
488
- .command-center-card.group,
489
- .pipeline-status-card.group,
490
- .campaign-output-card.group {
491
- background: var(--bg-card, #ffffff) !important;
492
- border: 1px solid var(--border-color, #e4e4e7) !important;
493
- border-radius: 20px !important;
494
- padding: 32px !important;
495
- backdrop-filter: none !important;
496
  }
497
 
498
- .dark .command-center-card.group,
499
- .dark .pipeline-status-card.group,
500
- .dark .campaign-output-card.group {
501
- background: var(--bg-card, #1c1c1f) !important;
502
  }
503
 
504
  /* Terminal content styling */
@@ -514,49 +566,81 @@ button.secondary:hover {
514
  line-height: 1.6 !important;
515
  }
516
 
517
- .dark .terminal-content,
518
- [data-theme="dark"] .terminal-content {
519
- background: var(--bg-tertiary, #27272a) !important;
520
- border-color: var(--border-color, #3f3f46) !important;
521
  }
522
 
523
- /* Ensure tabs inside campaign output card match styling */
524
  .campaign-output-card .tabs {
525
  background: transparent !important;
526
- border: 1px solid var(--border-color, #e4e4e7) !important;
527
- border-radius: 16px !important;
528
- overflow: hidden !important;
529
  box-shadow: none !important;
 
530
  }
531
 
532
  .campaign-output-card .tab-nav {
533
  background: var(--bg-tertiary, #f5f5f5) !important;
534
- border-bottom: 1px solid var(--border-color, #e4e4e7) !important;
535
- padding: 12px 16px !important;
 
 
 
536
  }
537
 
538
- .dark .campaign-output-card .tabs,
539
- [data-theme="dark"] .campaign-output-card .tabs {
540
- border-color: var(--border-color, #3f3f46) !important;
541
  }
542
 
543
- .dark .campaign-output-card .tab-nav,
544
- [data-theme="dark"] .campaign-output-card .tab-nav {
545
- background: var(--bg-tertiary, #27272a) !important;
546
- border-color: var(--border-color, #3f3f46) !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
547
  }
548
 
549
  .campaign-output-card .tabitem {
550
- background: var(--bg-secondary, #ffffff) !important;
 
 
551
  padding: 24px !important;
 
552
  }
553
 
554
- .dark .campaign-output-card .tabitem,
555
- [data-theme="dark"] .campaign-output-card .tabitem {
556
- background: var(--bg-secondary, #18181b) !important;
557
  }
558
 
559
- /* Form elements inside cards - consistent styling */
 
 
 
 
 
 
 
 
 
 
 
560
  .command-center-card input,
561
  .command-center-card textarea,
562
  .command-center-card select {
@@ -568,11 +652,11 @@ button.secondary:hover {
568
  .dark .command-center-card input,
569
  .dark .command-center-card textarea,
570
  .dark .command-center-card select {
571
- background: var(--bg-tertiary, #27272a) !important;
572
- border-color: var(--border-color, #3f3f46) !important;
573
  }
574
 
575
- /* Accordion inside command center - matching style */
576
  .command-center-card .accordion {
577
  background: var(--bg-tertiary, #f5f5f5) !important;
578
  border: 1px solid var(--border-color, #e4e4e7) !important;
@@ -581,105 +665,51 @@ button.secondary:hover {
581
  }
582
 
583
  .dark .command-center-card .accordion {
584
- background: var(--bg-tertiary, #27272a) !important;
585
- border-color: rgba(249, 115, 22, 0.2) !important;
586
- }
587
-
588
- /* Button row spacing */
589
- .command-center-card .row {
590
- margin-top: 20px !important;
591
- }
592
-
593
- /* ========================================
594
- Special Elements
595
- ======================================== */
596
- /* Hero section styling */
597
- .hero-card {
598
- background: linear-gradient(145deg, var(--bg-card), var(--bg-secondary)) !important;
599
- border: 1px solid var(--border-color) !important;
600
  }
601
 
602
- .dark .hero-card {
603
- background: linear-gradient(145deg, rgba(28, 28, 31, 0.9), rgba(18, 18, 20, 0.9)) !important;
604
- border: 1px solid rgba(139, 92, 246, 0.2) !important;
605
- }
606
-
607
- /* Terminal styling */
608
- .terminal-header {
609
- background: linear-gradient(90deg, var(--bg-tertiary), var(--bg-secondary)) !important;
610
- }
611
-
612
- .dark .terminal-header {
613
- background: linear-gradient(90deg, rgba(28, 28, 31, 0.9), rgba(24, 24, 27, 0.9)) !important;
614
- }
615
-
616
- /* Status indicator */
617
- .status-online {
618
- width: 10px;
619
- height: 10px;
620
- border-radius: 50%;
621
- background: var(--accent-green);
622
- animation: pulse 2s infinite;
623
- box-shadow: 0 0 10px var(--accent-green);
624
- }
625
-
626
- /* Badge styling */
627
- .badge {
628
- display: inline-flex;
629
- align-items: center;
630
- padding: 6px 14px;
631
- border-radius: 20px;
632
- font-size: 12px;
633
- font-weight: 600;
634
- transition: var(--transition);
635
  }
636
 
637
- .badge-purple {
638
- background: var(--accent-purple-light);
639
- color: var(--accent-purple);
640
- border: 1px solid rgba(139, 92, 246, 0.3);
641
- }
642
-
643
- .badge-green {
644
- background: var(--accent-green-light);
645
- color: var(--accent-green);
646
- border: 1px solid rgba(34, 197, 94, 0.3);
647
- }
648
-
649
- .badge-orange {
650
- background: var(--accent-orange-light);
651
- color: var(--accent-orange);
652
- border: 1px solid rgba(249, 115, 22, 0.3);
653
  }
654
 
655
- /* Feature card */
656
- .feature-card {
657
- background: var(--bg-secondary) !important;
658
- border: 1px solid var(--border-color) !important;
659
- border-radius: var(--radius-lg) !important;
660
- padding: 16px !important;
661
- transition: var(--transition);
662
  }
663
 
664
- .feature-card:hover {
665
- transform: translateY(-3px);
666
- box-shadow: var(--shadow-md);
667
- border-color: var(--accent-purple) !important;
 
 
 
 
668
  }
669
 
670
- /* Icon box */
671
- .icon-box {
672
- width: 44px;
673
- height: 44px;
674
- border-radius: var(--radius-md);
675
- display: flex;
676
- align-items: center;
677
- justify-content: center;
678
- transition: var(--transition);
679
  }
680
 
681
- .icon-box:hover {
682
- transform: scale(1.1);
 
 
683
  }
684
  """
685
 
@@ -722,7 +752,7 @@ def format_logs() -> str:
722
  for log in current_job["logs"]:
723
  color = color_map.get(log["color"], "var(--text-primary, #18181b)")
724
  lines.append(
725
- f'<div style="margin: 6px 0; padding: 4px 10px;">'
726
  f'<span style="color: var(--text-muted, #71717a);">β€Ί</span> '
727
  f'<span style="color: {color}; font-weight: 600;">[{log["agent"]}]</span> '
728
  f'<span style="color: var(--text-secondary, #52525b);">{log["message"]}</span>'
@@ -733,20 +763,20 @@ def format_logs() -> str:
733
 
734
  def get_progress_html(progress: int, status: str) -> str:
735
  """Generate progress bar HTML."""
736
- status_styles = {
737
- "idle": ("#71717a", "linear-gradient(135deg, rgba(113, 113, 122, 0.15), rgba(113, 113, 122, 0.05))", "rgba(113, 113, 122, 0.25)"),
738
- "analyzing": ("#8b5cf6", "linear-gradient(135deg, rgba(139, 92, 246, 0.15), rgba(139, 92, 246, 0.05))", "rgba(139, 92, 246, 0.25)"),
739
- "generating": ("#22c55e", "linear-gradient(135deg, rgba(34, 197, 94, 0.15), rgba(34, 197, 94, 0.05))", "rgba(34, 197, 94, 0.25)"),
740
- "completed": ("#22c55e", "linear-gradient(135deg, rgba(34, 197, 94, 0.15), rgba(34, 197, 94, 0.05))", "rgba(34, 197, 94, 0.25)"),
741
- "failed": ("#ef4444", "linear-gradient(135deg, rgba(239, 68, 68, 0.15), rgba(239, 68, 68, 0.05))", "rgba(239, 68, 68, 0.25)"),
742
  }
743
- text_color, bg_gradient, border_color = status_styles.get(status, status_styles["idle"])
744
 
745
  return f"""
746
- <div style="margin-bottom: 24px; padding: 10px;">
747
- <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px;">
748
- <span style="color: #8b5cf6; font-weight: 600; font-size: 14px; padding-left: 10px;">Pipeline Status</span>
749
- <span style="color: {text_color}; font-size: 13px; padding: 8px 16px; background: {bg_gradient}; border: 1px solid {border_color}; border-radius: 20px; font-weight: 600; text-transform: capitalize;">{status}</span>
750
  </div>
751
  <div style="width: 100%; height: 10px; background: var(--bg-tertiary, #f5f5f5); border-radius: 5px; overflow: hidden; border: 1px solid var(--border-color, #e4e4e7);">
752
  <div style="width: {progress}%; height: 100%; background: linear-gradient(90deg, #8b5cf6, #22c55e); transition: width 0.4s cubic-bezier(0.4, 0, 0.2, 1); border-radius: 5px;"></div>
@@ -1228,7 +1258,7 @@ def create_app():
1228
  panel_background_fill_dark="#1c1c1f",
1229
  # Borders
1230
  block_border_color="#e4e4e7",
1231
- block_border_color_dark="#27272a",
1232
  border_color_primary="#8b5cf6",
1233
  border_color_primary_dark="#a78bfa",
1234
  # Inputs
@@ -1258,7 +1288,7 @@ def create_app():
1258
  block_shadow="0 4px 6px -1px rgba(0, 0, 0, 0.1)",
1259
  block_shadow_dark="0 4px 6px -1px rgba(0, 0, 0, 0.4)",
1260
  # Radius
1261
- block_radius="20px",
1262
  button_large_radius="12px",
1263
  button_small_radius="8px",
1264
  )
@@ -1278,22 +1308,22 @@ def create_app():
1278
  app.theme = custom_theme
1279
  app.css = CUSTOM_CSS
1280
  app.js = DARK_MODE_JS
1281
- # Header - Clean, no background
1282
- with gr.Row(elem_classes=["header-row"]):
1283
- with gr.Column(elem_classes=["header-column"]):
1284
  gr.HTML(
1285
  """
1286
- <div style="display: flex; align-items: center; justify-content: space-between; padding: 24px 0; margin-bottom: 24px;">
1287
  <div style="display: flex; align-items: center; gap: 16px;">
1288
- <div style="width: 56px; height: 56px; background: linear-gradient(135deg, rgba(139, 92, 246, 0.2), rgba(34, 197, 94, 0.1)); border: 1px solid rgba(139, 92, 246, 0.3); border-radius: 16px; display: flex; align-items: center; justify-content: center; box-shadow: 0 0 30px rgba(139, 92, 246, 0.15);">
1289
- <span style="font-size: 28px;">✨</span>
1290
  </div>
1291
  <div>
1292
- <h1 style="margin: 0; background: linear-gradient(135deg, #8b5cf6, #22c55e); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; font-size: 32px; font-weight: 800; letter-spacing: -0.5px;">DevRel Campaign Generator</h1>
1293
- <p style="margin: 6px 0 0 0; color: var(--text-muted, #71717a); font-size: 14px;">AI-Powered Content for Developer Relations</p>
1294
  </div>
1295
  </div>
1296
- <div style="display: flex; align-items: center; gap: 10px; padding: 10px 18px; background: linear-gradient(135deg, rgba(34, 197, 94, 0.15), rgba(34, 197, 94, 0.05)); border: 1px solid rgba(34, 197, 94, 0.25); border-radius: 24px;">
1297
  <div style="width: 10px; height: 10px; border-radius: 50%; background: #22c55e; animation: pulse 2s infinite; box-shadow: 0 0 12px rgba(34, 197, 94, 0.6);"></div>
1298
  <span style="font-size: 13px; font-weight: 600; color: #22c55e;">System Online</span>
1299
  </div>
@@ -1312,7 +1342,7 @@ def create_app():
1312
  with gr.Column():
1313
  gr.HTML(
1314
  """
1315
- <div style="background: var(--bg-card, #ffffff); border: 1px solid var(--border-color, #e4e4e7); border-radius: 20px; padding: 32px; margin-bottom: 24px; box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); transition: all 0.3s ease;">
1316
  <!-- Header -->
1317
  <div style="display: flex; align-items: flex-start; justify-content: space-between; margin-bottom: 24px;">
1318
  <div style="display: flex; align-items: center; gap: 16px;">
@@ -1428,15 +1458,13 @@ def create_app():
1428
  with gr.Group(elem_classes=["command-center-card"]):
1429
  gr.HTML(
1430
  """
1431
- <div style="display: flex; align-items: flex-start; justify-content: space-between; margin-bottom: 24px;">
1432
- <div style="display: flex; align-items: center; gap: 16px; padding: 15px;">
1433
- <div style="width: 56px; height: 56px; background: linear-gradient(135deg, rgba(139, 92, 246, 0.2), rgba(139, 92, 246, 0.05)); border: 1px solid rgba(139, 92, 246, 0.3); border-radius: 16px; display: flex; align-items: center; justify-content: center; box-shadow: 0 0 30px rgba(139, 92, 246, 0.15);">
1434
- <span style="font-size: 28px;">πŸ™</span>
1435
- </div>
1436
- <div>
1437
- <h2 style="margin: 0; font-size: 24px; font-weight: 700; color: var(--text-primary, #18181b);">Command Center</h2>
1438
- <p style="margin: 6px 0 0 0; color: var(--text-muted, #71717a); font-size: 14px;">Configure and launch your campaign</p>
1439
- </div>
1440
  </div>
1441
  </div>
1442
  """
@@ -1463,7 +1491,7 @@ def create_app():
1463
  # Settings Accordion for API Keys
1464
  with gr.Accordion("βš™οΈ Settings (API Keys)", open=False):
1465
  gr.HTML(
1466
- '<div style="padding: 12px 0; color: var(--text-muted, #71717a); font-size: 14px;">πŸ’‘ Add your own API keys if the default quota is exhausted</div>'
1467
  )
1468
  anthropic_key = gr.Textbox(
1469
  label="Anthropic API Key (Claude)",
@@ -1478,7 +1506,7 @@ def create_app():
1478
  lines=1,
1479
  )
1480
  gr.HTML(
1481
- '''<div style="padding: 12px 0; color: var(--text-muted, #71717a); font-size: 14px;">
1482
  <p style="margin: 0 0 8px 0;">πŸ”‘ <a href="https://console.anthropic.com" target="_blank" style="color: #8b5cf6; text-decoration: none; font-weight: 500;">Get Anthropic API Key β†’</a></p>
1483
  <p style="margin: 0;">πŸ”‘ <a href="https://github.com/settings/tokens" target="_blank" style="color: #22c55e; text-decoration: none; font-weight: 500;">Get GitHub Token β†’</a></p>
1484
  </div>'''
@@ -1496,15 +1524,13 @@ def create_app():
1496
  with gr.Group(elem_classes=["pipeline-status-card"]):
1497
  gr.HTML(
1498
  """
1499
- <div style="display: flex; align-items: flex-start; justify-content: space-between; margin-bottom: 24px;">
1500
- <div style="display: flex; align-items: center; gap: 16px; padding: 10px;">
1501
- <div style="width: 56px; height: 56px; background: linear-gradient(135deg, rgba(34, 197, 94, 0.2), rgba(34, 197, 94, 0.05)); border: 1px solid rgba(34, 197, 94, 0.3); border-radius: 16px; display: flex; align-items: center; justify-content: center; box-shadow: 0 0 30px rgba(34, 197, 94, 0.15);">
1502
- <span style="font-size: 28px;">πŸ“Š</span>
1503
- </div>
1504
- <div>
1505
- <h2 style="margin: 0; font-size: 24px; font-weight: 700; color: var(--text-primary, #18181b);">Pipeline Status</h2>
1506
- <p style="margin: 6px 0 0 0; color: var(--text-muted, #71717a); font-size: 14px;">Real-time generation progress</p>
1507
- </div>
1508
  </div>
1509
  </div>
1510
  """
@@ -1516,8 +1542,8 @@ def create_app():
1516
  # Event Log Section Header
1517
  gr.HTML(
1518
  """
1519
- <div style="padding-top: 0px; padding-left: 20px; border-top: 1px solid var(--border-color, #e4e4e7); margin-top: 14px;">
1520
- <div style="display: flex; align-items: center; justify-content: space-between; margin-bottom: 16px;">
1521
  <div style="display: flex; align-items: center; gap: 12px;">
1522
  <div style="display: flex; gap: 6px;">
1523
  <div style="width: 12px; height: 12px; border-radius: 50%; background: linear-gradient(135deg, #ef4444, #dc2626); box-shadow: 0 0 6px rgba(239, 68, 68, 0.4);"></div>
@@ -1526,9 +1552,9 @@ def create_app():
1526
  </div>
1527
  <span style="font-weight: 600; color: var(--text-primary, #18181b); font-size: 14px;">Event Log</span>
1528
  </div>
1529
- <div style="margin: 10px; display: flex; align-items: center; gap: 6px; padding: 6px 14px; background: linear-gradient(135deg, rgba(34, 197, 94, 0.15), rgba(34, 197, 94, 0.05)); border: 1px solid rgba(34, 197, 94, 0.25); border-radius: 20px;">
1530
  <div style="width: 6px; height: 6px; border-radius: 50%; background: #22c55e; animation: pulse 2s infinite; box-shadow: 0 0 8px rgba(34, 197, 94, 0.6);"></div>
1531
- <span style="color: #22c55e; font-size: 13px; font-weight: 600;">LIVE</span>
1532
  </div>
1533
  </div>
1534
  </div>
@@ -1544,12 +1570,12 @@ def create_app():
1544
  # Footer
1545
  gr.HTML(
1546
  """
1547
- <div style="display: flex; align-items: center; justify-content: space-between; padding-left: 10px; padding-top: 16px; border-top: 1px solid var(--border-color, #e4e4e7); margin-top: 14px;">
1548
- <div style="display: flex; align-items: center; gap: 12px; padding: 10px;">
1549
- <span style="color: var(--text-muted, #71717a); font-size: 14px;">Powered by:</span>
1550
- <span style="background: linear-gradient(135deg, rgba(139, 92, 246, 0.15), rgba(139, 92, 246, 0.05)); color: #8b5cf6; padding: 8px 16px; border-radius: 20px; font-weight: 600; font-size: 13px; border: 1px solid rgba(139, 92, 246, 0.25);">Claude</span>
1551
- <span style="color: var(--text-muted, #71717a); font-size: 14px;">Γ—</span>
1552
- <span style="background: linear-gradient(135deg, rgba(249, 115, 22, 0.15), rgba(249, 115, 22, 0.05)); color: #f97316; padding: 8px 16px; border-radius: 20px; font-weight: 600; font-size: 13px; border: 1px solid rgba(249, 115, 22, 0.25);">Gradio 6</span>
1553
  </div>
1554
  </div>
1555
  """
@@ -1561,18 +1587,18 @@ def create_app():
1561
  with gr.Group(elem_classes=["campaign-output-card"]):
1562
  gr.HTML(
1563
  """
1564
- <div style="display: flex; align-items: flex-start; justify-content: space-between; margin-bottom: 24px;">
1565
- <div style="display: flex; align-items: center; gap: 16px; padding: 15px;">
1566
- <div style="width: 56px; height: 56px; background: linear-gradient(135deg, rgba(34, 197, 94, 0.2), rgba(6, 182, 212, 0.1)); border: 1px solid rgba(34, 197, 94, 0.3); border-radius: 16px; display: flex; align-items: center; justify-content: center; box-shadow: 0 0 30px rgba(34, 197, 94, 0.15);">
1567
- <span style="font-size: 28px;">πŸ“€</span>
1568
  </div>
1569
  <div>
1570
- <h2 style="margin: 0; font-size: 24px; font-weight: 700; color: var(--text-primary, #18181b);">Campaign Output</h2>
1571
- <p style="margin: 6px 0 0 0; color: var(--text-muted, #71717a); font-size: 14px;">Generated content for all platforms</p>
1572
  </div>
1573
  </div>
1574
- <div style="display: flex; gap: 10px; padding: 20px;">
1575
- <span style="background: linear-gradient(135deg, rgba(34, 197, 94, 0.15), rgba(34, 197, 94, 0.05)); color: #22c55e; padding: 8px 16px; border-radius: 20px; font-size: 13px; font-weight: 600; border: 1px solid rgba(34, 197, 94, 0.25);">6 Formats</span>
1576
  </div>
1577
  </div>
1578
  """
@@ -1660,8 +1686,8 @@ if __name__ == "__main__":
1660
  app = create_app()
1661
  app.launch(
1662
  server_name="0.0.0.0",
1663
- server_port=7865,
1664
- share=True,
1665
  show_error=True,
1666
  ssr_mode=False, # Disable experimental SSR to avoid potential issues
1667
  )
 
110
  }
111
 
112
  /* ========================================
113
+ Cards & Groups - Glass Morphism Style
114
  ======================================== */
115
  .group {
116
  background: var(--bg-card) !important;
117
  border: 1px solid var(--border-color) !important;
118
+ border-radius: var(--radius-xl) !important;
119
+ padding: 28px !important;
120
  margin-bottom: 24px !important;
121
+ box-shadow: var(--shadow-md) !important;
122
+ backdrop-filter: blur(10px) !important;
123
  transition: var(--transition);
124
  }
125
 
126
  .group:hover {
127
+ box-shadow: var(--shadow-lg), var(--shadow-glow) !important;
128
+ transform: translateY(-2px);
129
  }
130
 
131
  .dark .group {
132
+ background: linear-gradient(145deg, var(--bg-card) 0%, rgba(28, 28, 31, 0.8) 100%) !important;
133
+ border: 1px solid rgba(139, 92, 246, 0.15) !important;
134
  }
135
 
136
  /* ========================================
 
199
  Tabs - Premium Look
200
  ======================================== */
201
  .tabs {
202
+ background: var(--bg-card) !important;
203
  border: 1px solid var(--border-color) !important;
204
+ border-radius: var(--radius-xl) !important;
205
  overflow: hidden !important;
206
+ box-shadow: var(--shadow-md) !important;
207
  }
208
 
209
  .dark .tabs {
210
+ background: linear-gradient(145deg, var(--bg-card) 0%, rgba(28, 28, 31, 0.9) 100%) !important;
211
+ border: 1px solid rgba(74, 222, 128, 0.15) !important;
212
  }
213
 
214
  .tab-nav {
 
243
 
244
  .tabitem {
245
  background: var(--bg-secondary) !important;
246
+ padding: 28px !important;
247
  }
248
 
249
  /* ========================================
250
  Accordion - Expandable Sections
251
  ======================================== */
252
  .accordion {
253
+ background: var(--bg-card) !important;
254
  border: 1px solid var(--border-color) !important;
255
+ border-radius: var(--radius-lg) !important;
256
+ margin-top: 20px !important;
257
  overflow: hidden !important;
258
  transition: var(--transition);
259
  }
260
 
261
  .dark .accordion {
262
+ background: linear-gradient(145deg, rgba(28, 28, 31, 0.8), rgba(39, 39, 42, 0.5)) !important;
263
+ border: 1px solid rgba(249, 115, 22, 0.15) !important;
264
  }
265
 
266
  .accordion:hover {
 
384
  padding: 0 !important;
385
  }
386
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
387
  /* Container max width */
388
  .gradio-container > .main {
389
  padding: 0 !important;
 
410
  }
411
 
412
  /* ========================================
413
+ Special Elements
414
  ======================================== */
415
+ /* Hero section styling */
416
+ .hero-card {
417
+ background: linear-gradient(145deg, var(--bg-card), var(--bg-secondary)) !important;
418
+ border: 1px solid var(--border-color) !important;
419
+ }
420
+
421
+ .dark .hero-card {
422
+ background: linear-gradient(145deg, rgba(28, 28, 31, 0.9), rgba(18, 18, 20, 0.9)) !important;
423
+ border: 1px solid rgba(139, 92, 246, 0.2) !important;
424
+ }
425
+
426
+ /* Terminal styling */
427
+ .terminal-header {
428
+ background: linear-gradient(90deg, var(--bg-tertiary), var(--bg-secondary)) !important;
429
+ }
430
+
431
+ .dark .terminal-header {
432
+ background: linear-gradient(90deg, rgba(28, 28, 31, 0.9), rgba(24, 24, 27, 0.9)) !important;
433
+ }
434
+
435
+ /* Status indicator */
436
+ .status-online {
437
+ width: 10px;
438
+ height: 10px;
439
+ border-radius: 50%;
440
+ background: var(--accent-green);
441
+ animation: pulse 2s infinite;
442
+ box-shadow: 0 0 10px var(--accent-green);
443
+ }
444
+
445
+ /* Badge styling */
446
+ .badge {
447
+ display: inline-flex;
448
+ align-items: center;
449
+ padding: 6px 14px;
450
+ border-radius: 20px;
451
+ font-size: 12px;
452
+ font-weight: 600;
453
+ transition: var(--transition);
454
+ }
455
+
456
+ .badge-purple {
457
+ background: var(--accent-purple-light);
458
+ color: var(--accent-purple);
459
+ border: 1px solid rgba(139, 92, 246, 0.3);
460
+ }
461
+
462
+ .badge-green {
463
+ background: var(--accent-green-light);
464
+ color: var(--accent-green);
465
+ border: 1px solid rgba(34, 197, 94, 0.3);
466
+ }
467
+
468
+ .badge-orange {
469
+ background: var(--accent-orange-light);
470
+ color: var(--accent-orange);
471
+ border: 1px solid rgba(249, 115, 22, 0.3);
472
+ }
473
 
474
+ /* Feature card */
475
+ .feature-card {
476
+ background: var(--bg-secondary) !important;
477
+ border: 1px solid var(--border-color) !important;
478
+ border-radius: var(--radius-lg) !important;
479
+ padding: 16px !important;
480
+ transition: var(--transition);
481
+ }
482
+
483
+ .feature-card:hover {
484
+ transform: translateY(-3px);
485
+ box-shadow: var(--shadow-md);
486
+ border-color: var(--accent-purple) !important;
487
+ }
488
+
489
+ /* Icon box */
490
+ .icon-box {
491
+ width: 44px;
492
+ height: 44px;
493
+ border-radius: var(--radius-md);
494
+ display: flex;
495
+ align-items: center;
496
+ justify-content: center;
497
+ transition: var(--transition);
498
+ }
499
+
500
+ .icon-box:hover {
501
+ transform: scale(1.1);
502
+ }
503
+
504
+ /* ========================================
505
+ Custom Card Classes - Matching About Section Style
506
+ ======================================== */
507
  .command-center-card,
508
  .pipeline-status-card,
509
  .campaign-output-card {
 
513
  padding: 32px !important;
514
  margin-bottom: 24px !important;
515
  box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06) !important;
516
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1) !important;
517
  }
518
 
519
  .command-center-card:hover,
520
  .pipeline-status-card:hover,
521
  .campaign-output-card:hover {
522
+ box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05), 0 0 40px rgba(139, 92, 246, 0.1) !important;
523
  }
524
 
525
+ /* Dark mode for all business cards */
526
  .dark .command-center-card,
527
  .dark .pipeline-status-card,
528
+ .dark .campaign-output-card {
 
 
 
529
  background: var(--bg-card, #1c1c1f) !important;
530
+ border: 1px solid rgba(139, 92, 246, 0.15) !important;
531
+ box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.4), 0 2px 4px -1px rgba(0, 0, 0, 0.3) !important;
 
 
 
 
 
 
532
  }
533
 
534
+ .dark .command-center-card:hover,
535
+ .dark .pipeline-status-card:hover,
536
+ .dark .campaign-output-card:hover {
537
+ box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.5), 0 4px 6px -2px rgba(0, 0, 0, 0.4), 0 0 60px rgba(139, 92, 246, 0.2) !important;
538
+ border-color: rgba(139, 92, 246, 0.25) !important;
539
  }
540
 
541
+ /* Command Center - Purple accent border on hover */
542
+ .command-center-card:hover {
543
+ border-color: rgba(139, 92, 246, 0.3) !important;
 
544
  }
545
 
546
+ /* Pipeline Status - Green accent border on hover */
547
+ .pipeline-status-card:hover {
548
+ border-color: rgba(34, 197, 94, 0.3) !important;
 
 
 
 
 
 
549
  }
550
 
551
+ /* Campaign Output - Cyan accent border on hover */
552
+ .campaign-output-card:hover {
553
+ border-color: rgba(6, 182, 212, 0.3) !important;
 
554
  }
555
 
556
  /* Terminal content styling */
 
566
  line-height: 1.6 !important;
567
  }
568
 
569
+ .dark .terminal-content {
570
+ background: rgba(39, 39, 42, 0.5) !important;
571
+ border-color: rgba(63, 63, 70, 0.5) !important;
 
572
  }
573
 
574
+ /* Tabs inside Campaign Output - matching card style */
575
  .campaign-output-card .tabs {
576
  background: transparent !important;
577
+ border: none !important;
 
 
578
  box-shadow: none !important;
579
+ margin-top: 0 !important;
580
  }
581
 
582
  .campaign-output-card .tab-nav {
583
  background: var(--bg-tertiary, #f5f5f5) !important;
584
+ border: 1px solid var(--border-color, #e4e4e7) !important;
585
+ border-radius: 14px !important;
586
+ padding: 8px !important;
587
+ gap: 6px !important;
588
+ margin-bottom: 16px !important;
589
  }
590
 
591
+ .dark .campaign-output-card .tab-nav {
592
+ background: rgba(39, 39, 42, 0.4) !important;
593
+ border-color: rgba(63, 63, 70, 0.4) !important;
594
  }
595
 
596
+ .campaign-output-card .tab-nav button {
597
+ background: transparent !important;
598
+ border: none !important;
599
+ border-radius: 10px !important;
600
+ color: var(--text-muted, #71717a) !important;
601
+ font-weight: 500 !important;
602
+ font-size: 13px !important;
603
+ padding: 10px 16px !important;
604
+ transition: all 0.2s ease !important;
605
+ }
606
+
607
+ .campaign-output-card .tab-nav button:hover {
608
+ background: rgba(139, 92, 246, 0.1) !important;
609
+ color: var(--accent-purple, #8b5cf6) !important;
610
+ }
611
+
612
+ .campaign-output-card .tab-nav button.selected {
613
+ background: linear-gradient(135deg, rgba(139, 92, 246, 0.15), rgba(34, 197, 94, 0.1)) !important;
614
+ color: var(--accent-purple, #8b5cf6) !important;
615
+ font-weight: 600 !important;
616
+ box-shadow: 0 2px 4px rgba(139, 92, 246, 0.15) !important;
617
  }
618
 
619
  .campaign-output-card .tabitem {
620
+ background: var(--bg-tertiary, #f5f5f5) !important;
621
+ border: 1px solid var(--border-color, #e4e4e7) !important;
622
+ border-radius: 14px !important;
623
  padding: 24px !important;
624
+ min-height: 300px !important;
625
  }
626
 
627
+ .dark .campaign-output-card .tabitem {
628
+ background: rgba(39, 39, 42, 0.3) !important;
629
+ border-color: rgba(63, 63, 70, 0.4) !important;
630
  }
631
 
632
+ /* Markdown content inside tabs */
633
+ .campaign-output-card .markdown {
634
+ color: var(--text-primary, #18181b) !important;
635
+ font-size: 14px !important;
636
+ line-height: 1.7 !important;
637
+ }
638
+
639
+ .dark .campaign-output-card .markdown {
640
+ color: var(--text-primary, #fafafa) !important;
641
+ }
642
+
643
+ /* Form elements inside cards */
644
  .command-center-card input,
645
  .command-center-card textarea,
646
  .command-center-card select {
 
652
  .dark .command-center-card input,
653
  .dark .command-center-card textarea,
654
  .dark .command-center-card select {
655
+ background: rgba(39, 39, 42, 0.5) !important;
656
+ border-color: rgba(63, 63, 70, 0.5) !important;
657
  }
658
 
659
+ /* Accordion styling inside cards */
660
  .command-center-card .accordion {
661
  background: var(--bg-tertiary, #f5f5f5) !important;
662
  border: 1px solid var(--border-color, #e4e4e7) !important;
 
665
  }
666
 
667
  .dark .command-center-card .accordion {
668
+ background: rgba(39, 39, 42, 0.4) !important;
669
+ border-color: rgba(249, 115, 22, 0.15) !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
670
  }
671
 
672
+ .command-center-card .accordion:hover {
673
+ border-color: rgba(249, 115, 22, 0.3) !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
674
  }
675
 
676
+ /* Buttons inside cards */
677
+ .command-center-card button.primary {
678
+ background: linear-gradient(135deg, #8b5cf6, #7c3aed) !important;
679
+ border: none !important;
680
+ border-radius: 12px !important;
681
+ color: white !important;
682
+ font-weight: 600 !important;
683
+ padding: 14px 24px !important;
684
+ box-shadow: 0 4px 6px rgba(139, 92, 246, 0.25), 0 0 20px rgba(139, 92, 246, 0.2) !important;
685
+ transition: all 0.3s ease !important;
 
 
 
 
 
 
686
  }
687
 
688
+ .command-center-card button.primary:hover {
689
+ transform: translateY(-2px) !important;
690
+ box-shadow: 0 6px 12px rgba(139, 92, 246, 0.35), 0 0 30px rgba(139, 92, 246, 0.3) !important;
 
 
 
 
691
  }
692
 
693
+ .command-center-card button.secondary {
694
+ background: var(--bg-tertiary, #f5f5f5) !important;
695
+ border: 1px solid var(--border-color, #e4e4e7) !important;
696
+ border-radius: 12px !important;
697
+ color: var(--text-secondary, #52525b) !important;
698
+ font-weight: 500 !important;
699
+ padding: 14px 24px !important;
700
+ transition: all 0.3s ease !important;
701
  }
702
 
703
+ .dark .command-center-card button.secondary {
704
+ background: rgba(39, 39, 42, 0.5) !important;
705
+ border-color: rgba(63, 63, 70, 0.5) !important;
706
+ color: var(--text-secondary, #a1a1aa) !important;
 
 
 
 
 
707
  }
708
 
709
+ .command-center-card button.secondary:hover {
710
+ background: var(--bg-secondary, #ffffff) !important;
711
+ border-color: var(--accent-purple, #8b5cf6) !important;
712
+ color: var(--accent-purple, #8b5cf6) !important;
713
  }
714
  """
715
 
 
752
  for log in current_job["logs"]:
753
  color = color_map.get(log["color"], "var(--text-primary, #18181b)")
754
  lines.append(
755
+ f'<div style="margin: 6px 0; padding: 4px 0;">'
756
  f'<span style="color: var(--text-muted, #71717a);">β€Ί</span> '
757
  f'<span style="color: {color}; font-weight: 600;">[{log["agent"]}]</span> '
758
  f'<span style="color: var(--text-secondary, #52525b);">{log["message"]}</span>'
 
763
 
764
  def get_progress_html(progress: int, status: str) -> str:
765
  """Generate progress bar HTML."""
766
+ status_colors = {
767
+ "idle": ("var(--text-muted, #71717a)", "var(--border-color, #e4e4e7)"),
768
+ "analyzing": ("#8b5cf6", "rgba(139, 92, 246, 0.2)"),
769
+ "generating": ("#22c55e", "rgba(34, 197, 94, 0.2)"),
770
+ "completed": ("#22c55e", "rgba(34, 197, 94, 0.2)"),
771
+ "failed": ("#ef4444", "rgba(239, 68, 68, 0.2)"),
772
  }
773
+ text_color, bg_color = status_colors.get(status, status_colors["idle"])
774
 
775
  return f"""
776
+ <div style="margin-bottom: 16px;">
777
+ <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">
778
+ <span style="color: #8b5cf6; font-weight: 600; font-size: 14px;">Pipeline Status</span>
779
+ <span style="color: {text_color}; font-size: 12px; padding: 4px 12px; background: {bg_color}; border: 1px solid {text_color}33; border-radius: 16px; font-weight: 500; text-transform: capitalize;">{status}</span>
780
  </div>
781
  <div style="width: 100%; height: 10px; background: var(--bg-tertiary, #f5f5f5); border-radius: 5px; overflow: hidden; border: 1px solid var(--border-color, #e4e4e7);">
782
  <div style="width: {progress}%; height: 100%; background: linear-gradient(90deg, #8b5cf6, #22c55e); transition: width 0.4s cubic-bezier(0.4, 0, 0.2, 1); border-radius: 5px;"></div>
 
1258
  panel_background_fill_dark="#1c1c1f",
1259
  # Borders
1260
  block_border_color="#e4e4e7",
1261
+ block_border_color_dark="rgba(139, 92, 246, 0.2)",
1262
  border_color_primary="#8b5cf6",
1263
  border_color_primary_dark="#a78bfa",
1264
  # Inputs
 
1288
  block_shadow="0 4px 6px -1px rgba(0, 0, 0, 0.1)",
1289
  block_shadow_dark="0 4px 6px -1px rgba(0, 0, 0, 0.4)",
1290
  # Radius
1291
+ block_radius="16px",
1292
  button_large_radius="12px",
1293
  button_small_radius="8px",
1294
  )
 
1308
  app.theme = custom_theme
1309
  app.css = CUSTOM_CSS
1310
  app.js = DARK_MODE_JS
1311
+ # Header
1312
+ with gr.Row():
1313
+ with gr.Column():
1314
  gr.HTML(
1315
  """
1316
+ <div style="display: flex; align-items: center; justify-content: space-between; padding: 20px 0; margin-bottom: 8px;">
1317
  <div style="display: flex; align-items: center; gap: 16px;">
1318
+ <div style="width: 52px; height: 52px; background: linear-gradient(135deg, rgba(139, 92, 246, 0.15), rgba(34, 197, 94, 0.1)); border: 1px solid rgba(139, 92, 246, 0.3); border-radius: 14px; display: flex; align-items: center; justify-content: center; box-shadow: 0 0 30px rgba(139, 92, 246, 0.2);">
1319
+ <span style="font-size: 26px;">✨</span>
1320
  </div>
1321
  <div>
1322
+ <h1 style="margin: 0; background: linear-gradient(135deg, #8b5cf6, #22c55e); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; font-size: 28px; font-weight: 800; letter-spacing: -0.5px;">DevRel Campaign Generator</h1>
1323
+ <p style="margin: 4px 0 0 0; color: var(--text-muted, #71717a); font-size: 14px;">AI-Powered Content for Developer Relations</p>
1324
  </div>
1325
  </div>
1326
+ <div style="display: flex; align-items: center; gap: 10px; padding: 10px 18px; background: rgba(34, 197, 94, 0.1); border: 1px solid rgba(34, 197, 94, 0.2); border-radius: 24px;">
1327
  <div style="width: 10px; height: 10px; border-radius: 50%; background: #22c55e; animation: pulse 2s infinite; box-shadow: 0 0 12px rgba(34, 197, 94, 0.6);"></div>
1328
  <span style="font-size: 13px; font-weight: 600; color: #22c55e;">System Online</span>
1329
  </div>
 
1342
  with gr.Column():
1343
  gr.HTML(
1344
  """
1345
+ <div style="background: var(--bg-card, #ffffff); border: 1px solid var(--border-color, #e4e4e7); border-radius: 20px; padding: 32px; margin-bottom: 24px; box-shadow: var(--shadow-md, 0 4px 6px -1px rgba(0, 0, 0, 0.1)); transition: all 0.3s ease;">
1346
  <!-- Header -->
1347
  <div style="display: flex; align-items: flex-start; justify-content: space-between; margin-bottom: 24px;">
1348
  <div style="display: flex; align-items: center; gap: 16px;">
 
1458
  with gr.Group(elem_classes=["command-center-card"]):
1459
  gr.HTML(
1460
  """
1461
+ <div style="display: flex; align-items: center; gap: 14px; margin-bottom: 20px; padding-bottom: 16px; border-bottom: 1px solid var(--border-color, #e4e4e7);">
1462
+ <div style="width: 48px; height: 48px; background: linear-gradient(135deg, rgba(139, 92, 246, 0.2), rgba(139, 92, 246, 0.05)); border: 1px solid rgba(139, 92, 246, 0.3); border-radius: 14px; display: flex; align-items: center; justify-content: center; box-shadow: 0 0 20px rgba(139, 92, 246, 0.15);">
1463
+ <span style="font-size: 24px;">πŸ™</span>
1464
+ </div>
1465
+ <div>
1466
+ <h3 style="margin: 0; font-size: 20px; font-weight: 700; color: var(--text-primary, #18181b);">Command Center</h3>
1467
+ <p style="margin: 4px 0 0 0; color: var(--text-muted, #71717a); font-size: 13px;">Configure and launch your campaign</p>
 
 
1468
  </div>
1469
  </div>
1470
  """
 
1491
  # Settings Accordion for API Keys
1492
  with gr.Accordion("βš™οΈ Settings (API Keys)", open=False):
1493
  gr.HTML(
1494
+ '<div style="padding: 12px 0; color: var(--text-muted, #71717a); font-size: 13px;">πŸ’‘ Add your own API keys if the default quota is exhausted</div>'
1495
  )
1496
  anthropic_key = gr.Textbox(
1497
  label="Anthropic API Key (Claude)",
 
1506
  lines=1,
1507
  )
1508
  gr.HTML(
1509
+ '''<div style="padding: 12px 0; color: var(--text-muted, #71717a); font-size: 13px;">
1510
  <p style="margin: 0 0 8px 0;">πŸ”‘ <a href="https://console.anthropic.com" target="_blank" style="color: #8b5cf6; text-decoration: none; font-weight: 500;">Get Anthropic API Key β†’</a></p>
1511
  <p style="margin: 0;">πŸ”‘ <a href="https://github.com/settings/tokens" target="_blank" style="color: #22c55e; text-decoration: none; font-weight: 500;">Get GitHub Token β†’</a></p>
1512
  </div>'''
 
1524
  with gr.Group(elem_classes=["pipeline-status-card"]):
1525
  gr.HTML(
1526
  """
1527
+ <div style="display: flex; align-items: center; gap: 14px; margin-bottom: 16px; padding-bottom: 14px; border-bottom: 1px solid var(--border-color, #e4e4e7);">
1528
+ <div style="width: 44px; height: 44px; background: linear-gradient(135deg, rgba(34, 197, 94, 0.2), rgba(34, 197, 94, 0.05)); border: 1px solid rgba(34, 197, 94, 0.3); border-radius: 12px; display: flex; align-items: center; justify-content: center; box-shadow: 0 0 20px rgba(34, 197, 94, 0.15);">
1529
+ <span style="font-size: 22px;">πŸ“Š</span>
1530
+ </div>
1531
+ <div>
1532
+ <h3 style="margin: 0; font-size: 18px; font-weight: 700; color: var(--text-primary, #18181b);">Pipeline Status</h3>
1533
+ <p style="margin: 4px 0 0 0; color: var(--text-muted, #71717a); font-size: 12px;">Real-time generation progress</p>
 
 
1534
  </div>
1535
  </div>
1536
  """
 
1542
  # Event Log Section Header
1543
  gr.HTML(
1544
  """
1545
+ <div style="margin-top: 16px; border-top: 1px solid var(--border-color, #e4e4e7); padding-top: 16px;">
1546
+ <div style="display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px;">
1547
  <div style="display: flex; align-items: center; gap: 12px;">
1548
  <div style="display: flex; gap: 6px;">
1549
  <div style="width: 12px; height: 12px; border-radius: 50%; background: linear-gradient(135deg, #ef4444, #dc2626); box-shadow: 0 0 6px rgba(239, 68, 68, 0.4);"></div>
 
1552
  </div>
1553
  <span style="font-weight: 600; color: var(--text-primary, #18181b); font-size: 14px;">Event Log</span>
1554
  </div>
1555
+ <div style="display: flex; align-items: center; gap: 6px; padding: 4px 12px; background: rgba(34, 197, 94, 0.1); border: 1px solid rgba(34, 197, 94, 0.25); border-radius: 16px;">
1556
  <div style="width: 6px; height: 6px; border-radius: 50%; background: #22c55e; animation: pulse 2s infinite; box-shadow: 0 0 8px rgba(34, 197, 94, 0.6);"></div>
1557
+ <span style="color: #22c55e; font-size: 11px; font-weight: 600;">LIVE</span>
1558
  </div>
1559
  </div>
1560
  </div>
 
1570
  # Footer
1571
  gr.HTML(
1572
  """
1573
+ <div style="display: flex; align-items: center; justify-content: space-between; margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--border-color, #e4e4e7); font-size: 12px;">
1574
+ <div style="display: flex; align-items: center; gap: 12px;">
1575
+ <span style="color: var(--text-muted, #71717a);">Powered by:</span>
1576
+ <span style="background: linear-gradient(135deg, rgba(139, 92, 246, 0.15), rgba(139, 92, 246, 0.05)); color: #8b5cf6; padding: 4px 12px; border-radius: 14px; font-weight: 600; font-size: 11px; border: 1px solid rgba(139, 92, 246, 0.2);">Claude</span>
1577
+ <span style="color: var(--text-muted, #71717a);">Γ—</span>
1578
+ <span style="background: linear-gradient(135deg, rgba(249, 115, 22, 0.15), rgba(249, 115, 22, 0.05)); color: #f97316; padding: 4px 12px; border-radius: 14px; font-weight: 600; font-size: 11px; border: 1px solid rgba(249, 115, 22, 0.2);">Gradio 6</span>
1579
  </div>
1580
  </div>
1581
  """
 
1587
  with gr.Group(elem_classes=["campaign-output-card"]):
1588
  gr.HTML(
1589
  """
1590
+ <div style="display: flex; align-items: center; justify-content: space-between; margin-bottom: 20px; padding-bottom: 16px; border-bottom: 1px solid var(--border-color, #e4e4e7);">
1591
+ <div style="display: flex; align-items: center; gap: 14px;">
1592
+ <div style="width: 48px; height: 48px; background: linear-gradient(135deg, rgba(34, 197, 94, 0.2), rgba(6, 182, 212, 0.1)); border: 1px solid rgba(34, 197, 94, 0.3); border-radius: 14px; display: flex; align-items: center; justify-content: center; box-shadow: 0 0 20px rgba(34, 197, 94, 0.15);">
1593
+ <span style="font-size: 24px;">πŸ“€</span>
1594
  </div>
1595
  <div>
1596
+ <h3 style="margin: 0; font-size: 20px; font-weight: 700; color: var(--text-primary, #18181b);">Campaign Output</h3>
1597
+ <p style="margin: 4px 0 0 0; color: var(--text-muted, #71717a); font-size: 13px;">Generated content for all platforms</p>
1598
  </div>
1599
  </div>
1600
+ <div style="display: flex; gap: 10px;">
1601
+ <span style="background: rgba(34, 197, 94, 0.1); color: #22c55e; padding: 6px 14px; border-radius: 16px; font-size: 12px; font-weight: 600; border: 1px solid rgba(34, 197, 94, 0.2);">6 Formats</span>
1602
  </div>
1603
  </div>
1604
  """
 
1686
  app = create_app()
1687
  app.launch(
1688
  server_name="0.0.0.0",
1689
+ server_port=7860,
1690
+ share=False,
1691
  show_error=True,
1692
  ssr_mode=False, # Disable experimental SSR to avoid potential issues
1693
  )