brand: standardize "Upbeat Bytes" → "upbeatBytes" everywhere

Per the logo + brand: the name is upbeatBytes (camelCase). Swept all user-facing
strings — titles/og:site_name/og:title, logo alt text, share pages (share.py),
emails (email_send), classifier prompt (llm), digest/unsubscribe (api), PWA
manifest, game share text, sign-in, the SPA shell + patch-static-heads (play
title) — plus README/publish.sh and the email test fixture. (SMTP From env was
already upbeatBytes.) Domains (upbeatbytes.com) unchanged. 425 BE + 36 FE green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
jay
2026-06-28 20:01:20 -04:00
parent f8628b3b14
commit 667b1a82c3
24 changed files with 58 additions and 58 deletions
+3 -3
View File
@@ -767,7 +767,7 @@ def create_app() -> FastAPI:
ok = _do_unsubscribe(u, t)
msg = (
"Youre unsubscribed from the daily digest. No hard feelings — "
"Upbeat Bytes is always here when you want it."
"upbeatBytes is always here when you want it."
if ok else
"That unsubscribe link looks invalid or expired. You can manage the "
"digest from your account settings."
@@ -776,9 +776,9 @@ def create_app() -> FastAPI:
'<!doctype html><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">'
'<div style="max-width:520px;margin:12vh auto;padding:0 24px;text-align:center;'
'font-family:-apple-system,Segoe UI,Roboto,Helvetica,Arial,sans-serif;color:#16263a">'
'<h1 style="font-size:22px">Upbeat Bytes</h1>'
'<h1 style="font-size:22px">upbeatBytes</h1>'
f'<p style="font-size:16px;line-height:1.5;color:#3b4754">{msg}</p>'
'<p><a href="/" style="color:#0083ad;text-decoration:none">← Back to Upbeat Bytes</a></p></div>'
'<p><a href="/" style="color:#0083ad;text-decoration:none">← Back to upbeatBytes</a></p></div>'
)
return HTMLResponse(html)
+9 -9
View File
@@ -59,7 +59,7 @@ def send_email(to: str, subject: str, text: str, html: str | None = None, reply_
def send_feedback(to: str, category: str, message: str, contact: str | None, who: str) -> None:
"""Notify the admin of new user feedback (plain text is plenty here)."""
subject = f"Upbeat Bytes feedback · {category}"
subject = f"upbeatBytes feedback · {category}"
reply = contact or "(none given)"
text = (
f"New feedback ({category})\n"
@@ -74,14 +74,14 @@ def send_feedback_reply(to: str, reply_text: str, reply_html: str | None, origin
"""Reply to a reader's feedback from the admin inbox. Sends multipart
text/plain + text/html (the HTML is the pre-sanitized Markdown render). Quotes
their original note for context; exposes no analytics/account details."""
subject = "Re: Your Upbeat Bytes feedback"
subject = "Re: Your upbeatBytes feedback"
quoted = "\n".join("> " + line for line in (original_message or "").splitlines())
text = (
f"{reply_text}\n\n"
"\n"
"In reply to your note to Upbeat Bytes:\n"
"In reply to your note to upbeatBytes:\n"
f"{quoted}\n\n"
"Thanks for reaching out.\nUpbeat Bytes\n"
"Thanks for reaching out.\nupbeatBytes\n"
)
body_html = None
if reply_html:
@@ -90,9 +90,9 @@ def send_feedback_reply(to: str, reply_text: str, reply_html: str | None, origin
'<div style="font-family:-apple-system,Segoe UI,Roboto,Helvetica,Arial,sans-serif;'
'color:#16263a;font-size:15px;line-height:1.5">'
f"{reply_html}"
'<p style="color:#5d6b78;font-size:13px;margin-top:20px">In reply to your note to Upbeat Bytes:</p>'
'<p style="color:#5d6b78;font-size:13px;margin-top:20px">In reply to your note to upbeatBytes:</p>'
f'<blockquote style="color:#5d6b78;border-left:3px solid #e8e3d8;margin:0;padding-left:12px">{oq}</blockquote>'
"<p>Thanks for reaching out.<br>— Upbeat Bytes</p></div>"
"<p>Thanks for reaching out.<br>— upbeatBytes</p></div>"
)
# Route the reader's reply to our chosen inbox (never back to the reader).
cfg = _cfg()
@@ -102,9 +102,9 @@ def send_feedback_reply(to: str, reply_text: str, reply_html: str | None, origin
def send_magic_link(to: str, link: str) -> None:
"""Send a calm, single-purpose sign-in email."""
subject = "Your Upbeat Bytes sign-in link"
subject = "Your upbeatBytes sign-in link"
text = (
"Welcome back to Upbeat Bytes.\n\n"
"Welcome back to upbeatBytes.\n\n"
f"Tap to sign in:\n{link}\n\n"
"This link works once and expires in 15 minutes.\n"
"If you didn't request it, you can safely ignore this email."
@@ -113,7 +113,7 @@ def send_magic_link(to: str, link: str) -> None:
html = (
'<div style="font-family:-apple-system,Segoe UI,Roboto,Helvetica,Arial,sans-serif;'
'color:#16263a;line-height:1.6">'
"<p>Welcome back to <strong>Upbeat Bytes</strong>.</p>"
"<p>Welcome back to <strong>upbeatBytes</strong>.</p>"
f'<p><a href="{safe}" style="display:inline-block;background:#0083ad;color:#fff;'
'text-decoration:none;padding:11px 20px;border-radius:999px;font-weight:600">'
"Sign in</a></p>"
+1 -1
View File
@@ -78,7 +78,7 @@ _RESPONSE_FORMATS = (
)
SYSTEM_PROMPT = """You classify article metadata for Upbeat Bytes, a calm news digest.
SYSTEM_PROMPT = """You classify article metadata for upbeatBytes, a calm news digest.
The bar is NOT "is this happy?" — it is "will a reader finish this calm or a little better, never worse?" ACCEPT stories that are calm, neutral, insightful, or uplifting: they inform, teach, delight, or show progress or benefit. Neutral-but-absorbing is welcome — a discovery, a clear explainer, a clever build or gadget, a fascinating bit of science, space, nature, design, or culture, a genuinely useful insight — even when it isn't "feel-good."
+13 -13
View File
@@ -20,7 +20,7 @@ def _tag(name: str, content: str | None, attr: str = "property") -> str:
def render_share_page(article: dict, base_url: str, summary: str | None = None,
explanation: dict | None = None) -> str:
aid = article["id"]
title = (article.get("title") or "Upbeat Bytes").strip()
title = (article.get("title") or "upbeatBytes").strip()
why = (article.get("reason_text") or article.get("description")
or "A calm, constructive story worth your attention.").strip()
source = (article.get("source_name") or "the source").strip()
@@ -39,7 +39,7 @@ def render_share_page(article: dict, base_url: str, summary: str | None = None,
twitter_card = "summary_large_image" if image else "summary"
meta = "\n".join(filter(None, [
_tag("og:site_name", "Upbeat Bytes"),
_tag("og:site_name", "upbeatBytes"),
_tag("og:type", "article"),
_tag("og:title", title),
_tag("og:description", why),
@@ -138,7 +138,7 @@ def render_share_page(article: dict, base_url: str, summary: str | None = None,
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{escape(title)} · Upbeat Bytes</title>
<title>{escape(title)} · upbeatBytes</title>
<meta name="description" content="{escape(why)}">
<link rel="canonical" href="{escape(page_url)}">
<link rel="icon" href="/favicon.svg">
@@ -194,7 +194,7 @@ def render_share_page(article: dict, base_url: str, summary: str | None = None,
</style>
</head>
<body>
<div class="bar"><div class="inner"><a href="/"><img src="/logo.svg" alt="Upbeat Bytes"></a><button class="back" type="button" data-back aria-label="Go back"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M19 12H5M11 6l-6 6 6 6" fill="none" stroke="currentColor" stroke-width="2.1" stroke-linecap="round" stroke-linejoin="round"/></svg>Back</button></div></div>
<div class="bar"><div class="inner"><a href="/"><img src="/logo.svg" alt="upbeatBytes"></a><button class="back" type="button" data-back aria-label="Go back"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M19 12H5M11 6l-6 6 6 6" fill="none" stroke="currentColor" stroke-width="2.1" stroke-linecap="round" stroke-linejoin="round"/></svg>Back</button></div></div>
<main class="wrap">
<article class="card">
{media}
@@ -207,9 +207,9 @@ def render_share_page(article: dict, base_url: str, summary: str | None = None,
<div class="actions">
<a class="primary" href="{escape(src_url)}" target="_blank" rel="noopener" data-src-click>Read the full story at {escape(source)}</a>
<button class="secondary" type="button" data-share>Copy link</button>
<a class="secondary" href="/news">Explore Upbeat Bytes →</a>
<a class="secondary" href="/news">Explore upbeatBytes →</a>
</div>
<p class="note">Upbeat Bytes summarizes in its own words and links to the original publisher — it doesn't host the article.</p>
<p class="note">upbeatBytes summarizes in its own words and links to the original publisher — it doesn't host the article.</p>
</div>
</article>
</main>
@@ -275,7 +275,7 @@ def render_digest(items: list[dict], base_url: str, brief_date: str | None) -> s
)
meta = "\n".join(filter(None, [
_tag("og:site_name", "Upbeat Bytes"),
_tag("og:site_name", "upbeatBytes"),
_tag("og:type", "website"),
_tag("og:title", "Today's good news, summarized"),
_tag("og:description", intro),
@@ -292,7 +292,7 @@ def render_digest(items: list[dict], base_url: str, brief_date: str | None) -> s
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Today's good news, summarized · Upbeat Bytes</title>
<title>Today's good news, summarized · upbeatBytes</title>
<meta name="description" content="{escape(intro)}">
<link rel="canonical" href="{page_url}">
<link rel="icon" href="/favicon.svg">
@@ -324,12 +324,12 @@ def render_digest(items: list[dict], base_url: str, brief_date: str | None) -> s
</style>
</head>
<body>
<div class="bar"><div class="inner"><a href="/"><img src="/logo.svg" alt="Upbeat Bytes"></a></div></div>
<div class="bar"><div class="inner"><a href="/"><img src="/logo.svg" alt="upbeatBytes"></a></div></div>
<main class="wrap">
<h1>Today's good news</h1>
<p class="lede">{escape(intro)}{f' · {escape(brief_date)}' if brief_date else ''}</p>
{cards}
<p class="more"><a href="/news">Browse more on Upbeat Bytes →</a></p>
<p class="more"><a href="/news">Browse more on upbeatBytes →</a></p>
</main>
</body>
</html>"""
@@ -339,7 +339,7 @@ def render_not_found(base_url: str) -> str:
return f"""<!doctype html>
<html lang="en"><head><meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Story not found · Upbeat Bytes</title><link rel="icon" href="/favicon.svg">
<title>Story not found · upbeatBytes</title><link rel="icon" href="/favicon.svg">
<style>
body {{ margin:0; min-height:100vh; display:flex; flex-direction:column; align-items:center;
justify-content:center; gap:14px; text-align:center; padding:40px;
@@ -348,8 +348,8 @@ def render_not_found(base_url: str) -> str:
a {{ color:#006b8e; }}
</style></head>
<body>
<img src="/logo.svg" alt="Upbeat Bytes" style="height:44px">
<img src="/logo.svg" alt="upbeatBytes" style="height:44px">
<h1 style="font-family:Georgia,serif;font-weight:600">That story isn't here</h1>
<p style="color:#5d6b78">It may have moved on — the good news refreshes often.</p>
<a href="/">← Back to Upbeat Bytes</a>
<a href="/">← Back to upbeatBytes</a>
</body></html>"""