Cat Mode & Personality Mapping Layer
smo1 beginner 3 min read
ELI5
SMO1 can speak two languages. In “cat mode,” it says things like “Pawprintz” and “Treatz” and calls your dashboard “Paws Control.” In “professional mode,” it says “Activity Score” and “Compression Efficiency” and calls it “Filters.” It is like having a playful friend who can also put on a suit and talk business when needed. Users can switch between the two modes anytime.
Technical Deep Dive
Mind Map of Modes
%%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#e8f4f8', 'primaryTextColor': '#2d3748', 'primaryBorderColor': '#90cdf4', 'lineColor': '#718096', 'secondaryColor': '#f0fff4', 'tertiaryColor': '#fefcbf'}}}%%mindmap root((Personality Layer)) Cat Mode Pawprintz → Activity Score Treatz → Compression Efficiency Niblz → Characters Saved Paws Control → Filters Sniff out your smol links → Search links Boopz → Clicks Meow → Hello Professional Mode Activity Score Compression Efficiency Characters Saved Filters Search links Clicks Hello Shared Infrastructure @smo1/config React Context oklch colour space Tailwind CSSMapping Layer
The personality mapping lives in catnip-packages/packages/config/src/personality.ts:
export const personalityMap = { metrics: { pawprintz: { cat: 'Pawprintz', pro: 'Activity Score' }, treatz: { cat: 'Treatz', pro: 'Compression Efficiency' }, niblz: { cat: 'Niblz', pro: 'Characters Saved' }, }, actions: { search: { cat: 'Sniff out your smol links', pro: 'Search links' }, filter: { cat: 'Paws Control', pro: 'Filters' }, create: { cat: 'Make a smol link', pro: 'Create link' }, }, statuses: { new: { cat: '🆕 new', pro: 'New' }, zoomies: { cat: '⚡ zoomies', pro: 'Viral' }, playful: { cat: '🎾 playful', pro: 'Active' }, curious: { cat: '🔍 curious', pro: 'Warm' }, sleepy: { cat: '😴 sleepy', pro: 'Dormant' }, loaf: { cat: '🍞 loaf', pro: 'Inactive' }, }, labels: { clicks: { cat: 'Boopz', pro: 'Clicks' }, visitors: { cat: 'Sniffers', pro: 'Visitors' }, greeting: { cat: 'Meow', pro: 'Hello' }, },} as const;React Context
meow-web provides a CatModeContext that wraps the app:
// Simplifiedconst CatModeContext = createContext<{ mode: 'cat' | 'professional'; toggle: () => void;}>();- Default: Inferred from user preference (stored in localStorage) or system preference
- Toggle: A switch in
/settings/appearanceflips between modes - Persistence:
localStorage.setItem('smo1:personality', mode)
Colour System
Status colours use the oklch colour space for perceptual uniformity:
export const statusColors = { new: 'oklch(70% 0.15 250)', // soft blue zoomies: 'oklch(70% 0.2 30)', // vibrant red-orange playful: 'oklch(75% 0.18 140)', // lively green curious: 'oklch(75% 0.15 80)', // warm yellow sleepy: 'oklch(65% 0.05 260)', // muted grey-blue loaf: 'oklch(60% 0.03 30)', // dull brown};oklch advantages over hex/RGB:
- Perceptually uniform: changing lightness by 10% looks like the same visual step regardless of hue
- Wide gamut: supports modern displays (P3, Rec.2020)
- Accessible: easier to generate contrast-compliant variants
Usage in Components
import { usePersonality } from '@smo1/config';
function MetricCard({ type, value }) { const { label } = usePersonality(type); // Returns cat or pro label based on context return ( <Card> <CardTitle>{label}</CardTitle> <CardValue>{value}</CardValue> </Card> );}Feature Flag
Cat mode is controlled by the FEATURE_GAMIFICATION environment variable:
true(default): Cat mode toggle is availablefalse: UI defaults to professional mode; toggle is hidden
This allows enterprise deployments to disable playful branding entirely.
Key Terms
- Personality mapping → Translation layer between cat-themed and professional UI labels
- oklch → Perceptually uniform colour space used for status colours
- React Context → React mechanism for sharing state (mode preference) across the component tree without prop drilling
- Perceptually uniform → Colour space where equal numeric changes produce equal perceived visual changes
- Feature flag → Environment variable enabling/disabling a feature without code changes
Q&A
Q: Why two modes instead of just one? A: Cat mode reinforces brand identity and makes the product memorable. Professional mode is required for enterprise contexts, presentations to non-technical stakeholders, and users who simply prefer plain language.
Q: Does purr-api know about cat mode?
A: No. The API returns canonical identifiers (e.g., status: "zoomies"). The frontend translates these to cat or professional labels. The backend is mode-agnostic.
Q: Can third-party API consumers use cat mode? A: No. The REST API always returns canonical values. Cat mode is a presentation-layer concern exclusive to meow-web.
Q: What happens if a new status is added but personality mapping is forgotten?
A: The component falls back to the canonical identifier (e.g., "zoomies" instead of "Viral" or "⚡ zoomies"). This is a graceful degradation, but linting should catch missing mappings during development.
Examples
Think of the personality layer like a bilingual restaurant:
- Cat mode is the playful menu with dishes named “Purr-fect Pasta” and “Meow-shroom Risotto”
- Professional mode is the same menu in plain English: “Creamy Mushroom Risotto”
- The mapping layer is the translator who knows both languages and switches based on which customer sits down
- oklch colours are the carefully chosen paint colours that look the same brightness under different lighting (daylight vs. candlelight)
- The toggle switch is the “English / 日本語” button at the top of the menu
neighbors on the map
- Gamification: Pawprintz, Treatz & Niblz explaining link health scores to a user
- XP & Level System designing new achievement rewards