Remove duplicate h1, fix avatar gender caching, blacklist Celeste voice

- Hide h1 (sr-only) on homepage — banner already shows show name
- Promote tagline as visual lead after banner
- Fix avatar gender: add .gender marker files, re-fetch on mismatch
- Clear stale avatar cache so all re-fetch with correct gender
- Blacklist Celeste voice from caller pool

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-16 03:28:18 -06:00
parent 908255e5cf
commit 8a64a269f3
4 changed files with 20 additions and 8 deletions
+1 -1
View File
@@ -147,7 +147,7 @@ ELEVENLABS_MALE_VOICES.append("SAz9YHcvj6GT2YYXdXww") # River - Neutral
ELEVENLABS_FEMALE_VOICES.append("SAz9YHcvj6GT2YYXdXww") # River - Neutral
# Voices to never assign to callers (annoying, bad quality, etc.)
BLACKLISTED_VOICES = {"Evelyn", "Sebastian"} # Sebastian reserved for Silas
BLACKLISTED_VOICES = {"Evelyn", "Sebastian", "Celeste"} # Sebastian reserved for Silas
def _get_voice_pools():
+9 -4
View File
@@ -25,14 +25,19 @@ class AvatarService:
async def get_or_fetch(self, name: str, gender: str = "male") -> Path:
"""Get cached avatar or fetch from randomuser.me. Returns file path."""
g = "female" if gender.lower().startswith("f") else "male"
path = AVATAR_DIR / f"{name}.jpg"
# Check for gender mismatch marker — re-fetch if gender changed
marker = AVATAR_DIR / f"{name}.gender"
if path.exists():
cached_gender = marker.read_text().strip() if marker.exists() else None
if cached_gender == g:
return path
# Gender mismatch or no marker — re-fetch
path.unlink(missing_ok=True)
try:
# Seed includes gender so same name + different gender = different face
seed = f"{name.lower().replace(' ', '_')}_{gender.lower()}"
g = "female" if gender.lower().startswith("f") else "male"
seed = f"{name.lower().replace(' ', '_')}_{g}"
resp = await self.client.get(
"https://randomuser.me/api/",
params={"gender": g, "seed": seed},
@@ -42,11 +47,11 @@ class AvatarService:
data = resp.json()
photo_url = data["results"][0]["picture"]["large"]
# Download the photo
photo_resp = await self.client.get(photo_url, timeout=8.0)
photo_resp.raise_for_status()
path.write_bytes(photo_resp.content)
marker.write_text(g)
print(f"[Avatar] Fetched avatar for {name} ({g})")
return path
except Exception as e:
+7
View File
@@ -184,6 +184,13 @@ a:hover {
line-height: 1.5;
}
.tagline--hero {
font-size: 1.4rem;
color: var(--text);
font-weight: 600;
max-width: 600px;
}
.phone {
display: flex;
align-items: center;
+2 -2
View File
@@ -119,8 +119,8 @@
<section class="hero">
<div class="hero-inner hero-inner--full">
<div class="hero-info hero-info--centered">
<h1>Luke at the Roost</h1>
<p class="tagline">The call-in talk show where Luke gives life advice to biologically questionable organisms.</p>
<h1 class="sr-only">Luke at the Roost</h1>
<p class="tagline tagline--hero">The call-in talk show where Luke gives life advice to biologically questionable organisms.</p>
<div class="phone" id="phone-section">
<div class="on-air-badge" id="on-air-badge">
<span class="on-air-dot"></span>