File size: 7,468 Bytes
216b468 8ec6473 3a3b3ae 8ec6473 674b03f 216b468 41d63dd 216b468 ea51ae8 95adf40 ea51ae8 95adf40 41d63dd ea51ae8 c7e583c 674b03f 44926e2 41d63dd 8ec6473 c7e583c 57b94f2 41d63dd 44926e2 a7476c3 c7e583c 57b94f2 41d63dd 44926e2 a7476c3 c7e583c 95adf40 57b94f2 90fe7e3 95adf40 90fe7e3 95adf40 8ec6473 c7e583c 674b03f 3a3b3ae 6849280 c7e583c ea51ae8 c7e583c 216b468 c7e583c ea51ae8 2f7ec63 ea51ae8 41d63dd ea51ae8 41d63dd 674b03f a7476c3 674b03f a7476c3 ea51ae8 a7476c3 41d63dd 674b03f ea51ae8 41d63dd ea51ae8 41d63dd 50e6982 95adf40 50e6982 95adf40 50e6982 41d63dd 50e6982 ea51ae8 95adf40 ea51ae8 95adf40 ea51ae8 41d63dd ea51ae8 a7476c3 25e4f62 ea51ae8 41d63dd 25e4f62 95adf40 25e4f62 41d63dd ea51ae8 41d63dd 95adf40 41d63dd 25e4f62 41d63dd ea51ae8 c7e583c 674b03f 41d63dd 3a3b3ae 41d63dd 3a3b3ae 41d63dd 3a3b3ae 41d63dd 3a3b3ae 25e4f62 6849280 41d63dd 6849280 c7e583c 25e4f62 3a3b3ae 216b468 a7476c3 674b03f a7476c3 674b03f 95adf40 674b03f ea51ae8 90fe7e3 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 |
import base64, mimetypes
from html import escape
from pathlib import Path
import streamlit as st
# ========= PATHS (subfolder-safe) =========
BASE_DIR = Path(__file__).parent # -> Landing_Page/
ASSETS = BASE_DIR / "assets" # -> Landing_Page/assets/
# ========= CONTROLS (tweak these) =========
HERO_LOGO_SIZE = 160 # px (top company logo size)
TOP_SPACER = 100 # px (breathing room above hero; raise if the logo looks "trimmed")
CARD_WIDTH = 300 # px (fixed width per card on desktop)
CARD_THUMB_HEIGHT = 120 # px (image area inside each card)
GRID_GAP = 80 # px (space between the cards)
BUTTON_TEXT = "Click to Run APP"
OPEN_IN_NEW_TAB = False # True = open links in a new tab
# ========= BRAND / APPS =========
COMPANY_NAME = "Smart Thinking"
TAGLINE = "We Deliver Smart AI-Based Solutions For O&G Industry"
APP1 = {
"title": "ST_GeoMech",
"url": "https://smart-thinking-ai-suite-geomech.hf.space",
"thumb": ASSETS / "app1.png",
"blurb": "Real-Time UCS Prediction",
"bg": "#F7FBFF", # very light blue
"border":"#E8F2FF", # light blue border
}
APP2 = {
"title": "ST_TOC",
"url": "https://smart-thinking-gr.hf.space/",
"thumb": ASSETS / "app2.png",
"blurb": "Real-Time GR Log Prediction",
"bg": "#F6FFF7", # very light green
"border":"#E4F9E6", # light green border
}
# NEW third card (edit title/url/blurb/thumb/colors as needed)
APP3 = {
"title": "ST_Perm",
"url": "https://example.com/", # <-- replace with your Space URL
"thumb": ASSETS / "app3.png", # <-- upload this image
"blurb": "Describe your third app here",
"bg": "#F9F6FF", # very light purple
"border":"#EDE6FF", # light purple border
}
APP4 = {
"title": "ST_Porosity",
"url": "https://example.com/", # <-- replace with your Space URL
"thumb": ASSETS / "app3.png", # <-- upload this image
"blurb": "Describe your third app here",
"bg": "#F9F6FF", # very light purple
"border":"#EDE6FF", # light purple border
}
LOGO_PATH = ASSETS / "logo.png"
# ========= PAGE META =========
page_icon = str(LOGO_PATH) if LOGO_PATH.exists() else "🧭"
st.set_page_config(page_title=f"{COMPANY_NAME} — Apps", page_icon=page_icon, layout="wide")
# ========= CSS (fits one screen on desktop; no blank area under cards) =========
st.markdown(
f"""
<style>
:root {{
--top-spacer: {TOP_SPACER}px;
--card-width: {CARD_WIDTH}px;
--grid-gap: {GRID_GAP}px;
--tagline-gap: 0px; /* distance between H1 and tagline */
--grid-top-space: 20px; /* space above the cards */
}}
html, body, [data-testid="stAppViewContainer"] {{ height: 100%; }}
[data-testid="stAppViewContainer"] > .main {{ padding-top: 0 !important; padding-bottom: 0 !important; }}
.block-container {{
max-width: 1120px;
min-height: 100vh;
display: flex; flex-direction: column;
justify-content: center;
gap: 10px;
padding: var(--top-spacer) 0 8px !important;
}}
/* HERO */
.hero {{ text-align:center; margin: 0 0 8px; }}
.hero img {{
width: {HERO_LOGO_SIZE}px; max-width: 95vw; height: auto;
display:block; margin: 0 auto 8px;
filter: drop-shadow(0 2px 8px rgba(0,0,0,.12));
}}
/* Make tagline closer to the company name */
.hero h1 {{ font-size: 2.3rem; margin: .2rem 0 0; }}
.hero p {{
color: #5a5f6a;
margin: var(--tagline-gap) auto 0;
max-width: 720px;
font-style: italic;
}}
/* GRID: precise card width + extra space above cards */
.grid {{
display: flex;
gap: var(--grid-gap);
justify-content: center;
align-items: stretch;
flex-wrap: nowrap; /* keep three across on desktop */
margin-top: var(--grid-top-space);
}}
/* When viewport too narrow for 3-up, allow wrapping */
@media (max-width: calc(3 * var(--card-width) + 2 * var(--grid-gap) + 64px)) {{
.grid {{ flex-wrap: wrap; }}
}}
.card {{
width: var(--card-width);
background: var(--card-bg, #fff);
border: 1px solid var(--card-border, rgba(0,0,0,.06));
border-radius:16px; padding:14px;
box-shadow:0 4px 18px rgba(0,0,0,.05);
transition:transform .12s ease, box-shadow .12s ease;
text-align:center; display:flex; flex-direction:column; gap:10px;
}}
.card:hover {{ transform: translateY(-2px); box-shadow: 0 10px 28px rgba(0,0,0,.08); }}
.thumb {{
width: 100%;
height: {CARD_THUMB_HEIGHT}px;
border-radius:14px;
border:1px solid rgba(0,0,0,.06);
object-fit: contain; /* show full image */
background:#fff;
}}
.card h3 {{ margin:6px 0 2px; }}
.card p {{ color:#5a5f6a; min-height:30px; margin:0 8px 2px; }}
/* Light button with dark text */
.btn {{
display:inline-block; padding:10px 14px; border-radius:12px;
border:1px solid #e5e7eb; text-decoration:none;
background:#f3f4f6; color:#111827; font-weight:500;
}}
.btn:hover {{ background:#e5e7eb; }}
.footer {{ text-align:center; color:#6b7280; font-size:1.0em; margin-top: 6px; }}
.footer hr {{ margin: 6px 0; }}
</style>
""",
unsafe_allow_html=True,
)
# ========= IMAGE HELPERS =========
def data_uri(path: Path) -> str | None:
if 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) -> str:
uri = data_uri(path)
if uri:
return f'<img class="{cls}" src="{uri}" alt="{escape(alt)}" />'
return f'<div class="{cls}" style="display:flex;align-items:center;justify-content:center;color:#50545c;background:linear-gradient(180deg,#f6f7fb,#eceff4);">{escape(alt)}</div>'
# ========= HERO =========
st.markdown(
'<div class="hero">'
+ (img_tag(LOGO_PATH, "logo", "") if LOGO_PATH.exists() else "")
+ f"<h1>{escape(COMPANY_NAME)}</h1>"
+ f"<p>{escape(TAGLINE)}</p>"
+ "</div>",
unsafe_allow_html=True,
)
# ========= CARDS =========
def app_card(app: dict) -> str:
target = "_blank" if OPEN_IN_NEW_TAB else "_self"
style = f"--card-bg:{app.get('bg','#fff')}; --card-border:{app.get('border','rgba(0,0,0,.06)')};"
return (
f"<div class='card' style='{style}'>"
+ img_tag(app["thumb"], app["title"], "thumb")
+ f"<h3>{escape(app['title'])}</h3>"
+ f"<p>{escape(app['blurb'])}</p>"
+ f"<a class='btn' href='{escape(app['url'])}' target='{target}'>{escape(BUTTON_TEXT)}</a>"
+ "</div>"
)
# Render 3 cards side-by-side
st.markdown("<div class='grid'>" + app_card(APP1) + app_card(APP2) + app_card(APP3) + "</div>", unsafe_allow_html=True)
# ========= FOOTER (compact; no extra spacing) =========
st.markdown(
"""
<hr>
<div class='footer'>
© 2025 Smart Thinking AI-Solutions Team. All rights reserved.<br>
Website: <a href="https://smartthinking.com.sa" target="_blank" rel="noopener noreferrer">smartthinking.com.sa</a>
</div>
""",
unsafe_allow_html=True,
)
|