pounce/backend/app/services/yield_landing_page.py
Yves Gugger 8c499ddccd
Some checks failed
CI / Frontend Lint & Type Check (push) Has been cancelled
CI / Frontend Build (push) Has been cancelled
CI / Backend Lint (push) Has been cancelled
CI / Backend Tests (push) Has been cancelled
CI / Docker Build (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
Deploy / Build & Push Images (push) Has been cancelled
Deploy / Deploy to Server (push) Has been cancelled
Deploy / Notify (push) Has been cancelled
Deploy: 2025-12-17 16:34
2025-12-17 16:34:27 +01:00

106 lines
2.9 KiB
Python

"""
Generate a minimal, SEO-friendly landing page HTML for Yield domains.
The content comes from LLM-generated config stored on YieldDomain.
No placeholders or demo content: if required fields are missing, caller should error.
"""
from __future__ import annotations
from html import escape
from app.models.yield_domain import YieldDomain
def render_yield_landing_html(*, yield_domain: YieldDomain, cta_url: str) -> str:
headline = (yield_domain.landing_headline or "").strip()
intro = (yield_domain.landing_intro or "").strip()
cta_label = (yield_domain.landing_cta_label or "").strip()
if not headline or not intro or not cta_label:
raise ValueError("Yield landing config missing (headline/intro/cta_label)")
# Simple premium dark theme, fast to render, readable.
# Important: CTA must point to cta_url (which will record the click + redirect).
return f"""<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>{escape(headline)}</title>
<meta name="description" content="{escape(intro[:160])}" />
<style>
:root {{
--bg: #050505;
--panel: rgba(255,255,255,0.03);
--border: rgba(255,255,255,0.12);
--text: rgba(255,255,255,0.92);
--muted: rgba(255,255,255,0.60);
--accent: #10b981;
}}
html, body {{
margin: 0;
padding: 0;
background: var(--bg);
color: var(--text);
font-family: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, "Apple Color Emoji", "Segoe UI Emoji";
}}
.wrap {{
max-width: 920px;
margin: 0 auto;
padding: 48px 20px;
}}
.card {{
border: 1px solid var(--border);
background: var(--panel);
padding: 28px;
}}
h1 {{
font-size: 34px;
line-height: 1.15;
margin: 0 0 14px;
letter-spacing: -0.02em;
}}
p {{
font-size: 16px;
line-height: 1.6;
margin: 0;
color: var(--muted);
}}
.cta {{
margin-top: 22px;
display: inline-flex;
align-items: center;
justify-content: center;
gap: 10px;
height: 44px;
padding: 0 18px;
background: var(--accent);
color: #000;
font-weight: 800;
text-transform: uppercase;
letter-spacing: 0.12em;
font-size: 12px;
text-decoration: none;
}}
.fine {{
margin-top: 18px;
font-size: 12px;
color: rgba(255,255,255,0.35);
}}
</style>
</head>
<body>
<div class="wrap">
<div class="card">
<h1>{escape(headline)}</h1>
<p>{escape(intro)}</p>
<a class="cta" href="{escape(cta_url)}" rel="nofollow noopener">{escape(cta_label)}</a>
<div class="fine">Powered by Pounce Yield</div>
</div>
</div>
</body>
</html>
"""