commit 547c72dce037750f2e17845a2550f79696b6e515 Author: mealno Date: Mon May 25 09:31:04 2026 +0000 Upload files to "/" diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..7a550fe --- /dev/null +++ b/.env.example @@ -0,0 +1,9 @@ +# GEMINI_API_KEY: Required for Gemini AI API calls. +# AI Studio automatically injects this at runtime from user secrets. +# Users configure this via the Secrets panel in the AI Studio UI. +GEMINI_API_KEY="MY_GEMINI_API_KEY" + +# APP_URL: The URL where this applet is hosted. +# AI Studio automatically injects this at runtime with the Cloud Run service URL. +# Used for self-referential links, OAuth callbacks, and API endpoints. +APP_URL="MY_APP_URL" diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5a86d2a --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +node_modules/ +build/ +dist/ +coverage/ +.DS_Store +*.log +.env* +!.env.example diff --git a/App.tsx b/App.tsx new file mode 100644 index 0000000..1fd4ec4 --- /dev/null +++ b/App.tsx @@ -0,0 +1,334 @@ +import React from 'react'; +import { Flame, FlameKindle, MapPin, Search, Plus, Sparkles, Navigation, ArrowRight, Star, ShoppingBag, Truck, Camera, MessageSquareText, Timer, Bike, Banknote, Utensils } from 'lucide-react'; + +function Logo({ className = "h-8" }: { className?: string }) { + const [imgError, setImgError] = React.useState(false); + + // Fallback to text if the image is not uploaded yet + if (imgError) { + return ( + + mealno + + ); + } + + return ( + Mealno Logo setImgError(true)} + /> + ); +} + +function Navbar() { + return ( + + ); +} + +function Hero() { + return ( +
+
+
+ + {/* Left Content */} +
+
+
+ Dropping Soon +
+ +

+ Your Wallet Will Thank You.
+ Your Stomach Will Love You. +

+ +

+ Newtown's ultimate student cloud kitchen is dropping soon. Insane flavor, unbelievable student discounts. +

+ + {/* Countdown Box */} +
+
+
+ +
+ 05 + Days +
+ + : + +
+ 12 + Hours +
+ + : + +
+ 45 + Mins +
+ + : + +
+ 08 + Secs +
+ +
+
+ + {/* Waitlist Input Row */} +
e.preventDefault()}> +
+
+ + + +
+ +
+ +
+ + {/* Tiers Text */} +
+
+ +

+ Waitlist Tier 1 (First 500): Free Delivery for one month. +

+
+
+
+
+
+

+ Tier 2 (Next 1000): Priority first access. Sign up now. +

