Implements physics-based rotation that responds to where the user grabs
the card. When you grab a card off-center and drag it, it rotates
naturally based on the grab point and drag direction.
Features:
- Calculate grab offset from card center on pointer down
- Apply rotation using cross product of grab offset and drag direction
- Rotation clamped to ±45° to prevent excessive spinning
- Final rotation preserved when card is released
- Console logging for grab point coordinates and rotation changes
Physics details:
- Cross product (grabOffset.x * deltaY - grabOffset.y * deltaX) determines
rotation direction and magnitude
- Grabbing left side + dragging right = clockwise rotation
- Grabbing right side + dragging left = counter-clockwise rotation
- Scale factor of 5000 provides smooth, realistic rotation feel
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed logging issue where speed logs weren't showing during drag:
- Added separate lastLogTimeRef for logging throttle
- Logs now appear every ~200ms during drag (was never logging before)
- Velocity calculation unchanged, only logging throttle fixed
Now you can see speed values in console during drag to verify
shadow responsiveness.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
First physics enhancement - shadow changes based on how fast you drag:
- Tracks drag velocity (distance/time) during pointer move
- Shadow grows larger and darker with faster dragging
- Base: 8px offset, 24px blur, 0.3 opacity
- Fast: 32px offset, 64px blur, 0.6 opacity
- Smooth decay when released
Console logging included:
- [Shadow] logs on drag start/release
- Speed/distance/time logged during drag (throttled to ~100ms)
Test: Drag cards slowly vs fast and watch shadow change
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Replaced complex react-spring + useDrag implementation with simple
PointerEvents-based drag and drop:
- Uses native onPointerDown/Move/Up events
- Tracks position with useState (no animation library)
- Cards stay exactly where dropped (no physics or snap-back)
- Simple scale-up effect while dragging
- Much more predictable and maintainable
Removed dependencies on:
- @react-spring/web
- @use-gesture/react
- Complex velocity tracking and decay physics
- Transform-origin calculations
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Removed conflicting top-level config that was interfering with decay
animations. Now using explicit config objects for each property:
- x, y: decay physics with velocity
- scale, rotation: wobbly spring animations
This should fix the issue where cards were snapping back to pickup
position instead of staying where dropped.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed the issue where cards were snapping back to pickup position:
- Use api.set() to immediately snap spring position to dropped location
- Then apply decay animation with momentum from that position
- Removed problematic 'from' property which doesn't work with decay
The bug was that react-spring's 'from' property is ignored when using
decay: true, causing the spring to animate from its current value rather
than the specified position. Using api.set() first ensures the spring
starts from the correct dropped position.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Made interactive flashcards a fun easter egg by:
- Changed overflow from 'hidden' to 'visible' to allow cards to be
thrown anywhere on the page, not just within container bounds
- Fixed position persistence: cards now stay exactly where dropped
instead of snapping back to pickup location
- Updated currentPositionRef immediately on drop before applying
momentum physics
Cards can now be dragged and tossed freely around the entire page
and will maintain their position after being dropped.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Increased mobile scale from 2.5 to 3.5 to better utilize available screen
space on mobile devices. Screenshot review showed ample room above and
below the abacus without risk of overlapping title or scroll hint.
Final scales:
- Mobile (base): scale(3.5) - 75% larger than original
- Medium (md): scale(3.5) - 16% larger than original
- Desktop (lg): scale(4.25) - 6% larger than original
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Reduced mobile scale from 2.8 to 2.5 to ensure the "Scroll to explore"
hint at the bottom is not covered by the abacus.
Final scales:
- Mobile (base): scale(2.5) - 25% larger than original, no overlap
- Medium (md): scale(3.5) - 16% larger than original
- Desktop (lg): scale(4.25) - 6% larger than original
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fine-tuned scale values based on visual feedback:
- Mobile (base): scale(2.8) - increased for better mobile visibility (40% larger than original 2)
- Medium screens (md): scale(3.5) - unchanged (16% larger than original 3)
- Desktop (lg): scale(4.25) - reduced 15% for safety (6% larger than original 4)
This balances maximum visual impact on mobile while preventing any
layout issues on larger screens.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Increase scale values across all breakpoints, especially on mobile:
- Mobile (base): scale(2) → scale(3) (50% increase)
- Medium screens (md): scale(3) → scale(4.5) (50% increase)
- Large screens (lg): scale(4) → scale(6) (50% increase)
The abacus now fills more of the available hero space without
clipping, improving visual impact and usability on all devices.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Two small refinements to navbar branding:
- Added whiteSpace: 'nowrap' to subtitle to prevent text wrapping
- Removed abacus emoji from "Abaci One" branding for cleaner look
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed logic - the glassmorphism effect (backdrop blur, subtle backgrounds,
borders, shadows) now applies when the navbar is transparent at the top of
the homepage (isTransparent=true), not when scrolled down.
When scrolled or on other pages, the links are simpler without the extra
glassmorphism styling.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Enhanced nav links (Create, Guide, Games) with floating glass pill effect
when navbar is in scrolled mode:
- Added backdrop-filter blur(8px) to blur content underneath each link
- Subtle semi-transparent backgrounds (white for inactive, purple for active)
- Added borders with purple/white tints for enhanced definition
- Soft box shadows that glow purple on hover
- Enhanced hover states with stronger purple effects
The links now have better contrast against the dark navbar while maintaining
the ethereal floating illusion. Effects are only applied when scrolled (not
when navbar is transparent on homepage hero).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Removed the 10px gradient fade at the bottom of the navbar per user request.
Kept the border fix that removes the black line artifact when transparent.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed two visual issues with the navbar:
1. Removed black border line when transparent: Changed borderBottom to
conditionally be 'none' instead of '1px solid transparent', which was
showing up as a visible line when the navbar is transparent on homepage
2. Added 10px gradient fade at bottom: Applied linear-gradient that fades
from the dark background to transparent over the last 10px, creating a
softer transition instead of a sharp cut-off
The navbar now seamlessly blends into the page content with no visual artifacts.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Updated AppNavBar styling to blend with homepage's dark glassmorphism theme:
- Changed navbar background from white to semi-transparent dark (rgba(0,0,0,0.5))
- Added backdrop-filter blur(12px) for glassmorphism effect
- Updated border color to purple accent (rgba(139,92,246,0.2))
- Changed logo/branding text to white/light purple tones
- Updated nav link colors from gray to light gray/purple palette
- Enhanced hover states with purple highlights (rgba(196,181,253))
The navbar now seamlessly integrates with the homepage's dark theme while
maintaining transparency when the hero section is visible.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Prevents the level slider from causing horizontal overflow on mobile
devices, which was making the page width wider than intended.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Changed layout breakpoints from md (768px) to xl (1280px) to ensure:
- Skills section doesn't get clipped at medium viewport sizes
- Layout only switches to side-by-side when there's sufficient space
- Container min-width is responsive (100% below xl, 1400px at xl+)
This prevents the issue where content was overflowing at intermediate
viewport widths.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Moved "Learn by Doing" section outside the maxW:7xl container to allow
the demo div to be 1400px wide and properly centered with mx:auto.
Remaining content stays within the 7xl constrained container.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added minW: '1400px' and removed maxW: '1200px' constraint to ensure
the "What You'll Learn" section is properly sized and centered.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Increased container from 650px to 800px to ensure skill card titles
like "Friends techniques" don't wrap awkwardly across multiple lines.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed text being cut off on the right side of skill cards by:
- Adding minWidth: '0' to text container to enable proper flex shrinking
- Adding flexWrap: 'wrap' to title/badge row for better wrapping behavior
This fixes the flexbox issue where text was overflowing the card boundaries.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Changed width breakpoint from md to lg to match when the grid switches
to 2 columns. This prevents overflow on medium-width screens where the
container was 650px wide but still showing 1-column layout.
Now:
- Below lg: 100% width, 1 column
- At lg+: 650px width, 2 columns
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Increased the "What You'll Learn" container width from 420px to 650px
to give the 2-column grid of skill cards proper breathing room and
prevent cramped layouts.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed skill card abacus sizing by:
- Changing MiniAbacus to use width/height 100% instead of fixed 75px/80px
- Increased scale from 0.6 to 0.75 for better visibility
- Now properly fills the 120px/150px container set on the wrapper
This fixes the clipping issue by making the component hierarchy work correctly:
outer container (120px/150px) -> MiniAbacus (100%) -> scaled AbacusReact
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Increase abacus container width from 95px/110px to 120px (mobile) and
150px (desktop) to properly accommodate 3-column abacus visualizations
without clipping.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Remove overflow:hidden and increase the abacus container width from
75px to responsive widths (95px mobile, 110px desktop) to properly
accommodate the abacus visualizations without clipping.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>