Nischal Subedi commited on
Commit
ed1ba16
·
1 Parent(s): c97f068

enhanced UI

Browse files
Files changed (1) hide show
  1. app.py +224 -189
app.py CHANGED
@@ -169,7 +169,7 @@ Answer:"""
169
 
170
  if not answer_text:
171
  logging.warning("LLM returned an empty answer.")
172
- answer_text = "<div class='error-message'>The AI model returned an empty response. This might be due to the query, context limitations, or temporary issues. Please try rephrasing your question or try again later.</div>"
173
  else:
174
  logging.info("LLM generated answer successfully.")
175
 
@@ -192,7 +192,7 @@ Answer:"""
192
  error_message = "Error: The request to the AI model timed out. The service might be busy."
193
  details = "Please try again in a few moments."
194
 
195
- formatted_error = f"<div class='error-message'>{error_message}</div>"
196
  if details:
197
  formatted_error += f"<div class='error-details'>{details}</div>"
198
 
@@ -292,29 +292,31 @@ Answer:"""
292
 
293
  :root {
294
  /* Dark Theme Colors (Default: Legal Noir) */
295
- --app-bg-dark: #12121A; /* Deep, muted black/purple */
296
- --header-bg-dark: #0A0A10; /* Even darker header background */
297
- --main-content-bg-dark: #1E1E2A; /* Slightly lighter surface for main content */
 
298
  --text-primary-dark: #EAEAF0; /* Crisp off-white for main text */
299
  --text-secondary-dark: #A0A0B0; /* Muted light gray for secondary text */
300
  --accent-main-dark: #FFC107; /* Vibrant Gold/Amber for primary accents */
301
  --accent-hover-dark: #E0A800; /* Darker gold on hover */
302
- --border-dark: #333345; /* Subtle dark border */
303
- --shadow-dark: 0 1rem 3rem rgba(0,0,0,0.6); /* Deep, soft shadow for rich contrast */
304
  --focus-ring-dark: rgba(255, 193, 7, 0.4); /* Gold focus ring */
305
  --error-bg-dark: #4D001A; /* Deep red for errors */
306
  --error-text-dark: #FFB3C2; /* Light pink for error text */
307
  --error-border-dark: #990026;
308
 
309
  /* Light Theme Colors (Alternative: Legal Lumen) */
310
- --app-bg-light: #F8F9FA; /* Soft light gray background */
311
- --header-bg-light: #E9ECEF; /* Lighter header background */
312
- --main-content-bg-light: #FFFFFF; /* Pure white for main content */
 
313
  --text-primary-light: #212529; /* Dark charcoal */
314
  --text-secondary-light: #6C757D; /* Muted gray */
315
  --accent-main-light: #007bff; /* Professional blue */
316
  --accent-hover-light: #0056b3; /* Darker blue on hover */
317
- --border-light: #DEE2E6; /* Light border */
318
  --shadow-light: 0 0.8rem 2.5rem rgba(0,0,0,0.15); /* Soft shadow */
319
  --focus-ring-light: rgba(0, 123, 255, 0.3);
320
  --error-bg-light: #F8D7DA;
@@ -324,10 +326,11 @@ Answer:"""
324
  /* General Styling Variables */
325
  --font-family-main: 'Inter', sans-serif;
326
  --font-family-header: 'Playfair Display', serif; /* Elegant serif for titles */
 
327
  --radius-sm: 8px;
328
  --radius-md: 12px;
329
  --radius-lg: 24px; /* Larger radius for a premium, soft feel */
330
- --transition-speed: 0.5s ease-in-out; /* Slower, smoother transitions */
331
  --padding-xl: 4.5rem; /* Extra large padding for spaciousness */
332
  --padding-lg: 3.5rem;
333
  --padding-md: 2.5rem;
@@ -359,7 +362,7 @@ Answer:"""
359
 
360
  /* Global container for content alignment and padding */
361
  .gradio-container > .flex.flex-col {
362
- max-width: 1080px; /* Even wider for a more expansive dashboard feel */
363
  margin: 0 auto !important;
364
  padding: 0 !important; /* Managed by custom classes */
365
  gap: 0 !important;
@@ -368,7 +371,7 @@ Answer:"""
368
 
369
  /* Header styling: dynamic, centralized, and visually connecting */
370
  .app-header-wrapper {
371
- background: var(--header-bg-dark); /* Solid color for header, based on theme */
372
  color: var(--text-primary-dark) !important;
373
  padding: var(--padding-xl) var(--padding-lg) !important;
374
  text-align: center !important;
@@ -379,14 +382,17 @@ Answer:"""
379
  overflow: hidden;
380
  z-index: 10;
381
  transition: background var(--transition-speed), box-shadow var(--transition-speed);
382
- /* NEW: Blend with main content by overlapping its own radius */
383
- margin-bottom: calc(-1 * var(--radius-lg));
 
384
  }
385
  @media (prefers-color-scheme: light) {
386
  .app-header-wrapper {
387
  background: var(--header-bg-light);
388
  color: var(--text-primary-light) !important;
389
  box-shadow: var(--shadow-light);
 
 
390
  }
391
  }
392
 
@@ -399,7 +405,7 @@ Answer:"""
399
  }
400
  .app-header-logo {
401
  font-size: 5.5rem; /* Even larger icon for maximum impact */
402
- margin-bottom: 1.5rem;
403
  line-height: 1;
404
  filter: drop-shadow(0 0 15px var(--accent-main-dark)); /* Stronger glow effect for icon */
405
  transform: translateY(-40px); opacity: 0; /* Initial state for animation */
@@ -412,7 +418,7 @@ Answer:"""
412
  font-family: var(--font-family-header) !important;
413
  font-size: 4.2rem; /* The main title: massive, bold, and dynamic */
414
  font-weight: 900; /* Extra, extra bold */
415
- margin: 0 0 1.2rem 0;
416
  letter-spacing: -0.07em; /* Tighter for a strong presence */
417
  text-shadow: 0 8px 16px rgba(0,0,0,0.5); /* Deepest shadow for depth */
418
  transform: translateY(-40px); opacity: 0;
@@ -438,33 +444,49 @@ Answer:"""
438
  to { opacity: 1; transform: translateY(0); }
439
  }
440
 
441
- /* Main content area: The single, unified block containing all core functionality */
442
- .main-content-area {
443
- background: var(--main-content-bg-dark) !important;
444
  border-radius: var(--radius-lg);
445
  box-shadow: var(--shadow-dark);
446
  border: 1px solid var(--border-dark) !important;
447
- /* Match header's bottom radius on its top */
448
- border-top-left-radius: var(--radius-lg);
449
- border-top-right-radius: var(--radius-lg);
450
- margin: 0 auto 5rem auto; /* General spacing to the footer */
451
- /* New: compensate for header's margin-bottom overlap */
452
- padding-top: calc(var(--padding-xl) + var(--radius-lg)); /* Add back the space lost by header's overlap */
453
- padding-left: var(--padding-xl) !important;
454
- padding-right: var(--padding-xl) !important;
455
- padding-bottom: var(--padding-lg) !important; /* Bottom padding for the whole area */
456
  z-index: 1; /* Ensure it's behind header, but visually seamless */
457
  position: relative;
458
  transition: background var(--transition-speed), border-color var(--transition-speed), box-shadow var(--transition-speed);
 
 
 
459
  }
460
  @media (prefers-color-scheme: light) {
461
- .main-content-area {
462
- background: var(--main-content-bg-light) !important;
463
  box-shadow: var(--shadow-light);
464
  border: 1px solid var(--border-light) !important;
465
  }
466
  }
467
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
468
  /* Section titles within the unified main content area */
