openfree commited on
Commit
ffbc6a2
Β·
verified Β·
1 Parent(s): 0708028

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +35 -73
app.py CHANGED
@@ -4,13 +4,20 @@ import json
4
  from datetime import datetime, timedelta
5
  import base64
6
  import pandas as pd
7
-
8
  from travel import (
9
  destination_research_task, accommodation_task, transportation_task,
10
  activities_task, dining_task, itinerary_task,
11
  run_task
12
  )
13
 
 
 
 
 
 
 
 
 
14
  # ------------------------------------------
15
  # λ‹€κ΅­μ–΄ 지원을 μœ„ν•œ λ²ˆμ—­ 사전 및 헬퍼 ν•¨μˆ˜
16
  # ------------------------------------------
@@ -273,7 +280,6 @@ translations = {
273
  }
274
  }
275
 
276
- # λ²ˆμ—­ 헬퍼 ν•¨μˆ˜: μ„ νƒλœ 언어에 따라 ν‚€ 값을 λ°˜ν™˜ν•©λ‹ˆλ‹€.
277
  def t(key):
278
  lang = st.session_state.get("selected_language", "en")
279
  return translations[lang].get(key, key)
@@ -305,17 +311,9 @@ with st.sidebar:
305
  st.session_state.selected_language = lang_map.get(language, "en")
306
 
307
  # ------------------------------------------
308
- # νŽ˜μ΄μ§€ μ„€μ • (λ²ˆμ—­ 적용)
309
  # ------------------------------------------
310
 
311
-
312
- st.set_page_config(
313
- page_title="Globetrotter AI: Your AI Agent for Travelling",
314
- page_icon="✈️",
315
- layout="wide",
316
- initial_sidebar_state="expanded"
317
- )
318
-
319
  # Modern CSS with refined color scheme and sleek animations
