- Add documentation to usePatternRotationUpload about using same helpers as store
- Add documentation to App.tsx pattern resume logic
- Mark PatternLayer to continue using local memoization (receives props)
- All tests passing
Co-authored-by: jhbruhn <1036566+jhbruhn@users.noreply.github.com>
**Problem:**
Store initialization was happening at module load via side effect:
```typescript
useMachineStore.getState()._setupSubscriptions();
```
This caused several issues:
- Executed before app was ready
- Made testing difficult (runs before test setup)
- Hard to control initialization timing
- Could cause issues in different environments
**Solution:**
- Added public `initialize()` method to useMachineStore
- Call initialization from App component's useEffect (proper lifecycle)
- Removed module-level side effect
**Benefits:**
- ✅ Controlled initialization timing
- ✅ Better testability (no side effects on import)
- ✅ Follows React lifecycle patterns
- ✅ No behavioral changes for end users
**Testing:**
- Build tested successfully
- Linter passed
- All TypeScript types validated
Fixes#38🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Split the 570-line useMachineStore into three focused stores for better
separation of concerns and improved re-render optimization:
**New Stores:**
- useMachineUploadStore (128 lines): Pattern upload state and logic
- useMachineCacheStore (194 lines): Pattern caching and resume functionality
- useMachineStore (reduced to ~245 lines): Connection, status, and polling
**Benefits:**
- Components only subscribe to relevant state (reduces unnecessary re-renders)
- Clear separation of concerns (upload, cache, connection)
- Easier to test and maintain individual stores
- 30% reduction in main store size
**Technical Details:**
- Uses dynamic imports to avoid circular dependencies
- Maintains all existing functionality
- Updated FileUpload, PatternCanvas, and App components
- All TypeScript compilation errors resolved
- Build tested successfully
Implements conservative 2-store extraction approach from issue #31.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Store both original unrotated pesData and uploaded rotated pesData in cache
to ensure exact consistency on resume and prevent issues from algorithm changes
between versions. This fixes rotation/position reset issues after page reload.
- Cache original unrotated pattern + rotation angle for editing
- Cache exact uploaded pattern data sent to machine
- Restore original offset after loading cached pattern
- Use cached uploaded data on resume instead of recalculating
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Fixed CSS variable format by wrapping HSL values in hsl() function
- Removed double hsl() wrapping in @theme section (now uses var() directly)
- Switched dark mode card background to OKLCH for better perceptual uniformity
- Improved dark mode border visibility (17.5% → 37.5% lightness)
- Improved dark mode input visibility (17.5% → 47.5% lightness)
- Changed app background from gray-300 to gray-100 for cleaner appearance
- Enhanced PatternCanvasPlaceholder to match PatternCanvas styling with icon and description
These changes ensure shadcn components use colors correctly and improve overall dark mode readability.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Migrated PatternCanvas component to use shadcn Card components (Card, CardHeader, CardTitle, CardDescription, CardContent)
- Replaced custom zoom control buttons with shadcn Button component using outline variant and icon size
- Renamed PatternPreviewPlaceholder to PatternCanvasPlaceholder for consistency
- Updated all imports and references in App.tsx
- Maintained all existing functionality including Konva canvas rendering, zoom controls, and pattern positioning
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Define semantic color theme in App.css using @theme directive
- Primary (blue), Success (green), Warning (amber), Danger (red)
- Info (cyan), Accent (purple), Secondary (orange), Tertiary (teal)
- Semantic colors reference Tailwind color variables via var()
- Media query-based dark mode for canvas colors
- Migrate all 16 components from direct Tailwind colors to semantic names
- Create cssVariables.ts utility for Konva canvas color access
- Update KonvaComponents to use CSS variables dynamically
- Replace @apply with CSS variables in index.css for v4 compatibility
- Remove unused designTokens.ts file
- Improve light mode contrast with gray-300 app background
- Adjust canvas and info box backgrounds to gray-200
Benefits:
- Easy theme customization by updating App.css @theme block
- Consistent semantic naming across all components
- Proper dark mode support via media queries
- No visual regressions, all colors maintained
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Extracted App.tsx (469 lines → 91 lines) into 5 new components:
- ErrorPopover: Displays error details with solutions (84 lines)
- AppHeader: Machine status, workflow stepper, errors (207 lines)
- ConnectionPrompt: Connect button or browser warning (67 lines)
- LeftSidebar: Conditional rendering of controls (42 lines)
- PatternPreviewPlaceholder: Empty state for preview (46 lines)
This improves code organization, maintainability, and reusability.
Each component now has a single, clear responsibility.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Detects if the browser supports Web Bluetooth API and displays an
informative warning when unsupported. Provides users with clear
options: use a compatible browser or download the desktop app.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Read version from package.json at build time using Vite define
- Create global __APP_VERSION__ constant injected by Vite
- Update document title in App component to include version (e.g., "Respira v0.0.0")
- Works reliably in both web and Electron builds
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Move Pyodide/PyStitch pattern conversion to a dedicated Web Worker for
non-blocking UI performance. Pyodide now loads in the background on app
startup with real-time progress indicator showing download and initialization
status.
Key changes:
- Create patternConverter.worker.ts with full PES to PEN conversion logic
- Add patternConverterClient.ts singleton for worker management
- Implement progress tracking (0-100%) with step descriptions
- Add inline progress bar in FileUpload component with contextual messaging
- Configure COEP headers for Electron to support Web Workers
- Pass dynamic asset URLs to worker for file:// protocol support
- Update UIStore with progress state management
- Simplify pystitchConverter.ts to delegate to worker client
Benefits:
- Truly non-blocking UI (heavy Python/WASM runs off main thread)
- Real progress feedback during 15MB Pyodide download
- Works in both browser and Electron (dev and production)
- Faster app startup perception with background loading
- Better UX with "waiting" state if user clicks before ready
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Complete the component refactoring by updating WorkflowStepper to
consume stores directly instead of receiving props.
Changes:
- Updated WorkflowStepper to use useMachineStore and usePatternStore
- Removed 7 props that were being passed from App.tsx
- Added hasError import to WorkflowStepper
- Removed unused hasError import from App.tsx
Now all major components use Zustand stores directly:
- FileUpload: 0 props (was 14)
- ProgressMonitor: 0 props (was 9)
- PatternCanvas: 0 props (was 7)
- PatternSummaryCard: 0 props (was 5)
- WorkflowStepper: 0 props (was 7)
Total props eliminated: 42
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Refactor all child components to consume stores directly instead of
receiving props from App.tsx. This eliminates prop drilling and
simplifies the component tree.
Components updated:
- FileUpload: Now uses useMachineStore, usePatternStore, and useUIStore
directly instead of receiving 14 props
- ProgressMonitor: Now uses useMachineStore and usePatternStore instead
of receiving 9 props
- PatternCanvas: Now uses useMachineStore and usePatternStore instead of
receiving 7 props
- PatternSummaryCard: Now uses useMachineStore and usePatternStore
instead of receiving 5 props
Changes to App.tsx:
- Removed all component props that are now accessed via stores
- Removed unused callbacks: handlePatternLoaded, handlePatternOffsetChange,
handleUpload, handleDeletePattern
- Removed unused imports: PesPatternData, canDeletePattern, useCallback
- Simplified component tree with zero-prop component calls
Benefits:
- Eliminated prop drilling across 37 props total
- Components can access exactly what they need from stores
- Cleaner, more maintainable component interfaces
- Better separation of concerns
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add zustand dependency for modern state management
- Create three separate stores for better code organization:
- useMachineStore: Machine connection, status, and operations
- usePatternStore: Pattern data, offset, and upload state
- useUIStore: Pyodide and UI-specific state
- Migrate App.tsx from useBrotherMachine hook to Zustand stores
- Use useShallow for optimized multi-value selections
- Implement dynamic polling intervals based on machine state
- Add ESLint ignore for .vite build directory
Benefits:
- Better separation of concerns with logical store divisions
- Improved performance through selector-based subscriptions
- Cleaner code replacing 445-line hook with maintainable stores
- Full TypeScript support with proper typing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Provides more breathing room for controls and progress monitor
in the left column on wide screens.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Replace content-pushing error banners with header status indicator
- Add categorized error labels (Python Error, Connection Error, etc.)
- Show detailed error info with solutions in 600px popover on click
- Fix layout shift by always rendering error button (invisible when no error)
- Clear machineError state on disconnect
- Fix TypeScript error in WorkflowStepper ref callback
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Convert NextStepGuide to collapsible floating overlay in bottom-right
- Implement fixed viewport layout (no page scrolling on desktop)
- Make color blocks scrollable with dynamic gradient indicator
- Add responsive behavior: scrollable on mobile, fixed on desktop
- Increase overlay opacity for better readability
- Enable full-height columns that expand to fill available space
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Implemented comprehensive responsive design improvements for tablet support
and simplified typography from 12 different font sizes to a clean 5-level
hierarchy using only standard Tailwind classes.
Responsive improvements:
- Canvas height now adapts: 400px (mobile) → 500px (tablet) → 600px (desktop)
- Header stacks vertically on tablets, side-by-side on desktop (1024px+)
- WorkflowStepper scales appropriately for smaller screens
- Canvas overlays are more compact on mobile/tablet
- All components use responsive spacing and padding
Typography system redesign:
- Reduced from 12 sizes to 5 levels (Display, Heading, Subheading, Body, Label)
- Removed arbitrary pixel values (text-[7px], text-[9px], text-[10px], etc.)
- All text now uses standard Tailwind classes (text-xs, text-sm, text-base, text-lg, text-xl)
- Minimum text size is now 12px (text-xs) for better accessibility
- Buttons upgraded to text-sm (14px) for improved touch targets
- Consistent responsive scaling for top-level headers only
Added docs/TYPOGRAPHY_SYSTEM.md with usage guidelines and component mapping.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Validate pattern (with offset) fits within hoop bounds before upload
- Calculate precise overflow in each direction (left, right, top, bottom)
- Display detailed error message showing exact measurements
- Disable upload button when pattern exceeds hoop bounds
- Position error messages below buttons with smooth slide animation
- Set button sizing: file select (2/3), upload (1/3) for consistent layout
- Pass machineInfo to FileUpload component for hoop dimensions
Prevents uploading patterns that would exceed machine working area and
provides clear feedback on how to adjust pattern position.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Major changes:
- Add Electron main process and preload scripts with Web Bluetooth support
- Implement platform abstraction layer for storage and file services
- Create BluetoothDevicePicker component for device selection UI
- Migrate from electron-builder to Electron Forge for packaging
- Configure Vite for dual browser/Electron builds
- Add native file dialogs and persistent storage via electron-store
- Hide menu bar for cleaner desktop app appearance
The app now works in both browser (npm run dev) and Electron (npm run start).
Package with 'npm run package' or create installers with 'npm run make'.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Detect when device is not paired at OS level and handle automatic disconnections. The app now properly updates UI state when the device is disconnected by the OS.
Changes:
- Add BluetoothPairingError custom error class in BrotherPP1Service
- Track isInitialConnection state to differentiate pairing issues from disconnects
- Detect pairing issues in sendCommand() only during initial connection
- Add onDisconnect() subscription method to BrotherPP1Service
- Listen for 'gattserverdisconnected' events and update state automatically
- Add isPairingError state to useBrotherMachine hook
- Display pairing errors with blue info styling instead of red error styling
- Include step-by-step pairing instructions: long-press Bluetooth button on machine, then pair in OS settings
- Automatically reset connection state when device disconnects
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
FileUpload:
- Added FolderOpenIcon to "Choose PES File" button
ProgressMonitor:
- Start Sewing button takes 2x space (flex-[2]) as primary action
- Trace Again button takes 1x space (flex-1) as secondary action
- Added PlayIcon to Start/Resume Sewing buttons
- Added ArrowPathIcon to Trace Again button
- Buttons fill full width with proper flex distribution
- Sizing consistent with rest of UI (text-xs, px-3 py-2)
Header:
- Disconnect button turns red on hover for clear destructive action
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Show detailed machine information when hovering over serial number:
- Serial number
- MAC address
- Total stitches sewn by machine
- Stitches since last service
Tooltip dynamically includes only available information.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Increased title size from text-sm to text-lg for better prominence
- Moved serial number to upper row next to title (prevents truncation)
- Improved font sizes: serial (text-sm), controls (text-xs), not connected (text-sm)
- Enlarged icons and padding for better touch targets and readability
- Increased vertical spacing between rows for better breathing room
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Redesigned header with grid layout (300px fixed + flexible columns)
- Moved machine connection status to header with connection indicator
- Added disconnect button and status badge to header
- Moved connect button to "Get Started" card in left column
- Workflow stepper now always visible in dedicated column
- Fixed layout shifts by using fixed-width column and flex-shrink-0
- Connection status truncates within fixed width to prevent pushing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Replace inconsistent card layouts with a cohesive, space-efficient design
pattern featuring color-coded borders, icon headers, and compact spacing.
This redesign significantly reduces vertical space usage while improving
visual hierarchy and scannability.
UI/UX improvements:
- Apply consistent card design with border-left accent colors
- Add icon + title + subtitle header pattern to all cards
- Reduce padding from p-6 to p-4 for more compact layout
- Use smaller, tighter font sizes (text-xs, text-sm)
- Implement color-coded borders for quick visual identification
Component-specific changes:
- MachineConnection: Green/gray border, WiFi icon, compact status display
- PatternSummaryCard: Blue border, Document icon (new component)
- FileUpload: Orange/gray border, Document icon, inline button layout
- ProgressMonitor: Purple border, Chart icon, single-column layout
- PatternCanvas: Teal/gray border, Photo icon, dimensions in header
Conditional rendering optimizations:
- Show FileUpload OR PatternSummaryCard based on upload state
- Move ProgressMonitor to left column with PatternSummary
- Relocate NextStepGuide below PatternCanvas for better space usage
- Remove duplicate delete button from ProgressMonitor
Space savings: ~40-50% reduction in vertical space usage across all cards
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Remove unused imports and variables across multiple files
- Fix TypeScript 'any' type annotations with proper types
- Fix React setState in effect warnings
- Create shared embroidery constants file (embroideryConstants.ts)
- Replace magic number 0x10 with named MOVE constant
- Map PyStitch constants to JS constants using registerJsModule
- Ensure PEN encoding constants remain separate and valid
All build and lint checks now pass successfully.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Improve the previous fix by actually preserving the original filename
from the cache instead of using a generic fallback. This is a cleaner
solution that maintains the actual pattern name.
Changes:
- Add currentFileName state to App.tsx to track pattern filename
- When loading cached pattern, preserve resumeFileName in currentFileName
- When loading new pattern, pass fileName to handlePatternLoaded callback
- Pass currentFileName to FileUpload component as prop
- Use currentFileName in displayFileName logic (prioritized first)
- Remove generic 'pattern.pes' fallback
Now when you delete a cached pattern and re-upload it, the original
filename (e.g., "mypattern.pes") is preserved instead of using a
generic fallback name. This maintains better traceability.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Fix UI delay issue where buttons remained clickable during BLE communication
setup. Now provides instant visual feedback when operations begin.
Changes:
- Add isUploading and isDeleting state tracking in useBrotherMachine hook
- Set loading states immediately on button click, before BLE communication
- Update FileUpload component to disable upload button and show spinner
- Update ProgressMonitor to disable delete button with loading indicator
- Add PatternCacheService.deletePattern() method for proper cache cleanup
- Pass loading state props through App.tsx to child components
The UI now responds immediately with disabled buttons and loading spinners,
preventing double-clicks and providing clear feedback during the initial
BLE setup period before progress reporting begins.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Dark Mode Implementation:
- Add Tailwind config with darkMode: 'media' for system preference detection
- Update all 9 components with 200+ dark mode variants
- Semantic color backgrounds with semi-transparent overlays in dark mode
- Proper text contrast (gray-900/gray-100) for readability
- Enhanced borders, shadows, and focus rings for dark backgrounds
Component Dark Mode Updates:
- App.tsx: Header gradient, error banners, empty states
- MachineConnection: Status badges with proper dark variants for all states
- FileUpload: Pattern info cards, thread swatches, upload progress
- PatternCanvas: Canvas background, overlays, zoom controls
- ProgressMonitor: Color blocks, progress bars, state indicators with colored icons
- NextStepGuide: All status boxes (blue/yellow/cyan/green/red)
- WorkflowStepper: Progress indicators and step states
- ConfirmDialog: Modal overlays and dialog backgrounds
- KonvaComponents: Grid lines and origin markers
Pattern Visibility Improvements:
- Pattern shows full opacity (1.0) when unlocked for easy positioning
- Pattern shows reduced opacity (0.75) for unstitched areas when locked/uploading
- Helps distinguish completed vs pending stitches during sewing
- Pattern locks during upload to prevent accidental repositioning
- Canvas dragging disabled when pattern is uploading or uploaded
Status Indicator Enhancements:
- Machine status badges: All states (idle/active/waiting/complete/error) have dark variants
- Progress monitor state icons: Colored icons (blue/yellow/green/red) in both modes
- Color blocks: Proper backgrounds and borders for completed/current/pending states
- All semantic colors maintain visibility and meaning in dark mode
Canvas Lock Behavior:
- Pattern locked during upload (uploadProgress > 0 && < 100)
- Pattern locked after upload (patternUploaded = true)
- Lock indicator shows amber background with lock icon
- Cursor changes prevent confusion about draggability
- Full opacity during positioning, transparency during progress tracking
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Loading State Improvements:
- Add SkeletonLoader component with pattern info, canvas, and connection skeletons
- Show loading spinner on file selection and during pattern upload
- Display upload progress with enhanced progress bar and percentage
- Add success confirmation message when upload completes
- Show thread color preview dots inline with pattern info (up to 5 colors)
Visual Polish & Animations:
- Add custom animations: fadeIn, slideInRight, pulseGlow, skeleton-loading
- Enhance all cards with subtle hover shadow effects
- Improve header with richer gradient (blue-600 → blue-700 → blue-800)
- Polish error messages with icons and improved layouts
- Enhance empty state with decorative patterns and feature highlights
- Add smooth transitions to all NextStepGuide states
- Current color block pulses with blue glow animation
- Color blocks have hover states for better interactivity
Pattern Upload & Lock Functionality:
- Hide upload button after pattern is uploaded (patternUploaded && uploadProgress === 100)
- Disable pattern dragging when uploaded with visual lock indicator
- Pattern position overlay shows amber background with lock icon when locked
- Pattern remains in canvas after deletion for re-editing and re-upload
- Delete pattern from cache when deleting from machine to prevent auto-resume
- Add LockClosedIcon to indicate locked pattern state
Pattern Management:
- Keep pattern data in UI after deletion for repositioning and re-uploading
- Clear machine-related state but preserve pattern visualization
- Reset upload progress and pattern uploaded state on deletion
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Major fixes:
- Fix PEN data encoding to properly mark color changes and end markers
- COLOR_END (0x03) for intermediate color blocks
- DATA_END (0x05) for the final stitch only
- Machine now correctly reads total stitch count across all color blocks
- Reset uploadProgress when pattern is deleted to re-enable upload button
- Allow pattern deletion during WAITING states
- Allow pattern upload in COMPLETE states
- Fix pattern state tracking to reset when patternInfo is null
UI improvements:
- Integrate workflow stepper into compact header
- Change app title to "SKiTCH Controller"
- Reduce header size from ~200px to ~70px
- Make Sewing Progress section more compact with two-column layout
- Replace emojis with Heroicons throughout
- Reorganize action buttons with better visual hierarchy
- Add cursor-pointer to all buttons for better UX
- Fix cached pattern not showing info in Pattern File box
- Remove duplicate status messages (keep only state visual indicator)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
React-Konva Migration:
- Create KonvaComponents.tsx with declarative components
- Convert Grid, Origin, Hoop, Stitches, PatternBounds, and CurrentPosition to React components
- Add React.memo and useMemo for performance optimization
- Remove imperative layer manipulation (destroyChildren, add, batchDraw)
- Remove backgroundLayerRef and patternLayerRef
- Let React handle component lifecycle and updates
- Improve performance through React's diffing algorithm
Pattern Offset Persistence:
- Add patternOffset field to CachedPattern interface
- Update PatternCacheService.savePattern to accept and store offset
- Modify useBrotherMachine to save offset when uploading pattern
- Update resumedPattern state to include offset information
- Restore cached pattern offset in App.tsx on resume
- Add initialPatternOffset prop to PatternCanvas component
- Pattern position now persists across page reloads and reconnections
Benefits:
- More maintainable and React-idiomatic code
- Better performance with large patterns
- Automatic cleanup and no memory leaks
- Pattern positioning workflow preserved across sessions
- Improved developer experience
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Install Tailwind CSS and configure Vite plugin
- Replace all custom CSS classes with Tailwind utility classes
- Migrate all components to use Tailwind styling:
- App.tsx: Responsive layout with modern styling
- MachineConnection: Status badges and action buttons
- FileUpload: File input and progress bars with shimmer effect
- ProgressMonitor: Color blocks, state indicators, and actions
- ConfirmDialog: Modal overlay with backdrop blur
- PatternCanvas: Canvas viewer with floating controls
- Add custom shimmer animation for progress bars
- Fix canvas resizing issue during zoom operations:
- Add ResizeObserver for stable container dimensions
- Use clientWidth/clientHeight instead of offset dimensions
- Cache container size to prevent layout thrashing
- Improve zoom button behavior to zoom towards viewport center
- Maintain consistent design with shadows, borders, and transitions
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Replace vanilla canvas with Konva.js for better interactivity
- Add pan and zoom functionality (mouse wheel zoom, drag to pan)
- Make pattern draggable within hoop coordinate system
- Center canvas on embroidery origin (0,0)
- Default zoom shows entire 100x100mm hoop
- Pass user-defined pattern offset to LAYOUT command
- Replace auto-centering with manual pattern positioning
- Add visual overlays for thread legend, dimensions, pattern position, and zoom controls
- Fix effect dependencies to prevent drag interruption on machine status updates
- Memoize callbacks to prevent unnecessary re-renders
- Create konvaRenderers.ts utility for rendering grid, hoop, stitches, etc.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>