From a42847063f3738edbb26b511f9ecaef793da6789 Mon Sep 17 00:00:00 2001 From: Parfii-bot Date: Fri, 24 Apr 2026 03:17:25 +0800 Subject: [PATCH] feat(cortex-ui): pet sprite render with mood switcher MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cherry-pick 7 pixel-art sprites from feat/pet-ui-v1 (PR #16) — cat (idle/happy/think/sleep), dog-idle, owl-idle, blob-idle — into cortex-ui public dir so the PetEditor view renders a visual pet instead of a bare JSON dump. ## Behavior - Species inferred from first letter of pet_name: - 'd*' → dog, 'o*' → owl, 'b*' → blob, else → cat (default, has 4 mood states) - Mood switcher: click idle / happy / think / sleep → swaps sprite - image-rendering: pixelated for crisp pixel-art scaling - 32×32 native scaled to 128×128 (4x) with nearest-neighbor ## Why now User tested the UI end-to-end, confirmed auth+CORS+whitespace fix works, then asked for the cat. The sprite-gen commit (PR #16) is still unmerged but sprites are sibling static assets — safe to copy into cortex-ui without blocking on PR merge. Ownership stays with the sprite-gen branch; cortex-ui just embeds the artefacts. Rebuild hash: index-RLWTBoLo.js + index-BzERxlis.css. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../public/sprites/32px/blob-idle.png | Bin 0 -> 2301 bytes .../public/sprites/32px/cat-happy.png | Bin 0 -> 3193 bytes .../public/sprites/32px/cat-idle.png | Bin 0 -> 2611 bytes .../public/sprites/32px/cat-sleep.png | Bin 0 -> 2954 bytes .../public/sprites/32px/cat-think.png | Bin 0 -> 2149 bytes .../public/sprites/32px/dog-idle.png | Bin 0 -> 2302 bytes .../public/sprites/32px/owl-idle.png | Bin 0 -> 2959 bytes .../cortex-ui/src/routes/PetEditor.svelte | 46 ++++++++++++++++++ .../packages/cortex-ui/src/styles/app.css | 46 ++++++++++++++++++ 9 files changed, 92 insertions(+) create mode 100644 _ts_packages/packages/cortex-ui/public/sprites/32px/blob-idle.png create mode 100644 _ts_packages/packages/cortex-ui/public/sprites/32px/cat-happy.png create mode 100644 _ts_packages/packages/cortex-ui/public/sprites/32px/cat-idle.png create mode 100644 _ts_packages/packages/cortex-ui/public/sprites/32px/cat-sleep.png create mode 100644 _ts_packages/packages/cortex-ui/public/sprites/32px/cat-think.png create mode 100644 _ts_packages/packages/cortex-ui/public/sprites/32px/dog-idle.png create mode 100644 _ts_packages/packages/cortex-ui/public/sprites/32px/owl-idle.png diff --git a/_ts_packages/packages/cortex-ui/public/sprites/32px/blob-idle.png b/_ts_packages/packages/cortex-ui/public/sprites/32px/blob-idle.png new file mode 100644 index 0000000000000000000000000000000000000000..9903d66efa8e593c609d568b4526fb56ae42f220 GIT binary patch literal 2301 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 literal 0 HcmV?d00001 diff --git a/_ts_packages/packages/cortex-ui/public/sprites/32px/cat-happy.png b/_ts_packages/packages/cortex-ui/public/sprites/32px/cat-happy.png new file mode 100644 index 0000000000000000000000000000000000000000..7197fd58fcd56cfd5dfcc41ac1f7255e723e0316 GIT binary patch literal 3193 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 literal 0 HcmV?d00001 diff --git a/_ts_packages/packages/cortex-ui/src/routes/PetEditor.svelte b/_ts_packages/packages/cortex-ui/src/routes/PetEditor.svelte index b903daa..8bd833e 100644 --- a/_ts_packages/packages/cortex-ui/src/routes/PetEditor.svelte +++ b/_ts_packages/packages/cortex-ui/src/routes/PetEditor.svelte @@ -14,6 +14,30 @@ let manifest = $state(null); let error = $state(null); let loading = $state(true); + let mood = $state<'idle' | 'happy' | 'think' | 'sleep'>('idle'); + + const AVAILABLE = { + cat: ['idle', 'happy', 'think', 'sleep'] as const, + dog: ['idle'] as const, + owl: ['idle'] as const, + blob: ['idle'] as const, + }; + + // Pick species from pet name first letter, defaulting to cat (most states available) + function species_for(pet_name: string): 'cat' | 'dog' | 'owl' | 'blob' { + const first = pet_name.trim().toLowerCase().charAt(0); + if (first === 'd') return 'dog'; + if (first === 'o') return 'owl'; + if (first === 'b') return 'blob'; + return 'cat'; + } + + function sprite_src(pet_name: string, m: typeof mood): string { + const sp = species_for(pet_name); + const states = AVAILABLE[sp] as readonly string[]; + const state = states.includes(m) ? m : 'idle'; + return `./sprites/32px/${sp}-${state}.png`; + } onMount(async () => { if (!user_id) { @@ -34,6 +58,28 @@

Pet: {user_id}

+{#if manifest} +
+ {manifest.identity.pet_name} ({mood}) +
{manifest.identity.pet_name}
+
+ {#each AVAILABLE[species_for(manifest.identity.pet_name)] as m} + + {/each} +
+
+{/if} + {#if loading}

Loading manifest…

{:else if error} diff --git a/_ts_packages/packages/cortex-ui/src/styles/app.css b/_ts_packages/packages/cortex-ui/src/styles/app.css index 3b2e19a..db004cc 100644 --- a/_ts_packages/packages/cortex-ui/src/styles/app.css +++ b/_ts_packages/packages/cortex-ui/src/styles/app.css @@ -184,3 +184,49 @@ pre { overflow-x: auto; font-size: 13px; } + +.pet-sprite-box { + display: flex; + flex-direction: column; + align-items: center; + gap: 10px; + margin: 16px 0 24px; + padding: 20px; + background: var(--card); + border: 1px solid var(--border); + border-radius: 8px; +} +.pet-sprite { + image-rendering: pixelated; + image-rendering: -moz-crisp-edges; + -ms-interpolation-mode: nearest-neighbor; + width: 128px; + height: 128px; + display: block; +} +.pet-sprite-name { + font-weight: 600; + letter-spacing: 0.02em; +} +.pet-sprite-moods { + display: flex; + gap: 6px; + flex-wrap: wrap; +} +.mood-btn { + padding: 4px 10px; + font-size: 12px; + background: transparent; + border: 1px solid var(--border); + color: var(--text); + border-radius: 4px; + cursor: pointer; +} +.mood-btn.active { + background: var(--accent); + border-color: var(--accent); + color: white; +} +.mood-btn:hover:not(.active) { + border-color: var(--accent); +}