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,
|