+
+
+ +
+ + {/* Right Image */} +
+
+
+ {/* Chip on Image */} +
+ + Spicy AF +
+ + {/* Using a high-quality dark-themed burger image as placeholder */} + Delicious authentic Indian Biryani with spices + + {/* Vignette Overlay for dark aesthetic */} +
+
+
+ +
+
+
+ ); +} + +function StealsSection() { + const steals = [ + { + title: "Heavy Discounts", + description: "Daily flash sales and student-only pricing. Keep your ID ready.", + icon: , + iconBg: "bg-red-950/40 border-red-900/50" + }, + { + title: "Fresh & Fast", + description: "Cooked fresh, delivered straight to your hostel or flat before the craving dies.", + icon: , + iconBg: "bg-amber-950/40 border-amber-900/50" + }, + { + title: "Zero Delivery Fees", + description: "Order minimums? We don't know them. Free delivery within Newtown campus zones.", + icon: , + iconBg: "bg-blue-950/40 border-blue-900/50" + } + ]; + + return ( +
+
+
+

Student Steals

+

+ Because instant noodles shouldn't be your only late-night option. +

+
+ +
+ {steals.map((steal, i) => ( +
+
+ {steal.icon} +
+

{steal.title}

+

+ {steal.description} +

+
+ ))} +
+
+
+ ); +} + +function FounderSection() { + const team = [ + { + name: "Arnab Kapri", + role: "Founder", + quote: "\"Software dev by day, building your new favorite food brand by night to fix Newtown's late-night food scene.\"", + img: "https://images.unsplash.com/photo-1556157382-97eda2d62296?auto=format&fit=crop&w=800&q=80" + }, + { + name: "Alex Rivera", + role: "Co-Founder & Head of Operations", + quote: "\"Ensuring your late-night cravings hit your doorstep before the movie gets to the good part.\"", + img: "https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?auto=format&fit=crop&w=800&q=80" + }, + { + name: "Sarah Chen", + role: "Co-Founder & Culinary Lead", + quote: "\"Experimenting with flavors that'll make you rethink everything you know about midnight snacking.\"", + img: "https://images.unsplash.com/photo-1573496359142-b8d87734a5a2?auto=format&fit=crop&w=800&q=80" + } + ]; + + return ( +
+
+
+ The Hustle +

+ Built by locals, for late-night cravings. +

+

+ Meet the team bringing the heat to Newtown's after-hours food scene. +

+
+ +
+ {team.map((member, i) => ( +
+
+ {member.name} +
+ +
+ +
+

{member.name}

+

{member.role}

+ +
+

+ {member.quote} +

+
+
+
+ ))} +
+
+
+ ); +} + +function Footer() { + return ( + + ); +} + +export default function App() { + return ( +
+ +
+ + + +
+
+
+ ); +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..f1aa5e9 --- /dev/null +++ b/README.md @@ -0,0 +1,20 @@ +
+GHBanner +
+ +# Run and deploy your AI Studio app + +This contains everything you need to run your app locally. + +View your app in AI Studio: https://ai.studio/apps/3ee1668e-a64b-4275-bbd0-23ae0f558de6 + +## Run Locally + +**Prerequisites:** Node.js + + +1. Install dependencies: + `npm install` +2. Set the `GEMINI_API_KEY` in [.env.local](.env.local) to your Gemini API key +3. Run the app: + `npm run dev` diff --git a/index.css b/index.css new file mode 100644 index 0000000..b47c75b --- /dev/null +++ b/index.css @@ -0,0 +1,38 @@ +@import "tailwindcss"; + +@theme { + --color-background: #0b1326; + --color-surface: #131b2e; + --color-surface-dim: #0b1326; + --color-surface-bright: #31394d; + --color-surface-container: #171f33; + --color-on-surface: #dae2fd; + + --color-primary: #f93a4a; + --color-primary-text: #ff8c95; + --color-on-primary: #ffffff; + + --color-secondary: #ffb300; + --color-on-secondary: #4d3600; + + --color-border: #2d3449; + + --font-sans: 'Inter', sans-serif; + --font-display: 'Plus Jakarta Sans', sans-serif; +} + +body { + @apply bg-background text-on-surface font-sans antialiased; +} + +h1, h2, h3, h4, h5, h6, .font-display { + @apply font-display tracking-tight text-white; +} + +/* Custom glow utility */ +.glow-primary { + box-shadow: 0 0 20px rgba(249, 58, 74, 0.2); +} +.glow-primary:hover { + box-shadow: 0 0 30px rgba(249, 58, 74, 0.4); +} diff --git a/index.html b/index.html new file mode 100644 index 0000000..be2fbb7 --- /dev/null +++ b/index.html @@ -0,0 +1,16 @@ + + + + + + Mealno - Cloud Kitchen + + + + + +
+ + + + diff --git a/main.tsx b/main.tsx new file mode 100644 index 0000000..080dac3 --- /dev/null +++ b/main.tsx @@ -0,0 +1,10 @@ +import {StrictMode} from 'react'; +import {createRoot} from 'react-dom/client'; +import App from './App.tsx'; +import './index.css'; + +createRoot(document.getElementById('root')!).render( + + + , +); diff --git a/metadata.json b/metadata.json new file mode 100644 index 0000000..80ee3e0 --- /dev/null +++ b/metadata.json @@ -0,0 +1,6 @@ +{ + "name": "Mealno", + "description": "Gen-Z cloud kitchen landing page for students with dark-tech-appetizing aesthetic.", + "requestFramePermissions": [], + "majorCapabilities": ["MAJOR_CAPABILITY_SERVER_SIDE_GEMINI_API"] +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..44745ed --- /dev/null +++ b/package.json @@ -0,0 +1,35 @@ +{ + "name": "react-example", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite --port=3000 --host=0.0.0.0", + "build": "vite build", + "preview": "vite preview", + "clean": "rm -rf dist server.js", + "lint": "tsc --noEmit" + }, + "dependencies": { + "@google/genai": "^2.4.0", + "@tailwindcss/vite": "^4.1.14", + "@vitejs/plugin-react": "^5.0.4", + "lucide-react": "^0.546.0", + "react": "^19.0.1", + "react-dom": "^19.0.1", + "vite": "^6.2.3", + "express": "^4.21.2", + "dotenv": "^17.2.3", + "motion": "^12.23.24" + }, + "devDependencies": { + "@types/node": "^22.14.0", + "autoprefixer": "^10.4.21", + "esbuild": "^0.25.0", + "tailwindcss": "^4.1.14", + "tsx": "^4.21.0", + "typescript": "~5.8.2", + "vite": "^6.2.3", + "@types/express": "^4.17.21" + } +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..d88f175 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,26 @@ +{ + "compilerOptions": { + "target": "ES2022", + "experimentalDecorators": true, + "useDefineForClassFields": false, + "module": "ESNext", + "lib": [ + "ES2022", + "DOM", + "DOM.Iterable" + ], + "skipLibCheck": true, + "moduleResolution": "bundler", + "isolatedModules": true, + "moduleDetection": "force", + "allowJs": true, + "jsx": "react-jsx", + "paths": { + "@/*": [ + "./*" + ] + }, + "allowImportingTsExtensions": true, + "noEmit": true + } +} diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 0000000..fc23e76 --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,22 @@ +import tailwindcss from '@tailwindcss/vite'; +import react from '@vitejs/plugin-react'; +import path from 'path'; +import {defineConfig} from 'vite'; + +export default defineConfig(() => { + return { + plugins: [react(), tailwindcss()], + resolve: { + alias: { + '@': path.resolve(__dirname, '.'), + }, + }, + server: { + // HMR is disabled in AI Studio via DISABLE_HMR env var. + // Do not modify—file watching is disabled to prevent flickering during agent edits. + hmr: process.env.DISABLE_HMR !== 'true', + // Disable file watching when DISABLE_HMR is true to save CPU during agent edits. + watch: process.env.DISABLE_HMR === 'true' ? null : {}, + }, + }; +});