UCS2014 commited on
Commit
8a8dcb3
·
verified ·
1 Parent(s): e2645b8

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +130 -105
app.py CHANGED
@@ -7,51 +7,39 @@ import streamlit as st
7
  BASE_DIR = Path(__file__).parent # -> Landing_Page/
8
  ASSETS = BASE_DIR / "assets" # -> Landing_Page/assets/
9
 
10
- # ========= CONTROLS (tweak these) =========
11
  HERO_LOGO_SIZE = 172 # px
12
- TOP_SPACER = 140 # px (more breathing room at top)
13
- CARD_WIDTH = 260 # px (leaner cards)
14
- CARD_THUMB_HEIGHT = 120 # px (smaller thumbs)
15
- GRID_GAP = 48 # px (more but tighter than 100 when cards are smaller)
16
  BUTTON_TEXT = "Open App"
17
  OPEN_IN_NEW_TAB = False
18
 
19
- # Background image
20
- BACKGROUND_IMAGE = ASSETS / "bg.png"
21
- BACKGROUND_OPACITY = 0.18 # keep subtle; text stays readable
22
- BACKGROUND_BLUR_PX = 3 # add slight blur to reduce busyness
23
-
24
- # ========= BRAND / APPS =========
25
  COMPANY_NAME = "Smart Thinking - Logging"
26
  TAGLINE = "We Deliver Smart AI-Based Solutions For O&G Industry"
 
 
 
 
27
 
28
- # Accent color (brand)
29
- ACCENT = "#0E7490" # teal-ish
30
- ACCENT_SOFT = "rgba(14,116,144,0.12)"
31
-
32
  APP1 = {
33
  "title": "ST_Log_GR",
34
  "url": "https://smart-thinking-gr.hf.space/",
35
- "thumb": ASSETS / "app1.png",
36
- "blurb": "Real-time gamma ray log prediction.",
37
- "bg": "#FBFDFE",
38
- "border":"#D6EAF0",
39
  }
40
  APP2 = {
41
  "title": "ST_Log_Sonic (Ts)",
42
  "url": "https://smart-thinking-sonic-ts.hf.space",
43
- "thumb": ASSETS / "app2.png",
44
  "blurb": "Predict shear slowness (ΔtS) in real time.",
45
- "bg": "#FAFFFB",
46
- "border":"#DAF0D9",
47
  }
48
  APP3 = {
49
  "title": "ST_Log_Sonic (Tc)",
50
  "url": "https://smart-thinking-sonic-tc.hf.space",
51
- "thumb": ASSETS / "app3.png",
52
  "blurb": "Predict compressional slowness (ΔtC) in real time.",
53
- "bg": "#FCFBFF",
54
- "border":"#E4DAF0",
55
  }
56
 
57
  LOGO_PATH = ASSETS / "logo.png"
@@ -60,78 +48,77 @@ LOGO_PATH = ASSETS / "logo.png"
60
  page_icon = str(LOGO_PATH) if LOGO_PATH.exists() else "🧭"
61
  st.set_page_config(page_title=f"{COMPANY_NAME} — Apps", page_icon=page_icon, layout="wide")
62
 
63
- # ========= IMAGE HELPERS =========
64
  def data_uri(path: Path) -> str | None:
65
- if not path.exists(): return None
 
66
  mime, _ = mimetypes.guess_type(path.name)
67
- if not mime: mime = "image/png"
 
68
  b64 = base64.b64encode(path.read_bytes()).decode("utf-8")
69
  return f"data:{mime};base64,{b64}"
70
 
71
- def img_tag(path: Path, alt: str, cls: str) -> str:
72
  uri = data_uri(path)
73
  if uri:
74
- return f'<img class="{cls}" src="{uri}" alt="{escape(alt)}" />'
 
75
  # graceful fallback box if missing
76
  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>'
77
 
