EN

Brand & Voice

A retro pixel aesthetic committed to without escape hatches — no rounded corners, no dark mode — a mascot whose mood reads the verdict, and an octopus persona confined to the match content so the chrome around it stays straight.

Part of the Paulopus case study. Paulopus is a World Cup 2026 prediction project fronted by an octopus oracle. Two design surfaces had to stay separate: the product's own look and voice — pixel art, a mascot, a favicon — and the octopus persona that speaks only inside the match content it generates. This page is about the first, told plainly by the maker. The octopus does not narrate here; it never should.

A retro pixel-art aesthetic, committed to fully

Decision. After the app shipped with a conventional Next.js/Tailwind/shadcn look, I wanted the surface to carry a distinct character rather than read as another dashboard. Approach. On 2026-06-13 I overhauled the visual design to a retro 8-bit aesthetic and, critically, dropped the options that dilute a pixel look — no rounded corners, no dark mode. I also added lib/view.ts to flatten match and karma data into screen-ready shapes so the pixel components stayed dumb. Artifact — the design tokens the redesign locked in:

TokenValue
PaletteFixed 8-bit sand / ink / orange
Display fontTiny5
Body fontDM Sans
Border radius0 (zero, everywhere)
Dark modeDropped

Result. A single committed aesthetic instead of a themeable one — the constraint (no radius, no dark mode) is the brand.

Pixel flags to match the pixels

Decision. Emoji flags broke the illusion the moment they rendered as glossy full-color glyphs next to 8-bit type. Approach. I replaced them with 32×18 pixel-art PNG flags sourced from R74n PixelFlags, vendored under public/flags/ and resolved through lib/flags.ts, with attribution added to the footer. Artifact:

PropertyValue
Format32×18 pixel-art PNG
SourceR74n PixelFlags
Locationpublic/flags/
Resolverlib/flags.ts
AttributionFooter credit

Result. Every team marker now sits at the same resolution as the rest of the UI, and the borrowed asset is credited where it's used.

A mascot that reacts to the verdict

Decision. The octopus is the product's face, so it should express how a prediction turned out rather than sit static. Approach. On 2026-06-13 I replaced mascotForKarma() with mascotForVerdict(), driving four distinct match-result moods off the graded outcome. For matches that hadn't been played yet, I added nine host-nation octopus kits, selected through a match-id-to-country map derived from the FIFA schedule, and randomized the home hero octopus and its joke on load. Artifact — the two mascot selection paths:

SituationSelectorOutput
Finished matchmascotForVerdict()One of four result moods
Upcoming matchhost-nation map (match id → country)One of nine host-nation kits
Home herorandomizedRandom octopus + random joke

Result. The mascot became a status indicator with personality — its mood is a read on the verdict, and upcoming matches get a nod to where they're being played.

A favicon that shuffles per visit

Decision. Even the browser tab was a chance to carry the octopus, but the static/SSR case needs a stable, predictable mark. Approach. I set the ball-octopus PNG as the favicon for the static and server-rendered case, then swapped it client-side after hydration to a randomly chosen octopus drawn from the ball plus the nine nation kits. Artifact — the two-stage favicon behavior:

StageFavicon
Static / SSR (pre-hydration)Ball octopus PNG (fixed)
After hydration (client)Random pick from ball + 9 nation kits

Result. A small, deliberate surprise: the tab icon is consistent on first paint but varies visit to visit, reusing the same mascot art already loaded for the page.

The Paulopus voice — kept inside the content, not the chrome

Decision. The playful octopus tone is a strong flavor, and strong flavors ruin the frame if they leak into navigation, credits, or legal copy. So the voice was scoped to exactly one place: the match content the writer generates. Approach. In Writer Phase 1 (2026-06-12) I wrote the Paulopus voice system prompt alongside the lock and debrief zod output schemas and the context derivation that feeds them. The voice lives in the prompt; the app chrome around it stays in a neutral maker's register. Artifact — where the voice is, and is not:

