Spaces:
Sleeping
Sleeping
Upload app.py
Browse files
app.py
CHANGED
|
@@ -1218,7 +1218,7 @@ async def run_stage2_analysis_v2(
|
|
| 1218 |
typography_preview_html = generate_typography_preview_html(desktop_typo_dict, primary_font)
|
| 1219 |
except Exception as preview_err:
|
| 1220 |
state.log(f" β οΈ Preview generation failed: {str(preview_err)[:50]}")
|
| 1221 |
-
typography_preview_html = "<div
|
| 1222 |
|
| 1223 |
except Exception as format_err:
|
| 1224 |
state.log(f" β οΈ Formatting failed: {str(format_err)[:100]}")
|
|
@@ -1452,23 +1452,31 @@ def format_scores_dashboard_v2(rule_results, final_synthesis, best_practices) ->
|
|
| 1452 |
return "#ef4444" # Red
|
| 1453 |
|
| 1454 |
html = f"""
|
| 1455 |
-
<
|
| 1456 |
-
|
| 1457 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1458 |
<div style="font-size: 32px; font-weight: 700; color: {score_color(overall)};">{overall}</div>
|
| 1459 |
-
<div
|
| 1460 |
</div>
|
| 1461 |
-
<div
|
| 1462 |
<div style="font-size: 24px; font-weight: 600; color: {score_color(accessibility)};">{accessibility}</div>
|
| 1463 |
-
<div
|
| 1464 |
</div>
|
| 1465 |
-
<div
|
| 1466 |
<div style="font-size: 24px; font-weight: 600; color: {score_color(consistency)};">{consistency}</div>
|
| 1467 |
-
<div
|
| 1468 |
</div>
|
| 1469 |
-
<div
|
| 1470 |
<div style="font-size: 24px; font-weight: 600; color: {score_color(organization)};">{organization}</div>
|
| 1471 |
-
<div
|
| 1472 |
</div>
|
| 1473 |
</div>
|
| 1474 |
"""
|
|
@@ -1516,24 +1524,22 @@ def format_priority_actions_v2(rule_results, final_synthesis, best_practices) ->
|
|
| 1516 |
icon = "π΄" if impact == "high" else "π‘" if impact == "medium" else "π’"
|
| 1517 |
|
| 1518 |
html_items.append(f"""
|
| 1519 |
-
<div style="
|
| 1520 |
-
border-radius: 8px; padding: 16px; margin-bottom: 12px;">
|
| 1521 |
<div style="display: flex; justify-content: space-between; align-items: flex-start;">
|
| 1522 |
<div>
|
| 1523 |
-
<div
|
| 1524 |
{icon} {action.get('action', 'N/A')}
|
| 1525 |
</div>
|
| 1526 |
-
<div
|
| 1527 |
{action.get('details', '')}
|
| 1528 |
</div>
|
| 1529 |
</div>
|
| 1530 |
<div style="display: flex; gap: 8px;">
|
| 1531 |
-
<span style="background: {impact_bg}; color: {impact_text}; padding: 4px 8px;
|
| 1532 |
border-radius: 12px; font-size: 11px; font-weight: 600;">
|
| 1533 |
{impact.upper()}
|
| 1534 |
</span>
|
| 1535 |
-
<span
|
| 1536 |
-
border-radius: 12px; font-size: 11px;">
|
| 1537 |
{action.get('effort', '?')}
|
| 1538 |
</span>
|
| 1539 |
</div>
|
|
@@ -1542,8 +1548,21 @@ def format_priority_actions_v2(rule_results, final_synthesis, best_practices) ->
|
|
| 1542 |
""")
|
| 1543 |
|
| 1544 |
return f"""
|
| 1545 |
-
<
|
| 1546 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1547 |
{''.join(html_items)}
|
| 1548 |
</div>
|
| 1549 |
"""
|
|
@@ -1827,8 +1846,8 @@ def format_llm_color_recommendations_html(final_recs: dict, semantic_analysis: d
|
|
| 1827 |
|
| 1828 |
if not final_recs:
|
| 1829 |
return '''
|
| 1830 |
-
<div
|
| 1831 |
-
<p
|
| 1832 |
</div>
|
| 1833 |
'''
|
| 1834 |
|
|
@@ -1837,9 +1856,13 @@ def format_llm_color_recommendations_html(final_recs: dict, semantic_analysis: d
|
|
| 1837 |
|
| 1838 |
if not color_recs and not aa_fixes:
|
| 1839 |
return '''
|
| 1840 |
-
<div style="padding: 20px;
|
| 1841 |
-
<p style="
|
| 1842 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1843 |
'''
|
| 1844 |
|
| 1845 |
# Build recommendations HTML
|
|
@@ -1930,9 +1953,13 @@ def format_llm_color_recommendations_html(final_recs: dict, semantic_analysis: d
|
|
| 1930 |
|
| 1931 |
if not recs_html:
|
| 1932 |
return '''
|
| 1933 |
-
<div style="padding: 20px;
|
| 1934 |
-
<p style="
|
| 1935 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1936 |
'''
|
| 1937 |
|
| 1938 |
html = f'''
|
|
@@ -2042,6 +2069,19 @@ def format_llm_color_recommendations_html(final_recs: dict, semantic_analysis: d
|
|
| 2042 |
color: #991b1b !important;
|
| 2043 |
font-weight: 500;
|
| 2044 |
}}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2045 |
</style>
|
| 2046 |
|
| 2047 |
<div class="llm-recs-container">
|
|
@@ -3029,6 +3069,7 @@ def create_ui():
|
|
| 3029 |
}
|
| 3030 |
th {
|
| 3031 |
background: #f1f5f9;
|
|
|
|
| 3032 |
padding: 12px;
|
| 3033 |
text-align: left;
|
| 3034 |
font-weight: 600;
|
|
@@ -3036,9 +3077,27 @@ def create_ui():
|
|
| 3036 |
}
|
| 3037 |
td {
|
| 3038 |
padding: 12px;
|
|
|
|
| 3039 |
border-bottom: 1px solid #e2e8f0;
|
| 3040 |
}
|
| 3041 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3042 |
/* Dark mode adjustments */
|
| 3043 |
.dark .stage-header {
|
| 3044 |
background: linear-gradient(90deg, #1e293b 0%, #0f172a 100%);
|
|
@@ -3047,13 +3106,265 @@ def create_ui():
|
|
| 3047 |
.dark .stage-header h2 {
|
| 3048 |
color: #f1f5f9;
|
| 3049 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3050 |
.dark .benchmark-card {
|
| 3051 |
background: #1e293b;
|
| 3052 |
border-color: #334155;
|
| 3053 |
}
|
| 3054 |
.dark .action-item {
|
| 3055 |
background: #1e293b;
|
| 3056 |
-
border-color: #
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3057 |
}
|
| 3058 |
"""
|
| 3059 |
|
|
@@ -3182,42 +3493,42 @@ def create_ui():
|
|
| 3182 |
with gr.Tab("π€ Typography"):
|
| 3183 |
gr.Markdown("*Actual typography rendered with the detected font*")
|
| 3184 |
stage1_typography_preview = gr.HTML(
|
| 3185 |
-
value="<div
|
| 3186 |
label="Typography Preview"
|
| 3187 |
)
|
| 3188 |
|
| 3189 |
with gr.Tab("π¨ Colors"):
|
| 3190 |
gr.Markdown("*All detected colors (AS-IS β no generated ramps)*")
|
| 3191 |
stage1_colors_preview = gr.HTML(
|
| 3192 |
-
value="<div
|
| 3193 |
label="Colors Preview"
|
| 3194 |
)
|
| 3195 |
|
| 3196 |
with gr.Tab("π§ Semantic Colors"):
|
| 3197 |
gr.Markdown("*Colors categorized by usage: Brand, Text, Background, Border, Feedback*")
|
| 3198 |
stage1_semantic_preview = gr.HTML(
|
| 3199 |
-
value="<div
|
| 3200 |
label="Semantic Colors Preview"
|
| 3201 |
)
|
| 3202 |
|
| 3203 |
with gr.Tab("π Spacing"):
|
| 3204 |
gr.Markdown("*All detected spacing values*")
|
| 3205 |
stage1_spacing_preview = gr.HTML(
|
| 3206 |
-
value="<div
|
| 3207 |
label="Spacing Preview"
|
| 3208 |
)
|
| 3209 |
|
| 3210 |
with gr.Tab("π Radius"):
|
| 3211 |
gr.Markdown("*All detected border radius values*")
|
| 3212 |
stage1_radius_preview = gr.HTML(
|
| 3213 |
-
value="<div
|
| 3214 |
label="Radius Preview"
|
| 3215 |
)
|
| 3216 |
|
| 3217 |
with gr.Tab("π Shadows"):
|
| 3218 |
gr.Markdown("*All detected box shadow values*")
|
| 3219 |
stage1_shadows_preview = gr.HTML(
|
| 3220 |
-
value="<div
|
| 3221 |
label="Shadows Preview"
|
| 3222 |
)
|
| 3223 |
|
|
@@ -3235,7 +3546,7 @@ def create_ui():
|
|
| 3235 |
gr.HTML("""
|
| 3236 |
<div class="stage-header">
|
| 3237 |
<h2>π§ Stage 2: Multi-Agent Analysis</h2>
|
| 3238 |
-
<p style="color: #64748b; margin-top: 4px;">Rule Engine + Benchmark Research + LLM Agents</p>
|
| 3239 |
</div>
|
| 3240 |
""")
|
| 3241 |
|
|
@@ -3282,7 +3593,7 @@ def create_ui():
|
|
| 3282 |
)
|
| 3283 |
|
| 3284 |
gr.Markdown("""
|
| 3285 |
-
<small style="color: #64748b;">
|
| 3286 |
π‘ <b>Tip:</b> Select 2-4 benchmarks for best results. More benchmarks = longer analysis time.
|
| 3287 |
<br>
|
| 3288 |
π¦ Results are cached for 24 hours to speed up subsequent analyses.
|
|
@@ -3322,7 +3633,7 @@ def create_ui():
|
|
| 3322 |
gr.Markdown("## π Analysis Results")
|
| 3323 |
|
| 3324 |
scores_dashboard = gr.HTML(
|
| 3325 |
-
value="<div
|
| 3326 |
label="Scores"
|
| 3327 |
)
|
| 3328 |
|
|
@@ -3330,7 +3641,7 @@ def create_ui():
|
|
| 3330 |
# PRIORITY ACTIONS
|
| 3331 |
# =============================================================
|
| 3332 |
priority_actions_html = gr.HTML(
|
| 3333 |
-
value="<div
|
| 3334 |
label="Priority Actions"
|
| 3335 |
)
|
| 3336 |
|
|
@@ -3363,7 +3674,7 @@ def create_ui():
|
|
| 3363 |
|
| 3364 |
with gr.Accordion("ποΈ Typography Visual Preview", open=True):
|
| 3365 |
stage2_typography_preview = gr.HTML(
|
| 3366 |
-
value="<div
|
| 3367 |
label="Typography Preview"
|
| 3368 |
)
|
| 3369 |
|
|
@@ -3410,7 +3721,7 @@ def create_ui():
|
|
| 3410 |
""")
|
| 3411 |
|
| 3412 |
llm_color_recommendations = gr.HTML(
|
| 3413 |
-
value="<div
|
| 3414 |
label="LLM Recommendations"
|
| 3415 |
)
|
| 3416 |
|
|
@@ -3426,7 +3737,7 @@ def create_ui():
|
|
| 3426 |
# Visual Preview
|
| 3427 |
with gr.Accordion("ποΈ Color Ramps Visual Preview (Semantic Groups)", open=True):
|
| 3428 |
stage2_color_ramps_preview = gr.HTML(
|
| 3429 |
-
value="<div
|
| 3430 |
label="Color Ramps Preview"
|
| 3431 |
)
|
| 3432 |
|
|
|
|
| 1218 |
typography_preview_html = generate_typography_preview_html(desktop_typo_dict, primary_font)
|
| 1219 |
except Exception as preview_err:
|
| 1220 |
state.log(f" β οΈ Preview generation failed: {str(preview_err)[:50]}")
|
| 1221 |
+
typography_preview_html = "<div class='placeholder-msg'>Preview unavailable</div>"
|
| 1222 |
|
| 1223 |
except Exception as format_err:
|
| 1224 |
state.log(f" β οΈ Formatting failed: {str(format_err)[:100]}")
|
|
|
|
| 1452 |
return "#ef4444" # Red
|
| 1453 |
|
| 1454 |
html = f"""
|
| 1455 |
+
<style>
|
| 1456 |
+
.scores-grid {{ display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; margin: 20px 0; }}
|
| 1457 |
+
.score-card {{ border-radius: 12px; padding: 20px; text-align: center; }}
|
| 1458 |
+
.score-card-secondary {{ background: #f8fafc; border: 1px solid #e2e8f0; }}
|
| 1459 |
+
.score-card .score-label {{ font-size: 12px; color: #64748b; margin-top: 4px; }}
|
| 1460 |
+
.dark .score-card-secondary {{ background: #1e293b !important; border-color: #475569 !important; }}
|
| 1461 |
+
.dark .score-card .score-label {{ color: #94a3b8 !important; }}
|
| 1462 |
+
</style>
|
| 1463 |
+
<div class="scores-grid">
|
| 1464 |
+
<div class="score-card" style="background: linear-gradient(135deg, {score_color(overall)}22 0%, {score_color(overall)}11 100%);
|
| 1465 |
+
border: 2px solid {score_color(overall)};">
|
| 1466 |
<div style="font-size: 32px; font-weight: 700; color: {score_color(overall)};">{overall}</div>
|
| 1467 |
+
<div class="score-label">OVERALL</div>
|
| 1468 |
</div>
|
| 1469 |
+
<div class="score-card score-card-secondary">
|
| 1470 |
<div style="font-size: 24px; font-weight: 600; color: {score_color(accessibility)};">{accessibility}</div>
|
| 1471 |
+
<div class="score-label">Accessibility</div>
|
| 1472 |
</div>
|
| 1473 |
+
<div class="score-card score-card-secondary">
|
| 1474 |
<div style="font-size: 24px; font-weight: 600; color: {score_color(consistency)};">{consistency}</div>
|
| 1475 |
+
<div class="score-label">Consistency</div>
|
| 1476 |
</div>
|
| 1477 |
+
<div class="score-card score-card-secondary">
|
| 1478 |
<div style="font-size: 24px; font-weight: 600; color: {score_color(organization)};">{organization}</div>
|
| 1479 |
+
<div class="score-label">Organization</div>
|
| 1480 |
</div>
|
| 1481 |
</div>
|
| 1482 |
"""
|
|
|
|
| 1524 |
icon = "π΄" if impact == "high" else "π‘" if impact == "medium" else "π’"
|
| 1525 |
|
| 1526 |
html_items.append(f"""
|
| 1527 |
+
<div class="priority-action-card" style="border-left: 4px solid {border_color};">
|
|
|
|
| 1528 |
<div style="display: flex; justify-content: space-between; align-items: flex-start;">
|
| 1529 |
<div>
|
| 1530 |
+
<div class="priority-action-title">
|
| 1531 |
{icon} {action.get('action', 'N/A')}
|
| 1532 |
</div>
|
| 1533 |
+
<div class="priority-action-detail">
|
| 1534 |
{action.get('details', '')}
|
| 1535 |
</div>
|
| 1536 |
</div>
|
| 1537 |
<div style="display: flex; gap: 8px;">
|
| 1538 |
+
<span style="background: {impact_bg}; color: {impact_text}; padding: 4px 8px;
|
| 1539 |
border-radius: 12px; font-size: 11px; font-weight: 600;">
|
| 1540 |
{impact.upper()}
|
| 1541 |
</span>
|
| 1542 |
+
<span class="priority-effort-badge">
|
|
|
|
| 1543 |
{action.get('effort', '?')}
|
| 1544 |
</span>
|
| 1545 |
</div>
|
|
|
|
| 1548 |
""")
|
| 1549 |
|
| 1550 |
return f"""
|
| 1551 |
+
<style>
|
| 1552 |
+
.priority-actions-wrap {{ margin: 20px 0; }}
|
| 1553 |
+
.priority-actions-wrap h3 {{ margin-bottom: 16px; color: #1e293b; }}
|
| 1554 |
+
.priority-action-card {{ background: white; border: 1px solid #e2e8f0; border-radius: 8px; padding: 16px; margin-bottom: 12px; }}
|
| 1555 |
+
.priority-action-title {{ font-weight: 600; color: #1e293b; margin-bottom: 4px; }}
|
| 1556 |
+
.priority-action-detail {{ font-size: 13px; color: #64748b; }}
|
| 1557 |
+
.priority-effort-badge {{ background: #f1f5f9; color: #475569; padding: 4px 8px; border-radius: 12px; font-size: 11px; }}
|
| 1558 |
+
.dark .priority-actions-wrap h3 {{ color: #f1f5f9 !important; }}
|
| 1559 |
+
.dark .priority-action-card {{ background: #1e293b !important; border-color: #475569 !important; }}
|
| 1560 |
+
.dark .priority-action-title {{ color: #f1f5f9 !important; }}
|
| 1561 |
+
.dark .priority-action-detail {{ color: #94a3b8 !important; }}
|
| 1562 |
+
.dark .priority-effort-badge {{ background: #334155 !important; color: #cbd5e1 !important; }}
|
| 1563 |
+
</style>
|
| 1564 |
+
<div class="priority-actions-wrap">
|
| 1565 |
+
<h3>π― Priority Actions</h3>
|
| 1566 |
{''.join(html_items)}
|
| 1567 |
</div>
|
| 1568 |
"""
|
|
|
|
| 1846 |
|
| 1847 |
if not final_recs:
|
| 1848 |
return '''
|
| 1849 |
+
<div class="placeholder-msg" style="text-align: center;">
|
| 1850 |
+
<p>No LLM recommendations available yet. Run analysis first.</p>
|
| 1851 |
</div>
|
| 1852 |
'''
|
| 1853 |
|
|
|
|
| 1856 |
|
| 1857 |
if not color_recs and not aa_fixes:
|
| 1858 |
return '''
|
| 1859 |
+
<div class="llm-no-recs" style="padding: 20px; border-radius: 8px; border: 1px solid #28a745; background: #d4edda;">
|
| 1860 |
+
<p style="margin: 0; color: #155724;">β
No color changes recommended. Your colors look good!</p>
|
| 1861 |
</div>
|
| 1862 |
+
<style>
|
| 1863 |
+
.dark .llm-no-recs { background: #14532d !important; border-color: #22c55e !important; }
|
| 1864 |
+
.dark .llm-no-recs p { color: #86efac !important; }
|
| 1865 |
+
</style>
|
| 1866 |
'''
|
| 1867 |
|
| 1868 |
# Build recommendations HTML
|
|
|
|
| 1953 |
|
| 1954 |
if not recs_html:
|
| 1955 |
return '''
|
| 1956 |
+
<div class="llm-no-recs" style="padding: 20px; border-radius: 8px; border: 1px solid #28a745; background: #d4edda;">
|
| 1957 |
+
<p style="margin: 0; color: #155724;">β
No color changes recommended. Your colors look good!</p>
|
| 1958 |
</div>
|
| 1959 |
+
<style>
|
| 1960 |
+
.dark .llm-no-recs { background: #14532d !important; border-color: #22c55e !important; }
|
| 1961 |
+
.dark .llm-no-recs p { color: #86efac !important; }
|
| 1962 |
+
</style>
|
| 1963 |
'''
|
| 1964 |
|
| 1965 |
html = f'''
|
|
|
|
| 2069 |
color: #991b1b !important;
|
| 2070 |
font-weight: 500;
|
| 2071 |
}}
|
| 2072 |
+
|
| 2073 |
+
/* Dark mode */
|
| 2074 |
+
.dark .llm-recs-container {{ background: #0f172a !important; }}
|
| 2075 |
+
.dark .llm-rec-row {{ background: #1e293b !important; border-color: #475569 !important; }}
|
| 2076 |
+
.dark .llm-rec-row.aa-fix {{ background: #450a0a !important; }}
|
| 2077 |
+
.dark .llm-rec-row.keep {{ background: #14532d !important; }}
|
| 2078 |
+
.dark .rec-label {{ color: #94a3b8 !important; }}
|
| 2079 |
+
.dark .rec-hex {{ color: #cbd5e1 !important; }}
|
| 2080 |
+
.dark .rec-arrow {{ color: #94a3b8 !important; }}
|
| 2081 |
+
.dark .rec-role {{ color: #f1f5f9 !important; }}
|
| 2082 |
+
.dark .rec-rationale {{ color: #94a3b8 !important; }}
|
| 2083 |
+
.dark .rec-issue {{ color: #fca5a5 !important; }}
|
| 2084 |
+
.dark .rec-action.keep {{ background: #14532d !important; color: #86efac !important; }}
|
| 2085 |
</style>
|
| 2086 |
|
| 2087 |
<div class="llm-recs-container">
|
|
|
|
| 3069 |
}
|
| 3070 |
th {
|
| 3071 |
background: #f1f5f9;
|
| 3072 |
+
color: #1e293b;
|
| 3073 |
padding: 12px;
|
| 3074 |
text-align: left;
|
| 3075 |
font-weight: 600;
|
|
|
|
| 3077 |
}
|
| 3078 |
td {
|
| 3079 |
padding: 12px;
|
| 3080 |
+
color: #1e293b;
|
| 3081 |
border-bottom: 1px solid #e2e8f0;
|
| 3082 |
}
|
| 3083 |
+
|
| 3084 |
+
/* Placeholder messages */
|
| 3085 |
+
.placeholder-msg {
|
| 3086 |
+
padding: 20px;
|
| 3087 |
+
background: #f5f5f5;
|
| 3088 |
+
border-radius: 8px;
|
| 3089 |
+
color: #666;
|
| 3090 |
+
}
|
| 3091 |
+
.placeholder-msg.placeholder-lg {
|
| 3092 |
+
padding: 40px;
|
| 3093 |
+
text-align: center;
|
| 3094 |
+
}
|
| 3095 |
+
|
| 3096 |
+
/* Progress bar */
|
| 3097 |
+
.progress-bar {
|
| 3098 |
+
background: #e2e8f0;
|
| 3099 |
+
}
|
| 3100 |
+
|
| 3101 |
/* Dark mode adjustments */
|
| 3102 |
.dark .stage-header {
|
| 3103 |
background: linear-gradient(90deg, #1e293b 0%, #0f172a 100%);
|
|
|
|
| 3106 |
.dark .stage-header h2 {
|
| 3107 |
color: #f1f5f9;
|
| 3108 |
}
|
| 3109 |
+
.dark .stage-header-subtitle,
|
| 3110 |
+
.dark .tip-text {
|
| 3111 |
+
color: #94a3b8 !important;
|
| 3112 |
+
}
|
| 3113 |
.dark .benchmark-card {
|
| 3114 |
background: #1e293b;
|
| 3115 |
border-color: #334155;
|
| 3116 |
}
|
| 3117 |
.dark .action-item {
|
| 3118 |
background: #1e293b;
|
| 3119 |
+
border-color: #475569;
|
| 3120 |
+
color: #e2e8f0;
|
| 3121 |
+
}
|
| 3122 |
+
/* Dark mode: Placeholder messages */
|
| 3123 |
+
.dark .placeholder-msg {
|
| 3124 |
+
background: #1e293b !important;
|
| 3125 |
+
color: #94a3b8 !important;
|
| 3126 |
+
}
|
| 3127 |
+
/* Dark mode: Progress bar */
|
| 3128 |
+
.dark .progress-bar {
|
| 3129 |
+
background: #334155 !important;
|
| 3130 |
+
}
|
| 3131 |
+
/* Dark mode: Gradio Dataframe tables */
|
| 3132 |
+
.dark table th {
|
| 3133 |
+
background: #1e293b !important;
|
| 3134 |
+
color: #e2e8f0 !important;
|
| 3135 |
+
border-bottom-color: #475569 !important;
|
| 3136 |
+
}
|
| 3137 |
+
.dark table td {
|
| 3138 |
+
color: #e2e8f0 !important;
|
| 3139 |
+
border-bottom-color: #334155 !important;
|
| 3140 |
+
}
|
| 3141 |
+
.dark table tr {
|
| 3142 |
+
background: #0f172a !important;
|
| 3143 |
+
}
|
| 3144 |
+
.dark table tr:nth-child(even) {
|
| 3145 |
+
background: #1e293b !important;
|
| 3146 |
+
}
|
| 3147 |
+
/* Dark mode: HTML preview tables (typography, benchmarks) */
|
| 3148 |
+
.dark .typography-preview {
|
| 3149 |
+
background: #1e293b !important;
|
| 3150 |
+
}
|
| 3151 |
+
.dark .typography-preview th {
|
| 3152 |
+
background: #334155 !important;
|
| 3153 |
+
color: #e2e8f0 !important;
|
| 3154 |
+
border-bottom-color: #475569 !important;
|
| 3155 |
+
}
|
| 3156 |
+
.dark .typography-preview td {
|
| 3157 |
+
color: #e2e8f0 !important;
|
| 3158 |
+
}
|
| 3159 |
+
.dark .typography-preview .meta-row {
|
| 3160 |
+
background: #1e293b !important;
|
| 3161 |
+
border-top-color: #334155 !important;
|
| 3162 |
+
}
|
| 3163 |
+
.dark .typography-preview .scale-name,
|
| 3164 |
+
.dark .typography-preview .scale-label {
|
| 3165 |
+
color: #f1f5f9 !important;
|
| 3166 |
+
background: #475569 !important;
|
| 3167 |
+
}
|
| 3168 |
+
.dark .typography-preview .meta {
|
| 3169 |
+
color: #cbd5e1 !important;
|
| 3170 |
+
}
|
| 3171 |
+
.dark .typography-preview .preview-cell {
|
| 3172 |
+
background: #0f172a !important;
|
| 3173 |
+
border-bottom-color: #334155 !important;
|
| 3174 |
+
}
|
| 3175 |
+
.dark .typography-preview .preview-text {
|
| 3176 |
+
color: #f1f5f9 !important;
|
| 3177 |
+
}
|
| 3178 |
+
.dark .typography-preview tr:hover .preview-cell {
|
| 3179 |
+
background: #1e293b !important;
|
| 3180 |
+
}
|
| 3181 |
+
|
| 3182 |
+
/* Dark mode: Colors AS-IS preview */
|
| 3183 |
+
.dark .colors-asis-header {
|
| 3184 |
+
color: #e2e8f0 !important;
|
| 3185 |
+
background: #1e293b !important;
|
| 3186 |
+
}
|
| 3187 |
+
.dark .colors-asis-preview {
|
| 3188 |
+
background: #0f172a !important;
|
| 3189 |
+
}
|
| 3190 |
+
.dark .color-row-asis {
|
| 3191 |
+
background: #1e293b !important;
|
| 3192 |
+
border-color: #475569 !important;
|
| 3193 |
+
}
|
| 3194 |
+
.dark .color-name-asis {
|
| 3195 |
+
color: #f1f5f9 !important;
|
| 3196 |
+
}
|
| 3197 |
+
.dark .frequency {
|
| 3198 |
+
color: #cbd5e1 !important;
|
| 3199 |
+
}
|
| 3200 |
+
.dark .color-meta-asis .aa-pass {
|
| 3201 |
+
color: #22c55e !important;
|
| 3202 |
+
background: #14532d !important;
|
| 3203 |
+
}
|
| 3204 |
+
.dark .color-meta-asis .aa-fail {
|
| 3205 |
+
color: #f87171 !important;
|
| 3206 |
+
background: #450a0a !important;
|
| 3207 |
+
}
|
| 3208 |
+
.dark .context-badge {
|
| 3209 |
+
background: #334155 !important;
|
| 3210 |
+
color: #e2e8f0 !important;
|
| 3211 |
+
}
|
| 3212 |
+
|
| 3213 |
+
/* Dark mode: Color ramps preview */
|
| 3214 |
+
.dark .color-ramps-preview {
|
| 3215 |
+
background: #0f172a !important;
|
| 3216 |
+
}
|
| 3217 |
+
.dark .ramps-header-info {
|
| 3218 |
+
color: #e2e8f0 !important;
|
| 3219 |
+
background: #1e293b !important;
|
| 3220 |
+
}
|
| 3221 |
+
.dark .ramp-header {
|
| 3222 |
+
background: #1e293b !important;
|
| 3223 |
+
}
|
| 3224 |
+
.dark .ramp-header-label {
|
| 3225 |
+
color: #cbd5e1 !important;
|
| 3226 |
+
}
|
| 3227 |
+
.dark .color-row {
|
| 3228 |
+
background: #1e293b !important;
|
| 3229 |
+
border-color: #475569 !important;
|
| 3230 |
+
}
|
| 3231 |
+
.dark .color-name {
|
| 3232 |
+
color: #f1f5f9 !important;
|
| 3233 |
+
background: #475569 !important;
|
| 3234 |
+
}
|
| 3235 |
+
.dark .color-hex {
|
| 3236 |
+
color: #cbd5e1 !important;
|
| 3237 |
+
}
|
| 3238 |
+
|
| 3239 |
+
/* Dark mode: Spacing preview */
|
| 3240 |
+
.dark .spacing-asis-preview {
|
| 3241 |
+
background: #0f172a !important;
|
| 3242 |
+
}
|
| 3243 |
+
.dark .spacing-row-asis {
|
| 3244 |
+
background: #1e293b !important;
|
| 3245 |
+
}
|
| 3246 |
+
.dark .spacing-label {
|
| 3247 |
+
color: #f1f5f9 !important;
|
| 3248 |
+
}
|
| 3249 |
+
|
| 3250 |
+
/* Dark mode: Radius preview */
|
| 3251 |
+
.dark .radius-asis-preview {
|
| 3252 |
+
background: #0f172a !important;
|
| 3253 |
+
}
|
| 3254 |
+
.dark .radius-item {
|
| 3255 |
+
background: #1e293b !important;
|
| 3256 |
+
}
|
| 3257 |
+
.dark .radius-label {
|
| 3258 |
+
color: #f1f5f9 !important;
|
| 3259 |
+
}
|
| 3260 |
+
|
| 3261 |
+
/* Dark mode: Shadows preview */
|
| 3262 |
+
.dark .shadows-asis-preview {
|
| 3263 |
+
background: #0f172a !important;
|
| 3264 |
+
}
|
| 3265 |
+
.dark .shadow-item {
|
| 3266 |
+
background: #1e293b !important;
|
| 3267 |
+
}
|
| 3268 |
+
.dark .shadow-box {
|
| 3269 |
+
background: #334155 !important;
|
| 3270 |
+
}
|
| 3271 |
+
.dark .shadow-label {
|
| 3272 |
+
color: #f1f5f9 !important;
|
| 3273 |
+
}
|
| 3274 |
+
.dark .shadow-value {
|
| 3275 |
+
color: #94a3b8 !important;
|
| 3276 |
+
}
|
| 3277 |
+
|
| 3278 |
+
/* Dark mode: Semantic color ramps */
|
| 3279 |
+
.dark .sem-ramps-preview {
|
| 3280 |
+
background: #0f172a !important;
|
| 3281 |
+
}
|
| 3282 |
+
.dark .sem-category {
|
| 3283 |
+
background: #1e293b !important;
|
| 3284 |
+
border-color: #475569 !important;
|
| 3285 |
+
}
|
| 3286 |
+
.dark .sem-cat-title {
|
| 3287 |
+
color: #f1f5f9 !important;
|
| 3288 |
+
border-bottom-color: #475569 !important;
|
| 3289 |
+
}
|
| 3290 |
+
.dark .sem-color-row {
|
| 3291 |
+
background: #0f172a !important;
|
| 3292 |
+
border-color: #334155 !important;
|
| 3293 |
+
}
|
| 3294 |
+
.dark .sem-role {
|
| 3295 |
+
color: #f1f5f9 !important;
|
| 3296 |
+
}
|
| 3297 |
+
.dark .sem-hex {
|
| 3298 |
+
color: #cbd5e1 !important;
|
| 3299 |
+
}
|
| 3300 |
+
.dark .llm-rec {
|
| 3301 |
+
background: #422006 !important;
|
| 3302 |
+
border-color: #b45309 !important;
|
| 3303 |
+
}
|
| 3304 |
+
.dark .rec-label {
|
| 3305 |
+
color: #fbbf24 !important;
|
| 3306 |
+
}
|
| 3307 |
+
.dark .rec-issue {
|
| 3308 |
+
color: #fde68a !important;
|
| 3309 |
+
}
|
| 3310 |
+
.dark .rec-arrow {
|
| 3311 |
+
color: #fbbf24 !important;
|
| 3312 |
+
}
|
| 3313 |
+
.dark .llm-summary {
|
| 3314 |
+
background: #1e3a5f !important;
|
| 3315 |
+
border-color: #3b82f6 !important;
|
| 3316 |
+
}
|
| 3317 |
+
.dark .llm-summary h4 {
|
| 3318 |
+
color: #93c5fd !important;
|
| 3319 |
+
}
|
| 3320 |
+
.dark .llm-summary ul,
|
| 3321 |
+
.dark .llm-summary li {
|
| 3322 |
+
color: #bfdbfe !important;
|
| 3323 |
+
}
|
| 3324 |
+
|
| 3325 |
+
/* Dark mode: Score badges */
|
| 3326 |
+
.dark .score-badge.high { background: #14532d; color: #86efac; }
|
| 3327 |
+
.dark .score-badge.medium { background: #422006; color: #fde68a; }
|
| 3328 |
+
.dark .score-badge.low { background: #450a0a; color: #fca5a5; }
|
| 3329 |
+
|
| 3330 |
+
/* Dark mode: Benchmark & action cards */
|
| 3331 |
+
.dark .benchmark-card.selected {
|
| 3332 |
+
border-color: #3b82f6;
|
| 3333 |
+
background: #1e3a5f;
|
| 3334 |
+
}
|
| 3335 |
+
.dark .action-item.high-priority {
|
| 3336 |
+
border-left-color: #ef4444;
|
| 3337 |
+
}
|
| 3338 |
+
.dark .action-item.medium-priority {
|
| 3339 |
+
border-left-color: #f59e0b;
|
| 3340 |
+
}
|
| 3341 |
+
|
| 3342 |
+
/* Dark mode: Gradio markdown rendered tables */
|
| 3343 |
+
.dark .prose table th,
|
| 3344 |
+
.dark .markdown-text table th {
|
| 3345 |
+
background: #1e293b !important;
|
| 3346 |
+
color: #e2e8f0 !important;
|
| 3347 |
+
border-color: #475569 !important;
|
| 3348 |
+
}
|
| 3349 |
+
.dark .prose table td,
|
| 3350 |
+
.dark .markdown-text table td {
|
| 3351 |
+
color: #e2e8f0 !important;
|
| 3352 |
+
border-color: #334155 !important;
|
| 3353 |
+
}
|
| 3354 |
+
.dark .prose table tr,
|
| 3355 |
+
.dark .markdown-text table tr {
|
| 3356 |
+
background: #0f172a !important;
|
| 3357 |
+
}
|
| 3358 |
+
.dark .prose table tr:nth-child(even),
|
| 3359 |
+
.dark .markdown-text table tr:nth-child(even) {
|
| 3360 |
+
background: #1e293b !important;
|
| 3361 |
+
}
|
| 3362 |
+
|
| 3363 |
+
/* Dark mode: Generic text in HTML components */
|
| 3364 |
+
.dark .gradio-html p,
|
| 3365 |
+
.dark .gradio-html span,
|
| 3366 |
+
.dark .gradio-html div {
|
| 3367 |
+
color: #e2e8f0;
|
| 3368 |
}
|
| 3369 |
"""
|
| 3370 |
|
|
|
|
| 3493 |
with gr.Tab("π€ Typography"):
|
| 3494 |
gr.Markdown("*Actual typography rendered with the detected font*")
|
| 3495 |
stage1_typography_preview = gr.HTML(
|
| 3496 |
+
value="<div class='placeholder-msg'>Typography preview will appear after extraction...</div>",
|
| 3497 |
label="Typography Preview"
|
| 3498 |
)
|
| 3499 |
|
| 3500 |
with gr.Tab("π¨ Colors"):
|
| 3501 |
gr.Markdown("*All detected colors (AS-IS β no generated ramps)*")
|
| 3502 |
stage1_colors_preview = gr.HTML(
|
| 3503 |
+
value="<div class='placeholder-msg'>Colors preview will appear after extraction...</div>",
|
| 3504 |
label="Colors Preview"
|
| 3505 |
)
|
| 3506 |
|
| 3507 |
with gr.Tab("π§ Semantic Colors"):
|
| 3508 |
gr.Markdown("*Colors categorized by usage: Brand, Text, Background, Border, Feedback*")
|
| 3509 |
stage1_semantic_preview = gr.HTML(
|
| 3510 |
+
value="<div class='placeholder-msg'>Semantic color analysis will appear after extraction...</div>",
|
| 3511 |
label="Semantic Colors Preview"
|
| 3512 |
)
|
| 3513 |
|
| 3514 |
with gr.Tab("π Spacing"):
|
| 3515 |
gr.Markdown("*All detected spacing values*")
|
| 3516 |
stage1_spacing_preview = gr.HTML(
|
| 3517 |
+
value="<div class='placeholder-msg'>Spacing preview will appear after extraction...</div>",
|
| 3518 |
label="Spacing Preview"
|
| 3519 |
)
|
| 3520 |
|
| 3521 |
with gr.Tab("π Radius"):
|
| 3522 |
gr.Markdown("*All detected border radius values*")
|
| 3523 |
stage1_radius_preview = gr.HTML(
|
| 3524 |
+
value="<div class='placeholder-msg'>Radius preview will appear after extraction...</div>",
|
| 3525 |
label="Radius Preview"
|
| 3526 |
)
|
| 3527 |
|
| 3528 |
with gr.Tab("π Shadows"):
|
| 3529 |
gr.Markdown("*All detected box shadow values*")
|
| 3530 |
stage1_shadows_preview = gr.HTML(
|
| 3531 |
+
value="<div class='placeholder-msg'>Shadows preview will appear after extraction...</div>",
|
| 3532 |
label="Shadows Preview"
|
| 3533 |
)
|
| 3534 |
|
|
|
|
| 3546 |
gr.HTML("""
|
| 3547 |
<div class="stage-header">
|
| 3548 |
<h2>π§ Stage 2: Multi-Agent Analysis</h2>
|
| 3549 |
+
<p class="stage-header-subtitle" style="color: #64748b; margin-top: 4px;">Rule Engine + Benchmark Research + LLM Agents</p>
|
| 3550 |
</div>
|
| 3551 |
""")
|
| 3552 |
|
|
|
|
| 3593 |
)
|
| 3594 |
|
| 3595 |
gr.Markdown("""
|
| 3596 |
+
<small class="tip-text" style="color: #64748b;">
|
| 3597 |
π‘ <b>Tip:</b> Select 2-4 benchmarks for best results. More benchmarks = longer analysis time.
|
| 3598 |
<br>
|
| 3599 |
π¦ Results are cached for 24 hours to speed up subsequent analyses.
|
|
|
|
| 3633 |
gr.Markdown("## π Analysis Results")
|
| 3634 |
|
| 3635 |
scores_dashboard = gr.HTML(
|
| 3636 |
+
value="<div class='placeholder-msg placeholder-lg'>Scores will appear after analysis...</div>",
|
| 3637 |
label="Scores"
|
| 3638 |
)
|
| 3639 |
|
|
|
|
| 3641 |
# PRIORITY ACTIONS
|
| 3642 |
# =============================================================
|
| 3643 |
priority_actions_html = gr.HTML(
|
| 3644 |
+
value="<div class='placeholder-msg'>Priority actions will appear after analysis...</div>",
|
| 3645 |
label="Priority Actions"
|
| 3646 |
)
|
| 3647 |
|
|
|
|
| 3674 |
|
| 3675 |
with gr.Accordion("ποΈ Typography Visual Preview", open=True):
|
| 3676 |
stage2_typography_preview = gr.HTML(
|
| 3677 |
+
value="<div class='placeholder-msg'>Typography preview will appear after analysis...</div>",
|
| 3678 |
label="Typography Preview"
|
| 3679 |
)
|
| 3680 |
|
|
|
|
| 3721 |
""")
|
| 3722 |
|
| 3723 |
llm_color_recommendations = gr.HTML(
|
| 3724 |
+
value="<div class='placeholder-msg'>LLM recommendations will appear after analysis...</div>",
|
| 3725 |
label="LLM Recommendations"
|
| 3726 |
)
|
| 3727 |
|
|
|
|
| 3737 |
# Visual Preview
|
| 3738 |
with gr.Accordion("ποΈ Color Ramps Visual Preview (Semantic Groups)", open=True):
|
| 3739 |
stage2_color_ramps_preview = gr.HTML(
|
| 3740 |
+
value="<div class='placeholder-msg'>Color ramps preview will appear after analysis...</div>",
|
| 3741 |
label="Color Ramps Preview"
|
| 3742 |
)
|
| 3743 |
|