## Problem
- Calculator displayed rounded-up price per ton (e.g., $238/ton)
- Stripe checkout used exact Wren API price (e.g., $237.20/ton)
- This caused confusion when checkout amount differed from calculator
Example with 20,000 liters (53.9 tons):
- Calculator showed: 53.9 × $238 = $12,819
- Stripe charged: 53.9 × $237.20 = $12,775.35
## Solution
Modified both OffsetOrder.tsx and MobileOffsetOrder.tsx to:
- Keep displaying rounded-up price (Math.ceil) to users
- Pass roundedPricePerTon to Stripe checkout session
- Ensures calculator and Stripe always match exactly
## Changes
- OffsetOrder.tsx (line 170): Pass roundedPricePerTon to createCheckoutSession
- MobileOffsetOrder.tsx (lines 207-218): Add rounding to price display and calculations
Now the price users see is exactly what they pay.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
## Changes Made:
### 1. Remove Carbon Impact Comparisons from Calculator Pages
- Removed from OffsetOrder.tsx (lines 532-542)
- Removed from MobileOffsetOrder.tsx (lines 429-432)
- Keep comparisons ONLY on CheckoutSuccess receipt page per user request
### 2. Comprehensive CheckoutSuccess Page Redesign
- Add Puffin logo prominently at top of receipt
- Implement status mapping: paid/fulfilled → "Confirmed", pending → "Processing"
- Add comprehensive print CSS (@media print rules)
- Hide interactive elements (buttons) when printing
- Optimize layout and spacing for printed receipt
- Professional receipt aesthetics with enhanced design:
* Beautiful gradient header with logo
* Highlighted carbon offset display with icon
* Enhanced pricing breakdown section
* Better typography and spacing throughout
* Professional metadata section with date
* Improved button styling with gradients and hover effects
* Email confirmation notice with icon
* Footer with contact information
### Benefits:
- Cleaner calculator UX (comparisons only on success)
- Professional printable receipt
- Clear "Confirmed" status (not "PENDING")
- Beautiful modern design that matches brand
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Features:
- Add useCalculatorState hook with localStorage persistence and 1-hour expiry
- State persists through page reloads and Stripe checkout redirects
- Automatically clears state on successful payment (paid/fulfilled status)
Navigation fixes:
- Fix white page issues on checkout success/cancel pages
- Replace <a> links with button handlers for proper state-based routing
- Pass navigation handlers from App.tsx to checkout pages
State persistence integration:
- TripCalculator: Save/restore calculator inputs (fuel, distance, custom)
- MobileCalculator: Full state persistence for mobile app route
- OffsetOrder: Persist offset percentage and portfolio selection
- MobileOffsetOrder: Persist offset percentage for mobile flow
Carbon impact comparisons:
- Add varied carbon impact comparisons with random selection
- Display 3 comparisons in preview mode, 5 in success mode
- Categories: cars, flights, trees, streaming, homes
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Changes:
- Changed portfolio description from "Portfolio {ID}" to "Puffin Portfolio"
- Round pricePerTon UP using Math.ceil() instead of exact decimals
- Round total cost UP using Math.ceil()
Example: $237.19 per ton → $238 per ton
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
The backend was using a hardcoded PORTFOLIO_PRICING map that only had prices
for portfolios 1, 2, 3 (defaulting to $18/ton for others). When Wren API
returns Portfolio ID 37 at $237/ton, the backend was calculating with $18/ton
instead, causing massive pricing discrepancies.
Changes:
- Frontend now passes pricePerTon (from Wren API) in checkout request
- Backend uses the received pricePerTon instead of lookup table
- Removed dependency on hardcoded PORTFOLIO_PRICING map
- Added validation for pricePerTon parameter
Example fix:
- Before: 0.03 tons × $18/ton = $0.54 (wrong!)
- After: 0.03 tons × $237/ton = $7.11 (correct!)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
## Stripe Payment Integration
- Add Express.js backend server with Stripe Checkout Sessions
- Create SQLite database for order tracking
- Implement Stripe webhook handlers for payment events
- Integrate with Wren Climate API for carbon offset fulfillment
- Add CheckoutSuccess and CheckoutCancel pages
- Create checkout API client for frontend
- Update OffsetOrder component to redirect to Stripe Checkout
- Add processing fee calculation (3% of base amount)
- Implement order status tracking (pending → paid → fulfilled)
Backend (server/):
- Express server with CORS and middleware
- SQLite database with Order schema
- Stripe configuration and client
- Order CRUD operations model
- Checkout session creation endpoint
- Webhook handler for payment confirmation
- Wren API client for offset fulfillment
Frontend:
- CheckoutSuccess page with order details display
- CheckoutCancel page with retry encouragement
- Updated OffsetOrder to use Stripe checkout flow
- Added checkout routes to App.tsx
- TypeScript interfaces for checkout flow
## Visual & UX Enhancements
- Add CertificationBadge component for project verification status
- Create PortfolioDonutChart for visual portfolio allocation
- Implement RadialProgress for percentage displays
- Add reusable form components (FormInput, FormTextarea, FormSelect, FormFieldWrapper)
- Refactor OffsetOrder with improved layout and animations
- Add offset percentage slider with visual feedback
- Enhance MobileOffsetOrder with better responsive design
- Improve TripCalculator with cleaner UI structure
- Update CurrencySelect with better styling
- Add portfolio distribution visualization
- Enhance project cards with hover effects and animations
- Improve color palette and gradient usage throughout
## Configuration
- Add VITE_API_BASE_URL environment variable
- Create backend .env.example template
- Update frontend .env.example with API URL
- Add Stripe documentation references
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Create logger utility that only logs in development mode
- Update wrenClient.ts to use logger instead of console.log/warn
- Update OffsetOrder.tsx to use logger for debug messages
- Update config.ts to only log environment loading in dev mode
- Keeps console.error for actual errors (always shown)
Fixes: Console clutter in production deployment
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add comma-separated number formatting for better readability in all calculator inputs
- Move offset percentage selection from calculator to offset order page for clearer workflow
- Improve project card layout with consistent height alignment in OffsetOrder
- Change number inputs to text inputs to support formatted display
- Update form messages to reflect chosen offset percentage
- Add CLAUDE.md documentation for repository guidance
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Increase max widths and improve responsive spacing across components
- Add responsive grid columns (xl:grid-cols-4) for better large screen layout
- Remove redundant click area overlay and hover effects for cleaner code
- Consolidate padding management to main container level
- Install framer-motion dependency (v12.15.0)
- Add smooth transitions to forms and buttons in TripCalculator
- Implement hover and tap animations for interactive elements
- Add entrance/exit animations for component state changes
- Enhance user experience with motion effects in Home and OffsetOrder components