320
  st.markdown("""
321
  <style>
@@ -539,10 +537,10 @@ def display_modern_progress(current_step, total_steps=6):
539
  if 'progress_steps' not in st.session_state:
540
  st.session_state.progress_steps = {
541
  0: {'status': 'pending', 'name': t("trip_details")},
542
- 1: {'status': 'pending', 'name': t("about")}, # Accommodation
543
- 2: {'status': 'pending', 'name': t("travel_style")}, # Transportation
544
- 3: {'status': 'pending', 'name': t("live_agent_outputs")}, # Activities
545
- 4: {'status': 'pending', 'name': t("download_share")}, # Dining
546
  5: {'status': 'pending', 'name': t("full_itinerary")}
547
  }
548
 
@@ -689,7 +687,9 @@ def run_task_with_logs(task, input_text, log_container, output_container, result
689
 
690
  return result
691
 
692
- # Initialize session state
 
 
693
  if 'generated_itinerary' not in st.session_state:
694
  st.session_state.generated_itinerary = None
695
  if 'generation_complete' not in st.session_state:
@@ -781,6 +781,7 @@ with st.sidebar:
781
  st.markdown(f"**{name}**")
782
  st.markdown(f"<small>{desc}</small>", unsafe_allow_html=True)
783
  st.markdown('</div>', unsafe_allow_html=True)
 
784
  # Main content area
785
  if not st.session_state.generation_complete:
786
  # Sleek form with minimal design
@@ -821,13 +822,13 @@ if not st.session_state.generation_complete:
821
  "Nature", "Shopping", "Nightlife", "Family-friendly"],
822
  default=["Culture", "Food & Dining"])
823
 
824
- # Simplified expander
825
  with st.expander("Additional Preferences", expanded=False):
826
  preferences = st.text_area("Interests", placeholder="History museums, local cuisine, hiking, art...")
827
  special_requirements = st.text_area("Special Requirements",
828
  placeholder="Dietary restrictions, accessibility needs...")
829
 
830
- # Submit button with enhanced styling
831
  submit_button = st.form_submit_button(t("submit"))
832
 
833
  st.markdown('</div>', unsafe_allow_html=True)
@@ -850,7 +851,7 @@ if not st.session_state.generation_complete:
850
  "special_requirements": special_requirements
851
  }
852
 
853
- # Format the user input for tasks with enhanced details
854
  input_context = f"""Travel Request Details:
855
  Origin: {user_input['origin']}
856
  Destination: {user_input['destination']}
@@ -863,7 +864,7 @@ Preferences/Interests: {user_input['preferences']}
863
  Special Requirements: {user_input['special_requirements']}
864
  """
865
 
866
- # Display a minimal, sleek processing animation
867
  st.markdown("""
868
  <div class="sleek-processing-container">
869
  <div class="pulse-container">
@@ -922,13 +923,10 @@ Special Requirements: {user_input['special_requirements']}
922
  </style>
923
  """, unsafe_allow_html=True)
924
 
925
- # Create modern containers for progress, logs, and live output
926
  st.markdown('<div class="modern-card">', unsafe_allow_html=True)
927
-
928
- # Create tabs for better organization
929
  progress_tab, logs_tab, details_tab = st.tabs(["πŸ“Š Progress", "πŸ”„ Live Activity", "πŸ“‹ Request Details"])
930
 
931
- # Show request details in the details tab
932
  with details_tab:
933
  st.markdown("#### " + t("request_details"))
934
  st.markdown(f"**{t('destination')}:** {user_input['destination']}")
@@ -942,7 +940,6 @@ Special Requirements: {user_input['special_requirements']}
942
  st.markdown(f"**Special Requirements:** {user_input['special_requirements']}")
943
 
944
  with progress_tab:
945
- # Create a persistent placeholder for progress display to avoid duplication
946
  if 'progress_placeholder' not in st.session_state:
947
  st.session_state.progress_placeholder = st.empty()
948
  with st.session_state.progress_placeholder.container():
@@ -952,8 +949,7 @@ Special Requirements: {user_input['special_requirements']}
952
  log_container = st.container()
953
  st.session_state.log_messages = []
954
 
955
- # Create a container for output that spans the full width
956
- st.markdown('</div>', unsafe_allow_html=True) # Close the progress card
957
  output_container = st.container()
958
  with output_container:
959
  st.markdown('<div class="modern-card">', unsafe_allow_html=True)
@@ -961,13 +957,10 @@ Special Requirements: {user_input['special_requirements']}
961
  st.info("Our AI agents will show their work here as they create your itinerary")
962
  st.markdown('</div>', unsafe_allow_html=True)
963
 
964
- # Initialize progress tracking
965
  st.session_state.current_step = 0
966
 
967
- # Display initial progress - using the session state placeholder
968
-
969
  # Step 1: Destination Research
970
- update_step_status(0, 'active') # Mark step 1 as active
971
  with st.session_state.progress_placeholder.container():
972
  display_modern_progress(st.session_state.current_step)
973
 
@@ -982,10 +975,9 @@ Special Requirements: {user_input['special_requirements']}
982
  "destination_info"
983
  )
984
 
985
- # Update progress after step 1 completes
986
- update_step_status(0, 'complete') # Mark step 1 as complete
987
  st.session_state.current_step = 1
988
- update_step_status(1, 'active') # Mark step 2 as active
989
  with st.session_state.progress_placeholder.container():
990
  display_modern_progress(st.session_state.current_step)
991
 
@@ -1002,10 +994,9 @@ Special Requirements: {user_input['special_requirements']}
1002
  "accommodation_info"
1003
  )
1004
 
1005
- # Update progress after step 2 completes
1006
- update_step_status(1, 'complete') # Mark step 2 as complete
1007
  st.session_state.current_step = 2
1008
- update_step_status(2, 'active') # Mark step 3 as active
1009
  with st.session_state.progress_placeholder.container():
1010
  display_modern_progress(st.session_state.current_step)
1011
 
@@ -1021,10 +1012,9 @@ Special Requirements: {user_input['special_requirements']}
1021
  "transportation_info"
1022
  )
1023
 
1024
- # Update progress after step 3 completes
1025
- update_step_status(2, 'complete') # Mark step 3 as complete
1026
  st.session_state.current_step = 3
1027
- update_step_status(3, 'active') # Mark step 4 as active
1028
  with st.session_state.progress_placeholder.container():
1029
  display_modern_progress(st.session_state.current_step)
1030
 
@@ -1040,10 +1030,9 @@ Special Requirements: {user_input['special_requirements']}
1040
  "activities_info"
1041
  )
1042
 
1043
- # Update progress after step 4 completes
1044
- update_step_status(3, 'complete') # Mark step 4 as complete
1045
  st.session_state.current_step = 4
1046
- update_step_status(4, 'active') # Mark step 5 as active
1047
  with st.session_state.progress_placeholder.container():
1048
  display_modern_progress(st.session_state.current_step)
1049
 
@@ -1059,10 +1048,9 @@ Special Requirements: {user_input['special_requirements']}
1059
  "dining_info"
1060
  )
1061
 
1062
- # Update progress after step 5 completes
1063
- update_step_status(4, 'complete') # Mark step 5 as complete
1064
  st.session_state.current_step = 5
1065
- update_step_status(5, 'active') # Mark step 6 as active
1066
  with st.session_state.progress_placeholder.container():
1067
  display_modern_progress(st.session_state.current_step)
1068
 
@@ -1097,25 +1085,19 @@ Dining Recommendations:
1097
  "itinerary"
1098
  )
1099
 
1100
- # Update final step status to complete
1101
- update_step_status(5, 'complete') # Mark final step as complete
1102
  st.session_state.current_step = 6
1103
  with st.session_state.progress_placeholder.container():
1104
  display_modern_progress(st.session_state.current_step)
1105
 
1106
- # Save the generated itinerary to session state
1107
  st.session_state.generated_itinerary = itinerary
1108
  st.session_state.generation_complete = True
1109
 
1110
- # Create a filename based on the destination and date
1111
  date_str = datetime.now().strftime("%Y-%m-%d")
1112
  st.session_state.filename = f"{user_input['destination'].replace(' ', '_')}_{date_str}_itinerary.txt"
1113
-
1114
- # No need to rerun, we'll update the UI directly
1115
 
1116
  # Display results if generation is complete
1117
  if st.session_state.generation_complete:
1118
- # Success animation and header
1119
  st.markdown("""
1120
  <div class="modern-card animate-in">
1121
  <div style="display: flex; justify-content: center; margin-bottom: 20px;">
@@ -1183,18 +1165,13 @@ if st.session_state.generation_complete:
1183
  </style>
1184
  """, unsafe_allow_html=True)
1185
 
1186
- # Main container for itinerary content
1187
  st.markdown('<div class="modern-card">', unsafe_allow_html=True)
1188
-
1189
- # Modern tabs for different views
1190
  itinerary_tab, details_tab, download_tab = st.tabs([f"πŸ—’οΈ {t('full_itinerary')}", f"πŸ’Ό {t('details')}", f"πŸ’Ύ {t('download_share')}"])
1191
 
1192
  with itinerary_tab:
1193
- # Preview the itinerary as text
1194
  st.text_area("Your Itinerary", st.session_state.generated_itinerary, height=600)
1195
 
1196
  with details_tab:
1197
- # More detailed view with agent outputs in a nested tab structure
1198
  agent_tabs = st.tabs([
1199
  "🌎 Destination", "🏨 Accommodation", "πŸš— Transportation",
1200
  "🎭 Activities", "🍽️ Dining"
@@ -1226,36 +1203,26 @@ if st.session_state.generation_complete:
1226
  with col1:
1227
  st.markdown("### " + t("save_itinerary"))
1228
  st.markdown("Download your personalized travel plan to access it offline or share with your travel companions.")
1229
-
1230
- # Display stylized download button
1231
  st.markdown("""
1232
  <div style="background-color: #f8f9fa; padding: 15px; border-radius: 10px; margin-top: 20px;">
1233
  <h4 style="margin-top: 0;">Your Itinerary File</h4>
1234
  <p style="font-size: 0.9rem; color: #6c757d;">Text format - Can be opened in any text editor</p>
1235
  """, unsafe_allow_html=True)
1236
-
1237
- # Enhanced download link
1238
  st.markdown(
1239
  f"""<div style="margin: 10px 0;">{ get_download_link(st.session_state.generated_itinerary, st.session_state.filename) }</div>""",
1240
  unsafe_allow_html=True
1241
  )
1242
-
1243
  st.markdown("</div>", unsafe_allow_html=True)
1244
-
1245
- # Share options
1246
  st.markdown("### " + t("share_itinerary"))
1247
  st.markdown("*Coming soon: Email your itinerary or share via social media.*")
1248
 
1249
  with col2:
1250
- # QR code placeholder for future implementation
1251
  st.markdown("### " + t("save_for_mobile"))
1252
  st.markdown("*Coming soon: QR code for easy access on your phone*")
1253
 
1254
  st.markdown('</div>', unsafe_allow_html=True)
1255
 
1256
- # Add a reset button to create a new itinerary
1257
  if st.button(t("plan_another_trip"), key="reset_button"):
1258
- # Reset the session state
1259
  st.session_state.generated_itinerary = None
1260
  st.session_state.generation_complete = False
1261
  st.session_state.current_step = 0
@@ -1263,16 +1230,12 @@ if st.session_state.generation_complete:
1263
  st.session_state.results = {}
1264
  st.experimental_rerun()
1265
 
1266
- # Footer for the app
1267
  st.markdown(f"""
1268
  <div style="margin-top: 50px; text-align: center; padding: 20px; color: #6c757d; font-size: 0.8rem;">
1269
  <p>{t("built_with")}</p>
1270
  </div>
1271
  """, unsafe_allow_html=True)
1272
-
1273
- # End of app
1274
 
1275
- # Modern footer with more information
1276
  st.markdown("""
1277
  <div style="margin-top: 50px; border-top: 1px solid #e9ecef; padding: 30px 0; color: #6c757d;">
1278
  <div style="display: flex; justify-content: space-between; flex-wrap: wrap; max-width: 1200px; margin: 0 auto; padding: 0 20px;">
@@ -1293,7 +1256,6 @@ st.markdown("""
1293
  <h4 style="color: #4361ee; margin-bottom: 15px;">Connect</h4>
1294
  <p>Stay updated with our latest travel guides and features.</p>
1295
  <div style="margin-top: 15px;">
1296
- <!-- Social media icons would go here -->
1297
  <span>🐰 🐿 🐸 πŸ¦‰</span>
1298
  </div>
1299
  </div>
 
4
  from datetime import datetime, timedelta
5
  import base64
6
  import pandas as pd
 
7
  from travel import (
8
  destination_research_task, accommodation_task, transportation_task,
9
  activities_task, dining_task, itinerary_task,
10
  run_task
11
  )
12
 
13
+ # st.set_page_config()λŠ” λ‹€λ₯Έ Streamlit ν•¨μˆ˜ ν˜ΈμΆœλ³΄λ‹€ κ°€μž₯ λ¨Όμ € μ‹€ν–‰λ˜μ–΄μ•Ό ν•©λ‹ˆλ‹€.
14
+ st.set_page_config(
15
+ page_title="Globetrotter AI: Your AI Agent for Travelling", # 기본값은 μ˜μ–΄
16
+ page_icon="✈️",
17
+ layout="wide",
18
+ initial_sidebar_state="expanded"
19
+ )
20
+
21
  # ------------------------------------------
22
  # λ‹€κ΅­μ–΄ 지원을 μœ„ν•œ λ²ˆμ—­ 사전 및 헬퍼 ν•¨μˆ˜
23
  # ------------------------------------------
 
280
  }
281
  }
282
 
 
283
  def t(key):
284
  lang = st.session_state.get("selected_language", "en")
285
  return translations[lang].get(key, key)
 
311
  st.session_state.selected_language = lang_map.get(language, "en")
312
 
313
  # ------------------------------------------
314
+ # 이후 Streamlit UI μ½”λ“œ μ‹œμž‘
315
  # ------------------------------------------
316
 
 
 
 
 
 
 
 
 
317
  # Modern CSS with refined color scheme and sleek animations
318
  st.markdown("""
319
  <style>
 
537
  if 'progress_steps' not in st.session_state:
538
  st.session_state.progress_steps = {
539
  0: {'status': 'pending', 'name': t("trip_details")},
540
+ 1: {'status': 'pending', 'name': t("about")}, # 예: μˆ™μ†Œ κ΄€λ ¨
541
+ 2: {'status': 'pending', 'name': t("travel_style")}, # 예: κ΅ν†΅νŽΈ κ΄€λ ¨
542
+ 3: {'status': 'pending', 'name': t("live_agent_outputs")}, # 예: μ•‘ν‹°λΉ„ν‹° κ΄€λ ¨
543
+ 4: {'status': 'pending', 'name': t("download_share")}, # 예: 식사 κ΄€λ ¨
544
  5: {'status': 'pending', 'name': t("full_itinerary")}
545
  }
546
 
 
687
 
688
  return result
689
 
690
+ # ------------------------------------------
691
+ # Session state μ΄ˆκΈ°ν™”
692
+ # ------------------------------------------
693
  if 'generated_itinerary' not in st.session_state:
694
  st.session_state.generated_itinerary = None
695
  if 'generation_complete' not in st.session_state:
 
781
  st.markdown(f"**{name}**")
782
  st.markdown(f"<small>{desc}</small>", unsafe_allow_html=True)
783
  st.markdown('</div>', unsafe_allow_html=True)
784
+
785
  # Main content area
786
  if not st.session_state.generation_complete:
787
  # Sleek form with minimal design
 
822
  "Nature", "Shopping", "Nightlife", "Family-friendly"],
823
  default=["Culture", "Food & Dining"])
