Single bg-white/40 backdrop-blur-xl container as CSS grid.
Sidebars, top bar, bottom bar are grid cells sharing one rounded frame.
Center cell transparent for Live2D. Thin border-white/20 dividers.
Manual task input box in TaskList component.
Tasks persisted to Honcho as JSON preference on every mutation.
Tasks loaded from Honcho on identify (session reconnect).
5 tools: add_task, remove_task, complete_task, get_tasks, clear_completed_tasks
Backend stores tasks in-memory per session. Frontend TaskList component syncs via WS.
Kira can manage tasks via voice or text conversation.
Uses PIXI.BaseTexture.from(url) for proper pipeline.
Deletes old texture's _glTextures entry before swap.
Deletes new texture's _glTextures after swap to force re-upload.
Render loop (line 4960) detects missing GL entry and re-binds.
Bypasses PIXI texture pipeline entirely. Loads outfit PNG as Image,
creates raw WebGL texture, and calls cubismRenderer.bindTexture() directly.
Also updated lo-fi video IDs to confirmed working non-stream videos:
- 7ccH8u8fj8Y: Lofi Girl best of 2025
- HFQibg2OJkU: Chillhop Spring 2025
- udGvUx70Q3U: Lofi Chilled Beats 12hr
Old Lofi Girl streams were taken down. Updated to active streams:
- 7NOSDKb0HlU: lofi hip hop radio
- MCkTebktHVc: Chill lofi (College Music)
- KMXZF-K2mus: 24/7 beats
Epsilon model has 3 texture sheets: body (00), hair (01), clothes (02).
Outfit PNGs in /outfits/ replace texture_02 at runtime via PIXI BaseTexture swap.
Live2DStage now accepts outfit prop and swaps on change.
App passes currentOutfit to Live2DStage.
The YT Player API silently fails to autoplay in hidden iframes.
Replaced with a direct <iframe> embed with allow='autoplay; encrypted-media'.
- On 'Start Lo-Fi': creates iframe with autoplay=1
- Station change: remounts iframe with new videoId
- Volume: postMessage API to YT iframe (best effort)
- Much simpler, no external script dependency
Epsilon model registers expressions as 'Smile.exp3.json' not 'Smile'.
Added EXPR_MAP to map friendly names to full registered names.
Fixes expression buttons and idle cycling.
Cat position is now measured from the [data-petzone] DOM element's
getBoundingClientRect(), so it always aligns with the PetZone section
regardless of window size or sidebar content height.
Removed Live2DCat import from PetZone (cat renders on shared stage).
Cat was rendering huge because scale was computed from current model.width
which included previous scale transforms. Now resets to scale(1) first,
reads natural bounds, then computes target scale for 100px rendered height.
- Extract layout constants matching Tailwind config (PAD, LEFT_W, GAP, RIGHT_W)
- positionModels() helper computes exact pixel positions from layout
- Kira: centered in center panel at 78% of available space
- Mochi: 120px tall, centered in right sidebar, above status bar
- Both models reposition on window resize
Live2DStage creates ONE full-viewport transparent canvas (z-0, pointer-events:none).
Both Kira and Mochi cat models render on the same Pixi stage and WebGL context.
KiraAvatar is now UI-only (no canvas), receives model ref from stage.
PetZone is label-only. Eliminates all WebGL context conflict errors.
Cat gets its own canvas with WebGL1 context (Kira uses WebGL2 by default).
Different GL versions don't share buffers, so no bindBuffer spam.
Cat now renders in the PetZone section of the right sidebar where it belongs.
Removed all shared-context onAppReady plumbing.
Single WebGL context, no bindBuffer spam. Cat model loads onto
KiraAvatar's stage and positions itself at bottom-right corner.
PetZone passes app prop through to Live2DCat.
Reverts shared-context approach. Live2DCat gets its own canvas with
forceCanvas:true (Canvas2D renderer), which avoids the WebGL bindBuffer
spam entirely. Cleaned up onAppReady prop from KiraAvatar.
Eliminates WebGL bindBuffer/bindTexture spam from dual Application contexts.
Cat model now loads onto KiraAvatar's shared stage via onAppReady callback.
- Copied LittleCat model files to frontend/public/live2d/models/little-cat/
- Using the black alternate texture as default
- Created Live2DCat component that renders the model in a small canvas
- PetZone now shows a single Live2D cat instead of two SVG cats
React was potentially clearing the canvas on re-render because we
appended it manually to a div. Now using a <canvas ref={canvasRef}>
element directly in JSX that React manages. Pixi app uses .
Scale set to 82% of container.
Previous approach set CSS width:100% on a low-res canvas, causing the browser
to stretch/pixelate the model. Now using Pixi's built-in resizeTo so the
canvas internal resolution always matches the container. Model scaled to 90%
of container with centered anchor.
Pixi renderer.resize() overwrites canvas inline width/height styles,
locking the canvas to the initial size and leaving empty space below.
Now we re-apply width:100%;height:100% after every resize so the canvas
always fills its container. Removed unused appRef.
Problem: flex layout wasn't ready on first paint, so clientWidth fell back
to 400px. Canvas was 400px wide but parent was only 288px, causing the
avatar to be clipped on the right.
Fix: ResizeObserver measures real laid-out size before init. Canvas forced
to width/height 100% via CSS so it never overflows. Model scaled to 68%
with centered anchor. Resize handled dynamically.
Replaced the hero + scrollable grid with a fixed-height three-column
workspace:
- Left (fixed 288px): Kira avatar + compact chat + text input
- Center (flex): Large focus timer + notes
- Right (fixed 256px): Music, white noise, wardrobe, pets
Thin top bar: scene selector dots + clock
Thin bottom bar: status + connection indicator
No cards, no scrollable grid, no wasted space. Clean, modern,
everything visible at once. Avatar fills full sidebar height.
All 15+ glass-card instances removed across every component (Timer, Music,
Notes, WhiteNoise, PetZone, Clock, ChatBubble, Wardrobe, Toolbar, KiraAvatar,
BackgroundScene, WelcomeScreen, App text input + bottom bar).
New design: widgets sit directly on the gradient background with only padding,
no frosted-glass backgrounds, borders, or shadows. Cleaner, more modern look.
- Avatar now centered in its own row above the tools grid (was crammed in column 1)
- KiraAvatar container: min-height 33vh, canvas up to 500px wide
- Tools reorganized into 4 columns below: Chat, Timer+Music, Notes+Noise, Clock+Pets+Wardrobe
- WelcomeScreen restored to full (not compact) for first-time users