SurfaceVoice
Pronostic / brief / debrief contentPaulopus octopus persona (from the voice system prompt)
Pronostic appreciation on match rowsPaulopus octopus persona
Tabs, footer, About, Legal, creditsNeutral, maker's voice

Result. The persona has one home. Everything structural around it reads straight, which is what lets the octopus be funny without the whole product feeling like a bit.

A shared verdict palette so the brand can't drift

Decision. Verdict color kept appearing in multiple places — a proportional gauge, counts, badges — and any of them drifting would make the four verdicts feel like different taxonomies. Approach. On 2026-06-17 the karma page redesign replaced its two-cell (Inspired / Red Cards) display with the home page's proportional verdict gauge, extended to all four verdict counts and tinted from a single shared VERDICT_PALETTE so segment, count, and badge colors are sourced from one place. Artifact:

ElementColor source
Gauge segmentVERDICT_PALETTE
Verdict countVERDICT_PALETTE
Verdict badgeVERDICT_PALETTE

Result. One palette, three consumers, zero drift — the four verdicts read as one system across every screen that shows them.

Crediting the borrowed and the generated

Decision. A brand assembled from vendored assets and AI collaborators owes a clear paper trail. Approach. On 2026-06-17 I expanded the footer with a dedicated CREDITS section and added standalone About and Legal pages covering attributions and disclaimers. Artifact — the credited contributors:

Credited
Design
Claude Code
Superpowers
R74n flags
Claude Sonnet
openfootball
Mascot art

Result. The mascot art, pixel flags, and AI collaborators that make the brand possible are all named on the surface itself — the credits are part of the design, not an afterthought.

