import gradio as gr import pandas as pd import numpy as np import plotly.graph_objects as go BRAND_COLORS = { 'primary': '#1F2C6D', # Navy 'secondary': '#081423', # Dark Navy 'accent': '#FFC700', # Yellow 'dark_bg': '#081423', # Dark Navy 'light_bg': '#ECF0F6', # Light Gray 'button_bg': '#FFC700', # Yellow 'light_text': '#FFFFFF', # White 'dark_text': '#081423', # Dark Navy 'table_header': '#4556E4', # Light Blue 'table_row_odd': '#FFFFFF', # Pure white 'table_row_even': '#ECF0F6', # Light Gray 'label_text': '#000000', # Black for Labels 'button_text': '#081423', # Dark Navy for Button Text 'input_text': '#081423', # Dark Navy for Input Text 'result_header': '#081423', # Dark Navy for Result Headings 'result_text': '#FFFFFF', # White 'result_bg': '#081423' # Dark Navy } default_departments = pd.DataFrame({ "Department": ["IT", "Finance", "HR", "Marketing", "Sales", "Operations"], "Number of Employees": [10, 15, 8, 12, 20, 25], "Average Salary": [95000, 85000, 70000, 75000, 85000, 65000], "Hours Per Week on Manual Tasks": [20, 20, 15, 10, 12, 18] }) default_subscriptions = pd.DataFrame({ "Tool Category": [ "CRM", "ERP", "Project Management", "Cloud Storage", "SaaS Subscriptions" ], "Current Monthly Cost per User": [80, 150, 30, 25, 45], "Number of Users": [90, 90, 90, 90, 90], "Estimated Reduction %": [30, 20, 50, 10, 15] }) industry_compliance_data = { "Financial Services": pd.DataFrame({ "Regulation": ["GDPR", "CCPA", "SOX", "PCI DSS", "GLBA"], "Potential Violations": [2, 1, 1, 3, 2], "Penalty": [250000, 150000, 100000, 200000, 175000], "Attorney Cost": [50000, 40000, 30000, 45000, 40000] }), "Healthcare": pd.DataFrame({ "Regulation": ["HIPAA", "HITECH Act", "GDPR", "CCPA", "Data Protection Act 2018"], "Potential Violations": [3, 2, 1, 1, 2], "Penalty": [175000, 125000, 100000, 90000, 80000], "Attorney Cost": [45000, 35000, 30000, 25000, 20000] }), "Manufacturing": pd.DataFrame({ "Regulation": [ "OSHA Regulations", "EPA Regulations", "ISO Standards", "NIST Cybersecurity Framework", "GDPR" ], "Potential Violations": [2, 3, 1, 2, 1], "Penalty": [75000, 100000, 50000, 150000, 200000], "Attorney Cost": [20000, 30000, 15000, 45000, 50000] }), "Retail": pd.DataFrame({ "Regulation": [ "PCI DSS", "CCPA", "GDPR", "Consumer Rights Act", "Sales Tax Regulations" ], "Potential Violations": [3, 2, 2, 1, 3], "Penalty": [100000, 125000, 150000, 50000, 75000], "Attorney Cost": [30000, 40000, 50000, 15000, 25000] }), "Technology": pd.DataFrame({ "Regulation": [ "GDPR", "CCPA", "COPPA", "Software Licensing Compliance", "Export Controls" ], "Potential Violations": [2, 2, 1, 3, 2], "Penalty": [200000, 150000, 100000, 175000, 125000], "Attorney Cost": [50000, 45000, 30000, 40000, 35000] }), "Government/Defense": pd.DataFrame({ "Regulation": ["FedRAMP", "CMMC", "NIST SP 800-171", "FISMA", "ITAR"], "Potential Violations": [1, 2, 3, 2, 1], "Penalty": [250000, 300000, 200000, 150000, 275000], "Attorney Cost": [60000, 75000, 50000, 40000, 65000] }), "Professional Services": pd.DataFrame({ "Regulation": [ "Client Confidentiality Agreements", "Professional Standards", "GDPR", "CCPA", "Ethics Rules" ], "Potential Violations": [2, 1, 1, 1, 3], "Penalty": [50000, 100000, 150000, 125000, 75000], "Attorney Cost": [20000, 30000, 40000, 35000, 25000] }), "Energy": pd.DataFrame({ "Regulation": [ "NERC CIP", "FERC Regulations", "EPA Regulations", "State Public Utility Commissions", "Cybersecurity Regulations" ], "Potential Violations": [3, 2, 2, 1, 3], "Penalty": [200000, 150000, 175000, 100000, 125000], "Attorney Cost": [50000, 40000, 45000, 30000, 35000] }), "Other": pd.DataFrame({ "Regulation": [ "Data Privacy", "Financial Reporting", "Industry-Specific Requirements", "Records Retention", "Security Controls" ], "Potential Violations": [2, 1, 1, 3, 2], "Penalty": [250000, 100000, 75000, 50000, 125000], "Attorney Cost": [50000, 30000, 25000, 15000, 40000] }) } industry_ai_risks = { "Financial Services": [ "Data privacy breaches with sensitive financial information", "Sharing Material nonpublic information (MNPI) to unauthorized 3rd parties", "Compliance violations with regulatory frameworks (e.g., GDPR, CCPA, SOX, PCI DSS, GLBA)" ], "Healthcare": [ "Patient data confidentiality breaches", "HIPAA compliance violations", "Data corruption","Sensitive healthcare information sharing to unauthorized 3rd parties", "Compliance with HITECH Act, GDPR, CCPA, Data Protection Act 2018" ], "Manufacturing": [ "Quality control failures from AI systems", "Supply chain vulnerability from automated decisions", "Safety risks from AI-controlled equipment", "Compliance with OSHA, EPA, ISO standards, NIST, GDPR." ], "Retail": [ "Customer data privacy breaches", "Payment processing vulnerabilities", "Biased pricing algorithms", "Compliance with PCI DSS, CCPA, GDPR, Consumer Rights Act, Sales Tax regulations." ], "Technology": [ "Code vulnerabilities in AI-generated software", "Intellectual property theft via AI systems", "Data leakage through AI pipelines", "Compliance with GDPR, CCPA, COPPA, Software Licensing, Export Controls." ], "Government/Defense": [ "Classified information exposure through AI systems", "Supply chain risks in AI components","Insider threats accessing data through AI systems", "Compliance violations with FedRAMP, CMMC, NIST, FISMA, ITAR." ], "Professional Services": [ "Client confidentiality breaches", "Legal privilege violations through AI tools", "Inaccurate professional advice from AI systems", "Compliance with Client Agreements, GDPR, CCPA, and Ethics Rules" ], "Energy": [ "Critical infrastructure vulnerability", "Physical safety risks from automated control systems", "Energy supply disruption from AI forecasting errors", "Compliance with NERC CIP, FERC and EPA Regulations." ], "Other": [ "Data privacy and security risks", "Regulatory compliance issues", "Intellectual property protection" ] } department_use_cases = { "IT": [ "Automated ticket resolution", "Infrastructure optimization", "Code generation" ], "Finance": ["Automated reporting", "Fraud detection", "Invoice processing"], "HR": ["Resume screening", "Employee onboarding", "HR analytics"], "Marketing": ["Content generation", "Campaign optimization", "Customer segmentation"], "Sales": ["Lead prioritization", "Sales forecasting", "Automated follow-ups"], "Operations": ["Process automation", "Supply chain optimization", "Quality control"], "Legal/Compliance": ["Contract review", "Regulatory tracking", "Compliance monitoring"], "Customer Service": ["Response generation", "Ticket categorization", "Sentiment analysis"], "Research": ["Literature review", "Patent analysis", "Experiment design"], "Other": ["Document processing", "Data analysis", "Process automation"] } # --- Calculation and Recommendation Functions --- def create_subscription_savings_chart(subscription_data): # Use pandas vectorized operations instead of loop df = subscription_data.copy() # Calculate costs and savings in one go df['monthly_cost'] = df["Current Monthly Cost per User"] * df["Number of Users"] df['savings'] = df['monthly_cost'] * (df["Estimated Reduction %"] / 100) # Convert to lists for plotly categories = df["Tool Category"].tolist() current_costs = df['monthly_cost'].tolist() savings = df['savings'].tolist() # Create the figure with all styling applied at once fig = go.Figure() # Add both traces at once fig.add_trace( go.Bar(x=categories, y=current_costs, name="Current Monthly Cost", marker_color=BRAND_COLORS['primary'], opacity=0.9)) fig.add_trace( go.Bar(x=categories, y=savings, name="Potential Monthly Savings", marker_color=BRAND_COLORS['accent'], opacity=0.9)) # Set layout all at once fig.update_layout( title="Potential Monthly Subscription Savings with AI", barmode='group', xaxis_title="Subscription Categories", yaxis_title="Cost ($)", legend=dict(orientation="h", yanchor="bottom", y=1.02, xanchor="center", x=0.5, font=dict(color=BRAND_COLORS['light_text'])), template="plotly_white", font=dict(family="Inter, sans-serif", size=12, color=BRAND_COLORS['light_text']), paper_bgcolor=BRAND_COLORS['dark_bg'], plot_bgcolor=BRAND_COLORS['dark_bg'], margin=dict(l=40, r=40, t=80, b=40) ) return fig def calculate_department_roi(dept_data, hourly_wage_multiplier=1.5): results = [] for _, row in dept_data.iterrows(): department = row["Department"] employees = row["Number of Employees"] avg_salary = row["Average Salary"] manual_hours = row["Hours Per Week on Manual Tasks"] hourly_wage = avg_salary / (52 * 40) * hourly_wage_multiplier efficiency_gain = np.random.uniform(0.3, 0.4) annual_hours_saved = manual_hours * efficiency_gain * 52 * employees annual_savings = annual_hours_saved * hourly_wage implementation_cost = avg_salary * 0.2 * employees roi = ((annual_savings - implementation_cost) / implementation_cost) * 100 if implementation_cost > 0 else 0 use_cases = department_use_cases.get( department, department_use_cases.get( next((k for k in department_use_cases if k.lower() in department.lower()), "Other"))) results.append({ "Department": department, "Employees": employees, "Annual Hours Saved": annual_hours_saved, "Annual Cost Savings": annual_savings, "Implementation Cost": implementation_cost, "ROI": roi, "Use Cases": use_cases[:3] }) return sorted(results, key=lambda x: x["ROI"], reverse=True) def calculate_subscription_savings(subscription_data): total_current_cost = subscription_data.apply(lambda row: row[ "Current Monthly Cost per User"] * row["Number of Users"] * 12, axis=1).sum() total_savings = subscription_data.apply( lambda row: row["Current Monthly Cost per User"] * row[ "Number of Users"] * 12 * row["Estimated Reduction %"] / 100, axis=1).sum() savings_percentage = (total_savings / total_current_cost ) * 100 if total_current_cost > 0 else 0 return { "total_current_cost": total_current_cost, "total_savings": total_savings, "savings_percentage": savings_percentage } def calculate_compliance_savings(compliance_data): if compliance_data.empty: return {"total_savings": 0, "key_regulations": []} compliance_data["Potential Violations"] = pd.to_numeric( compliance_data["Potential Violations"], errors='coerce').fillna(0) compliance_data["Penalty"] = pd.to_numeric(compliance_data["Penalty"], errors='coerce').fillna(0) compliance_data["Attorney Cost"] = pd.to_numeric( compliance_data["Attorney Cost"], errors='coerce').fillna(0) total_savings = ( compliance_data["Potential Violations"] * (compliance_data["Penalty"] + compliance_data["Attorney Cost"])).sum() compliance_data['TotalCost'] = compliance_data["Potential Violations"] * ( compliance_data["Penalty"] + compliance_data["Attorney Cost"]) sorted_compliance = compliance_data.sort_values(by='TotalCost', ascending=False) key_regulations = [{ "name": row["Regulation"], "cost": row["TotalCost"] } for _, row in sorted_compliance.head(3).iterrows()] return {"total_savings": total_savings, "key_regulations": key_regulations} def recommend_preamble_solution(industry, org_size, monthly_budget, has_ai_app, api_calls=10000): """Recommends Preamble solution with budget and AI app considerations.""" high_risk_industries = [ "Financial Services", "Healthcare", "Government/Defense" ] org_size = int(org_size) if org_size is not None else 0 monthly_budget = float( monthly_budget) if monthly_budget is not None else 0.0 api_calls = int(api_calls) if api_calls is not None else 10000 shadow_ai_blocker = "[Shadow AI Blocker Chrome Extension](https://chromewebstore.google.com/detail/shadow-ai-blocker/jkcnihggbeejafmbgohlahlighagphon)" if monthly_budget < 27000: if has_ai_app: solution = "Guardrails Only" monthly_cost = api_calls * 0.005 description = f""" #### ⚡ [Guardrails Only - Compliance](https://preamble.com/pricing) Perfect for integrating with your existing AI application: - Quick API integration. - Pre-built security and privacy guardrails. - Basic compliance templates. - Agentless operation. - Free Trial available. - Free Shadow AI Tool {shadow_ai_blocker} $0.005 per API call (Est. monthly cost: ${monthly_cost:,.2f} at {api_calls:,} calls/month) [Learn more about Preamble pricing options](https://preamble.com/pricing)""" image = "🛡️" else: solution = "SMB" description = f""" #### 🚀 [SMB](https://preamble.com/pricing) Perfect for teams getting started with AI: - Full platform features. - Standard compliance templates. - Protection for up to 25 AI applications. - Secure Knowledge Base. - SaaS Hosting. - Free Shadow AI Tool {shadow_ai_blocker} $50 per user/month [Learn more about Preamble pricing options](https://preamble.com/pricing)""" image = "🏢" elif org_size >= 1000 or industry in high_risk_industries: solution = "Enterprise" description = f""" #### 🏢 [Enterprise License](https://preamble.com/pricing) Perfect for large or high-risk organizations: - Complete compliance controls. - Custom AI Assistant Development Support. - Dedicated support team. - Private AI Marketplace. - Custom integrations. - Private cloud/on-premise options. - Free Shadow AI Tool {shadow_ai_blocker} Starting at $27,000/month with discounts for multi-year deals [Learn more about Preamble pricing options](https://preamble.com/pricing)""" image = "🚀" elif org_size >= 100: solution = "SMB" description = f""" #### 🚀 [SMB](https://preamble.com/pricing) Perfect for teams getting started with AI: - Full platform features. - Standard compliance templates. - Custom AI Assistants. - Safe AI Search Agent - Secure Knowledge Base. - SaaS Hosting. - Free Shadow AI Tool {shadow_ai_blocker} $50 per user/month [Learn more about Preamble pricing options](https://preamble.com/pricing)""" image = "🏢" else: solution = "Guardrails Only" monthly_cost = api_calls * 0.005 description = f""" #### ⚡ [Guardrails Only - Compliance](https://preamble.com/pricing) Perfect for integrating with your existing AI application: - Quick API integration. - Pre-built security and privacy guardrails. - Basic compliance templates. - Agentless operation. - Free Trial available. - Free Shadow AI Tool {shadow_ai_blocker} $0.005 per API call (Est. monthly cost: ${monthly_cost:,.2f} at {api_calls:,} calls/month) [Learn more about Preamble pricing options](https://preamble.com/pricing)""" image = "🛡️" return {"solution": solution, "description": description, "image": image} def calculate_build_vs_buy_comparison(initial_dev_cost=1000000, num_ai_personnel=1, avg_annual_salary=200000, annual_maintenance=500000, security_compliance=250000): # Convert inputs to numbers if they aren't already try: initial_dev_cost = float(initial_dev_cost) num_ai_personnel = int(num_ai_personnel) avg_annual_salary = float(avg_annual_salary) annual_maintenance = float(annual_maintenance) security_compliance = float(security_compliance) except (ValueError, TypeError): # Default values if conversion fails initial_dev_cost = 1000000.0 num_ai_personnel = 1 avg_annual_salary = 200000.0 annual_maintenance = 500000.0 security_compliance = 250000.0 first_year_cost = initial_dev_cost + (num_ai_personnel * avg_annual_salary) + security_compliance ongoing_annual_cost = (num_ai_personnel * avg_annual_salary) + annual_maintenance + security_compliance three_year_build_cost = first_year_cost + (ongoing_annual_cost * 2) preamble_annual_cost = 27000 * 12 three_year_preamble_cost = preamble_annual_cost * 3 three_year_savings = three_year_build_cost - three_year_preamble_cost savings_percentage = (three_year_savings / three_year_build_cost) * 100 if three_year_build_cost > 0 else 0 return { "first_year_build": first_year_cost, "ongoing_annual_build": ongoing_annual_cost, "three_year_build": three_year_build_cost, "annual_preamble": preamble_annual_cost, "three_year_preamble": three_year_preamble_cost, "three_year_savings": three_year_savings, "savings_percentage": savings_percentage } def create_build_vs_buy_chart(comparison_data): labels = ["Year 1", "Year 2", "Year 3", "3-Year Total"] build_costs = [ comparison_data["first_year_build"], comparison_data["ongoing_annual_build"], comparison_data["ongoing_annual_build"], comparison_data["three_year_build"] ] preamble_costs = [ comparison_data["annual_preamble"], comparison_data["annual_preamble"], comparison_data["annual_preamble"], comparison_data["three_year_preamble"] ] fig = go.Figure() fig.add_trace(go.Bar( x=labels, y=build_costs, name="Build In-House", marker_color=BRAND_COLORS['primary'], opacity=0.9 )) fig.add_trace(go.Bar( x=labels, y=preamble_costs, name="Preamble Enterprise", marker_color=BRAND_COLORS['accent'], opacity=0.9 )) fig.update_layout( title="Build vs Buy: 3-Year Cost Comparison", barmode='group', xaxis_title="Timeline", yaxis_title="Cost ($)", legend=dict( orientation="h", yanchor="bottom", y=1.02, xanchor="center", x=0.5, font=dict(color=BRAND_COLORS['light_text']) ), template="plotly_white", font=dict( family="Inter, sans-serif", size=12, color=BRAND_COLORS['light_text'] ), paper_bgcolor=BRAND_COLORS['dark_bg'], plot_bgcolor=BRAND_COLORS['dark_bg'], margin=dict(l=40, r=40, t=80, b=40) ) return fig def generate_recommendations(industry, org_size, monthly_budget, has_ai_app, dept_roi_results, subscription_savings, compliance_savings, api_calls=10000, initial_dev_cost=1000000, num_ai_personnel=1, avg_annual_salary=200000, annual_maintenance=500000, security_compliance=250000): top_departments = dept_roi_results[:3] solution_rec = recommend_preamble_solution(industry, org_size, monthly_budget, has_ai_app, api_calls) total_dept_savings = sum(dept["Annual Cost Savings"] for dept in dept_roi_results) industry_risks = industry_ai_risks.get(industry, industry_ai_risks["Other"]) comparison = calculate_build_vs_buy_comparison( initial_dev_cost, num_ai_personnel, avg_annual_salary, annual_maintenance, security_compliance ) dept_recommendations = "" for i, dept in enumerate(top_departments): dept_recommendations += f"\n{i+1}. **{dept['Department']}** (ROI: {dept['ROI']:.1f}%)\n" dept_recommendations += f" - Annual cost savings: ${dept['Annual Cost Savings']:,.2f}\n" dept_recommendations += f" - Hours saved annually: {dept['Annual Hours Saved']:,.0f}\n" dept_recommendations += " - Top AI use cases:\n" for use_case in dept["Use Cases"]: dept_recommendations += f" - {use_case}\n" security_text = "\n\n### Key Security Considerations\n" for risk in industry_risks: security_text += f"- {risk}\n" subscription_text = "\n### Subscription & Tool Optimization\n" subscription_text += f"- **Current annual spend:** ${subscription_savings['total_current_cost']:,.2f}\n" subscription_text += f"- **Potential annual savings:** ${subscription_savings['total_savings']:,.2f} ({subscription_savings['savings_percentage']:.1f}%)\n" subscription_text += "- **Recommendation:** Evaluate consolidation of overlapping tools with AI capabilities\n" compliance_text = "\n### Compliance Risk Reduction\n" compliance_text += f"- **Potential risk exposure reduction:** ${compliance_savings['total_savings']:,.2f}\n" compliance_text += "- **Key regulations to address:**\n" for reg in compliance_savings['key_regulations']: compliance_text += f" - {reg['name']}: ${reg['cost']:,.2f} risk exposure\n" build_vs_buy_text = "\n### Build vs Buy Analysis\n" build_vs_buy_text += "- **Building in-house:**\n" build_vs_buy_text += f" - First year cost: ${comparison['first_year_build']:,.2f}\n" build_vs_buy_text += f" - Ongoing annual cost: ${comparison['ongoing_annual_build']:,.2f}\n" build_vs_buy_text += f" - 3-year total cost: ${comparison['three_year_build']:,.2f}\n\n" build_vs_buy_text += "- **Preamble Enterprise:**\n" build_vs_buy_text += f" - Annual cost: ${comparison['annual_preamble']:,.2f}\n" build_vs_buy_text += f" - 3-year total cost: ${comparison['three_year_preamble']:,.2f}\n\n" build_vs_buy_text += f"- **3-year savings with Preamble:** ${comparison['three_year_savings']:,.2f} ({comparison['savings_percentage']:.1f}%)\n" build_vs_buy_text += f"- **ROI:** {((comparison['three_year_savings'] / comparison['three_year_preamble']) * 100):,.1f}%\n" # Improve formatting for Executive Summary with line breaks between items executive_summary = "## Executive Summary\n" executive_summary += f"- **Industry:** {industry}\n" executive_summary += f"- **Organization Size:** {org_size:,} employees\n" executive_summary += f"- **Monthly Budget:** ${monthly_budget:,.2f}\n" executive_summary += f"- **Existing AI Application:** {'Yes' if has_ai_app else 'No'}\n" executive_summary += f"- **Total Potential Annual Savings:** ${total_dept_savings + subscription_savings['total_savings'] + compliance_savings['total_savings']:,.2f}\n\n" # Format implementation roadmap with proper line breaks implementation_roadmap = "## Implementation Roadmap\n\n" implementation_roadmap += "1. **Phase 1: Security Foundation** (1-2 months)\n" implementation_roadmap += f" - Deploy Preamble {solution_rec['solution']}\n" implementation_roadmap += " - Establish AI governance framework\n" implementation_roadmap += " - Train key personnel\n\n" implementation_roadmap += "2. **Phase 2: Department Pilots** (2-3 months)\n" implementation_roadmap += f" - Implement AI use cases in {top_departments[0]['Department']}\n" implementation_roadmap += " - Measure results\n\n" implementation_roadmap += "3. **Phase 3: Expansion** (3-6 months)\n" implementation_roadmap += " - Roll out to additional departments\n" implementation_roadmap += " - Begin subscription consolidation\n" implementation_roadmap += " - Scale security controls\n\n" report = ( f"# AI Implementation & Security Recommendation\n{executive_summary}" f"## Recommended Preamble Solution\n{solution_rec['image']} {solution_rec['description']}\n\n" f"{build_vs_buy_text}\n" f"## Department Recommendations\nThe following departments show the highest potential ROI for AI implementation:{dept_recommendations}\n" f"{subscription_text}{compliance_text}{security_text}\n\n{implementation_roadmap}" f"\n[Learn more about Preamble solutions and pricing](https://preamble.com/pricing)" ) return report, comparison CUSTOM_CSS = f""" /* General Styles */ .gradio-container {{ max-width: 1200px !important; margin: auto !important; padding: 2rem !important; background-color: {BRAND_COLORS['dark_bg']} !important; font-family: 'Inter', sans-serif !important; color: {BRAND_COLORS['light_text']} !important; border-radius: 12px !important; box-shadow: 0 8px 16px rgba(0, 0, 0, 0.15) !important; font-size: 16px !important; }} /* Main container */ .main-container {{ display: flex !important; flex-direction: column !important; gap: 2rem !important; }} /* Section styling */ .section-container {{ background-color: {BRAND_COLORS['secondary']} !important; border-radius: 12px !important; padding: 2.5rem !important; margin-bottom: 2rem !important; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15) !important; border: 1px solid {BRAND_COLORS['primary']} !important; transition: all 0.3s ease !important; }} .section-title {{ font-size: 2.2rem !important; color: {BRAND_COLORS['accent']} !important; font-weight: 700 !important; margin-bottom: 1.5rem !important; line-height: 1.3 !important; text-align: center !important; text-shadow: 0px 1px 2px rgba(0,0,0,0.2) !important; }} .subsection-title {{ color: {BRAND_COLORS['dark_text']} !important; font-size: 1.6rem !important; font-weight: 600 !important; margin: 1.5rem 0 1rem !important; border-bottom: 2px solid {BRAND_COLORS['accent']} !important; padding-bottom: 0.5rem !important; display: inline-block !important; }} /* Input fields styling */ .input-row {{ display: grid !important; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)) !important; gap: 1.5rem !important; margin: 1.5rem 0 !important; }} .number-input, .text-input, .dropdown-input, .radio-input {{ background-color: {BRAND_COLORS['primary']} !important; border: 2px solid {BRAND_COLORS['light_bg']} !important; border-radius: 10px !important; padding: 1rem !important; color: {BRAND_COLORS['light_text']} !important; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1) !important; transition: all 0.2s ease-in-out !important; font-size: 16px !important; }} .number-input:focus, .text-input:focus, .dropdown-input:focus, .radio-input:focus {{ border-color: {BRAND_COLORS['accent']} !important; box-shadow: 0 0 0 4px rgba(255, 199, 0, 0.3) !important; outline: none !important; transform: translateY(-2px) !important; }} /* Input Labels - Use the defined label_text color */ .label-text, .textinput label, .dropdown-input label, .radio-input label, .number-input label {{ color: {BRAND_COLORS['accent']} !important; margin-bottom: 0.75rem !important; font-weight: 600 !important; font-size: 17px !important; display: block !important; letter-spacing: 0.5px !important; }} /* Table/Dataframe styling */ .table-container {{ background-color: {BRAND_COLORS['light_bg']} !important; border-radius: 10px !important; margin: 1.5rem 0 !important; overflow: auto !important; /* Changed from 'hidden' to 'auto' to allow scrolling when needed */ border: 2px solid {BRAND_COLORS['primary']} !important; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1) !important; max-height: 400px !important; /* Set maximum height */ }} .table-container table {{ color: {BRAND_COLORS['input_text']} !important; width: 100% !important; border-collapse: collapse !important; font-size: 16px !important; display: table !important; /* Ensure proper table display */ table-layout: fixed !important; /* Fixed layout for better control */ }} .table-container th {{ background-color: {BRAND_COLORS['table_header']} !important; color: #FFFFFF !important; padding: 1rem !important; text-align: left !important; border-bottom: 2px solid {BRAND_COLORS['primary']} !important; font-size: 16px !important; text-transform: uppercase !important; letter-spacing: 0.5px !important; }} .table-container td {{ padding: 1rem !important; text-align: left !important; border-bottom: 1px solid {BRAND_COLORS['table_header']} !important; }} .table-container tr:nth-child(odd) {{ background-color: {BRAND_COLORS['table_row_odd']} !important; }} .table-container tr:nth-child(even) {{ background-color: {BRAND_COLORS['table_row_even']} !important; }} .table-container tr:hover {{ background-color: rgba(255, 199, 0, 0.1) !important; }} /* Department table specific styling */ .department-table {{ height: 350px !important; min-height: 350px !important; overflow-y: visible !important; }} .department-table table {{ height: auto !important; }} .department-table td {{ white-space: normal !important; overflow: visible !important; text-overflow: clip !important; padding: 12px !important; }} /* Results container - General background and text */ .results-container {{ background-color: {BRAND_COLORS['result_bg']} !important; border-radius: 12px !important; padding: 2.5rem !important; margin-top: 2rem !important; color: {BRAND_COLORS['result_text']} !important; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15) !important; }} /* Result Card - Specific overrides */ .result-card {{ background-color: {BRAND_COLORS['result_bg']} !important; border-radius: 10px !important; padding: 2rem !important; margin: 1.5rem 0 !important; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1) !important; font-size: 16px !important; color: {BRAND_COLORS['result_text']} !important; border-left: 5px solid {BRAND_COLORS['accent']} !important; }} /* Enhanced Markdown Rendering - All heading levels */ .result-card h1 {{ font-size: 2.2rem !important; margin: 1.5rem 0 1.2rem !important; color: {BRAND_COLORS['accent']} !important; font-weight: 700 !important; border-bottom: 2px solid {BRAND_COLORS['accent']} !important; padding-bottom: 0.6rem !important; }} .result-card h2 {{ font-size: 2rem !important; margin: 1.4rem 0 1rem !important; color: {BRAND_COLORS['result_text']} !important; font-weight: 700 !important; border-bottom: 1px solid {BRAND_COLORS['accent']} !important; padding-bottom: 0.5rem !important; }} .result-card h3 {{ font-size: 1.8rem !important; margin: 1.3rem 0 1rem !important; color: {BRAND_COLORS['result_text']} !important; font-weight: 600 !important; border-bottom: 1px solid rgba(255, 199, 0, 0.5) !important; padding-bottom: 0.4rem !important; display: inline-block !important; }} .result-card h4 {{ font-size: 1.5rem !important; margin: 1.2rem 0 0.8rem !important; color: {BRAND_COLORS['result_text']} !important; font-weight: 600 !important; }} .result-card h5 {{ font-size: 1.25rem !important; margin: 1rem 0 0.6rem !important; color: {BRAND_COLORS['result_text']} !important; font-weight: 600 !important; }} /* Result card text elements */ .result-card p {{ color: {BRAND_COLORS['result_text']} !important; font-size: 16px !important; line-height: 1.7 !important; margin-bottom: 1rem !important; }} .result-card strong, .result-card b {{ color: {BRAND_COLORS['accent']} !important; font-weight: 600 !important; }} .result-card em, .result-card i {{ font-style: italic !important; }} .result-card a {{ color: {BRAND_COLORS['accent']} !important; text-decoration: underline !important; transition: all 0.2s ease !important; }} .result-card a:hover {{ opacity: 0.8 !important; }} /* Lists styling */ .result-card ul, .result-card ol {{ padding-left: 1.8rem !important; margin: 0.8rem 0 1.2rem 0.5rem !important; }} .result-card li {{ margin-bottom: 0.7rem !important; color: {BRAND_COLORS['result_text']} !important; }} /* Code blocks */ .result-card code {{ background-color: rgba(0, 0, 0, 0.3) !important; padding: 0.2rem 0.4rem !important; border-radius: 4px !important; font-family: monospace !important; font-size: 0.9rem !important; }} .result-card pre {{ background-color: rgba(0, 0, 0, 0.3) !important; padding: 1rem !important; border-radius: 6px !important; overflow-x: auto !important; margin: 1rem 0 !important; }} /* Blockquotes */ .result-card blockquote {{ border-left: 4px solid {BRAND_COLORS['accent']} !important; padding-left: 1rem !important; margin-left: 0 !important; margin-right: 0 !important; font-style: italic !important; color: rgba(255, 255, 255, 0.9) !important; }} /* Tables */ .result-card table {{ width: 100% !important; border-collapse: collapse !important; margin: 1.5rem 0 !important; }} .result-card th {{ background-color: {BRAND_COLORS['primary']} !important; color: {BRAND_COLORS['light_text']} !important; padding: 0.8rem !important; text-align: left !important; font-weight: 600 !important; }} .result-card td {{ border: 1px solid rgba(255, 255, 255, 0.2) !important; padding: 0.8rem !important; }} .result-card tr:nth-child(even) {{ background-color: rgba(0, 0, 0, 0.2) !important; }} /* Buttons styling */ .calculate-button {{ background-color: {BRAND_COLORS['accent']} !important; color: {BRAND_COLORS['button_text']} !important; font-weight: 600 !important; padding: 1rem 2rem !important; border-radius: 50px !important; margin-top: 2rem !important; font-size: 1.2rem !important; min-width: 200px !important; transition: all 0.3s ease !important; display: inline-block !important; border: none !important; cursor: pointer !important; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1) !important; text-align: center !important; letter-spacing: 0.5px !important; }} .calculate-button:hover {{ background-color: #e6b400 !important; box-shadow: 0 6px 10px rgba(255, 199, 0, 0.3) !important; transform: translateY(-2px) !important; }} .back-button {{ background-color: transparent !important; color: {BRAND_COLORS['light_text']} !important; border: 2px solid {BRAND_COLORS['light_text']} !important; font-weight: 600 !important; padding: 0.8rem 1.5rem !important; border-radius: 50px !important; margin-top: 2rem !important; font-size: 1.1rem !important; min-width: 150px !important; transition: all 0.3s ease !important; display: inline-block !important; cursor: pointer !important; text-align: center !important; }} .back-button:hover {{ background-color: rgba(255, 255, 255, 0.1) !important; box-shadow: 0 2px 4px rgba(255, 255, 255, 0.1) !important; }} /* Button container */ .button-container {{ display: flex !important; justify-content: space-between !important; align-items: center !important; margin-top: 2rem !important; gap: 1rem !important; }} .center-button-container {{ display: flex !important; justify-content: center !important; align-items: center !important; margin-top: 2rem !important; gap: 1rem !important; }} /* Chart container */ .chart-container {{ background-color: {BRAND_COLORS['light_bg']} !important; border-radius: 12px !important; padding: 2rem !important; margin: 1.5rem 0 !important; height: 500px !important; border: 2px solid {BRAND_COLORS['primary']} !important; color: {BRAND_COLORS['input_text']} !important; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1) !important; }} /* Tab styling */ .tab-nav {{ padding: 0 !important; margin-bottom: 2rem !important; display: flex !important; justify-content: center !important; gap: 0.5rem !important; flex-wrap: wrap !important; }} .tab-nav button {{ color: {BRAND_COLORS['light_text']} !important; padding: 0.8rem 1.8rem !important; border-radius: 50px !important; opacity: 0.9 !important; border: 2px solid {BRAND_COLORS['primary']} !important; background-color: {BRAND_COLORS['secondary']} !important; cursor: pointer !important; font-size: 16px !important; font-weight: 600 !important; transition: all 0.3s ease !important; min-width: 180px !important; text-align: center !important; }} .tab-nav button.selected {{ background-color: {BRAND_COLORS['primary']} !important; color: {BRAND_COLORS['light_text']} !important; opacity: 1 !important; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1) !important; }} .tab-nav button:hover {{ transform: translateY(-2px) !important; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1) !important; }} /* Timeline progress indicator */ .timeline-container {{ display: flex !important; justify-content: space-between !important; align-items: center !important; margin: 0 auto 2rem auto !important; position: relative !important; max-width: 800px !important; padding: 15px 20px !important; background-color: {BRAND_COLORS['secondary']} !important; border-radius: 8px !important; }} .timeline-container:after {{ content: "" !important; position: absolute !important; height: 3px !important; background-color: {BRAND_COLORS['primary']} !important; top: 50% !important; left: 0 !important; right: 0 !important; z-index: 1 !important; }} .timeline-step {{ padding: 8px 15px !important; border-radius: 6px !important; font-weight: 600 !important; font-size: 14px !important; color: {BRAND_COLORS['light_text']} !important; background-color: {BRAND_COLORS['primary']} !important; z-index: 2 !important; position: relative !important; transition: all 0.3s ease !important; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2) !important; cursor: default !important; }} .timeline-step.active {{ background-color: {BRAND_COLORS['accent']} !important; color: {BRAND_COLORS['dark_text']} !important; transform: translateY(-2px) !important; box-shadow: 0 4px 8px rgba(255, 199, 0, 0.3) !important; }} @media (max-width: 768px) {{ .timeline-container {{ flex-direction: column !important; }} .timeline-container {{ gap: 10px !important; }} .timeline-container:after {{ display: none !important; }} .timeline-step {{ width: 100% !important; text-align: center !important; }} }} /* Info card */ .info-card {{ background-color: rgba(255, 199, 0, 0.1) !important; border-left: 4px solid {BRAND_COLORS['accent']} !important; padding: 1.2rem !important; margin: 1.5rem 0 !important; border-radius: 0 8px 8px 0 !important; }} .info-card-title {{ font-weight: 600 !important; margin-bottom: 0.5rem !important; color: {BRAND_COLORS['accent']} !important; }} .helper-text {{ color: {BRAND_COLORS['accent']} !important; font-size: 14px !important; margin-top: 0.5rem !important; opacity: 0.9 !important; }} /* Responsive adjustments */ @media (max-width: 768px) {{ .progress-container:after {{ left: 0 !important; right: 0 !important; }} .section-title {{ font-size: 1.8rem !important; }} .subsection-title {{ font-size: 1.4rem !important; }} .calculate-button, .back-button {{ width: 100% !important; }} }} /* Responsive adjustments for smaller screens */ @media (max-width: 768px) {{ .input-row {{ grid-template-columns: 1fr !important; /* Stack inputs vertically */ }} }} """ def create_app(): with gr.Blocks(css=CUSTOM_CSS, theme=gr.themes.Default()) as roi_app: current_step = gr.State(value=1) total_employees_state = gr.State(value=90) with gr.Column(elem_classes="main-container"): gr.Markdown("# Preamble AI Security ROI Calculator", elem_classes="section-title") with gr.Row(elem_classes="timeline-container"): step1_indicator = gr.Markdown( "Organization Profile", elem_classes="timeline-step active", elem_id="step1-indicator") step2_indicator = gr.Markdown( "Department Assessment", elem_classes="timeline-step", elem_id="step2-indicator") step3_indicator = gr.Markdown( "Tools & Compliance", elem_classes="timeline-step", elem_id="step3-indicator") step4_indicator = gr.Markdown( "Results", elem_classes="timeline-step", elem_id="step4-indicator") with gr.Column(visible=True, elem_id="step1", elem_classes="section-container") as step1: gr.Markdown("## Organization Profile", elem_classes="section-title") gr.Markdown("""