File size: 9,796 Bytes
14a35b3
 
8c3cca9
977f082
8c3cca9
14a35b3
977f082
 
 
 
8c3cca9
977f082
 
 
 
 
 
2821cf4
 
 
 
 
 
 
 
 
 
977f082
 
 
 
 
 
 
 
 
 
 
 
 
14a35b3
 
8c3cca9
977f082
8c3cca9
 
 
 
14a35b3
8c3cca9
14a35b3
 
977f082
8c3cca9
 
 
 
14a35b3
977f082
14a35b3
b4b93f2
 
 
 
 
 
14a35b3
 
2821cf4
 
 
 
977f082
 
 
 
 
 
 
 
 
 
 
8c3cca9
977f082
8c3cca9
977f082
 
8c3cca9
977f082
8c3cca9
 
977f082
8c3cca9
 
977f082
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2821cf4
8c3cca9
977f082
 
 
 
 
 
 
 
 
 
 
8c3cca9
2821cf4
8c3cca9
977f082
8c3cca9
977f082
 
 
 
8c3cca9
977f082
8c3cca9
 
977f082
 
 
8c3cca9
977f082
8c3cca9
977f082
 
8c3cca9
 
977f082
 
 
8c3cca9
 
977f082
8c3cca9
 
 
2821cf4
 
14a35b3
 
8c3cca9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2821cf4
8c3cca9
 
 
2821cf4
8c3cca9
 
14a35b3
8c3cca9
14a35b3
 
2821cf4
 
 
 
 
 
 
 
 
 
 
 
8c3cca9
2821cf4
 
 
8c3cca9
14a35b3
2821cf4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8c3cca9
14a35b3
8c3cca9
977f082
14a35b3
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
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
import streamlit as st
import random
from io import BytesIO
from pathlib import Path
from PIL import Image, ImageDraw, ImageFont

# ------------------- BRAND CONFIG -------------------
BRAND = "#0F2C59"   # Procelevate navy
ACCENT = "#00FFFF"  # Cyan glow
PINK   = "#FF00FF"  # Magenta glow

st.set_page_config(
    page_title="AI Name Magic - Procelevate",
    page_icon="โœจ",
    layout="centered",
)

# ------------------- SESSION STATE -------------------
if "gallery" not in st.session_state:
    st.session_state.gallery = []  # list of dicts: {"img": bytes, "name": str, "fact": str}
if "current_name" not in st.session_state:
    st.session_state.current_name = ""
if "current_fact" not in st.session_state:
    st.session_state.current_fact = ""
if "current_card" not in st.session_state:
    st.session_state.current_card = None

# ------------------- HEADER (CENTERED LOGO) -------------------
# Try a few common locations for the logo so path changes don't break the app.
logo_candidates = [
    "src/procelevate_logo.png",
    "src/assets/procelevate_logo.png",
    "procelevate_logo.png",
]
logo_path = next((p for p in logo_candidates if Path(p).exists()), None)

if logo_path:
    c1, c2, c3 = st.columns([1, 2, 1])
    with c2:
        st.image(logo_path, width=150)

st.markdown(
    f"""
    <div style="text-align:center; margin-top:4px;">
      <h1 style="margin:0; color:{BRAND};">AI Name Magic โœจ</h1>
      <div style="font-size:20px; color:#1f2937;">Powered by <b style="color:{BRAND};">Procelevate Consulting</b></div>
    </div>
    <hr style="opacity:.2;"/>
    """,
    unsafe_allow_html=True,
)

# ------------------- INPUT FORM -------------------
with st.form("name_form", clear_on_submit=False):
    st.subheader("๐Ÿ”ฎ Type Your Name & See AI Magic")
    name = st.text_input("Enter your name:")
    submitted = st.form_submit_button("Show My AI Prediction ๐Ÿš€")