824
 
825
+ # Simplified expander for additional preferences
826
  with st.expander("Additional Preferences", expanded=False):
827
  preferences = st.text_area("Interests", placeholder="History museums, local cuisine, hiking, art...")
828
  special_requirements = st.text_area("Special Requirements",
829
  placeholder="Dietary restrictions, accessibility needs...")
830
 
831
+ # Submit button
832
  submit_button = st.form_submit_button(t("submit"))
833
 
834
  st.markdown('</div>', unsafe_allow_html=True)
 
851
  "special_requirements": special_requirements
852
  }
853
 
854
+ # Format the user input for tasks
855
  input_context = f"""Travel Request Details:
856
  Origin: {user_input['origin']}
857
  Destination: {user_input['destination']}
 
864
  Special Requirements: {user_input['special_requirements']}
865
  """
866
 
867
+ # Display processing animation
868
  st.markdown("""
869
  <div class="sleek-processing-container">
870
  <div class="pulse-container">
 
923
  </style>
924
  """, unsafe_allow_html=True)
925
 
926
+ # Create containers for progress, logs, and live output
927
  st.markdown('<div class="modern-card">', unsafe_allow_html=True)
 
 
928
  progress_tab, logs_tab, details_tab = st.tabs(["πŸ“Š Progress", "πŸ”„ Live Activity", "πŸ“‹ Request Details"])
