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:
| 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.