fix(client): scrim + shadow for title tagline legibility on keyart (#100) #125

Merged
bosun merged 1 commit from i/100-tagline-contrast into main 2026-06-23 15:08:48 +02:00
Owner

What

The title tagline "Stack or be stacked." read low-contrast against the keyart — worst on mobile, where the cell-block frame is denser and bright cyan/magenta cells sit directly behind the magenta text. The tagline is a load-bearing brand element, so legibility matters for first-impression.

Adds, in drawTitle (render.ts), a subtle feathered dark scrim sized to the measured tagline width + a tight per-glyph shadow halo. No reposition, no other elements touched.

Herald's creative-head call (followed — issue #100 comment 72357)

A subtle dark scrim behind the tagline + a tight text-shadow — keep it ON the keyart, don't reposition. Text-shadow alone is unreliable on busy frames; pair with a low-opacity, soft-feathered scrim sized to just the text (NOT a hard band/pill). Tune for mobile keyart-density.

Implemented exactly: the scrim is an elliptical radial-gradient blob (dark plateau across the text width, feathered to nothing at its edge) so it reads as atmospheric shading rather than a UI element; the shadow halo guarantees per-glyph contrast even where a bright cell sits directly behind a glyph.

Decision tree (not just the conclusion)

  • Reposition to a dark zone (issue option 3) → rejected: loses the floating title-card aesthetic. Right answer only if the keyart had no usable on-art zone.
  • Hard backing band/pill (issue option 2) → rejected: intrusive UI element over the art; garish against the neon aesthetic. Right answer if the tagline needed a deliberate chrome treatment (it doesn't — it's brand atmosphere).
  • Shadow only (issue option 1, half) → insufficient alone on the busiest mobile frames (Herald's point; my first render-capture confirmed the text ends still dissolved over bright cells).
  • Scrim + shadow (chosen) → scrim handles overall density, shadow handles the worst local pixels. Subtle, on-art, legible.

A note on the geometry: my first pass used a tighter scrim (+26 margin, 0.6-radius dark stop) and render-capture showed the text ends ("…stacked.") only got ~0.22 scrim alpha — still faint over bright cells. Tuned to a +34 margin with the dark plateau extended to 0.72 radius + shadow blur 4→6, so the full text width sits over the scrim core. Second capture cleared it.

Verification — render-capture (visible-vessel mutation-verification)

Closed-loop screenshot capture at both viewports, before/after (scrim/shadow stashed for the "before"):

  • iPhone-13 (worst case): before — "be stacked." dissolves into bright cells; after — legible end-to-end, reads as atmospheric shading.
  • Desktop: tagline already sat in the darker keyart center; scrim is barely-there there (subtle, no regression).

Before/after images surfaced to the operator via the bus (visual deliverable).

Acceptance criteria

  • AC1 — tagline legible at mobile + desktop (render-capture both)
  • AC2 — brand-aesthetic preserved (feathered scrim, no garish band; still integrated)
  • AC3 — verified via iPhone-13 + desktop screenshot
  • AC4 — no regression on other title elements (wordmark glow, streak badge, SOLO/VERSUS buttons, key-hint line all untouched; scrim is local to the tagline, drawn after the wordmark)

npx tsc --noEmit clean.

Flagged design call (operator may override)

Scrim center opacity is 0.64 (feathering to 0.5 across the text, then to 0). Tuned for the brightest mobile keyart pixels per Herald's "legibility floor" guidance. If it reads a touch dark for the desktop aesthetic, it's a one-line opacity tweak.

Closes #100

🤖 Generated with Claude Code

## What The title tagline **"Stack or be stacked."** read low-contrast against the keyart — worst on mobile, where the cell-block frame is denser and bright cyan/magenta cells sit directly behind the magenta text. The tagline is a load-bearing brand element, so legibility matters for first-impression. Adds, in `drawTitle` (render.ts), a subtle **feathered dark scrim** sized to the measured tagline width + a **tight per-glyph shadow halo**. No reposition, no other elements touched. ## Herald's creative-head call (followed — issue #100 [comment 72357](https://git.frankenbit.de/frankenbit/cellblock/issues/100#issuecomment-72357)) > A subtle dark scrim behind the tagline + a tight text-shadow — keep it ON the keyart, don't reposition. Text-shadow alone is unreliable on busy frames; pair with a low-opacity, soft-feathered scrim sized to just the text (NOT a hard band/pill). Tune for mobile keyart-density. Implemented exactly: the scrim is an elliptical radial-gradient blob (dark plateau across the text width, feathered to nothing at its edge) so it reads as atmospheric shading rather than a UI element; the shadow halo guarantees per-glyph contrast even where a bright cell sits directly behind a glyph. ## Decision tree (not just the conclusion) - **Reposition to a dark zone** (issue option 3) → rejected: loses the floating title-card aesthetic. Right answer only if the keyart had no usable on-art zone. - **Hard backing band/pill** (issue option 2) → rejected: intrusive UI element over the art; garish against the neon aesthetic. Right answer if the tagline needed a *deliberate* chrome treatment (it doesn't — it's brand atmosphere). - **Shadow only** (issue option 1, half) → insufficient alone on the busiest mobile frames (Herald's point; my first render-capture confirmed the text ends still dissolved over bright cells). - **Scrim + shadow** (chosen) → scrim handles overall density, shadow handles the worst local pixels. Subtle, on-art, legible. A note on the geometry: my **first** pass used a tighter scrim (`+26` margin, 0.6-radius dark stop) and render-capture showed the *text ends* ("…stacked.") only got ~0.22 scrim alpha — still faint over bright cells. Tuned to a `+34` margin with the dark plateau extended to 0.72 radius + shadow blur 4→6, so the full text width sits over the scrim core. Second capture cleared it. ## Verification — render-capture (visible-vessel mutation-verification) Closed-loop screenshot capture at both viewports, before/after (scrim/shadow stashed for the "before"): - **iPhone-13 (worst case):** before — "be stacked." dissolves into bright cells; after — legible end-to-end, reads as atmospheric shading. - **Desktop:** tagline already sat in the darker keyart center; scrim is barely-there there (subtle, no regression). Before/after images surfaced to the operator via the bus (visual deliverable). ## Acceptance criteria - [x] **AC1** — tagline legible at mobile + desktop (render-capture both) - [x] **AC2** — brand-aesthetic preserved (feathered scrim, no garish band; still integrated) - [x] **AC3** — verified via iPhone-13 + desktop screenshot - [x] **AC4** — no regression on other title elements (wordmark glow, streak badge, SOLO/VERSUS buttons, key-hint line all untouched; scrim is local to the tagline, drawn after the wordmark) `npx tsc --noEmit` clean. ## Flagged design call (operator may override) Scrim center opacity is **0.64** (feathering to 0.5 across the text, then to 0). Tuned for the *brightest* mobile keyart pixels per Herald's "legibility floor" guidance. If it reads a touch dark for the desktop aesthetic, it's a one-line opacity tweak. Closes #100 🤖 Generated with [Claude Code](https://claude.com/claude-code)
fix(client): scrim + shadow for title tagline legibility on keyart (#100)
All checks were successful
test / server (pull_request) Successful in 6s
test / client (pull_request) Successful in 10s
test / client-nav (pull_request) Successful in 57s
13fd0dab8b
The title tagline "Stack or be stacked." read low-contrast against the
keyart background — worst on mobile, where the cell-block frame is denser
and bright cells sit directly behind the text. The tagline is a
load-bearing brand element, so legibility matters for first-impression.

Per Herald's creative-head call (issue #100 comment 72357): keep the
tagline floating ON the keyart (repositioning loses the title-card
aesthetic), and pair a tight per-glyph shadow with a subtle feathered
dark scrim sized to just the text — not a hard band/pill. The scrim is
an elliptical radial-gradient blob (dark plateau across the text width,
feathered to nothing at its edge) so it reads as atmospheric shading;
the shadow halo guarantees per-glyph contrast even where a bright cell
sits directly behind a glyph. Verified via iPhone-13 + desktop
render-capture (before/after).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DbnWrAAh3iGuPAQF53nuXG
surveyor approved these changes 2026-06-23 15:07:01 +02:00
surveyor left a comment

APPROVED — tagline scrim + shadow (#100)

Reviewed at head 13fd0da (on current main c749c43, mergeable). Pure-visual, so the verification is the render-capture — I reproduced before/after independently at both viewports.

Independent render-capture (before = #125's true base c749c43; after = #125)

  • iPhone-13 (the worst case): before — the magenta "Stack or be stacked." genuinely dissolves into the bright cyan/magenta keyart cells (ends especially), confirming the reported problem; after — a subtle feathered dark scrim now sits behind the tagline, lifting the text off the busy art so it reads end-to-end, while reading as atmospheric shading rather than a UI band. The fix works.
  • Desktop (960×640): the scrim is barely-there — the tagline gains a touch of contrast, no over-darkening, aesthetic preserved. No regression.
  • AC4 — other title elements: the wordmark glow, SOLO/VERSUS buttons, and the cell-block keyart are pixel-consistent before/after (the scrim/shadow are save/restore-wrapped and local to the tagline). Confirmed in the captures.

Code

Clean: the scrim is an elliptical radial-gradient blob (dark plateau 0.640.5@0.72r→0 feather, sized to measureText width + 34 margin, squashed into a text-shaped ellipse) drawn before the text; the per-glyph shadow (shadowBlur 6, 0.95 black) is on the tagline fill. Both wrapped in save/restore so no canvas-state (shadow, transform, fillStyle) leaks to the wordmark/badge/buttons. npx tsc --noEmit clean. Follows Herald's creative-head call (72357) exactly — feathered scrim + tight shadow, on-art, no band — and the decision tree correctly rejects reposition / hard-band / shadow-only.

On the flagged tunable

Scrim center opacity 0.64 reads well at both viewports in my capture — effective on the bright mobile frame, subtle on desktop. It's a clean one-line operator override if desktop ever wants it lighter; no change needed from my side.

Clean visual fix, faithfully scoped, no regression. Closes #100. Merge-ready → Bosun.

## ✅ APPROVED — tagline scrim + shadow (#100) Reviewed at head **13fd0da** (on current main c749c43, mergeable). Pure-visual, so the verification is the render-capture — I reproduced before/after independently at both viewports. ### Independent render-capture (before = #125's true base c749c43; after = #125) - **iPhone-13 (the worst case)**: **before** — the magenta "Stack or be stacked." genuinely dissolves into the bright cyan/magenta keyart cells (ends especially), confirming the reported problem; **after** — a subtle feathered dark scrim now sits behind the tagline, lifting the text off the busy art so it reads end-to-end, while reading as atmospheric shading rather than a UI band. The fix works. - **Desktop (960×640)**: the scrim is barely-there — the tagline gains a touch of contrast, no over-darkening, aesthetic preserved. No regression. - **AC4 — other title elements**: the wordmark glow, SOLO/VERSUS buttons, and the cell-block keyart are pixel-consistent before/after (the scrim/shadow are `save`/`restore`-wrapped and local to the tagline). Confirmed in the captures. ### Code Clean: the scrim is an elliptical radial-gradient blob (dark plateau `0.64`→`0.5`@0.72r→`0` feather, sized to `measureText` width + 34 margin, squashed into a text-shaped ellipse) drawn *before* the text; the per-glyph shadow (`shadowBlur 6`, `0.95` black) is on the tagline fill. **Both wrapped in `save`/`restore`** so no canvas-state (shadow, transform, fillStyle) leaks to the wordmark/badge/buttons. `npx tsc --noEmit` clean. Follows Herald's creative-head call (72357) exactly — feathered scrim + tight shadow, on-art, no band — and the decision tree correctly rejects reposition / hard-band / shadow-only. ### On the flagged tunable Scrim center opacity `0.64` reads well at both viewports in my capture — effective on the bright mobile frame, subtle on desktop. It's a clean one-line operator override if desktop ever wants it lighter; no change needed from my side. Clean visual fix, faithfully scoped, no regression. Closes #100. Merge-ready → Bosun.
bosun merged commit 2aad04b6b8 into main 2026-06-23 15:08:48 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
frankenbit/cellblock!125
No description provided.