78
- # ========= BACKGROUND (robust) =========
79
- def inject_background(image_path: Path, opacity: float = 0.15, blur_px: int = 0) -> None:
80
- uri = data_uri(image_path)
81
- if not uri:
82
- st.caption(f"Background image not found: {image_path}")
83
- return
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
  st.markdown(f"""
85
  <style>
86
- :root {{
87
- --bg-opacity: {max(0.0, min(opacity, 1.0))};
88
- }}
89
-
90
  .stApp {{
91
- position: relative !important;
92
- background: transparent !important;
 
 
 
 
 
93
  }}
94
- [data-testid="stAppViewContainer"],
95
- [data-testid="stAppViewContainer"] > .main,
96
- html, body {{
97
- background: transparent !important;
98
- }}
99
-
100
- /* background layer */
101
  .stApp::before {{
102
  content: "";
103
- position: fixed;
104
- inset: 0;
105
- z-index: 0;
106
- background-image: url('{uri}');
107
- background-size: cover;
108
- background-position: center;
109
- background-repeat: no-repeat;
110
- opacity: var(--bg-opacity);
111
- filter: blur({int(blur_px)}px) saturate(0.9) brightness(1.02);
112
- pointer-events: none;
113
- }}
114
-
115
- /* gradient veil for better readability */
116
- .stApp::after {{
117
- content: "";
118
- position: fixed;
119
- inset: 0;
120
- z-index: 0;
121
- background: radial-gradient(ellipse at center,
122
- rgba(255,255,255,0.75) 0%,
123
- rgba(255,255,255,0.55) 40%,
124
- rgba(255,255,255,0.35) 70%,
125
- rgba(255,255,255,0.15) 100%);
126
  pointer-events: none;
127
  }}
128
-
129
- /* Ensure all content is above the bg */
130
  .stApp > * {{ position: relative; z-index: 1; }}
 
 
131
  </style>
132
  """, unsafe_allow_html=True)
133
 
134
- inject_background(BACKGROUND_IMAGE, BACKGROUND_OPACITY, BACKGROUND_BLUR_PX)
 
135
 
136
  # ========= CORE CSS =========
