CelagenexResearch commited on
Commit
180b1bf
Β·
verified Β·
1 Parent(s): cf6850c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +168 -465
app.py CHANGED
@@ -1077,336 +1077,83 @@ def update_media_input(input_type):
1077
  else: # Video Analysis
1078
  return gr.update(visible=False), gr.update(visible=True)
1079
 
 
1080
  custom_css = """
1081
- /* Import the design system variables and base styles */
1082
- :root {
1083
- /* Color system */
1084
- --color-primary: #2563eb;
1085
- --color-primary-hover: #1d4ed8;
1086
- --color-primary-active: #1e40af;
1087
- --color-secondary: #f1f5f9;
1088
- --color-background: #fefefe;
1089
- --color-surface: #ffffff;
1090
- --color-text: #0f172a;
1091
- --color-text-secondary: #64748b;
1092
- --color-border: #e2e8f0;
1093
- --color-card-border: #e2e8f0;
1094
-
1095
- /* Spacing */
1096
- --space-8: 8px;
1097
- --space-12: 12px;
1098
- --space-16: 16px;
1099
- --space-20: 20px;
1100
- --space-24: 24px;
1101
- --space-32: 32px;
1102
-
1103
- /* Typography */
1104
- --font-size-base: 14px;
1105
- --font-size-lg: 16px;
1106
- --font-size-xl: 18px;
1107
- --font-size-2xl: 20px;
1108
- --font-size-3xl: 24px;
1109
- --font-size-4xl: 30px;
1110
-
1111
- /* Border radius */
1112
- --radius-base: 8px;
1113
- --radius-lg: 12px;
1114
- --radius-xl: 16px;
1115
-
1116
- /* Shadows */
1117
- --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.04), 0 1px 2px rgba(0, 0, 0, 0.02);
1118
- --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.04), 0 2px 4px -1px rgba(0, 0, 0, 0.02);
1119
- --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.04), 0 4px 6px -2px rgba(0, 0, 0, 0.02);
1120
- }
1121
-
1122
- /* Base container styling */
1123
  .gradio-container {
1124
- background: var(--color-background);
1125
  min-height: 100vh;
1126
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
1127
- }
1128
-
1129
- /* Header styling matching your design */
1130
- .main-header {
1131
- background: linear-gradient(135deg, var(--color-primary) 0%, #7c3aed 100%);
1132
- color: white;
1133
- text-align: center;
1134
- padding: var(--space-32);
1135
- border-radius: var(--radius-xl);
1136
- margin-bottom: var(--space-32);
1137
- box-shadow: 0 8px 25px rgba(37, 99, 235, 0.2);
1138
- }
1139
-
1140
- .main-header h1 {
1141
- margin: 0;
1142
- font-size: var(--font-size-4xl);
1143
- font-weight: 700;
1144
- text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
1145
- }
1146
-
1147
- .main-header p {
1148
- margin: var(--space-16) 0 0 0;
1149
- font-size: var(--font-size-xl);
1150
- opacity: 0.9;
1151
- font-weight: 400;
1152
  }
1153
 
1154
- /* Card styling matching your clean design */
1155
  .input-card, .questionnaire-card {
1156
- background: var(--color-surface);
1157
- border-radius: var(--radius-xl);
1158
- padding: var(--space-24);
1159
- box-shadow: var(--shadow-sm);
1160
- margin: var(--space-16) 0;
1161
- border: 1px solid var(--color-card-border);
1162
- transition: all 0.3s ease;
1163
  }
1164
 
1165
- .input-card:hover, .questionnaire-card:hover {
1166
- box-shadow: var(--shadow-md);
1167
- transform: translateY(-1px);
1168
- }
1169
-
1170
- .section-title {
1171
- color: var(--color-primary);
1172
- margin: 0 0 var(--space-20) 0;
1173
  text-align: center;
1174
- font-size: var(--font-size-2xl);
1175
- font-weight: 600;
 
 
1176
  }
1177
 
1178
- /* Upload area styling */
1179
- .upload-area {
1180
- border: 2px dashed var(--color-border);
1181
- border-radius: var(--radius-lg);
1182
- padding: var(--space-32);
1183
- text-align: center;
 
 
 
 
1184
  transition: all 0.3s ease;
1185
- background-color: #f8fafc;
1186
- }
1187
-
1188
- .upload-area:hover {
1189
- border-color: var(--color-primary);
1190
- background-color: #f1f5f9;
1191
  }
1192
 
1193
- /* Enhanced form controls */
1194
- .gr-dropdown, .gr-textbox, .gr-number {
1195
- border-radius: var(--radius-base) !important;
1196
- border: 2px solid var(--color-border) !important;
1197
- transition: border-color 0.3s ease !important;
1198
- font-size: var(--font-size-base) !important;
1199
- }
1200
-
1201
- .gr-dropdown:focus, .gr-textbox:focus, .gr-number:focus {
1202
- border-color: var(--color-primary) !important;
1203
- box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1) !important;
1204
- outline: none !important;
1205
  }
1206
 
1207
- /* Accordion styling for questionnaire */
1208
  .accordion-header {
1209
- background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
1210
- border: 1px solid var(--color-border);
1211
- border-radius: var(--radius-base);
1212
- padding: var(--space-16);
1213
- margin: var(--space-12) 0;
1214
  cursor: pointer;
1215
  transition: all 0.3s ease;
1216
  }
1217
 
1218
  .accordion-header:hover {
1219
- background: linear-gradient(135deg, #e2e8f0 0%, #cbd5e1 100%);
1220
  transform: translateY(-1px);
1221
  }
1222
 
1223
- .accordion-header h3 {
1224
- margin: 0;
1225
- color: var(--color-text);
1226
- font-size: var(--font-size-lg);
1227
- font-weight: 600;
1228
- }
1229
-
1230
- .accordion-header p {
1231
- margin: 5px 0 0 0;
1232
- color: var(--color-text-secondary);
1233
- font-size: var(--font-size-base);
1234
- }
1235
-
1236
- /* Enhanced button styling */
1237
- .analyze-button {
1238
- background: linear-gradient(135deg, var(--color-primary) 0%, #7c3aed 100%) !important;
1239
- border: none !important;
1240
- color: white !important;
1241
- padding: var(--space-16) var(--space-32) !important;
1242
- font-size: var(--font-size-lg) !important;
1243
- font-weight: 600 !important;
1244
- border-radius: 25px !important;
1245
- cursor: pointer !important;
1246
- transition: all 0.3s ease !important;
1247
- box-shadow: 0 4px 15px rgba(37, 99, 235, 0.3) !important;
1248
- min-width: 300px !important;
1249
- }
1250
-
1251
- .analyze-button:hover {
1252
- transform: translateY(-2px) !important;
1253
- box-shadow: 0 8px 25px rgba(37, 99, 235, 0.4) !important;
1254
- }
1255
-
1256
- .analyze-button:disabled {
1257
- opacity: 0.6 !important;
1258
- cursor: not-allowed !important;
1259
- transform: none !important;
1260
- }
1261
-
1262
- /* Progress bar styling */
1263
- .progress-container {
1264
- margin: var(--space-24) 0;
1265
- }
1266
-
1267
- .progress-bar {
1268
- width: 100%;
1269
- height: 8px;
1270
- background-color: var(--color-secondary);
1271
- border-radius: 25px;
1272
- overflow: hidden;
1273
- margin-bottom: var(--space-8);
1274
- }
1275
-
1276
- .progress-fill {
1277
- height: 100%;
1278
- background: linear-gradient(90deg, var(--color-primary) 0%, #06b6d4 100%);
1279
- border-radius: 25px;
1280
- transition: width 0.5s ease;
1281
- width: 0%;
1282
- }
1283
-
1284
- .progress-text {
1285
- font-size: var(--font-size-base);
1286
- color: var(--color-text-secondary);
1287
- text-align: center;
1288
- }
1289
-
1290
- /* Results section styling */
1291
- .results-section {
1292
- margin-top: var(--space-32);
1293
- background: var(--color-surface);
1294
- border-radius: var(--radius-xl);
1295
- padding: var(--space-32);
1296
- box-shadow: var(--shadow-lg);
1297
- border: 1px solid var(--color-card-border);
1298
- }
1299
-
1300
- .results-grid {
1301
- display: grid;
1302
- grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
1303
- gap: var(--space-20);
1304
- margin-bottom: var(--space-24);
1305
- }
1306
-
1307
- .result-card {
1308
- background: var(--color-surface);
1309
- border: 1px solid var(--color-card-border);
1310
- border-radius: var(--radius-lg);
1311
- padding: var(--space-20);
1312
- text-align: center;
1313
- box-shadow: var(--shadow-sm);
1314
- transition: all 0.3s ease;
1315
- }
1316
-
1317
- .result-card:hover {
1318
- box-shadow: var(--shadow-md);
1319
- transform: translateY(-2px);
1320
- }
1321
-
1322
- .metric-title {
1323
- font-size: var(--font-size-base);
1324
- font-weight: 500;
1325
- color: var(--color-text-secondary);
1326
- margin: 0 0 var(--space-8) 0;
1327
- text-transform: uppercase;
1328
- letter-spacing: 0.5px;
1329
- }
1330
-
1331
- .metric-value {
1332
- font-size: var(--font-size-3xl);
1333
- font-weight: 700;
1334
- color: var(--color-primary);
1335
- margin: 0;
1336
- }
1337
-
1338
- .metric-subtitle {
1339
- font-size: var(--font-size-base);
1340
- color: var(--color-text-secondary);
1341
- margin: var(--space-8) 0 0 0;
1342
- }
1343
-
1344
- /* Score bars */
1345
- .score-bar {
1346
- width: 100%;
1347
- height: 8px;
1348
- background-color: var(--color-secondary);
1349
- border-radius: 25px;
1350
- overflow: hidden;
1351
- margin: var(--space-12) 0;
1352
- }
1353
-
1354
- .score-fill {
1355
- height: 100%;
1356
- border-radius: 25px;
1357
- transition: width 0.8s ease;
1358
- }
1359
-
1360
- .score-excellent { background: linear-gradient(90deg, #10b981 0%, #34d399 100%); }
1361
- .score-good { background: linear-gradient(90deg, #3b82f6 0%, #60a5fa 100%); }
1362
- .score-fair { background: linear-gradient(90deg, #f59e0b 0%, #fbbf24 100%); }
1363
- .score-poor { background: linear-gradient(90deg, #ef4444 0%, #f87171 100%); }
1364
-
1365
- /* Recommendations styling */
1366
- .recommendations-list {
1367
- list-style: none;
1368
- padding: 0;
1369
- margin: 0;
1370
- }
1371
-
1372
- .recommendations-list li {
1373
- background: #f8fafc;
1374
- padding: var(--space-12) var(--space-16);
1375
- margin: var(--space-8) 0;
1376
- border-radius: var(--radius-base);
1377
- border-left: 4px solid var(--color-primary);
1378
- font-size: var(--font-size-base);
1379
- line-height: 1.5;
1380
- }
1381
-
1382
- /* Health aspects grid */
1383
- .health-aspects {
1384
- display: grid;
1385
- grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
1386
- gap: var(--space-16);
1387
- margin-top: var(--space-24);
1388
- }
1389
-
1390
- .aspect-item {
1391
- display: flex;
1392
- justify-content: space-between;
1393
- align-items: center;
1394
- padding: var(--space-12);
1395
- background: #f8fafc;
1396
- border-radius: var(--radius-base);
1397
- font-size: var(--font-size-base);
1398
- }
1399
-
1400
- .aspect-name {
1401
- font-weight: 500;
1402
- color: var(--color-text);
1403
  }
1404
 
1405
- .aspect-value {
1406
- color: var(--color-text-secondary);
 
1407
  }
1408
 
1409
- /* Loading animation */
1410
  @keyframes pulse {
1411
  0% { opacity: 1; }
1412
  50% { opacity: 0.5; }
@@ -1416,196 +1163,152 @@ custom_css = """
1416
  .loading-pulse {
1417
  animation: pulse 2s infinite;
1418
  }
