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
+1 -1
View File
@@ -19,7 +19,7 @@ const PAGES = [
},
{
file: 'play.html', path: '/play',
title: 'Play · Upbeat Bytes — calm daily games',
title: 'Play · upbeatBytes — calm daily games',
desc: 'A calm set of daily games — Daily Word, Word Search, Bloom, and Memory Match. ' +
'A friendly little break from the doomscroll.',
},
+1 -1
View File
@@ -8,7 +8,7 @@
font-display: swap;
}
/* Upbeat Bytes calm design system.
/* upbeatBytes calm design system.
Sand, sea, and sun: warm paper surfaces, a vivid-azure accent, gold highlight,
a serif voice for headlines, strong readable contrast, generous space.
No urgency colors (no red). Built around the logo's #0083ad azure. */
+3 -3
View File
@@ -10,7 +10,7 @@
<meta name="description" content="A calmer, brighter corner of the internet: good news, daily art, small games, and little resets." />
<title>upbeatBytes — a calmer, brighter corner of the internet</title>
<link rel="canonical" href="https://upbeatbytes.com/" />
<meta property="og:site_name" content="Upbeat Bytes" />
<meta property="og:site_name" content="upbeatBytes" />
<meta property="og:type" content="website" />
<meta property="og:title" content="upbeatBytes — a calmer, brighter corner of the internet" />
<meta property="og:description" content="A calmer, brighter corner of the internet: good news, daily art, small games, and little resets. No ads, no paywalls, no doomscrolling." />
@@ -128,9 +128,9 @@
<div style="display: contents">%sveltekit.body%</div>
<div id="boot-fallback" role="alert" aria-live="polite">
<div class="bf">
<img src="%sveltekit.assets%/logo.svg" alt="Upbeat Bytes" />
<img src="%sveltekit.assets%/logo.svg" alt="upbeatBytes" />
<p>We had a little trouble loading. A quick refresh usually sorts it out.</p>
<button type="button" onclick="location.reload()">Refresh Upbeat Bytes</button>
<button type="button" onclick="location.reload()">Refresh upbeatBytes</button>
</div>
</div>
</body>
@@ -59,7 +59,7 @@
if (value) onaction?.(kind, value);
}
// Sharing: share the branded Upbeat Bytes card page (default), with copy-source.
// Sharing: share the branded upbeatBytes card page (default), with copy-source.
let shareOpen = $state(false);
let copied = $state('');
const canNativeShare = typeof navigator !== 'undefined' && !!navigator.share;
@@ -105,7 +105,7 @@
</a>
{:else if usePlaceholder}
<a class="media placeholder" href={summaryHref} onclick={opened} style="--c:{accentColor}" tabindex="-1" aria-hidden="true">
<span class="ph-word">{humanize(article.topic) || 'upbeat bytes'}</span>
<span class="ph-word">{humanize(article.topic) || 'upbeatBytes'}</span>
</a>
{/if}
+1 -1
View File
@@ -228,7 +228,7 @@
const breakdown = Object.keys(byLen).sort((a, b) => b - a).map((l) => `${l}×${byLen[l]}`).join(' ');
const pang = found.some(isPangram) ? ' · pangram ✓' : '';
const bloomV = mode === 'daily' ? 'daily' : (format === 'wild' ? 'free-wild' : 'free-center');
const text = `Upbeat Bytes · Bloom ${date}\n${fullBloom ? 'Full Bloom 🌸' : tier.name} · ${found.length} words${pang}\n${breakdown}\n${gameShareUrl('bloom', bloomV)}`;
const text = `upbeatBytes · Bloom ${date}\n${fullBloom ? 'Full Bloom 🌸' : tier.name} · ${found.length} words${pang}\n${breakdown}\n${gameShareUrl('bloom', bloomV)}`;
if (navigator.share) navigator.share({ text }).then(() => trackGame('bloom', 'shared')).catch(() => {});
else navigator.clipboard?.writeText(text).then(() => { trackGame('bloom', 'shared'); copied = true; setTimeout(() => (copied = false), 1500); });
}
+2 -2
View File
@@ -6,8 +6,8 @@
<header class="appbar">
<div class="container bar">
<a class="brand" href="/" aria-label="Upbeat Bytes — home">
<img class="logo" src="/logo.svg" alt="Upbeat Bytes" width="586" height="196" />
<a class="brand" href="/" aria-label="upbeatBytes — home">
<img class="logo" src="/logo.svg" alt="upbeatBytes" width="586" height="196" />
</a>
<nav class="utils" aria-label="Your controls">
+1 -1
View File
@@ -133,7 +133,7 @@
function share() {
const label = `${TIER_LABEL[tier] || tier} · ${format === 'colors' ? 'colors' : 'icons'}`;
const when = isFree ? 'Free play' : date;
const text = `Upbeat Bytes · Memory Match (${label}) ${when}\nCleared in ${moves} moves\n${gameShareUrl('match', `${mode}-${format}-${tier}`)}`;
const text = `upbeatBytes · Memory Match (${label}) ${when}\nCleared in ${moves} moves\n${gameShareUrl('match', `${mode}-${format}-${tier}`)}`;
if (navigator.share) navigator.share({ text }).then(() => trackGame('match', 'shared')).catch(() => {});
else navigator.clipboard?.writeText(text).then(() => { trackGame('match', 'shared'); copied = true; setTimeout(() => (copied = false), 1500); });
}
+4 -4
View File
@@ -181,7 +181,7 @@
);
let viewSubtitle = $derived(
selected === 'today' ? localDateLabel(brief)
: selected === 'search' ? 'Results across Upbeat Bytes'
: selected === 'search' ? 'Results across upbeatBytes'
: selected.startsWith('source:') ? 'Latest from this source'
: selected === 'latest' ? 'Freshest calm reads — newest first'
: selected === 'following' ? 'From the sources & topics you follow'
@@ -629,7 +629,7 @@
moods = m; topics = c.topics;
await loadView(selected);
} catch (e) {
if (!brief) error = 'Could not reach Upbeat Bytes.'; // keep painted content if a refresh failed
if (!brief) error = 'Could not reach upbeatBytes.'; // keep painted content if a refresh failed
} finally {
loading = false;
}
@@ -872,7 +872,7 @@
{#if families.length}
<section id="explore" class="explore">
<h2>Explore Upbeat Bytes</h2>
<h2>Explore upbeatBytes</h2>
<div class="families">
{#each families as f (f.name)}
{@const tags = f.tags.filter((t) => t.count > 0)}
@@ -895,7 +895,7 @@
{#if !pwa.isStandalone && !pwa.dismissed && (pwa.canInstall || pwa.isIOS)}
<aside class="install rise">
<div class="install-text">
<strong>Keep Upbeat Bytes a tap away.</strong>
<strong>Keep upbeatBytes a tap away.</strong>
{#if pwa.canInstall}Add it to your home screen — it opens like an app, no store needed.
{:else}On iPhone: tap the <span class="ios-share">Share</span> button, then “Add to Home Screen.”{/if}
</div>
+1 -1
View File
@@ -41,7 +41,7 @@
</p>
<button class="primary" onclick={onclose}>Done</button>
{:else}
<h2>Sign in to Upbeat Bytes</h2>
<h2>Sign in to upbeatBytes</h2>
<p class="sub">
Save articles and keep your history across devices.
</p>
+1 -1
View File
@@ -167,7 +167,7 @@
const label = variant === '6' ? 'Long Word' : 'Daily Word';
const score = status === 'won' ? guesses.length : 'X';
const grid = cols.map((cs) => cs.map((c) => EMOJI[c]).join('')).join('\n');
const text = `Upbeat Bytes · ${label} ${date}\n${score}/${maxGuesses}\n${grid}\n${gameShareUrl('word', variant)}`;
const text = `upbeatBytes · ${label} ${date}\n${score}/${maxGuesses}\n${grid}\n${gameShareUrl('word', variant)}`;
// Count a share only once it actually happens (sheet completed / clipboard wrote),
// never on a cancelled share sheet or denied clipboard.
if (navigator.share) navigator.share({ text }).then(() => trackGame('word', 'shared')).catch(() => {});
@@ -223,7 +223,7 @@
function share() {
const label = { small: 'Small', med: 'Medium', large: 'Large' }[size] || '';
const text = `Upbeat Bytes · Word Search (${label}) ${date}\n${theme} — cleared in ${fmt(resultMs)}\n${gameShareUrl('wordsearch', size)}`;
const text = `upbeatBytes · Word Search (${label}) ${date}\n${theme} — cleared in ${fmt(resultMs)}\n${gameShareUrl('wordsearch', size)}`;
if (navigator.share) navigator.share({ text }).then(() => trackGame('wordsearch', 'shared')).catch(() => {});
else navigator.clipboard?.writeText(text).then(() => { trackGame('wordsearch', 'shared'); copied = true; setTimeout(() => (copied = false), 1500); });
}
+1 -1
View File
@@ -101,7 +101,7 @@
<header class="bar">
<div class="container inner">
<a class="brand" href="/" aria-label="Upbeat Bytes — home"><img class="logo" src="/logo.svg" alt="Upbeat Bytes" /></a>
<a class="brand" href="/" aria-label="upbeatBytes — home"><img class="logo" src="/logo.svg" alt="upbeatBytes" /></a>
<div class="baractions">
<button class="fb" onclick={openFeedback} aria-label="Share feedback" title="Share feedback">
<svg viewBox="0 0 24 24" width="18" height="18" aria-hidden="true"><path d="M4 5h16v11H8l-4 3z" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round" /></svg>
+1 -1
View File
@@ -675,7 +675,7 @@
<header class="bar">
<div class="container inner">
<a class="brand" href="/"><img class="logo" src="/logo.svg" alt="Upbeat Bytes" /></a>
<a class="brand" href="/"><img class="logo" src="/logo.svg" alt="upbeatBytes" /></a>
<a class="back" href="/account"><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>Account</a>
</div>
</header>
+1 -1
View File
@@ -35,7 +35,7 @@
{:else}
<h1>Couldn't sign you in</h1>
<p class="muted">{error}</p>
<a class="back" href="/">← Back to Upbeat Bytes</a>
<a class="back" href="/">← Back to upbeatBytes</a>
{/if}
</main>
+1 -1
View File
@@ -273,7 +273,7 @@
<!-- Canonical/OG/description for /play are baked into the static play.html at build
time (scripts/patch-static-heads.mjs) so non-JS social scrapers get them; we keep
only the browser-tab title + dev-gate noindex here to avoid duplicate tags. -->
<title>Play · Upbeat Bytes — calm daily games</title>
<title>Play · upbeatBytes — calm daily games</title>
{#if isDevGated(game)}<meta name="robots" content="noindex" />{/if}
</svelte:head>
+2 -2
View File
@@ -51,13 +51,13 @@
</script>
<svelte:head>
<title>The Zen Den · Upbeat Bytes</title>
<title>The Zen Den · upbeatBytes</title>
{#if isDevGated('zen')}<meta name="robots" content="noindex" />{/if}
</svelte:head>
<header class="bar">
<div class="container inner">
<a class="brand" href="/"><img class="logo" src="/logo.svg" alt="Upbeat Bytes" /></a>
<a class="brand" href="/"><img class="logo" src="/logo.svg" alt="upbeatBytes" /></a>
<a class="back" href="/play">
<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>Play
</a>
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "Upbeat Bytes",
"short_name": "Upbeat Bytes",
"name": "upbeatBytes",
"short_name": "upbeatBytes",
"description": "A calmer, brighter corner of the internet: good news, daily art, small games, and little resets.",
"start_url": "/",
"scope": "/",