From bed97e62ad236a1d8658f44a7eeffdc407ce5097 Mon Sep 17 00:00:00 2001 From: Thomas Hallock Date: Sun, 14 Sep 2025 15:57:31 -0500 Subject: [PATCH] feat: convert SorobanQuiz memory game styling to Panda CSS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replace all CSS classes with Panda CSS css() function calls - Convert originalGameStyles string to minimal globalAnimations for required keyframes - Systematically update all components: SetupPhase, DisplayPhase, CardGrid, InputPhase, ResultsPhase - Maintain all visual styling and responsive behavior while using project's design system - Preserve advanced features: 3D card flips, explosion animations, smart input styling - Keep only essential CSS animations (pulse, fadeInScale, explode) as global styles - Ensure consistent color scheme and spacing using Panda CSS tokens 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- apps/web/src/app/games/memory-quiz/page.tsx | 1170 ++++++++----------- 1 file changed, 514 insertions(+), 656 deletions(-) diff --git a/apps/web/src/app/games/memory-quiz/page.tsx b/apps/web/src/app/games/memory-quiz/page.tsx index 33a8ad9b..6486ded9 100644 --- a/apps/web/src/app/games/memory-quiz/page.tsx +++ b/apps/web/src/app/games/memory-quiz/page.tsx @@ -217,37 +217,84 @@ function SetupPhase({ state, dispatch }: { state: SorobanQuizState; dispatch: Re } return ( -
-

🧠 Speed Memory Quiz

-

Test your soroban reading skills! Cards will be shown briefly, then you'll enter the numbers you remember.

+
+

🧠 Speed Memory Quiz

+

Test your soroban reading skills! Cards will be shown briefly, then you'll enter the numbers you remember.

-
-
- -
+
+
+ +
{Object.entries(DIFFICULTY_LEVELS).map(([key, level]) => ( ))}
-
- -
+
+ +
{[2, 5, 8, 12, 15].map(count => (
-
- -
+
+ +
handleTimeChange(parseFloat(e.target.value))} + className={css({ + flex: 1, + maxWidth: '300px' + })} /> - {state.displayTime.toFixed(1)}s + {state.displayTime.toFixed(1)}s
-
@@ -336,21 +411,60 @@ function DisplayPhase({ state, dispatch }: { state: SorobanQuizState; dispatch: }, [state.currentCardIndex, state.displayTime, state.quizCards.length, dispatch]) return ( -
-
-
-
+
+
+
+
- + Card {state.currentCardIndex + 1} of {state.quizCards.length}
{countdown && ( -
+
{countdown}
)} {showCard && currentCard && ( -
+
{currentCard.svgComponent}
)} @@ -377,25 +513,90 @@ function CardGrid({ state }: { state: SorobanQuizState }) { if (state.quizCards.length === 0) return null return ( -
-

Cards shown to you:

-
+
+

Cards shown to you:

+
{state.quizCards.map((card, index) => { const isRevealed = state.foundNumbers.includes(card.number) return (
-
+
{/* Card back (hidden state) */} -
-
?
+
+
?
{/* Card front (revealed state) - using ServerSorobanSVG */} -
-
+
+
-

Enter the Numbers You Remember

-
-
- Cards shown: - {state.quizCards.length} +
+

Enter the Numbers You Remember

+
+
+ Cards shown: + {state.quizCards.length}
-
- Guesses left: - {state.guessesRemaining} +
+ Guesses left: + {state.guessesRemaining}
-
- Found: - {state.foundNumbers.length} +
+ Found: + {state.foundNumbers.length}
-
-
+
+
{state.guessesRemaining === 0 ? 'Out of guesses!' : 'Just start typing numbers on your keyboard:' }
- + {state.guessesRemaining === 0 ? 'No more guesses' : state.currentInput || ( @@ -557,9 +850,30 @@ function InputPhase({ state, dispatch }: { state: SorobanQuizState; dispatch: Re
-
+
{state.foundNumbers.map((number, index) => ( - + {number} ))} @@ -569,25 +883,73 @@ function InputPhase({ state, dispatch }: { state: SorobanQuizState; dispatch: Re {/* Wrong guess explosion animations */} -
+
{state.wrongGuessAnimations.map((animation) => ( -
+
{animation.number}
))}
{showFinishButtons && ( -
+
{hasFoundSome && !hasFoundAll && !outOfGuesses && (