1419
-
1420
- /* Responsive design */
1421
- @media (max-width: 768px) {
1422
- .main-header {
1423
- padding: var(--space-24);
1424
- }
1425
-
1426
- .main-header h1 {
1427
- font-size: var(--font-size-3xl);
1428
- }
1429
-
1430
- .main-header p {
1431
- font-size: var(--font-size-lg);
1432
- }
1433
-
1434
- .input-card, .questionnaire-card {
1435
- padding: var(--space-20);
1436
- margin: var(--space-12) 0;
1437
- }
1438
-
1439
- .analyze-button {
1440
- min-width: auto !important;
1441
- width: 100% !important;
1442
- }
1443
-
1444
- .results-grid {
1445
- grid-template-columns: 1fr;
1446
- }
1447
- }
1448
-
1449
- /* Hide default gradio styling that conflicts */
1450
- .gradio-container .prose {
1451
- max-width: none !important;
1452
- }
1453
-
1454
- .gradio-container .container {
1455
- max-width: none !important;
1456
- }
1457
-
1458
- /* Enhanced spacing for main content */
1459
- .gradio-container > .contain {
1460
- padding: var(--space-24) !important;
1461
- max-width: 1200px !important;
1462
- margin: 0 auto !important;
1463
- }
1464
  """
1465
 
1466
- # Your existing comprehensive_healthspan_analysis function and other logic
1467
- # (Keep all your existing functions exactly as they are)
1468
-
1469
- def update_media_input(analysis_type):
1470
- if analysis_type == "Image Analysis":
1471
- return gr.update(visible=True), gr.update(visible=False)
1472
- else:
1473
- return gr.update(visible=False), gr.update(visible=True)
1474
-
1475
- # Gradio Interface with Clean Professional UI
1476
  with gr.Blocks(
1477
  title="🐢 Enhanced AI Dog Health Analyzer",
1478
  theme=gr.themes.Soft(),
1479
  css=custom_css
1480
  ) as demo:
1481
 
1482
- # Main Header with clean styling
1483
  gr.HTML("""
