import gradio as gr from gradio.themes.utils import colors, fonts, sizes saffron = colors.Color( name="saffron", c50="#fff7ed", c100="#ffedd5", c200="#fed7aa", c300="#fdba74", c400="#fb923c", c500="#f97316", c600="#ea580c", c700="#c2410c", c800="#9a3412", c900="#7c2d12", c950="#431407", ) indiagreen = colors.Color( name="indiagreen", c50="#f0fdf4", c100="#dcfce7", c200="#bbf7d0", c300="#86efac", c400="#4ade80", c500="#22c55e", c600="#16a34a", c700="#15803d", c800="#166534", c900="#14532d", c950="#052e16", ) class SariMadiTheme(gr.themes.Base): def __init__(self): super().__init__( primary_hue=saffron, secondary_hue=indiagreen, neutral_hue=colors.stone, spacing_size=sizes.spacing_lg, radius_size=sizes.radius_lg, font=( fonts.GoogleFont("Plus Jakarta Sans"), "ui-sans-serif", "system-ui", "sans-serif", ), font_mono=( fonts.GoogleFont("JetBrains Mono"), "ui-monospace", "monospace", ), ) self.set( body_background_fill="#fbfaf7", body_background_fill_dark="#1a1714", block_background_fill="#ffffff", block_background_fill_dark="#252019", block_border_width="1px", block_border_color="#ece7dd", block_border_color_dark="#3a3228", block_radius="16px", block_shadow="0 1px 2px rgba(124, 45, 18, 0.04)", block_title_text_weight="600", block_label_text_weight="500", button_large_radius="12px", button_small_radius="10px", button_primary_background_fill="*primary_500", button_primary_background_fill_hover="*primary_600", button_primary_text_color="#ffffff", button_primary_background_fill_dark="*primary_600", button_secondary_background_fill="*secondary_50", button_secondary_background_fill_hover="*secondary_100", button_secondary_text_color="*secondary_700", button_secondary_border_color="*secondary_200", input_background_fill="#ffffff", input_background_fill_dark="#2d2820", input_border_color="#e7e1d6", input_border_color_focus="*primary_400", input_radius="12px", slider_color="*primary_500", ) CUSTOM_CSS = """ .gradio-container { max-width: 760px !important; margin: 0 auto !important; padding: 0 14px !important; } #sari-header { text-align: center; padding: 22px 0 14px; width: 100%; max-width: 480px; margin: 0 auto; display: flex; flex-direction: column; align-items: center; } #sari-header .kicker { font-size: 12px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; color: var(--primary-500); margin: 0 0 6px; width: 100%; text-align: center; } #sari-header h1 { font-size: 38px; font-weight: 700; letter-spacing: -0.025em; margin: 0; background: linear-gradient(90deg, #f97316, #22c55e); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; line-height: 1.1; width: 100%; text-align: center; } #sari-header p { color: var(--body-text-color-subdued); font-size: 15px; margin: 10px auto 0; max-width: 430px; line-height: 1.55; width: 100%; text-align: center; } .step-card { border: 1px solid var(--border-color-primary) !important; border-radius: 20px !important; padding: 22px !important; background: var(--block-background-fill) !important; box-shadow: 0 1px 3px rgba(0,0,0,0.04) !important; transition: border-color 0.2s ease !important; } .step-card:hover { border-color: var(--primary-300) !important; } .step-head { display: flex; align-items: center; gap: 11px; font-size: 15px; font-weight: 600; color: var(--body-text-color); margin-bottom: 16px; } .step-num { display: inline-flex; align-items: center; justify-content: center; width: 27px; height: 27px; border-radius: 50%; background: linear-gradient(135deg, #f97316, #fb923c); color: #fff; font-size: 13px; font-weight: 700; flex-shrink: 0; } .locate-btn { width: 100% !important; font-weight: 600 !important; border-radius: 13px !important; padding: 13px !important; transition: transform 0.1s ease !important; } .locate-btn:active { transform: scale(0.99) !important; } .loc-status { font-size: 13px; margin-top: 10px; min-height: 18px; color: var(--body-text-color-subdued); } .loc-status.loc-ok { color: var(--secondary-500); font-weight: 500; } .loc-status.loc-err { color: #ef4444; } .loc-status.loc-pending { color: var(--primary-500); } .generate-btn { width: 100% !important; font-size: 16px !important; font-weight: 600 !important; padding: 16px !important; border-radius: 15px !important; margin-top: 8px !important; transition: transform 0.1s ease, box-shadow 0.2s ease !important; box-shadow: 0 4px 14px rgba(249, 115, 22, 0.25) !important; } .generate-btn:hover { box-shadow: 0 6px 20px rgba(249, 115, 22, 0.35) !important; } .generate-btn:active { transform: scale(0.99) !important; } .result-empty { text-align: center; padding: 40px 20px; border: 1.5px dashed var(--border-color-primary); border-radius: 20px; margin-top: 8px; } .result-empty .re-icon { width: 52px; height: 52px; border-radius: 14px; margin: 0 auto 14px; background: linear-gradient(135deg, #fff7ed, #f0fdf4); display: flex; align-items: center; justify-content: center; font-size: 24px; } .result-empty .re-title { font-size: 15px; font-weight: 600; color: var(--body-text-color); margin: 0; } .result-empty .re-sub { font-size: 13px; color: var(--body-text-color-subdued); margin: 4px 0 0; } .officer-card { border-radius: 20px; padding: 24px; background: var(--block-background-fill); border: 1px solid var(--primary-300); margin-top: 8px; } .oc-head { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; flex-wrap: wrap; } .oc-issue { font-size: 20px; font-weight: 700; color: var(--body-text-color); } .oc-sev { font-size: 12px; font-weight: 600; color: #fff; padding: 3px 12px; border-radius: 999px; text-transform: capitalize; } .oc-desc { margin: 0; font-size: 14px; color: var(--body-text-color); line-height: 1.6; } .seen-text { margin: 8px 0 0; font-size: 13px; color: var(--body-text-color-subdued); font-style: italic; } .oc-divider { height: 1px; background: var(--border-color-primary); margin: 18px 0; } .oc-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; } .oc-grid > div { display: flex; flex-direction: column; gap: 3px; } .oc-label { font-size: 12px; color: var(--body-text-color-subdued); text-transform: uppercase; letter-spacing: 0.04em; } .oc-value { font-size: 15px; font-weight: 600; color: var(--body-text-color); } .oc-phone { color: #fff; text-decoration: none; font-weight: 600; background: var(--secondary-500); padding: 6px 14px; border-radius: 10px; display: inline-block; font-size: 14px; } .error-banner { background: var(--block-background-fill); border: 1px solid #ef4444; color: #ef4444; padding: 15px 18px; border-radius: 14px; font-size: 14px; line-height: 1.5; } @media (max-width: 640px) { #sari-header h1 { font-size: 30px; } #sari-header p { font-size: 14px; } .step-card { padding: 18px !important; border-radius: 16px !important; } .officer-card { padding: 18px; border-radius: 16px; } .oc-grid { grid-template-columns: 1fr; gap: 14px; } .oc-issue { font-size: 18px; } } footer { display: none !important; } """