Some checks failed
Build and Push Docker Images / docker (push) Failing after 1m58s
This is a major migration from Vite to Next.js 16.0.1 for improved performance, better SEO, and modern React features. ## Next.js Migration Changes - Upgraded to Next.js 16.0.1 with Turbopack (from Vite 6) - Migrated from client-side routing to App Router architecture - Created app/ directory with Next.js page structure - Added server components and client components pattern - Configured standalone Docker builds for production ## Bug Fixes - React Hooks - Fixed infinite loop in Header.tsx scroll behavior (removed lastScrollY state dependency) - Fixed infinite loop in useCalculatorState.ts (wrapped saveState/clearState in useCallback) - Fixed infinite loop in OffsetOrder.tsx (removed savedState from useEffect dependencies) - Removed unused React imports from all client components ## Environment Variable Migration - Migrated all VITE_ variables to NEXT_PUBLIC_ prefix - Updated src/utils/config.ts to use direct static references (required for Next.js) - Updated src/api/checkoutClient.ts, emailClient.ts, aisClient.ts for Next.js env vars - Updated src/vite-env.d.ts types for Next.js environment - Maintained backward compatibility with Docker window.env ## Layout & UX Improvements - Fixed footer to always stay at bottom of viewport using flexbox - Updated app/layout.tsx with flex-1 main content area - Preserved glass morphism effects and luxury styling ## TypeScript & Build - Fixed TypeScript strict mode compilation errors - Removed unused imports and variables - Fixed Axios interceptor types in project/src/api/wrenClient.ts - Production build verified and passing ## Testing & Verification - Tested calculator end-to-end in Playwright - Verified Wren API integration working (11 portfolios fetched) - Confirmed calculation: 5000L → 13.47 tons CO₂ → $3,206 total - All navigation routes working correctly - Footer positioning verified across all pages ## Files Added - app/ directory with Next.js routes - components/ directory with client components - next.config.mjs, next-env.d.ts - ENV_MIGRATION.md, NEXTJS_MIGRATION_COMPLETE.md documentation ## Files Modified - Docker configuration for Next.js standalone builds - package.json dependencies (Next.js, React 19) - ts config.json for Next.js - All API clients for new env var pattern 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
280 lines
6.2 KiB
CSS
280 lines
6.2 KiB
CSS
@tailwind base;
|
|
@tailwind components;
|
|
@tailwind utilities;
|
|
|
|
/* Custom CSS Variables for Luxury Yacht Club Theme */
|
|
:root {
|
|
--navy-deep: #0F172A;
|
|
--ocean-blue: #1E40AF;
|
|
--ocean-light: #3B82F6;
|
|
--gold-accent: #F59E0B;
|
|
--gold-light: #FCD34D;
|
|
--gray-sophisticated: #64748B;
|
|
--gray-light: #E2E8F0;
|
|
--white-tinted: #F8FAFC;
|
|
}
|
|
|
|
/* Global Styles */
|
|
* {
|
|
scroll-behavior: smooth;
|
|
}
|
|
|
|
body {
|
|
background: linear-gradient(135deg, var(--white-tinted) 0%, #E0F2FE 100%);
|
|
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
}
|
|
|
|
/* Custom Glassmorphism Classes */
|
|
.glass-card {
|
|
background: rgba(255, 255, 255, 0.25);
|
|
backdrop-filter: blur(10px);
|
|
border: 1px solid rgba(255, 255, 255, 0.18);
|
|
box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37);
|
|
}
|
|
|
|
.glass-nav {
|
|
background: rgba(255, 255, 255, 0.95);
|
|
backdrop-filter: blur(20px);
|
|
border-bottom: 1px solid rgba(255, 255, 255, 0.2);
|
|
}
|
|
|
|
/* Premium Button Styles */
|
|
.btn-premium {
|
|
background: linear-gradient(135deg, var(--ocean-blue) 0%, var(--ocean-light) 100%);
|
|
color: white;
|
|
padding: 12px 32px;
|
|
border-radius: 12px;
|
|
font-weight: 600;
|
|
letter-spacing: 0.025em;
|
|
border: none;
|
|
cursor: pointer;
|
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
box-shadow: 0 4px 15px 0 rgba(30, 64, 175, 0.3);
|
|
position: relative;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.btn-premium::before {
|
|
content: '';
|
|
position: absolute;
|
|
top: 0;
|
|
left: -100%;
|
|
width: 100%;
|
|
height: 100%;
|
|
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
|
|
transition: left 0.5s;
|
|
}
|
|
|
|
.btn-premium:hover::before {
|
|
left: 100%;
|
|
}
|
|
|
|
.btn-premium:hover {
|
|
transform: translateY(-2px);
|
|
box-shadow: 0 8px 25px 0 rgba(30, 64, 175, 0.4);
|
|
}
|
|
|
|
.btn-secondary {
|
|
background: linear-gradient(135deg, var(--gold-accent) 0%, var(--gold-light) 100%);
|
|
color: var(--navy-deep);
|
|
padding: 12px 32px;
|
|
border-radius: 12px;
|
|
font-weight: 600;
|
|
letter-spacing: 0.025em;
|
|
border: none;
|
|
cursor: pointer;
|
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
box-shadow: 0 4px 15px 0 rgba(245, 158, 11, 0.3);
|
|
position: relative;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.btn-secondary:hover {
|
|
transform: translateY(-2px);
|
|
box-shadow: 0 8px 25px 0 rgba(245, 158, 11, 0.4);
|
|
}
|
|
|
|
/* Custom Shadow Classes */
|
|
.shadow-luxury {
|
|
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
|
|
}
|
|
|
|
.shadow-premium {
|
|
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
|
|
}
|
|
|
|
/* Wave Pattern Background */
|
|
.wave-pattern {
|
|
background-image: url("data:image/svg+xml,%3csvg width='100' height='20' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='m0 10c20-10 20 10 40 0s20 10 40 0 20-10 20 0v10h-100z' fill='%23ffffff' fill-opacity='0.03'/%3e%3c/svg%3e");
|
|
background-repeat: repeat-x;
|
|
background-position: bottom;
|
|
}
|
|
|
|
/* Premium Card Styles */
|
|
.luxury-card {
|
|
background: linear-gradient(145deg, #ffffff 0%, #f8fafc 100%);
|
|
border: 1px solid rgba(226, 232, 240, 0.8);
|
|
border-radius: 20px;
|
|
box-shadow: 0 10px 30px -5px rgba(0, 0, 0, 0.1);
|
|
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
|
position: relative;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.luxury-card::before {
|
|
content: '';
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
height: 1px;
|
|
background: linear-gradient(90deg, transparent, var(--gold-accent), transparent);
|
|
opacity: 0;
|
|
transition: opacity 0.3s ease;
|
|
}
|
|
|
|
.luxury-card:hover::before {
|
|
opacity: 1;
|
|
}
|
|
|
|
.luxury-card:hover {
|
|
transform: translateY(-8px);
|
|
box-shadow: 0 20px 40px -5px rgba(0, 0, 0, 0.15);
|
|
border-color: rgba(30, 64, 175, 0.2);
|
|
}
|
|
|
|
/* Typography Enhancements */
|
|
.heading-luxury {
|
|
background: linear-gradient(135deg, var(--navy-deep) 0%, var(--ocean-blue) 100%);
|
|
background-clip: text;
|
|
-webkit-background-clip: text;
|
|
-webkit-text-fill-color: transparent;
|
|
font-weight: 700;
|
|
letter-spacing: -0.025em;
|
|
}
|
|
|
|
.text-gradient-gold {
|
|
background: linear-gradient(135deg, var(--gold-accent) 0%, var(--gold-light) 100%);
|
|
background-clip: text;
|
|
-webkit-background-clip: text;
|
|
-webkit-text-fill-color: transparent;
|
|
font-weight: 600;
|
|
}
|
|
|
|
/* Parallax Container */
|
|
.parallax-container {
|
|
position: relative;
|
|
overflow: hidden;
|
|
transform-style: preserve-3d;
|
|
}
|
|
|
|
/* Custom Scrollbar */
|
|
::-webkit-scrollbar {
|
|
width: 8px;
|
|
}
|
|
|
|
::-webkit-scrollbar-track {
|
|
background: var(--gray-light);
|
|
}
|
|
|
|
::-webkit-scrollbar-thumb {
|
|
background: linear-gradient(135deg, var(--ocean-blue), var(--ocean-light));
|
|
border-radius: 4px;
|
|
}
|
|
|
|
::-webkit-scrollbar-thumb:hover {
|
|
background: linear-gradient(135deg, var(--navy-deep), var(--ocean-blue));
|
|
}
|
|
|
|
/* Animated Wave Effect */
|
|
@keyframes wave {
|
|
0% {
|
|
transform: translateX(0);
|
|
}
|
|
100% {
|
|
transform: translateX(-100px);
|
|
}
|
|
}
|
|
|
|
.animate-wave {
|
|
animation: wave 15s linear infinite;
|
|
}
|
|
|
|
/* Animated Floating Particles */
|
|
@keyframes float {
|
|
0% {
|
|
transform: translateY(0px) translateX(0px);
|
|
opacity: 0;
|
|
}
|
|
10% {
|
|
opacity: 1;
|
|
}
|
|
90% {
|
|
opacity: 1;
|
|
}
|
|
100% {
|
|
transform: translateY(-100vh) translateX(50px);
|
|
opacity: 0;
|
|
}
|
|
}
|
|
|
|
.particle {
|
|
position: absolute;
|
|
background-color: rgba(255, 255, 255, 0.1);
|
|
border-radius: 50%;
|
|
animation: float 15s infinite;
|
|
}
|
|
|
|
/* Enhanced gradient overlays */
|
|
.gradient-luxury {
|
|
background: linear-gradient(135deg,
|
|
rgba(15, 23, 42, 0.95) 0%,
|
|
rgba(30, 64, 175, 0.85) 50%,
|
|
rgba(30, 58, 138, 0.9) 100%);
|
|
}
|
|
|
|
/* Custom Range Slider Styles */
|
|
input[type="range"].slider {
|
|
-webkit-appearance: none;
|
|
width: 100%;
|
|
height: 12px;
|
|
border-radius: 6px;
|
|
background: #e5e7eb;
|
|
outline: none;
|
|
opacity: 1;
|
|
transition: opacity 0.2s;
|
|
}
|
|
|
|
input[type="range"].slider::-webkit-slider-thumb {
|
|
-webkit-appearance: none;
|
|
appearance: none;
|
|
width: 24px;
|
|
height: 24px;
|
|
border-radius: 50%;
|
|
background: #3b82f6;
|
|
cursor: pointer;
|
|
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);
|
|
transition: transform 0.2s, box-shadow 0.2s;
|
|
}
|
|
|
|
input[type="range"].slider::-moz-range-thumb {
|
|
width: 24px;
|
|
height: 24px;
|
|
border-radius: 50%;
|
|
background: #3b82f6;
|
|
cursor: pointer;
|
|
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);
|
|
transition: transform 0.2s, box-shadow 0.2s;
|
|
border: none;
|
|
}
|
|
|
|
input[type="range"].slider:hover::-webkit-slider-thumb {
|
|
transform: scale(1.1);
|
|
box-shadow: 0 3px 8px rgba(0, 0, 0, 0.2);
|
|
}
|
|
|
|
input[type="range"].slider:hover::-moz-range-thumb {
|
|
transform: scale(1.1);
|
|
box-shadow: 0 3px 8px rgba(0, 0, 0, 0.2);
|
|
}
|