1484
  <div class="main-header">
1485
- <h1>πŸ• Enhanced AI Dog Health & Aging Analyzer</h1>
1486
- <p>Advanced Biological Age Prediction β€’ Multi-Factor Analysis β€’ Breed-Specific Calibration</p>
 
 
 
 
1487
  </div>
1488
  """)
1489
 
1490
  with gr.Row():
1491
- # Left Column - Media Input Section
1492
  with gr.Column(scale=1):
1493
- with gr.Group():
1494
- gr.HTML("""
1495
- <div class="input-card">
1496
- <h2 class="section-title">πŸ“Έ Media Input Selection</h2>
1497
- </div>
1498
- """)
1499
-
1500
- # Analysis type dropdown
1501
- input_type_dropdown = gr.Dropdown(
1502
- choices=["Image Analysis", "Video Analysis"],
1503
- label="πŸ” Select Analysis Type",
1504
- value="Image Analysis",
1505
- interactive=True,
1506
- elem_classes=["gr-dropdown"]
1507
- )
1508
-
1509
- # Media input components
1510
- image_input = gr.Image(
1511
- type="pil",
1512
- label="πŸ“· Upload Dog Photo or Use Webcam",
1513
- visible=True,
1514
- sources=["upload", "webcam"],
1515
- height=300
1516
- )
1517
-
1518
- video_input = gr.Video(
1519
- label="πŸŽ₯ Upload Video (10-30 seconds) or Record with Webcam",
1520
- visible=False,
1521
- sources=["upload", "webcam"],
1522
- height=300
1523
- )
1524
-
1525
- # Update visibility based on dropdown selection
1526
- input_type_dropdown.change(
1527
- fn=update_media_input,
1528
- inputs=[input_type_dropdown],
1529
- outputs=[image_input, video_input]
1530
- )
1531
 
1532
- # Optional Information Section
1533
- with gr.Group():
1534
- gr.HTML("""
1535
- <div style="margin: 20px 0;">
1536
- <h3 class="section-title">βš™ Optional Information</h3>
1537
- </div>
1538
- """)
1539
-
1540
- breed_input = gr.Dropdown(
1541
- STANFORD_BREEDS,
1542
- label="πŸ• Dog Breed (Auto-detected if not specified)",
1543
- value=None,
1544
- allow_custom_value=True,
1545
- elem_classes=["gr-dropdown"]
1546
- )
1547
-
1548
- age_input = gr.Number(
1549
- label="πŸ“… Chronological Age (years)",
1550
- precision=1,
1551
- value=None,
1552
- minimum=0,
1553
- maximum=25
1554
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1555
 
1556
- # Right Column - HRQOL Questionnaire
1557
  with gr.Column(scale=1):
1558
- with gr.Group():
1559
- gr.HTML("""
1560
- <div class="questionnaire-card">
1561
- <h2 class="section-title">πŸ“‹ Streamlined HRQOL Assessment</h2>
1562
- <p style="text-align: center; color: var(--color-text-secondary); font-style: italic; margin-bottom: 20px;">
1563
- Complete all 4 comprehensive questions for accurate healthspan analysis
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1564
  </p>