929
 
 
930
  with details_tab:
931
  st.markdown("#### " + t("request_details"))
932
  st.markdown(f"**{t('destination')}:** {user_input['destination']}")
 
940
  st.markdown(f"**Special Requirements:** {user_input['special_requirements']}")
941
 
942
  with progress_tab:
 
943
  if 'progress_placeholder' not in st.session_state:
944
  st.session_state.progress_placeholder = st.empty()
945
  with st.session_state.progress_placeholder.container():
 
949
  log_container = st.container()
950
  st.session_state.log_messages = []
951
 
952
+ st.markdown('</div>', unsafe_allow_html=True)
 
953
  output_container = st.container()
954
  with output_container:
955
  st.markdown('<div class="modern-card">', unsafe_allow_html=True)
 
957
  st.info("Our AI agents will show their work here as they create your itinerary")
958
  st.markdown('</div>', unsafe_allow_html=True)
959
 
 
960
  st.session_state.current_step = 0
961
 
 
 
962
  # Step 1: Destination Research
963
+ update_step_status(0, 'active')
964
  with st.session_state.progress_placeholder.container():
965
  display_modern_progress(st.session_state.current_step)
966
 
 
975
  "destination_info"
976
  )
977
 
978
+ update_step_status(0, 'complete')
 
979
  st.session_state.current_step = 1
