2026-10-22 17:20:44 +05:30
"""
app.py
2026-10-27 10:23:02 +05:30
HIFFI Artist Intelligence - Multi-Platform Executive Dashboard
Clean dark-themed design with multi-platform evidence tiers, Spotify & Instagram telemetry,
2026-10-30 11:10:54 +05:30
ChartMasters record sales (CSPC/EAS), breakout velocity index, deep-dive scouting dossier,
and experimental Commercial Power Index (CPI) simulation engine with sensitivity analysis.
2026-10-22 17:20:44 +05:30
"""
2026-10-27 10:23:02 +05:30
from pathlib import Path
2026-10-22 17:20:44 +05:30
import pandas as pd
import plotly.express as px
2026-10-28 17:07:19 +05:30
import plotly.graph_objects as go
2026-10-22 17:20:44 +05:30
import streamlit as st
2026-10-30 11:10:54 +05:30
from core.cpi_engine import CommercialPowerEngine
from exporters.excel_workbook import generate_executive_sales_workbook
2026-10-22 17:20:44 +05:30
st . set_page_config (
2026-10-27 10:23:02 +05:30
page_title = "HIFFI | Multi-Platform Intelligence" ,
2026-10-22 17:20:44 +05:30
page_icon = "⚡" ,
layout = "wide" ,
initial_sidebar_state = "expanded" ,
)
2026-10-27 10:23:02 +05:30
DATA_PATH = Path ( "data/hiffi_multiplatform_500.csv" )
FALLBACK_DATA_PATH = Path ( "enriched_artists.csv" )
2026-10-22 17:20:44 +05:30
2026-10-30 11:10:54 +05:30
# Global CSS Styling
2026-10-22 17:20:44 +05:30
st . markdown (
"""
<style>
.block-container {
padding-top: 1.8rem;
padding-bottom: 2.5rem;
padding-left: 2.5rem;
padding-right: 2.5rem;
max-width: 100% !important;
}
/* KPI Cards */
.kpi-box {
background: #111827;
border: 1px solid #1f2937;
border-radius: 12px;
padding: 16px 20px;
margin-bottom: 12px;
}
.kpi-title {
font-size: 0.75rem;
font-weight: 700;
color: #9ca3af;
text-transform: uppercase;
letter-spacing: 0.05em;
}
.kpi-value {
font-size: 1.9rem;
font-weight: 800;
color: #f9fafb;
margin: 4px 0;
}
.kpi-subtitle {
font-size: 0.75rem;
color: #6b7280;
}
2026-10-30 11:10:54 +05:30
/* Telemetry Coverage Banner */
.coverage-card {
background: #0f172a;
border: 1px solid #1e293b;
border-radius: 8px;
padding: 12px 18px;
margin-bottom: 16px;
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
}
/* Simulation Micro-Cards */
.sim-kpi-card {
background: #0f172a;
border: 1px solid #334155;
border-radius: 8px;
padding: 10px 14px;
margin-bottom: 10px;
}
.sim-kpi-title {
font-size: 0.68rem;
font-weight: 700;
color: #94a3b8;
text-transform: uppercase;
}
.sim-kpi-val {
font-size: 1.25rem;
font-weight: 800;
margin-top: 2px;
}
2026-10-22 17:20:44 +05:30
/* Podium Cards */
.podium-tile {
background: #111827;
border-radius: 12px;
padding: 18px 20px;
border: 1px solid #1f2937;
height: 100%;
}
.podium-gold { border-top: 4px solid #f59e0b; }
.podium-silver { border-top: 4px solid #94a3b8; }
.podium-bronze { border-top: 4px solid #f97316; }
2026-10-30 11:10:54 +05:30
/* Badges */
2026-10-22 17:20:44 +05:30
.badge {
display: inline-block;
padding: 3px 8px;
border-radius: 6px;
font-size: 0.70rem;
font-weight: 700;
text-transform: uppercase;
}
2026-10-27 10:23:02 +05:30
.badge-tier3 { background: rgba(16, 185, 129, 0.2); color: #10b981; }
.badge-tier2 { background: rgba(56, 189, 248, 0.2); color: #38bdf8; }
.badge-tier1 { background: rgba(245, 158, 11, 0.2); color: #f59e0b; }
.badge-dormant { background: rgba(239, 68, 68, 0.2); color: #ef4444; }
2026-10-22 17:20:44 +05:30
.custom-divider {
height: 1px;
background: #1f2937;
margin: 24px 0;
}
</style>
""" ,
unsafe_allow_html = True ,
)
@st.cache_data ( ttl = 60 )
def load_data ():
2026-10-27 10:23:02 +05:30
target = DATA_PATH if DATA_PATH . exists () else FALLBACK_DATA_PATH
if not target . exists ():
2026-10-22 17:20:44 +05:30
return pd . DataFrame ()
2026-10-27 10:23:02 +05:30
df = pd . read_csv ( target )
if "hiffi_xp_published_rank" not in df . columns :
df [ "hiffi_xp_published_rank" ] = df . get ( "hiffi_xp_rank" , df . get ( "hiffi_rank" , df . index + 1 ))
if "hiffi_xp_score" not in df . columns :
df [ "hiffi_xp_score" ] = df . get ( "production_hiffi_score" , df . get ( "hiffi_score" , 0.0 ))
if "platform_evidence_tier" not in df . columns :
has_yt = df . get ( "production_hiffi_score" , df . get ( "hiffi_score" )) . notna () . astype ( int )
has_sp = df . get ( "spotify_monthly_listeners" , pd . Series ( index = df . index )) . notna () . astype ( int )
has_ig = df . get ( "instagram_followers" , pd . Series ( index = df . index )) . notna () . astype ( int )
df [ "platform_evidence_tier" ] = has_yt + has_sp + has_ig
2026-10-22 17:20:44 +05:30
numeric_cols = [
2026-10-27 10:23:02 +05:30
"hiffi_xp_published_rank" ,
"hiffi_xp_rank" ,
"hiffi_xp_score" ,
"production_hiffi_rank" ,
"production_hiffi_score" ,
"platform_evidence_tier" ,
2026-10-22 17:20:44 +05:30
"breakout_velocity_index" ,
"subscriber_count" ,
"daily_view_velocity" ,
"momentum_30d" ,
2026-10-27 10:23:02 +05:30
"spotify_monthly_listeners" ,
"spotify_daily_change" ,
"instagram_followers" ,
2026-10-22 17:20:44 +05:30
"confidence_score" ,
2026-10-28 17:07:19 +05:30
"breakout_rank" ,
"chartmasters_sales_rank" ,
"cohort_sales_rank" ,
"pure_album_sales" ,
"physical_singles_sales" ,
"digital_singles_sales" ,
"streaming_eas" ,
"total_eas_cspc" ,
2026-10-30 11:10:54 +05:30
"riaa_certified_album_units" ,
"riaa_certified_singles_units" ,
2026-10-22 17:20:44 +05:30
]
for col in numeric_cols :
if col in df . columns :
df [ col ] = pd . to_numeric ( df [ col ], errors = "coerce" )
2026-10-23 10:52:54 +05:30
2026-10-30 11:10:54 +05:30
# Commercial Power Engine
engine = CommercialPowerEngine ()
df [ "commercial_power_index" ] = engine . calculate_cpi ( df )
2026-10-23 10:52:54 +05:30
if "subgenre" not in df . columns :
def infer_subgenre ( r ):
subs = r . get ( "subscriber_count" , 0 ) or 0
bvi = r . get ( "breakout_velocity_index" , 0 ) or 0
if bvi >= 70 :
return "Breakout / Emerging"
elif subs >= 15000000 :
return "Legends"
else :
return "Trap & Street"
df [ "subgenre" ] = df . apply ( infer_subgenre , axis = 1 )
2026-10-22 17:20:44 +05:30
return df
df = load_data ()
2026-10-30 11:10:54 +05:30
engine = CommercialPowerEngine ()
def get_provenance_badge ( status : str ) -> str :
"""Format status values into readable provenance labels."""
s = str ( status ) . strip ()
if s == "VERIFIED_CSPC" :
return "✅ VERIFIED (CSPC)"
elif s == "VERIFIED_RIAA" :
return "🏅 VERIFIED (RIAA)"
elif s == "ESTIMATED_SEA" :
return "📊 ESTIMATED (SEA)"
return "⏳ PENDING_INGESTION"
2026-10-22 17:20:44 +05:30
# ----------------- Sidebar Controls -----------------
with st . sidebar :
2026-10-27 10:23:02 +05:30
st . markdown ( "### ⚡ HIFFI Multi-Platform" )
2026-10-30 11:10:54 +05:30
st . caption ( "YouTube • Spotify • Instagram • Sales Telemetry" )
2026-10-22 17:20:44 +05:30
st . markdown ( "<div class='custom-divider'></div>" , unsafe_allow_html = True )
if df . empty :
2026-10-30 11:10:54 +05:30
st . error ( "No dataset found. Run pipeline to generate master data." )
2026-10-22 17:20:44 +05:30
st . stop ()
view_mode = st . radio (
"Leaderboard Perspective:" ,
2026-10-28 17:07:19 +05:30
[
"🏆 Published Multi-Platform Rank" ,
"🚀 Breakout Velocity (BVI)" ,
2026-10-30 11:10:54 +05:30
"💿 Record Sales (CSPC Methodology)" ,
"🧪 Commercial Simulation Engine (CPI)" ,
2026-10-28 17:07:19 +05:30
"🔍 Full Cohort Audit Grid" ,
],
2026-10-22 17:20:44 +05:30
index = 0 ,
)
st . markdown ( "<div class='custom-divider'></div>" , unsafe_allow_html = True )
2026-10-30 11:10:54 +05:30
catalog_filter = "All Monitored Artists (500)"
if view_mode in ( "💿 Record Sales (CSPC Methodology)" , "🧪 Commercial Simulation Engine (CPI)" ):
st . markdown ( "##### 🔍 Sales Catalog Scope" )
catalog_filter = st . radio (
"Filter Rows by Sales Telemetry:" ,
[ "All Monitored Artists (500)" , "Verified Only (321)" , "Pure CSPC Only (62)" ],
index = 0 ,
help = "Toggle between viewing the full cohort, verified certifications, or only ChartMasters studies." ,
)
st . markdown ( "<div class='custom-divider'></div>" , unsafe_allow_html = True )
sim_weight = 0.15
sim_mode = "matched_only"
if view_mode == "🧪 Commercial Simulation Engine (CPI)" :
st . markdown ( "##### 🧪 Simulation Parameters" )
sim_mode_choice = st . radio (
"Evaluation Scope:" ,
[ "🎯 Matched Cohort Only" , "🌐 Global Cohort (N=500, Weight Redistribution)" ],
index = 1 if catalog_filter == "All Monitored Artists (500)" else 0 ,
help = "Matched Cohort evaluates cataloged artists in an isolated leaderboard. Global Cohort keeps all artists with normalized weights." ,
)
sim_mode = "matched_only" if "Matched" in sim_mode_choice else "global_redistribution"
sim_weight = st . select_slider (
"Commercial Signal Weight:" ,
options = [ 0.0 , 0.05 , 0.10 , 0.15 , 0.20 ],
value = 0.15 ,
format_func = lambda x : f " { int ( x * 100 ) } % Commercial" ,
help = "Blends Commercial Power Index (CPI) with baseline production score." ,
)
st . caption ( f "Baseline Score Weight: ** { int (( 1.0 - sim_weight ) * 100 ) } %**" )
st . markdown ( "<div class='custom-divider'></div>" , unsafe_allow_html = True )
st . markdown ( "##### 🛡️ Cohort Filters" )
2026-10-23 10:52:54 +05:30
all_verticals = sorted ( df [ "subgenre" ] . dropna () . unique () . tolist ())
2026-10-27 10:23:02 +05:30
selected_verticals = st . multiselect ( "Vertical" , options = all_verticals , default = all_verticals )
2026-10-23 10:52:54 +05:30
2026-10-27 10:23:02 +05:30
tier_options = sorted ( df [ "platform_evidence_tier" ] . dropna () . unique () . astype ( int ) . tolist (), reverse = True )
selected_tiers = st . multiselect ( "Evidence Tier" , options = tier_options , default = tier_options )
2026-10-22 17:20:44 +05:30
2026-10-27 10:23:02 +05:30
min_xp = st . slider ( "Min HIFFI-XP Score" , 0.0 , 100.0 , 0.0 , 5.0 )
2026-10-22 17:20:44 +05:30
2026-10-30 11:10:54 +05:30
# Filter logic
2026-10-22 17:20:44 +05:30
filtered_df = df [
2026-10-27 10:23:02 +05:30
( df [ "subgenre" ] . isin ( selected_verticals ))
& ( df [ "platform_evidence_tier" ] . isin ( selected_tiers ))
& ( df [ "hiffi_xp_score" ] . fillna ( 0.0 ) >= min_xp )
2026-10-22 17:20:44 +05:30
] . copy ()
2026-10-30 11:10:54 +05:30
if catalog_filter == "Pure CSPC Only (62)" :
filtered_df = filtered_df [ filtered_df [ "sales_data_status" ] == "VERIFIED_CSPC" ] . copy ()
elif catalog_filter == "Verified Only (321)" :
filtered_df = filtered_df [ filtered_df [ "sales_data_status" ] . isin ([ "VERIFIED_CSPC" , "VERIFIED_RIAA" ])] . copy ()
# Execute simulation calculations if chosen
sim_metrics = {}
if view_mode == "🧪 Commercial Simulation Engine (CPI)" :
filtered_df = engine . simulate_ranking ( filtered_df , commercial_weight = sim_weight , mode = sim_mode )
sim_metrics = engine . compute_simulation_metrics ( filtered_df )
2026-10-23 10:52:54 +05:30
with st . sidebar :
st . markdown ( "<div class='custom-divider'></div>" , unsafe_allow_html = True )
2026-10-30 11:10:54 +05:30
st . markdown ( "##### 💾 Unified Audit Exports" )
excel_workbook_bytes = generate_executive_sales_workbook ( filtered_df , commercial_weight = sim_weight , mode = sim_mode )
st . download_button (
"📊 Multi-Tab Audit Excel (.xlsx)" ,
data = excel_workbook_bytes ,
file_name = "hiffi_executive_sales_audit.xlsx" ,
mime = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" ,
width = "stretch" ,
)
2026-10-27 10:23:02 +05:30
2026-10-23 10:52:54 +05:30
csv_payload = filtered_df . to_csv ( index = False ) . encode ( "utf-8" )
2026-10-30 11:10:54 +05:30
st . download_button (
"📥 Filtered Table CSV" ,
2026-10-23 10:52:54 +05:30
data = csv_payload ,
2026-10-27 10:23:02 +05:30
file_name = "hiffi_multiplatform_filtered.csv" ,
2026-10-23 10:52:54 +05:30
mime = "text/csv" ,
2026-10-27 10:23:02 +05:30
width = "stretch" ,
2026-10-23 10:52:54 +05:30
)
st . markdown ( "<div class='custom-divider'></div>" , unsafe_allow_html = True )
2026-10-30 11:10:54 +05:30
st . caption ( "Governance: CSPC Methodology • EAS Units • Zero-Imputation Compliant" )
2026-10-23 10:52:54 +05:30
2026-10-22 17:20:44 +05:30
# ----------------- Main Header -----------------
head_col1 , head_col2 = st . columns ([ 3 , 1 ])
with head_col1 :
2026-10-27 10:23:02 +05:30
st . markdown ( "<h2 style='margin-bottom: 2px;'>HIFFI Multi-Platform Intelligence Hub</h2>" , unsafe_allow_html = True )
2026-10-28 17:07:19 +05:30
st . markdown ( "<p style='color: #9ca3af; font-size: 0.92rem; margin-top: 0;'>Multi-platform composite rankings with zero-imputation policy, dynamic weight redistribution, and verified record sales.</p>" , unsafe_allow_html = True )
2026-10-22 17:20:44 +05:30
with head_col2 :
st . markdown (
2026-10-27 10:23:02 +05:30
f "<div style='text-align: right; color: #6b7280; font-size: 0.8rem; padding-top: 10px;'>Filtered Cohort: <b> { len ( filtered_df ) } / { len ( df ) } </b> artists</div>" ,
2026-10-22 17:20:44 +05:30
unsafe_allow_html = True ,
)
2026-10-30 11:10:54 +05:30
# ----------------- Macro KPI Cards -----------------
2026-10-28 17:07:19 +05:30
k1 , k2 , k3 , k4 , k5 = st . columns ( 5 )
2026-10-22 17:20:44 +05:30
with k1 :
2026-10-30 11:10:54 +05:30
st . markdown ( f '<div class="kpi-box"><div class="kpi-title">Tracked Artists</div><div class="kpi-value"> { len ( df ) } </div><div class="kpi-subtitle">Monitored Cohort</div></div>' , unsafe_allow_html = True )
2026-10-22 17:20:44 +05:30
with k2 :
2026-10-27 10:23:02 +05:30
t3_count = len ( df [ df [ "platform_evidence_tier" ] == 3 ])
2026-10-30 11:10:54 +05:30
st . markdown ( f '<div class="kpi-box"><div class="kpi-title" style="color: #10b981;">Tier 3 (Complete)</div><div class="kpi-value" style="color: #10b981;"> { t3_count } </div><div class="kpi-subtitle">YouTube + Spotify + Instagram</div></div>' , unsafe_allow_html = True )
2026-10-22 17:20:44 +05:30
with k3 :
2026-10-27 10:23:02 +05:30
sp_count = df [ "spotify_monthly_listeners" ] . notna () . sum ()
2026-10-30 11:10:54 +05:30
st . markdown ( f '<div class="kpi-box"><div class="kpi-title" style="color: #38bdf8;">Spotify Telemetry</div><div class="kpi-value" style="color: #38bdf8;"> { sp_count } </div><div class="kpi-subtitle">Verified monthly listeners</div></div>' , unsafe_allow_html = True )
2026-10-22 17:20:44 +05:30
with k4 :
2026-10-27 10:23:02 +05:30
ig_count = df [ "instagram_followers" ] . notna () . sum ()
2026-10-30 11:10:54 +05:30
st . markdown ( f '<div class="kpi-box"><div class="kpi-title" style="color: #f59e0b;">Instagram Audience</div><div class="kpi-value" style="color: #f59e0b;"> { ig_count } </div><div class="kpi-subtitle">Verified public followings</div></div>' , unsafe_allow_html = True )
2026-10-28 17:07:19 +05:30
with k5 :
2026-10-30 11:10:54 +05:30
cataloged_count = df [ "total_eas_cspc" ] . fillna ( 0 ) . gt ( 0 ) . sum ()
st . markdown ( f '<div class="kpi-box"><div class="kpi-title" style="color: #ec4899;">Catalog Coverage</div><div class="kpi-value" style="color: #ec4899;"> { cataloged_count } </div><div class="kpi-subtitle">100% Cohort Cataloged</div></div>' , unsafe_allow_html = True )
2026-10-28 17:07:19 +05:30
2026-10-22 17:20:44 +05:30
st . markdown ( "<div class='custom-divider'></div>" , unsafe_allow_html = True )
2026-10-30 11:10:54 +05:30
# ----------------- Dynamic Telemetry Coverage Banner -----------------
if view_mode in ( "💿 Record Sales (CSPC Methodology)" , "🧪 Commercial Simulation Engine (CPI)" ):
verified_cspc_cnt = int (( df [ "sales_data_status" ] == "VERIFIED_CSPC" ) . sum ())
verified_riaa_cnt = int (( df [ "sales_data_status" ] == "VERIFIED_RIAA" ) . sum ())
estimated_sea_cnt = int (( df [ "sales_data_status" ] == "ESTIMATED_SEA" ) . sum ())
total_active_coverage = verified_cspc_cnt + verified_riaa_cnt + estimated_sea_cnt
coverage_pct = ( total_active_coverage / len ( df )) * 100.0
2026-10-22 17:20:44 +05:30
2026-10-30 11:10:54 +05:30
st . markdown (
f """
<div class="coverage-card">
<div>
<span style="font-weight: 800; color: #f9fafb; font-size: 0.92rem;">📡 Commercial Telemetry Coverage Progress:</span>
<span style="color: #10b981; font-weight: 700; margin-left: 8px;"> { verified_cspc_cnt } CSPC Verified</span>
<span style="color: #64748b; margin: 0 6px;">•</span>
<span style="color: #38bdf8; font-weight: 700;"> { verified_riaa_cnt } RIAA Certified</span>
<span style="color: #64748b; margin: 0 6px;">•</span>
<span style="color: #a855f7; font-weight: 600;"> { estimated_sea_cnt } Streaming SEA</span>
</div>
<div style="font-size: 0.85rem; color: #94a3b8;">
Active Commercial Coverage: <strong style="color: #10b981;"> { coverage_pct : .1f } %</strong> ( { total_active_coverage } / { len ( df ) } )
</div>
</div>
""" ,
unsafe_allow_html = True ,
2026-10-22 17:20:44 +05:30
)
2026-10-30 11:10:54 +05:30
# ----------------- Standalone Module Views -----------------
if view_mode == "💿 Record Sales (CSPC Methodology)" :
st . markdown ( "### 💿 Global Record Sales & Lifetime Commercial Ranking" )
st . caption ( "Standardized on ChartMasters CSPC, verified RIAA certifications, and video/audio streaming equivalent units." )
sc1 , sc2 , sc3 , sc4 = st . columns ( 4 )
total_sales_volume = filtered_df [ "total_eas_cspc" ] . fillna ( 0 ) . sum ()
cspc_count = ( filtered_df [ "sales_data_status" ] == "VERIFIED_CSPC" ) . sum ()
riaa_count = ( filtered_df [ "sales_data_status" ] == "VERIFIED_RIAA" ) . sum ()
sea_count = ( filtered_df [ "sales_data_status" ] == "ESTIMATED_SEA" ) . sum ()
with sc1 :
st . markdown ( f '<div class="kpi-box"><div class="kpi-title">Tracked Catalog Volume</div><div class="kpi-value"> { total_sales_volume / 1e6 : .1f } M</div><div class="kpi-subtitle">Total Equivalent Album Sales (EAS)</div></div>' , unsafe_allow_html = True )
with sc2 :
st . markdown ( f '<div class="kpi-box"><div class="kpi-title" style="color: #10b981;">CSPC Verified</div><div class="kpi-value" style="color: #10b981;"> { cspc_count } </div><div class="kpi-subtitle">ChartMasters Full Dossiers</div></div>' , unsafe_allow_html = True )
with sc3 :
st . markdown ( f '<div class="kpi-box"><div class="kpi-title" style="color: #38bdf8;">RIAA Certified</div><div class="kpi-value" style="color: #38bdf8;"> { riaa_count } </div><div class="kpi-subtitle">Domestic Certifications</div></div>' , unsafe_allow_html = True )
with sc4 :
st . markdown ( f '<div class="kpi-box"><div class="kpi-title" style="color: #a855f7;">Streaming SEA</div><div class="kpi-value" style="color: #a855f7;"> { sea_count } </div><div class="kpi-subtitle">Luminate/Billboard Conversion</div></div>' , unsafe_allow_html = True )
st . markdown ( "#### 🏆 All-Time Global Sales Leaderboard" )
sales_table_df = filtered_df . sort_values ( by = "total_eas_cspc" , ascending = False ) . copy ()
sales_table_df [ "provenance_badge" ] = sales_table_df [ "sales_data_status" ] . apply ( get_provenance_badge )
sales_cols = [
2026-10-28 17:07:19 +05:30
"cohort_sales_rank" ,
"chartmasters_sales_rank" ,
"name" ,
2026-10-30 11:10:54 +05:30
"provenance_badge" ,
2026-10-28 17:07:19 +05:30
"total_eas_cspc" ,
"pure_album_sales" ,
"streaming_eas" ,
"physical_singles_sales" ,
"digital_singles_sales" ,
2026-10-30 11:10:54 +05:30
"commercial_power_index" ,
2026-10-27 10:23:02 +05:30
"hiffi_xp_published_rank" ,
2026-10-22 17:20:44 +05:30
]
2026-10-30 11:10:54 +05:30
render_s_cols = [ c for c in sales_cols if c in sales_table_df . columns ]
2026-10-22 17:20:44 +05:30
2026-10-30 11:10:54 +05:30
st . dataframe (
sales_table_df [ render_s_cols ] . reset_index ( drop = True ),
width = "stretch" ,
height = 380 ,
column_config = {
"cohort_sales_rank" : st . column_config . NumberColumn ( "Cohort Sales Rank" , format = "# %d " , width = "small" ),
"chartmasters_sales_rank" : st . column_config . NumberColumn ( "All-Time Global Rank" , format = "# %d " , width = "small" ),
"name" : st . column_config . TextColumn ( "Artist" , width = "medium" ),
"provenance_badge" : st . column_config . TextColumn ( "Audit Provenance" , width = "medium" ),
"total_eas_cspc" : st . column_config . NumberColumn ( "Total EAS Units" , format = "%,d" , width = "medium" ),
"pure_album_sales" : st . column_config . NumberColumn ( "Pure Studio Albums" , format = "%,d" , width = "medium" ),
"streaming_eas" : st . column_config . NumberColumn ( "Streaming EAS" , format = "%,d" , width = "medium" ),
"physical_singles_sales" : st . column_config . NumberColumn ( "Physical Singles" , format = "%,d" , width = "small" ),
"digital_singles_sales" : st . column_config . NumberColumn ( "Digital Downloads" , format = "%,d" , width = "small" ),
"commercial_power_index" : st . column_config . ProgressColumn ( "CPI Score" , min_value = 0 , max_value = 100 , format = " %.1f " , width = "small" ),
"hiffi_xp_published_rank" : st . column_config . NumberColumn ( "HIFFI Base Rank" , format = "# %d " , width = "small" ),
},
)
2026-10-23 10:52:54 +05:30
2026-10-30 11:10:54 +05:30
st . markdown ( "<div class='custom-divider'></div>" , unsafe_allow_html = True )
2026-10-22 17:20:44 +05:30
2026-10-30 11:10:54 +05:30
c_s1 , c_s2 = st . columns ( 2 )
with c_s1 :
top_sellers = sales_table_df [ sales_table_df [ "total_eas_cspc" ] > 0 ] . head ( 12 )
fig_format = go . Figure ()
fig_format . add_trace ( go . Bar ( name = "Traditional Albums" , x = top_sellers [ "name" ], y = top_sellers [ "pure_album_sales" ], marker_color = "#8b5cf6" ))
fig_format . add_trace ( go . Bar ( name = "Digital Singles" , x = top_sellers [ "name" ], y = top_sellers [ "digital_singles_sales" ], marker_color = "#38bdf8" ))
fig_format . add_trace ( go . Bar ( name = "Streaming EAS" , x = top_sellers [ "name" ], y = top_sellers [ "streaming_eas" ], marker_color = "#10b981" ))
fig_format . update_layout (
barmode = "stack" ,
title = "Format Contribution: Pure Albums vs Downloads vs Streaming EAS" ,
template = "plotly_dark" ,
paper_bgcolor = "#111827" ,
plot_bgcolor = "#111827" ,
font = dict ( color = "#9ca3af" ),
height = 360 ,
margin = dict ( l = 20 , r = 20 , t = 50 , b = 20 ),
legend = dict ( orientation = "h" , yanchor = "bottom" , y = 1.02 , xanchor = "right" , x = 1.0 ),
2026-10-27 10:23:02 +05:30
)
2026-10-30 11:10:54 +05:30
st . plotly_chart ( fig_format , width = "stretch" )
2026-10-28 17:07:19 +05:30
2026-10-30 11:10:54 +05:30
with c_s2 :
scatter_data = sales_table_df . dropna ( subset = [ "total_eas_cspc" , "hiffi_xp_score" ]) . copy ()
fig_quad = px . scatter (
scatter_data ,
x = "hiffi_xp_score" ,
y = "total_eas_cspc" ,
size = "total_eas_cspc" ,
color = "provenance_badge" ,
hover_name = "name" ,
log_y = True ,
title = "Legacy vs. Velocity Quadrant (All-Time Sales vs HIFFI-XP)" ,
labels = { "hiffi_xp_score" : "Current Multi-Platform Velocity (HIFFI-XP)" , "total_eas_cspc" : "Total Lifetime EAS Units (Log Scale)" },
template = "plotly_dark" ,
)
fig_quad . update_layout (
paper_bgcolor = "#111827" ,
plot_bgcolor = "#111827" ,
font = dict ( color = "#9ca3af" ),
height = 360 ,
margin = dict ( l = 20 , r = 20 , t = 50 , b = 20 ),
)
st . plotly_chart ( fig_quad , width = "stretch" )
2026-10-28 17:07:19 +05:30
else :
2026-10-30 11:10:54 +05:30
top3 = filtered_df . sort_values ( by = "hiffi_xp_published_rank" , ascending = True ) . head ( 3 )
if len ( top3 ) >= 3 and view_mode != "🧪 Commercial Simulation Engine (CPI)" :
st . markdown ( "#### 👑 Market Leaders (Published Baseline Rankings)" )
p1 , p2 , p3 = st . columns ( 3 )
podium_data = [
( p1 , top3 . iloc [ 0 ], "🥇 PUBLISHED #1" , "podium-gold" , "#f59e0b" ),
( p2 , top3 . iloc [ 1 ], "🥈 PUBLISHED #2" , "podium-silver" , "#94a3b8" ),
( p3 , top3 . iloc [ 2 ], "🥉 PUBLISHED #3" , "podium-bronze" , "#f97316" ),
]
for col , row_data , rank_label , css_class , accent_color in podium_data :
tier_val = int ( row_data . get ( "platform_evidence_tier" , 1 ))
sp_str = f " { int ( row_data [ 'spotify_monthly_listeners' ]) : , } " if pd . notna ( row_data . get ( "spotify_monthly_listeners" )) else "NaN"
ig_str = f " { int ( row_data [ 'instagram_followers' ]) : , } " if pd . notna ( row_data . get ( "instagram_followers" )) else "NaN"
with col :
st . markdown (
f """
<div class="podium-tile { css_class } ">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 6px;">
<span style="font-weight: 800; color: { accent_color } ; font-size: 0.85rem;"> { rank_label } </span>
<span class="badge badge-tier { tier_val } ">Tier { tier_val } Evidence</span>
</div>
<div style="font-size: 1.35rem; font-weight: 800; color: #ffffff; margin-bottom: 2px;"> { row_data [ 'name' ] } </div>
<div style="font-size: 0.8rem; color: #6b7280; margin-bottom: 12px;"> { row_data . get ( 'channel_title' , '' ) } </div>
<div style="display: flex; justify-content: space-between; background: #0b0f17; padding: 10px 14px; border-radius: 8px;">
<div><div style="font-size: 0.68rem; color: #9ca3af;">HIFFI-XP</div><div style="font-size: 1.25rem; font-weight: 800; color: { accent_color } ;"> { row_data [ 'hiffi_xp_score' ] : .2f } </div></div>
<div><div style="font-size: 0.68rem; color: #9ca3af;">Spotify Monthly</div><div style="font-size: 1.05rem; font-weight: 700; color: #38bdf8;"> { sp_str } </div></div>
<div><div style="font-size: 0.68rem; color: #9ca3af;">IG Followers</div><div style="font-size: 1.05rem; font-weight: 700; color: #e5e7eb;"> { ig_str } </div></div>
</div>
</div>
""" ,
unsafe_allow_html = True ,
)
st . markdown ( "<div class='custom-divider'></div>" , unsafe_allow_html = True )
2026-10-28 17:07:19 +05:30
2026-10-30 11:10:54 +05:30
if view_mode == "🧪 Commercial Simulation Engine (CPI)" :
st . markdown ( "#### 🧪 Simulation Impact & Decision Summary" )
sm1 , sm2 , sm3 , sm4 = st . columns ( 4 )
g_delta = f "+ { sim_metrics . get ( 'top_gainer_delta' , 0 ) } " if sim_metrics . get ( 'top_gainer_delta' , 0 ) > 0 else f " { sim_metrics . get ( 'top_gainer_delta' , 0 ) } "
l_delta = f " { sim_metrics . get ( 'top_loser_delta' , 0 ) } "
with sm1 :
st . markdown ( f '<div class="sim-kpi-card"><div class="sim-kpi-title">Top Gainer</div><div class="sim-kpi-val" style="color: #10b981;"> { sim_metrics . get ( "top_gainer_name" , "None" ) } <span style="font-size: 0.85rem;">(▲ { g_delta } )</span></div></div>' , unsafe_allow_html = True )
with sm2 :
st . markdown ( f '<div class="sim-kpi-card"><div class="sim-kpi-title">Top Loser</div><div class="sim-kpi-val" style="color: #ef4444;"> { sim_metrics . get ( "top_loser_name" , "None" ) } <span style="font-size: 0.85rem;">(▼ { l_delta } )</span></div></div>' , unsafe_allow_html = True )
with sm3 :
st . markdown ( f '<div class="sim-kpi-card"><div class="sim-kpi-title">Mean Absolute Shift</div><div class="sim-kpi-val" style="color: #38bdf8;">± { sim_metrics . get ( "mean_abs_delta" , 0.0 ) } <span style="font-size: 0.85rem; color: #94a3b8;">positions</span></div></div>' , unsafe_allow_html = True )
with sm4 :
st . markdown ( f '<div class="sim-kpi-card"><div class="sim-kpi-title">Simulation Scope</div><div class="sim-kpi-val" style="color: #f59e0b;"> { sim_metrics . get ( "matched_coverage" , 0 ) } / { len ( filtered_df ) } <span style="font-size: 0.85rem; color: #94a3b8;">( { sim_mode } )</span></div></div>' , unsafe_allow_html = True )
st . caption ( f "💡 **Executive Takeaway:** At ** { int ( sim_weight * 100 ) } % commercial weight**, the average cataloged artist moves **± { sim_metrics . get ( 'mean_abs_delta' , 0.0 ) } positions**." )
st . markdown ( "<div class='custom-divider'></div>" , unsafe_allow_html = True )
st . markdown ( f "#### 📋 { view_mode } " )
if view_mode == "🏆 Published Multi-Platform Rank" :
table_df = filtered_df . sort_values ( by = "hiffi_xp_published_rank" , ascending = True ) . copy ()
cols = [ "hiffi_xp_published_rank" , "hiffi_xp_rank" , "name" , "platform_evidence_tier" , "hiffi_xp_score" , "spotify_monthly_listeners" , "instagram_followers" , "effective_weights" , "anomaly_flags" ]
elif view_mode == "🚀 Breakout Velocity (BVI)" :
table_df = filtered_df [ filtered_df [ "breakout_velocity_index" ] . notna ()] . sort_values ( by = "breakout_velocity_index" , ascending = False ) . copy ()
cols = [ "name" , "breakout_velocity_index" , "hiffi_xp_published_rank" , "daily_view_velocity" , "momentum_30d" , "subscriber_count" , "subgenre" ]
elif view_mode == "🧪 Commercial Simulation Engine (CPI)" :
table_df = filtered_df . sort_values ( by = "simulated_rank" , ascending = True ) . copy ()
def format_rank_delta ( val ):
if pd . isna ( val ):
return "N/A"
ival = int ( val )
if ival > 0 :
return f "▲ + { ival } (Up)"
elif ival < 0 :
return f "▼ { ival } (Down)"
else :
return "— 0 (Equal)"
table_df [ "rank_shift_indicator" ] = table_df [ "simulation_rank_delta" ] . apply ( format_rank_delta )
comp_rank = "baseline_matched_rank" if sim_mode == "matched_only" else "hiffi_xp_published_rank"
cols = [
"simulated_rank" ,
comp_rank ,
"rank_shift_indicator" ,
"name" ,
"simulated_hiffi_score" ,
"hiffi_xp_score" ,
"commercial_power_index" ,
"total_eas_cspc" ,
"sales_data_status" ,
]
else :
table_df = filtered_df . sort_values ( by = "hiffi_xp_published_rank" , ascending = True ) . copy ()
cols = [ "hiffi_xp_published_rank" , "name" , "production_hiffi_rank" , "hiffi_xp_rank" , "rank_delta" , "platform_evidence_tier" , "hiffi_xp_score" , "spotify_monthly_listeners" , "instagram_followers" , "total_eas_cspc" , "sales_data_status" , "evidence_exclusions" , "anomaly_flags" ]
display_table = table_df . copy ()
if "sales_data_status" in display_table . columns :
display_table [ "sales_data_status" ] = display_table [ "sales_data_status" ] . apply ( get_provenance_badge )
render_cols = [ c for c in cols if c in display_table . columns ]
st . dataframe (
display_table [ render_cols ] . reset_index ( drop = True ),
width = "stretch" ,
height = 340 ,
column_config = {
"hiffi_xp_published_rank" : st . column_config . NumberColumn ( "Published Rank" , format = " %d " , width = "small" ),
"baseline_matched_rank" : st . column_config . NumberColumn ( "Baseline Match Rank" , format = " %d " , width = "small" ),
"simulated_rank" : st . column_config . NumberColumn ( "Simulated Rank" , format = " %d " , width = "small" ),
"rank_shift_indicator" : st . column_config . TextColumn ( "Simulated Δ (Movement)" , width = "medium" ),
"simulated_hiffi_score" : st . column_config . ProgressColumn ( "Simulated Score" , format = " %.2f " , min_value = 0 , max_value = 100 , width = "medium" ),
"hiffi_xp_score" : st . column_config . ProgressColumn ( "HIFFI-XP Score" , format = " %.2f " , min_value = 0 , max_value = 100 , width = "medium" ),
"commercial_power_index" : st . column_config . ProgressColumn ( "Commercial Power Index" , format = " %.1f " , min_value = 0 , max_value = 100 , width = "medium" ),
"total_eas_cspc" : st . column_config . NumberColumn ( "Total Equivalent Album Sales" , format = "%,d" , width = "medium" ),
"pure_album_sales" : st . column_config . NumberColumn ( "Traditional Album Sales" , format = "%,d" , width = "medium" ),
"streaming_eas" : st . column_config . NumberColumn ( "Streaming-Equivalent Album Sales" , format = "%,d" , width = "medium" ),
"sales_data_status" : st . column_config . TextColumn ( "Sales Audit Status" , width = "medium" ),
},
)
st . markdown ( "<div class='custom-divider'></div>" , unsafe_allow_html = True )
if view_mode == "🧪 Commercial Simulation Engine (CPI)" :
c_sim1 , c_sim2 = st . columns ( 2 )
with c_sim1 :
sim_delta_df = filtered_df . dropna ( subset = [ "simulation_rank_delta" ]) . sort_values ( by = "total_eas_cspc" , ascending = False ) . head ( 15 ) . copy ()
if not sim_delta_df . empty :
fig_delta = px . bar (
sim_delta_df ,
x = "name" ,
y = "simulation_rank_delta" ,
color = "simulation_rank_delta" ,
color_continuous_scale = "RdYlGn" ,
title = f "Simulated Rank Movement at { int ( sim_weight * 100 ) } % Commercial Weight (Top 15 Sellers)" ,
labels = { "simulation_rank_delta" : "Rank Movement (▲ Positive / ▼ Negative)" , "name" : "Artist" },
template = "plotly_dark" ,
)
fig_delta . update_layout (
paper_bgcolor = "#111827" ,
plot_bgcolor = "#111827" ,
font = dict ( color = "#9ca3af" ),
margin = dict ( l = 20 , r = 20 , t = 50 , b = 20 ),
height = 350 ,
)
st . plotly_chart ( fig_delta , width = "stretch" )
with c_sim2 :
sensitivity_df = engine . run_sensitivity_matrix ( filtered_df , mode = sim_mode ) . head ( 15 )
fig_sens = go . Figure ()
for idx , r in sensitivity_df . head ( 6 ) . iterrows ():
fig_sens . add_trace ( go . Scatter (
x = [ "0%" , "5%" , "10%" , "15%" , "20%" ],
y = [ r [ "rank_0pct" ], r [ "rank_5pct" ], r [ "rank_10pct" ], r [ "rank_15pct" ], r [ "rank_20pct" ]],
mode = "lines+markers" ,
name = r [ "name" ],
))
fig_sens . update_layout (
title = "Weight Sensitivity: Rank Trajectories Across Weights (Top Volatile Acts)" ,
yaxis = dict ( autorange = "reversed" , title = "Simulated Rank (Lower is Better)" ),
xaxis = dict ( title = "Commercial Signal Weight (%)" ),
2026-10-28 17:07:19 +05:30
template = "plotly_dark" ,
2026-10-30 11:10:54 +05:30
paper_bgcolor = "#111827" ,
plot_bgcolor = "#111827" ,
font = dict ( color = "#9ca3af" ),
margin = dict ( l = 20 , r = 20 , t = 50 , b = 20 ),
height = 350 ,
2026-10-28 17:07:19 +05:30
)
2026-10-30 11:10:54 +05:30
st . plotly_chart ( fig_sens , width = "stretch" )
else :
c_left , c_right = st . columns ( 2 )
with c_left :
chart_df = filtered_df . dropna ( subset = [ "spotify_monthly_listeners" , "instagram_followers" , "hiffi_xp_score" ]) . copy ()
if not chart_df . empty :
fig_scatter = px . scatter (
chart_df ,
x = "spotify_monthly_listeners" ,
y = "instagram_followers" ,
size = "hiffi_xp_score" ,
color = "platform_evidence_tier" ,
hover_name = "name" ,
log_x = True ,
log_y = True ,
title = "Spotify Monthly Listeners vs. Instagram Followers" ,
labels = { "spotify_monthly_listeners" : "Spotify Monthly Listeners (Log Scale)" , "instagram_followers" : "Instagram Followers (Log Scale)" , "platform_evidence_tier" : "Tier" },
template = "plotly_dark" ,
)
fig_scatter . update_layout (
paper_bgcolor = "#111827" ,
plot_bgcolor = "#111827" ,
font = dict ( color = "#9ca3af" ),
margin = dict ( l = 20 , r = 20 , t = 40 , b = 20 ),
height = 320 ,
)
st . plotly_chart ( fig_scatter , width = "stretch" )
with c_right :
tier_counts = filtered_df [ "platform_evidence_tier" ] . value_counts () . reset_index ()
tier_counts . columns = [ "Tier" , "Count" ]
fig_pie = px . pie ( tier_counts , values = "Count" , names = "Tier" , title = "Evidence Tier Cohort Distribution" , template = "plotly_dark" , color = "Tier" , color_discrete_map = { 3 : "#10b981" , 2 : "#38bdf8" , 1 : "#f59e0b" , 0 : "#ef4444" })
fig_pie . update_layout (
2026-10-28 17:07:19 +05:30
paper_bgcolor = "#111827" ,
plot_bgcolor = "#111827" ,
font = dict ( color = "#9ca3af" ),
margin = dict ( l = 20 , r = 20 , t = 40 , b = 20 ),
height = 320 ,
)
2026-10-30 11:10:54 +05:30
st . plotly_chart ( fig_pie , width = "stretch" )
2026-10-22 17:20:44 +05:30
# ----------------- Deep Dive Scouting Dossier -----------------
2026-10-27 10:23:02 +05:30
st . markdown ( "<div class='custom-divider'></div>" , unsafe_allow_html = True )
2026-10-22 17:20:44 +05:30
st . markdown ( "#### 🔎 Artist Dossier" )
selected_name = st . selectbox ( "Inspect Artist Details:" , df [ "name" ] . unique (), label_visibility = "collapsed" )
row = df [ df [ "name" ] == selected_name ] . iloc [ 0 ]
2026-10-28 17:07:19 +05:30
d1 , d2 , d3 , d4 , d5 = st . columns ( 5 )
2026-10-22 17:20:44 +05:30
with d1 :
2026-10-27 10:23:02 +05:30
h_val = row . get ( "hiffi_xp_score" )
st . metric ( "HIFFI-XP Score" , f " { h_val : .2f } " if pd . notna ( h_val ) else "N/A" )
2026-10-22 17:20:44 +05:30
with d2 :
2026-10-27 10:23:02 +05:30
pub_rank = row . get ( "hiffi_xp_published_rank" )
st . metric ( "Published Rank" , f "# { int ( pub_rank ) } " if pd . notna ( pub_rank ) else "Unranked" )
2026-10-22 17:20:44 +05:30
with d3 :
2026-10-27 10:23:02 +05:30
sp_l = row . get ( "spotify_monthly_listeners" )
st . metric ( "Spotify Listeners" , f " { int ( sp_l ) : , } " if pd . notna ( sp_l ) else "Unindexed (NaN)" )
2026-10-22 17:20:44 +05:30
with d4 :
2026-10-27 10:23:02 +05:30
ig_f = row . get ( "instagram_followers" )
st . metric ( "Instagram Followers" , f " { int ( ig_f ) : , } " if pd . notna ( ig_f ) else "Unindexed (NaN)" )
2026-10-28 17:07:19 +05:30
with d5 :
sales_val = row . get ( "total_eas_cspc" )
2026-10-30 11:10:54 +05:30
st . metric ( "Total EAS Sales" , f " { int ( sales_val ) : , } " if pd . notna ( sales_val ) else "Awaiting Ingestion" )
2026-10-22 17:20:44 +05:30
st . markdown (
f """
2026-10-27 10:23:02 +05:30
<div style="background: #111827; padding: 14px 18px; border-radius: 8px; border: 1px solid #1f2937; margin-top: 10px; font-size: 0.85rem;">
<div style="display: flex; gap: 20px; flex-wrap: wrap;">
2026-10-23 10:52:54 +05:30
<div><b>Artist:</b> { row [ 'name' ] } </div>
2026-10-27 10:23:02 +05:30
<div><b>Evidence Tier:</b> Tier { int ( row . get ( 'platform_evidence_tier' , 1 )) } </div>
2026-10-28 17:07:19 +05:30
<div><b>Global Sales Rank:</b> { f "# { int ( row . get ( 'chartmasters_sales_rank' )) } " if pd . notna ( row . get ( 'chartmasters_sales_rank' )) else "Unranked" } </div>
<div><b>Cohort Sales Rank:</b> { f "# { int ( row . get ( 'cohort_sales_rank' )) } " if pd . notna ( row . get ( 'cohort_sales_rank' )) else "Uncataloged" } </div>
2026-10-30 11:10:54 +05:30
<div><b>Commercial Power Index:</b> { f " { row . get ( 'commercial_power_index' ) : .1f } " if pd . notna ( row . get ( 'commercial_power_index' )) else "Awaiting Audit" } </div>
<div><b>Traditional Albums:</b> { f " { int ( row . get ( 'pure_album_sales' )) : , } " if pd . notna ( row . get ( 'pure_album_sales' )) else "N/A" } </div>
<div><b>Streaming-Equivalent EAS:</b> { f " { int ( row . get ( 'streaming_eas' )) : , } " if pd . notna ( row . get ( 'streaming_eas' )) else "N/A" } </div>
<div><b>Sales Status:</b> { get_provenance_badge ( row . get ( 'sales_data_status' , '' )) } </div>
2026-10-27 10:23:02 +05:30
<div><b>Effective Weights:</b> { row . get ( 'effective_weights' , 'N/A' ) } </div>
<div><b>Anomaly Flags:</b> { row . get ( 'anomaly_flags' , 'CLEAN' ) } </div>
2026-10-23 10:52:54 +05:30
</div>
2026-10-22 17:20:44 +05:30
</div>
""" ,
unsafe_allow_html = True ,
2026-10-27 10:23:02 +05:30
)