Spaces:
Configuration error
Configuration error
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8" /> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
| <title>Doge Whale Wars</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <link rel="stylesheet" href="app.css"> | |
| <script src="https://accounts.google.com/gsi/client" async></script> | |
| <style> | |
| body { | |
| margin: 0; | |
| padding: 0; | |
| font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', | |
| 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', | |
| sans-serif; | |
| -webkit-font-smoothing: antialiased; | |
| -moz-osx-font-smoothing: grayscale; | |
| background: linear-gradient(to bottom, #1e90ff, #000428); | |
| color: var(--theme-text); /* Keep text color from theme */ | |
| overflow: hidden; /* Prevent scrollbars from base layout */ | |
| min-height: 100vh; | |
| } | |
| #root { | |
| display: flex; | |
| flex-direction: column; | |
| min-height: 100vh; | |
| position: relative; /* Ensure root is part of stacking context if needed */ | |
| z-index: 3; /* Above background fish, below modals */ | |
| } | |
| /* Custom scrollbar for modal content if needed */ | |
| .overflow-y-auto::-webkit-scrollbar { | |
| width: 8px; | |
| } | |
| .overflow-y-auto::-webkit-scrollbar-track { | |
| background: #2d3748; /* theme-primary/50 or similar */ | |
| border-radius: 10px; | |
| } | |
| .overflow-y-auto::-webkit-scrollbar-thumb { | |
| background: #4a5568; /* theme-border or similar */ | |
| border-radius: 10px; | |
| } | |
| .overflow-y-auto::-webkit-scrollbar-thumb:hover { | |
| background: #718096; /* A lighter shade */ | |
| } | |
| .nav-button, .nav-button-admin { | |
| /* Tailwind classes are now applied directly in App.tsx for these */ | |
| } | |
| .game-container-outer { | |
| /* For the outer border/glow effect when playing */ | |
| } | |
| .game-container-outer.playing { | |
| /* Styles when game is active, e.g., border */ | |
| } | |
| /* Tailwind custom animations if needed */ | |
| @keyframes fadeIn { | |
| from { opacity: 0; } | |
| to { opacity: 1; } | |
| } | |
| .animate-fadeIn { | |
| animation: fadeIn 0.3s ease-out forwards; | |
| } | |
| @keyframes slideDown { | |
| from { transform: translateY(-20px); opacity: 0.8; } | |
| to { transform: translateY(0); opacity: 1; } | |
| } | |
| .animate-slideDown { | |
| animation: slideDown 0.3s ease-out forwards; | |
| } | |
| @keyframes pulseCustom { | |
| 0%, 100% { opacity: 1; transform: scale(1); } | |
| 50% { opacity: 0.8; transform: scale(1.02); } | |
| } | |
| .animate-pulseCustom { | |
| animation: pulseCustom 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; | |
| } | |
| canvas { | |
| display: block; | |
| image-rendering: -moz-crisp-edges; | |
| image-rendering: -webkit-crisp-edges; | |
| image-rendering: pixelated; | |
| image-rendering: crisp-edges; | |
| max-width: 100%; | |
| max-height: 100%; | |
| object-fit: contain; /* Ensures canvas scales within bounds maintaining aspect ratio */ | |
| position: relative; | |
| z-index: 2; | |
| } | |
| .text-xxs { | |
| font-size: 0.65rem; | |
| line-height: 0.85rem; | |
| } | |
| :root { | |
| /* --theme-background: #0D1B2A; /* Deep Dark Blue - Body background is now gradient */ | |
| --theme-dark: #1B263B; /* Dark Blue-Gray */ | |
| --theme-primary: #415A77; /* Muted Blue */ | |
| --theme-secondary: #778DA9; /* Light Steel Blue */ | |
| --theme-accent: #00A9E0; /* Bright Cyan/Sky Blue */ | |
| --theme-hover: #00CFFF; /* Lighter Cyan for hover */ | |
| --theme-border: #5A7D9A; /* Mid-tone blue for borders */ | |
| --theme-text: #E0E1DD; /* Off-white/Light Gray */ | |
| --theme-success: #3FB950; /* Green */ | |
| --theme-danger: #F85149; /* Red */ | |
| --theme-warning: #F3B50C; /* Yellow/Gold */ | |
| --theme-info: #58A6FF; /* Bright Blue */ | |
| --theme-white: #FFFFFF; | |
| --font-sans: 'Inter', sans-serif; | |
| /* Layout Variables */ | |
| --header-height: 3.5rem; /* Approx 56px for p-3 header with text */ | |
| --footer-height: 2rem; /* Approx 32px for p-2 footer with text */ | |
| --theme-accent-rgb: 0, 169, 224; /* For app.css focus rings */ | |
| } | |
| /* Updated fish styles based on user's new HTML */ | |
| .fish { /* Follower fish */ | |
| position: absolute; | |
| width: 60px; | |
| height: auto; | |
| pointer-events: none; | |
| transition: transform 0.1s linear; | |
| z-index: 45; /* Maintained z-index from app's original design for correct layering */ | |
| } | |
| .bg-fish { /* Random background fish */ | |
| position: absolute; | |
| width: 50px; | |
| height: auto; | |
| pointer-events: none; | |
| z-index: 1; /* Lowest layer, behind #root (3) */ | |
| } | |
| @keyframes swimRandom { /* Updated animation from user's new HTML */ | |
| 0% { | |
| transform: translate(0, 0) rotate(0deg); | |
| opacity: 0; | |
| } | |
| 10% { | |
| opacity: 1; | |
| } | |
| 100% { | |
| transform: translate(var(--x), var(--y)) rotate(var(--r)); | |
| opacity: 0; | |
| } | |
| } | |
| /* Spin & Win Styles */ | |
| @keyframes spin { | |
| 0% { transform: rotate(0deg); } | |
| 100% { transform: rotate(360deg); } | |
| } | |
| .wheel-section { | |
| position: absolute; | |
| width: 50%; | |
| height: 50%; | |
| transform-origin: bottom right; | |
| clip-path: polygon(0 0, 100% 0, 0 100%); | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| } | |
| .wheel-section span { | |
| position: absolute; | |
| transform: rotate(45deg) translateX(70px) rotate(-45deg); /* Adjusted for Tailwind's transform-origin */ | |
| font-weight: bold; | |
| color: white; | |
| text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.7); | |
| font-size: 0.75rem; /* Smaller font for better fit */ | |
| } | |
| .spinning { | |
| animation: spin 0.5s linear infinite; | |
| } | |
| .pulse-spin-button { /* More specific to avoid conflict if 'pulse' is used elsewhere */ | |
| animation: pulseCustom 1.5s infinite; | |
| } | |
| .confetti { | |
| position: absolute; | |
| width: 10px; | |
| height: 10px; | |
| background-color: #f00; /* Will be overridden by JS */ | |
| opacity: 0; | |
| animation: confetti-fall 3s ease-out forwards; /* Apply animation directly */ | |
| } | |
| /* Removed .confetti-animation class as animation is applied directly */ | |
| @keyframes confetti-fall { | |
| 0% { | |
| transform: translateY(-100px) rotate(0deg); | |
| opacity: 1; | |
| } | |
| 100% { | |
| transform: translateY(100vh) rotate(720deg); /* More spin */ | |
| opacity: 0; | |
| } | |
| } | |
| /* Lottery Card Flip Styles */ | |
| .lottery-card-container { | |
| perspective: 1000px; | |
| } | |
| .lottery-card { | |
| position: relative; | |
| width: 80px; | |
| height: 120px; | |
| cursor: pointer; | |
| transform-style: preserve-3d; | |
| transition: transform 0.6s; | |
| border-radius: 0.5rem; /* rounded-lg */ | |
| } | |
| .lottery-card.flipped { | |
| transform: rotateY(180deg); | |
| } | |
| .lottery-card-face { | |
| position: absolute; | |
| width: 100%; | |
| height: 100%; | |
| backface-visibility: hidden; | |
| border-radius: 0.5rem; /* rounded-lg */ | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| flex-direction: column; /* For icon and text */ | |
| box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); /* shadow-md */ | |
| } | |
| .lottery-card-front { | |
| background: linear-gradient(135deg, #f59e0b, #f97316); /* Example Tailwind amber-500 to orange-500 */ | |
| color: white; | |
| font-size: 1.875rem; /* text-3xl for icon */ | |
| } | |
| .lottery-card-front i { /* For Font Awesome icon if used */ | |
| font-size: 2.5rem; /* text-5xl */ | |
| } | |
| .lottery-card-front .ticket-text { | |
| font-size: 0.65rem; /* text-xxs */ | |
| font-weight: bold; | |
| margin-top: 0.25rem; /* mt-1 */ | |
| } | |
| .lottery-card-back { | |
| background: linear-gradient(135deg, #3b82f6, #6366f1); /* Example Tailwind blue-500 to indigo-500 */ | |
| color: white; | |
| transform: rotateY(180deg); | |
| font-size: 1rem; /* text-base */ | |
| font-weight: bold; | |
| } | |
| .lottery-card-back i { /* For prize icon */ | |
| font-size: 2rem; /* text-4xl */ | |
| margin-bottom: 0.5rem; /* mb-2 */ | |
| } | |
| /* Progress bar for lottery (can be Tailwind, but custom gives more control) */ | |
| .progress-container { | |
| width: 100%; | |
| height: 10px; | |
| background-color: rgba(255, 255, 255, 0.1); /* bg-white/10 */ | |
| border-radius: 0.375rem; /* rounded-md */ | |
| margin: 1rem 0; /* my-4 */ | |
| } | |
| .progress-bar { | |
| height: 100%; | |
| background: linear-gradient(90deg, #f59e0b, #f97316); /* Example Tailwind amber-500 to orange-500 */ | |
| border-radius: 0.375rem; /* rounded-md */ | |
| transition: width 0.3s ease; | |
| } | |
| /* Ensure Font Awesome icons are vertically centered in buttons */ | |
| .nav-button i, .nav-button-admin i { | |
| vertical-align: middle; | |
| } | |
| </style> | |
| <script> | |
| tailwind.config = { | |
| theme: { | |
| extend: { | |
| colors: { | |
| /* 'theme-background': 'var(--theme-background)', // Body background is now gradient */ | |
| 'theme-dark': 'var(--theme-dark)', | |
| 'theme-primary': 'var(--theme-primary)', | |
| 'theme-secondary': 'var(--theme-secondary)', | |
| 'theme-accent': 'var(--theme-accent)', | |
| 'theme-hover': 'var(--theme-hover)', | |
| 'theme-border': 'var(--theme-border)', | |
| 'theme-text': 'var(--theme-text)', | |
| 'theme-success': 'var(--theme-success)', | |
| 'theme-danger': 'var(--theme-danger)', | |
| 'theme-warning': 'var(--theme-warning)', | |
| 'theme-info': 'var(--theme-info)', | |
| 'theme-white': 'var(--theme-white)', | |
| }, | |
| fontFamily: { | |
| sans: ['Inter', 'ui-sans-serif', 'system-ui'], | |
| }, | |
| animation: { | |
| fadeIn: 'fadeIn 0.3s ease-out forwards', | |
| slideDown: 'slideDown 0.3s ease-out forwards', | |
| pulseCustom: 'pulseCustom 2s cubic-bezier(0.4, 0, 0.6, 1) infinite', | |
| spin: 'spin 1s linear infinite', /* Added for wheel, JS can override duration */ | |
| 'confetti-fall': 'confetti-fall 3s ease-out forwards', | |
| shake: 'shake 0.5s cubic-bezier(.36,.07,.19,.97) both', // Added shake animation | |
| }, | |
| keyframes: { | |
| fadeIn: { | |
| '0%': { opacity: '0' }, | |
| '100%': { opacity: '1' }, | |
| }, | |
| slideDown: { | |
| '0%': { transform: 'translateY(-20px)', opacity: '0.8' }, | |
| '100%': { transform: 'translateY(0)', opacity: '1' }, | |
| }, | |
| pulseCustom: { | |
| '0%, 100%': { opacity: '1', transform: 'scale(1)' }, | |
| '50%': { opacity: '0.8', transform: 'scale(1.02)' }, | |
| }, | |
| spin: { /* Added for wheel */ | |
| '0%': { transform: 'rotate(0deg)' }, | |
| '100%': { transform: 'rotate(360deg)' }, | |
| }, | |
| 'confetti-fall': { /* Added for confetti */ | |
| '0%': { transform: 'translateY(-100px) rotate(0deg)', opacity: '1'}, | |
| '100%': { transform: 'translateY(100vh) rotate(720deg)', opacity: '0'}, | |
| }, | |
| shake: { // Added shake keyframes | |
| '10%, 90%': { transform: 'translate3d(-1px, 0, 0)' }, | |
| '20%, 80%': { transform: 'translate3d(2px, 0, 0)' }, | |
| '30%, 50%, 70%': { transform: 'translate3d(-4px, 0, 0)' }, | |
| '40%, 60%': { transform: 'translate3d(4px, 0, 0)' } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| </script> | |
| <link rel="preconnect" href="https://fonts.googleapis.com"> | |
| <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> | |
| <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Orbitron:wght@400;500;700&display=swap" rel="stylesheet"> | |
| <script type="importmap"> | |
| { | |
| "imports": { | |
| "react": "https://esm.sh/react@^19.1.0", | |
| "react-dom/": "https://esm.sh/react-dom@^19.1.0/", | |
| "react/": "https://esm.sh/react@^19.1.0/", | |
| "@google/genai": "https://esm.sh/@google/genai@^1.1.0", | |
| "@/constants": "/constants.ts", | |
| "@/components/modals/AdminLoginModal": "./components/modals/AdminLoginModal.tsx" | |
| } | |
| } | |
| </script> | |
| </head> | |
| <body> | |
| <noscript>You need to enable JavaScript to run this app.</noscript> | |
| <!-- Blue fish that follow the cursor - updated src from user's HTML --> | |
| <img src="https://pngimg.com/uploads/fish/fish_PNG1151.png" class="fish" id="fish1" alt=""/> | |
| <img src="https://pngimg.com/uploads/fish/fish_PNG1151.png" class="fish" id="fish2" alt=""/> | |
| <div id="root"></div> | |
| <!-- Default Sound Effect Placeholders REMOVED | |
| Sound playback is now managed by sounds.ts and AdminConfig. | |
| --> | |
| <script type="module" src="/index.tsx"></script> | |
| <!-- Updated fish animation script based on user's new HTML --> | |
| <script> | |
| const fish1Global = document.getElementById("fish1"); | |
| const fish2Global = document.getElementById("fish2"); | |
| document.addEventListener("mousemove", (e) => { | |
| const x = e.clientX; | |
| const y = e.clientY; | |
| if (fish1Global) fish1Global.style.transform = `translate(${x}px, ${y}px)`; | |
| setTimeout(() => { | |
| if (fish2Global) fish2Global.style.transform = `translate(${x - 40}px, ${y + 40}px)`; | |
| }, 100); | |
| }); | |
| // Background random swimming fish - updated src to yellow fish | |
| const fishImageGlobal = 'https://www.transparentpng.com/thumb/fish/yellow-tang-fish-transparent-background-Q9PKK1.png'; | |
| function createBackgroundFish() { | |
| const fishElement = document.createElement('img'); | |
| fishElement.src = fishImageGlobal; | |
| fishElement.classList.add('bg-fish'); | |
| fishElement.setAttribute('alt', ''); // Decorative image | |
| fishElement.style.top = Math.floor(Math.random() * window.innerHeight) + 'px'; | |
| fishElement.style.left = Math.floor(Math.random() * window.innerWidth) + 'px'; | |
| const moveX = Math.floor(Math.random() * 1000 - 500) + 'px'; | |
| const moveY = Math.floor(Math.random() * 1000 - 500) + 'px'; | |
| const rotate = Math.floor(Math.random() * 360) + 'deg'; | |
| fishElement.style.setProperty('--x', moveX); | |
| fishElement.style.setProperty('--y', moveY); | |
| fishElement.style.setProperty('--r', rotate); | |
| fishElement.style.animation = 'swimRandom 14s linear forwards'; | |
| document.body.appendChild(fishElement); | |
| setTimeout(() => { | |
| fishElement.remove(); | |
| }, 14000); | |
| } | |
| setInterval(createBackgroundFish, 1000); | |
| </script> | |
| </body> | |
| </html><link rel="stylesheet" href="index.css"> | |
| <script src="index.tsx" type="module"></script> | |