AsmaJ2026's picture
fix: dark text in OST editor inputs, results page top spacing, upload filename guide
856124c
Raw
History Blame Contribute Delete
6.42 kB
import streamlit as st
import base64
import os
def _logo_b64(size: int) -> str:
logo_path = os.path.join(os.path.dirname(__file__), "..", "logo.png")
logo_path = os.path.normpath(logo_path)
if not os.path.exists(logo_path):
return ""
with open(logo_path, "rb") as f:
data = base64.b64encode(f.read()).decode()
return f'<img src="data:image/png;base64,{data}" width="{size}" height="{size}" style="object-fit:contain;" />'
def _logo_img_tag(size: int) -> str:
tag = _logo_b64(size)
return tag if tag else _logo_svg_fallback(size)
def _logo_svg_fallback(size: int) -> str:
grad_id = "swirl1" if size > 40 else "s1"
grad_id2 = "swirl2" if size > 40 else "s2"
return f"""<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" width="{size}" height="{size}">
<defs>
<linearGradient id="{grad_id}" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#9B7FFF"/>
<stop offset="100%" stop-color="#1E148C"/>
</linearGradient>
<linearGradient id="{grad_id2}" x1="100%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" stop-color="#7C5CE8"/>
<stop offset="100%" stop-color="#120E6B"/>
</linearGradient>
</defs>
<path d="M 52 8 C 82 10 95 38 82 68 C 72 52 62 30 52 8 Z" fill="url(#{grad_id})" opacity="0.95"/>
<path d="M 48 92 C 18 90 5 62 18 32 C 28 48 38 70 48 92 Z" fill="url(#{grad_id2})" opacity="0.90"/>
<path d="M 10 38 C 22 12 52 6 78 22 C 60 28 36 32 10 38 Z" fill="url(#{grad_id})" opacity="0.80"/>
<path d="M 90 62 C 78 88 48 94 22 78 C 40 72 64 68 90 62 Z" fill="url(#{grad_id2})" opacity="0.75"/>
<circle cx="50" cy="50" r="20" fill="white" opacity="0.92"/>
<circle cx="50" cy="50" r="12" fill="white" opacity="0.4"/>
</svg>"""
# Pre-compute at import time
LOGO_SVG = _logo_img_tag(56)
LOGO_SVG_SMALL = _logo_img_tag(36)
def apply_theme():
st.sidebar.markdown(
f'<div style="padding:16px 8px 12px;border-bottom:1px solid rgba(255,255,255,0.15);'
f'margin-bottom:8px;display:flex;align-items:center;gap:10px;">'
f'{LOGO_SVG_SMALL}'
f'<div><div style="color:white;font-weight:800;font-size:15px;line-height:1.2;">Discovery Lens</div>'
f'<div style="color:rgba(255,255,255,0.65);font-size:10px;">Discovery data is everywhere. <em>Insight isn\'t.</em></div></div>'
f'</div>',
unsafe_allow_html=True,
)
st.markdown("""
<style>
/* ── Page background ── */
[data-testid="stAppViewContainer"] > .main {
background-color: #EEEDF6;
}
[data-testid="stHeader"] {
background-color: #EEEDF6;
}
/* ── Sidebar ── */
[data-testid="stSidebar"] {
background-color: #3D2F9E !important;
}
[data-testid="stSidebar"] * {
color: rgba(255,255,255,0.85) !important;
}
[data-testid="stSidebar"] [data-testid="stSidebarNav"] a {
color: rgba(255,255,255,0.75) !important;
border-radius: 6px;
padding: 5px 10px;
}
[data-testid="stSidebar"] [data-testid="stSidebarNav"] a:hover,
[data-testid="stSidebar"] [data-testid="stSidebarNav"] a[aria-current="page"] {
background: rgba(255,255,255,0.15) !important;
color: white !important;
}
[data-testid="stSidebar"] hr {
border-color: rgba(255,255,255,0.2) !important;
}
/* ── Typography ── */
h1, h2, h3, h4 {
color: #26215C !important;
}
/* ── Primary buttons ── */
.stButton > button[kind="primary"] {
background-color: #534AB7 !important;
border-color: #534AB7 !important;
color: white !important;
border-radius: 8px !important;
font-weight: 600 !important;
}
.stButton > button[kind="primary"]:hover {
background-color: #3D2F9E !important;
border-color: #3D2F9E !important;
}
.stButton > button[kind="secondary"] {
border-color: #534AB7 !important;
color: #534AB7 !important;
border-radius: 8px !important;
}
/* ── Inputs ── */
[data-testid="stTextInput"] input,
[data-testid="stTextArea"] textarea {
border-color: #D0CCF0 !important;
border-radius: 8px !important;
background: white !important;
}
[data-testid="stTextInput"] input:focus,
[data-testid="stTextArea"] textarea:focus {
border-color: #534AB7 !important;
box-shadow: 0 0 0 2px rgba(83,74,183,0.15) !important;
}
/* ── Selectbox ── */
[data-testid="stSelectbox"] > div > div {
border-color: #D0CCF0 !important;
border-radius: 8px !important;
background: white !important;
}
/* ── Expander ── */
[data-testid="stExpander"] {
border: 1.5px solid #D0CCF0 !important;
border-radius: 10px !important;
background: white !important;
}
/* ── Tabs ── */
[data-testid="stTabs"] [data-baseweb="tab"] {
color: #534AB7 !important;
font-weight: 600 !important;
}
[data-testid="stTabs"] [data-baseweb="tab"][aria-selected="true"] {
border-bottom-color: #534AB7 !important;
}
/* ── Download buttons ── */
[data-testid="stDownloadButton"] > button {
border-color: #534AB7 !important;
color: #534AB7 !important;
border-radius: 8px !important;
background: white !important;
}
/* ── Alerts ── */
[data-testid="stAlert"][data-type="error"] {
background-color: #FEF0F0 !important;
border-color: #E24B4A !important;
}
[data-testid="stAlert"][data-type="warning"] {
background-color: #FEF8EC !important;
border-color: #EF9F27 !important;
}
[data-testid="stAlert"][data-type="info"] {
background-color: #EEEDFE !important;
border-color: #534AB7 !important;
}
[data-testid="stAlert"][data-type="success"] {
background-color: #F0F7E8 !important;
border-color: #639922 !important;
}
/* ── Block container ── */
.block-container {
padding-top: 3rem !important;
}
/* ── Sidebar inputs β€” keep text dark so it's readable on white background ── */
[data-testid="stSidebar"] [data-testid="stTextInput"] input,
[data-testid="stSidebar"] [data-testid="stTextArea"] textarea {
color: #26215C !important;
background: white !important;
}
[data-testid="stSidebar"] [data-testid="stSelectbox"] span,
[data-testid="stSidebar"] [data-testid="stSelectbox"] div[data-baseweb="select"] * {
color: #26215C !important;
}
/* ── Divider ── */
hr {
border-color: #D0CCF0 !important;
}
/* ── Status widget ── */
[data-testid="stStatus"] {
border-color: #534AB7 !important;
border-radius: 10px !important;
}
</style>
""", unsafe_allow_html=True)