1565
  </div>
1566
  """)
1567
 
1568
- hrqol_inputs = []
1569
-
1570
- for domain_key, domain_data in HRQOL_QUESTIONNAIRE.items():
1571
- # Enhanced accordion header
1572
- gr.HTML(f"""
1573
- <div class="accordion-header">
1574
- <h3>{domain_data['title']}</h3>
1575
- <p>{domain_data['description']}</p>
1576
- </div>
1577
- """)
1578
-
1579
- with gr.Accordion(domain_data["title"], open=True):
1580
- for question in domain_data["questions"]:
1581
- # Enhanced dropdown for each question
1582
- dropdown = gr.Dropdown(
1583
- choices=question["options"],
1584
- label=question["text"],
1585
- value=None,
1586
- interactive=True,
1587
- elem_classes=["gr-dropdown"]
1588
- )
1589
- hrqol_inputs.append(dropdown)
1590
 
1591
- # Enhanced Analysis Button with center alignment
1592
- with gr.Row():
1593
- with gr.Column():
1594
- gr.HTML("""<div style="text-align: center; margin: 30px 0;">""")
1595
-
1596
- analyze_button = gr.Button(
1597
- "πŸ”¬ Run Advanced AI Analysis",
1598
- variant="primary",
1599
- size="lg",
1600
- elem_classes=["analyze-button"]
1601
- )
1602
-
1603
- gr.HTML("</div>")
1604
 
1605
  # Enhanced Results Section
1606
  output_report = gr.HTML()
1607
 
1608
- # Connect analysis function (keep your existing logic)
1609
  analyze_button.click(
1610
  fn=comprehensive_healthspan_analysis,
1611
  inputs=[input_type_dropdown, image_input, video_input, breed_input, age_input] + hrqol_inputs,
@@ -1613,4 +1316,4 @@ with gr.Blocks(
1613
  )
1614
 
1615
  if __name__ == "__main__":
1616
- demo.launch()
 
1077
  else: # Video Analysis
1078
  return gr.update(visible=False), gr.update(visible=True)
1079
 
1080
+ # Custom CSS for enhanced styling
1081
  custom_css = """
