feat(ui): center avatar as hero, ~1/3 viewport height; tools grid below
- 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
This commit is contained in:
+23
-18
@@ -80,7 +80,7 @@ export default function App() {
|
||||
if (!identified && !loadingPrefs) {
|
||||
const savedId = localStorage.getItem('kira-user-id');
|
||||
if (!savedId) {
|
||||
return <WelcomeScreen onComplete={handleWelcome} isCompact />;
|
||||
return <WelcomeScreen onComplete={handleWelcome} />;
|
||||
}
|
||||
// Has saved ID but not identified yet — show welcome with their name
|
||||
return (
|
||||
@@ -121,13 +121,9 @@ export default function App() {
|
||||
<Toolbar currentScene={currentSceneId} onSceneChange={handleSceneChange} />
|
||||
</div>
|
||||
|
||||
{/* Main grid */}
|
||||
<div className="flex-1 overflow-y-auto px-4 py-4 scrollbar-thin">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4 max-w-7xl mx-auto">
|
||||
|
||||
{/* Column 1: Kira + Clock */}
|
||||
<div className="space-y-4">
|
||||
<Clock />
|
||||
{/* Hero: Avatar centered, ~1/3 of viewport */}
|
||||
<div className="flex-none flex justify-center py-4 px-4">
|
||||
<div className="w-full max-w-md">
|
||||
<KiraAvatar
|
||||
isSpeaking={isKiraSpeaking}
|
||||
isListening={isRecording}
|
||||
@@ -136,22 +132,18 @@ export default function App() {
|
||||
onTalkToggle={handleTalkToggle}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Column 2: Timer + Music + Notes + WhiteNoise */}
|
||||
<div className="space-y-4">
|
||||
<Timer />
|
||||
<MusicPlayer />
|
||||
<Notes />
|
||||
<WhiteNoise />
|
||||
</div>
|
||||
|
||||
{/* Column 3: Chat + Text Input */}
|
||||
{/* Tools grid below the avatar */}
|
||||
<div className="flex-1 overflow-y-auto px-4 pb-4 scrollbar-thin">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4 max-w-7xl mx-auto">
|
||||
|
||||
{/* Column 1: Chat + Text Input */}
|
||||
<div className="space-y-4">
|
||||
<ChatBubble messages={messages} isKiraSpeaking={isKiraSpeaking} userName={userName} livePartial={livePartial} />
|
||||
|
||||
{/* Text input fallback */}
|
||||
<div className="glass-card p-3">
|
||||
{/* Subtle greeting */}
|
||||
<div className="text-[10px] text-kira-plum/30 mb-2">
|
||||
hey {userName} ✨
|
||||
</div>
|
||||
@@ -174,8 +166,21 @@ export default function App() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Column 4: Cats + Wardrobe */}
|
||||
{/* Column 2: Timer + Music */}
|
||||
<div className="space-y-4">
|
||||
<Timer />
|
||||
<MusicPlayer />
|
||||
</div>
|
||||
|
||||
{/* Column 3: Notes + White Noise */}
|
||||
<div className="space-y-4">
|
||||
<Notes />
|
||||
<WhiteNoise />
|
||||
</div>
|
||||
|
||||
{/* Column 4: Cats + Wardrobe + Clock */}
|
||||
<div className="space-y-4">
|
||||
<Clock />
|
||||
<PetZone />
|
||||
<Wardrobe onOutfitChange={handleOutfitChange} onAccessoryChange={handleAccessoryChange} />
|
||||
</div>
|
||||
|
||||
@@ -55,8 +55,9 @@ export default function KiraAvatar(props: Props) {
|
||||
// Cast needed due to pixi-live2d-display expecting older Ticker type
|
||||
(Live2DModel as any).registerTicker(Ticker as any);
|
||||
|
||||
// Responsive sizing
|
||||
const size = Math.min(container.clientWidth || 260, 260);
|
||||
// Responsive sizing — fill the container, target ~1/3 viewport
|
||||
const containerW = container.clientWidth || 400;
|
||||
const size = Math.min(containerW, 500);
|
||||
const app = new Application({
|
||||
width: size,
|
||||
height: size * 1.25,
|
||||
@@ -198,12 +199,12 @@ export default function KiraAvatar(props: Props) {
|
||||
}, [props.accessory, live2dReady]);
|
||||
|
||||
return (
|
||||
<div className="glass-card p-4 flex flex-col items-center" style={{ minHeight: 360 }}>
|
||||
<div className="glass-card p-6 flex flex-col items-center w-full" style={{ minHeight: '33vh' }}>
|
||||
{/* Live2D canvas */}
|
||||
<div
|
||||
ref={canvasRef}
|
||||
className={`relative w-full ${live2dReady ? 'block' : 'hidden'}`}
|
||||
style={{ maxWidth: 260, height: 325 }}
|
||||
style={{ maxWidth: 500, height: '30vh', minHeight: 250 }}
|
||||
/>
|
||||
|
||||
{/* SVG fallback */}
|
||||
|
||||
Reference in New Issue
Block a user