980
+ update_step_status(1, 'active')
981
  with st.session_state.progress_placeholder.container():
982
  display_modern_progress(st.session_state.current_step)
983
 
 
994
  "accommodation_info"
995
  )
996
 
997
+ update_step_status(1, 'complete')
 
998
  st.session_state.current_step = 2
999
+ update_step_status(2, 'active')
1000
  with st.session_state.progress_placeholder.container():
1001
  display_modern_progress(st.session_state.current_step)
1002
 
 
1012
  "transportation_info"
1013
  )
1014
 
1015
+ update_step_status(2, 'complete')
 
1016
  st.session_state.current_step = 3
1017
+ update_step_status(3, 'active')
1018
  with st.session_state.progress_placeholder.container():
1019
  display_modern_progress(st.session_state.current_step)
1020
 
 
1030
  "activities_info"
1031
  )
1032
 
1033
+ update_step_status(3, 'complete')
 
1034
  st.session_state.current_step = 4
1035
+ update_step_status(4, 'active')
1036
  with st.session_state.progress_placeholder.container():
1037
  display_modern_progress(st.session_state.current_step)
1038
 
 
1048
  "dining_info"
1049
  )
1050
 
1051
+ update_step_status(4, 'complete')
 
1052
  st.session_state.current_step = 5
1053
+ update_step_status(5, 'active')
1054
  with st.session_state.progress_placeholder.container():
