About this template
Virtual Pet Companion is a playable browser toy built around an original pixel-art pet and its miniature habitat. Feeding, playing, cleaning, and resting produce immediate sprite reactions while hunger, mood, cleanliness, and energy change with elapsed real time. Two short mini-games award coins, and a working wardrobe turns those winnings into wearable accessories. The pet, currency, high scores, outfits, and settings persist locally, so returning visitors can continue caring for the same companion.
This template suits developers, creators, students, and designers who want a compact game project, an interactive portfolio piece, or the starting point for a cozy web toy. It demonstrates a persistent simulation, keyboard and touch controls, canvas gameplay, SVG sprite animation, and responsive interface design without accounts or a backend. The main screen keeps the pet large and the care controls close at hand rather than presenting a marketing landing page.
Silkscreen headings, Nunito interface text, deep plum outlines, warm cream panels, and bright meadow accents establish a friendly retro-handheld character. The habitat, pet states, accessories, and mini-game objects are all drawn in code on integer pixel grids. There are no downloaded character sprites, stock images, branded objects, or external media requests.
Change the brand, pet name, species, habitat, or coin name in one content file and rewrite the supporting copy and artwork to fit. The same care loop works for a garden creature, space animal, tiny robot, or other original companion. Mobile layouts retain large touch targets, reduced-motion preferences are respected, and the complete production site builds to static files with local fonts and assets.
The template prompt
The live demo was built from exactly this text — nothing added.
# Virtual Pet Companion
Build this website exactly as described below. Replace the [VARIABLES] with your own values; keep everything else.
## Brief
Build [BRAND], an original virtual pet web toy starring [PET_NAME], a [PET_KIND] who lives in [HABITAT]. The first screen is a playable pixel-art habitat, not a promotional hero. Feed, play, clean, and rest actions change four real-time care meters and trigger original sprite reactions. Include two fully playable mini-games that award [COIN_NAME], six wearable outfit items to unlock and equip, local high scores, and versioned localStorage persistence. Use hash views for the pet home, arcade, and wardrobe while keeping one shared live pet state.
- Audience: Developers, creators, students, and designers building a cozy browser game, an interactive portfolio piece, or a small virtual companion for casual play on desktop and mobile.
- Goal: Let a visitor understand the pet's condition at a glance, perform a satisfying care action within five seconds, earn currency through real skill-based play, spend it on visible accessories, and return later to a consistent locally saved companion. Every visible control must perform its described function.
- Tone: Warm, playful, concise, and gently funny without baby talk, guilt, urgency, or punitive mechanics. Use clear US English labels and specific variable-aware messages. The pet can be sleepy or messy but never dies, gets ill, or shames the visitor.
## Stack
- Framework: Vite 7 + React 19 + TypeScript 5
- Styling: Tailwind CSS 3.4 + custom CSS
- Libraries: react (MIT), react-dom (MIT), lucide-react (ISC), @fontsource/silkscreen (OFL), @fontsource-variable/nunito (OFL)
- Build: `npm run build` → static files in `dist/`. No backend, no server code, no external APIs.
- Setup:
- Use React 19.2, TypeScript 5.9, Vite 7.2, @vitejs/plugin-react, Tailwind CSS 3.4, PostCSS, and Autoprefixer. package.json scripts are dev='vite', build='tsc -b && vite build', and preview='vite preview'. Do not add routing, state-management, animation, physics, game, audio, or component libraries.
- In vite.config.ts set base='./', plugins=[react()], build.outDir='dist', build.sourcemap=false, and assetsInlineLimit=0. Keep all asset URLs relative and do not copy src/ into dist/. The production build must be minified and remain below 20 MB.
- Configure Tailwind content for ./index.html and ./src/**/*.{ts,tsx}. Add every Design color to theme.extend.colors, display=['Silkscreen','monospace'], and sans=['Nunito Variable','system-ui','sans-serif']. Put integer-grid pixel rendering, stepped sprite keyframes, hard pixel shadows, canvas scaling, focus styles, and reduced-motion overrides in src/index.css.
- Import @fontsource/silkscreen/400.css, @fontsource/silkscreen/700.css, and @fontsource-variable/nunito in src/fonts.ts. Self-host only emitted Fontsource files; never request a font CDN. Use the actual OFL license files from the installed packages when writing ASSETS.md.
- Keep all visitor-facing copy, variable defaults, pet and habitat definitions, care-action labels and messages, game names and instructions, outfit names and prices, and empty states in typed src/content.ts. Resolve them from [BRAND], [PET_NAME], [PET_KIND], [HABITAT], and [COIN_NAME]. When values change, rewrite supporting copy, snack names, welcome messages, and original pet and habitat motifs to match; no default-specific string may remain in a component.
- Use one React context and reducer for the shared simulation. Keep hunger, mood, cleanliness, and energy as numbers from 0 to 100, plus [COIN_NAME] balance, owned and equipped outfits, game high scores, settings, activity messages, lastTickAt, and lastSavedAt. Recompute elapsed decay from Date.now() rather than counting intervals. Update the visible state once per second while the page is open and immediately after every action.
- Initial state is hunger 72, mood 80, cleanliness 68, energy 86, 30 [COIN_NAME], Leaf Cap owned and equipped, no high scores, and sound-free visual mode. Passive decay per real elapsed minute is hunger 0.30, mood 0.18, cleanliness 0.12, and energy 0.10. Clamp every meter to 0–100 and cap offline simulation at 10,080 minutes. At zero the pet shows a tired or needy sprite and a useful care prompt, never a death or failure state.
- Implement src/lib/storage.ts with a versioned key derived from a lowercase hyphenated BRAND slug, safe JSON parsing, explicit schema validation, numeric clamping, try/catch around localStorage, and a migration hook. Persist after each action, purchase, equip, completed game, and reset; also flush every 10 seconds and on pagehide. On reload apply elapsed decay once and show a single 'While you were away' summary only when at least one displayed meter changed. If saved data is corrupt, start cleanly and show a nonblocking explanation.
- Implement lightweight hash routing in src/App.tsx without a package: empty hash and index.html show the pet home, #/games shows the arcade, and #/wardrobe shows the wardrobe. Listen for hashchange, preserve the same in-memory simulation, and support direct deep links. Navigation uses ./index.html, #/games, and #/wardrobe; never use bare directory URLs or add undeclared routes.
- Suggested source files are App.tsx, content.ts, components/AppShell.tsx, PetScene.tsx, CarePanel.tsx, ActivityPanel.tsx, Arcade.tsx, MiniGameCanvas.tsx, Wardrobe.tsx, Toast.tsx, ResetDialog.tsx, lib/simulation.ts, lib/storage.ts, and lib/gameEngine.ts. Keep canvas game logic independent of React rendering and expose snapshots for HUD and results.
- Render both games on one responsive HTML canvas with a fixed 640×360 logical coordinate system, devicePixelRatio capped at 2, ResizeObserver, and pointer-coordinate scaling. Use requestAnimationFrame only during an active round, a fixed 1/60-second simulation step, and a seeded per-round PRNG. Pause must stop elapsed round time and movement. Cancel animation frames and listeners on exit or unmount. Do not use a game engine or remote assets.
## Variables
- [BRAND] — Virtual pet world name (default: "Pocket Meadow"). An invented short name used in the wordmark, document title, storage prefix, and footer.
- [PET_NAME] — Pet name (default: "Bramble"). A short invented companion name used throughout copy, reactions, and results.
- [PET_KIND] — Pet species (default: "moss bunny"). A lowercase original creature description; redraw the base sprite when this changes.
- [HABITAT] — Habitat name (default: "Sunpatch Burrow"). An invented place name that guides the room or landscape details.
- [COIN_NAME] — Currency name (default: "acorns"). A lowercase plural noun used for balances, rewards, prices, and insufficient-funds messages.
- [CREDIT] — keep a small "Template by VibeFather" link to https://vibefather.ai/t/virtual-pet-companion in the footer (default: yes; delete this line to remove it)
The copy under Pages & Sections is written for the default values. If your values differ, rewrite every headline, paragraph, label and image for them — same length, tone and structure. Layout, colors, type and motion stay as described.
Keep all copy, image paths and links in one content file (for example `src/content.ts`), keyed by section, so the content can be swapped later without touching components.
## Design
### Colors
- Midnight Plum `#241D31` — Page background, pixel outlines, and dark text on bright buttons.
- Deep Plum `#372A49` — Header, console panels, dialogs, and secondary dark surfaces.
- Warm Paper `#FFF3D6` — Primary text on dark surfaces, cards, labels, and sprite highlights.
- Muted Lavender `#B9AEC5` — Secondary text and inactive icons on dark surfaces.
- Meadow Leaf `#8AC926` — Primary actions, hunger meter, success states, and habitat foliage.
- Berry Coral `#FF7B6B` — Play action, mood meter, cheeks, and friendly alerts.
- Bubble Sky `#69C3D4` — Clean action, cleanliness meter, water, and cool highlights.
- Dream Lavender `#A78BFA` — Rest action, energy meter, night details, and selected outfit accents.
- Coin Honey `#F6C453` — Currency, unlock prices, rewards, and rare game objects.
- Habitat Mint `#BFE3C0` — Default habitat background and quiet illustrated surfaces.
- Pixel Line `#574665` — Panel borders, dividers, meter tracks, and inactive controls.
### Typography
- Wordmark, pet name, view headings, button labels, scores, and short status labels: Silkscreen (OFL), weights 400/700
- Body copy, instructions, activity messages, dialogs, meter context, and mobile navigation labels: Nunito Variable (OFL), weights 400/600/700/800
### Layout & motion
- Spacing: Use a 4px base grid and an 8px dominant rhythm. The app maximum width is 1280px with 24px desktop gutters and 12px mobile gutters. Header height is 64px desktop and 56px mobile. Main desktop top padding is 24px; the home grid columns have a 20px gap. Scene and console padding is 16px or 20px. Keep pointer targets at least 48×48px with at least 8px separation. On mobile use 12px panel padding and avoid squeezing four action buttons into one narrow row.
- Radius: Use a crisp pixel silhouette: 12px outer app panels, 8px scene and canvas frames, 4px buttons and meter cards, and 3px Midnight Plum borders. Primary buttons have a hard 4px 4px 0 Midnight Plum shadow that compresses to 1px 1px on press. Avoid glass, soft drop shadows, pill overload, and generic rounded bento cards.
- Motion: The pet idles on a two-frame steps(1,end) loop with one logical pixel of vertical movement every 760ms, a blink every 4.2 seconds, and occasional habitat prop movement. Keep the face and equipped accessory aligned in every frame.
- Motion: Feed, Play, Clean, and Rest select dedicated sprite states for 900ms. Feed drops two snack pixels toward the bowl, Play bounces a small ball once, Clean raises six square bubbles, and Rest dims the habitat by 18 percent and shows two small Z glyphs. Action feedback never blocks the next view navigation.
- Motion: Meter fills update over 180ms with steps(6,end), while numeric values update immediately. Buttons depress with the hard-shadow compression described above. Toasts remain for 2.4 seconds and never cover the pet or primary controls.
- Motion: Hash-view content crossfades for 140ms without route-based scroll-jacking. Wardrobe equips crossfade only the accessory layer for 120ms. Unlocking emits eight tiny square sparkles for 500ms, never full-screen confetti.
- Motion: Mini-games use continuous motion only after explicit Start. Reduced-motion mode removes decorative particles, easing, screen shake, and idle bobbing; game objects move in readable 10fps discrete steps and all results remain legible.
- Motion: Under prefers-reduced-motion outside active games, use static sprite poses, instant meter and accessory changes, no floating hearts or sparkles, and no automatic scene animation. Never flash more than three times per second.
- Imagery: Draw every visual asset in code as original pixel art. Build the habitat as inline SVG on a 160×90 logical grid with shape-rendering='crispEdges', integer coordinates, hard-edged rects and polygons, and no raster texture. Build the pet on a separate 32×32 grid rendered at least 192×192px on desktop. Default [PET_NAME] is a moss bunny with an original square body, two uneven leaf ears, a cream muzzle, coral cheek pixels, and a tiny square tail; do not derive its silhouette from an existing character. Create idle, blink, happy, eating, playing, washing, resting, and needy poses plus independent 32×32 accessory overlays. The default habitat includes a large window, leafy arch, food bowl, toy ball, washing nook, shelf, rug, and small plants. Rewrite and redraw species-specific features, habitat motifs, and falling snacks when PET_KIND or HABITAT changes. Use the same original pet and equipped overlay in home, arcade, and wardrobe. No people, real likenesses, stock images, downloaded sprite sheets, logos, branded props, or text baked into artwork.
## Pages & Sections
### [BRAND] — [PET_NAME]'s Home (`index.html`)
1. **Shared header and navigation** — Create the shared shell used by all three views. The header has an original four-pixel sprout mark, the [BRAND] wordmark, and three navigation links labeled 'Pet', 'Arcade', and 'Wardrobe'. Pet links to ./index.html, Arcade to #/games, and Wardrobe to #/wardrobe. The right side shows a Honey coin icon, the current numeric balance, and [COIN_NAME]. The active view has a Meadow Leaf underline and aria-current='page'. The document title begins with [BRAND] and the favicon uses the original sprout mark. Do not add login, cloud, notification, store, or social controls.
Layout: Use a Midnight Plum page with a Deep Plum sticky header and a 3px Pixel Line bottom border. Keep header content inside the 1280px container. Brand sits left, navigation center, and currency right. At 390px use brand icon plus short wordmark on the first row only if it fits; otherwise put the wordmark above a compact three-link navigation row within the 56px minimum header, keep the currency visible, and never hide navigation behind an unlabeled icon. All links retain 48px touch targets.
Motion: Active navigation changes immediately; hover only shifts a link by one logical pixel. Currency changes briefly highlight in Coin Honey for 300ms without counting up slowly.
2. **Pet habitat and welcome** — Above the scene, a small Warm Paper eyebrow reads [HABITAT] and the H1 reads 'Meet [PET_NAME].' A short variable-aware line says 'Your little [PET_KIND], ready for a quiet break.' Inside the large original habitat, show [PET_NAME] with the currently equipped outfit and an expressive thought bubble; the default thought is 'Is that a snack?' Clicking or tapping the pet toggles a happy reaction and adds one activity message but does not award currency. A bowl triggers Feed, the ball triggers Play, and the washing nook triggers Clean using the same reducer actions as the care buttons. Bottom-left scene text reads [HABITAT]; bottom-right status is derived from the lowest meter and reads 'All needs steady', 'Could use a little care', or 'Time for some care'. Include a visually hidden text summary of the scene and current pet state.
Layout: The home workspace is a grid with minmax(0,1.65fr) and minmax(330px,0.85fr). The habitat occupies the left column with a 16/10 aspect ratio, minimum height 460px, overflow hidden, Habitat Mint background, and a 3px Midnight Plum frame. The heading row is compact enough that the scene and care actions fit within the first 900px desktop viewport. The pet fills roughly 32 percent of scene width and sits slightly below center, with props kept away from its face. Below 900px use one column with habitat first. At 390px use a 4/3 scene, no minimum height, a pet about 46 percent of scene width, smaller captions on solid Deep Plum backing, and no horizontal cropping or page overflow.
Motion: Use the idle, blink, prop-click, and action reactions from Design. The thought bubble changes only with state or actions, never as an infinite text marquee. Reduced-motion users see a complete static habitat with clear textual status.
3. **Live care console** — Title the right console 'Care for [PET_NAME]' with a small live indicator labeled 'Needs update with real time'. Render four meters in this exact order: Hunger in Meadow Leaf, Mood in Berry Coral, Cleanliness in Bubble Sky, and Energy in Dream Lavender. Each has a Lucide icon, label, integer 0–100 value, accessible progress bar, and status word: 70–100 'Great', 40–69 'Okay', 1–39 'Low', and 0 'Needs care'. The summary line always recommends an action for the lowest meter instead of using generic filler.
Render four action buttons: Feed with Utensils and shortcut F, Play with Gamepad2 and P, Clean with ShowerHead and C, and Rest with Moon and R. Feed adds 24 Hunger, 3 Mood, and subtracts 4 Cleanliness. Play adds 18 Mood and subtracts 10 Energy, 6 Cleanliness, and 4 Hunger; if Energy is below 10, do not run it and show 'A quick rest will help first.' Clean adds 32 Cleanliness and 4 Mood and subtracts 3 Energy. Rest adds 30 Energy and subtracts 4 Hunger. Clamp results to 0–100. Each action updates lastTickAt, the pet sprite, activity log, and local save. Ignore keyboard shortcuts while typing or playing a mini-game. During a 1.2-second action cooldown, keep controls readable and show a small inline status rather than silently dropping input.
Layout: Use one Deep Plum console with 20px padding and four 58px meter rows separated by Pixel Line dividers. The action area is a two-by-two grid of 52px-minimum buttons with icon, label, and small shortcut hint. Feed uses Meadow Leaf, Play Berry Coral, Clean Bubble Sky, and Rest Dream Lavender, all with Midnight Plum text and borders. On mobile use a two-column meter summary followed by the same two-by-two action grid; do not create a horizontally scrolling button strip or cover content with a sticky action bar.
Motion: Each successful action runs its named 900ms sprite state and corresponding particles. Low-energy Play uses a single 160ms horizontal nudge and the explanatory message, with no shake under reduced motion. Meter updates follow the stepped transition in Design.
4. **Activity, next unlock, and save controls** — Below the workspace, create a two-column area. 'Little moments' lists the four newest activity messages newest first without dates or fake online events; initial entries are '[PET_NAME] moved into [HABITAT].' and 'A tiny jar held 30 [COIN_NAME].' Subsequent entries name the actual care action, game reward, unlock, or equipped item. 'Next wardrobe treat' shows the least expensive item not yet owned, its pixel preview, exact price, current balance, and a 'Visit wardrobe' link. If every item is owned, show 'Every look is unlocked. Time to mix and match.'
A compact 'How care works' row contains three notes: 'Needs change with elapsed time', 'Games earn [COIN_NAME]', and 'Progress saves on this device'. Include a subtle 'Reset pet' text button. Its dialog says 'Start over with [PET_NAME]?' and explains that care progress, [COIN_NAME], outfits, activity, and high scores on this device will be cleared. Cancel and Reset pet are explicit; resetting restores the initial state and closes the dialog.
Layout: Use minmax(0,1.3fr) and minmax(300px,0.7fr) columns with 20px gap and Deep Plum surfaces, then stack below 820px. Activity rows are text-led with 12px vertical gaps rather than nested cards. The next-unlock panel has a 96px pixel preview at left and details at right. The reset dialog is centered at maximum width 440px with a Midnight Plum scrim, focus trap, Escape handling, and focus return.
Motion: New activity appears with a 140ms opacity change. Next-unlock progress and dialog use no elaborate celebration. Reduced motion makes all changes instant.
5. **Shared footer** — The shared footer left reads [BRAND] followed by 'A small companion for quiet breaks.' The right reads 'Saved on this device · No account · Original pixel art' and includes the optional [CREDIT] link when enabled. Do not display dates, member counts, reviews, pricing, cloud claims, health claims, or template-license text inside the toy.
Layout: Use a full-width top Pixel Line border, 24px vertical padding, and the same 1280px container. Keep footer items in a desktop flex row and stack them with 8px gaps on mobile. Reuse this footer unchanged on arcade and wardrobe views.
Motion: The footer is static.
### [BRAND] — Pocket Arcade (`#/games`)
1. **Arcade intro and game selector** — Reuse the shared header, live [COIN_NAME] balance, and footer. The eyebrow reads 'Pocket arcade' and H1 reads 'Play for [COIN_NAME].' Supporting copy says 'Two quick games. Real rewards. Your best scores stay on this device.' Provide two selector cards with original pixel thumbnails and Play buttons. 'Snack Catch' is labeled '30 seconds · Move & catch' with instructions 'Guide [PET_NAME] under falling snacks. Each catch adds 1 to the round reward.' 'Bubble Pop' is labeled '25 seconds · Aim & pop' with instructions 'Pop drifting bubbles. Large bubbles add 1 and small bubbles add 2.' Each card shows its saved high score or 'No score yet'. Selecting a card prepares the matching game but does not start movement until Start is pressed.
Layout: Keep the intro compact, then use a two-column selector grid above the game workspace. Cards have 16px padding, 3px Pixel Line borders, 96px pixel thumbnails, and a Meadow Leaf selected border. The game workspace uses minmax(0,1fr) and a 280px instructions rail on desktop. Below 900px make one column; on mobile keep selector cards as two compact columns only if labels fit without truncation, otherwise stack them. The canvas remains fully visible at 390px with a 16/9 ratio.
Motion: Selecting a game swaps the prepared scene with a 140ms crossfade and updates the instructions. Thumbnails are static pixel compositions, not autoplaying game demos.
2. **Snack Catch live game** — The shared canvas HUD shows 'Snack Catch', Score, Time, current high score, Pause, and Restart. The initial canvas shows [PET_NAME] beside a basket and the overlay 'Catch snacks for 30 seconds.' The primary button says Start. During play, move [PET_NAME] horizontally along the bottom with ArrowLeft/ArrowRight or A/D, pointer drag, and two visible 48px touch buttons labeled Left and Right. Spawn one variable-appropriate snack every 600ms at a seeded horizontal position. Falling speed starts at 110 logical pixels per second, rises by 4 pixels per second each elapsed second, and caps at 230. A caught snack adds 1 Score and 1 to the pending [COIN_NAME] reward; a miss has no penalty. Pause freezes movement and the absolute round timer. At 30 seconds, bank Score as the same number of [COIN_NAME], update total balance and high score once, save, and show 'Round complete', Score, '+N [COIN_NAME]', Play again, and 'Back to pet'. Exiting before completion banks nothing and says so in a small confirmation.
Layout: Use the 640×360 logical canvas with a Deep Plum frame and a solid habitat-colored playfield. HUD sits above the canvas in one row and wraps into three compact groups on mobile. Touch direction buttons sit below, not over, the canvas. The instructions rail repeats controls, reward rule, and 'Misses cost nothing.' Results appear as a centered Deep Plum panel over a paused final frame with no layout shift outside the canvas.
Motion: Use fixed-step movement and small square catch particles. Never move the entire page, shake the canvas, or flash on catches. Reduced motion uses discrete 10fps positions and no particles.
3. **Bubble Pop live game** — Bubble Pop uses the same HUD, result, pause, restart, banking, and exit behavior with a 25-second round. The initial overlay reads 'Pop bubbles for 25 seconds.' Spawn at most eight bubbles, one every 550ms, each with a 3.2-second lifetime and a slow upward drift. Seventy-five percent are large radius-22 Bubble Sky bubbles worth 1; twenty-five percent are small radius-13 Coin Honey bubbles worth 2. Pointer and touch taps pop directly. For keyboard play, Arrow keys or WASD move a visible square reticle and Space pops a bubble whose center is within its radius plus 10 logical pixels. Show the control hint before Start and keep focus on the game region during a round. Misses and expired bubbles have no penalty. Final Score converts one-for-one to [COIN_NAME], updates balance and high score once, and persists immediately.
Layout: Keep the same canvas and HUD geometry as Snack Catch so switching games does not jump the page. Bubbles cannot spawn under the HUD or within 20 logical pixels of the canvas edge. The instructions rail lists Pointer/touch: tap a bubble; Keyboard: arrows or WASD, Space to pop; Large +1, small +2. Provide an accessible text score and timer outside the canvas.
Motion: Bubbles drift at 24–42 logical pixels per second with no unpredictable acceleration. Popping uses a 120ms four-pixel ring only in standard motion. Reduced motion removes the ring and uses discrete movement while preserving hit areas and timing.
4. **Reward explanation and wardrobe link** — Below the game workspace, show three concise notes: 'Rewards bank when a round ends', 'Pausing freezes the clock', and 'High scores and [COIN_NAME] save on this device'. A Dream Lavender panel says 'Ready for a new look?' with a 'Spend [COIN_NAME] in the wardrobe' link to #/wardrobe. Do not add leaderboards, multiplayer, daily streaks, ads, random paid loot, fake opponents, online status, or external sharing.
Layout: Use a simple three-column notes row and a full-width inline wardrobe callout with 20px padding. Stack notes on mobile. Keep the callout below the playable area so it never competes with Start or game controls.
Motion: Only the link hover uses a one-pixel translation; the notes are static.
### [BRAND] — [PET_NAME]'s Wardrobe (`#/wardrobe`)
1. **Dressing room and pet preview** — Reuse the shared shell and balance. The eyebrow reads 'Wardrobe' and H1 reads 'A new look for [PET_NAME].' Supporting copy says 'Unlock once, wear whenever. Everything is saved on this device.' The left preview shows the same original [PET_KIND] sprite and current accessory over a simple checker-pixel dressing rug in [HABITAT]. Under it show the equipped item name and a 'Remove accessory' action that selects the always-available None state without deleting owned items. A 'Play to earn more' link returns to #/games.
Layout: Use a minmax(0,0.9fr) and minmax(0,1.1fr) two-column dressing room with 20px gap. The preview is at least 420px high on desktop with the pet rendered 224×224px, a large Warm Paper nameplate, and a Deep Plum frame. Stack preview first on mobile, reduce its height to 300px and pet to 176×176px, and keep the Remove accessory and earning link reachable without horizontal scrolling.
Motion: Changing accessories crossfades only the overlay for 120ms and plays the pet's happy pose. Reduced motion swaps instantly. The preview otherwise uses the same quiet idle as the home pet.
2. **Six-item unlock and equip grid** — Render exactly six original accessory cards, each with a code-drawn preview, description, price in [COIN_NAME], and one clear action. Leaf Cap costs 0 and starts owned: 'A two-leaf cap for sunny lounging.' Berry Scarf costs 20: 'A coral neckerchief with a square knot.' Cloud Hood costs 35: 'A sky-blue hood with tiny cream tufts.' Star Glasses costs 55: 'Honey pixel frames with four-point arms.' Cozy Cape costs 80: 'A lavender cape with a cream clasp.' Sun Crown costs 120: 'A five-point crown made for tiny celebrations.' None is a separate free state, not a seventh purchasable card.
Owned items show Equip or Equipped with aria-pressed. Unowned items show 'Unlock · N [COIN_NAME]'. Unlocking checks the current balance atomically, subtracts the exact price, adds the item to owned items, equips it, updates every balance display, saves, and shows '[Item] unlocked. Looking good, [PET_NAME]!' If funds are insufficient, show 'Need N more [COIN_NAME]' and do not change balance or inventory. Never use fake purchase buttons or a checkout. Accessories are independent aligned overlays on the same pet and remain visible on home, game previews, and after reload.
Layout: Use a two-column card grid within the right column, with 16px gaps and 16px padding. Each card has a 96×96px pixel preview at top, name and price on one row, short description, and a full-width 48px action at bottom. At 390px keep one card per row so descriptions and buttons never truncate. Equipped uses Dream Lavender, affordable Unlock uses Meadow Leaf, and insufficient funds uses Deep Plum with Muted Lavender text while retaining readable contrast.
Motion: Unlock uses the eight-square sparkle burst and a brief balance highlight. Equip uses only the preview transition. No slot-machine motion, random rarity, countdown, or artificial scarcity.
3. **Wardrobe help** — A bottom note titled 'Tiny closet, simple rules' contains three lines: 'Play either arcade game to earn [COIN_NAME].', 'Unlocks are permanent on this device.', 'Choose Remove accessory for the original look.' Include a text link 'Back to [PET_NAME]' pointing to ./index.html. Do not add premium currency, real-money prices, trading, selling, item durability, expiring items, or unimplemented 'coming soon' cards.
Layout: Place the note below the dressing room as one flat Deep Plum panel with 20px padding and three short rows. Keep the back link at the lower right on desktop and full width on mobile.
Motion: The help area is static.
## Assets
- image: No third-party, stock, raster, or generated image files. Draw the sprout mark, favicon, pet and all poses, habitat, care props, accessory overlays, game thumbnails, snacks, bubbles, and particles as original inline SVG, CSS, and Canvas pixel art on the specified integer grids. Record in ASSETS.md that all illustrations and sprites are project-original code-drawn assets and that no external image files are used.
- icon: Use only tree-shaken lucide-react icons (ISC) for interface controls: Coins, House, Gamepad2, Shirt, Utensils, ShowerHead, Moon, Heart, Droplets, Zap, Play, Pause, RotateCcw, Trophy, ArrowLeft, ArrowRight, Lock, Check, X, Sparkles, and ChevronRight. Do not import brand icons. In ASSETS.md list imported modules, https://www.npmjs.com/package/lucide-react, Lucide contributors, and the ISC license.
- font: Self-host Silkscreen 400/700 and Nunito Variable through @fontsource/silkscreen and @fontsource-variable/nunito (OFL). In ASSETS.md list emitted local woff2 paths, package source URLs, copyright holders copied from the bundled OFL files, and the OFL license. No Google Fonts, Adobe Fonts, or other font CDN.
## Don'ts
- Do not copy or adapt any existing virtual-pet brand, character species design, mascot, silhouette, signature animation, sprite sheet, screen layout, meter design, icons, sounds, code, prompt, slogans, or exact copy. Implement the specified original pet and interface from scratch.
- Do not use real people's likenesses, anime, game or film characters, celebrity-inspired pets, branded accessories, recognizable product designs, logos, or existing game typography. The default and alternate pets must both be original generic creations.
- Do not use stock photos, downloaded sprite packs, placeholder-image services, external image URLs, Unsplash, Pexels, Pixabay, or generated raster assets. All visual game and habitat art is local SVG, CSS, or Canvas code.
- Do not use a backend, server code, API routes, accounts, authentication, databases, external APIs, analytics, ads, notifications, cloud sync, online leaderboards, or forms that submit anywhere. All simulation and persistence stay in the browser with localStorage.
- Do not fake the simulation. Meters must derive from elapsed real time, all four care actions must apply the exact effects, both mini-games must be playable with working timing and rewards, purchases must debit the exact balance, equipped accessories must render on the pet, and all specified state must survive reload.
- Do not use interval counts as a substitute for timestamps, apply offline decay twice, award currency for idling or repeated early exits, bank a round twice, allow negative currency, or allow invalid saved JSON to crash the app. Clamp values and handle storage failures visibly but nondestructively.
- Do not leave default variable content in components or merely swap labels when values change. All copy lives in src/content.ts; pet features, habitat motifs, snack art, activity messages, reward labels, and wardrobe feedback must follow [BRAND], [PET_NAME], [PET_KIND], [HABITAT], and [COIN_NAME].
- Do not add death, illness, injury, punishment, guilt copy, streak loss, urgent push notifications, manipulative timers, paid loot, gambling, real-money purchases, or claims about health, productivity, or emotional benefits.
- Do not load scripts, styles, fonts, icons, images, audio, or media from a CDN or hotlink. Self-host the fixed Fontsource fonts, tree-shake Lucide, list all third-party files and licenses in ASSETS.md, and add no unverified audio or video.
- Do not add npm dependencies beyond the fixed stack or use restricted UI source, commercial fonts, CC BY-NC, CC BY-SA, unlicensed packages, a game engine, a router, or a state-management library.
- Do not turn the first screen into a typography-led landing page, marketing hero, static app screenshot, generic bento dashboard, signup funnel, or pricing page. The large animated pet habitat and working care console are the product.
- Do not add scroll-jacking, parallax, cursor followers, autoplaying game rounds, automatic audio, infinite text marquees, flashing effects, fake opponents, online activity, public scores, member counts, dates, or invented accolades.
- Do not emit source maps, copy src/ into dist/, use absolute root asset URLs, exceed 20 MB, or require a server. The single npm run build command must produce minified relative-path static files in dist/.
- Do not add routes beyond ./index.html, #/games, and #/wardrobe, use bare-directory links, or leave deep links broken. Reuse the shared simulation and shell on every view; dialogs and game results are local interface states.
- Do not ignore mobile or accessibility. At 1440×900 and 390×844 there must be zero console errors and no page-level horizontal overflow; all controls need labels, visible focus, 48px targets, keyboard equivalents, accessible meter values, touch-friendly game controls, and reduced-motion behavior.
- Do not mention VibeFather inside the toy except the optional [CREDIT] footer link, and do not add SEO metadata blocks, structured data, sitemap instructions, keyword-stuffed headings, or other unrelated marketing work.
---
— Prompt by VibeFather · https://vibefather.ai/t/virtual-pet-companion · CC BY-NC 4.0 (non-commercial; commercial use needs a VibeFather Pro license) · Request removal: https://vibefather.ai/takedown
Free for personal projects under CC BY-NC 4.0. Commercial use comes with Pro.
DESIGN.md
The design system on its own — colors, type, spacing and motion. Apply this look to a project you already have.
---
name: "Virtual Pet Companion"
colors:
midnight_plum: "#241D31"
deep_plum: "#372A49"
warm_paper: "#FFF3D6"
muted_lavender: "#B9AEC5"
meadow_leaf: "#8AC926"
berry_coral: "#FF7B6B"
bubble_sky: "#69C3D4"
dream_lavender: "#A78BFA"
coin_honey: "#F6C453"
habitat_mint: "#BFE3C0"
pixel_line: "#574665"
typography:
wordmark_pet_name_view_headings_button_labels_scores_and_short_status_labels: { family: "Silkscreen", weights: [400, 700] }
body_copy_instructions_activity_messages_dialogs_meter_context_and_mobile_navigation_labels: { family: "Nunito Variable", weights: [400, 600, 700, 800] }
spacing: "Use a 4px base grid and an 8px dominant rhythm. The app maximum width is 1280px with 24px desktop gutters and 12px mobile gutters. Header height is 64px desktop and 56px mobile. Main desktop top padding is 24px; the home grid columns have a 20px gap. Scene and console padding is 16px or 20px. Keep pointer targets at least 48×48px with at least 8px separation. On mobile use 12px panel padding and avoid squeezing four action buttons into one narrow row."
radius: "Use a crisp pixel silhouette: 12px outer app panels, 8px scene and canvas frames, 4px buttons and meter cards, and 3px Midnight Plum borders. Primary buttons have a hard 4px 4px 0 Midnight Plum shadow that compresses to 1px 1px on press. Avoid glass, soft drop shadows, pill overload, and generic rounded bento cards."
---
# Virtual Pet Companion — Design System
Apply this design system to an existing project. It describes the look and feel only; for the full site, use prompt.md.
## Colors
- **Midnight Plum** `#241D31` — Page background, pixel outlines, and dark text on bright buttons.
- **Deep Plum** `#372A49` — Header, console panels, dialogs, and secondary dark surfaces.
- **Warm Paper** `#FFF3D6` — Primary text on dark surfaces, cards, labels, and sprite highlights.
- **Muted Lavender** `#B9AEC5` — Secondary text and inactive icons on dark surfaces.
- **Meadow Leaf** `#8AC926` — Primary actions, hunger meter, success states, and habitat foliage.
- **Berry Coral** `#FF7B6B` — Play action, mood meter, cheeks, and friendly alerts.
- **Bubble Sky** `#69C3D4` — Clean action, cleanliness meter, water, and cool highlights.
- **Dream Lavender** `#A78BFA` — Rest action, energy meter, night details, and selected outfit accents.
- **Coin Honey** `#F6C453` — Currency, unlock prices, rewards, and rare game objects.
- **Habitat Mint** `#BFE3C0` — Default habitat background and quiet illustrated surfaces.
- **Pixel Line** `#574665` — Panel borders, dividers, meter tracks, and inactive controls.
## Typography
- **Wordmark, pet name, view headings, button labels, scores, and short status labels** — Silkscreen (OFL), weights 400/700. Self-host the font files.
- **Body copy, instructions, activity messages, dialogs, meter context, and mobile navigation labels** — Nunito Variable (OFL), weights 400/600/700/800. Self-host the font files.
## Spacing & shape
- Spacing: Use a 4px base grid and an 8px dominant rhythm. The app maximum width is 1280px with 24px desktop gutters and 12px mobile gutters. Header height is 64px desktop and 56px mobile. Main desktop top padding is 24px; the home grid columns have a 20px gap. Scene and console padding is 16px or 20px. Keep pointer targets at least 48×48px with at least 8px separation. On mobile use 12px panel padding and avoid squeezing four action buttons into one narrow row.
- Radius: Use a crisp pixel silhouette: 12px outer app panels, 8px scene and canvas frames, 4px buttons and meter cards, and 3px Midnight Plum borders. Primary buttons have a hard 4px 4px 0 Midnight Plum shadow that compresses to 1px 1px on press. Avoid glass, soft drop shadows, pill overload, and generic rounded bento cards.
## Motion
- The pet idles on a two-frame steps(1,end) loop with one logical pixel of vertical movement every 760ms, a blink every 4.2 seconds, and occasional habitat prop movement. Keep the face and equipped accessory aligned in every frame.
- Feed, Play, Clean, and Rest select dedicated sprite states for 900ms. Feed drops two snack pixels toward the bowl, Play bounces a small ball once, Clean raises six square bubbles, and Rest dims the habitat by 18 percent and shows two small Z glyphs. Action feedback never blocks the next view navigation.
- Meter fills update over 180ms with steps(6,end), while numeric values update immediately. Buttons depress with the hard-shadow compression described above. Toasts remain for 2.4 seconds and never cover the pet or primary controls.
- Hash-view content crossfades for 140ms without route-based scroll-jacking. Wardrobe equips crossfade only the accessory layer for 120ms. Unlocking emits eight tiny square sparkles for 500ms, never full-screen confetti.
- Mini-games use continuous motion only after explicit Start. Reduced-motion mode removes decorative particles, easing, screen shake, and idle bobbing; game objects move in readable 10fps discrete steps and all results remain legible.
- Under prefers-reduced-motion outside active games, use static sprite poses, instant meter and accessory changes, no floating hearts or sparkles, and no automatic scene animation. Never flash more than three times per second.
## Imagery
Draw every visual asset in code as original pixel art. Build the habitat as inline SVG on a 160×90 logical grid with shape-rendering='crispEdges', integer coordinates, hard-edged rects and polygons, and no raster texture. Build the pet on a separate 32×32 grid rendered at least 192×192px on desktop. Default [PET_NAME] is a moss bunny with an original square body, two uneven leaf ears, a cream muzzle, coral cheek pixels, and a tiny square tail; do not derive its silhouette from an existing character. Create idle, blink, happy, eating, playing, washing, resting, and needy poses plus independent 32×32 accessory overlays. The default habitat includes a large window, leafy arch, food bowl, toy ball, washing nook, shelf, rug, and small plants. Rewrite and redraw species-specific features, habitat motifs, and falling snacks when PET_KIND or HABITAT changes. Use the same original pet and equipped overlay in home, arcade, and wardrobe. No people, real likenesses, stock images, downloaded sprite sheets, logos, branded props, or text baked into artwork.
## Tone
Warm, playful, concise, and gently funny without baby talk, guilt, urgency, or punitive mechanics. Use clear US English labels and specific variable-aware messages. The pet can be sleepy or messy but never dies, gets ill, or shames the visitor.
---
— Prompt by VibeFather · https://vibefather.ai/t/virtual-pet-companion · CC BY-NC 4.0 (non-commercial; commercial use needs a VibeFather Pro license) · Request removal: https://vibefather.ai/takedown