Pegumenezes commited on
Commit
f76598c
·
verified ·
1 Parent(s): 7d85b55

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +260 -128
src/streamlit_app.py CHANGED
@@ -6,39 +6,121 @@ import plotly.express as px
6
  import plotly.graph_objects as go
7
  import numpy_financial as npf
8
 
 
9
  st.set_page_config(
10
  layout="wide",
11
  page_title="Dashboard Estratégico de Reciclagem",
12
  page_icon="♻️"
13
  )
14
 
15
- # --- 2. ESTILO CSS PROFISSIONAL ---
 
 
 
 
 
 
 
 
 
 
16
  st.markdown("""
17
  <style>
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  .stMetric {
19
- border-radius: 10px; padding: 15px; background-color: #FFFFFF;
20
- border: 1px solid #E6E6E6; box-shadow: 0 4px 8px rgba(0,0,0,0.04);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
  }
22
- .stTabs [data-baseweb="tab-list"] { gap: 24px; }
23
  .stTabs [data-baseweb="tab"] {
24
- height: 50px; background-color: #F0F2F6; border-radius: 4px 4px 0px 0px; padding: 10px 15px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  }
26
- .stTabs [aria-selected="true"] { background-color: #FFFFFF; }
27
  </style>
28
  """, unsafe_allow_html=True)
29
 
30
 
31
- # --- 3. DEFINIÇÃO DAS FUNÇÕES GLOBAIS DE CÁLCULO ---
 
32
  def formatar_brl(valor): return f"R$ {valor:,.2f}"
33
  def formatar_percentual(valor): return f"{valor:.2%}" if pd.notna(valor) and not np.isinf(valor) else "N/A"
34
  def calcular_vpl(fluxo_caixa, taxa_desconto):
35
  try: return npf.npv(taxa_desconto, fluxo_caixa)
36
  except: return np.nan
37
  def calcular_tir(fluxo_caixa):
38
- try: return npf.irr(fluxo_caixa) if np.any(np.sign(fluxo_caixa)) and np.any(np.sign(fluxo_caixa) * -1) else np.nan
 
39
  except: return np.nan
40
  def calcular_mtir(fluxo_caixa, taxa_desconto, taxa_reinvestimento):
41
- try: return npf.mirr(fluxo_caixa, taxa_desconto, taxa_reinvestimento) if np.any(np.sign(fluxo_caixa)) and np.any(np.sign(fluxo_caixa) * -1) else np.nan
 
42
  except: return np.nan
43
  def calcular_payback_descontado(fluxo_caixa, taxa_desconto):
44
  investimento_inicial = abs(fluxo_caixa[0])
@@ -49,6 +131,7 @@ def calcular_payback_descontado(fluxo_caixa, taxa_desconto):
49
  ultimo_fluxo_necessario = investimento_inicial - (fluxo_acumulado_descontado - (valor / ((1 + taxa_desconto) ** periodo)))
50
  return (periodo - 1) + (ultimo_fluxo_necessario / (valor / ((1 + taxa_desconto) ** periodo)))
51
  return np.inf
 
52
  @st.cache_data
53
  def simular_faturamento_bootstrap(_df_dados_mensais_numeric, precos_dict, cenarios_dict, eficiencia_geral_coleta, n_simulacoes=2000, seed=42):
54
  np.random.seed(seed)
