# -*- coding: utf-8 -*- from typing import Optional, Dict, Any import base64, mimetypes from html import escape from pathlib import Path import streamlit as st # ========= PATHS ========= BASE_DIR = Path(__file__).parent ASSETS = BASE_DIR / "assets" # ========= META ========= st.set_page_config(page_title="ST_LOG SUITE", layout="wide") # ========= GLOBAL THEME (one place) ========= THEME: Dict[str, Any] = { "strip": { "gap": 10, # px between pill and tagline "below_gap": 30, # px between strip row and hero "pill_pad_v": 8, # px "pill_pad_h": 14, # px "pill_font": 16, # px "tagline_font": 15, # px # GOLD header palette (high contrast) "bg1": "#D4AF37", # gold "bg2": "#B88917", # deeper gold "text": "#0B1220", # dark text in pill for contrast "tagline_color": "#000000", }, "page": { "top_padding": 50, "container_width": 1120, "bg_radial": True, }, "hero": { "width": 400, "margin_bottom": 30, "logo": ASSETS / "AI_Suite_Log_logo.png", }, "grid": { "gap": 50, "card_width": 340, }, "card": { "radius": 22, "border_width": 2, "pad_v": 24, "pad_h": 20, "border": "#0B1220", "border_hover": "#243447", "bg_top": "#FFFFFF", "bg_bot": "#FBFCFE", "title_color": "#0B1220", "blurb_color": "#566275", }, "icon": { "diam": 118, "img": 106, "circle_bg": "#F1F5F9", "circle_border": "rgba(12,18,32,0.10)", }, "button": { "pad_v": 12, "pad_h": 20, "radius": 14, "bg1": "#0B1220", "bg2": "#162338", "text": "#FFFFFF", "border": "rgba(11,18,32,.55)", }, } # ========= CARDS ========= CARDS = [ { "title": " ST_Log_GR", "blurb": "Real-time gamma-ray log prediction.", "url": "https://smart-thinking-gr.hf.space/", "icon": ASSETS / "GR_logo.png", "style": { "bg_top": "#EAF7F1", "bg_bot": "#F6FBF8", "border": "#0F3D3E", }, }, { "title": " ST_Log_Sonic (Ts)", "blurb": "Predict shear slowness (DtS) in real time.", "url": "https://smart-thinking-sonic-ts.hf.space", "icon": ASSETS / "Ts_logo.png", "style": { "bg_top": "#EAF7FD", "bg_bot": "#F5FBFF", "border": "#0E4A6E", }, }, { "title": " ST_Log_Sonic (Tc)", "blurb": "Predict compressional slowness (DtC) in real time.", "url": "https://smart-thinking-sonic-tc.hf.space", "icon": ASSETS / "Tc_logo.png", "style": { "bg_top": "#EEF0FF", "bg_bot": "#F7F8FF", "border": "#3E4EB8", }, }, ] # ========= Helpers ========= def data_uri(path: Path) -> Optional[str]: if not path or not path.exists(): return None mime, _ = mimetypes.guess_type(path.name) if not mime: mime = "image/png" b64 = base64.b64encode(path.read_bytes()).decode("utf-8") return f"data:{mime};base64,{b64}" def img_tag(path: Path, alt: str, cls: str = "", style: str = "") -> str: uri = data_uri(path) if not uri: return "" cls_attr = f' class="{cls}"' if cls else "" style_attr = f' style="{style}"' if style else "" return f'' # ========= CSS ========= strip = THEME["strip"]; page = THEME["page"]; hero = THEME["hero"] grid = THEME["grid"]; card = THEME["card"]; icon = THEME["icon"]; button = THEME["button"] bg_radial_css = """ background: radial-gradient(980px 460px at 50% -140px, rgba(2,12,30,0.06) 0%, rgba(2,12,30,0.04) 28%, rgba(255,255,255,0.98) 60%, rgba(255,255,255,1) 100%); """ if page["bg_radial"] else "background: #fff;" st.markdown(f""" """, unsafe_allow_html=True) # ========= Strip (top-left) ========= st.markdown( f"""
{"ST_LOG SUITE"} {"Generating AI-Based Well Logging Profiles While Drilling"}
""", unsafe_allow_html=True, ) # ========= Hero ========= hero_html = img_tag(THEME["hero"]["logo"], "ST_LOG SUITE") st.markdown(f"
{hero_html}
", unsafe_allow_html=True) def build_card_vars(style: Dict[str, Any]) -> str: s = [] if "width" in style: s.append(f"--c-w:{int(style['width'])}px") if "radius" in style: s.append(f"--c-radius:{int(style['radius'])}px") if "pad_v" in style: s.append(f"--c-pv:{int(style['pad_v'])}px") if "pad_h" in style: s.append(f"--c-ph:{int(style['pad_h'])}px") if "bg_top" in style: s.append(f"--c-bg-top:{style['bg_top']}") if "bg_bot" in style: s.append(f"--c-bg-bot:{style['bg_bot']}") if "border" in style: s.append(f"--c-border:{style['border']}") if "border_width" in style: s.append(f"--c-bw:{int(style['border_width'])}px") if "title_color" in style: s.append(f"--c-title-color:{style['title_color']}") if "title_fs" in style: s.append(f"--c-title-fs:{int(style['title_fs'])}px") if "blurb_color" in style: s.append(f"--c-blurb-color:{style['blurb_color']}") if "blurb_fs" in style: s.append(f"--c-blurb-fs:{int(style['blurb_fs'])}px") if "btn_bg1" in style: s.append(f"--c-btn-bg1:{style['btn_bg1']}") if "btn_bg2" in style: s.append(f"--c-btn-bg2:{style['btn_bg2']}") if "btn_text" in style: s.append(f"--c-btn-text:{style['btn_text']}") if "btn_border" in style: s.append(f"--c-btn-border:{style['btn_border']}") if "btn_fs" in style: s.append(f"--c-btn-fs:{int(style['btn_fs'])}px") if "btn_pad_v" in style: s.append(f"--c-btn-pv:{int(style['btn_pad_v'])}px") if "btn_pad_h" in style: s.append(f"--c-btn-ph:{int(style['btn_pad_h'])}px") if "icon_diam" in style: s.append(f"--c-icon-d:{int(style['icon_diam'])}px") if "icon_img" in style: s.append(f"--c-icon-img:{int(style['icon_img'])}px") if "icon_bg" in style: s.append(f"--c-icon-bg:{style['icon_bg']}") if "icon_border" in style: s.append(f"--c-icon-border:{style['icon_border']}") return "; ".join(s) def app_card(card_cfg: Dict[str, Any]) -> str: style = card_cfg.get("style", {}) vars_inline = build_card_vars(style) icon_html = img_tag(card_cfg.get("icon"), "icon") if card_cfg.get("icon") and card_cfg["icon"].exists() else "" target = "_self" return ( f"
" + f"
{icon_html}
" + f"

{escape(card_cfg['title'])}

" + f"

{escape(card_cfg['blurb'])}

" + f"Run App" + "
" ) st.markdown("
" + "".join(app_card(c) for c in CARDS) + "
", unsafe_allow_html=True) # ========= Footer ========= st.markdown( """
""", unsafe_allow_html=True, )