469
  .section-title { /* For 'Know Your Rights' */
470
  font-family: var(--font-family-header) !important;
@@ -472,20 +494,20 @@ Answer:"""
472
  font-weight: 800 !important; /* Extra bold */
473
  color: var(--text-primary-dark) !important;
474
  text-align: center !important;
475
- margin: 0 auto 3.5rem auto !important; /* More space below */
476
- padding-bottom: 1.5rem !important;
477
  border-bottom: 2px solid var(--border-dark) !important;
478
  width: 100%;
479
  transition: color var(--transition-speed), border-color var(--transition-speed);
480
  }
481
- .sub-section-title { /* For 'Ask Your Question', 'Answer', 'Explore Sample Questions' */
482
  font-family: var(--font-family-header) !important;
483
  font-size: 2rem !important; /* Slightly smaller for sub-sections */
484
  font-weight: 700 !important;
485
  color: var(--text-primary-dark) !important;
486
- text-align: center !important;
487
- margin-top: 3rem !important; /* Tighter vertical spacing for more cohesive display */
488
- margin-bottom: 1.5rem !important; /* Tighter coupling to content */
489
  transition: color var(--transition-speed);
490
  }
491
  @media (prefers-color-scheme: light) {
@@ -496,55 +518,54 @@ Answer:"""
496
  }
497
 
498
  /* General text styling within main content: highly legible */
499
- .main-content-area p {
500
  font-size: 1.15rem; /* Larger, more readable body text */
501
  line-height: 1.8; /* Generous line height for comfort */
502
  color: var(--text-secondary-dark);
503
- margin-bottom: 1.5rem;
504
  transition: color var(--transition-speed);
505
  }
506
- .main-content-area a {
507
  color: var(--accent-main-dark);
508
  text-decoration: none;
509
  font-weight: 500;
510
  transition: color var(--transition-speed), text-decoration var(--transition-speed);
511
  }
512
- .main-content-area a:hover {
513
  color: var(--accent-hover-dark);
514
  text-decoration: underline;
515
  }
516
- .main-content-area strong {
517
  font-weight: 700;
518
  color: var(--text-primary-dark);
519
  transition: color var(--transition-speed);
520
  }
521
  @media (prefers-color-scheme: light) {
522
- .main-content-area p { color: var(--text-secondary-light); }
523
- .main-content-area a { color: var(--accent-main-light); }
524
- .main-content-area a:hover { color: var(--accent-hover-light); }
525
- .main-content-area strong { color: var(--text-primary-light); }
526
  }
527
 
528
  /* Horizontal rule for visual separation within the main block */
529
  .section-divider {
530
  border: none;
531
  border-top: 1px solid var(--border-dark); /* Subtle, but present for structure */
532
- margin: 4rem 0; /* Adjusted for better overall flow */
533
  transition: border-color var(--transition-speed);
534
  }
535
  @media (prefers-color-scheme: light) { .section-divider { border-top: 1px solid var(--border-light); } }
536
 
537
  /* Input field groups and layout: spacious and clear */
538
- .input-field-group { margin-bottom: 2rem; } /* Adjusted for tighter coupling */
539
  .input-row {
540
  display: flex;
541
- gap: 3rem; /* Still generous space between inputs */
542
  flex-wrap: wrap;
543
- margin-bottom: 3rem; /* Adjusted for tighter coupling to buttons */
544
  }
545
  .input-field {
546
- flex: 1;
547
- min-width: 350px; /* Wider min-width for larger inputs */
548
  }
549
 
550
  /* Input labels and info text: prominent and clear */
@@ -552,7 +573,7 @@ Answer:"""
552
  font-size: 1.2rem !important; /* Larger, more prominent labels */
553
  font-weight: 500 !important;
554
  color: var(--text-primary-dark) !important;
555
- margin-bottom: 1rem !important;
556
  display: block !important;
557
  transition: color var(--transition-speed);
558
  }
@@ -575,7 +596,7 @@ Answer:"""
575
  border-radius: var(--radius-md) !important;
576
  padding: 1.3rem 1.6rem !important; /* Even more padding */
577
  font-size: 1.15rem !important; /* Larger font size */
578
- background: var(--main-content-bg-dark) !important;
579
  color: var(--text-primary-dark) !important;
580
  width: 100% !important;
581
  box-shadow: inset 0 1px 3px rgba(0,0,0,0.3); /* Inner shadow for depth */
@@ -596,7 +617,7 @@ Answer:"""
596
  .gradio-dropdown select,
597
  .gradio-textbox input[type=password] {
598
  border: 2px solid var(--border-light) !important;
599
- background: var(--main-content-bg-light) !important;
600
  color: var(--text-primary-light) !important;
601
  box-shadow: inset 0 1px 3px rgba(0,0,0,0.1);
602
  }
@@ -628,8 +649,8 @@ Answer:"""
628
  /* Button group and styling: dynamic and clear actions */
629
  .button-row {
630
  display: flex;
631
- gap: 2.5rem;
632
- margin-top: 2.5rem;
633
  flex-wrap: wrap;
634
  justify-content: flex-end;
635
  }
@@ -658,7 +679,7 @@ Answer:"""
658
  /* Primary button */
659
  .gr-button-primary {
660
  background: var(--accent-main-dark) !important;
661
- color: #12121A !important; /* Dark text on gold */
662
  border-color: var(--accent-main-dark) !important;
663
  }
664
  .gr-button-primary:hover:not(:disabled) {
@@ -709,11 +730,16 @@ Answer:"""
709
  }
710
 
711
  /* Output Styling within the main content area */
712
- .output-card .response-header {
 
 
 
 
 
713
  font-size: 1.8rem; /* Larger and clearer */
714
  font-weight: 700;
715
  color: var(--text-primary-dark);
716
- margin: 0 0 1.5rem 0;
717
  display: flex;
718
  align-items: center;
719
  gap: 1.2rem;
@@ -727,10 +753,10 @@ Answer:"""
727
  .output-card .divider {
728
  border: none;
729
  border-top: 1px solid var(--border-dark);
730
- margin: 2rem 0 2.5rem 0;
731
  transition: border-color var(--transition-speed);
732
  }
733
- .output-card .output-content-wrapper {
734
  font-size: 1.15rem; /* Highly legible output text */
735
  line-height: 1.8;
736
  color: var(--text-primary-dark);
@@ -765,9 +791,9 @@ Answer:"""
765
  }
766
 
767
  /* Error messages: clear, prominent, and legible */
