import gradio as gr import pandas as pd import plotly.express as px df = pd.read_csv("sample_100_jobs.csv") def filter_data(industry, country, max_risk, min_salary): d = df.copy() if industry != "All": d = d[d["Industry"] == industry] if country != "All": d = d[d["Country"] == country] d = d[(d["AI_Replacement_Risk"] <= max_risk) & (d["Average_Salary_USD"] >= min_salary)] return d.sort_values("Demand_Risk_Ratio", ascending=False) def scatter(): fig = px.scatter(df, x="AI_Replacement_Risk", y="Average_Salary_USD", color="AI_Risk_Category", size="Demand_Risk_Ratio", hover_data=["Job_Title"], template="plotly_dark", height=420, color_discrete_map={"Low":"#10B981","Medium":"#3B82F6","High":"#EF4444"}) fig.update_layout( paper_bgcolor="rgba(0,0,0,0)", plot_bgcolor="rgba(0,0,0,0)", margin=dict(l=10,r=10,t=40,b=10), font=dict(family="Inter") ) return fig def top_jobs(): top = df.nlargest(10, "Demand_Risk_Ratio") fig = px.bar(top, x="Demand_Risk_Ratio", y="Job_Title", orientation="h", template="plotly_dark", color="Demand_Risk_Ratio", height=420, color_continuous_scale="Viridis") fig.update_layout( paper_bgcolor="rgba(0,0,0,0)", plot_bgcolor="rgba(0,0,0,0)", yaxis={"categoryorder":"total ascending"}, font=dict(family="Inter") ) return fig css = """ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800;900&display=swap'); * {font-family: 'Inter', sans-serif !important;} body{ background: radial-gradient(ellipse 80% 50% at 50% -20%, rgba(120,119,198,0.3), transparent), radial-gradient(ellipse 80% 50% at 50% 120%, rgba(79,70,229,0.2), transparent), linear-gradient(180deg, #020617 0%, #0F172A 50%, #020617 100%) !important; background-attachment: fixed !important; } .gradio-container{ width:96% !important; max-width:1400px !important; margin: 0 auto !important; } /* ANIMASI GRADIENT BERJALAN */ @keyframes gradientFlow { 0% {background-position: 0% 50%;} 50% {background-position: 100% 50%;} 100% {background-position: 0% 50%;} } .animated-gradient { background: linear-gradient(90deg, #60A5FA, #A855F7, #EC4899, #60A5FA); background-size: 300% 300%; -webkit-background-clip: text; -webkit-text-fill-color: transparent; animation: gradientFlow 4s ease infinite; } /* NAVBAR */ .navbar{ display: flex;justify-content: space-between;align-items: center; padding: 20px 0;margin-bottom: 30px; } .nav-left{display:flex;align-items:center;gap:40px} .logo{display:flex;align-items:center;gap:12px;font-weight:900;font-size:22px;color:#fff} .logo-icon{ width:32px;height:32px;border-radius:8px; background:linear-gradient(135deg,#6366F1,#A855F7); display:flex;align-items:center;justify-content:center; box-shadow:0 0 20px rgba(99,102,241,.6); } .nav-links{display:flex;gap:32px} .nav-links a{color:#94A3B8;text-decoration:none;font-weight:600;font-size:14px} .nav-links a:hover{color:#fff} .nav-right{display:flex;gap:12px} .btn-ghost{ background:rgba(30,41,59,.6);border:1px solid rgba(99,102,241,.3); color:#fff;padding:10px 20px;border-radius:12px;font-weight:700;cursor:pointer; } .btn-primary{ background:linear-gradient(90deg,#6366F1,#A855F7); color:#fff;padding:10px 24px;border-radius:12px;border:none; font-weight:700;cursor:pointer; box-shadow:0 4px 20px rgba(99,102,241,.4), 0 0 40px rgba(99,102,241,.2); } /* HERO */ .hero{ padding:70px 45px; border-radius:24px; background: linear-gradient(135deg, rgba(15,23,42,.8), rgba(30,41,59,.6)); border:1px solid rgba(99,102,241,.2); box-shadow: 0 0 60px rgba(99,102,241,.15), inset 0 1px 0 rgba(255,255,255,.1); margin-bottom:40px; text-align: center; backdrop-filter: blur(20px); position:relative;overflow:hidden; } .hero::before{ content:'';position:absolute;top:-50%;left:50%;transform:translateX(-50%); width:600px;height:600px; background:radial-gradient(circle, rgba(99,102,241,.25), transparent 70%); filter:blur(80px);z-index:0; } .hero-badge{ display:inline-flex;align-items:center;gap:8px; padding:8px 16px;background:rgba(99,102,241,.1); border:1px solid rgba(99,102,241,.3);border-radius:99px; font-size:14px;color:#A5B4FC;margin-bottom:24px;position:relative;z-index:1;font-weight:600; } .hero h1{ font-size:68px;line-height:1.1;font-weight:900; margin:0 0 16px 0;position:relative;z-index:1; color:#FFFFFF; letter-spacing:-1px; } .hero h1 .gradient{ font-weight:900; display:block; margin-top:8px; } .hero p{ font-size:18px;color:#CBD5E1;max-width:700px; margin:0 auto 32px auto;line-height:1.7;position:relative;z-index:1;font-weight:500; } .hero-cta{display:flex;gap:16px;justify-content:center;position:relative;z-index:1} /* STATS */ .stats{ display: grid; grid-template-columns: repeat(4, 1fr); gap: 20px; margin-bottom: 80px; } .stat-card{ padding:28px 24px; border-radius:20px; background: linear-gradient(135deg, rgba(99,102,241,.1), rgba(168,85,247,.05)); backdrop-filter: blur(20px); border: 1px solid rgba(99,102,241,.2); text-align: center; box-shadow: 0 8px 32px rgba(99,102,241,.1); } .stat-card .label{ display:flex;align-items:center;gap:8px;justify-content:center; color:#94A3B8;font-size:14px;margin-bottom:12px;font-weight:600; } .stat-card .value{ font-size:36px;font-weight:900; background: linear-gradient(90deg, #6366F1, #A855F7); -webkit-background-clip: text; -webkit-text-fill-color: transparent; } /* DASHBOARD */ .section-header{margin-bottom:32px} .section-header h2{font-size:32px;margin:0 0 8px 0;font-weight:900;color:#fff} .section-header p{color:#94A3B8;margin:0;font-size:15px;font-weight:500} .card{ padding:24px;border-radius:20px; background: rgba(15,23,42,.6) !important; backdrop-filter: blur(20px) !important; border: 1px solid rgba(99,102,241,.15) !important; margin-bottom:24px;box-shadow: 0 8px 32px rgba(0,0,0,.3); } .footer{ margin-top:60px;padding:40px 30px;text-align:center; color: #64748B;border-top: 1px solid rgba(99,102,241,.1);font-weight: 600; } @media (max-width: 768px) { .nav-links{display:none} .hero h1 { font-size: 42px; } .stats { grid-template-columns: repeat(2, 1fr); } .hero-cta{flex-direction:column} } """ with gr.Blocks(css=css, fill_width=True, theme=gr.themes.Base()) as demo: # NAVBAR gr.HTML("""
""") # HERO - FONT TEBEL + GRADIENT ANIMASI gr.HTML("""Analyze job market trends, salary projections, and AI automation risks. Make data-driven decisions for 2031 and beyond with real-time predictive analytics.
Filter and explore 100+ jobs with real-time risk scoring