@@ -60,6 +143,7 @@ def simular_faturamento_bootstrap(_df_dados_mensais_numeric, precos_dict, cenari
60
  faturamento_liquido = faturamento_bruto_iteracao * eficiencia_geral_coleta * fator_cenario
61
  faturamentos_simulados[nome_cen].append(faturamento_liquido)
62
  return {nome: np.array(data) for nome, data in faturamentos_simulados.items()}
 
63
  def gerar_fluxo_caixa_projeto(investimento_inicial, receita_anual_base, custos_operacionais_anuais, horizonte_anos, taxa_crescimento):
64
  fluxo_caixa = [-abs(investimento_inicial)]
65
  for ano in range(1, horizonte_anos + 1):
@@ -68,11 +152,16 @@ def gerar_fluxo_caixa_projeto(investimento_inicial, receita_anual_base, custos_o
68
  fluxo_caixa.append(fluxo_liquido_ano)
69
  return fluxo_caixa
70
 
71
- # --- 4. CARREGAMENTO DE DADOS (FUNÇÃO CACHEADA) ---
72
  @st.cache_data
73
  def carregar_dados():
74
  meses = ['Jan', 'Fev', 'Mar', 'Abr', 'Mai', 'Jun', 'Jul', 'Ago', 'Set', 'Out', 'Nov', 'Dez']
75
- dados_2024 = {'Mes': meses, 'Papel_Papelao': [8047, 11287, 8184, 10183, 5699, 5830, 7465, 5600, 2960, 5175, 9656, 3960], 'Plastico': [6353, 8771, 6993, 8050, 4880, 5296, 5937, 4747, 2446, 4109, 7667, 3367], 'Metal': [1061, 2025, 1121, 1832, 716, 936, 1553, 904, 361, 630, 1904, 569], 'Vidro': [5248, 6929, 6014, 5821, 3697, 3655, 4950, 3360, 1580, 3261, 6173, 2357]}
 
 
 
 
 
76
  df_2024 = pd.DataFrame(dados_2024)
77
  df_2024_numeric = df_2024.drop(columns='Mes')
78
  dados_anuais = {'Ano': [2022, 2023, 2024], 'Papel_Papelao': [18780, 58718, df_2024_numeric['Papel_Papelao'].sum()], 'Plastico': [5340, 1041, df_2024_numeric['Plastico'].sum()], 'Metal': [1300, 1737, df_2024_numeric['Metal'].sum()], 'Vidro': [0, 725, df_2024_numeric['Vidro'].sum()]}
@@ -81,42 +170,95 @@ def carregar_dados():
81
  custos_mensais_iniciais = {"Locacao_Maquina": 4400, "Coleta_Destinacao": 1400, "Outros": 500}
82
  return df_2024, df_anuais, precos_iniciais, df_2024_numeric, custos_mensais_iniciais
83
 
84
- # --- NOVA ESTRUTURA: FUNÇÕES DE RENDERIZAÇÃO DE PÁGINA ---
 
 
 
 
 
 
 
 
85
 
86
- def render_eda_page(df_2024, df_anuais):
87
- """Renderiza todo o conteúdo da página de Análise Exploratória."""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
  st.title("🔎 Análise Exploratória dos Dados de Coleta")
89
- st.markdown("O primeiro passo para qualquer projeção é entender o passado. Aqui, exploramos os dados históricos de coleta para identificar padrões, sazonalidades e anomalias.")
90
  st.divider()
91
 
92
- st.subheader("Evolução da Coleta Total Anual (Histórico)")
93
- df_coleta_anual = df_anuais.sum(axis=1).reset_index()
94
- df_coleta_anual.columns = ['Ano', 'Coleta Total (kg)']
95
- fig_evol_coleta = px.bar(df_coleta_anual, x='Ano', y='Coleta Total (kg)', text_auto='.3s', title="Volume Total Anual de Materiais Coletados")
96
- st.plotly_chart(fig_evol_coleta, use_container_width=True)
97
- st.warning("**Observação:** Note a queda acentuada na coleta de Plástico e Metal em 2023 em comparação com 2022 nos dados fornecidos. É crucial investigar se isso reflete a realidade operacional ou uma anomalia nos dados antes de prosseguir com projeções críticas.")
98
-
99
  col1, col2 = st.columns(2)
100
  with col1:
101
  st.subheader("Coleta Mensal por Material (2024)")
102
  df_melt_mensal = df_2024.melt(id_vars='Mes', var_name='Material', value_name='Quantidade (kg)')
103
- fig_evol_mensal = px.line(df_melt_mensal, x='Mes', y='Quantidade (kg)', color='Material', title="Variação Mensal da Coleta por Material", markers=True)
 
 
 
 
 
104
  st.plotly_chart(fig_evol_mensal, use_container_width=True)
 
105
  with col2:
106
  st.subheader("Distribuição da Coleta Mensal (2024)")
107
- fig_boxplot = px.box(df_melt_mensal, x='Material', y='Quantidade (kg)', color='Material', title="Variação e Volatilidade da Coleta Mensal")
 
 
 
 
 
108
  st.plotly_chart(fig_boxplot, use_container_width=True)
109
-
110
  st.info("O **gráfico de linhas** mostra a tendência e sazonalidade ao longo do ano. O **boxplot** revela a volatilidade de cada material: caixas mais 'altas' indicam maior variação mensal, o que se traduz em maior risco e incerteza no faturamento.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
111
 
112
- def render_faturamento_page(df_2024_numeric, precos_editaveis, cenarios, eficiencia_coleta_geral):
113
- """Renderiza todo o conteúdo da página de Simulação de Faturamento."""
114
  st.title("🎯 Simulação e Projeção de Faturamento Anual")
115
- st.markdown("Utilizando a técnica de bootstrapping, simulamos 2.000 possíveis anos de faturamento com base na volatilidade dos dados de 2024 e na eficiência de coleta definida.")
116
  st.divider()
117
-
 
118
  simulacoes_faturamento = simular_faturamento_bootstrap(df_2024_numeric, precos_editaveis, cenarios, eficiencia_coleta_geral)
119
-
120
  kpi1, kpi2, kpi3 = st.columns(3)
121
  media_faturamento_base = np.mean(simulacoes_faturamento['Base'])
122
  desvio_padrao_base = np.std(simulacoes_faturamento['Base'])
@@ -124,144 +266,134 @@ def render_faturamento_page(df_2024_numeric, precos_editaveis, cenarios, eficien
124
  material_mais_rentavel = max(faturamento_material_base, key=faturamento_material_base.get)
125
 
126
  kpi1.metric("Faturamento Anual Médio (Base)", formatar_brl(media_faturamento_base))
127
- kpi2.metric("Desvio Padrão do Faturamento", formatar_brl(desvio_padrao_base), help="Mede a volatilidade ou risco do faturamento. Valores mais altos indicam maior incerteza.")
128
- kpi3.metric("Material Mais Rentável (Base 2024)", material_mais_rentavel.replace('_', ' '))
129
  st.divider()
130
-
131
- col_g1, col_g2 = st.columns([6, 4])
132
  with col_g1:
133
  st.subheader("Distribuição do Faturamento Anual Simulado")
134
  fig_dist = go.Figure()
 
135
  for nome, data in simulacoes_faturamento.items():
136
- fig_dist.add_trace(go.Histogram(x=data, name=nome, histnorm='probability density', opacity=0.75))
137
- fig_dist.update_layout(barmode='overlay', title_text="Comparativo de Cenários de Faturamento", xaxis_title="Faturamento Anual (R$)", yaxis_title="Densidade de Probabilidade", legend_title_text='Cenário')
 
 
 
 
 
 
 
 
138
  st.plotly_chart(fig_dist, use_container_width=True)
 
139
  with col_g2:
140
- st.subheader("Composição do Faturamento (Base 2024)")
141
  df_faturamento_material = pd.DataFrame(list(faturamento_material_base.items()), columns=['Material', 'Faturamento'])
142
- fig_comp = px.pie(df_faturamento_material, values='Faturamento', names='Material', hole=0.4, title="Faturamento por Material")
 
 
 
 
 
143
  st.plotly_chart(fig_comp, use_container_width=True)
144
 
145
- def render_viabilidade_page(df_2024_numeric, precos_editaveis, cenarios, eficiencia_coleta_geral, investimento_inicial, custos_operacionais_anuais, horizonte_projeto, taxa_crescimento, taxa_desconto, taxa_reinvestimento):
146
- """Renderiza todo o conteúdo da página de Análise de Viabilidade."""
147
  st.title("📊 Análise de Viabilidade Financeira e Risco")
148
- st.markdown("Esta é a etapa final, onde combinamos as projeções de receita com as premissas de investimento e custos para avaliar a viabilidade do projeto sob a ótica do risco.")
149
-
 
150
  simulacoes_faturamento = simular_faturamento_bootstrap(df_2024_numeric, precos_editaveis, cenarios, eficiencia_coleta_geral)
151
-
152
- cenario_analise = st.radio("Selecione o cenário para a análise detalhada:", options=list(cenarios.keys()), index=1, horizontal=True)
 
 
 
 
153
  st.divider()
154
-
155
  receita_anual_media = np.mean(simulacoes_faturamento[cenario_analise])
156
  fluxo_caixa_projeto = gerar_fluxo_caixa_projeto(investimento_inicial, receita_anual_media, custos_operacionais_anuais, horizonte_projeto, taxa_crescimento)
157
-
158
  vpl = calcular_vpl(fluxo_caixa_projeto, taxa_desconto)
159
  tir = calcular_tir(fluxo_caixa_projeto)
160
  mtir = calcular_mtir(fluxo_caixa_projeto, taxa_desconto, taxa_reinvestimento)
161
  payback_desc = calcular_payback_descontado(fluxo_caixa_projeto, taxa_desconto)
162
-
163
- tab_kpis, tab_fluxo, tab_risco, tab_resumo = st.tabs(["📈 Indicadores Chave", "📂 Fluxo de Caixa", "🎲 Análise de Risco (Monte Carlo)", "📋 Resumo Executivo"])
164
 
165
  with tab_kpis:
166
- st.subheader(f"Indicadores para o Cenário: {cenario_analise}")
167
  col1, col2, col3, col4 = st.columns(4)
168
- col1.metric("VPL", formatar_brl(vpl), "Viável" if vpl >= 0 else "Inviável")
169
- col2.metric("TIR", formatar_percentual(tir), "Superior à TMA" if pd.notna(tir) and tir > taxa_desconto else "Inferior à TMA")
170
- col3.metric("MTIR", formatar_percentual(mtir), "Superior à TMA" if pd.notna(mtir) and mtir > taxa_desconto else "Inferior à TMA")
171
- col4.metric("Payback Descontado", f"{payback_desc:.1f} anos" if not np.isinf(payback_desc) else "Não recupera")
172
 
173
  with tab_fluxo:
174
  st.subheader("Visualização do Fluxo de Caixa do Projeto")
175
  df_fluxo = pd.DataFrame({'Ano': list(range(horizonte_projeto + 1)), 'Fluxo de Caixa': fluxo_caixa_projeto})
176
  df_fluxo['Fluxo Acumulado'] = df_fluxo['Fluxo de Caixa'].cumsum()
177
- fig_fluxo = go.Figure(data=[go.Bar(name='Fluxo Anual', x=df_fluxo['Ano'], y=df_fluxo['Fluxo de Caixa'], marker_color=['#d62728' if x < 0 else '#2ca02c' for x in df_fluxo['Fluxo de Caixa']]), go.Scatter(name='Fluxo Acumulado', x=df_fluxo['Ano'], y=df_fluxo['Fluxo Acumulado'], mode='lines+markers')])
178
- fig_fluxo.update_layout(title_text="Fluxo de Caixa Anual e Acumulado", hovermode='x unified')
 
 
 
 
 
 
179
  st.plotly_chart(fig_fluxo, use_container_width=True)
180
 
181
  with tab_risco:
182
- st.subheader(f"Simulação Monte Carlo para o VPL (Cenário: {cenario_analise})")
 
183
  receitas_mc = np.random.choice(simulacoes_faturamento[cenario_analise], size=5000, replace=True)
184
  vpls_mc = [calcular_vpl(gerar_fluxo_caixa_projeto(investimento_inicial, r, custos_operacionais_anuais, horizonte_projeto, taxa_crescimento), taxa_desconto) for r in receitas_mc]
185
  prob_viabilidade = (np.array(vpls_mc) >= 0).mean()
186
  vpl_medio_mc = np.mean(vpls_mc)
187
  vpl_std_mc = np.std(vpls_mc)
 
188
  mc1, mc2, mc3 = st.columns(3)
189
  mc1.metric("VPL Médio Simulado", formatar_brl(vpl_medio_mc))
190
- mc2.metric("Probabilidade de Viabilidade", formatar_percentual(prob_viabilidade))
191
- mc3.metric("Desvio Padrão do VPL", formatar_brl(vpl_std_mc), help="Mede a volatilidade ou risco do VPL. Valores mais altos indicam maior incerteza.")
 
192
  fig_mc = px.histogram(x=vpls_mc, nbins=50, title=f"Distribuição do VPL ({len(vpls_mc)} Simulações)")
193
- fig_mc.add_vline(x=0, line_dash="dash", line_color="red", annotation_text="Viabilidade")
 
194
  st.plotly_chart(fig_mc, use_container_width=True)
195
 
196
  with tab_resumo:
197
  st.subheader("Resumo Executivo e Parecer Final")
 
 
 
 
 
 
 
 
 
 
 
198
  conclusoes = []
199
- if vpl >= 0: conclusoes.append(f"✅ **Projeto VIÁVEL** no cenário '{cenario_analise}', com um VPL de **{formatar_brl(vpl)}**.")
200
- else: conclusoes.append(f" **Projeto INVIÁVEL** no cenário '{cenario_analise}', com um VPL de **{formatar_brl(vpl)}**.")
201
- if not pd.isna(tir) and tir > taxa_desconto: conclusoes.append(f"✅ A **TIR de {formatar_percentual(tir)} é superior à TMA de {formatar_percentual(taxa_desconto)}**, reforçando a atratividade.")
202
- else: conclusoes.append(f" A **TIR de {formatar_percentual(tir)} é inferior à TMA**, um forte indicador contra o investimento.")
203
- if prob_viabilidade > 0.75: conclusoes.append(f"✅ A simulação de Monte Carlo aponta uma **alta probabilidade de sucesso de {formatar_percentual(prob_viabilidade)}**.")
204
- elif prob_viabilidade > 0.5: conclusoes.append(f"⚠️ A probabilidade de sucesso de **{formatar_percentual(prob_viabilidade)} é moderada**.")
205
- else: conclusoes.append(f" A probabilidade de sucesso de **{formatar_percentual(prob_viabilidade)} é baixa**, indicando risco elevado.")
206
- st.markdown("#### Conclusões Chave:")
207
- for c in conclusoes: st.markdown(f"- {c}")
208
- st.markdown("#### Parecer Final:")
209
- if vpl > 0 and prob_viabilidade > 0.7: st.success("**RECOMENDAÇÃO: APROVAR O PROJETO.** Os indicadores são fortemente positivos e a análise de risco confere robustez à decisão.")
210
- elif vpl > 0 and prob_viabilidade > 0.5: st.warning("**RECOMENDAÇÃO: APROVAR COM CAUTELA.** O projeto é viável, mas a análise de risco mostra sensibilidade. Recomenda-se um plano de monitoramento de riscos focado em garantir as receitas projetadas.")
211
- else: st.error("**RECOMENDAÇÃO: REAVALIAR OU REJEITAR O PROJETO.** Os indicadores atuais, combinados com o perfil de risco, não justificam o investimento. Revisar premissas de receita, custos ou investimento inicial.")
212
-
213
-
214
- # --- SCRIPT PRINCIPAL E LÓGICA DE NAVEGAÇÃO ---
215
- def main():
216
- """Função principal que carrega os dados e controla a navegação."""
217
-
218
- # Carrega todos os dados
219
- df_2024, df_anuais, precos_iniciais, df_2024_numeric, custos_mensais_iniciais = carregar_dados()
220
-
221
- # Monta a sidebar e coleta as premissas do usuário
222
- st.sidebar.title(" Painel de Controle")
223
- st.sidebar.markdown("Use os menus abaixo para navegar entre as análises e ajustar os parâmetros do projeto.")
224
- st.sidebar.divider()
225
-
226
- pagina_selecionada = st.sidebar.radio("Menu de Navegação",
227
- ["🔎 Análise Exploratória (EDA)", "🎯 Simulação de Faturamento", "📊 Análise de Viabilidade"],
228
- captions=["Análise dos dados históricos", "Projeção de receitas via simulação", "Cálculos de VPL, TIR e Risco"]
229
- )
230
- st.sidebar.divider()
231
-
232
- with st.sidebar.expander("⚙️ Premissas Financeiras do Projeto", expanded=True):
233
- investimento_inicial = st.number_input("Investimento Inicial (R$)", min_value=1000.0, value=5000.0, step=1000.0)
234
- st.markdown("**Custos Fixos Mensais (R$)**")
235
- custos_mensais_editaveis = {custo: st.number_input(custo.replace("_", " "), value=valor, step=50, key=custo) for custo, valor in custos_mensais_iniciais.items()}
236
- custos_operacionais_anuais = sum(custos_mensais_editaveis.values()) * 12
237
- st.info(f"Custo Anual Calculado: **{formatar_brl(custos_operacionais_anuais)}**")
238
- horizonte_projeto = st.slider("Horizonte do Projeto (anos)", 3, 20, 10)
239
- taxa_desconto = st.slider("Taxa de Desconto (TMA) (%)", 5.0, 25.0, 12.0, 0.5) / 100
240
- taxa_crescimento = st.slider("Crescimento Anual (Receitas/Custos) (%)", 0.0, 10.0, 3.0, 0.5) / 100
241
- taxa_reinvestimento = st.slider("Taxa de Reinvestimento (MTIR) (%)", 2.0, 18.0, 10.0, 0.5) / 100
242
-
243
- with st.sidebar.expander("📈 Preços e Cenários de Simulação", expanded=False):
244
- eficiencia_coleta_geral = st.slider("Eficiência Geral da Coleta (%)", 0, 100, 30, help="Fator mestre que afeta a quantidade de material coletado em todos os cenários.") / 100
245
- st.markdown("**Preços dos Materiais (R$/kg)**")
246
- precos_editaveis = {material: st.number_input(f"{material.replace('_', ' ')}", value=preco, step=0.1, key=f"preco_{material}") for material, preco in precos_iniciais.items()}
247
- st.markdown("**Fatores de Variação de Cenário**")
248
- fator_pessimista = st.slider("Cenário Pessimista (%)", 0, 100, 80) / 100
249
- fator_otimista = st.slider("Cenário Otimista (%)", 100, 200, 115) / 100
250
-
251
- st.sidebar.divider()
252
- st.sidebar.info(f"Última atualização: {pd.Timestamp.now(tz='America/Sao_Paulo').strftime('%d/%m/%Y %H:%M')}")
253
-
254
- # Chama a função de renderização correta com base na seleção da página
255
- if pagina_selecionada == "🔎 Análise Exploratória (EDA)":
256
- render_eda_page(df_2024, df_anuais)
257
-
258
- elif pagina_selecionada == "🎯 Simulação de Faturamento":
259
- cenarios = {'Pessimista': fator_pessimista, 'Base': 1.0, 'Otimista': fator_otimista}
260
- render_faturamento_page(df_2024_numeric, precos_editaveis, cenarios, eficiencia_coleta_geral)
261
-
262
- elif pagina_selecionada == "📊 Análise de Viabilidade":
263
- cenarios = {'Pessimista': fator_pessimista, 'Base': 1.0, 'Otimista': fator_otimista}
264
- render_viabilidade_page(df_2024_numeric, precos_editaveis, cenarios, eficiencia_coleta_geral, investimento_inicial, custos_operacionais_anuais, horizonte_projeto, taxa_crescimento, taxa_desconto, taxa_reinvestimento)
265
-
266
- if __name__ == '__main__':
267
- main()
 
6
  import plotly.graph_objects as go
7
  import numpy_financial as npf
8
 
9
+ # Configuração da página com um tema mais moderno
10
  st.set_page_config(
11
  layout="wide",
12
  page_title="Dashboard Estratégico de Reciclagem",
13
  page_icon="♻️"
14
  )
15
 
16
+ # --- 2. ESTILO CSS PROFISSIONAL E APRIMORADO ---
17
+ # Paleta de Cores:
18
+ # Verde Principal (Ações, Destaques Positivos): #2ca02c
19
+ # Azul Profundo (Gráficos, Títulos Principais): #1f77b4
20
+ # Cinza Escuro (Texto Principal): #333333
21
+ # Cinza Médio (Texto Secundário, Rótulos): #666666
22
+ # Cinza Claro (Fundo Principal, Bordas): #f0f2f6
23
+ # Fundo dos Cards/Métricas: #ffffff
24
+ # Sombra Suave dos Cards: rgba(0, 0, 0, 0.05)
25
+ # Vermelho para Alertas/Negativo: #d62728
26
+
27
  st.markdown("""
28
  <style>
29
+ /* --- CONFIGURAÇÕES GERAIS --- */
30
+ body {
31
+ font-family: 'Segoe UI', 'Roboto', 'Helvetica Neue', sans-serif;
32
+ background-color: #f0f2f6;
33
+ }
34
+
35
+ /* --- TÍTULOS E TEXTOS --- */
36
+ h1, h2, h3 {
37
+ color: #1f77b4; /* Azul profundo para títulos */
38
+ font-weight: 600;
39
+ }
40
+
41
+ /* --- MÉTRICAS (KPIs) --- */
42
  .stMetric {
43
+ background-color: #FFFFFF;
44
+ border: 1px solid #E0E0E0;
45
+ border-radius: 12px;
46
+ padding: 20px;
47
+ box-shadow: 0 4px 12px rgba(0,0,0,0.05);
48
+ transition: all 0.3s ease-in-out;
49
+ }
50
+ .stMetric:hover {
51
+ transform: translateY(-5px);
52
+ box-shadow: 0 8px 16px rgba(0,0,0,0.1);
53
+ }
54
+ .stMetric [data-testid="stMetricLabel"] {
55
+ color: #666666; /* Cinza médio para o rótulo */
56
+ font-size: 0.95rem;
57
+ }
58
+ .stMetric [data-testid="stMetricValue"] {
59
+ color: #1f77b4; /* Azul profundo para o valor */
60
+ font-size: 2.1rem;
61
+ }
62
+ .stMetric [data-testid="stMetricDelta"] {
63
+ color: #666666; /* Cor neutra para o texto auxiliar */
64
+ }
65
+
66
+ /* --- ABAS (TABS) --- */
67
+ .stTabs [data-baseweb="tab-list"] {
68
+ gap: 8px;
69
+ border-bottom: 2px solid #e0e0e0;
70
  }
 
71
  .stTabs [data-baseweb="tab"] {
72
+ height: 50px;
73
+ background-color: transparent;
74
+ border-radius: 8px 8px 0 0;
75
+ padding: 10px 20px;
76
+ color: #666666;
77
+ border: 0;
78
+ font-weight: 500;
79
+ }
80
+ .stTabs [aria-selected="true"] {
81
+ background-color: #f0f2f6;
82
+ color: #1f77b4;
83
+ border-bottom: 3px solid #1f77b4; /* Linha indicadora na aba ativa */
84
+ }
85
+
86
+ /* --- BARRA LATERAL (SIDEBAR) --- */
87
+ [data-testid="stSidebar"] {
88
+ background-color: #ffffff;
89
+ border-right: 1px solid #e0e0e0;
90
+ }
91
+ [data-testid="stSidebar"] .st-emotion-cache-16txtl3 { /* Título da Sidebar */
92
+ color: #1f77b4;
93
+ }
94
+
95
+ /* --- BOTÕES E WIDGETS --- */
96
+ .stButton>button {
97
+ border-radius: 8px;
98
+ border: 1px solid #1f77b4;
99
+ background-color: #1f77b4;
100
+ color: white;
101
+ }
102
+ .stRadio [data-baseweb="radio"] > div:first-child{
103
+ border-color: #1f77b4 !important;
104
  }
105
+
106
  </style>
107
  """, unsafe_allow_html=True)
108
 
109
 
110
+ # --- 3. DEFINIÇÃO DAS FUNÇÕES GLOBAIS (sem alterações) ---
111
+ # As suas funções de cálculo permanecem as mesmas, pois são a lógica do negócio.
112
  def formatar_brl(valor): return f"R$ {valor:,.2f}"
113
  def formatar_percentual(valor): return f"{valor:.2%}" if pd.notna(valor) and not np.isinf(valor) else "N/A"
114
  def calcular_vpl(fluxo_caixa, taxa_desconto):
115
  try: return npf.npv(taxa_desconto, fluxo_caixa)
116
  except: return np.nan
117
  def calcular_tir(fluxo_caixa):
118
+ try:
119
+ return npf.irr(fluxo_caixa) if np.any(np.sign(fluxo_caixa)) and np.any(np.sign(fluxo_caixa) * -1) else np.nan
120
  except: return np.nan
121
  def calcular_mtir(fluxo_caixa, taxa_desconto, taxa_reinvestimento):
122
+ try:
123
+ return npf.mirr(fluxo_caixa, taxa_desconto, taxa_reinvestimento) if np.any(np.sign(fluxo_caixa)) and np.any(np.sign(fluxo_caixa) * -1) else np.nan
124
  except: return np.nan
125
  def calcular_payback_descontado(fluxo_caixa, taxa_desconto):
126
  investimento_inicial = abs(fluxo_caixa[0])
 
131
  ultimo_fluxo_necessario = investimento_inicial - (fluxo_acumulado_descontado - (valor / ((1 + taxa_desconto) ** periodo)))
132
  return (periodo - 1) + (ultimo_fluxo_necessario / (valor / ((1 + taxa_desconto) ** periodo)))
133
  return np.inf
134
+
135
  @st.cache_data
136
  def simular_faturamento_bootstrap(_df_dados_mensais_numeric, precos_dict, cenarios_dict, eficiencia_geral_coleta, n_simulacoes=2000, seed=42):
137
  np.random.seed(seed)
 
143
  faturamento_liquido = faturamento_bruto_iteracao * eficiencia_geral_coleta * fator_cenario
144
  faturamentos_simulados[nome_cen].append(faturamento_liquido)
145
  return {nome: np.array(data) for nome, data in faturamentos_simulados.items()}
146
+
147
  def gerar_fluxo_caixa_projeto(investimento_inicial, receita_anual_base, custos_operacionais_anuais, horizonte_anos, taxa_crescimento):
148
  fluxo_caixa = [-abs(investimento_inicial)]
149
  for ano in range(1, horizonte_anos + 1):
 
152
  fluxo_caixa.append(fluxo_liquido_ano)
153
  return fluxo_caixa
154
 
155
+ # --- 4. CARREGAMENTO DE DADOS (sem alterações) ---
156
  @st.cache_data
157
  def carregar_dados():
158
  meses = ['Jan', 'Fev', 'Mar', 'Abr', 'Mai', 'Jun', 'Jul', 'Ago', 'Set', 'Out', 'Nov', 'Dez']
159
+ dados_2024 = {
160
+ 'Mes': meses, 'Papel_Papelao': [8047, 11287, 8184, 10183, 5699, 5830, 7465, 5600, 2960, 5175, 9656, 3960],
161
+ 'Plastico': [6353, 8771, 6993, 8050, 4880, 5296, 5937, 4747, 2446, 4109, 7667, 3367],
162
+ 'Metal': [1061, 2025, 1121, 1832, 716, 936, 1553, 904, 361, 630, 1904, 569],
163
+ 'Vidro': [5248, 6929, 6014, 5821, 3697, 3655, 4950, 3360, 1580, 3261, 6173, 2357]
164
+ }
165
  df_2024 = pd.DataFrame(dados_2024)
166
  df_2024_numeric = df_2024.drop(columns='Mes')
167
  dados_anuais = {'Ano': [2022, 2023, 2024], 'Papel_Papelao': [18780, 58718, df_2024_numeric['Papel_Papelao'].sum()], 'Plastico': [5340, 1041, df_2024_numeric['Plastico'].sum()], 'Metal': [1300, 1737, df_2024_numeric['Metal'].sum()], 'Vidro': [0, 725, df_2024_numeric['Vidro'].sum()]}
 
170
  custos_mensais_iniciais = {"Locacao_Maquina": 4400, "Coleta_Destinacao": 1400, "Outros": 500}
171
  return df_2024, df_anuais, precos_iniciais, df_2024_numeric, custos_mensais_iniciais
172
 
173
+ # --- 5. EXECUÇÃO INICIAL E SIDEBAR DE CONTROLES (com pequenos ajustes) ---
174
+ df_2024, df_anuais, precos_iniciais, df_2024_numeric, custos_mensais_iniciais = carregar_dados()
175
+
176
+ # Paleta de cores para os gráficos
177
+ PALETA_CORES_PROFISSIONAL = ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', '#9467bd', '#8c564b']
178
+
179
+ st.sidebar.title("♻️ Painel de Controle")
180
+ st.sidebar.markdown("Navegue pelas análises e ajuste as premissas do projeto.")
181
+ st.sidebar.divider()
182
 
183
+ pagina_selecionada = st.sidebar.radio(
184
+ "**Menu Principal**",
185
+ ["🔎 Análise Exploratória", "🎯 Simulação de Faturamento", "📊 Análise de Viabilidade"],
186
+ captions=["Dados históricos de coleta", "Projeções de receita", "Cálculos de VPL, TIR e Risco"]
187
+ )
188
+ st.sidebar.divider()
189
+
190
+ with st.sidebar.expander("⚙️ Premissas Financeiras", expanded=True):
191
+ investimento_inicial = st.number_input("Investimento Inicial (R$)", min_value=1000.0, value=5000.0, step=1000.0)
192
+ custos_operacionais_anuais = sum(custos_mensais_iniciais.values()) * 12
193
+ horizonte_projeto = st.slider("Horizonte do Projeto (anos)", 3, 20, 10)
194
+ taxa_desconto = st.slider("Taxa de Desconto (TMA) (%)", 5.0, 25.0, 12.0, 0.5) / 100
195
+ taxa_crescimento = st.slider("Crescimento Anual (%)", 0.0, 10.0, 3.0, 0.5) / 100
196
+ taxa_reinvestimento = st.slider("Taxa de Reinvestimento (MTIR) (%)", 2.0, 18.0, 10.0, 0.5) / 100
197
+
198
+ with st.sidebar.expander("📈 Premissas de Mercado", expanded=False):
199
+ eficiencia_coleta_geral = st.slider("Eficiência Geral da Coleta (%)", 0, 100, 30, help="Fator mestre que afeta a quantidade de material coletado.") / 100
200
+ st.markdown("**Preços dos Materiais (R$/kg)**")
201
+ precos_editaveis = {material: st.number_input(f"{material.replace('_', ' ')}", value=preco, step=0.1, key=f"preco_{material}") for material, preco in precos_iniciais.items()}
202
+ st.markdown("**Variação de Cenários (%)**")
203
+ fator_pessimista = st.slider("Cenário Pessimista", 50, 100, 80) / 100
204
+ fator_otimista = st.slider("Cenário Otimista", 100, 150, 115) / 100
205
+
206
+ st.sidebar.divider()
207
+ st.sidebar.info(f"Dados atualizados em: {pd.Timestamp.now(tz='America/Sao_Paulo').strftime('%d/%m/%Y %H:%M')}")
208
+
209
+ # --- 6. LÓGICA DE RENDERIZAÇÃO DAS PÁGINAS (com gráficos aprimorados) ---
210
+
211
+ if pagina_selecionada == "🔎 Análise Exploratória":
212
  st.title("🔎 Análise Exploratória dos Dados de Coleta")
213
+ st.markdown("O primeiro passo para uma projeção robusta é entender o passado. Aqui, exploramos os dados históricos de coleta para identificar padrões, tendências e pontos de atenção.")
214
  st.divider()
215
 
 
 
 
 
 
 
 
216
  col1, col2 = st.columns(2)
217
  with col1:
218
  st.subheader("Coleta Mensal por Material (2024)")
219
  df_melt_mensal = df_2024.melt(id_vars='Mes', var_name='Material', value_name='Quantidade (kg)')
220
+ fig_evol_mensal = px.line(
221
+ df_melt_mensal, x='Mes', y='Quantidade (kg)', color='Material',
222
+ title="Variação Mensal da Coleta por Material", markers=True,
223
+ color_discrete_sequence=PALETA_CORES_PROFISSIONAL
224
+ )
225
+ fig_evol_mensal.update_layout(legend_title_text='Material', plot_bgcolor='white', font_color='#333')
226
  st.plotly_chart(fig_evol_mensal, use_container_width=True)
227
+
228
  with col2:
229
  st.subheader("Distribuição da Coleta Mensal (2024)")
230
+ fig_boxplot = px.box(
231
+ df_melt_mensal, x='Material', y='Quantidade (kg)', color='Material',
232
+ title="Variação e Volatilidade da Coleta Mensal",
233
+ color_discrete_sequence=PALETA_CORES_PROFISSIONAL
234
+ )
235
+ fig_boxplot.update_layout(legend_title_text='Material', plot_bgcolor='white', font_color='#333')
236
  st.plotly_chart(fig_boxplot, use_container_width=True)
237
+
238
  st.info("O **gráfico de linhas** mostra a tendência e sazonalidade ao longo do ano. O **boxplot** revela a volatilidade de cada material: caixas mais 'altas' indicam maior variação mensal, o que se traduz em maior risco e incerteza no faturamento.")
239
+ st.divider()
240
+
241
+ st.subheader("Evolução da Coleta Total Anual (Histórico)")
242
+ df_coleta_anual = df_anuais.sum(axis=1).reset_index()
243
+ df_coleta_anual.columns = ['Ano', 'Coleta Total (kg)']
244
+ fig_evol_coleta = px.bar(
245
+ df_coleta_anual, x='Ano', y='Coleta Total (kg)', text_auto='.3s',
246
+ title="Volume Total Anual de Materiais Coletados"
247
+ )
248
+ fig_evol_coleta.update_traces(marker_color='#1f77b4')
249
+ fig_evol_coleta.update_layout(plot_bgcolor='white', font_color='#333')
250
+ st.plotly_chart(fig_evol_coleta, use_container_width=True)
251
+ st.warning("**Observação:** A queda na coleta em 2023, principalmente em Plástico, é um ponto crítico. É crucial investigar se isso reflete a realidade operacional ou uma anomalia nos dados antes de basear decisões estratégicas nessas projeções.")
252
+
253
 
254
+ elif pagina_selecionada == "🎯 Simulação de Faturamento":
 
255
  st.title("🎯 Simulação e Projeção de Faturamento Anual")
256
+ st.markdown("Utilizando a técnica de *bootstrapping*, simulamos 2.000 possíveis anos de faturamento com base na volatilidade histórica e nas premissas de preço e eficiência definidas.")
257
  st.divider()
258
+
259
+ cenarios = {'Pessimista': fator_pessimista, 'Base': 1.0, 'Otimista': fator_otimista}
260
  simulacoes_faturamento = simular_faturamento_bootstrap(df_2024_numeric, precos_editaveis, cenarios, eficiencia_coleta_geral)
261
+
262
  kpi1, kpi2, kpi3 = st.columns(3)
263
  media_faturamento_base = np.mean(simulacoes_faturamento['Base'])
264
  desvio_padrao_base = np.std(simulacoes_faturamento['Base'])
 
266
  material_mais_rentavel = max(faturamento_material_base, key=faturamento_material_base.get)
267
 
268
  kpi1.metric("Faturamento Anual Médio (Base)", formatar_brl(media_faturamento_base))
269
+ kpi2.metric("Risco do Faturamento (DP)", formatar_brl(desvio_padrao_base), help="Desvio Padrão. Mede a volatilidade do faturamento. Valores mais altos indicam maior incerteza.")
270
+ kpi3.metric("Principal Material (Receita)", material_mais_rentavel.replace('_', ' '))
271
  st.divider()
272
+
273
+ col_g1, col_g2 = st.columns([3, 2])
274
  with col_g1:
275
  st.subheader("Distribuição do Faturamento Anual Simulado")
276
  fig_dist = go.Figure()
277
+ cores_cenario = {'Pessimista': '#d62728', 'Base': '#1f77b4', 'Otimista': '#2ca02c'}
278
  for nome, data in simulacoes_faturamento.items():
279
+ fig_dist.add_trace(go.Histogram(
280
+ x=data, name=nome, histnorm='probability density',
281
+ marker_color=cores_cenario[nome], opacity=0.7
282
+ ))
283
+ fig_dist.update_layout(
284
+ barmode='overlay', title_text="Comparativo de Cenários de Faturamento",
285
+ xaxis_title="Faturamento Anual (R$)", yaxis_title="Probabilidade",
286
+ legend_title_text='Cenário', plot_bgcolor='white', font_color='#333'
287
+ )
288
+ fig_dist.update_traces(opacity=0.75)
289
  st.plotly_chart(fig_dist, use_container_width=True)
290
+
291
  with col_g2:
292
+ st.subheader("Composição da Receita (Cenário Base)")
293
  df_faturamento_material = pd.DataFrame(list(faturamento_material_base.items()), columns=['Material', 'Faturamento'])
294
+ fig_comp = px.pie(
295
+ df_faturamento_material, values='Faturamento', names='Material',
296
+ hole=0.4, title="Faturamento por Material",
297
+ color_discrete_sequence=PALETA_CORES_PROFISSIONAL
298
+ )
299
+ fig_comp.update_layout(legend_title_text='Material', plot_bgcolor='white', font_color='#333')
300
  st.plotly_chart(fig_comp, use_container_width=True)
301
 
302
+
303
+ elif pagina_selecionada == "📊 Análise de Viabilidade":
304
  st.title("📊 Análise de Viabilidade Financeira e Risco")
305
+ st.markdown("Esta é a etapa final, onde combinamos as projeções de receita com as premissas de investimento e custos para avaliar a viabilidade do projeto sob a ótica de risco.")
306
+
307
+ cenarios = {'Pessimista': fator_pessimista, 'Base': 1.0, 'Otimista': fator_otimista}
308
  simulacoes_faturamento = simular_faturamento_bootstrap(df_2024_numeric, precos_editaveis, cenarios, eficiencia_coleta_geral)
309
+
310
+ st.info("Selecione o cenário para a análise detalhada dos indicadores e do fluxo de caixa.")
311
+ cenario_analise = st.radio(
312
+ "**Selecione o cenário para a análise detalhada:**",
313
+ options=list(cenarios.keys()), index=1, horizontal=True, label_visibility="collapsed"
314
+ )
315
  st.divider()
316
+
317
  receita_anual_media = np.mean(simulacoes_faturamento[cenario_analise])
318
  fluxo_caixa_projeto = gerar_fluxo_caixa_projeto(investimento_inicial, receita_anual_media, custos_operacionais_anuais, horizonte_projeto, taxa_crescimento)
319
+
320
  vpl = calcular_vpl(fluxo_caixa_projeto, taxa_desconto)
321
  tir = calcular_tir(fluxo_caixa_projeto)
322
  mtir = calcular_mtir(fluxo_caixa_projeto, taxa_desconto, taxa_reinvestimento)
323
  payback_desc = calcular_payback_descontado(fluxo_caixa_projeto, taxa_desconto)
324
+
325
+ tab_kpis, tab_fluxo, tab_risco, tab_resumo = st.tabs(["📈 Indicadores Chave", "📂 Fluxo de Caixa", "🎲 Análise de Risco", "📋 Resumo Executivo"])
326
 
327
  with tab_kpis:
328
+ st.subheader(f"Indicadores Financeiros para o Cenário: {cenario_analise}")
329
  col1, col2, col3, col4 = st.columns(4)
330
+ col1.metric("VPL (Valor Presente Líquido)", formatar_brl(vpl), "Viável" if vpl >= 0 else "Inviável", delta_color="off")
331
+ col2.metric("TIR (Taxa Interna de Retorno)", formatar_percentual(tir), "Acima da TMA" if pd.notna(tir) and tir > taxa_desconto else "Abaixo da TMA", delta_color="off")
332
+ col3.metric("MTIR (TIR Modificada)", formatar_percentual(mtir), "Acima da TMA" if pd.notna(mtir) and mtir > taxa_desconto else "Abaixo da TMA", delta_color="off")
333
+ col4.metric("Payback Descontado", f"{payback_desc:.1f} anos" if not np.isinf(payback_desc) else "Não recupera", help="Tempo para recuperar o investimento inicial.")
334
 
335
  with tab_fluxo:
336
  st.subheader("Visualização do Fluxo de Caixa do Projeto")
337
  df_fluxo = pd.DataFrame({'Ano': list(range(horizonte_projeto + 1)), 'Fluxo de Caixa': fluxo_caixa_projeto})
338
  df_fluxo['Fluxo Acumulado'] = df_fluxo['Fluxo de Caixa'].cumsum()
339
+ fig_fluxo = go.Figure(data=[
340
+ go.Bar(name='Fluxo Anual', x=df_fluxo['Ano'], y=df_fluxo['Fluxo de Caixa'], marker_color=['#d62728' if x < 0 else '#2ca02c' for x in df_fluxo['Fluxo de Caixa']]),
341
+ go.Scatter(name='Fluxo Acumulado', x=df_fluxo['Ano'], y=df_fluxo['Fluxo Acumulado'], mode='lines+markers', line=dict(color='#1f77b4', width=3))
342
+ ])
343
+ fig_fluxo.update_layout(
344
+ title_text="Fluxo de Caixa Anual e Acumulado",
345
+ hovermode='x unified', plot_bgcolor='white', font_color='#333'
346
+ )
347
  st.plotly_chart(fig_fluxo, use_container_width=True)
348
 
349
  with tab_risco:
350
+ st.subheader(f"Análise de Risco do VPL (Simulação de Monte Carlo)")
351
+ st.markdown(f"Executamos 5.000 simulações baseadas na distribuição de receitas do **cenário {cenario_analise}** para entender a probabilidade de sucesso do projeto.")
352
  receitas_mc = np.random.choice(simulacoes_faturamento[cenario_analise], size=5000, replace=True)
353
  vpls_mc = [calcular_vpl(gerar_fluxo_caixa_projeto(investimento_inicial, r, custos_operacionais_anuais, horizonte_projeto, taxa_crescimento), taxa_desconto) for r in receitas_mc]
354
  prob_viabilidade = (np.array(vpls_mc) >= 0).mean()
355
  vpl_medio_mc = np.mean(vpls_mc)
356
  vpl_std_mc = np.std(vpls_mc)
357
+
358
  mc1, mc2, mc3 = st.columns(3)
359
  mc1.metric("VPL Médio Simulado", formatar_brl(vpl_medio_mc))
360
+ mc2.metric("Probabilidade de Viabilidade", formatar_percentual(prob_viabilidade), help="Percentual de simulações com VPL >= 0.")
361
+ mc3.metric("Risco do VPL (DP)", formatar_brl(vpl_std_mc), help="Mede a volatilidade ou risco do VPL.")
362
+
363
  fig_mc = px.histogram(x=vpls_mc, nbins=50, title=f"Distribuição do VPL ({len(vpls_mc)} Simulações)")
364
+ fig_mc.add_vline(x=0, line_dash="dash", line_color="red", annotation_text="Ponto de Viabilidade")
365
+ fig_mc.update_layout(xaxis_title="VPL (R$)", yaxis_title="Frequência", plot_bgcolor='white', font_color='#333')
366
  st.plotly_chart(fig_mc, use_container_width=True)
367
 
368
  with tab_resumo:
369
  st.subheader("Resumo Executivo e Parecer Final")
370
+ st.markdown(f"Análise consolidada com base no **cenário {cenario_analise}**.")
371
+
372
+ if vpl > 0 and prob_viabilidade > 0.75:
373
+ st.success("**RECOMENDAÇÃO: APROVAR.** O projeto demonstra forte viabilidade financeira (VPL positivo e TIR acima da TMA) e robustez, com uma alta probabilidade de sucesso superior a 75% na simulação de risco.")
374
+ elif vpl > 0 and prob_viabilidade > 0.5:
375
+ st.warning("**RECOMENDAÇÃO: APROVAR COM CAUTELA.** Embora o cenário base seja viável, a probabilidade de sucesso é moderada. Recomenda-se um plano de mitigação para os riscos de receita, garantindo que as metas de coleta sejam atingidas.")
376
+ else:
377
+ st.error("**RECOMENDAÇÃO: REAVALIAR/REJEITAR.** Os indicadores financeiros, combinados com um perfil de risco elevado (baixa probabilidade de VPL positivo), não sustentam o investimento nas condições atuais. É crucial revisar as premissas de custos, receitas ou o investimento inicial.")
378
+
379
+ st.markdown("---")
380
+ st.markdown("#### Detalhes da Análise:")
381
  conclusoes = []
382
+ if vpl >= 0:
383
+ conclusoes.append(f"<li><span style='color: {PALETA_CORES_PROFISSIONAL[2]};'>✔</span> **Viabilidade Financeira:** O projeto é considerado **VIÁVEL** com um VPL de **{formatar_brl(vpl)}**.</li>")
384
+ else:
385
+ conclusoes.append(f"<li><span style='color: {PALETA_CORES_PROFISSIONAL[3]};'>❌</span> **Viabilidade Financeira:** O projeto é **INVIÁVEL** com um VPL negativo de **{formatar_brl(vpl)}**.</li>")
386
+
387
+ if not pd.isna(tir) and tir > taxa_desconto:
388
+ conclusoes.append(f"<li><span style='color: {PALETA_CORES_PROFISSIONAL[2]};'>✔</span> **Atratividade do Retorno:** A TIR de **{formatar_percentual(tir)}** supera a TMA de {formatar_percentual(taxa_desconto)}, reforçando a atratividade.</li>")
389
+ else:
390
+ conclusoes.append(f"<li><span style='color: {PALETA_CORES_PROFISSIONAL[3]};'>❌</span> **Atratividade do Retorno:** A TIR de **{formatar_percentual(tir)}** é inferior à TMA, um forte indicador contra o projeto.</li>")
391
+
392
+ if prob_viabilidade > 0.75:
393
+ conclusoes.append(f"<li><span style='color: {PALETA_CORES_PROFISSIONAL[2]};'>✔</span> **Análise de Risco:** A simulação aponta uma **alta probabilidade de sucesso de {formatar_percentual(prob_viabilidade)}**, conferindo robustez à decisão.</li>")
394
+ elif prob_viabilidade > 0.5:
395
+ conclusoes.append(f"<li><span style='color: {PALETA_CORES_PROFISSIONAL[1]};'>⚠️</span> **Análise de Risco:** A probabilidade de sucesso de **{formatar_percentual(prob_viabilidade)} é moderada**, indicando sensibilidade às variações.</li>")
396
+ else:
397
+ conclusoes.append(f"<li><span style='color: {PALETA_CORES_PROFISSIONAL[3]};'>❌</span> **Análise de Risco:** A probabilidade de sucesso de **{formatar_percentual(prob_viabilidade)} é baixa**, indicando um risco elevado.</li>")
398
+
399
+ st.markdown("<ul>" + "".join(conclusoes) + "</ul>", unsafe_allow_html=True)