1055
  display_modern_progress(st.session_state.current_step)
1056
 
 
1085
  "itinerary"
1086
  )
1087
 
1088
+ update_step_status(5, 'complete')
 
1089
  st.session_state.current_step = 6
1090
  with st.session_state.progress_placeholder.container():
1091
  display_modern_progress(st.session_state.current_step)
1092
 
 
1093
  st.session_state.generated_itinerary = itinerary
1094
  st.session_state.generation_complete = True
1095
 
 
1096
  date_str = datetime.now().strftime("%Y-%m-%d")
1097
  st.session_state.filename = f"{user_input['destination'].replace(' ', '_')}_{date_str}_itinerary.txt"
 
 
1098
 
1099
  # Display results if generation is complete
1100
  if st.session_state.generation_complete:
 
1101
  st.markdown("""
1102
  <div class="modern-card animate-in">
1103
  <div style="display: flex; justify-content: center; margin-bottom: 20px;">
 
1165
  </style>
1166
  """, unsafe_allow_html=True)
1167
 
 
1168
  st.markdown('<div class="modern-card">', unsafe_allow_html=True)
 
 
1169
  itinerary_tab, details_tab, download_tab = st.tabs([f"πŸ—’οΈ {t('full_itinerary')}", f"πŸ’Ό {t('details')}", f"πŸ’Ύ {t('download_share')}"])
1170
 
1171
  with itinerary_tab:
 
1172
  st.text_area("Your Itinerary", st.session_state.generated_itinerary, height=600)
1173
 
1174
  with details_tab:
 
1175
  agent_tabs = st.tabs([
1176
  "🌎 Destination", "🏨 Accommodation", "πŸš— Transportation",
1177
  "🎭 Activities", "🍽️ Dining"
 
1203
  with col1:
1204
  st.markdown("### " + t("save_itinerary"))
1205
  st.markdown("Download your personalized travel plan to access it offline or share with your travel companions.")
 
 
1206
  st.markdown("""
1207
  <div style="background-color: #f8f9fa; padding: 15px; border-radius: 10px; margin-top: 20px;">
1208
  <h4 style="margin-top: 0;">Your Itinerary File</h4>
1209
  <p style="font-size: 0.9rem; color: #6c757d;">Text format - Can be opened in any text editor</p>
1210
  """, unsafe_allow_html=True)
 
 
1211
  st.markdown(
1212
  f"""<div style="margin: 10px 0;">{ get_download_link(st.session_state.generated_itinerary, st.session_state.filename) }</div>""",
1213
  unsafe_allow_html=True
1214
  )
 
1215
  st.markdown("</div>", unsafe_allow_html=True)
 
 
1216
  st.markdown("### " + t("share_itinerary"))
1217
  st.markdown("*Coming soon: Email your itinerary or share via social media.*")
1218
 
1219
  with col2:
 
1220
  st.markdown("### " + t("save_for_mobile"))
1221
  st.markdown("*Coming soon: QR code for easy access on your phone*")
1222
 
1223
  st.markdown('</div>', unsafe_allow_html=True)
1224
 
 
1225
  if st.button(t("plan_another_trip"), key="reset_button"):
 
1226
  st.session_state.generated_itinerary = None
1227
  st.session_state.generation_complete = False
1228
  st.session_state.current_step = 0
 
1230
  st.session_state.results = {}
1231
  st.experimental_rerun()
1232
 
 
1233
  st.markdown(f"""
1234
  <div style="margin-top: 50px; text-align: center; padding: 20px; color: #6c757d; font-size: 0.8rem;">
1235
  <p>{t("built_with")}</p>
1236
  </div>
1237
  """, unsafe_allow_html=True)
 
 
1238
 
 
1239
  st.markdown("""
1240
  <div style="margin-top: 50px; border-top: 1px solid #e9ecef; padding: 30px 0; color: #6c757d;">
1241
  <div style="display: flex; justify-content: space-between; flex-wrap: wrap; max-width: 1200px; margin: 0 auto; padding: 0 20px;">
 
1256
  <h4 style="color: #4361ee; margin-bottom: 15px;">Connect</h4>
1257
  <p>Stay updated with our latest travel guides and features.</p>
1258
  <div style="margin-top: 15px;">
 
1259
  <span>🐰 🐿 🐸 πŸ¦‰</span>
1260
  </div>
1261
  </div>