768
- .output-card .error-message {
769
- padding: 1.8rem 2.5rem;
770
- margin-top: 2.5rem;
771
  font-size: 1.1rem;
772
  border-radius: var(--radius-md);
773
  background: var(--error-bg-dark);
@@ -798,9 +824,9 @@ Answer:"""
798
  }
799
 
800
  /* Output placeholder styling: inviting and distinct */
801
- .output-card .placeholder {
802
- padding: 5rem 2rem;
803
- font-size: 1.3rem; /* Larger, more inviting placeholder */
804
  border-radius: var(--radius-md);
805
  border: 3px dashed var(--border-dark); /* Thicker dashed border */
806
  color: var(--text-secondary-dark);
@@ -817,41 +843,37 @@ Answer:"""
817
 
818
  /* Examples table styling: integrated within the main content block, but with clear visual identity */
819
  /* Applied to the gr.Column that wraps the examples */
820
- .examples-section {
821
- padding-top: 4.5rem; /* Generous top padding to separate from Answer section */
822
- /* No background/border/shadow here, as it's part of the main-content-area */
823
- }
824
  .examples-section .gr-examples-table {
825
  border-radius: var(--radius-md) !important;
826
  border: 1px solid var(--border-dark) !important;
827
  overflow: hidden;
828
- background: var(--main-content-bg-dark) !important; /* Ensure table matches main content background */
829
  box-shadow: inset 0 0 10px rgba(0,0,0,0.2); /* Subtle inner shadow */
830
  transition: border-color var(--transition-speed), background var(--transition-speed), box-shadow var(--transition-speed);
831
  }
832
  @media (prefers-color-scheme: light) {
833
  .examples-section .gr-examples-table {
834
  border: 1px solid var(--border-light) !important;
835
- background: var(--main-content-bg-light) !important;
836
  box-shadow: inset 0 0 8px rgba(0,0,0,0.05);
837
  }
838
  }
839
 
840
  .examples-section .gr-examples-table th,
841
  .examples-section .gr-examples-table td {
842
- padding: 1.1rem 1.4rem !important; /* Slightly reduced padding for tighter coupling */
843
  font-size: 1.05rem !important;
844
  border: none !important;
845
  }
846
  .examples-section .gr-examples-table th {
847
- background: var(--app-bg-dark) !important; /* Match app background for table header */
848
  color: var(--text-primary-dark) !important;
849
  font-weight: 600 !important;
850
  text-align: left;
851
  transition: background var(--transition-speed), color var(--transition-speed);
852
  }
853
  .examples-section .gr-examples-table td {
854
- background: var(--main-content-bg-dark) !important;
855
  color: var(--text-primary-dark) !important;
856
  border-top: 1px solid var(--border-dark) !important;
857
  cursor: pointer;
@@ -863,20 +885,20 @@ Answer:"""
863
  .examples-section .gr-examples-table tr:first-child td { border-top: none !important; }
864
 
865
  @media (prefers-color-scheme: light) {
866
- .examples-section .gr-examples-table { border: 1px solid var(--border-light) !important; background: var(--main-content-bg-light) !important; }
867
- .examples-section .gr-examples-table th { background: var(--app-bg-light) !important; color: var(--text-primary-light) !important; }
868
- .examples-section .gr-examples-table td { background: var(--main-content-bg-light) !important; color: var(--text-primary-light) !important; border-top: 1px solid var(--border-light) !important; }
869
  .examples-section .gr-examples-table tr:hover td { background: rgba(0, 123, 255, 0.08) !important; }
870
  }
871
 
872
 
873
  /* Footer styling: clean and informative, integrated at the very bottom */
874
  .app-footer-wrapper {
875
- background: var(--header-bg-dark); /* Match header/app background for consistency */
876
  border-top: 1px solid var(--border-dark) !important;
877
- margin-top: 5rem; /* Reduced space from last content for cohesion */
878
- padding-top: 4rem;
879
- padding-bottom: 4rem;
880
  border-top-left-radius: var(--radius-lg);
881
  border-top-right-radius: var(--radius-lg);
882
  box-shadow: inset 0 8px 15px rgba(0,0,0,0.2); /* Inset shadow for depth */
@@ -935,19 +957,36 @@ Answer:"""
935
  }
936
  .gradio-button span:focus { outline: none !important; }
937
 
938
- /* Gradio Overrides for full control - PERMANENTLY HIDE UNWANTED LABELS */
939
- .gradio-container > .flex { gap: 0 !important; }
940
- .gradio-markdown > *:first-child { margin-top: 0; }
941
- .gradio-markdown > *:last-child { margin-bottom: 0; }
942
- .gradio-dropdown, .gradio-textbox { border: none !important; padding: 0 !important; background: transparent !important; }
943
-
944
- /* MOST AGGRESSIVE "FALSE" REMOVAL - GRADIO'S INTERNAL LABELS ARE PURE EVIL */
945
- /* These cover various Gradio versions and nesting patterns */
946
- .gr-box.gr-component.gradio-example { position: relative !important; } /* Needed for absolute positioning if child is default label */
947
- .gr-examples .gradio-html div[dir="auto"].primary span { display: none !important; } /* Hides "false" directly */
948
- .gr-examples-header { display: none !important; } /* Hides default Gradio example header */
949
- .gr-examples .label-wrap { display: none !important; } /* Targets another common label wrapper */
950
- .gr-label { display: none !important; } /* General label suppression for Gradio 4.0+ if it's generic */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
951
 
952
 
953
  /* Responsive Adjustments (meticulously refined) */
@@ -955,72 +994,70 @@ Answer:"""
955
  .gradio-container > .flex.flex-col { max-width: 960px; padding: 0 1.5rem !important; }
956
  .app-header-title { font-size: 3.8rem; }
957
  .app-header-tagline { font-size: 1.5rem; }
958
- .app-header-wrapper { margin-bottom: calc(-1 * var(--radius-md)); /* Smaller radius for smaller screens */ }
959
- .main-content-area { padding: var(--padding-lg) var(--padding-lg) !important; border-top-left-radius: var(--radius-md); border-top-right-radius: var(--radius-md); }
960
- .main-content-area { padding-top: calc(var(--padding-lg) + var(--radius-md)); }
961
- .section-title { font-size: 2.2rem !important; margin-bottom: 3rem !important; }
962
- .sub-section-title { font-size: 1.8rem !important; margin-top: 3rem !important; margin-bottom: 1.5rem !important; }
963
- .section-divider { margin: 3.5rem 0; }
964
- .input-row { gap: 2.5rem; }
965
- .input-field { min-width: 300px; }
966
  .gradio-textbox textarea { min-height: 160px; }
967
  .output-card .response-header { font-size: 1.7rem; }
968
- .examples-section { padding-top: 4rem; }
969
- .examples-section .gr-examples-table th, .examples-section .gr-examples-table td { padding: 1.1rem 1.4rem !important; }
970
- .app-footer-wrapper { margin-top: 4rem; border-top-left-radius: var(--radius-md); border-top-right-radius: var(--radius-md); }
971
  }
972
 
973
  @media (max-width: 768px) {
974
  .gradio-container > .flex.flex-col { padding: 0 1rem !important; }
975
- .app-header-wrapper { padding: var(--padding-md) var(--padding-md) !important; border-bottom-left-radius: var(--radius-md); border-bottom-right-radius: var(--radius-md); }
976
- .app-header-logo { font-size: 4.5rem; margin-bottom: 1rem; }
977
  .app-header-title { font-size: 3.2rem; letter-spacing: -0.06em; }
978
  .app-header-tagline { font-size: 1.3rem; }
979
- .app-header-wrapper { margin-bottom: calc(-1 * var(--radius-md)); }
980
- .main-content-area { padding: var(--padding-md) var(--padding-md) !important; border-radius: var(--radius-md); border-top-left-radius: var(--radius-md); border-top-right-radius: var(--radius-md); }
981
- .main-content-area { padding-top: calc(var(--padding-md) + var(--radius-md)); }
982
- .section-title { font-size: 2rem !important; margin-bottom: 2.5rem !important; padding-bottom: 1.2rem !important; }
983
- .sub-section-title { font-size: 1.6rem !important; margin-top: 3rem !important; margin-bottom: 1.5rem !important; }
984
- .section-divider { margin: 3rem 0; }
985
- .input-row { flex-direction: column; gap: 2rem; }
986
  .input-field { min-width: 100%; }
987
  .gradio-textbox textarea { min-height: 140px; }
988
- .button-row { justify-content: stretch; gap: 1.5rem; }
989
  .gradio-button { width: 100%; padding: 1.1rem 2rem !important; font-size: 1.1rem !important; }
990
  .output-card .response-header { font-size: 1.5rem; }
991
  .output-card .response-icon { font-size: 1.7rem; }
992
- .output-card .placeholder { padding: 4rem 1.5rem; font-size: 1.2rem; }
993
- .examples-section { padding-top: 3rem; }
994
- .examples-section .gr-examples-table th, .examples-section .gr-examples-table td { padding: 1rem 1.2rem !important; font-size: 1.0rem !important; }
995
- .app-footer-wrapper { margin-top: 3.5rem; padding-top: 2.5rem; padding-bottom: 2.5rem; border-top-left-radius: var(--radius-md); border-top-right-radius: var(--radius-md); }
996
  }
997
 
998
  @media (max-width: 480px) {
999
  .gradio-container > .flex.flex-col { padding: 0 0.8rem !important; }
1000
- .app-header-wrapper { padding: var(--padding-sm) 1rem !important; border-bottom-left-radius: var(--radius-sm); border-bottom-right-radius: var(--radius-sm); }
1001
- .app-header-logo { font-size: 3.8rem; margin-bottom: 0.8rem; }
1002
  .app-header-title { font-size: 2.8rem; }
1003
  .app-header-tagline { font-size: 1.1rem; }
1004
- .app-header-wrapper { margin-bottom: calc(-1 * var(--radius-sm)); }
1005
- .main-content-area { padding: var(--padding-sm) 1rem !important; border-radius: var(--radius-sm); border-top-left-radius: var(--radius-sm); border-top-right-radius: var(--radius-sm); }
1006
- .main-content-area { padding-top: calc(var(--padding-sm) + var(--radius-sm)); }
1007
- .section-title { font-size: 1.8rem !important; margin-bottom: 2rem !important; padding-bottom: 1rem !important; }
1008
- .sub-section-title { font-size: 1.4rem !important; margin-top: 2.5rem !important; margin-bottom: 1.2rem !important; }
1009
- .section-divider { margin: 2.5rem 0; }
1010
  .gradio-textbox textarea, .gradio-dropdown select, .gradio-textbox input[type=password] { font-size: 1.05rem !important; padding: 1rem 1.2rem !important; }
1011
  .gradio-textbox textarea { min-height: 120px; }
1012
  .gradio-button { padding: 1rem 1.5rem !important; font-size: 1rem !important; }
1013
  .output-card .response-header { font-size: 1.4rem; }
1014
  .output-card .response-icon { font-size: 1.5rem; }
1015
- .output-card .placeholder { padding: 3.5rem 1rem; font-size: 1.1rem; }
1016
- .examples-section { padding-top: 2.5rem; }
1017
- .examples-section .gr-examples-table th, .examples-section .gr-examples-table td { padding: 0.8rem 1rem !important; font-size: 0.95rem !important; }
1018
- .app-footer-wrapper { margin-top: 3rem; padding-top: 2rem; padding-bottom: 2rem; border-top-left-radius: var(--radius-sm); border-top-right-radius: var(--radius-sm); }
1019
  }
1020
  """
1021
 
1022
  with gr.Blocks(theme=None, css=custom_css, title="Landlord-Tenant Rights Assistant") as demo:
1023
- # --- Header Section: Truly dynamic and bold, with animations ---
1024
  with gr.Group(elem_classes="app-header-wrapper"):
1025
  gr.Markdown(
1026
  """
@@ -1032,68 +1069,66 @@ Answer:"""
1032
  """
1033
  )
1034
 
1035
- # --- Main Content Area: A single, unified block containing all core functionality ---
1036
- # This is the key change for cohesion. All inner sections are now part of this one group.
1037
- with gr.Group(elem_classes="main-content-area"):
1038
-
1039
- # "Know Your Rights" Section
1040
- gr.Markdown("<h3 class='section-title'>Know Your Rights</h3>")
1041
- gr.Markdown(
1042
- """
1043
- <p>Navigate landlord-tenant laws with ease. Enter your <strong>OpenAI API key</strong>, select your state, and ask your question to get detailed, state-specific answers.</p>
1044
- <p>Don't have an API key? <a href='https://platform.openai.com/api-keys' target='_blank'>Get one free from OpenAI</a>.</p>
1045
- <p><strong>Disclaimer:</strong> This tool provides information only, not legal advice. For legal guidance, always consult a licensed attorney.</p>
1046
- """
1047
- )
1048
-
1049
- gr.HTML("<hr class='section-divider'>") # Aesthetic divider for internal separation
1050
 
1051
- # "Ask Your Question" Section (Input Form)
1052
- gr.Markdown("<h3>Ask Your Question</h3>", elem_classes="sub-section-title")
1053
- with gr.Column(elem_classes="input-field-group"):
1054
  api_key_input = gr.Textbox(
1055
  label="OpenAI API Key", type="password", placeholder="Enter your API key (e.g., sk-...)",
1056
- info="Required to process your query. Securely used per request, not stored.", lines=1
1057
  )
1058
- with gr.Row(elem_classes="input-row"):
1059
- with gr.Column(elem_classes="input-field", min_width="58%"):
1060
- query_input = gr.Textbox(
1061
- label="Your Question", placeholder="E.g., What are the rules for security deposit returns in my state?",
1062
- lines=5, max_lines=10
1063
- )
1064
- with gr.Column(elem_classes="input-field", min_width="38%"):
1065
- state_input = gr.Dropdown(
1066
- label="Select State", choices=dropdown_choices, value=initial_value,
1067
- allow_custom_value=False
1068
- )
1069
- with gr.Row(elem_classes="button-row"):
1070
- clear_button = gr.Button("Clear", variant="secondary", elem_classes=["gr-button-secondary"])
1071
- submit_button = gr.Button("Submit Query", variant="primary", elem_classes=["gr-button-primary"])
1072
-
1073
- gr.HTML("<hr class='section-divider'>") # Another divider for separation
1074
-
1075
- # Output Section
1076
- gr.Markdown("<h3>Answer</h3>", elem_classes="sub-section-title")
1077
- output = gr.Markdown(
1078
- value="<div class='placeholder output-card'>Your answer will appear here after submitting your query.</div>",
1079
- elem_classes="output-content-wrapper output-card" # Apply these classes for styling
1080
- )
1081
-
1082
- # --- "Explore Sample Questions" Section: Integrated within the main unified block ---
1083
- # Fixed: Wrap gr.Examples in a gr.Column to apply elem_classes correctly.
1084
- with gr.Column(elem_classes="examples-section"): # Apply 'examples-section' class to this wrapper
1085
- gr.Markdown("<h3>Explore Sample Questions</h3>", elem_classes="sub-section-title")
 
 
1086
  if example_queries:
1087
  gr.Examples(
1088
  examples=example_queries, inputs=[query_input, state_input],
1089
  examples_per_page=5,
1090
- label=False, # This is crucial to hide the default "false" label
1091
  )
1092
  else:
1093
  gr.Markdown("<div class='placeholder'>Sample questions could not be loaded.</div>")
1094
 
1095
- # --- Footer Section: Designed to blend harmoniously with header's aesthetic ---
1096
- # It matches the header's background, creating a top-bottom "frame" around the main content.
1097
  with gr.Group(elem_classes="app-footer-wrapper"):
1098
  gr.Markdown(
1099
  """
@@ -1119,7 +1154,7 @@ Answer:"""
1119
  ),
1120
  inputs=[], outputs=[api_key_input, query_input, state_input, output]
1121
  )
1122
- logging.info("Fully cohesive, dynamic, and legible Gradio interface created with Legal Noir theme.")
1123
  return demo
1124
 
1125
  # --- Main Execution Block (remains untouched from original logic) ---
@@ -1127,8 +1162,8 @@ if __name__ == "__main__":
1127
  logging.info("Starting Landlord-Tenant Rights Bot application...")
1128
  try:
1129
  SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
1130
- DEFAULT_PDF_PATH = os.path.join(SCRIPT_DIR, "tenant-landlord.pdf")
1131
- DEFAULT_DB_PATH = os.path.join(SCRIPT_DIR, "chroma_db")
1132
 
1133
  # Use environment variables if set, otherwise default paths
1134
  PDF_PATH = os.getenv("PDF_PATH", DEFAULT_PDF_PATH)
 
169
 
170
  if not answer_text:
171
  logging.warning("LLM returned an empty answer.")
172
+ answer_text = "<div class='error-message'><span class='error-icon'>⚠️</span>The AI model returned an empty response. This might be due to the query, context limitations, or temporary issues. Please try rephrasing your question or try again later.</div>"
173
  else:
174
  logging.info("LLM generated answer successfully.")
175
 
 
192
  error_message = "Error: The request to the AI model timed out. The service might be busy."
193
  details = "Please try again in a few moments."
194
 
195
+ formatted_error = f"<div class='error-message'><span class='error-icon'>❌</span>{error_message}</div>"
196
  if details:
197
  formatted_error += f"<div class='error-details'>{details}</div>"
198
 
 
292
 
293
  :root {
294
  /* Dark Theme Colors (Default: Legal Noir) */
295
+ --app-bg-dark: #0F0F1A; /* Very dark blue-purple for the absolute background */
296
+ --header-bg-dark: #1A1A2B; /* Darker, slightly more saturated for header/footer elements */
297
+ --main-card-bg-dark: #1E1E30; /* Main content "console" background */
298
+ --card-section-bg-dark: #2A2A40; /* Background for individual cards within the console */
299
  --text-primary-dark: #EAEAF0; /* Crisp off-white for main text */
300
  --text-secondary-dark: #A0A0B0; /* Muted light gray for secondary text */
301
  --accent-main-dark: #FFC107; /* Vibrant Gold/Amber for primary accents */
302
  --accent-hover-dark: #E0A800; /* Darker gold on hover */
303
+ --border-dark: #3F3F5A; /* Subtle dark border */
304
+ --shadow-dark: 0 1.2rem 3.5rem rgba(0,0,0,0.6); /* Deep, soft shadow for rich contrast */
305
  --focus-ring-dark: rgba(255, 193, 7, 0.4); /* Gold focus ring */
306
  --error-bg-dark: #4D001A; /* Deep red for errors */
307
  --error-text-dark: #FFB3C2; /* Light pink for error text */
308
  --error-border-dark: #990026;
309
 
310
  /* Light Theme Colors (Alternative: Legal Lumen) */
311
+ --app-bg-light: #F0F2F5; /* Soft light gray background */
312
+ --header-bg-light: #E0E4EB; /* Lighter header/footer elements */
313
+ --main-card-bg-light: #FFFFFF; /* Pure white for main content "console" */
314
+ --card-section-bg-light: #F8F9FA; /* Background for individual cards within the console */
315
  --text-primary-light: #212529; /* Dark charcoal */
316
  --text-secondary-light: #6C757D; /* Muted gray */
317
  --accent-main-light: #007bff; /* Professional blue */
318
  --accent-hover-light: #0056b3; /* Darker blue on hover */
319
+ --border-light: #DDE2E8; /* Light border */
320
  --shadow-light: 0 0.8rem 2.5rem rgba(0,0,0,0.15); /* Soft shadow */
321
  --focus-ring-light: rgba(0, 123, 255, 0.3);
322
  --error-bg-light: #F8D7DA;
 
326
  /* General Styling Variables */
327
  --font-family-main: 'Inter', sans-serif;
328
  --font-family-header: 'Playfair Display', serif; /* Elegant serif for titles */
329
+ --radius-xs: 4px;
330
  --radius-sm: 8px;
331
  --radius-md: 12px;
332
  --radius-lg: 24px; /* Larger radius for a premium, soft feel */
333
+ --transition-speed: 0.4s ease-in-out; /* Slightly faster, smoother transitions */
334
  --padding-xl: 4.5rem; /* Extra large padding for spaciousness */
335
  --padding-lg: 3.5rem;
336
  --padding-md: 2.5rem;
 
362
 
363
  /* Global container for content alignment and padding */
364
  .gradio-container > .flex.flex-col {
365
+ max-width: 1120px; /* Even wider for a more expansive dashboard feel */
366
  margin: 0 auto !important;
367
  padding: 0 !important; /* Managed by custom classes */
368
  gap: 0 !important;
 
371
 
372
  /* Header styling: dynamic, centralized, and visually connecting */
373
  .app-header-wrapper {
374
+ background: var(--header-bg-dark);
375
  color: var(--text-primary-dark) !important;
376
  padding: var(--padding-xl) var(--padding-lg) !important;
377
  text-align: center !important;
 
382
  overflow: hidden;
383
  z-index: 10;
384
  transition: background var(--transition-speed), box-shadow var(--transition-speed);
385
+ margin-bottom: 2.5rem; /* Space between header and main console */
386
+ border: 1px solid var(--border-dark); /* Subtle frame */
387
+ border-top: none; /* No top border for flush with screen top */
388
  }
389
  @media (prefers-color-scheme: light) {
390
  .app-header-wrapper {
391
  background: var(--header-bg-light);
392
  color: var(--text-primary-light) !important;
393
  box-shadow: var(--shadow-light);
394
+ border: 1px solid var(--border-light);
395
+ border-top: none;
396
  }
397
  }
398
 
 
405
  }
406
  .app-header-logo {
407
  font-size: 5.5rem; /* Even larger icon for maximum impact */
408
+ margin-bottom: 0.8rem; /* Further reduced margin */
409
  line-height: 1;
410
  filter: drop-shadow(0 0 15px var(--accent-main-dark)); /* Stronger glow effect for icon */
411
  transform: translateY(-40px); opacity: 0; /* Initial state for animation */
 
418
  font-family: var(--font-family-header) !important;
419
  font-size: 4.2rem; /* The main title: massive, bold, and dynamic */
420
  font-weight: 900; /* Extra, extra bold */
421
+ margin: 0 0 0.8rem 0; /* Further reduced margin */
422
  letter-spacing: -0.07em; /* Tighter for a strong presence */
423
  text-shadow: 0 8px 16px rgba(0,0,0,0.5); /* Deepest shadow for depth */
424
  transform: translateY(-40px); opacity: 0;
 
444
  to { opacity: 1; transform: translateY(0); }
445
  }
446
 
447
+ /* --- NEW: Main Dashboard Console Container --- */
448
+ .main-dashboard-container {
449
+ background: var(--main-card-bg-dark) !important;
450
  border-radius: var(--radius-lg);
451
  box-shadow: var(--shadow-dark);
452
  border: 1px solid var(--border-dark) !important;
453
+ padding: var(--padding-lg) !important; /* Overall padding for the console */
454
+ margin: 0 auto 0.8rem auto; /* Adjusted for tighter gap */
 
 
 
 
 
 
 
455
  z-index: 1; /* Ensure it's behind header, but visually seamless */
456
  position: relative;
457
  transition: background var(--transition-speed), border-color var(--transition-speed), box-shadow var(--transition-speed);
458
+ display: flex;
459
+ flex-direction: column;
460
+ gap: 2.5rem; /* Space between the main "cards" inside the console */
461
  }
462
  @media (prefers-color-scheme: light) {
463
+ .main-dashboard-container {
464
+ background: var(--main-card-bg-light) !important;
465
  box-shadow: var(--shadow-light);
466
  border: 1px solid var(--border-light) !important;
467
  }
468
  }
469
 
470
+ /* --- NEW: Card Sections within the Main Console --- */
471
+ .dashboard-card-section {
472
+ background: var(--card-section-bg-dark) !important;
473
+ border-radius: var(--radius-md);
474
+ border: 1px solid var(--border-dark);
475
+ padding: var(--padding-md); /* Padding inside each card section */
476
+ box-shadow: inset 0 0 10px rgba(0,0,0,0.2); /* Subtle inner shadow for depth */
477
+ transition: background var(--transition-speed), border-color var(--transition-speed), box-shadow var(--transition-speed);
478
+ display: flex;
479
+ flex-direction: column;
480
+ gap: 1.5rem; /* Space between elements within a card section */
481
+ }
482
+ @media (prefers-color-scheme: light) {
483
+ .dashboard-card-section {
484
+ background: var(--card-section-bg-light) !important;
485
+ border: 1px solid var(--border-light);
486
+ box-shadow: inset 0 0 8px rgba(0,0,0,0.05);
487
+ }
488
+ }
489
+
490
  /* Section titles within the unified main content area */
491
  .section-title { /* For 'Know Your Rights' */
492
  font-family: var(--font-family-header) !important;
 
494
  font-weight: 800 !important; /* Extra bold */
495
  color: var(--text-primary-dark) !important;
496
  text-align: center !important;
497
+ margin: 0 auto 1.8rem auto !important; /* Reduced margin from 2.5rem */
498
+ padding-bottom: 0.8rem !important; /* Reduced padding from 1rem */
499
  border-bottom: 2px solid var(--border-dark) !important;
500
  width: 100%;
501
  transition: color var(--transition-speed), border-color var(--transition-speed);
502
  }
503
+ .sub-section-title { /* For 'Ask Your Question', 'Example Questions to Ask' */
504
  font-family: var(--font-family-header) !important;
505
  font-size: 2rem !important; /* Slightly smaller for sub-sections */
506
  font-weight: 700 !important;
507
  color: var(--text-primary-dark) !important;
508
+ text-align: center !important; /* Ensures centering for all sub-section titles */
509
+ margin-top: 1.5rem !important; /* Reduced from 2rem */
510
+ margin-bottom: 0.8rem !important; /* Reduced from 1rem */
511
  transition: color var(--transition-speed);
512
  }
513
  @media (prefers-color-scheme: light) {
 
518
  }
519
 
520
  /* General text styling within main content: highly legible */
521
+ .dashboard-card-section p, .output-content-wrapper p {
522
  font-size: 1.15rem; /* Larger, more readable body text */
523
  line-height: 1.8; /* Generous line height for comfort */
524
  color: var(--text-secondary-dark);
525
+ margin-bottom: 1.2rem; /* Reduced from 1.5rem */
526
  transition: color var(--transition-speed);
527
  }
528
+ .dashboard-card-section a, .output-content-wrapper a {
529
  color: var(--accent-main-dark);
530
  text-decoration: none;
531
  font-weight: 500;
532
  transition: color var(--transition-speed), text-decoration var(--transition-speed);
533
  }
534
+ .dashboard-card-section a:hover, .output-content-wrapper a:hover {
535
  color: var(--accent-hover-dark);
536
  text-decoration: underline;
537
  }
538
+ .dashboard-card-section strong, .output-content-wrapper strong {
539
  font-weight: 700;
540
  color: var(--text-primary-dark);
541
  transition: color var(--transition-speed);
542
  }
543
  @media (prefers-color-scheme: light) {
544
+ .dashboard-card-section p, .output-content-wrapper p { color: var(--text-secondary-light); }
545
+ .dashboard-card-section a, .output-content-wrapper a { color: var(--accent-main-light); }
546
+ .dashboard-card-section a:hover, .output-content-wrapper a:hover { color: var(--accent-hover-light); }
547
+ .dashboard-card-section strong, .output-content-wrapper strong { color: var(--text-primary-light); }
548
  }
549
 
550
  /* Horizontal rule for visual separation within the main block */
551
  .section-divider {
552
  border: none;
553
  border-top: 1px solid var(--border-dark); /* Subtle, but present for structure */
554
+ margin: 2rem 0 !important; /* Reduced from 2.5rem */
555
  transition: border-color var(--transition-speed);
556
  }
557
  @media (prefers-color-scheme: light) { .section-divider { border-top: 1px solid var(--border-light); } }
558
 
559
  /* Input field groups and layout: spacious and clear */
560
+ .input-field-group { margin-bottom: 1rem; } /* Reduced from 1.5rem */
561
  .input-row {
562
  display: flex;
563
+ gap: 1.8rem; /* Reduced from 2rem */
564
  flex-wrap: wrap;
565
+ margin-bottom: 1rem; /* Reduced from 1.5rem */
566
  }
567
  .input-field {
568
+ flex: 1; /* Allows flexible sizing */
 
569
  }
570
 
571
  /* Input labels and info text: prominent and clear */
 
573
  font-size: 1.2rem !important; /* Larger, more prominent labels */
574
  font-weight: 500 !important;
575
  color: var(--text-primary-dark) !important;
576
+ margin-bottom: 0.8rem !important; /* Reduced from 1rem */
577
  display: block !important;
578
  transition: color var(--transition-speed);
579
  }
 
596
  border-radius: var(--radius-md) !important;
597
  padding: 1.3rem 1.6rem !important; /* Even more padding */
598
  font-size: 1.15rem !important; /* Larger font size */
599
+ background: var(--main-card-bg-dark) !important; /* Input background matches main console */
600
  color: var(--text-primary-dark) !important;
601
  width: 100% !important;
602
  box-shadow: inset 0 1px 3px rgba(0,0,0,0.3); /* Inner shadow for depth */
 
617
  .gradio-dropdown select,
618
  .gradio-textbox input[type=password] {
619
  border: 2px solid var(--border-light) !important;
620
+ background: var(--main-card-bg-light) !important;
621
  color: var(--text-primary-light) !important;
622
  box-shadow: inset 0 1px 3px rgba(0,0,0,0.1);
623
  }
 
649
  /* Button group and styling: dynamic and clear actions */
650
  .button-row {
651
  display: flex;
652
+ gap: 2rem; /* Reduced from 2.5rem */
653
+ margin-top: 2rem; /* Reduced from 2.5rem */
654
  flex-wrap: wrap;
655
  justify-content: flex-end;
656
  }
 
679
  /* Primary button */
680
  .gr-button-primary {
681
  background: var(--accent-main-dark) !important;
682
+ color: var(--header-bg-dark) !important; /* Dark text on gold */
683
  border-color: var(--accent-main-dark) !important;
684
  }
685
  .gr-button-primary:hover:not(:disabled) {
 
730
  }
731
 
732
  /* Output Styling within the main content area */
733
+ .output-card { /* Class for the output content area markdown component */
734
+ padding: 0 !important; /* Markdown itself might have padding, control it within */
735
+ margin-top: 0 !important; /* Ensure no extra margin */
736
+ margin-bottom: 0 !important; /* Ensure no extra margin */
737
+ }
738
+ .output-card .response-header { /* For actual answers */
739
  font-size: 1.8rem; /* Larger and clearer */
740
  font-weight: 700;
741
  color: var(--text-primary-dark);
742
+ margin: 0 0 1rem 0; /* Reduced margin */
743
  display: flex;
744
  align-items: center;
745
  gap: 1.2rem;
 
753
  .output-card .divider {
754
  border: none;
755
  border-top: 1px solid var(--border-dark);
756
+ margin: 1.5rem 0 1.8rem 0; /* Adjusted for tighter spacing */
757
  transition: border-color var(--transition-speed);
758
  }
759
+ .output-card .output-content-wrapper { /* Applies to the entire markdown content block */
760
  font-size: 1.15rem; /* Highly legible output text */
761
  line-height: 1.8;
762
  color: var(--text-primary-dark);
 
791
  }
792
 
793
  /* Error messages: clear, prominent, and legible */
794
+ .output-card .error-message { /* This is also an inner div within the output markdown */
795
+ padding: 1.5rem 2rem; /* Reduced padding */
796
+ margin-top: 1.5rem; /* Keeping this margin to separate from prev section */
797
  font-size: 1.1rem;
798
  border-radius: var(--radius-md);
799
  background: var(--error-bg-dark);
 
824
  }
825
 
826
  /* Output placeholder styling: inviting and distinct */
827
+ .output-card .placeholder { /* Also an inner div within the output markdown */
828
+ padding: 2.5rem 2rem; /* Reduced padding */
829
+ font-size: 1.2rem; /* Adjusted font size */
830
  border-radius: var(--radius-md);
831
  border: 3px dashed var(--border-dark); /* Thicker dashed border */
832
  color: var(--text-secondary-dark);
 
843
 
844
  /* Examples table styling: integrated within the main content block, but with clear visual identity */
845
  /* Applied to the gr.Column that wraps the examples */
 
 
 
 
846
  .examples-section .gr-examples-table {
847
  border-radius: var(--radius-md) !important;
848
  border: 1px solid var(--border-dark) !important;
849
  overflow: hidden;
850
+ background: var(--card-section-bg-dark) !important; /* Ensure table matches main content background */
851
  box-shadow: inset 0 0 10px rgba(0,0,0,0.2); /* Subtle inner shadow */
852
  transition: border-color var(--transition-speed), background var(--transition-speed), box-shadow var(--transition-speed);
853
  }
854
  @media (prefers-color-scheme: light) {
855
  .examples-section .gr-examples-table {
856
  border: 1px solid var(--border-light) !important;
857
+ background: var(--card-section-bg-light) !important;
858
  box-shadow: inset 0 0 8px rgba(0,0,0,0.05);
859
  }
860
  }
861
 
862
  .examples-section .gr-examples-table th,
863
  .examples-section .gr-examples-table td {
864
+ padding: 1rem 1.2rem !important; /* Slightly reduced padding for tighter coupling */
865
  font-size: 1.05rem !important;
866
  border: none !important;
867
  }
868
  .examples-section .gr-examples-table th {
869
+ background: var(--header-bg-dark) !important; /* Match header background for table header */
870
  color: var(--text-primary-dark) !important;
871
  font-weight: 600 !important;
872
  text-align: left;
873
  transition: background var(--transition-speed), color var(--transition-speed);
874
  }
875
  .examples-section .gr-examples-table td {
876
+ background: var(--card-section-bg-dark) !important;
877
  color: var(--text-primary-dark) !important;
878
  border-top: 1px solid var(--border-dark) !important;
879
  cursor: pointer;
 
885
  .examples-section .gr-examples-table tr:first-child td { border-top: none !important; }
886
 
887
  @media (prefers-color-scheme: light) {
888
+ .examples-section .gr-examples-table { border: 1px solid var(--border-light) !important; background: var(--card-section-bg-light) !important; }
889
+ .examples-section .gr-examples-table th { background: var(--header-bg-light) !important; color: var(--text-primary-light) !important; }
890
+ .examples-section .gr-examples-table td { background: var(--card-section-bg-light) !important; color: var(--text-primary-light) !important; border-top: 1px solid var(--border-light) !important; }
891
  .examples-section .gr-examples-table tr:hover td { background: rgba(0, 123, 255, 0.08) !important; }
892
  }
893
 
894
 
895
  /* Footer styling: clean and informative, integrated at the very bottom */
896
  .app-footer-wrapper {
897
+ background: var(--header-bg-dark); /* Match header background for consistency */
898
  border-top: 1px solid var(--border-dark) !important;
899
+ margin-top: 0.5rem; /* Adjusted for tighter gap, assuming minimum needed */
900
+ padding-top: 2.5rem; /* Reduced from 3rem */
901
+ padding-bottom: 2.5rem; /* Reduced from 3rem */
902
  border-top-left-radius: var(--radius-lg);
903
  border-top-right-radius: var(--radius-lg);
904
  box-shadow: inset 0 8px 15px rgba(0,0,0,0.2); /* Inset shadow for depth */
 
957
  }
958
  .gradio-button span:focus { outline: none !important; }
959
 
960
+ /* MOST AGGRESSIVE "FALSE" REMOVAL - THIS SHOULD FINALLY KILL IT */
961
+ /* Targets ALL known problematic elements that might contain "false" or the menu icon */
962
+ .gr-examples .gr-label,
963
+ .gr-examples .gr-examples-header, /* Standard header for examples */
964
+ .gr-examples button.gr-button-filter, /* The "☰" icon button */
965
+ .gr-examples .label-wrap, /* Common wrapper for labels */
966
+ .gr-examples div[data-testid*="label-text"], /* Div containing "false" text by data-testid */
967
+ .gr-examples span[data-testid*="label-text"], /* Span containing "false" text by data-testid */
968
+ .gr-examples div[class*="label"], /* Any div with "label" in its class name */
969
+ .gr-examples .gr-example-label, /* Specific class for example labels */
970
+ .gr-examples .gr-box.gr-component.gradio-example > div:first-child:has(> span[data-testid]), /* Target parent div of specific internal spans with data-testid */
971
+ .gr-examples .gr-box.gr-component.gradio-example > div:first-child > span, /* Direct span within example items, often containing "false" */
972
+ /* Targeting elements immediately following our custom H3 within the examples-section that might still render something */
973
+ .examples-section .sub-section-title + div:has(> button.gr-button-filter),
974
+ .examples-section .sub-section-title + div:has(span[data-testid*="label-text"]),
975
+ .examples-section .sub-section-title + div.flex.flex-col.overflow-hidden.h-full.relative /* Catch a common Gradio wrapper div */
976
+ {
977
+ display: none !important;
978
+ visibility: hidden !important; /* Double down on hiding */
979
+ width: 0 !important;
980
+ height: 0 !important;
981
+ overflow: hidden !important;
982
+ margin: 0 !important;
983
+ padding: 0 !important;
984
+ border: 0 !important;
985
+ font-size: 0 !important;
986
+ line-height: 0 !important;
987
+ position: absolute !important; /* Take it out of normal flow */
988
+ pointer-events: none !important; /* Ensure it's not interactive */
989
+ }
990
 
991
 
992
  /* Responsive Adjustments (meticulously refined) */
 
994
  .gradio-container > .flex.flex-col { max-width: 960px; padding: 0 1.5rem !important; }
995
  .app-header-title { font-size: 3.8rem; }
996
  .app-header-tagline { font-size: 1.5rem; }
997
+ .app-header-wrapper { padding: var(--padding-md) var(--padding-lg) !important; margin-bottom: 2rem; border-bottom-left-radius: var(--radius-md); border-bottom-right-radius: var(--radius-md); }
998
+ .main-dashboard-container { padding: var(--padding-md) !important; margin-bottom: 0.6rem; border-radius: var(--radius-md); gap: 2rem; }
999
+ .dashboard-card-section { padding: var(--padding-sm); border-radius: var(--radius-sm); }
1000
+ .section-title { font-size: 2.2rem !important; margin-bottom: 1.5rem !important; }
1001
+ .sub-section-title { font-size: 1.8rem !important; margin-top: 1.2rem !important; margin-bottom: 0.7rem !important; }
1002
+ .section-divider { margin: 1.8rem 0; }
1003
+ .input-row { gap: 1.5rem; }
1004
+ .input-field { min-width: 280px; }
1005
  .gradio-textbox textarea { min-height: 160px; }
1006
  .output-card .response-header { font-size: 1.7rem; }
1007
+ .examples-section { padding-top: 1.2rem; }
1008
+ .examples-section .gr-examples-table th, .examples-section .gr-examples-table td { padding: 0.9rem 1.1rem !important; }
1009
+ .app-footer-wrapper { margin-top: 0.6rem; border-top-left-radius: var(--radius-md); border-top-right-radius: var(--radius-md); }
1010
  }
1011
 
1012
  @media (max-width: 768px) {
1013
  .gradio-container > .flex.flex-col { padding: 0 1rem !important; }
1014
+ .app-header-wrapper { padding: var(--padding-sm) var(--padding-md) !important; margin-bottom: 1.8rem; border-bottom-left-radius: var(--radius-md); border-bottom-right-radius: var(--radius-md); }
1015
+ .app-header-logo { font-size: 4.5rem; margin-bottom: 0.6rem; }
1016
  .app-header-title { font-size: 3.2rem; letter-spacing: -0.06em; }
1017
  .app-header-tagline { font-size: 1.3rem; }
1018
+ .main-dashboard-container { padding: var(--padding-sm) !important; margin-bottom: 0.5rem; border-radius: var(--radius-md); gap: 1.8rem; }
1019
+ .dashboard-card-section { padding: 1.5rem; border-radius: var(--radius-sm); }
1020
+ .section-title { font-size: 2rem !important; margin-bottom: 1.2rem !important; }
1021
+ .sub-section-title { font-size: 1.6rem !important; margin-top: 1rem !important; margin-bottom: 0.6rem !important; }
1022
+ .section-divider { margin: 1.5rem 0; }
1023
+ .input-row { flex-direction: column; gap: 1rem; }
 
1024
  .input-field { min-width: 100%; }
1025
  .gradio-textbox textarea { min-height: 140px; }
1026
+ .button-row { justify-content: stretch; gap: 1rem; }
1027
  .gradio-button { width: 100%; padding: 1.1rem 2rem !important; font-size: 1.1rem !important; }
1028
  .output-card .response-header { font-size: 1.5rem; }
1029
  .output-card .response-icon { font-size: 1.7rem; }
1030
+ .output-card .placeholder { padding: 2.5rem 1.5rem; font-size: 1.1rem; }
1031
+ .examples-section { padding-top: 1rem; }
1032
+ .examples-section .gr-examples-table th, .examples-section .gr-examples-table td { padding: 0.8rem 1rem !important; font-size: 1.0rem !important; }
1033
+ .app-footer-wrapper { margin-top: 0.5rem; padding-top: 2rem; padding-bottom: 2rem; border-top-left-radius: var(--radius-md); border-top-right-radius: var(--radius-md); }
1034
  }
1035
 
1036
  @media (max-width: 480px) {
1037
  .gradio-container > .flex.flex-col { padding: 0 0.8rem !important; }
1038
+ .app-header-wrapper { padding: 1.2rem 1rem !important; margin-bottom: 1.5rem; border-bottom-left-radius: var(--radius-sm); border-bottom-right-radius: var(--radius-sm); }
1039
+ .app-header-logo { font-size: 3.8rem; margin-bottom: 0.5rem; }
1040
  .app-header-title { font-size: 2.8rem; }
1041
  .app-header-tagline { font-size: 1.1rem; }
1042
+ .main-dashboard-container { padding: 1.2rem !important; margin-bottom: 0.4rem; border-radius: var(--radius-sm); gap: 1.5rem; }
1043
+ .dashboard-card-section { padding: 1rem; border-radius: var(--radius-xs); }
1044
+ .section-title { font-size: 1.8rem !important; margin-bottom: 1rem !important; }
1045
+ .sub-section-title { font-size: 1.4rem !important; margin-top: 0.8rem !important; margin-bottom: 0.5rem !important; }
1046
+ .section-divider { margin: 1rem 0; }
 
1047
  .gradio-textbox textarea, .gradio-dropdown select, .gradio-textbox input[type=password] { font-size: 1.05rem !important; padding: 1rem 1.2rem !important; }
1048
  .gradio-textbox textarea { min-height: 120px; }
1049
  .gradio-button { padding: 1rem 1.5rem !important; font-size: 1rem !important; }
1050
  .output-card .response-header { font-size: 1.4rem; }
1051
  .output-card .response-icon { font-size: 1.5rem; }
1052
+ .output-card .placeholder { padding: 2rem 1rem; font-size: 1.05rem; }
1053
+ .examples-section { padding-top: 0.8rem; } /* Slightly reduce padding on tiny screens for example section */
1054
+ .examples-section .gr-examples-table th, .examples-section .gr-examples-table td { padding: 0.6rem 0.8rem !important; font-size: 0.95rem !important; }
1055
+ .app-footer-wrapper { margin-top: 0.4rem; padding-top: 1.5rem; padding-bottom: 1.5rem; border-top-left-radius: var(--radius-sm); border-top-right-radius: var(--radius-sm); }
1056
  }
1057
  """
1058
 
1059
  with gr.Blocks(theme=None, css=custom_css, title="Landlord-Tenant Rights Assistant") as demo:
1060
+ # --- Header Section ---
1061
  with gr.Group(elem_classes="app-header-wrapper"):
1062
  gr.Markdown(
1063
  """
 
1069
  """
1070
  )
1071
 
1072
+ # --- NEW: Main Dashboard Console Container (This holds everything central) ---
1073
+ with gr.Column(elem_classes="main-dashboard-container"):
1074
+
1075
+ # --- Section 1: Introduction and Disclaimer Card ---
1076
+ with gr.Group(elem_classes="dashboard-card-section"):
1077
+ gr.Markdown("<h3 class='sub-section-title'>Welcome & Disclaimer</h3>")
1078
+ gr.Markdown(
1079
+ """
1080
+ <p>Navigate landlord-tenant laws with ease. This assistant provides detailed, state-specific answers grounded in legal authority.</p>
1081
+ <p><strong>Disclaimer:</strong> This tool gives information, not legal advice. For specific legal guidance, always consult a licensed attorney in your jurisdiction.</p>
1082
+ """
1083
+ )
 
 
 
1084
 
1085
+ # --- Section 2: OpenAI API Key Input Card ---
1086
+ with gr.Group(elem_classes="dashboard-card-section"):
1087
+ gr.Markdown("<h3 class='sub-section-title'>OpenAI API Key</h3>")
1088
  api_key_input = gr.Textbox(
1089
  label="OpenAI API Key", type="password", placeholder="Enter your API key (e.g., sk-...)",
1090
+ info="Required to process your query. Securely used per request, not stored. <a href='https://platform.openai.com/api-keys' target='_blank'>Get one free from OpenAI</a>.", lines=1
1091
  )
1092
+
1093
+ # --- Section 3: Query Input and State Selection Card ---
1094
+ with gr.Group(elem_classes="dashboard-card-section"):
1095
+ gr.Markdown("<h3 class='sub-section-title'>Ask Your Question</h3>")
1096
+ with gr.Row(elem_classes="input-row"): # Query and State in one row
1097
+ with gr.Column(elem_classes="input-field", scale=3): # Query box takes more space
1098
+ query_input = gr.Textbox(
1099
+ label="Your Question", placeholder="E.g., What are the rules for security deposit returns in my state?",
1100
+ lines=5, max_lines=10
1101
+ )
1102
+ with gr.Column(elem_classes="input-field", scale=1): # State dropdown takes less space
1103
+ state_input = gr.Dropdown(
1104
+ label="Select State", choices=dropdown_choices, value=initial_value,
1105
+ allow_custom_value=False
1106
+ )
1107
+ with gr.Row(elem_classes="button-row"):
1108
+ clear_button = gr.Button("Clear", variant="secondary", elem_classes=["gr-button-secondary"])
1109
+ submit_button = gr.Button("Submit Query", variant="primary", elem_classes=["gr-button-primary"])
1110
+
1111
+ # --- Section 4: Output Display Card ---
1112
+ with gr.Group(elem_classes="dashboard-card-section"):
1113
+ gr.Markdown("<h3 class='sub-section-title'>Legal Assistant's Response</h3>")
1114
+ output = gr.Markdown(
1115
+ value="<div class='placeholder output-card'>The answer will appear here after submitting your query.</div>",
1116
+ elem_classes="output-content-wrapper output-card" # Apply these classes for styling
1117
+ )
1118
+
1119
+ # --- Section 5: Example Questions Section (NO ACCORDION, direct display) ---
1120
+ with gr.Group(elem_classes="dashboard-card-section examples-section"):
1121
+ gr.Markdown("<h3 class='sub-section-title'>Example Questions to Ask</h3>")
1122
  if example_queries:
1123
  gr.Examples(
1124
  examples=example_queries, inputs=[query_input, state_input],
1125
  examples_per_page=5,
1126
+ label="", # This is crucial, but CSS handles the rest
1127
  )
1128
  else:
1129
  gr.Markdown("<div class='placeholder'>Sample questions could not be loaded.</div>")
1130
 
1131
+ # --- Footer Section ---
 
1132
  with gr.Group(elem_classes="app-footer-wrapper"):
1133
  gr.Markdown(
1134
  """
 
1154
  ),
1155
  inputs=[], outputs=[api_key_input, query_input, state_input, output]
1156
  )
1157
+ logging.info("Completely new, cohesive, dynamic, and legible Gradio interface created with Legal Console theme.")
1158
  return demo
1159
 
1160
  # --- Main Execution Block (remains untouched from original logic) ---
 
1162
  logging.info("Starting Landlord-Tenant Rights Bot application...")
1163
  try:
1164
  SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
1165
+ DEFAULT_PDF_PATH = os.path.join(SCRIPT_DIR, "data/tenant-landlord.pdf")
1166
+ DEFAULT_DB_PATH = os.path.join(SCRIPT_DIR, "data/chroma_db")
1167
 
1168
  # Use environment variables if set, otherwise default paths
1169
  PDF_PATH = os.getenv("PDF_PATH", DEFAULT_PDF_PATH)