import streamlit as st
import json
import os
import numpy as np
import plotly.graph_objs as go
from groq import Groq
from dotenv import load_dotenv
load_dotenv() # load .env file
GROQ_API_KEY = os.environ.get("GROQ_API_KEY")
# --- CONFIG ---
GROQ_MODEL = "llama3-70b-8192"
groq_client = Groq(api_key=GROQ_API_KEY)
PERSONA_PATH = os.getenv("PERSONA_PATH", "/tmp/personas.json")
# --- THEME COLORS ---
neon_blue = "#00fff7"
neon_green = "#7CFC00"
neon_pink = "#F72585"
neon_cyan = "#0ffcff"
neon_bg = "#181830"
neon_orange = "#FFB347"
neon_shadow = "#2dfdff44"
font_main = "Inter, Segoe UI, Arial, sans-serif"
st.set_page_config(page_title="🚀 New Launch Studio", layout="wide", initial_sidebar_state="collapsed")
# Set dark theme programmatically
st.markdown(
"""
""",
unsafe_allow_html=True
)
# --- STYLE ---
st.markdown(f"""
""", unsafe_allow_html=True)
# --- TITLE & DESCRIPTION ---
st.markdown(f"
Will your next product idea actually vibe with your audience? Pop your concept below and instantly see what your customer personas think—no fluff, just punchy, actionable feedback and a reality check on your launch.
", unsafe_allow_html=True)
st.markdown(f"⚡ Heads up: Our demo and market data is based on protein powder reviews—so for best results, enter a health, nutrition, or supplement product!
", unsafe_allow_html=True)
# --- NAVIGATION BUTTONS ---
st.markdown(f"""
", unsafe_allow_html=True)
st.markdown("
", unsafe_allow_html=True)
st.markdown(f"
{section_icons['Probable Reaction']} Probable Reaction
", unsafe_allow_html=True)
reactions = ai_points(
f"Summarize two brief but complete points for this persona's likely reaction to the product: {product_desc}. Use clear, direct language.",
max_points=2, max_tokens=90
)
st.markdown(f"
" + "".join([f"- {r}
" for r in reactions]) + "
", unsafe_allow_html=True)
st.markdown(f"
{section_icons['Alignment with Persona']} Alignment with Persona
", unsafe_allow_html=True)
aligns = ai_points(
f"List two specific ways this persona's characteristics or needs will match with the features or benefits of the product: {product_desc}. "
f"Be explicit: mention which part of the persona is satisfied by which product feature. Use clear, direct language.",
max_points=2, max_tokens=100
)
st.markdown(f"
" + "".join([f"- {a}
" for a in aligns]) + "
", unsafe_allow_html=True)
st.markdown("
", unsafe_allow_html=True)
st.markdown("
", unsafe_allow_html=True)
st.markdown(f"
{section_icons['Potential Mismatches or Concerns']} Potential Mismatches or Concerns
", unsafe_allow_html=True)
mismatches = ai_points(
f"List two precise concerns or mismatches: Which features or aspects of the {product_desc} may NOT align with this persona's preferences or needs? "
f"Be explicit: mention which product feature is likely to be a turn-off or ignored by this persona.",
max_points=2, max_tokens=100
)
st.markdown(f"
" + "".join([f"- {m}
" for m in mismatches]) + "
", unsafe_allow_html=True)
st.markdown(f"
{section_icons['Marketing Strategy']} Marketing Strategy
", unsafe_allow_html=True)
strategy = ai_points(
f"Suggest two creative, product-specific marketing strategies targeted at this persona for this product: {product_desc}. "
f"Each point must clearly connect a product feature with a unique marketing approach for this persona.",
max_points=2, max_tokens=100
)
st.markdown(f"
" + "".join([f"- {s}
" for s in strategy]) + "
", unsafe_allow_html=True)
st.markdown("
", unsafe_allow_html=True)
st.markdown("
", unsafe_allow_html=True)
st.markdown(
f"""
Interest Likelihood: {ai_percent('Estimate the likelihood (percent) that '+persona['name']+' would be interested in this product. Just the number and % sign, nothing else.')}
{section_icons['Personalized Notification']} Personalized Notification
{ai_notification(
f"Write a concise, energetic notification or email about this product: {product_desc} aimed specifically at the persona {persona['name']}. "
f"Address their top motivations and finish with a strong call-to-action. No names, no symbols."
)}
""", unsafe_allow_html=True
)
st.markdown("
", unsafe_allow_html=True)
# --- CHARTS (Demo) ---
st.markdown(f"
3. Projected Market Impact
", unsafe_allow_html=True)
persona_names = [p['name'] for p in personas]
np.random.seed(42)
projected_market_share = np.random.dirichlet(np.ones(len(persona_names)), size=1)[0]
projected_sentiment = projected_market_share * 0.6 + np.random.rand(len(persona_names)) * 0.4 # correlation
c1, c2 = st.columns(2)
with c1:
st.markdown(f"
Projected Market Share by Persona
", unsafe_allow_html=True)
fig1 = go.Figure(data=[go.Pie(labels=persona_names, values=projected_market_share, hole=0.45)])
fig1.update_traces(textinfo='percent+label')
fig1.update_layout(margin=dict(l=14, r=14, b=14, t=14), showlegend=True)
st.plotly_chart(fig1, use_container_width=True)
with c2:
st.markdown(f"
Projected Sentiment by Persona
", unsafe_allow_html=True)
fig2 = go.Figure(data=[go.Bar(x=persona_names, y=projected_sentiment,
marker=dict(color=[neon_green, neon_blue, neon_pink, neon_orange, neon_cyan][:len(persona_names)]))])
fig2.update_layout(xaxis_title="Persona", yaxis_title="Projected Sentiment", font=dict(size=15))
st.plotly_chart(fig2, use_container_width=True)
# --- Combined Chart Insights ---
combined_prompt = (
f"Given the projected market share {list(np.round(projected_market_share*100,1))} percent and projected sentiment {list(np.round(projected_sentiment*100,1))} for these personas: {', '.join(persona_names)}, "
"summarize 4 concise points that correlate the two charts and reveal the most important market insights. Each point should be in a new line and fully written."
)
insights = ai_graph_insights(combined_prompt, max_tokens=200)
st.markdown(
f"
Key Combined Insights
"
f"
" + "".join([f"- {bp}
" for bp in insights]) + "
", unsafe_allow_html=True
)
# --- OVERALL SUMMARY ---
st.markdown(f"
4. Overall Summary
", unsafe_allow_html=True)
overall_prompt = (
f"Given these personas: {', '.join([p['name'] for p in personas])}, and the new product: {product_desc}, "
"write a concise executive summary (3 sentences, no intro, no asterisks), focusing on overall fit, the main challenge, and the best next move for launch."
)
summary_text = ai_summary(overall_prompt, max_tokens=1000)
st.markdown(
f"
{summary_text}
",
unsafe_allow_html=True
)
st.markdown("---")
elif test_btn:
st.warning("Please enter your product description to see the results.")