Nischal Subedi
commited on
Commit
·
f743e73
1
Parent(s):
97ad337
UI v33
Browse files
app.py
CHANGED
|
@@ -268,13 +268,17 @@ Answer:"""
|
|
| 268 |
|
| 269 |
try:
|
| 270 |
available_states_list = self.get_states()
|
|
|
|
|
|
|
| 271 |
# Ensure "Select a state..." is always the first option
|
| 272 |
dropdown_choices = ["Select a state..."] + (available_states_list if available_states_list and "Error" not in available_states_list[0] else ["Error: States unavailable"])
|
| 273 |
initial_value = dropdown_choices[0] # Set initial value to the prompt
|
| 274 |
-
except Exception: # Catch-all for safety
|
|
|
|
| 275 |
dropdown_choices = ["Error: Critical failure loading states"]
|
| 276 |
initial_value = dropdown_choices[0]
|
| 277 |
|
|
|
|
| 278 |
# Define example queries, filtering based on available states
|
| 279 |
example_queries_base = [
|
| 280 |
["What are the rules for security deposit returns?", "California"],
|
|
@@ -363,13 +367,8 @@ Answer:"""
|
|
| 363 |
box-shadow: var(--shadow-md) !important;
|
| 364 |
position: relative; /* For potential pseudo-element effects */
|
| 365 |
overflow: hidden; /* For any overflow animations */
|
| 366 |
-
|
| 367 |
-
|
| 368 |
-
.app-header {
|
| 369 |
-
display: flex !important;
|
| 370 |
-
flex-direction: column !important;
|
| 371 |
-
align-items: center !important; /* This centers children horizontally */
|
| 372 |
-
width: 100% !important; /* Ensure it takes full width to center effectively */
|
| 373 |
}
|
| 374 |
|
| 375 |
.app-header-wrapper::before { /* Subtle background pattern for dynamism */
|
|
@@ -389,7 +388,7 @@ Answer:"""
|
|
| 389 |
.app-header-logo {
|
| 390 |
font-size: 4.5rem !important; /* Larger icon */
|
| 391 |
margin-bottom: 0.75rem !important;
|
| 392 |
-
display: block !important;
|
| 393 |
color: var(--primary-color) !important; /* Theme color */
|
| 394 |
position: relative;
|
| 395 |
z-index: 1; /* Bring icon to front of pseudo-element */
|
|
@@ -413,7 +412,8 @@ Answer:"""
|
|
| 413 |
letter-spacing: -0.03em !important; /* Tighter spacing */
|
| 414 |
position: relative;
|
| 415 |
z-index: 1;
|
| 416 |
-
text-align: center
|
|
|
|
| 417 |
}
|
| 418 |
.app-header-tagline {
|
| 419 |
font-size: 1.25rem !important; /* Slightly larger tagline */
|
|
@@ -421,9 +421,9 @@ Answer:"""
|
|
| 421 |
font-weight: 400 !important;
|
| 422 |
margin: 0 !important;
|
| 423 |
max-width: 700px; /* Constrain tagline width */
|
|
|
|
| 424 |
position: relative;
|
| 425 |
z-index: 1;
|
| 426 |
-
text-align: center; /* Redundant due to flexbox, but good for fallback */
|
| 427 |
}
|
| 428 |
|
| 429 |
/* Main container with consistent spacing */
|
|
@@ -447,24 +447,25 @@ Answer:"""
|
|
| 447 |
transform: translateY(-3px) !important; /* More pronounced lift */
|
| 448 |
}
|
| 449 |
|
| 450 |
-
/* Class to center content within Markdown blocks
|
| 451 |
-
.
|
| 452 |
text-align: center !important;
|
|
|
|
|
|
|
| 453 |
}
|
| 454 |
|
| 455 |
-
/*
|
| 456 |
.sub-section-title {
|
| 457 |
font-family: 'Poppins', sans-serif !important;
|
| 458 |
font-size: 1.7rem !important; /* Slightly larger */
|
| 459 |
font-weight: 700 !important; /* Bolder */
|
| 460 |
color: var(--text-primary) !important;
|
| 461 |
-
/* Removed text-align here, handled by parent .centered-markdown-content */
|
| 462 |
margin: 0 0 1.25rem 0 !important; /* More space below title */
|
| 463 |
padding-bottom: 0.75rem !important;
|
| 464 |
border-bottom: 2px solid var(--border-color) !important; /* Underline effect */
|
| 465 |
-
display: block !important; /*
|
| 466 |
-
width: 100% !important; /* Ensure it takes full width of its parent */
|
| 467 |
letter-spacing: -0.01em !important;
|
|
|
|
| 468 |
}
|
| 469 |
|
| 470 |
/* Specific styling for the welcome/disclaimer markdown content */
|
|
@@ -482,11 +483,13 @@ Answer:"""
|
|
| 482 |
.gradio-textbox, .gradio-dropdown {
|
| 483 |
margin-bottom: 0.75rem !important;
|
| 484 |
}
|
|
|
|
| 485 |
.gradio-textbox textarea,
|
| 486 |
.gradio-textbox input,
|
| 487 |
-
|
| 488 |
-
.gradio-dropdown .primary-wrap, /*
|
| 489 |
-
.gradio-dropdown .
|
|
|
|
| 490 |
{
|
| 491 |
background-color: var(--background-primary) !important; /* Explicitly set background to primary cream */
|
| 492 |
border: 2px solid var(--border-color) !important; /* Clear border */
|
|
@@ -498,14 +501,27 @@ Answer:"""
|
|
| 498 |
transition: border-color 0.2s ease, box-shadow 0.2s ease !important; /* Smooth transitions */
|
| 499 |
box-shadow: var(--shadow-sm) !important;
|
| 500 |
}
|
|
|
|
| 501 |
.gradio-textbox textarea:focus,
|
| 502 |
.gradio-textbox input:focus,
|
| 503 |
-
.gradio-dropdown > div > input
|
| 504 |
-
.gradio-dropdown .primary-wrap.focused { /*
|
| 505 |
outline: none !important;
|
| 506 |
border-color: var(--border-focus) !important; /* Distinct border on focus */
|
| 507 |
box-shadow: 0 0 0 4px rgba(255, 140, 0, 0.2) !important; /* Broader, softer glow on focus */
|
| 508 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 509 |
|
| 510 |
/* Label styling for better readability */
|
| 511 |
.gradio-textbox label,
|
|
@@ -516,12 +532,12 @@ Answer:"""
|
|
| 516 |
margin-bottom: 0.6rem !important;
|
| 517 |
display: block !important;
|
| 518 |
}
|
| 519 |
-
/* Info text styling below inputs */
|
| 520 |
-
.
|
| 521 |
-
.gradio-dropdown .gr-form {
|
| 522 |
font-size: 0.9rem !important;
|
| 523 |
color: var(--text-secondary) !important;
|
| 524 |
margin-top: 0.4rem !important; /* More space for info text */
|
|
|
|
| 525 |
}
|
| 526 |
/* Input row layout improvements */
|
| 527 |
.input-row {
|
|
@@ -557,7 +573,7 @@ Answer:"""
|
|
| 557 |
}
|
| 558 |
.gr-button-primary:hover {
|
| 559 |
background-color: var(--primary-hover) !important; /* Explicitly set background */
|
| 560 |
-
|
| 561 |
transform: translateY(-2px) !important; /* Subtle lift effect on hover */
|
| 562 |
}
|
| 563 |
.gr-button-primary:active { /* Press down effect on click */
|
|
@@ -778,24 +794,19 @@ Answer:"""
|
|
| 778 |
with gr.Blocks(css=custom_css, title="Landlord-Tenant Rights Assistant") as demo:
|
| 779 |
# Header Section - uses gr.Group for distinct card-like styling
|
| 780 |
with gr.Group(elem_classes="app-header-wrapper"):
|
| 781 |
-
# Markdown
|
| 782 |
-
|
| 783 |
-
|
| 784 |
-
|
| 785 |
-
|
| 786 |
-
<h1 class="app-header-title">Landlord-Tenant Rights Assistant</h1>
|
| 787 |
-
<p class="app-header-tagline">Empowering You with State-Specific Legal Insights</p>
|
| 788 |
-
</div>
|
| 789 |
-
"""
|
| 790 |
-
)
|
| 791 |
|
| 792 |
# Main Dashboard Container - acts as a column to stack various sections
|
| 793 |
with gr.Column(elem_classes="main-dashboard-container"):
|
| 794 |
|
| 795 |
# Introduction and Disclaimer Card
|
| 796 |
with gr.Group(elem_classes="dashboard-card-section"):
|
| 797 |
-
#
|
| 798 |
-
gr.Markdown("<h3 class='sub-section-title'>Welcome & Disclaimer</h3>", elem_classes="
|
| 799 |
gr.Markdown(
|
| 800 |
"""
|
| 801 |
Navigate landlord-tenant laws with ease. This assistant provides detailed, state-specific answers grounded in legal authority.
|
|
@@ -806,8 +817,8 @@ Answer:"""
|
|
| 806 |
|
| 807 |
# OpenAI API Key Input Card
|
| 808 |
with gr.Group(elem_classes="dashboard-card-section"):
|
| 809 |
-
#
|
| 810 |
-
gr.Markdown("<h3 class='sub-section-title'>OpenAI API Key</h3>", elem_classes="
|
| 811 |
api_key_input = gr.Textbox(
|
| 812 |
label="API Key",
|
| 813 |
type="password", # Hides the input for security
|
|
@@ -819,8 +830,8 @@ Answer:"""
|
|
| 819 |
|
| 820 |
# Query Input and State Selection Card
|
| 821 |
with gr.Group(elem_classes="dashboard-card-section"):
|
| 822 |
-
#
|
| 823 |
-
gr.Markdown("<h3 class='sub-section-title'>Ask Your Question</h3>", elem_classes="
|
| 824 |
with gr.Row(elem_classes="input-row"): # Row for side-by-side query and state
|
| 825 |
with gr.Column(elem_classes="input-field", scale=3): # Query text area takes more space
|
| 826 |
query_input = gr.Textbox(
|
|
@@ -836,7 +847,7 @@ Answer:"""
|
|
| 836 |
choices=dropdown_choices,
|
| 837 |
value=initial_value,
|
| 838 |
allow_custom_value=False,
|
| 839 |
-
elem_classes=["input-field-group"]
|
| 840 |
)
|
| 841 |
with gr.Row(elem_classes="button-row"): # Row for action buttons
|
| 842 |
clear_button = gr.Button("Clear", variant="secondary", elem_classes=["gr-button-secondary"])
|
|
@@ -844,8 +855,8 @@ Answer:"""
|
|
| 844 |
|
| 845 |
# Output Display Card - Using gr.HTML for better animation control
|
| 846 |
with gr.Group(elem_classes="dashboard-card-section"):
|
| 847 |
-
#
|
| 848 |
-
gr.Markdown("<h3 class='sub-section-title'>Legal Assistant's Response</h3>", elem_classes="
|
| 849 |
output = gr.HTML( # Changed to gr.HTML to wrap content with animation class
|
| 850 |
value="<div class='placeholder'>The answer will appear here after submitting your query.</div>",
|
| 851 |
elem_classes="output-content-wrapper" # Custom class for output styling
|
|
@@ -853,8 +864,8 @@ Answer:"""
|
|
| 853 |
|
| 854 |
# Example Questions Section
|
| 855 |
with gr.Group(elem_classes="dashboard-card-section examples-section"):
|
| 856 |
-
#
|
| 857 |
-
gr.Markdown("<h3 class='sub-section-title'>Example Questions</h3>", elem_classes="
|
| 858 |
if example_queries:
|
| 859 |
gr.Examples(
|
| 860 |
examples=example_queries,
|
|
|
|
| 268 |
|
| 269 |
try:
|
| 270 |
available_states_list = self.get_states()
|
| 271 |
+
# DEBUG: Print states to console to verify if data is loaded
|
| 272 |
+
print(f"DEBUG: States loaded for dropdown: {available_states_list}")
|
| 273 |
# Ensure "Select a state..." is always the first option
|
| 274 |
dropdown_choices = ["Select a state..."] + (available_states_list if available_states_list and "Error" not in available_states_list[0] else ["Error: States unavailable"])
|
| 275 |
initial_value = dropdown_choices[0] # Set initial value to the prompt
|
| 276 |
+
except Exception as e: # Catch-all for safety
|
| 277 |
+
print(f"DEBUG: Error loading states for dropdown: {e}")
|
| 278 |
dropdown_choices = ["Error: Critical failure loading states"]
|
| 279 |
initial_value = dropdown_choices[0]
|
| 280 |
|
| 281 |
+
|
| 282 |
# Define example queries, filtering based on available states
|
| 283 |
example_queries_base = [
|
| 284 |
["What are the rules for security deposit returns?", "California"],
|
|
|
|
| 367 |
box-shadow: var(--shadow-md) !important;
|
| 368 |
position: relative; /* For potential pseudo-element effects */
|
| 369 |
overflow: hidden; /* For any overflow animations */
|
| 370 |
+
/* text-align: center applied here for general content within wrapper */
|
| 371 |
+
text-align: center !important;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 372 |
}
|
| 373 |
|
| 374 |
.app-header-wrapper::before { /* Subtle background pattern for dynamism */
|
|
|
|
| 388 |
.app-header-logo {
|
| 389 |
font-size: 4.5rem !important; /* Larger icon */
|
| 390 |
margin-bottom: 0.75rem !important;
|
| 391 |
+
display: block !important; /* Make it a block to center it within text-align */
|
| 392 |
color: var(--primary-color) !important; /* Theme color */
|
| 393 |
position: relative;
|
| 394 |
z-index: 1; /* Bring icon to front of pseudo-element */
|
|
|
|
| 412 |
letter-spacing: -0.03em !important; /* Tighter spacing */
|
| 413 |
position: relative;
|
| 414 |
z-index: 1;
|
| 415 |
+
display: inline-block; /* Essential for text-align: center on parent to work for this block */
|
| 416 |
+
max-width: 100%; /* Prevent overflow on smaller screens */
|
| 417 |
}
|
| 418 |
.app-header-tagline {
|
| 419 |
font-size: 1.25rem !important; /* Slightly larger tagline */
|
|
|
|
| 421 |
font-weight: 400 !important;
|
| 422 |
margin: 0 !important;
|
| 423 |
max-width: 700px; /* Constrain tagline width */
|
| 424 |
+
display: inline-block; /* Essential for text-align: center on parent to work for this block */
|
| 425 |
position: relative;
|
| 426 |
z-index: 1;
|
|
|
|
| 427 |
}
|
| 428 |
|
| 429 |
/* Main container with consistent spacing */
|
|
|
|
| 447 |
transform: translateY(-3px) !important; /* More pronounced lift */
|
| 448 |
}
|
| 449 |
|
| 450 |
+
/* NEW: Class to center content within Markdown blocks */
|
| 451 |
+
.text-center-markdown {
|
| 452 |
text-align: center !important;
|
| 453 |
+
width: 100% !important; /* Ensure it takes full width to center its content */
|
| 454 |
+
display: block !important; /* Make sure it's a block level container */
|
| 455 |
}
|
| 456 |
|
| 457 |
+
/* Section titles (h3 inside markdown) */
|
| 458 |
.sub-section-title {
|
| 459 |
font-family: 'Poppins', sans-serif !important;
|
| 460 |
font-size: 1.7rem !important; /* Slightly larger */
|
| 461 |
font-weight: 700 !important; /* Bolder */
|
| 462 |
color: var(--text-primary) !important;
|
|
|
|
| 463 |
margin: 0 0 1.25rem 0 !important; /* More space below title */
|
| 464 |
padding-bottom: 0.75rem !important;
|
| 465 |
border-bottom: 2px solid var(--border-color) !important; /* Underline effect */
|
| 466 |
+
display: inline-block !important; /* Allow it to shrink-wrap its content for proper border-bottom width */
|
|
|
|
| 467 |
letter-spacing: -0.01em !important;
|
| 468 |
+
/* To center this inline-block, its parent (.text-center-markdown) must have text-align: center */
|
| 469 |
}
|
| 470 |
|
| 471 |
/* Specific styling for the welcome/disclaimer markdown content */
|
|
|
|
| 483 |
.gradio-textbox, .gradio-dropdown {
|
| 484 |
margin-bottom: 0.75rem !important;
|
| 485 |
}
|
| 486 |
+
/* Directly targeting internal Gradio input elements for specific background/border */
|
| 487 |
.gradio-textbox textarea,
|
| 488 |
.gradio-textbox input,
|
| 489 |
+
/* Specific targeting for dropdown elements */
|
| 490 |
+
.gradio-dropdown > div.primary-wrap > div > input, /* The input field within the dropdown */
|
| 491 |
+
.gradio-dropdown > div.primary-wrap, /* The main clickable wrapper of the dropdown */
|
| 492 |
+
.gradio-dropdown > div.scroll-hide /* The actual dropdown options list container */
|
| 493 |
{
|
| 494 |
background-color: var(--background-primary) !important; /* Explicitly set background to primary cream */
|
| 495 |
border: 2px solid var(--border-color) !important; /* Clear border */
|
|
|
|
| 501 |
transition: border-color 0.2s ease, box-shadow 0.2s ease !important; /* Smooth transitions */
|
| 502 |
box-shadow: var(--shadow-sm) !important;
|
| 503 |
}
|
| 504 |
+
/* Focus styles */
|
| 505 |
.gradio-textbox textarea:focus,
|
| 506 |
.gradio-textbox input:focus,
|
| 507 |
+
.gradio-dropdown > div.primary-wrap > div > input:focus, /* Focus for dropdown input */
|
| 508 |
+
.gradio-dropdown > div.primary-wrap.focused { /* Focus for dropdown wrapper */
|
| 509 |
outline: none !important;
|
| 510 |
border-color: var(--border-focus) !important; /* Distinct border on focus */
|
| 511 |
box-shadow: 0 0 0 4px rgba(255, 140, 0, 0.2) !important; /* Broader, softer glow on focus */
|
| 512 |
}
|
| 513 |
+
/* Ensure dropdown arrow is styled correctly */
|
| 514 |
+
.gradio-dropdown .primary-wrap .text-lg { /* Targeting the arrow icon itself */
|
| 515 |
+
color: var(--text-secondary) !important; /* Use a neutral color for the arrow */
|
| 516 |
+
}
|
| 517 |
+
/* Handle active/selected state for dropdown options */
|
| 518 |
+
.gradio-dropdown .secondary-wrap > div:hover,
|
| 519 |
+
.gradio-dropdown .secondary-wrap > div.focused,
|
| 520 |
+
.gradio-dropdown .secondary-wrap > div[aria-selected="true"] {
|
| 521 |
+
background-color: var(--background-secondary) !important; /* Highlight on hover/focus/selection */
|
| 522 |
+
color: var(--primary-color) !important; /* Primary color for selected text */
|
| 523 |
+
}
|
| 524 |
+
|
| 525 |
|
| 526 |
/* Label styling for better readability */
|
| 527 |
.gradio-textbox label,
|
|
|
|
| 532 |
margin-bottom: 0.6rem !important;
|
| 533 |
display: block !important;
|
| 534 |
}
|
| 535 |
+
/* Info text styling below inputs (typically .gr-prose or .gr-form in Gradio) */
|
| 536 |
+
.gr-prose {
|
|
|
|
| 537 |
font-size: 0.9rem !important;
|
| 538 |
color: var(--text-secondary) !important;
|
| 539 |
margin-top: 0.4rem !important; /* More space for info text */
|
| 540 |
+
text-align: left !important; /* Ensure info text is left aligned */
|
| 541 |
}
|
| 542 |
/* Input row layout improvements */
|
| 543 |
.input-row {
|
|
|
|
| 573 |
}
|
| 574 |
.gr-button-primary:hover {
|
| 575 |
background-color: var(--primary-hover) !important; /* Explicitly set background */
|
| 576 |
+
box-shadow: var(--shadow-md) !important;
|
| 577 |
transform: translateY(-2px) !important; /* Subtle lift effect on hover */
|
| 578 |
}
|
| 579 |
.gr-button-primary:active { /* Press down effect on click */
|
|
|
|
| 794 |
with gr.Blocks(css=custom_css, title="Landlord-Tenant Rights Assistant") as demo:
|
| 795 |
# Header Section - uses gr.Group for distinct card-like styling
|
| 796 |
with gr.Group(elem_classes="app-header-wrapper"):
|
| 797 |
+
# Using separate Markdown components for each part of the header
|
| 798 |
+
# with the new 'text-center-markdown' class for robust centering.
|
| 799 |
+
gr.Markdown("<span class='app-header-logo'>⚖️</span>", elem_classes="text-center-markdown")
|
| 800 |
+
gr.Markdown("<h1 class='app-header-title'>Landlord-Tenant Rights Assistant</h1>", elem_classes="text-center-markdown")
|
| 801 |
+
gr.Markdown("<p class='app-header-tagline'>Empowering You with State-Specific Legal Insights</p>", elem_classes="text-center-markdown")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 802 |
|
| 803 |
# Main Dashboard Container - acts as a column to stack various sections
|
| 804 |
with gr.Column(elem_classes="main-dashboard-container"):
|
| 805 |
|
| 806 |
# Introduction and Disclaimer Card
|
| 807 |
with gr.Group(elem_classes="dashboard-card-section"):
|
| 808 |
+
# Apply 'text-center-markdown' for section titles
|
| 809 |
+
gr.Markdown("<h3 class='sub-section-title'>Welcome & Disclaimer</h3>", elem_classes="text-center-markdown")
|
| 810 |
gr.Markdown(
|
| 811 |
"""
|
| 812 |
Navigate landlord-tenant laws with ease. This assistant provides detailed, state-specific answers grounded in legal authority.
|
|
|
|
| 817 |
|
| 818 |
# OpenAI API Key Input Card
|
| 819 |
with gr.Group(elem_classes="dashboard-card-section"):
|
| 820 |
+
# Apply 'text-center-markdown' for section titles
|
| 821 |
+
gr.Markdown("<h3 class='sub-section-title'>OpenAI API Key</h3>", elem_classes="text-center-markdown")
|
| 822 |
api_key_input = gr.Textbox(
|
| 823 |
label="API Key",
|
| 824 |
type="password", # Hides the input for security
|
|
|
|
| 830 |
|
| 831 |
# Query Input and State Selection Card
|
| 832 |
with gr.Group(elem_classes="dashboard-card-section"):
|
| 833 |
+
# Apply 'text-center-markdown' for section titles
|
| 834 |
+
gr.Markdown("<h3 class='sub-section-title'>Ask Your Question</h3>", elem_classes="text-center-markdown")
|
| 835 |
with gr.Row(elem_classes="input-row"): # Row for side-by-side query and state
|
| 836 |
with gr.Column(elem_classes="input-field", scale=3): # Query text area takes more space
|
| 837 |
query_input = gr.Textbox(
|
|
|
|
| 847 |
choices=dropdown_choices,
|
| 848 |
value=initial_value,
|
| 849 |
allow_custom_value=False,
|
| 850 |
+
elem_classes=["input-field-group"]
|
| 851 |
)
|
| 852 |
with gr.Row(elem_classes="button-row"): # Row for action buttons
|
| 853 |
clear_button = gr.Button("Clear", variant="secondary", elem_classes=["gr-button-secondary"])
|
|
|
|
| 855 |
|
| 856 |
# Output Display Card - Using gr.HTML for better animation control
|
| 857 |
with gr.Group(elem_classes="dashboard-card-section"):
|
| 858 |
+
# Apply 'text-center-markdown' for section titles
|
| 859 |
+
gr.Markdown("<h3 class='sub-section-title'>Legal Assistant's Response</h3>", elem_classes="text-center-markdown")
|
| 860 |
output = gr.HTML( # Changed to gr.HTML to wrap content with animation class
|
| 861 |
value="<div class='placeholder'>The answer will appear here after submitting your query.</div>",
|
| 862 |
elem_classes="output-content-wrapper" # Custom class for output styling
|
|
|
|
| 864 |
|
| 865 |
# Example Questions Section
|
| 866 |
with gr.Group(elem_classes="dashboard-card-section examples-section"):
|
| 867 |
+
# Apply 'text-center-markdown' for section titles
|
| 868 |
+
gr.Markdown("<h3 class='sub-section-title'>Example Questions</h3>", elem_classes="text-center-markdown")
|
| 869 |
if example_queries:
|
| 870 |
gr.Examples(
|
| 871 |
examples=example_queries,
|