rameshmoorthy's picture
Upload 9 files
67bf425 verified
"""
styles.py β€” Global WCO colour palette, CSS injection, and shared UI helpers
"""
import streamlit as st
# ── WCO Colour Palette ──────────────────────────────────────────────────────
WCO_NAVY = "#003087"
WCO_BLUE = "#0066CC"
WCO_GOLD = "#C8A951"
WCO_GREEN = "#00843D"
WCO_RED = "#C8102E"
WCO_YELLOW = "#F5A800"
WCO_GREY_BG = "#0B1220"
WCO_CARD_BG = "#0F1C35"
WCO_BORDER = "#1E3A6E"
WCO_TEXT = "#D0DCF0"
WCO_MUTED = "#6B85AA"
CHANNEL_COLORS = {
"RED": WCO_RED,
"YELLOW": WCO_YELLOW,
"GREEN": WCO_GREEN,
}
RISK_COLORS = {
"Drugs & Narcotics": "#C8102E",
"Environmental/Plastic Waste": "#00843D",
"Revenue Leakage": "#F5A800",
"IPR Enforcement": "#9B59B6",
"Wildlife Smuggling": "#E67E22",
}
def inject_global_css():
st.markdown(f"""
<style>
@import url('https://fonts.googleapis.com/css2?family=Playfair+Display:wght@400;600;700&family=IBM+Plex+Sans:wght@300;400;500;600&family=IBM+Plex+Mono:wght@400;500&display=swap');
/* ── Root reset ── */
html, body, [data-testid="stAppViewContainer"] {{
background-color: {WCO_GREY_BG} !important;
color: {WCO_TEXT} !important;
font-family: 'IBM Plex Sans', sans-serif;
}}
[data-testid="stSidebar"] {{
background-color: #070E1C !important;
border-right: 1px solid {WCO_BORDER};
}}
[data-testid="stSidebar"] * {{ color: {WCO_TEXT} !important; }}
/* ── Header bar ── */
.wco-header {{
background: linear-gradient(135deg, {WCO_NAVY} 0%, #001550 100%);
border-bottom: 3px solid {WCO_GOLD};
padding: 18px 28px;
border-radius: 12px;
margin-bottom: 20px;
display: flex;
align-items: center;
gap: 16px;
}}
.wco-header h1 {{
font-family: 'Playfair Display', serif;
color: {WCO_GOLD};
font-size: 26px;
margin: 0;
line-height: 1.2;
}}
.wco-header p {{
color: #8BAAD4;
font-size: 12px;
margin: 4px 0 0;
font-family: 'IBM Plex Mono', monospace;
letter-spacing: 0.06em;
}}
/* ── Cards ── */
.wco-card {{
background: {WCO_CARD_BG};
border: 1px solid {WCO_BORDER};
border-radius: 12px;
padding: 22px 24px;
margin-bottom: 16px;
}}
.wco-card-gold {{
background: {WCO_CARD_BG};
border: 1px solid {WCO_GOLD};
border-radius: 12px;
padding: 22px 24px;
margin-bottom: 16px;
}}
.wco-card h3 {{
font-family: 'Playfair Display', serif;
color: {WCO_GOLD};
font-size: 16px;
margin: 0 0 14px;
padding-bottom: 10px;
border-bottom: 1px solid {WCO_BORDER};
}}
/* ── Section title ── */
.section-title {{
font-family: 'Playfair Display', serif;
color: {WCO_GOLD};
font-size: 20px;
font-weight: 700;
margin: 8px 0 16px;
letter-spacing: 0.01em;
}}
/* ── KPI tiles ── */
.kpi-row {{ display: flex; gap: 12px; flex-wrap: wrap; margin-bottom: 18px; }}
.kpi-tile {{
flex: 1;
min-width: 140px;
background: {WCO_CARD_BG};
border: 1px solid {WCO_BORDER};
border-radius: 10px;
padding: 16px 18px;
text-align: center;
}}
.kpi-tile .val {{
font-family: 'Playfair Display', serif;
font-size: 32px;
font-weight: 700;
line-height: 1;
}}
.kpi-tile .lbl {{
font-size: 11px;
color: {WCO_MUTED};
margin-top: 6px;
text-transform: uppercase;
letter-spacing: 0.08em;
}}
/* ── Channel badges ── */
.badge-red {{ background:#3A0010; color:#FF4466; border:1px solid #C8102E; border-radius:6px; padding:3px 10px; font-size:12px; font-weight:600; }}
.badge-yellow {{ background:#2A1900; color:#FFD700; border:1px solid #F5A800; border-radius:6px; padding:3px 10px; font-size:12px; font-weight:600; }}
.badge-green {{ background:#001A09; color:#44CC88; border:1px solid #00843D; border-radius:6px; padding:3px 10px; font-size:12px; font-weight:600; }}
.badge-gold {{ background:#1C1400; color:{WCO_GOLD}; border:1px solid {WCO_GOLD}; border-radius:6px; padding:3px 10px; font-size:12px; font-weight:600; }}
/* ── Tables ── */
.wco-table {{ width:100%; border-collapse:collapse; font-size:13px; }}
.wco-table th {{
background:{WCO_NAVY};
color:{WCO_GOLD};
font-family:'Playfair Display',serif;
padding:10px 14px;
text-align:left;
border-bottom:2px solid {WCO_GOLD};
font-size:12px;
letter-spacing:0.05em;
}}
.wco-table td {{
padding:9px 14px;
border-bottom:1px solid {WCO_BORDER};
color:{WCO_TEXT};
vertical-align:top;
}}
.wco-table tr:hover td {{ background:rgba(0,48,135,0.25); }}
/* ── Progress bars ── */
.prog-bar-wrap {{ background:#111D30; border-radius:6px; height:10px; margin:4px 0; overflow:hidden; }}
.prog-bar-fill {{ height:100%; border-radius:6px; transition:width 0.6s ease; }}
/* ── Alerts ── */
.alert-gold {{
background:rgba(200,169,81,0.1);
border-left:4px solid {WCO_GOLD};
border-radius:0 8px 8px 0;
padding:12px 16px;
color:#D4B96A;
font-size:13px;
margin:10px 0;
}}
.alert-blue {{
background:rgba(0,102,204,0.1);
border-left:4px solid {WCO_BLUE};
border-radius:0 8px 8px 0;
padding:12px 16px;
color:#66AAFF;
font-size:13px;
margin:10px 0;
}}
/* ── Streamlit widget tweaks ── */
.stSlider > div > div > div {{ background:{WCO_BORDER} !important; }}
.stSlider [data-baseweb="slider"] [role="slider"] {{ background:{WCO_GOLD} !important; border-color:{WCO_GOLD} !important; }}
.stButton > button {{
background:linear-gradient(135deg,{WCO_NAVY},{WCO_BLUE});
color:{WCO_GOLD};
border:1px solid {WCO_GOLD};
border-radius:8px;
font-family:'IBM Plex Sans',sans-serif;
font-weight:600;
letter-spacing:0.04em;
padding:8px 24px;
transition:all 0.2s;
}}
.stButton > button:hover {{
background:linear-gradient(135deg,{WCO_BLUE},{WCO_NAVY});
border-color:#FFD700;
color:#FFD700;
transform:translateY(-1px);
box-shadow:0 4px 16px rgba(200,169,81,0.25);
}}
div[data-testid="stMetricValue"] {{
font-family:'Playfair Display',serif !important;
color:{WCO_GOLD} !important;
}}
[data-testid="stMetricLabel"] {{ color:{WCO_MUTED} !important; font-size:11px !important; text-transform:uppercase !important; letter-spacing:0.07em !important; }}
[data-testid="stExpander"] {{
background:{WCO_CARD_BG} !important;
border:1px solid {WCO_BORDER} !important;
border-radius:10px !important;
}}
div[data-testid="stDataFrame"] {{ border-radius:10px; overflow:hidden; }}
.stTabs [data-baseweb="tab-list"] {{ background:{WCO_CARD_BG}; border-radius:10px 10px 0 0; }}
.stTabs [data-baseweb="tab"] {{ color:{WCO_MUTED}; font-family:'IBM Plex Sans',sans-serif; }}
.stTabs [aria-selected="true"] {{ color:{WCO_GOLD} !important; border-bottom:2px solid {WCO_GOLD} !important; }}
hr {{ border-color:{WCO_BORDER} !important; }}
</style>
""", unsafe_allow_html=True)
def page_header(icon: str, title: str, subtitle: str):
st.markdown(f"""
<div class="wco-header">
<div style="font-size:40px">{icon}</div>
<div>
<h1>{title}</h1>
<p>{subtitle}</p>
</div>
<div style="margin-left:auto;text-align:right;">
<div style="color:#C8A951;font-family:'IBM Plex Mono',monospace;font-size:11px;">🌐 WCO ACCREDITED</div>
<div style="color:#6B85AA;font-size:10px;margin-top:2px;">No-CelH Self-Learning RMS v2.0</div>
</div>
</div>
""", unsafe_allow_html=True)
def metric_row(metrics: list):
"""metrics = [(value, label, color), ...]"""
cols_html = ""
for val, lbl, col in metrics:
cols_html += f"""
<div class="kpi-tile">
<div class="val" style="color:{col}">{val}</div>
<div class="lbl">{lbl}</div>
</div>"""
st.markdown(f'<div class="kpi-row">{cols_html}</div>', unsafe_allow_html=True)