137
  st.markdown(
@@ -139,10 +126,11 @@ st.markdown(
139
  <style>
140
  :root {{
141
  --top-spacer: {TOP_SPACER}px;
142
- --card-width: {CARD_WIDTH}px; /* we'll override to fixed 260 below */
143
  --grid-gap: {GRID_GAP}px;
144
  --grid-top-space: 28px;
145
  --brand: {ACCENT};
 
 
146
  }}
147
 
148
  html, body, [data-testid="stAppViewContainer"] {{ height: 100%; }}
@@ -158,7 +146,7 @@ st.markdown(
158
  }}
159
 
160
  /* HERO */
161
- .hero {{ text-align:center; margin: 0 0 18px; }}
162
  .hero img {{
163
  width: {HERO_LOGO_SIZE}px; max-width: 95vw; height: auto;
164
  display:block; margin: 0 auto 8px;
@@ -177,7 +165,22 @@ st.markdown(
177
  font-style: italic;
178
  }}
179
 
180
- /* GRID */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
181
  .grid {{
182
  display: grid;
183
  grid-template-columns: repeat(3, 260px);
@@ -193,51 +196,56 @@ st.markdown(
193
  .grid {{ grid-template-columns: 1fr; }}
194
  }}
195
 
 
196
  .card {{
197
  width: 260px;
198
- background: color-mix(in oklab, white 88%, #f6fafe 12%);
199
- border: 1px solid rgba(0,0,0,.06);
200
  border-radius:18px; padding:16px 14px;
201
  box-shadow: 0 6px 28px rgba(2,20,35,.06);
202
  transition: transform .16s ease, box-shadow .16s ease, border-color .16s ease;
203
  text-align:center; display:flex; flex-direction:column; gap:10px;
204
  align-items: center;
205
- backdrop-filter: saturate(1.1) blur(2px);
206
  }}
207
  .card:hover {{
208
  transform: translateY(-4px);
209
  box-shadow: 0 14px 40px rgba(2,20,35,.12);
210
- border-color: {ACCENT_SOFT};
211
  }}
212
 
213
- .thumb {{
214
- width: 100%;
215
- height: {CARD_THUMB_HEIGHT}px;
216
- border-radius:14px;
217
- border:1px solid rgba(0,0,0,.04);
218
- object-fit: contain;
219
- background:#fff;
 
 
 
220
  }}
 
 
 
 
 
 
 
 
221
 
222
  .card h3 {{
223
- margin: 6px 0 0;
224
- font-size: 1.05rem;
225
- font-weight: 700;
226
- letter-spacing: .2px;
227
- color: #0b1220;
228
  }}
229
  .card p {{
230
- color:#495464;
231
- min-height: 34px;
232
- margin: 4px 8px 0;
233
- font-size: .95rem;
234
  }}
235
 
236
- /* Brand gradient button */
237
  .btn {{
238
  display:inline-block; padding:10px 16px; border-radius:12px;
239
  border:1px solid rgba(14,116,144,0.25); text-decoration:none;
240
- background: linear-gradient(90deg, {ACCENT} 0%, #14B8A6 100%);
241
  color: white; font-weight: 600; letter-spacing:.2px;
242
  margin: 8px auto 0;
243
  box-shadow: 0 6px 18px rgba(20,184,166,.28);
@@ -265,21 +273,38 @@ st.markdown(
265
  unsafe_allow_html=True,
266
  )
267
 
 
 
 
 
 
 
 
 
 
 
 
268
  # ========= CARDS =========
269
  def app_card(app: dict) -> str:
270
  target = "_blank" if OPEN_IN_NEW_TAB else "_self"
271
- style = f"--card-bg:{app.get('bg','#fff')}; --card-border:{app.get('border','rgba(0,0,0,.06)')};"
272
- # Leaner cards: keep thumb (icon) but smaller; concise description
273
  return (
274
- f"<div class='card' style='{style}'>"
275
- + img_tag(app['thumb'], app['title'], "thumb")
276
  + f"<h3>{escape(app['title'])}</h3>"
277
  + f"<p>{escape(app['blurb'])}</p>"
278
  + f"<a class='btn' href='{escape(app['url'])}' target='{target}' rel='noopener'>{escape(BUTTON_TEXT)}</a>"
279
  + "</div>"
280
  )
281
 
282
- st.markdown("<div class='grid'>" + app_card(APP1) + app_card(APP2) + app_card(APP3) + "</div>", unsafe_allow_html=True)
 
 
 
 
 
 
 
283
 
284
  # ========= FOOTER =========
285
  st.markdown(
 
7
  BASE_DIR = Path(__file__).parent # -> Landing_Page/
8
  ASSETS = BASE_DIR / "assets" # -> Landing_Page/assets/
9
 
10
+ # ========= CONTROLS =========
11
  HERO_LOGO_SIZE = 172 # px
12
+ TOP_SPACER = 140 # px
13
+ GRID_GAP = 48 # px
 
 
14
  BUTTON_TEXT = "Open App"
15
  OPEN_IN_NEW_TAB = False
16
 
17
+ # BRAND (use a distinct color per suite to differentiate pages)
 
 
 
 
 
18
  COMPANY_NAME = "Smart Thinking - Logging"
19
  TAGLINE = "We Deliver Smart AI-Based Solutions For O&G Industry"
20
+ SUITE_NAME = "ST_LOG SUITE"
21
+ ACCENT = "#0E7490" # teal for Logging
22
+ ACCENT_END = "#14B8A6" # gradient end
23
+ ACCENT_SOFT = "rgba(14,116,144,0.15)"
24
 
25
+ # ========= APPS =========
 
 
 
26
  APP1 = {
27
  "title": "ST_Log_GR",
28
  "url": "https://smart-thinking-gr.hf.space/",
29
+ "blurb": "Real-time gamma-ray log prediction.",
30
+ "icon": ASSETS / "app1_icon.png", # tiny glyph (optional)
 
 
31
  }
32
  APP2 = {
33
  "title": "ST_Log_Sonic (Ts)",
34
  "url": "https://smart-thinking-sonic-ts.hf.space",
 
35
  "blurb": "Predict shear slowness (ΔtS) in real time.",
36
+ "icon": ASSETS / "app2_icon.png",
 
37
  }
38
  APP3 = {
39
  "title": "ST_Log_Sonic (Tc)",
40
  "url": "https://smart-thinking-sonic-tc.hf.space",
 
41
  "blurb": "Predict compressional slowness (ΔtC) in real time.",
42
+ "icon": ASSETS / "app3_icon.png",
 
43
  }
44
 
45
  LOGO_PATH = ASSETS / "logo.png"
 
48
  page_icon = str(LOGO_PATH) if LOGO_PATH.exists() else "🧭"
49
  st.set_page_config(page_title=f"{COMPANY_NAME} — Apps", page_icon=page_icon, layout="wide")
50
 
51
+ # ========= HELPERS =========
52
  def data_uri(path: Path) -> str | None:
53
+ if not path or not path.exists():
54
+ return None
55
  mime, _ = mimetypes.guess_type(path.name)
56
+ if not mime:
57
+ mime = "image/png"
58
  b64 = base64.b64encode(path.read_bytes()).decode("utf-8")
59
  return f"data:{mime};base64,{b64}"
60
 
61
+ def img_tag(path: Path, alt: str, cls: str = "") -> str:
62
  uri = data_uri(path)
63
  if uri:
64
+ cls_attr = f' class="{cls}"' if cls else ""
65
+ return f'<img{cls_attr} src="{uri}" alt="{escape(alt)}" />'
66
  # graceful fallback box if missing
67
  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>'
68
 
69
+ def card_header_badge(icon_path: Path | None, suite_label: str) -> str:
70
+ icon_uri = data_uri(icon_path) if icon_path else None
71
+ icon_html = f"<img src='{icon_uri}' alt='icon' style='width:22px;height:22px;'>" if icon_uri else ""
72
+ return f"""
73
+ <div class="badge">
74
+ <div class="badge-left">{icon_html}</div>
75
+ <div class="badge-right">{escape(suite_label)}</div>
76
+ </div>
77
+ """
78
+
79
+ def inject_subtle_bg() -> None:
80
+ """
81
+ Soft brand gradient + faint SVG grid pattern.
82
+ Comfortable, fast, and doesn't fight content.
83
+ """
84
+ pattern_svg = """
85
+ data:image/svg+xml;utf8,
86
+ <svg xmlns='http://www.w3.org/2000/svg' width='64' height='64' viewBox='0 0 64 64'>
87
+ <defs>
88
+ <pattern id='p' width='32' height='32' patternUnits='userSpaceOnUse'>
89
+ <path d='M0 16 H32 M16 0 V32' stroke='rgba(15,23,42,0.06)' stroke-width='1'/>
90
+ </pattern>
91
+ </defs>
92
+ <rect width='100%' height='100%' fill='url(#p)'/>
93
+ </svg>
94
+ """.strip()
95
+
96
  st.markdown(f"""
97
  <style>
 
 
 
 
98
  .stApp {{
99
+ position: relative;
100
+ background:
101
+ radial-gradient(1200px 600px at 50% 0%,
102
+ rgba(20,184,166,0.14) 0%,
103
+ rgba(14,116,144,0.10) 35%,
104
+ rgba(255,255,255,0.92) 70%,
105
+ rgba(255,255,255,1) 100%) !important;
106
  }}
 
 
 
 
 
 
 
107
  .stApp::before {{
108
  content: "";
109
+ position: fixed; inset: 0; z-index: 0;
110
+ background-image: url("{pattern_svg}");
111
+ opacity: .6;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
112
  pointer-events: none;
113
  }}
 
 
114
  .stApp > * {{ position: relative; z-index: 1; }}
115
+ [data-testid="stAppViewContainer"], [data-testid="stAppViewContainer"] > .main,
116
+ html, body {{ background: transparent !important; }}
117
  </style>
118
  """, unsafe_allow_html=True)
119
 
120
+ # Apply subtle background
121
+ inject_subtle_bg()
122
 
123
  # ========= CORE CSS =========
124
  st.markdown(
 
126
  <style>
127
  :root {{
128
  --top-spacer: {TOP_SPACER}px;
 
129
  --grid-gap: {GRID_GAP}px;
130
  --grid-top-space: 28px;
131
  --brand: {ACCENT};
132
+ --brand2: {ACCENT_END};
133
+ --brandSoft: {ACCENT_SOFT};
134
  }}
135
 
136
  html, body, [data-testid="stAppViewContainer"] {{ height: 100%; }}
 
146
  }}
147
 
148
  /* HERO */
149
+ .hero {{ text-align:center; margin: 0 0 6px; }}
150
  .hero img {{
151
  width: {HERO_LOGO_SIZE}px; max-width: 95vw; height: auto;
152
  display:block; margin: 0 auto 8px;
 
165
  font-style: italic;
166
  }}
167
 
168
+ /* SUITE BANNER */
169
+ .suite-banner {{
170
+ display:flex; gap:12px; justify-content:center; align-items:center;
171
+ margin: 10px 0 12px;
172
+ }}
173
+ .suite-pill {{
174
+ background: linear-gradient(90deg, var(--brand) 0%, var(--brand2) 100%);
175
+ color:#fff; padding:8px 12px; border-radius:999px;
176
+ font-weight:700; letter-spacing:.2px;
177
+ box-shadow: 0 8px 18px rgba(14,116,144,.25);
178
+ }}
179
+ .suite-sub {{
180
+ color:#334155; font-weight:500; opacity:.95;
181
+ }}
182
+
183
+ /* GRID (3 → 2 → 1) */
184
  .grid {{
185
  display: grid;
186
  grid-template-columns: repeat(3, 260px);
 
196
  .grid {{ grid-template-columns: 1fr; }}
197
  }}
198
 
199
+ /* CARD */
200
  .card {{
201
  width: 260px;
202
+ background: rgba(255,255,255,0.9);
203
+ border: 1px solid rgba(2,20,35,.06);
204
  border-radius:18px; padding:16px 14px;
205
  box-shadow: 0 6px 28px rgba(2,20,35,.06);
206
  transition: transform .16s ease, box-shadow .16s ease, border-color .16s ease;
207
  text-align:center; display:flex; flex-direction:column; gap:10px;
208
  align-items: center;
209
+ backdrop-filter: saturate(1.05) blur(2px);
210
  }}
211
  .card:hover {{
212
  transform: translateY(-4px);
213
  box-shadow: 0 14px 40px rgba(2,20,35,.12);
214
+ border-color: var(--brandSoft);
215
  }}
216
 
217
+ /* BADGE (replaces bulky logos) */
218
+ .badge {{
219
+ width:100%;
220
+ display:flex; align-items:center; justify-content:flex-start;
221
+ gap:10px;
222
+ background: linear-gradient(90deg, var(--brand) 0%, var(--brand2) 100%);
223
+ color:#fff;
224
+ padding:10px 12px;
225
+ border-radius:12px;
226
+ box-shadow: 0 8px 18px rgba(14,116,144,.25);
227
  }}
228
+ .badge-left {{
229
+ width:30px; height:30px;
230
+ display:grid; place-items:center;
231
+ background: rgba(255,255,255,.14);
232
+ border-radius:10px; overflow:hidden;
233
+ }}
234
+ .badge-left img {{ width:22px; height:22px; display:block; }}
235
+ .badge-right {{ font-weight:700; letter-spacing:.2px; }}
236
 
237
  .card h3 {{
238
+ margin: 10px 0 0; font-size: 1.06rem; font-weight: 800; color:#0b1220;
 
 
 
 
239
  }}
240
  .card p {{
241
+ color:#495464; min-height: 32px; margin: 6px 6px 0; font-size: .95rem;
 
 
 
242
  }}
243
 
244
+ /* BUTTON (brand gradient) */
245
  .btn {{
246
  display:inline-block; padding:10px 16px; border-radius:12px;
247
  border:1px solid rgba(14,116,144,0.25); text-decoration:none;
248
+ background: linear-gradient(90deg, var(--brand) 0%, var(--brand2) 100%);
249
  color: white; font-weight: 600; letter-spacing:.2px;
250
  margin: 8px auto 0;
251
  box-shadow: 0 6px 18px rgba(20,184,166,.28);
 
273
  unsafe_allow_html=True,
274
  )
275
 
276
+ # ========= SUITE BANNER (differentiates this page) =========
277
+ st.markdown(
278
+ f"""
279
+ <div class="suite-banner">
280
+ <span class="suite-pill">{escape(SUITE_NAME)}</span>
281
+ <span class="suite-sub">Real-time well logging intelligence • 3 apps</span>
282
+ </div>
283
+ """,
284
+ unsafe_allow_html=True,
285
+ )
286
+
287
  # ========= CARDS =========
288
  def app_card(app: dict) -> str:
289
  target = "_blank" if OPEN_IN_NEW_TAB else "_self"
290
+ header = card_header_badge(app.get("icon"), SUITE_NAME)
 
291
  return (
292
+ f"<div class='card'>"
293
+ + header
294
  + f"<h3>{escape(app['title'])}</h3>"
295
  + f"<p>{escape(app['blurb'])}</p>"
296
  + f"<a class='btn' href='{escape(app['url'])}' target='{target}' rel='noopener'>{escape(BUTTON_TEXT)}</a>"
297
  + "</div>"
298
  )
299
 
300
+ st.markdown(
301
+ "<div class='grid'>"
302
+ + app_card(APP1)
303
+ + app_card(APP2)
304
+ + app_card(APP3)
305
+ + "</div>",
306
+ unsafe_allow_html=True,
307
+ )
308
 
309
  # ========= FOOTER =========
310
  st.markdown(