Brand & Voice
  • slugbrand-voice-0
  • contentPart of the [Paulopus](/plant/paulopus#execution) case study. Paulopus is a World Cup 2026 prediction project fronted by an octopus oracle. Two design surfaces had to stay separate: the **product's own look and voice** — pixel art, a mascot, a favicon — and the **octopus persona** that speaks only inside the match content it generates. This page is about the first, told plainly by the maker. The octopus does not narrate here; it never should. ## A retro pixel-art aesthetic, committed to fully **Decision.** After the app shipped with a conventional Next.js/Tailwind/shadcn look, I wanted the surface to carry a distinct character rather than read as another dashboard. **Approach.** On 2026-06-13 I overhauled the visual design to a retro 8-bit aesthetic and, critically, dropped the options that dilute a pixel look — no rounded corners, no dark mode. I also added `lib/view.ts` to flatten match and karma data into screen-ready shapes so the pixel components stayed dumb. **Artifact** — the design tokens the redesign locked in: | Token | Value | | --- | --- | | Palette | Fixed 8-bit sand / ink / orange | | Display font | Tiny5 | | Body font | DM Sans | | Border radius | 0 (zero, everywhere) | | Dark mode | Dropped | **Result.** A single committed aesthetic instead of a themeable one — the constraint (no radius, no dark mode) is the brand. ## Pixel flags to match the pixels **Decision.** Emoji flags broke the illusion the moment they rendered as glossy full-color glyphs next to 8-bit type. **Approach.** I replaced them with 32×18 pixel-art PNG flags sourced from R74n PixelFlags, vendored under `public/flags/` and resolved through `lib/flags.ts`, with attribution added to the footer. **Artifact:** | Property | Value | | --- | --- | | Format | 32×18 pixel-art PNG | | Source | R74n PixelFlags | | Location | `public/flags/` | | Resolver | `lib/flags.ts` | | Attribution | Footer credit | **Result.** Every team marker now sits at the same resolution as the rest of the UI, and the borrowed asset is credited where it's used. ## A mascot that reacts to the verdict **Decision.** The octopus is the product's face, so it should express how a prediction turned out rather than sit static. **Approach.** On 2026-06-13 I replaced `mascotForKarma()` with `mascotForVerdict()`, driving four distinct match-result moods off the graded outcome. For matches that hadn't been played yet, I added nine host-nation octopus kits, selected through a match-id-to-country map derived from the FIFA schedule, and randomized the home hero octopus and its joke on load. **Artifact** — the two mascot selection paths: | Situation | Selector | Output | | --- | --- | --- | | Finished match | `mascotForVerdict()` | One of four result moods | | Upcoming match | host-nation map (match id → country) | One of nine host-nation kits | | Home hero | randomized | Random octopus + random joke | **Result.** The mascot became a status indicator with personality — its mood is a read on the verdict, and upcoming matches get a nod to where they're being played. ## A favicon that shuffles per visit **Decision.** Even the browser tab was a chance to carry the octopus, but the static/SSR case needs a stable, predictable mark. **Approach.** I set the ball-octopus PNG as the favicon for the static and server-rendered case, then swapped it client-side after hydration to a randomly chosen octopus drawn from the ball plus the nine nation kits. **Artifact** — the two-stage favicon behavior: | Stage | Favicon | | --- | --- | | Static / SSR (pre-hydration) | Ball octopus PNG (fixed) | | After hydration (client) | Random pick from ball + 9 nation kits | **Result.** A small, deliberate surprise: the tab icon is consistent on first paint but varies visit to visit, reusing the same mascot art already loaded for the page. ## The Paulopus voice — kept inside the content, not the chrome **Decision.** The playful octopus tone is a strong flavor, and strong flavors ruin the frame if they leak into navigation, credits, or legal copy. So the voice was scoped to exactly one place: the match content the writer generates. **Approach.** In Writer Phase 1 (2026-06-12) I wrote the Paulopus voice system prompt alongside the lock and debrief zod output schemas and the context derivation that feeds them. The voice lives in the prompt; the app chrome around it stays in a neutral maker's register. **Artifact** — where the voice is, and is not: | Surface | Voice | | --- | --- | | Pronostic / brief / debrief content | Paulopus octopus persona (from the voice system prompt) | | Pronostic appreciation on match rows | Paulopus octopus persona | | Tabs, footer, About, Legal, credits | Neutral, maker's voice | **Result.** The persona has one home. Everything structural around it reads straight, which is what lets the octopus be funny without the whole product feeling like a bit. ## A shared verdict palette so the brand can't drift **Decision.** Verdict color kept appearing in multiple places — a proportional gauge, counts, badges — and any of them drifting would make the four verdicts feel like different taxonomies. **Approach.** On 2026-06-17 the karma page redesign replaced its two-cell (Inspired / Red Cards) display with the home page's proportional verdict gauge, extended to all four verdict counts and tinted from a single shared `VERDICT_PALETTE` so segment, count, and badge colors are sourced from one place. **Artifact:** | Element | Color source | | --- | --- | | Gauge segment | `VERDICT_PALETTE` | | Verdict count | `VERDICT_PALETTE` | | Verdict badge | `VERDICT_PALETTE` | **Result.** One palette, three consumers, zero drift — the four verdicts read as one system across every screen that shows them. ## Crediting the borrowed and the generated **Decision.** A brand assembled from vendored assets and AI collaborators owes a clear paper trail. **Approach.** On 2026-06-17 I expanded the footer with a dedicated CREDITS section and added standalone About and Legal pages covering attributions and disclaimers. **Artifact** — the credited contributors: | Credited | | --- | | Design | | Claude Code | | Superpowers | | R74n flags | | Claude Sonnet | | openfootball | | Mascot art | **Result.** The mascot art, pixel flags, and AI collaborators that make the brand possible are all named on the surface itself — the credits are part of the design, not an afterthought.
  • date2026-07-24
  • descriptionA retro pixel aesthetic committed to without escape hatches — no rounded corners, no dark mode — a mascot whose mood reads the verdict, and an octopus persona confined to the match content so the chrome around it stays straight.
  • nameBrand & Voice
  • typearticle
  • statepublished