import pandas as pd from datetime import datetime AQI_BANDS = [ (0, 50, "Good", "#10b981", "#ecfdf5"), (51, 100, "Moderate", "#f59e0b", "#fffbeb"), (101, 150, "Unhealthy for Sensitive Groups", "#f97316", "#fff7ed"), (151, 200, "Unhealthy", "#ef4444", "#fef2f2"), (201, 300, "Very Unhealthy", "#8b5cf6", "#f5f3ff"), (301, 999, "Hazardous", "#7f1d1d", "#fef2f2"), ] AQI_TIPS = { "Good": "Great day to be outdoors!", "Moderate": "Sensitive groups should reduce prolonged outdoor exertion.", "Unhealthy for Sensitive Groups": "Limit outdoor activity if you have asthma or heart conditions.", "Unhealthy": "Wear a mask outdoors and keep windows closed.", "Very Unhealthy": "Avoid going outside; use an air purifier indoors.", "Hazardous": "Stay indoors — this is a health emergency level.", } CSS = """ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap'); .gradio-container { background: #f0fdfa !important; background-image: linear-gradient(180deg, #99f6e4 0%, #f0fdfa 40%, #ffffff 100%) !important; font-family: 'Inter', sans-serif !important; max-width: 100% !important; width: 100% !important; margin: 0 !important; padding: 0 40px !important; } #main-container { max-width: 1400px; margin: 0 auto; width: 100%; } /* Header Styles */ .app-header { display: flex; justify-content: space-between; align-items: center; padding: 20px 0; } .location-info h2 { margin: 0; font-size: 1.2rem; font-weight: 700; color: #0f172a; } .location-info p { margin: 0; font-size: 0.9rem; color: #64748b; } /* Card Styles */ .mobile-card { background: white !important; border-radius: 24px !important; border: none !important; box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.05), 0 8px 10px -6px rgba(0, 0, 0, 0.05) !important; padding: 20px !important; overflow: hidden; margin-top: 20px; } /* Status Card */ .status-hero { position: relative; border-radius: 24px; padding: 24px; color: white; text-align: left; overflow: hidden; margin-bottom: 20px; } .status-hero h1 { font-size: 2.5rem; font-weight: 800; margin: 0; } .status-hero p { font-size: 1.1rem; opacity: 0.9; margin: 4px 0 0 0; } /* Metric Grid */ .metric-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px; } .metric-item { background: #f8fafc; border-radius: 20px; padding: 16px; display: flex; flex-direction: column; gap: 8px; } .metric-top { display: flex; align-items: center; gap: 10px; } .metric-icon-bg { width: 40px; height: 40px; border-radius: 12px; display: flex; align-items: center; justify-content: center; font-size: 1.2rem; } .metric-label { font-size: 0.85rem; font-weight: 500; color: #64748b; } .metric-value { font-size: 1.1rem; font-weight: 700; color: #0f172a; } /* Forecast Grid */ .forecast-scroll { display: flex; gap: 12px; overflow-x: auto; padding-bottom: 8px; scrollbar-width: none; } .forecast-scroll::-webkit-scrollbar { display: none; } .forecast-item { min-width: 80px; text-align: center; padding: 12px; border-radius: 16px; background: #f8fafc; } .forecast-day { font-size: 0.8rem; font-weight: 600; color: #64748b; margin-bottom: 8px; } .forecast-icon { font-size: 1.5rem; margin-bottom: 8px; } .forecast-temp { font-size: 1rem; font-weight: 700; color: #0f172a; } /* Buttons */ #predict-btn { background: #0f172a !important; color: white !important; border-radius: 16px !important; font-weight: 600 !important; padding: 12px !important; } /* Window toggle */ #window-radio { display: flex; align-items: center; gap: 0 !important; } #window-radio .wrap { display: flex; gap: 6px; flex-direction: row !important; } #window-radio label { background: #f1f5f9; border-radius: 10px; padding: 4px 14px; font-size: 0.8rem; font-weight: 600; color: #64748b; cursor: pointer; border: none; } #window-radio input[type=radio]:checked + label, #window-radio label:has(input:checked) { background: #0f172a; color: white; } /* Tabs row alignment */ .tab-row-header { display: flex; justify-content: space-between; align-items: center; } """ def get_header_html(): now = datetime.now() date_str = now.strftime("%d %B %Y") return f"""
{date_str}
Current Observation
Air Quality Index: {cat}