1082
+ /* Enhanced gradient background */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1083
  .gradio-container {
1084
+ background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
1085
  min-height: 100vh;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1086
  }
1087
 
1088
+ /* Card styling */
1089
  .input-card, .questionnaire-card {
1090
+ background: white;
1091
+ border-radius: 15px;
1092
+ padding: 25px;
1093
+ box-shadow: 0 8px 25px rgba(0,0,0,0.1);
1094
+ margin: 10px;
1095
+ border: 1px solid #e0e6ed;
 
1096
  }
1097
 
1098
+ /* Header styling */
1099
+ .main-header {
1100
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
1101
+ color: white;
 
 
 
 
1102
  text-align: center;
1103
+ padding: 30px;
1104
+ border-radius: 15px;
1105
+ margin-bottom: 30px;
1106
+ box-shadow: 0 8px 25px rgba(102, 126, 234, 0.3);
1107
  }
1108
 
1109
+ /* Button styling */
1110
+ .analyze-button {
1111
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
1112
+ border: none;
1113
+ color: white;
1114
+ padding: 15px 30px;
1115
+ font-size: 16px;
1116
+ font-weight: 600;
1117
+ border-radius: 25px;
1118
+ cursor: pointer;
1119
  transition: all 0.3s ease;
1120
+ box-shadow: 0 4px 15px rgba(102, 126, 234, 0.3);
 
 
 
 
 
1121
  }
