kappai commited on
Commit
bdc0601
Β·
verified Β·
1 Parent(s): 88d8038

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +18 -231
app.py CHANGED
@@ -599,7 +599,7 @@ def get_questions_and_micro(
599
  if q:
600
  seen_set.add(q)
601
 
602
- payload = {
603
  "category": category_key,
604
  "language": lang,
605
  "questions": questions,
@@ -608,228 +608,20 @@ def get_questions_and_micro(
608
  "tone": tone,
609
  "safety_notes": safety_notes,
610
  }
 
 
 
611
  return {
612
- "questions": questions,
613
- "micro_actions": micro,
614
- "raw_json": json.dumps(payload, ensure_ascii=False, indent=2),
615
- "seen": list(seen_set),
616
- }
617
 
618
 
619
  # ────────────────────────────────────────────────────────────────────────────────
620
  # UI – pastel, animated, color-coded cards
621
 
622
 
623
- CUSTOM_CSS = """
624
- :root {
625
- --nv-bg: #f7f2ec;
626
- --nv-card: #fffdf8;
627
- --nv-border: #e5d8c7;
628
- --nv-accent: #f38a6b;
629
- --nv-accent-soft: #ffe4d4;
630
- --nv-text-main: #262626;
631
- --nv-text-muted: #6c6459;
632
- }
633
-
634
- /* page */
635
- .gradio-container {
636
- font-family: system-ui, -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", sans-serif;
637
- background: radial-gradient(circle at top left, #fff6ee 0, #f7f2ec 50%, #f2ece6 100%);
638
- max-width: 960px !important;
639
- margin: 0 auto !important;
640
- padding: 32px 0 40px 0;
641
- position: relative;
642
- }
643
-
644
- /* floating blobs */
645
- @keyframes nvBlobFloat {
646
- 0% { transform: translate3d(0, 0, 0) scale(1); opacity: 0.6; }
647
- 50% { transform: translate3d(10px, -8px, 0) scale(1.04); opacity: 0.9; }
648
- 100% { transform: translate3d(0, 0, 0) scale(1); opacity: 0.6; }
649
- }
650
- .gradio-container::before,
651
- .gradio-container::after {
652
- content: "";
653
- position: fixed;
654
- width: 260px;
655
- height: 260px;
656
- border-radius: 999px;
657
- z-index: -1;
658
- filter: blur(3px);
659
- animation: nvBlobFloat 14s ease-in-out infinite alternate;
660
- }
661
- .gradio-container::before {
662
- top: -80px;
663
- left: -60px;
664
- background: radial-gradient(circle at 30% 30%, #ffd5c5, transparent 60%);
665
- }
666
- .gradio-container::after {
667
- bottom: -120px;
668
- right: -40px;
669
- background: radial-gradient(circle at 70% 70%, #c3e4ff, transparent 60%);
670
- animation-delay: 4s;
671
- }
672
-
673
- /* main panel */
674
- @keyframes nvCardIn {
675
- 0% { opacity: 0; transform: translateY(8px) scale(0.98); }
676
- 100% { opacity: 1; transform: translateY(0) scale(1); }
677
- }
678
- .nv-shell {
679
- background: var(--nv-card);
680
- border-radius: 32px;
681
- border: 1px solid var(--nv-border);
682
- box-shadow:
683
- 0 20px 40px rgba(15, 23, 42, 0.12),
684
- 0 1px 0 rgba(255, 255, 255, 0.8) inset;
685
- padding: 26px 24px 22px;
686
- animation: nvCardIn 500ms ease-out;
687
- }
688
-
689
- .nv-badge {
690
- font-size: 0.78rem;
691
- letter-spacing: 0.16em;
692
- text-transform: uppercase;
693
- color: var(--nv-text-muted);
694
- }
695
- .nv-title {
696
- font-size: 1.9rem;
697
- font-weight: 650;
698
- margin-top: 4px;
699
- }
700
- .nv-subtitle {
701
- font-size: 0.95rem;
702
- color: var(--nv-text-muted);
703
- margin-top: 6px;
704
- margin-bottom: 18px;
705
- }
706
-
707
- /* sections */
708
- .nv-section {
709
- background: #fbf6ee;
710
- border-radius: 24px;
711
- border: 1px solid #e6dac7;
712
- padding: 16px 16px 14px;
713
- margin-bottom: 14px;
714
- }
715
- .nv-label {
716
- font-size: 0.78rem;
717
- letter-spacing: 0.12em;
718
- text-transform: uppercase;
719
- color: #a29078;
720
- margin-bottom: 8px;
721
- }
722
-
723
- /* pills */
724
- .nv-pills label {
725
- border-radius: 999px !important;
726
- border: 1px solid #decfbb !important;
727
- padding: 6px 11px !important;
728
- font-size: 0.84rem !important;
729
- background: #fdf8f1;
730
- transition: background 150ms ease, transform 120ms ease, box-shadow 120ms ease;
731
- }
732
- .nv-pills input:checked + label {
733
- background: linear-gradient(135deg, #ffe4d4, #ffd6c6) !important;
734
- border-color: var(--nv-accent) !important;
735
- color: var(--nv-text-main) !important;
736
- box-shadow: 0 4px 10px rgba(243, 138, 107, 0.18);
737
- transform: translateY(-1px);
738
- }
739
-
740
- /* button (breathing) */
741
- @keyframes nvPulse {
742
- 0% { transform: translateY(0) scale(1); box-shadow: 0 10px 22px rgba(243, 138, 107, 0.30); }
743
- 50% { transform: translateY(-1px) scale(1.02); box-shadow: 0 14px 26px rgba(243, 138, 107, 0.40); }
744
- 100% { transform: translateY(0) scale(1); box-shadow: 0 10px 22px rgba(243, 138, 107, 0.30); }
745
- }
746
- .gr-button {
747
- border-radius: 999px !important;
748
- padding: 10px 20px !important;
749
- font-weight: 600 !important;
750
- font-size: 0.96rem !important;
751
- border: none !important;
752
- background:
753
- radial-gradient(circle at 0 0, #ffe4d4, transparent 55%),
754
- linear-gradient(135deg, #f6a37d, #f38a6b) !important;
755
- color: #fff !important;
756
- animation: nvPulse 4s ease-in-out infinite;
757
- }
758
- .gr-button:hover {
759
- animation-duration: 1.4s;
760
- }
761
-
762
- /* cards grid */
763
- .nv-card-grid {
764
- display: grid;
765
- grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
766
- gap: 10px;
767
- }
768
-
769
- /* deal animation */
770
- @keyframes nvCardDeal {
771
- 0% { opacity: 0; transform: translate3d(0, 0, 0) scale(0.7); }
772
- 100% { opacity: 1; transform: translate3d(0, 0, 0) scale(1); }
773
- }
774
- .nv-card {
775
- border-radius: 18px;
776
- padding: 10px 11px;
777
- font-size: 0.9rem;
778
- border: 1px solid rgba(0,0,0,0.03);
779
- box-shadow: 0 6px 14px rgba(15, 23, 42, 0.06);
780
- opacity: 0;
781
- transform: scale(0.7);
782
- animation: nvCardDeal 420ms ease-out forwards;
783
- }
784
-
785
- /* color-coded by category */
786
- .nv-card--cat-alimentation {
787
- background: radial-gradient(circle at 0 0, #e3f7df 0, #ffffff 60%);
788
- border-color: #c3e5bc;
789
- }
790
- .nv-card--cat-mouvement {
791
- background: radial-gradient(circle at 0 0, #dbeeff 0, #ffffff 60%);
792
- border-color: #b9d8ff;
793
- }
794
- .nv-card--cat-cerveau {
795
- background: radial-gradient(circle at 0 0, #ffd6d6 0, #ffffff 60%);
796
- border-color: #f7b6b6;
797
- }
798
- .nv-card--cat-liens {
799
- background: radial-gradient(circle at 0 0, #ffead1 0, #ffffff 60%);
800
- border-color: #f6d2a3;
801
- }
802
- .nv-card--cat-bien-etre {
803
- background: radial-gradient(circle at 0 0, #ffe1f2 0, #ffffff 60%);
804
- border-color: #f3c3e4;
805
- }
806
-
807
- .nv-card-title {
808
- font-size: 0.72rem;
809
- letter-spacing: 0.14em;
810
- text-transform: uppercase;
811
- color: #7c6a9a;
812
- margin-bottom: 4px;
813
- }
814
-
815
- /* JSON box */
816
- .nv-json code, .nv-json textarea {
817
- border-radius: 16px !important;
818
- }
819
-
820
- /* mobile */
821
- @media (max-width: 640px) {
822
- .nv-shell {
823
- border-radius: 24px;
824
- padding: 20px 16px 18px;
825
- }
826
- .nv-title {
827
- font-size: 1.6rem;
828
- }
829
- }
830
- """
831
-
832
-
833
  def _map_category(choice: str) -> str:
834
  mapping = {
835
  "alimentation 🍎": "alimentation",
@@ -857,7 +649,6 @@ def update_cards(lang: str, category_choice: str, variant: str, seen: List[str])
857
  result = get_questions_and_micro(lang, category_key, variant, seen or [])
858
  questions = result["questions"]
859
  micro = result["micro_actions"]
860
- raw_json = result["raw_json"]
861
  new_seen = result["seen"]
862
 
863
  # Stagger cards a bit
@@ -890,7 +681,7 @@ def update_cards(lang: str, category_choice: str, variant: str, seen: List[str])
890
  )
891
  )
892
 
893
- return (*q_htmls, *m_htmls, raw_json, new_seen)
894
 
895
 
896
  # ────────────────────────────────────────────────────────────────────────────────
@@ -898,7 +689,8 @@ def update_cards(lang: str, category_choice: str, variant: str, seen: List[str])
898
 
899
 
900
  with gr.Blocks(title="Neurovie – Question Studio") as demo:
901
- gr.HTML(f"<style>{CUSTOM_CSS}</style>")
 
902
 
903
  seen_state = gr.State([]) # per-session list of seen questions
904
 
@@ -966,20 +758,15 @@ with gr.Blocks(title="Neurovie – Question Studio") as demo:
966
  m1 = gr.HTML()
967
  m2 = gr.HTML()
968
 
969
- # JSON output (for dev)
970
- with gr.Column(elem_classes=["nv-section", "nv-json"]):
971
- gr.HTML("<div class='nv-label'>JSON (for dev)</div>")
972
- raw_json = gr.Code(
973
- label="",
974
- language="json",
975
- show_label=False,
976
- )
977
 
978
  btn.click(
979
- update_cards,
980
- [lang, category, variant, seen_state],
981
- [q1, q2, q3, q4, m1, m2, raw_json, seen_state],
982
- )
 
 
983
 
984
  if __name__ == "__main__":
985
  demo.launch()
 
599
  if q:
600
  seen_set.add(q)
601
 
602
+ payload = {
603
  "category": category_key,
604
  "language": lang,
605
  "questions": questions,
 
608
  "tone": tone,
609
  "safety_notes": safety_notes,
610
  }
611
+
612
+ # If you ever need the payload again, you can use it here;
613
+ # for the UI we only return questions + micro + updated seen.
614
  return {
615
+ "questions": questions,
616
+ "micro_actions": micro,
617
+ "seen": list(seen_set),
618
+ }
 
619
 
620
 
621
  # ────────────────────────────────────────────────────────────────────────────────
622
  # UI – pastel, animated, color-coded cards
623
 
624
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
625
  def _map_category(choice: str) -> str:
626
  mapping = {
627
  "alimentation 🍎": "alimentation",
 
649
  result = get_questions_and_micro(lang, category_key, variant, seen or [])
650
  questions = result["questions"]
651
  micro = result["micro_actions"]
 
652
  new_seen = result["seen"]
653
 
654
  # Stagger cards a bit
 
681
  )
682
  )
683
 
684
+ return (*q_htmls, *m_htmls, new_seen)
685
 
686
 
687
  # ────────────────────────────────────────────────────────────────────────────────
 
689
 
690
 
691
  with gr.Blocks(title="Neurovie – Question Studio") as demo:
692
+ # Load external CSS file
693
+ gr.HTML("<link rel='stylesheet' href='style.css'>")
694
 
695
  seen_state = gr.State([]) # per-session list of seen questions
696
 
 
758
  m1 = gr.HTML()
759
  m2 = gr.HTML()
760
 
761
+
 
 
 
 
 
 
 
762
 
763
  btn.click(
764
+ update_cards,
765
+ [lang, category, variant, seen_state],
766
+ [q1, q2, q3, q4, m1, m2, seen_state],
767
+ show_progress=False, # hide Gradio built-in progress indicator
768
+ )
769
+
770
 
771
  if __name__ == "__main__":
772
  demo.launch()