feat: make home page abacus interactive with audio

Enhanced the hero abacus to be a fully interactive showcase:
- Increased size from default to 2.2x scale factor
- Enabled interactive mode (click beads to change value)
- Enabled smooth animations for bead movements
- Enabled audio feedback with volume at 0.4
- Added live value display below abacus in large golden text
- Added instructional text "Click the beads to interact!"
- Shows place value numbers on each column

The abacus now serves as a "try it now" demo right on the landing page.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Thomas Hallock
2025-10-18 17:44:33 -05:00
parent d2d8f7740f
commit 9a53d7e5db
2 changed files with 47 additions and 14 deletions

View File

@@ -1,5 +1,6 @@
'use client'
import { useState } from 'react'
import Link from 'next/link'
import { PageWithNav } from '@/components/PageWithNav'
import { AbacusReact } from '@soroban/abacus-react'
@@ -7,6 +8,7 @@ import { css } from '../../styled-system/css'
import { container, grid, hstack, stack } from '../../styled-system/patterns'
export default function HomePage() {
const [abacusValue, setAbacusValue] = useState(1234567)
return (
<PageWithNav navTitle="Soroban Mastery Platform" navEmoji="🧮">
<div className={css({ bg: 'gray.900', minHeight: '100vh' })}>
@@ -51,7 +53,9 @@ export default function HomePage() {
<div
className={css({
display: 'flex',
justifyContent: 'center',
flexDirection: 'column',
alignItems: 'center',
gap: '4',
my: '10',
p: '8',
bg: 'rgba(0, 0, 0, 0.4)',
@@ -61,13 +65,43 @@ export default function HomePage() {
boxShadow: '0 25px 50px -12px rgba(139, 92, 246, 0.25)',
})}
>
<div
className={css({
fontSize: 'lg',
fontWeight: 'semibold',
color: 'gray.300',
mb: '2',
})}
>
Click the beads to interact!
</div>
<AbacusReact
value={1234567}
value={abacusValue}
columns={7}
beadShape="diamond"
colorScheme="place-value"
hideInactiveBeads={false}
interactive={true}
animated={true}
soundEnabled={true}
soundVolume={0.4}
scaleFactor={2.2}
showNumbers={true}
callbacks={{
onValueChange: (newValue: number) => setAbacusValue(newValue),
}}
/>
<div
className={css({
fontSize: '4xl',
fontWeight: 'bold',
color: 'yellow.400',
fontFamily: 'mono',
letterSpacing: 'wide',
})}
>
{abacusValue.toLocaleString()}
</div>
</div>
<p

View File

@@ -314,17 +314,16 @@ export function PlayingPhase() {
<div
dangerouslySetInnerHTML={{ __html: card.svgContent }}
className={css({
width: '100%',
height: '100%',
width: '74px',
height: '74px',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
overflow: 'hidden',
'& svg': {
maxWidth: '100%',
maxHeight: '100%',
height: 'auto',
width: '100%',
height: '100%',
display: 'block',
margin: '0 auto',
},
})}
/>
@@ -459,17 +458,17 @@ export function PlayingPhase() {
__html: card.svgContent,
}}
className={css({
width: '100%',
flex: 1,
width: '70px',
height: '70px',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
overflow: 'hidden',
margin: '0 auto',
'& svg': {
maxWidth: '70px',
maxHeight: '100%',
height: 'auto',
width: '100%',
height: '100%',
display: 'block',
margin: '0 auto',
},
})}
/>