1122
 
1123
+ .analyze-button:hover {
1124
+ transform: translateY(-2px);
1125
+ box-shadow: 0 8px 25px rgba(102, 126, 234, 0.4);
 
 
 
 
 
 
 
 
 
1126
  }
1127
 
1128
+ /* Accordion styling */
1129
  .accordion-header {
1130
+ background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
1131
+ border: 1px solid #dee2e6;
1132
+ border-radius: 8px;
1133
+ padding: 15px;
1134
+ margin: 10px 0;
1135
  cursor: pointer;
1136
  transition: all 0.3s ease;
1137
  }
1138
 
1139
  .accordion-header:hover {
1140
+ background: linear-gradient(135deg, #e9ecef 0%, #dee2e6 100%);
1141
  transform: translateY(-1px);
1142
  }
1143
 
1144
+ /* Dropdown styling */
1145
+ .gr-dropdown {
1146
+ border-radius: 8px;
1147
+ border: 2px solid #e0e6ed;
1148
+ transition: border-color 0.3s ease;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1149
  }
1150
 
1151
+ .gr-dropdown:focus {
1152
+ border-color: #667eea;
1153
+ box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
1154
  }
1155
 
1156
+ /* Progress animation */
1157
  @keyframes pulse {
1158
  0% { opacity: 1; }
1159
  50% { opacity: 0.5; }
 
1163
  .loading-pulse {
1164
  animation: pulse 2s infinite;
1165
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1166
  """
1167
 
1168
+ # Gradio Interface with Enhanced UI
 
 
 
 
 
 
 
 
 
1169
  with gr.Blocks(
1170
  title="🐢 Enhanced AI Dog Health Analyzer",
1171
  theme=gr.themes.Soft(),
1172
  css=custom_css
1173
  ) as demo:
1174
 
1175
+ # Main Header
1176
  gr.HTML("""
1177
  <div class="main-header">
1178
+ <h1 style="margin: 0; font-size: 2.5em; text-shadow: 2px 2px 4px rgba(0,0,0,0.3);">
1179
+ πŸ• Enhanced AI Dog Health & Aging Analyzer
1180
+ </h1>
1181
+ <p style="margin: 15px 0 0 0; font-size: 1.2em; opacity: 0.9;">
1182
+ Advanced Biological Age Prediction β€’ Multi-Factor Analysis β€’ Breed-Specific Calibration
1183
+ </p>
1184
  </div>
1185
  """)
1186
 
1187
  with gr.Row():
1188
+ # Left Column - Enhanced Media Input
1189
  with gr.Column(scale=1):
1190
+ gr.HTML("""
1191
+ <div class="input-card">
1192
+ <h2 style="color: #667eea; margin: 0 0 20px 0; text-align: center;">
1193
+ πŸ“Έ Media Input Selection
1194
+ </h2>
1195
+ </div>
1196
+ """)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1197
 
1198
+ # Enhanced dropdown with better styling
1199
+ input_type_dropdown = gr.Dropdown(
1200
+ choices=["Image Analysis", "Video Analysis"],
1201
+ label="πŸ” Select Analysis Type",
1202
+ value="Image Analysis",
1203
+ interactive=True,
1204
+ elem_classes=["gr-dropdown"]
1205
+ )
1206
+
1207
+ # Media input components with enhanced labels
1208
+ image_input = gr.Image(
1209
+ type="pil",
1210
+ label="πŸ“· Upload Dog Photo or Use Webcam",
1211
+ visible=True,
1212
+ sources=["upload", "webcam"],
1213
+ height=300
1214
+ )
1215
+
1216
+ video_input = gr.Video(
1217
+ label="πŸŽ₯ Upload Video (10-30 seconds) or Record with Webcam",
1218
+ visible=False,
1219
+ sources=["upload", "webcam"],
1220
+ height=300
1221
+ )
1222
+
1223
+ # Update visibility based on dropdown selection
1224
+ input_type_dropdown.change(
1225
+ fn=update_media_input,
1226
+ inputs=[input_type_dropdown],
1227
+ outputs=[image_input, video_input]
1228
+ )
1229
+
1230
+ # Enhanced optional information section
1231
+ gr.HTML("""
1232
+ <div style="margin: 20px 0;">
1233
+ <h3 style="color: #667eea; text-align: center; margin-bottom: 15px;">
1234
+ βš™ Optional Information
1235
+ </h3>
1236
+ </div>
1237
+ """)
1238
+
1239
+ breed_input = gr.Dropdown(
1240
+ STANFORD_BREEDS,
1241
+ label="πŸ• Dog Breed (Auto-detected if not specified)",
1242
+ value=None,
1243
+ allow_custom_value=True,
1244
+ elem_classes=["gr-dropdown"]
1245
+ )
1246
+ age_input = gr.Number(
1247
+ label="πŸ“… Chronological Age (years)",
1248
+ precision=1,
1249
+ value=None,
1250
+ minimum=0,
1251
+ maximum=25
1252
+ )
1253
 
1254
+ # Right Column - SHORTENED HRQOL Questionnaire
1255
  with gr.Column(scale=1):
1256
+ gr.HTML("""
1257
+ <div class="questionnaire-card">
1258
+ <h2 style="color: #667eea; margin: 0 0 10px 0; text-align: center;">
1259
+ πŸ“‹ Streamlined HRQOL Assessment
1260
+ </h2>
1261
+ <p style="text-align: center; color: #666; font-style: italic; margin-bottom: 20px;">
1262
+ Complete all 4 comprehensive questions for accurate healthspan analysis
1263
+ </p>
1264
+ </div>
1265
+ """)
1266
+
1267
+ hrqol_inputs = []
1268
+
1269
+ for domain_key, domain_data in HRQOL_QUESTIONNAIRE.items():
1270
+ # Enhanced accordion header
1271
+ gr.HTML(f"""
1272
+ <div class="accordion-header">
1273
+ <h3 style="margin: 0; color: #333;">
1274
+ {domain_data['title']}
1275
+ </h3>
1276
+ <p style="margin: 5px 0 0 0; color: #666; font-size: 0.9em;">
1277
+ {domain_data['description']}
1278
  </p>
1279
  </div>
1280
  """)
1281
 
1282
+ with gr.Accordion(domain_data["title"], open=True):
1283
+ for question in domain_data["questions"]:
1284
+ # Enhanced dropdown for each question
1285
+ dropdown = gr.Dropdown(
1286
+ choices=question["options"],
1287
+ label=question["text"],
1288
+ value=None,
1289
+ interactive=True,
1290
+ elem_classes=["gr-dropdown"]
1291
+ )
1292
+ hrqol_inputs.append(dropdown)
 
 
 
 
 
 
 
 
 
 
 
1293
 
1294
+ # Enhanced Analysis Button
1295
+ gr.HTML("""
1296
+ <div style="text-align: center; margin: 30px 0;">
1297
+ """)
1298
+
1299
+ analyze_button = gr.Button(
1300
+ "πŸ”¬ Run Advanced AI Analysis",
1301
+ variant="primary",
1302
+ size="lg",
1303
+ elem_classes=["analyze-button"]
1304
+ )
1305
+
1306
+ gr.HTML("</div>")
1307
 
1308
  # Enhanced Results Section
1309
  output_report = gr.HTML()
1310
 
1311
+ # Connect analysis function with loading
1312
  analyze_button.click(
1313
  fn=comprehensive_healthspan_analysis,
1314
  inputs=[input_type_dropdown, image_input, video_input, breed_input, age_input] + hrqol_inputs,
 
1316
  )
1317
 
1318
  if __name__ == "__main__":
1319
+ demo.launch()