# ------------------- PREDICTION POOL -------------------
facts = [
    "It's a beautiful name...AI predicts youโ€™ll be a Future Innovator. Keep rocking..! ๐Ÿš€",
    "It's a beautiful name...Your curiosity will power the next big idea. Keep inspiring...! ๐Ÿ’ก",
    "It's a beautiful name...You might be the Next Data Scientist / Data Engineer. Best Wishes for you....! ๐Ÿ“Š",
    "It's a beautiful name...AI says youโ€™ll shape the Future of Tech. Thank you future CTO...! ๐Ÿค–",
    "It's a beautiful name...Leadership and technology is in your DNA ๐ŸŒŸ",
    "It's a beautiful name...AI foresees a potential CEO / CTO of a big company ๐ŸŒ",
]

def choose_new_fact(exclude=None):
    pool = [f for f in facts if f != exclude] or facts
    return random.choice(pool)

# ------------------- IMAGE GENERATOR (PNG CARD) -------------------
def _load_font(path_candidates, size):
    """Try to load a TTF font from common paths; fall back to default."""
    for p in path_candidates:
        if Path(p).exists():
            try:
                return ImageFont.truetype(p, size)
            except Exception:
                pass
    return ImageFont.load_default()

def make_card(name_text: str, fact_text: str) -> bytes:
    """Create a branded 'Future Me Card' PNG and return bytes."""
    W, H = 1200, 630
    base = Image.new("RGB", (W, H), (15, 44, 89))  # #0F2C59
    draw = ImageDraw.Draw(base)

    # Subtle cyan gradient overlay
    grad = Image.new("RGB", (W, H))
    for y in range(H):
        c = int(255 * (y / H) * 0.18)
        grad.putpixel((0, y), (0, 180, 180 - c))
    grad = grad.resize((W, H))
    base = Image.blend(base, grad, 0.15)
    draw = ImageDraw.Draw(base)

    # Fonts: try DejaVu (available if installed), else default
    dejavu_bold = [
        "/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf",
        "/usr/local/share/fonts/DejaVuSans-Bold.ttf",
    ]
    dejavu = [
        "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf",
        "/usr/local/share/fonts/DejaVuSans.ttf",
    ]
    title_font = _load_font(dejavu_bold, 70)
    name_font  = _load_font(dejavu_bold, 120)
    fact_font  = _load_font(dejavu, 46)
    foot_font  = _load_font(dejavu, 28)

    # Paste logo if available (resolve relative to this file)
    try:
        local_dir = Path(__file__).parent
        lp = None
        for cand in ["procelevate_logo.png", "assets/procelevate_logo.png", "../procelevate_logo.png"]:
            p = (local_dir / cand).resolve()
            if p.exists():
                lp = p
                break
        if lp:
            logo = Image.open(lp).convert("RGBA")
            logo = logo.resize((140, 140))
            base.paste(logo, (50, 50), logo)
    except Exception:
        pass  # OK if logo missing

    # Title pill
    title = "YOUR AI PREDICTION"
    tw = draw.textlength(title, font=title_font)
    th = getattr(title_font, "size", 70)
    draw.rounded_rectangle([(400, 70), (400 + tw + 60, 70 + th + 40)], radius=18, fill=(255, 255, 255))
    draw.text((430, 90), title, font=title_font, fill=(15, 44, 89))

    # Neon name
    name_text = name_text.upper()
    nx, ny = 120, 260
    draw.text((nx + 6, ny + 6), name_text, font=name_font, fill=(255, 0, 255))   # magenta shadow
    draw.text((nx - 6, ny - 6), name_text, font=name_font, fill=(0, 255, 255))   # cyan shadow
    draw.text((nx, ny), name_text, font=name_font, fill=(255, 255, 255))         # white main

    # Fact chip
    fact_box_y = ny + 170
    draw.rounded_rectangle([(80, fact_box_y), (W - 80, fact_box_y + 170)], radius=24, fill=(255, 255, 255))
    draw.text((110, fact_box_y + 55), f"โœจ {fact_text}", font=fact_font, fill=(15, 44, 89))

    # Footer
    footer = "ยฉ Procelevate Consulting โ€ข Elevating Processes. Empowering People."
    fw = draw.textlength(footer, font=foot_font)
    draw.text(((W - fw) // 2, H - 60), footer, font=foot_font, fill=(230, 240, 245))

    buf = BytesIO()
    base.save(buf, format="PNG")
    buf.seek(0)
    return buf.getvalue()

# ------------------- RENDER RESULT BLOCK -------------------
def render_result(name_text: str, fact_text: str):
    st.markdown(
        f"""
        <div style="
            margin: 10px auto 0 auto;
            max-width: 820px;
            text-align:center;
            padding: 18px 22px;
            border-radius: 16px;
            background:
                radial-gradient(circle at 20% 10%, rgba(0,255,255,.25), transparent 40%),
                radial-gradient(circle at 80% 0%, rgba(255,0,255,.25), transparent 35%),
                linear-gradient(180deg, #ffffff 0%, #f7fbff 100%);
            border: 2px solid #e6eef7;">
          <div style="font-size:14px; letter-spacing:1px; color:{BRAND}; font-weight:700;
                      display:inline-block; padding:6px 12px; border-radius:999px; background:#e6f3ff; margin-bottom:8px;">
            YOUR AI PREDICTION
          </div>
          <h1 style="margin:4px 0 8px 0; font-size:56px; color:{BRAND};
                     text-shadow: 2px 2px {ACCENT}, -2px -2px {PINK};">
            {name_text.upper()}
          </h1>
          <div style="font-size:22px; color:#0b2239; padding:12px 16px; border-radius:12px;
                      background:#f0f9ff; display:inline-block;">
            โœจ {fact_text}
          </div>
        </div>
        """,
        unsafe_allow_html=True,
    )

# ------------------- HANDLE SUBMIT -------------------
if submitted and name.strip():
    st.session_state.current_name = name.strip()
    st.session_state.current_fact = choose_new_fact(None)
    st.session_state.current_card = make_card(st.session_state.current_name, st.session_state.current_fact)

    # Add to gallery (cap 5 latest)
    st.session_state.gallery = (st.session_state.gallery + [{
        "img": st.session_state.current_card,
        "name": st.session_state.current_name,
        "fact": st.session_state.current_fact
    }])[-5:]

    st.balloons()

elif submitted and not name.strip():
    st.warning("Please enter your name first ๐Ÿ™‚")

# ------------------- TRY ANOTHER PREDICTION BUTTON -------------------
# Show only if we already have a name
if st.session_state.current_name:
    try_another = st.button("๐Ÿ”„ Try another prediction")
    if try_another:
        st.session_state.current_fact = choose_new_fact(st.session_state.current_fact)
        st.session_state.current_card = make_card(st.session_state.current_name, st.session_state.current_fact)
        st.session_state.gallery = (st.session_state.gallery + [{
            "img": st.session_state.current_card,
            "name": st.session_state.current_name,
            "fact": st.session_state.current_fact
        }])[-5:]

# ------------------- SHOW RESULT (IF ANY) -------------------
if st.session_state.current_name and st.session_state.current_fact:
    render_result(st.session_state.current_name, st.session_state.current_fact)

    # Download button for the latest card
    if st.session_state.current_card:
        st.download_button(
            "โฌ‡๏ธ Download My Future Me Card (PNG)",
            data=st.session_state.current_card,
            file_name=f"{st.session_state.current_name.replace(' ','_')}_future_me.png",
            mime="image/png",
        )

# ------------------- LIVE GALLERY (LAST 5) -------------------
if st.session_state.gallery:
    st.markdown("<hr style='opacity:.15;'/>", unsafe_allow_html=True)
    st.subheader("๐Ÿ“ธ Live Gallery (latest 5)")
    items = list(reversed(st.session_state.gallery))  # newest first
    cols = st.columns(len(items))
    for col, item in zip(cols, items):
        with col:
            st.image(item["img"], caption=item["name"], use_container_width=True)

st.markdown("<hr style='opacity:.2;'/>", unsafe_allow_html=True)
st.markdown(
    "<p style='text-align:center; font-size:14px;'>ยฉ 2025 Procelevate Consulting</p>",
    unsafe_allow_html=True,
)