Spaces:
Sleeping
Sleeping
| import base64 | |
| from pathlib import Path | |
| import streamlit as st | |
| import os | |
| # Choose one of these: | |
| # A) Env var: APP_ENV=prod on your server / cloud | |
| APP_ENV = os.getenv("natsar", "local").lower() | |
| # B) Or secrets: put env="prod" in .streamlit/secrets.toml on your server | |
| # APP_ENV = st.secrets.get("env", "local").lower() | |
| IS_LOCAL = True | |
| # … later, where you currently render your Deploy controls … | |
| if IS_LOCAL: | |
| st.markdown(""" | |
| <style> | |
| /* Hide the toolbar and header (which creates the black bar) */ | |
| [data-testid="stToolbar"] { display: none !important; } | |
| header[data-testid="stHeader"] { display: none !important; } | |
| /* (Legacy fallbacks) */ | |
| #MainMenu { visibility: hidden; } | |
| footer { visibility: hidden; } | |
| /* Remove the empty space the header leaves behind */ | |
| [data-testid="stAppViewContainer"] { padding-top: 0 !important; } | |
| [data-testid="stAppViewContainer"] .main .block-container { padding-top: 0 !important; } | |
| /* Give the sidebar a little breathing room at the top */ | |
| section[data-testid="stSidebar"] > div:first-child { padding-top: 0.5rem; } | |
| </style> | |
| """, unsafe_allow_html=True) | |
| def local_image_to_data_url(path: str | Path) -> str: | |
| """Convert a local image into a base64 data URL for inlined CSS backgrounds.""" | |
| p = Path(path) | |
| if not p.is_absolute(): | |
| p = Path(__file__).parent / p | |
| mime = "image/png" if p.suffix.lower() == ".png" else "image/jpeg" | |
| b64 = base64.b64encode(p.read_bytes()).decode() | |
| return f"data:{mime};base64,{b64}" | |
| def main() -> None: | |
| st.set_page_config( | |
| page_title="Home", | |
| layout="wide", | |
| initial_sidebar_state="expanded", | |
| ) | |
| # --- Load logo --- | |
| logo_path = "resources/images/lucid_insights_logo.png" # update path as needed | |
| logo_data_url = local_image_to_data_url(logo_path) | |
| with st.sidebar: | |
| # --- Display left-aligned logo above Home menu --- | |
| st.markdown( | |
| f""" | |
| <div style="text-align:left; margin-bottom: 1rem; margin-left: 0.3rem;"> | |
| <img src="{logo_data_url}" style="width: 150px; height: auto;" alt="Lucid Insights Logo"> | |
| </div> | |
| """, | |
| unsafe_allow_html=True, | |
| ) | |
| st.markdown("---") | |
| # --- Sidebar navigation --- | |
| st.markdown("") | |
| st.page_link("app.py", label="Home") | |
| # st.page_link("pages/lost_at_sea.py", label="Lost at Sea") | |
| st.page_link("pages/signal_watch.py", label="Signal Watch") | |
| st.page_link("pages/bushland_beacon.py", label="Bushland Beacon") | |
| st.page_link("pages/misc_find.py", label="Misc Finder") | |
| st.markdown("---") | |
| st.page_link("pages/task_drone.py", label="Task Drone") | |
| st.page_link("pages/task_satellite.py", label="Task Satellite") | |
| st.page_link("pages/information.py", label="Information") | |
| # --- Background setup --- | |
| bg_image = local_image_to_data_url("resources/images/rescue3.jpg") | |
| hide_default_css = """ | |
| <style> | |
| #MainMenu {visibility: hidden;} | |
| footer {visibility: hidden;} | |
| .block-container {padding-top: 0rem; padding-bottom: 0rem;} | |
| </style> | |
| """ | |
| st.markdown(hide_default_css, unsafe_allow_html=True) | |
| st.markdown( | |
| f""" | |
| <style> | |
| :root {{ | |
| --text: #ffffff; | |
| --text-dim: rgba(255,255,255,0.85); | |
| --cta: #3e6ae1; | |
| --cta-alt: #f4f4f4; | |
| }} | |
| /* Fixed full-screen background */ | |
| .stApp {{ | |
| background: | |
| linear-gradient(rgba(0, 164, 255, 0.2), rgba(0, 0, 0, 0.2)), | |
| url("{bg_image}") no-repeat center center fixed; | |
| background-size: cover; | |
| }} | |
| /* Sidebar styling */ | |
| [data-testid="stSidebar"] > div:first-child {{ | |
| background-color: rgba(255,255,255,0); | |
| backdrop-filter: blur(4px); | |
| }} | |
| .hero {{ | |
| position: relative; | |
| min-height: 92vh; | |
| width: 100%; | |
| display: grid; | |
| place-items: center; | |
| text-align: center; | |
| color: var(--text); | |
| }} | |
| .hero .content {{ | |
| max-width: 1100px; | |
| padding: 2rem 1rem 5rem; | |
| }} | |
| .hero h1 {{ | |
| font-size: clamp(3rem, 5vw, 7rem); | |
| font-weight: 500; | |
| letter-spacing: 0.3px; | |
| margin: 0 0 1rem 0; | |
| color: yellow; | |
| }} | |
| .hero h2 {{ | |
| font-size: clamp(1.6rem, 3vw, 4rem); | |
| font-weight: 500; | |
| letter-spacing: 0.3px; | |
| margin: 0 0 1rem 0; | |
| }} | |
| .hero .disclaimer {{ | |
| font-size: clamp(1rem, 2.1vw, 1.3rem); | |
| color: var(--text-dim); | |
| margin-bottom: 1.4rem; | |
| }} | |
| .hero .subtitle {{ | |
| font-size: clamp(1.7rem, 2.1vw, 2.0rem); | |
| font-weight: bold; | |
| color: var(--text-dim); | |
| margin-bottom: 1.4rem; | |
| }} | |
| .hero .ctas {{ | |
| display: flex; | |
| gap: 0.8rem; | |
| justify-content: center; | |
| flex-wrap: wrap; | |
| }} | |
| </style> | |
| """, | |
| unsafe_allow_html=True, | |
| ) | |
| # --- Main content --- | |
| st.markdown( | |
| """ | |
| <section class="hero"> | |
| <div class="content"> | |
| <h1>SAR-X<sup>ai</sup></h1> | |
| <h2>Detection Hub</h2> | |
| <div class="subtitle"> | |
| AI-powered person recognition | |
| </div> | |
| <div class="disclaimer"> | |
| (fictional web app) | |
| </div> | |
| </div> | |
| </section> | |
| """, | |
| unsafe_allow_html=True, | |
| ) | |
| if __name__ == "__main__": | |
| main() | |