Spaces:
Running
Running
import streamlit as st | |
import pandas as pd | |
import joblib | |
import numpy as np | |
import warnings | |
from streamlit.components.v1 import html | |
import time # For simulating loading | |
# --- Set page configuration --- | |
st.set_page_config( | |
page_title="CreditIQ - AI-Powered Credit Expenditure Prediction", | |
page_icon="💳", | |
layout="wide", # Use wide layout to better accommodate complex design | |
initial_sidebar_state="collapsed" # Hide sidebar to give full canvas | |
) | |
# --- Initialize session state for page management --- | |
if 'active_page' not in st.session_state: | |
st.session_state.active_page = 'home' | |
if 'show_prediction' not in st.session_state: | |
st.session_state.show_prediction = False | |
if 'predicted_value' not in st.session_state: | |
st.session_state.predicted_value = 0.0 | |
warnings.filterwarnings('ignore') | |
st.markdown(""" | |
<style> | |
/* Hide Streamlit's default header, footer, and hamburger menu */ | |
#MainMenu, header, footer { visibility: hidden; } | |
/* Remove padding from the main block container for a full-width feel */ | |
.block-container { | |
padding: 0 !important; | |
} | |
[class*="st-key-dismiss_modal_btn"] { | |
display:none; | |
} | |
div.stButton > button { | |
background: transparent; | |
color: var(--gray-light); | |
text-decoration: none !important; | |
font-weight: 500; | |
transition: all 0.3s ease; | |
font-family: "Times New Roman " !important; /* Font */ | |
font-size: 18px !important; /* Font size */ | |
border: none; /* Remove border */ | |
display: flex; | |
align-items: center; | |
justify-content: center; | |
width:110px; | |
height:50px; | |
margin-top:-5px; | |
position:fixed; | |
z-index:10000000; | |
} | |
div[data-testid="stSelectbox"] | |
{{ | |
background-color: white !important; | |
position: relative; | |
border-bottom:1px solid #ccc; | |
border-radius:0px; | |
}} | |
div[data-testid="stTextInput"]{{ | |
}} | |
div[data-testid="stTextInput"] > div >div {{ | |
background-color: rgba(255, 158, 87, 0.12) !important; | |
}} | |
div[data-testid="stTextInputRootElement"]{{ | |
border: 1px solid white !important; | |
}} | |
/* Hover effect */ | |
div.stButton > button:hover { | |
color: var(--white) !important; | |
transform: none !important; | |
} | |
div.stButton > button.active { | |
color: var(--white) !important; | |
} | |
/* Style the sidebar to have a modern, dark look */ | |
section[data-testid="stSidebar"] {{ | |
backdrop-filter: blur(10px); | |
background: rgba(255, 255, 255, 0.15); | |
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.01); | |
height:100px; | |
[data-testid="stSidebar"] h2 {{ | |
color: #FFFFFF; /* White headers in the sidebar */ | |
font-family:time new roman !important; | |
}} | |
[data-testid="stSidebar"] .st-emotion-cache-1629p8f a {{ | |
color: #94A3B8; /* Lighter text color for links */ | |
font-family:time new roman !important; | |
}} | |
[data-testid="stImageContainer"]>img{{ | |
max-width:70% !important; | |
margin-top:-70px; | |
}} | |
div[data-testid="stMarkdownContainer"] >p{{ | |
font-family:time new roman !important; | |
}} | |
</style> | |
""", unsafe_allow_html=True) | |
# --- Inject Custom HTML, CSS, and Inline JavaScript --- | |
# This block defines the sophisticated styling and background animations, | |
# navigation, and overall page structure. | |
# Streamlit components will be injected into specific HTML placeholders. | |
st.markdown(f""" | |
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>CreditIQ - AI-Powered Credit Expenditure Prediction</title> | |
<meta name="description" content="Professional AI-powered credit card expenditure prediction platform. Get accurate spending forecasts with advanced machine learning algorithms."> | |
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>💳</text></svg>"> | |
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800;900&display=swap" rel="stylesheet"> | |
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet"> | |
<style> | |
/* General Resets */ | |
* {{ | |
margin: 0; | |
padding: 0; | |
box-sizing: border-box; | |
font-family:time new roman !important; | |
}} | |
html, body, .main {{ | |
margin: 0; | |
padding: 0; | |
height: 100%; | |
overflow-x: hidden; | |
position: relative; | |
}} | |
i[class^="fa"], i[class*=" fa"] {{ | |
font-family: "Font Awesome 6 Free" !important; | |
font-weight: 900 !important; | |
font-style: normal !important; | |
display: inline-block !important; | |
text-rendering: auto; | |
-webkit-font-smoothing: antialiased; | |
}} | |
/* Custom Button Styling for Navigation */ | |
.nav-button {{ | |
background: transparent !important; | |
color: var(--gray-light) !important; | |
border: none !important; | |
font-weight: 500 !important; | |
font-family: 'Inter', sans-serif !important; | |
padding: 0 !important; | |
text-align: center; | |
position: relative; | |
transition: all 0.3s ease; | |
box-shadow: none !important; | |
}} | |
[class*="st-key-nav_"]:hover {{ | |
color: var(--white) !important; | |
transform: none !important; | |
}} | |
[class*="st-key-nav_home_home"]::after | |
{{ | |
content: ''; | |
position: absolute; | |
bottom: -8px; | |
left: 0; | |
width: 100%; | |
height: 2px; | |
background: var(--gradient-accent); | |
color: var(--white) !important; | |
margin-left:15px; | |
}} | |
[class*="st-key-nav_about_about"]::after | |
{{ | |
content: ''; | |
position: absolute; | |
bottom: -8px; | |
left: 0; | |
width: 100%; | |
height: 2px; | |
background: var(--gradient-accent); | |
color: var(--white) !important; | |
margin-left:15px; | |
}} | |
[class*="st-key-nav_predictor_predictor"]::after | |
{{ | |
content: ''; | |
position: absolute; | |
bottom: -8px; | |
left: 0; | |
width: 100%; | |
height: 2px; | |
background: var(--gradient-accent); | |
color: var(--white) !important; | |
margin-left:15px; | |
}} | |
[class*="st-key-nav_features_features"]::after | |
{{ | |
content: ''; | |
position: absolute; | |
bottom: -8px; | |
left: 0; | |
width: 100%; | |
height: 2px; | |
background: var(--gradient-accent); | |
color: var(--white) !important; | |
margin-left:15px; | |
}} | |
[class*="st-key-nav_contact_contact"]::after | |
{{ | |
content: ''; | |
position: absolute; | |
bottom: -8px; | |
left: 0; | |
width: 45%; | |
height: 2px; | |
background: var(--gradient-accent); | |
color: var(--white) !important; | |
margin-left:15px; | |
}} | |
/* Root Variables for Colors and Shadows */ | |
:root {{ | |
--primary: #4F46E5; | |
--primary-dark: #3730A3; | |
--secondary: #06B6D4; | |
--accent: #8B5CF6; | |
--success: #10B981; | |
--warning: #F59E0B; | |
--error: #EF4444; | |
--dark: #0F172A; | |
--dark-light: #1E293B; | |
--gray: #64748B; | |
--gray-light: #94A3B8; | |
--white: #FFFFFF; | |
--glass-bg: rgba(255, 255, 255, 0.1); | |
--glass-nav: rgba(255, 255, 255, 0.03); | |
--glass-border: rgba(255, 255, 255, 0.2); | |
--gradient-primary: linear-gradient(135deg, #667eea 0%, #764ba2 100%); | |
--gradient-secondary: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); | |
--gradient-accent: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); | |
--shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.1); | |
--shadow-md: 0 8px 32px rgba(0, 0, 0, 0.15); | |
--shadow-lg: 0 16px 64px rgba(0, 0, 0, 0.2); | |
}} | |
/* Body and App Background */ | |
body, .stApp {{ | |
font-family: 'Inter', sans-serif; | |
background: linear-gradient(135deg, #0F172A 0%, #1E293B 100%); | |
color: var(--white); | |
line-height: 1.6; | |
overflow-x: hidden; | |
height: 100vh; | |
position: relative; /* Needed for absolute positioning of bg-animation */ | |
}} | |
/* Streamlit's main content wrapper */ | |
.st-emotion-block-container {{ | |
max-width: 1200px; | |
margin: 0 auto; | |
padding: 0 2rem; | |
position: relative; | |
z-index: 1; /* Ensure content is above backgrounds */ | |
}} | |
/* Background Animation */ | |
.bg-animation {{ | |
position: absolute; | |
top: 0; | |
left: 0; | |
width: 100%; | |
height: 100%; | |
z-index: -2; /* Ensure it's behind everything */ | |
background: linear-gradient(45deg, #667eea, #764ba2, #f093fb, #f5576c, #4facfe, #00f2fe); | |
background-size: 400% 400%; | |
animation: gradientShift 15s ease infinite; | |
}} | |
@keyframes gradientShift {{ | |
0% {{ background-position: 0% 50%; }} | |
50% {{ background-position: 100% 50%; }} | |
100% {{ background-position: 0% 50%; }} | |
}} | |
/* Floating Shapes Animation */ | |
.floating-shapes {{ | |
position: fixed; | |
top: 0; | |
left: 0; | |
width: 100%; | |
height: 100%; | |
z-index: -1; /* Above bg-animation, below content */ | |
pointer-events: none; /* Allows clicks to pass through */ | |
}} | |
.shape {{ | |
position: absolute; | |
opacity: 0.1; | |
animation: float 20s infinite ease-in-out; | |
}} | |
.shape:nth-child(1) {{ | |
top: 10%; | |
left: 10%; | |
width: 80px; | |
height: 80px; | |
background: var(--gradient-accent); | |
border-radius: 50%; | |
animation-delay: 0s; | |
}} | |
.shape:nth-child(2) {{ | |
top: 70%; | |
right: 10%; | |
width: 120px; | |
height: 120px; | |
background: var(--gradient-secondary); | |
border-radius: 30% 70% 70% 30% / 30% 30% 70% 70%; | |
animation-delay: 5s; | |
}} | |
.shape:nth-child(3) {{ | |
bottom: 20%; | |
left: 20%; | |
width: 100px; | |
height: 100px; | |
background: var(--gradient-primary); | |
border-radius: 20px; | |
transform: rotate(45deg); | |
animation-delay: 10s; | |
}} | |
@keyframes float {{ | |
0%, 100% {{ transform: translateY(0px) rotate(0deg); }} | |
33% {{ transform: translateY(-30px) rotate(120deg); }} | |
66% {{ transform: translateY(15px) rotate(240deg); }} | |
}} | |
/* Navigation */ | |
.navbar {{ | |
position: fixed; | |
top: 0; | |
width: 100%; | |
z-index: 1000; | |
transition: all 0.3s ease; | |
background: var(--glass-nav); | |
backdrop-filter: blur(20px); | |
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); | |
}} | |
.navbar.scrolled {{ | |
background: rgba(15, 23, 42, 0.98); | |
box-shadow: var(--shadow-md); | |
}} | |
.nav-container {{ | |
max-width: 1500px; | |
margin: 0 auto; | |
padding: 0 2rem; | |
display: flex; | |
justify-content: space-between; | |
align-items: center; | |
height: 80px; | |
}} | |
.logo {{ | |
font-size: 1.8rem; | |
font-weight: 800; | |
background: var(--gradient-accent); | |
-webkit-background-clip: text; | |
-webkit-text-fill-color: transparent; | |
background-clip: text; | |
text-decoration: none; | |
}} | |
.nav-menu {{ | |
display: flex; | |
list-style: none; | |
gap: 2rem; | |
align-items: center; | |
}} | |
.nav-link {{ | |
color: var(--gray-light); | |
text-decoration: none !important; | |
font-weight: 500; | |
transition: all 0.3s ease; | |
position: relative; | |
}} | |
.nav-link:hover, | |
.nav-link.active {{ | |
color: var(--white); | |
}} | |
.nav-link::after {{ | |
content: ''; | |
position: absolute; | |
bottom: -5px; | |
left: 0; | |
width: 0; | |
height: 2px; | |
background: var(--gradient-accent); | |
transition: width 0.3s ease; | |
}} | |
.nav-link:hover::after, | |
.nav-link.active::after {{ | |
width: 100%; | |
}} | |
.cta-btn {{ | |
background: var(--gradient-accent); | |
color: var(--white); | |
padding: 0.75rem 1.5rem; | |
border-radius: 50px; | |
text-decoration: none; | |
font-weight: 600; | |
transition: all 0.3s ease; | |
box-shadow: var(--shadow-sm); | |
}} | |
.cta-btn:hover {{ | |
transform: translateY(-2px); | |
box-shadow: var(--shadow-md); | |
}} | |
.mobile-menu-btn {{ | |
display: none; | |
background: none; | |
border: none; | |
color: var(--white); | |
font-size: 1.5rem; | |
cursor: pointer; | |
}} | |
/* Hero Section */ | |
.hero {{ | |
height: 900px; | |
display: flex; | |
align-items: center; | |
position: relative; | |
overflow: hidden; | |
padding-top: 80px; /* Account for fixed navbar */ | |
margin-top:-250px; | |
}} | |
.hero-bg {{ | |
position: absolute; | |
top: 0; | |
left: 0; | |
width: 100%; | |
height: 100%; | |
background: var(--gradient-primary); | |
opacity: 0.1; | |
/*animation: gradientShift 15s ease infinite;*/ | |
z-index: -1; | |
}} | |
.hero-container {{ | |
max-width: 1200px; | |
margin: 0 auto; | |
padding: 0 2rem; | |
display: grid; | |
grid-template-columns: 1fr 1fr; | |
gap: 4rem; | |
align-items: center; | |
position: relative; | |
z-index: 1; | |
width: 100%; /* Ensure it takes full width of st.container */ | |
}} | |
.hero-content h1 {{ | |
font-size: 4rem; | |
font-weight: 900; | |
line-height: 1.1; | |
margin-bottom: 1.5rem; | |
background: linear-gradient(135deg, #fff, #e2e8f0); | |
-webkit-background-clip: text; | |
-webkit-text-fill-color: transparent; | |
background-clip: text; | |
}} | |
.hero-content .highlight {{ | |
background: var(--gradient-accent); | |
-webkit-background-clip: text; | |
-webkit-text-fill-color: transparent; | |
background-clip: text; | |
}} | |
.hero-content p {{ | |
font-size: 1.2rem; | |
color: var(--gray-light); | |
margin-bottom: 2rem; | |
max-width: 500px; | |
}} | |
.hero-buttons {{ | |
display: flex; | |
gap: 1rem; | |
flex-wrap: wrap; | |
}} | |
.btn-primary {{ | |
background: var(--gradient-accent); | |
color: var(--white); | |
padding: 1rem 2rem; | |
border-radius: 50px; | |
text-decoration: none; | |
font-weight: 600; | |
transition: all 0.3s ease; | |
display: inline-flex; | |
align-items: center; | |
gap: 0.5rem; | |
box-shadow: var(--shadow-md); | |
}} | |
.btn-primary:hover {{ | |
transform: translateY(-3px); | |
box-shadow: var(--shadow-lg); | |
}} | |
.btn-secondary {{ | |
background: transparent; | |
color: var(--white); | |
padding: 1rem 2rem; | |
border: 2px solid var(--glass-border); | |
border-radius: 50px; | |
text-decoration: none; | |
font-weight: 600; | |
transition: all 0.3s ease; | |
display: inline-flex; | |
align-items: center; | |
gap: 0.5rem; | |
}} | |
.btn-secondary:hover {{ | |
background: var(--glass-bg); | |
border-color: var(--white); | |
}} | |
.hero-visual {{ | |
position: relative; | |
height: 500px; /* Fixed height for visual consistency */ | |
width: 100%; | |
}} | |
.hero-card {{ | |
position: absolute; | |
background: var(--glass-bg); | |
backdrop-filter: blur(20px); | |
border: 1px solid var(--glass-border); | |
border-radius: 24px; | |
padding: 2rem; | |
box-shadow: var(--shadow-lg); | |
animation: float 6s ease-in-out infinite; | |
}} | |
.hero-card:nth-child(1) {{ | |
top: 0; | |
left: 0; | |
width: 280px; | |
animation-delay: 0s; | |
}} | |
.hero-card:nth-child(2) {{ | |
top: 100px; | |
right: 0; | |
width: 250px; | |
animation-delay: 2s; | |
}} | |
.hero-card:nth-child(3) {{ | |
bottom: 0; | |
left: 50px; | |
width: 200px; | |
animation-delay: 4s; | |
}} | |
/* Main Content Pages */ | |
/* Streamlit will show/hide these based on st.session_state */ | |
.page {{ | |
display: none; /* Controlled by Streamlit's Python logic */ | |
height: 900px; | |
padding: 120px 0 80px; /* Padding for header/footer */ | |
margin-top: -250px; | |
}} | |
.page.active {{ | |
display: block; /* Shown by Streamlit */ | |
margin-top: -100px !important; | |
}} | |
.page-header {{ | |
text-align: center; | |
margin-bottom: 4rem; | |
margin-top:-50px; | |
}} | |
.page-header h1 {{ | |
font-size: 3rem; | |
font-weight: 800; | |
margin-bottom: 1rem; | |
background: linear-gradient(135deg, #fff, #e2e8f0); | |
-webkit-background-clip: text; | |
-webkit-text-fill-color: transparent; | |
background-clip: text; | |
}} | |
.page-header p {{ | |
font-size: 1.2rem; | |
color: var(--gray-light); | |
max-width: 600px; | |
margin: 0 auto; | |
margin-top:-20px | |
}} | |
/* Predictor Form */ | |
/* Streamlit Help Text Overrides */ | |
.st-cg, .st-cr {{ | |
font-size: 0.8rem; | |
color: var(--gray-light); | |
margin-top: 0.25rem; | |
}} | |
.predict-btn-custom {{ /* Custom class to be used by st.button */ | |
background: var(--gradient-accent) !important; | |
color: var(--white) !important; | |
padding: 1.25rem 3rem !important; | |
border: none !important; | |
border-radius: 50px !important; | |
font-size: 1.1rem !important; | |
font-weight: 700 !important; | |
cursor: pointer !important; | |
transition: all 0.3s ease !important; | |
display: block !important; | |
margin: 2rem auto !important; | |
text-transform: uppercase !important; | |
letter-spacing: 1px !important; | |
box-shadow: var(--shadow-md) !important; | |
position: relative !important; | |
overflow: hidden !important; | |
}} | |
.predict-btn-custom:hover {{ | |
transform: translateY(-3px) !important; | |
box-shadow: var(--shadow-lg) !important; | |
}} | |
.predict-btn-custom::before {{ | |
content: ''; | |
position: absolute; | |
top: 0; | |
left: -100%; | |
width: 100%; | |
height: 100%; | |
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent); | |
transition: left 0.5s; | |
}} | |
.predict-btn-custom:hover::before {{ | |
left: 100%; | |
}} | |
.result-card {{ | |
background: var(--glass-bg); | |
backdrop-filter: blur(20px); | |
border: 1px solid var(--glass-border); | |
border-radius: 24px; | |
padding: 3rem; | |
text-align: center; | |
transform: translateY(30px); | |
transition: all 0.5s ease; | |
}} | |
.result-card.show {{ | |
opacity: 1; | |
transform: translateY(0); | |
}} | |
.result-amount {{ | |
font-size: 3.5rem; | |
font-weight: 900; | |
background: var(--gradient-accent); | |
-webkit-background-clip: text; | |
-webkit-text-fill-color: transparent; | |
background-clip: text; | |
margin-bottom: 1rem; | |
animation: countUp 1s ease-out; | |
}} | |
/* Features Section */ | |
.features-grid {{ | |
display: grid; | |
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); | |
gap: 2rem; | |
margin:25px; | |
}} | |
.feature-card {{ | |
background: var(--glass-bg); | |
backdrop-filter: blur(20px); | |
border: 1px solid var(--glass-border); | |
border-radius: 24px; | |
padding: 2.5rem; | |
text-align: center; | |
transition: all 0.3s ease; | |
box-shadow: var(--shadow-sm); /* Default shadow */ | |
}} | |
.feature-card:hover {{ | |
transform: translateY(-10px); | |
box-shadow: var(--shadow-lg); | |
}} | |
.feature-icon {{ | |
font-size: 3rem; | |
background: var(--gradient-accent); | |
-webkit-background-clip: text; | |
-webkit-text-fill-color: transparent; | |
background-clip: text; | |
margin-bottom: 1rem; | |
}} | |
.feature-card h3 {{ | |
font-size: 1.5rem; | |
font-weight: 700; | |
margin-bottom: 1rem; | |
color: var(--white); /* Ensure headings are visible */ | |
}} | |
/* About Section */ | |
.about-content {{ | |
display: grid; | |
grid-template-columns: 1fr 1fr; | |
gap: 4rem; | |
align-items: center; | |
margin:30px; | |
}} | |
.about-text h2 {{ | |
font-size: 2.5rem; | |
font-weight: 800; | |
margin-bottom: 1.5rem; | |
background: linear-gradient(135deg, #fff, #e2e8f0); | |
-webkit-background-clip: text; | |
-webkit-text-fill-color: transparent; | |
background-clip: text; | |
}} | |
.about-text p {{ | |
margin-bottom: 1.5rem; | |
color: var(--gray-light); | |
font-size: 1.1rem; | |
}} | |
.stats-grid {{ | |
display: grid; | |
grid-template-columns: repeat(2, 1fr); | |
gap: 2rem; | |
margin-top: 3rem; | |
}} | |
.stat-card {{ | |
text-align: center; | |
padding: 2rem; | |
background: var(--glass-bg); | |
border-radius: 16px; | |
box-shadow: var(--shadow-sm); | |
}} | |
.stat-number {{ | |
font-size: 2.5rem; | |
font-weight: 900; | |
background: var(--gradient-accent); | |
-webkit-background-clip: text; | |
-webkit-text-fill-color: transparent; | |
background-clip: text; | |
}} | |
/* Contact Section */ | |
[class*="st-key-contact-form"]{{ | |
background: var(--glass-bg); | |
backdrop-filter: blur(20px); | |
border: 1px solid var(--glass-border); | |
border-radius: 24px; | |
padding: 0.5rem; | |
max-width: 800px; | |
margin: 0 auto; | |
margin-top:-680px; | |
max-height:400px !important; | |
}} | |
/* Loading Animation */ | |
.loading {{ | |
display: none; /* Controlled by Streamlit's session state */ | |
text-align: center; | |
padding: 2rem; | |
}} | |
.loading.show {{ | |
display: block; | |
}} | |
.spinner {{ | |
width: 40px; | |
height: 40px; | |
border: 3px solid rgba(255, 255, 255, 0.3); | |
border-top: 3px solid var(--secondary); | |
border-radius: 50%; | |
animation: spin 1s linear infinite; | |
margin: 0 auto 1rem; | |
}} | |
@keyframes spin {{ | |
0% {{ transform: rotate(0deg); }} | |
100% {{ transform: rotate(360deg); }} | |
}} | |
/* Responsive Design */ | |
@media (max-width: 768px) {{ | |
.mobile-menu-btn {{ | |
display: block; | |
}} | |
.nav-menu {{ | |
position: fixed; | |
top: 80px; | |
left: -100%; | |
width: 100%; | |
height: calc(100vh - 80px); | |
background: var(--dark); | |
flex-direction: column; | |
justify-content: center; | |
transition: left 0.3s ease; | |
}} | |
.nav-menu.active {{ | |
left: 0; | |
}} | |
.hero-container {{ | |
grid-template-columns: 1fr; | |
text-align: center; | |
padding-top: 2rem; /* Adjust padding for mobile hero */ | |
}} | |
.hero-visual {{ | |
height: auto; /* Allow height to adjust */ | |
margin-top: 2rem; | |
}} | |
.hero-card {{ | |
position: static; /* Remove absolute positioning on mobile */ | |
width: 100%; | |
margin-bottom: 1.5rem; | |
animation: none; /* Disable float animation on mobile */ | |
}} | |
.page {{ | |
padding: 100px 0 60px; /* Adjust page padding for mobile */ | |
}} | |
.header h1, .page-header h1 {{ | |
font-size: 2.5rem; | |
}} | |
.header .icon {{ | |
font-size: 3rem; | |
}} | |
.main-form, .predictor-form, .contact-form {{ | |
padding: 2rem; | |
border-radius: 24px; | |
}} | |
.input-grid, .form-grid {{ | |
grid-template-columns: 1fr; | |
gap: 1.5rem; | |
}} | |
.result-amount {{ | |
font-size: 2.5rem; | |
}} | |
.about-content, .footer-content {{ | |
grid-template-columns: 1fr; | |
}} | |
.stats-grid {{ | |
grid-template-columns: 1fr; | |
}} | |
}} | |
/* Streamlit Specific Overrides */ | |
/* Hide Streamlit's default header/footer elements */ | |
footer {{ visibility: hidden; height: 0; overflow: hidden; }} /* Hides Streamlit's "Made with Streamlit" */ | |
#MainMenu {{ visibility: hidden; }} /* Hides Streamlit's main menu icon */ | |
.css-vk325g {{ /* Targets the header elements generated by Streamlit */ | |
display: none !important; | |
}} | |
</style> | |
</head> | |
<body> | |
<div class="bg-animation"></div> | |
<div class="floating-shapes"> | |
<div class="shape"></div> | |
<div class="shape"></div> | |
<div class="shape"></div> | |
</div> | |
<!-- Navigation --> | |
<nav class="navbar" id="navbar"> | |
<div class="nav-container"> | |
<a href="#" class="logo" onclick="showPage('home')">CreditIQ</a> | |
""",unsafe_allow_html=True) | |
nav_cols = st.columns([5, 0.5, 0.5, 0.5, 0.5, 1]) | |
with nav_cols[0]: | |
st.markdown('<p class="logo">CreditIQ</p>', unsafe_allow_html=True) | |
nav_items = ["home", "predictor", "features", "about", "contact"] | |
for i, item in enumerate(nav_items): | |
with nav_cols[i+1]: | |
active = "active" if st.session_state.active_page == item else "" | |
# Each button click updates the session state and triggers a rerun | |
if st.button(item, key=f"nav_{item}_{st.session_state.active_page}", use_container_width=True): | |
st.session_state.active_page = item | |
st.session_state.show_prediction = False # Reset prediction display | |
st.rerun() | |
# JavaScript to apply the correct CSS classes to the Streamlit buttons | |
st.markdown(""" | |
<script> | |
const buttons = window.parent.document.querySelectorAll('.stButton button'); | |
const activePage = '""" + st.session_state.active_page + """'; | |
buttons.forEach(button => { | |
const buttonText = button.innerText; | |
if (["Home", "Predictor", "Features", "About", "Contact"].includes(buttonText)) { | |
button.classList.add('nav-button'); | |
if (buttonText === activePage) { | |
button.classList.add('active'); | |
} | |
} | |
}); | |
</script> | |
""", unsafe_allow_html=True) | |
st.markdown(f""" | |
</div> | |
</nav> | |
<!-- Content Pages (managed by Streamlit Python logic) --> | |
<div id="streamlit_content_container"> | |
<!-- Streamlit will inject its components here, corresponding to active_page --> | |
</div> | |
<!-- This part of the HTML is only for the footer, as Streamlit manages the main content --> | |
<footer class="app-footer"> | |
<div class="footer-content"> | |
<div class="footer-section"> | |
<h3>CreditIQ</h3> | |
<p style="color: var(--gray-light); font-size: 0.9rem;">Your trusted AI partner for credit expenditure forecasting. Empowering financial decisions.</p> | |
</div> | |
<div class="footer-section"> | |
<h3>Quick Links</h3> | |
<ul> | |
<li><a href="#" onclick="showPage('home')">Home</a></li> | |
<li><a href="#" onclick="showPage('predictor')">Predictor</a></li> | |
<li><a href="#" onclick="showPage('features')">Features</a></li> | |
<li><a href="#" onclick="showPage('about')">About</a></li> | |
</ul> | |
</div> | |
<div class="footer-section"> | |
<h3>Contact Us</h3> | |
<p style="color: var(--gray-light);"><i class="fas fa-envelope"></i> [email protected]</p> | |
<p style="color: var(--gray-light);"><i class="fas fa-phone"></i> +1 (123) 456-7890</p> | |
</div> | |
<div class="footer-section"> | |
<h3>Follow Us</h3> | |
<ul style="display: flex; gap: 1rem;"> | |
<li><a href="#" style="font-size: 1.2rem;"><i class="fab fa-facebook-f"></i></a></li> | |
<li><a href="#" style="font-size: 1.2rem;"><i class="fab fa-twitter"></i></a></li> | |
<li><a href="#" style="font-size: 1.2rem;"><i class="fab fa-linkedin-in"></i></a></li> | |
<li><a href="#" style="font-size: 1.2rem;"><i class="fab fa-instagram"></i></a></li> | |
</ul> | |
</div> | |
</div> | |
<div class="footer-bottom"> | |
© 2023 CreditIQ. All rights reserved. | |
</div> | |
</footer> | |
</body> | |
</html> | |
""", unsafe_allow_html=True) | |
st.markdown(""" | |
<style> | |
:root { | |
--primary-gradient: linear-gradient(135deg, #667eea 0%, #764ba2 100%); | |
--secondary-gradient: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); | |
--accent-gradient: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); | |
--dark-gradient: linear-gradient(135deg, #0c0c0c 0%, #1a1a1a 100%); | |
--glass-bg: rgba(255, 255, 255, 0.1); | |
--glass-border: rgba(255, 255, 255, 0.2); | |
--shadow-medium: 0 16px 64px rgba(0, 0, 0, 0.15); | |
--shadow-strong: 0 24px 96px rgba(0, 0, 0, 0.2); | |
} | |
.bg-animation { | |
position: fixed; top: 0; left: 0; | |
width: 100%; height: 100%; z-index: -2; | |
background: linear-gradient(45deg, #667eea, #764ba2, #f093fb, #f5576c, #4facfe, #00f2fe); | |
background-size: 400% 400%; animation: gradientShift 15s ease infinite; | |
} | |
@keyframes gradientShift { 0% {background-position: 0% 50%;} 50% {background-position: 100% 50%;} 100% {background-position: 0% 50%;} } | |
.floating-shapes { | |
position: fixed; top: 0; left: 0; | |
width: 100%; height: 100%; z-index: -1; pointer-events: none; | |
} | |
.shape { position: absolute; opacity: 0.1; animation: float 20s infinite ease-in-out; } | |
.shape:nth-child(1) { top: 10%; left: 10%; width: 80px; height: 80px; background: var(--accent-gradient); border-radius: 50%; } | |
.shape:nth-child(2) { top: 70%; right: 10%; width: 120px; height: 120px; background: var(--secondary-gradient); border-radius: 30% 70% 70% 30% / 30% 30% 70% 70%; animation-delay: 5s; } | |
.shape:nth-child(3) { bottom: 20%; left: 20%; width: 100px; height: 100px; background: var(--primary-gradient); border-radius: 20px; transform: rotate(45deg); animation-delay: 10s; } | |
@keyframes float { 0%, 100% {transform: translateY(0px) rotate(0deg);} 33% {transform: translateY(-30px) rotate(120deg);} 66% {transform: translateY(15px) rotate(240deg);} } | |
/* Header and Form Styling */ | |
.header { text-align: center; margin-bottom: 3rem; } | |
.header h1 { font-size: 3.5rem; font-weight: 900; background: linear-gradient(135deg, #fff, #f0f0f0); -webkit-background-clip: text; -webkit-text-fill-color: transparent; margin-bottom: 1rem; } | |
.header .icon { font-size: 4rem; margin-bottom: 1rem; background: var(--accent-gradient); -webkit-background-clip: text; -webkit-text-fill-color: transparent; } | |
.header p { font-size: 1.2rem; color: rgba(255, 255, 255, 0.8); max-width: 600px; margin: 0 auto; } | |
.section-title { | |
font-size: 1.8rem; | |
font-weight: 700; | |
margin-bottom: 2rem; | |
text-align: center; | |
background: linear-gradient(135deg, #fff, #f0f0f0); | |
-webkit-background-clip: text; | |
-webkit-text-fill-color: transparent; | |
font-family:time new roman !important; | |
} | |
/* Styling Streamlit Widgets to Match Your Design */ | |
.stTextInput label, .stNumberInput label, .stSelectbox label { | |
font-weight: 500; margin-bottom: 0.5rem; color: rgba(255, 255, 255, 0.9); | |
font-size: 0.9rem; text-transform: uppercase; letter-spacing: 0.5px; | |
font-family:time new roman !important; | |
} | |
.stTextInput label > div > p, .stNumberInput label > div > p , .stSelectbox label > div > p { | |
font-family:time new roman !important; | |
} | |
.stTextInput input, .stNumberInput input{ | |
width: 100%; padding: 1rem 1.25rem; | |
background: rgba(255, 255, 255, 0.1) !important; | |
border: 1px solid rgba(255, 255, 255, 0.2) !important; | |
border-radius: 16px !important; color: #004cff !important; | |
font-size: 1rem !important; transition: all 0.3s ease !important; | |
backdrop-filter: blur(10px) !important; | |
font-family:time new roman !important; | |
} | |
.stSelectbox div[data-baseweb="select"] > div { | |
font-family:time new roman !important; | |
} | |
.stForm [data-testid="stFormSubmitButton"] button > div > p { | |
font-family:time new roman !important; | |
} | |
.stForm [data-testid="stFormSubmitButton"] button { | |
background: var(--accent-gradient); border: none; padding: 1.25rem 3rem; | |
border-radius: 50px; color: white; font-size: 1.1rem; | |
font-weight: 700; cursor: pointer; transition: all 0.3s ease; | |
text-transform: uppercase; letter-spacing: 1px; | |
box-shadow: var(--shadow-medium); display: block; margin: 2rem auto; | |
font-family:time new roman !important; | |
height:60px; | |
text-align:center; | |
margin-top:-3px; | |
} | |
.stForm [data-testid="stFormSubmitButton"] button:hover { | |
transform: translateY(-3px); box-shadow: var(--shadow-strong); | |
font-family:time new roman !important; | |
} | |
[class*="st-key-pred"] >div >button >div >p { | |
text-decoration: underline; | |
color:var(--primary); | |
width:200px; | |
font-weight:bold; | |
} | |
[class*="st-key-pred"]>div >button:active { | |
background:transparent !important; | |
} | |
[class*="st-key-abt"] >div >button >div >p { | |
text-decoration: underline; | |
color:var(--primary); | |
width:200px; | |
font-weight:bold; | |
} | |
[class*="st-key-abt"]>div >button:active { | |
background:transparent !important; | |
} | |
[class*="st-key-navbtn"] { | |
display: flex; | |
gap: 1rem; | |
z-index:100000000; | |
margin-top:-330px; | |
flex-wrap: wrap; | |
margin-left:200px; | |
} | |
[class*="st-key-abt"] { | |
background: transparent; | |
color: var(--white); | |
padding: 1rem 2rem; | |
border: 2px solid var(--glass-border); | |
border-radius: 50px; | |
text-decoration: none; | |
font-weight: 600; | |
transition: all 0.3s ease; | |
display: inline-flex; | |
align-items: center; | |
gap: 0.5rem; | |
width:185px; | |
margin-left:220px; | |
height:60px; | |
margin-top:-74px; | |
} | |
[class*="st-key-pred"] { | |
background: var(--gradient-accent); | |
color: var(--white); | |
padding: 1rem 2rem; | |
border-radius: 50px; | |
text-decoration: none; | |
font-weight: 600; | |
transition: all 0.3s ease; | |
display: inline-flex; | |
align-items: center; | |
gap: 0.5rem; | |
box-shadow: var(--shadow-md); | |
width:200px; | |
height:60px; | |
} | |
[class*="st-key-pred"] :hover { | |
transform: translateY(-3px); box-shadow: var(--shadow-strong); | |
font-family:time new roman !important; | |
} | |
/* Result Card */ | |
.result-card { | |
background: var(--glass-bg); backdrop-filter: blur(20px); | |
border: 1px solid var(--glass-border); border-radius: 24px; | |
padding: 2.5rem; margin-top: 2rem; text-align: center; | |
box-shadow: var(--shadow-medium); | |
} | |
.result-amount { font-size: 3rem; font-weight: 900; background: var(--accent-gradient); -webkit-background-clip: text; -webkit-text-fill-color: transparent; margin-bottom: 1rem; } | |
.result-label { font-size: 1.2rem; color: rgba(255, 255, 255, 0.8); margin-bottom: 1rem; } | |
button[kind="secondary"] { | |
position: relative !important; | |
} | |
button[kind="secondary"]:hover,button[kind="secondary"]:active { | |
color: var(--white) !important; | |
} | |
button[kind="secondary"]:active { | |
background: linear-gradient(to right, #4f46e5, #9333ea); | |
} | |
[class*="st-key-main-form"]{ | |
background: var(--glass-bg); backdrop-filter: blur(20px); | |
border: 1px solid var(--glass-border); border-radius: 32px; | |
padding: 3rem; box-shadow: var(--shadow-strong); | |
width:60%; | |
align-self: center; | |
color:blue; | |
max-height:520px; | |
} | |
</style> | |
""", unsafe_allow_html=True) | |
# --- Load the trained model --- | |
def load_model(): | |
try: | |
model = joblib.load('credit_card_expenditure_model.joblib') | |
return model | |
except FileNotFoundError: | |
st.error("Model file 'credit_card_expenditure_model.joblib' not found. Please ensure it's in the same directory as this app.") | |
st.stop() # Stop the app if model is not found | |
except Exception as e: | |
st.error(f"Error loading model: {e}") | |
st.stop() | |
# --- Streamlit Content Injection --- | |
# This section uses st.empty() to create a placeholder where our content | |
# for the active page will be rendered. | |
streamlit_content_placeholder = st.empty() | |
# --- Page Rendering Logic based on active_page state --- | |
with streamlit_content_placeholder.container(): | |
# Home Page | |
if st.session_state.active_page == 'home': | |
st.markdown(f""" | |
<div id="home" class="page active"> | |
<section class="hero"> | |
<div class="hero-bg"></div> | |
<div class="hero-container"> | |
<div class="hero-content"> | |
<h1>Predict Credit <span class="highlight">Expenditure</span> with AI</h1> | |
<p>Harness the power of advanced machine learning to accurately forecast credit card spending patterns and make informed financial decisions.</p> | |
</div> | |
<div class="hero-visual"> | |
<div class="hero-card"> | |
<i class="fas fa-brain" style="font-size: 2rem; color: #4facfe; margin-bottom: 1rem;"></i> | |
<h3>AI-Powered</h3> | |
<p>Advanced algorithms analyze spending patterns</p> | |
</div> | |
<div class="hero-card"> | |
<i class="fas fa-shield-alt" style="font-size: 2rem; color: #10B981; margin-bottom: 1rem;"></i> | |
<h3>Secure</h3> | |
<p>Bank-level security for your data</p> | |
</div> | |
<div class="hero-card"> | |
<i class="fas fa-bolt" style="font-size: 2rem; color: #F59E0B; margin-bottom: 1rem;"></i> | |
<h3>Fast</h3> | |
<p>Instant predictions in seconds</p> | |
</div> | |
</div> | |
</div> | |
</section> | |
</div> | |
""", unsafe_allow_html=True) | |
with st.container(key="navbtn"): | |
if st.button(" Start Predicting",key="pred"): | |
st.session_state.active_page = 'predictor' | |
st.rerun() | |
if st.button(" Learn More",key="abt"): | |
st.session_state.active_page = 'about' | |
st.rerun() | |
# We need to trigger the JS function to set active state and navigate | |
elif st.session_state.active_page == 'predictor': | |
# --- Prediction Form --- | |
# We use st.form to group all the inputs. When the submit button is pressed, | |
# Streamlit re-runs the script with all the new input values. | |
with st.container(key ="main-form" ): | |
st.markdown('<h2 class="section-title">Customer Financial Profile</h2>', unsafe_allow_html=True) | |
with st.form(key="prediction_form"): | |
# Create columns for the input grid layout | |
col1, col2, col3 = st.columns(3) | |
with col1: | |
reports = st.number_input("Major Derogatory Reports", min_value=0, max_value=20, value=0, help="Number of serious credit issues reported") | |
age = st.number_input("Age (years)", min_value=18.0, max_value=100.0, value=30.0, step=0.1, help="Customer's age in years") | |
income = st.number_input("Yearly Income ($10,000s)", min_value=0.0, max_value=100.0, value=3.0, step=0.1, help="Annual income in tens of thousands") | |
owner = st.selectbox("Home Owner", ('no', 'yes'), help="Does customer own their home?") | |
with col2: | |
card = st.selectbox("Card Owner", ('no', 'yes'), help="Does customer own a credit card?") | |
share = st.number_input("Monthly Expenditure Ratio", min_value=0.0, max_value=1.0, value=0.1, step=0.01, help="Ratio of monthly spending to yearly income") | |
active = st.number_input("Active Credit Accounts", min_value=0, max_value=50, value=5, help="Total number of active credit accounts") | |
selfemp = st.selectbox("Self Employed", ('no', 'yes'), help="Is the customer self-employed?") | |
with col3: | |
dependents = st.number_input("Number of Dependents", min_value=0, max_value=10, value=0, help="Financially dependent individuals") | |
months = st.number_input("Months at Current Address", min_value=0, max_value=500, value=36, help="Duration at current residence") | |
majorcards = st.number_input("Major Credit Cards", min_value=0, max_value=10, value=1, help="Number of major credit cards owned") | |
payments = st.number_input("Credit Card Payments", min_value=0, max_value=50, value=6, help="Total credit card payments made") | |
# The submit button for the form | |
submitted = st.form_submit_button("Predict Expenditure") | |
# --- Model Prediction Logic --- | |
# This block runs only when the form has been submitted. | |
if st.button("Dismiss modal", key="dismiss_modal_btn", help="Hidden dismiss button"): | |
st.session_state.show_prediction = False | |
st.rerun() | |
if submitted: | |
model = load_model() | |
if model is not None: | |
# Show a loading spinner while processing | |
with st.spinner("Analyzing financial data with AI..."): | |
time.sleep(1) # Simulate processing time | |
# Convert categorical inputs from 'yes'/'no' to 1/0 for the model | |
owner_encoded = 1 if owner == 'yes' else 0 | |
card_encoded = 1 if card == 'yes' else 0 | |
selfemp_encoded = 1 if selfemp == 'yes' else 0 | |
# Create a pandas DataFrame with the exact structure the model expects | |
input_data = pd.DataFrame([{ | |
'card': card, # "yes"/"no" as string | |
'reports': reports, # int | |
'age': age, # float | |
'income': income, # float | |
'share': share, # float | |
'owner': owner, # "yes"/"no" as string | |
'selfemp': selfemp, # "yes"/"no" as string | |
'dependents': dependents, # int | |
'months': months, # int | |
'majorcards': majorcards, | |
'active':active# int | |
# float or placeholder if unknown | |
}]) | |
expected_features = model.feature_names_in_ | |
# Filter and reorder the input columns to match the model | |
input_filtered = input_data[expected_features] | |
print("input_data",input_data) | |
print("expected",model.feature_names_in_) # If using scikit-learn 1.0+ | |
print("input_data_type",input_data.dtypes) | |
try: | |
# Get the prediction from the model | |
prediction = model.predict(input_filtered)[0] | |
print("prediction:",prediction) | |
# Store the result and set the flag to show it | |
st.session_state.predicted_value = abs(prediction) # Ensure it's a positive number | |
st.session_state.show_prediction = True | |
except Exception as e: | |
st.error(f"Could not make a prediction. Error: {e}") | |
else: | |
st.error("The prediction model is not available. Please check server logs.") | |
# --- Display Prediction Result --- | |
# This block displays the result card if a prediction has been made. | |
if st.session_state.show_prediction: | |
st.markdown(f""" | |
<style> | |
/* Modal overlay */ | |
.modal-overlay {{ | |
position: fixed; | |
top: 0; left: 0; right: 0; bottom: 0; | |
background: rgba(0,0,0,0.6); | |
display: flex; | |
justify-content: center; | |
align-items: center; | |
z-index: 9999; | |
}} | |
/* Modal content */ | |
.modal-content {{ | |
background: #222; | |
padding: 2rem 3rem; | |
border-radius: 10px; | |
color: white; | |
max-width: 400px; | |
box-shadow: 0 0 15px rgba(0,0,0,0.5); | |
text-align: center; | |
position: relative; | |
}} | |
.result-label {{ | |
font-size: 1.2rem; | |
font-weight: 600; | |
margin-bottom: 0.5rem; | |
}} | |
.result-amount {{ | |
font-size: 2.5rem; | |
font-weight: 700; | |
margin-bottom: 1rem; | |
}} | |
</style> | |
<div class="modal-overlay" id="modal-overlay"> | |
<div class="modal-content" id="modal-content"> | |
<div class="result-label">Predicted Monthly Expenditure</div> | |
<div class="result-amount">{st.session_state.predicted_value:,.2f}</div> | |
<p style="color: rgba(255, 255, 255, 0.7); margin-top: 1rem;"> | |
Based on advanced machine learning analysis of financial patterns. | |
</p> | |
</div> | |
</div> | |
""", | |
unsafe_allow_html=True, | |
) | |
my_js = """ | |
// Close modal if clicking outside the modal-content | |
const overlay = window.parent.document.getElementById("modal-overlay"); | |
overlay.addEventListener("click", function(e) {{ | |
if (e.target.id === "modal-overlay") {{ | |
const btn = window.parent.document.querySelector('[class*="st-key-dismiss_modal_btn"]>div >div >div >div >button'); | |
if (btn) { | |
btn.click(); | |
} | |
//overlay.style.display = "none"; | |
}} | |
}}); | |
""" | |
my_html = f"<script>{my_js}</script>" | |
html(my_html) | |
# Features Page | |
elif st.session_state.active_page == 'features': | |
st.markdown(""" | |
<div id="features" class="page active"> | |
<div class="container"> | |
<div class="page-header"> | |
<h1>Powerful Features</h1> | |
<p>Discover what makes CreditIQ your ideal partner for financial insights.</p> | |
</div> | |
<div class="features-grid"> | |
<div class="feature-card"> | |
<i class="fas fa-chart-area feature-icon"></i> | |
<h3>Accurate Predictions</h3> | |
<p style="color: var(--gray-light);">Leverage state-of-the-art machine learning models for highly precise expenditure forecasts.</p> | |
</div> | |
<div class="feature-card"> | |
<i class="fas fa-database feature-icon"></i> | |
<h3>Data Security</h3> | |
<p style="color: var(--gray-light);">Your financial data is protected with industry-leading encryption and security protocols.</p> | |
</div> | |
<div class="feature-card"> | |
<i class="fas fa-user-shield feature-icon"></i> | |
<h3>Privacy Focused</h3> | |
<p style="color: var(--gray-light);">We prioritize your privacy with strict data handling and anonymity measures.</p> | |
</div> | |
<div class="feature-card"> | |
<i class="fas fa-mobile-alt feature-icon"></i> | |
<h3>Responsive Design</h3> | |
<p style="color: var(--gray-light);">Access CreditIQ seamlessly on any device, from desktop to mobile.</p> | |
</div> | |
<div class="feature-card"> | |
<i class="fas fa-lightbulb feature-icon"></i> | |
<h3>Actionable Insights</h3> | |
<p style="color: var(--gray-light);">Understand your spending habits and gain insights to optimize your finances.</p> | |
</div> | |
<div class="feature-card"> | |
<i class="fas fa-cogs feature-icon"></i> | |
<h3>Customizable Models</h3> | |
<p style="color: var(--gray-light);">Tailor prediction models to fit unique financial scenarios and individual needs.</p> | |
</div> | |
</div> | |
</div> | |
</div> | |
""", unsafe_allow_html=True) | |
# About Page | |
elif st.session_state.active_page == 'about': | |
st.markdown(""" | |
<div id="about" class="page active"> | |
<div class="container"> | |
<div class="page-header"> | |
<h1>About CreditIQ</h1> | |
<p>Our mission is to empower individuals and businesses with intelligent financial forecasting tools.</p> | |
</div> | |
<div class="about-content"> | |
<div class="about-text"> | |
<h2>Revolutionizing Financial Forecasting</h2> | |
<p>CreditIQ was founded on the principle that informed financial decisions lead to greater stability and growth. We believe that by providing highly accurate, AI-driven credit expenditure predictions, we can help our users better manage their budgets, identify trends, and plan for the future with confidence.</p> | |
<p>Our team of data scientists and financial experts has developed a robust platform that combines cutting-edge machine learning algorithms with user-friendly design. We are committed to continuous innovation and maintaining the highest standards of data security and privacy.</p> | |
<div class="stats-grid"> | |
<div class="stat-card"> | |
<div class="stat-number">99%</div> | |
<div style="color: var(--gray-light);">Accuracy Rate</div> | |
</div> | |
<div class="stat-card"> | |
<div class="stat-number">1M+</div> | |
<div style="color: var(--gray-light);">Predictions Made</div> | |
</div> | |
</div> | |
</div> | |
<div class="about-visual"> | |
<!-- Placeholder for an image or animated visual if desired --> | |
<img src="https://placehold.co/400x300/0c0c0c/1a1a1a?text=AI+Financials" alt="AI Financial Illustration" style="max-width: 100%; height: auto; border-radius: 16px; box-shadow: var(--shadow-md);"> | |
</div> | |
</div> | |
</div> | |
</div> | |
""", unsafe_allow_html=True) | |
st.markdown(f"<script>showPage('about');</script>", unsafe_allow_html=True) | |
# Contact Page | |
elif st.session_state.active_page == 'contact': | |
st.markdown(""" | |
<div id="contact" class="page active"> | |
<div class="container"> | |
<div class="page-header"> | |
<h1>Get in Touch</h1> | |
<p>Have questions, feedback, or need support? We're here to help.</p> | |
</div> | |
</div> | |
</div> | |
""", unsafe_allow_html=True) | |
# Inject Streamlit components into the Contact form | |
with st.container(key="contact-form"): | |
with st.form("contact_form",clear_on_submit=True): | |
st.text_input("Your Name", key="contact_name_input", help="Please enter your name.") | |
st.text_input("Your Email", key="contact_email_input", help="Please enter your email address.") | |
st.text_area("Message", key="contact_message_input", help="Type your message here.") | |
submittedcon = st.form_submit_button("Send Message", help="Click to send your message.") | |
if submittedcon : | |
st.success("Thank you for your message! We will get back to you soon.") | |